Merge branch 'master' of https://github.com/brkcvn/akaunting into new-plans

This commit is contained in:
Burak Civan
2022-10-24 09:33:36 +03:00
48 changed files with 2113 additions and 516 deletions

View File

@@ -189,8 +189,10 @@ export default {
let el = this.$refs.dropdownMenu;
let target = event.target;
if (el !== target && ! el.contains(target)) {
this.isOpen = false;
if (typeof el != "undefined") {
if (el !== target && ! el.contains(target)) {
this.isOpen = false;
}
}
},
},

View File

@@ -52,13 +52,11 @@
</div>
</div>
</div>
</div>
</div>
<div v-else class="document-contact-with-contact-bill-to">
<div>
<span class="text-sm">{{ contactInfoText }}</span>
</div>
</div>
<div class="overflow-x-visible mt-0">
<table class="table table-borderless p-0">
<tbody>
@@ -88,28 +86,26 @@
<th class="font-normal text-xs text-left p-0">
{{ contact.phone }} &nbsp;
<span v-if="contact.email">
- {{ contact.email }}
- {{ contact.email }}
</span>
</th>
</tr>
</tbody>
</table>
</div>
<div class="absolute flex flex-col mt-2">
<button type="button" class="p-0 text-xs text-purple ltr:text-left rtl:text-right" @click="onContactEdit">
<span class="bg-no-repeat bg-0-2 bg-0-full hover:bg-full-2 bg-gradient-to-b from-transparent to-purple transition-backgroundSize">
{{ editContactText.replace(':contact_name', contact.name).replace(':field', contact.name) }}
</span>
</button>
<button type="button" class="p-0 text-xs text-purple ltr:text-left rtl:text-right" @click="onContactList">
<span class="bg-no-repeat bg-0-2 bg-0-full hover:bg-full-2 bg-gradient-to-b from-transparent to-purple transition-backgroundSize">
{{ chooseDifferentContactText }}
</span>
</button>
</div>
</div>
</div>
<div :class="show.contact_selected ? 'flex' : 'hidden'" class="absolute flex-col mt-2">
<button type="button" class="p-0 text-xs text-purple ltr:text-left rtl:text-right" @click="onContactEdit">
<span class="bg-no-repeat bg-0-2 bg-0-full hover:bg-full-2 bg-gradient-to-b from-transparent to-purple transition-backgroundSize">
{{ editContactText.replace(':contact_name', contact.name).replace(':field', contact.name) }}
</span>
</button>
<button type="button" class="p-0 text-xs text-purple ltr:text-left rtl:text-right" @click="onContactList">
<span class="bg-no-repeat bg-0-2 bg-0-full hover:bg-full-2 bg-gradient-to-b from-transparent to-purple transition-backgroundSize">
{{ chooseDifferentContactText }}
</span>
</button>
</div>
<component v-bind:is="add_new_html" @submit="onSubmit" @cancel="onCancel"></component>
</div>
</div>

View File

@@ -303,8 +303,8 @@ export default {
onInput(evt) {
this.search = evt.target.value;
let option_url = this.selected_options[this.filter_index].url;
let option_url = this.selected_options.length > 0 ? this.selected_options[this.filter_index].url : '';
if (this.search) {
if (option_url.indexOf('?') === -1) {
@@ -581,7 +581,7 @@ export default {
onFilterDelete(index) {
this.show_icon = true;
this.show_close_icon = false;
this.filter_list.push(this.selected_options[index]);
if (this.filter_last_step == 'options') {
@@ -598,8 +598,10 @@ export default {
if (this.filter_index == 0) {
this.onChangeSearchAndFilterText(this.defaultPlaceholder, true);
this.show_close_icon = false;
} else {
this.show_icon = false;
this.show_close_icon = true;
}
this.filter_last_step = 'options';
@@ -790,6 +792,10 @@ export default {
if (this.filter_index > 0) {
this.onChangeSearchAndFilterText(this.enterPlaceholder, false);
}
if (this.selected_values.length > 0) {
this.show_close_icon = true;
}
},
computed: {

View File

@@ -875,7 +875,7 @@ export default {
if (this.multiple) {
this.selected = [];
} else {
this.selected = null;
this.selected = '';
}
return;
@@ -892,7 +892,7 @@ export default {
}, this);
} else {
if (! options.find((option) => option == this.selected)) {
this.selected = null;
this.selected = '';
}
}
}

View File

@@ -1094,7 +1094,7 @@ export default {
if (this.multiple) {
this.selected = [];
} else {
this.selected = null;
this.selected = '';
}
return;
@@ -1111,7 +1111,7 @@ export default {
}, this);
} else {
if (! options.find((option) => option == this.selected)) {
this.selected = null;
this.selected = '';
}
}
},

View File

@@ -229,6 +229,9 @@ export default {
// Bulk Action modal cancel
onCancelBulkAction() {
this.bulk_action.modal = false;
let documentClasses = document.body.classList;
documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4');
},
// Bulk Action Clear selected items
@@ -583,6 +586,396 @@ export default {
this.onChangeCurrency(currency_code);
},
async onAddPayment(url) {
let payment = {
modal: false,
url: url,
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="max-w-md" modal-position-top :show="payment.modal" @submit="onSubmit" @cancel="onCancel" :buttons="payment.buttons" :title="payment.title" :is_component=true :message="payment.html"></akaunting-modal-add-new></div>',
components: {
AkauntingDropzoneFileUpload,
AkauntingContactCard,
AkauntingCompanyEdit,
AkauntingEditItemColumns,
AkauntingItemButton,
AkauntingDocumentButton,
AkauntingSearch,
AkauntingRadioGroup,
AkauntingSelect,
AkauntingSelectRemote,
AkauntingMoney,
AkauntingModal,
AkauntingModalAddNew,
AkauntingDate,
AkauntingRecurring,
AkauntingHtmlEditor,
AkauntingCountdown,
AkauntingCurrencyConversion,
AkauntingConnectTransactions,
AkauntingSwitch,
AkauntingSlider,
AkauntingColor,
CardForm,
[Select.name]: Select,
[Option.name]: Option,
[Steps.name]: Steps,
[Step.name]: Step,
[Button.name]: Button,
[Link.name]: Link,
[Tooltip.name]: Tooltip,
[ColorPicker.name]: ColorPicker,
},
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('overflow-y-hidden', 'overflow-overlay', '-ml-4');
},
}
})
});
})
.catch(error => {
})
.finally(function () {
// always executed
});
},
async onEditPayment(url) {
let payment = {
modal: false,
url: url,
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="max-w-md" modal-position-top :show="payment.modal" @submit="onSubmit" @cancel="onCancel" :buttons="payment.buttons" :title="payment.title" :is_component=true :message="payment.html"></akaunting-modal-add-new></div>',
components: {
AkauntingDropzoneFileUpload,
AkauntingContactCard,
AkauntingCompanyEdit,
AkauntingEditItemColumns,
AkauntingItemButton,
AkauntingDocumentButton,
AkauntingSearch,
AkauntingRadioGroup,
AkauntingSelect,
AkauntingSelectRemote,
AkauntingMoney,
AkauntingModal,
AkauntingModalAddNew,
AkauntingDate,
AkauntingRecurring,
AkauntingHtmlEditor,
AkauntingCountdown,
AkauntingCurrencyConversion,
AkauntingConnectTransactions,
AkauntingSwitch,
AkauntingSlider,
AkauntingColor,
CardForm,
[Select.name]: Select,
[Option.name]: Option,
[Steps.name]: Steps,
[Step.name]: Step,
[Button.name]: Button,
[Link.name]: Link,
[Tooltip.name]: Tooltip,
[ColorPicker.name]: ColorPicker,
},
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('overflow-y-hidden', 'overflow-overlay', '-ml-4');
},
}
})
});
})
.catch(error => {
})
.finally(function () {
// always executed
});
},
async onSendEmail(url) {
let email = {
modal: false,
url: url,
title: '',
html: '',
buttons:{}
};
let email_promise = Promise.resolve(window.axios.get(email.url));
if (this.email_template) {
email_promise = Promise.resolve(window.axios.get(email.url, {
params: {
email_template: this.email_template
}
}));
}
this.email_template = false;
email_promise.then(response => {
email.modal = true;
email.title = response.data.data.title;
email.html = response.data.html;
email.buttons = response.data.data.buttons;
this.component = Vue.component('add-new-component', (resolve, reject) => {
resolve({
template: '<div id="dynamic-email-component"><akaunting-modal-add-new modal-dialog-class="max-w-screen-md" :show="email.modal" @submit="onSubmit" @cancel="onCancel" :buttons="email.buttons" :title="email.title" :is_component=true :message="email.html"></akaunting-modal-add-new></div>',
components: {
AkauntingDropzoneFileUpload,
AkauntingContactCard,
AkauntingCompanyEdit,
AkauntingEditItemColumns,
AkauntingItemButton,
AkauntingDocumentButton,
AkauntingSearch,
AkauntingRadioGroup,
AkauntingSelect,
AkauntingSelectRemote,
AkauntingMoney,
AkauntingModal,
AkauntingModalAddNew,
AkauntingDate,
AkauntingRecurring,
AkauntingHtmlEditor,
AkauntingCountdown,
AkauntingCurrencyConversion,
AkauntingConnectTransactions,
AkauntingSwitch,
AkauntingSlider,
AkauntingColor,
CardForm,
[Select.name]: Select,
[Option.name]: Option,
[Steps.name]: Steps,
[Step.name]: Step,
[Button.name]: Button,
[Link.name]: Link,
[Tooltip.name]: Tooltip,
[ColorPicker.name]: ColorPicker,
},
data: function () {
return {
form:{},
email: email,
}
},
methods: {
onSubmit(event) {
this.$emit('submit', event);
event.submit();
},
onCancel() {
this.email.modal = false;
this.email.html = null;
let documentClasses = document.body.classList;
documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4');
},
}
})
});
})
.catch(error => {
})
.finally(function () {
// always executed
});
},
onShareLink(url) {
let share = {
modal: false,

View File

@@ -493,7 +493,9 @@ export default class Form {
// Form fields check validation issue
onFail(error) {
this.errors.record(error.response.data.errors);
if (typeof this.errors != "undefined") {
this.errors.record(error.response.data.errors);
}
this.loading = false;
}

View File

@@ -50,7 +50,7 @@ const app = new Vue({
}
},
methods:{
methods: {
setDueMinDate(date) {
this.min_due_date = date;
},

View File

@@ -33,62 +33,6 @@ const app = new Vue({
},
methods: {
async onEmail(route) {
let email = {
modal: false,
route: route,
title: '',
html: '',
buttons:{}
};
let email_promise = Promise.resolve(window.axios.get(email.route));
email_promise.then(response => {
email.modal = true;
email.title = response.data.data.title;
email.html = response.data.html;
email.buttons = response.data.data.buttons;
this.component = Vue.component('add-new-component', (resolve, reject) => {
resolve({
template: '<div id="dynamic-email-component"><akaunting-modal-add-new modal-dialog-class="max-w-md" :show="email.modal" @submit="onSubmit" @cancel="onCancel" :buttons="email.buttons" :title="email.title" :is_component=true :message="email.html"></akaunting-modal-add-new></div>',
mixins: [
Global
],
data: function () {
return {
form:{},
email: email,
}
},
methods: {
onSubmit(event) {
this.$emit('submit', event);
event.submit();
},
onCancel() {
this.email.modal = false;
this.email.html = null;
let documentClasses = document.body.classList;
documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4');
},
}
})
});
})
.catch(error => {
})
.finally(function () {
// always executed
});
},
//
},
});

View File

@@ -589,315 +589,10 @@ const app = new Vue({
this.form.items[item_index][field_name] = this.items[item_index][field_name];
},
async onPayment(document_id) {
if (typeof document_id == 'object') {
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="max-w-md" modal-position-top :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('overflow-y-hidden', 'overflow-overlay', '-ml-4');
},
}
})
});
})
.catch(error => {
})
.finally(function () {
// always executed
});
},
async onEditPayment(transaction_id) {
let document_id = document.getElementById('document_id').value;
let payment = {
modal: false,
url: url + '/modals/documents/' + document_id + '/transactions/' + transaction_id + '/edit',
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="max-w-md" modal-position-top :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('overflow-y-hidden', 'overflow-overlay', '-ml-4');
},
}
})
});
})
.catch(error => {
})
.finally(function () {
// always executed
});
},
async onEmail(route) {
let email = {
modal: false,
route: route,
title: '',
html: '',
buttons:{}
};
let email_promise = Promise.resolve(window.axios.get(email.route));
if (this.email_template) {
email_promise = Promise.resolve(window.axios.get(email.route, {
params: {
email_template: this.email_template
}
}));
}
this.email_template = false;
email_promise.then(response => {
email.modal = true;
email.title = response.data.data.title;
email.html = response.data.html;
email.buttons = response.data.data.buttons;
this.component = Vue.component('add-new-component', (resolve, reject) => {
resolve({
template: '<div id="dynamic-email-component"><akaunting-modal-add-new modal-dialog-class="max-w-md" :show="email.modal" @submit="onSubmit" @cancel="onCancel" :buttons="email.buttons" :title="email.title" :is_component=true :message="email.html"></akaunting-modal-add-new></div>',
mixins: [
Global
],
data: function () {
return {
form:{},
email: email,
}
},
methods: {
onSubmit(event) {
this.$emit('submit', event);
event.submit();
},
onCancel() {
this.email.modal = false;
this.email.html = null;
let documentClasses = document.body.classList;
documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4');
},
}
})
});
})
.catch(error => {
})
.finally(function () {
// always executed
});
},
onEmailViaTemplate(route, template) {
this.email_template = template;
this.onEmail(route);
this.onSendEmail(route);
},
// Change currency get money
@@ -1108,7 +803,7 @@ const app = new Vue({
let email_route = document.getElementById('senddocument_route').value;
this.onEmail(email_route);
this.onSendEmail(email_route);
}
this.page_loaded = true;