mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-28 12:11:08 -04:00
add changes in tax per item calculation
This commit is contained in:
@ -271,6 +271,7 @@ const price = computed({
|
|||||||
} else {
|
} else {
|
||||||
updateItemAttribute('price', newValue)
|
updateItemAttribute('price', newValue)
|
||||||
}
|
}
|
||||||
|
setDiscount()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -281,13 +282,8 @@ const discount = computed({
|
|||||||
return props.itemData.discount
|
return props.itemData.discount
|
||||||
},
|
},
|
||||||
set: (newValue) => {
|
set: (newValue) => {
|
||||||
if (props.itemData.discount_type === 'percentage') {
|
|
||||||
updateItemAttribute('discount_val', (subtotal.value * newValue) / 100)
|
|
||||||
} else {
|
|
||||||
updateItemAttribute('discount_val', Math.round(newValue * 100))
|
|
||||||
}
|
|
||||||
|
|
||||||
updateItemAttribute('discount', newValue)
|
updateItemAttribute('discount', newValue)
|
||||||
|
setDiscount()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -399,7 +395,7 @@ const v$ = useVuelidate(
|
|||||||
|
|
||||||
function updateTax(data) {
|
function updateTax(data) {
|
||||||
props.store.$patch((state) => {
|
props.store.$patch((state) => {
|
||||||
state[props.storeProp].items[props.index]['taxes'][data.index] = data.item
|
state[props.storeProp].items[props.index].taxes[data.index] = data.item
|
||||||
})
|
})
|
||||||
|
|
||||||
let lastTax = props.itemData.taxes[props.itemData.taxes.length - 1]
|
let lastTax = props.itemData.taxes[props.itemData.taxes.length - 1]
|
||||||
@ -416,6 +412,16 @@ function updateTax(data) {
|
|||||||
syncItemToStore()
|
syncItemToStore()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setDiscount() {
|
||||||
|
const newValue = props.store[props.storeProp].items[props.index].discount
|
||||||
|
|
||||||
|
if (props.itemData.discount_type === 'percentage'){
|
||||||
|
updateItemAttribute('discount_val', Math.round((subtotal.value * newValue) / 100))
|
||||||
|
}else{
|
||||||
|
updateItemAttribute('discount_val', Math.round(newValue * 100))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function searchVal(val) {
|
function searchVal(val) {
|
||||||
updateItemAttribute('name', val)
|
updateItemAttribute('name', val)
|
||||||
}
|
}
|
||||||
@ -489,6 +495,9 @@ function syncItemToStore() {
|
|||||||
totalTax: totalTax.value,
|
totalTax: totalTax.value,
|
||||||
tax: totalTax.value,
|
tax: totalTax.value,
|
||||||
taxes: [...itemTaxes],
|
taxes: [...itemTaxes],
|
||||||
|
tax_type_ids: itemTaxes.flatMap(_t =>
|
||||||
|
_t.tax_type_id ? _t.tax_type_id : [],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
props.store.updateItem(data)
|
props.store.updateItem(data)
|
||||||
|
|||||||
@ -148,7 +148,7 @@ const filteredTypes = computed(() => {
|
|||||||
const taxAmount = computed(() => {
|
const taxAmount = computed(() => {
|
||||||
if (localTax.compound_tax && props.discountedTotal) {
|
if (localTax.compound_tax && props.discountedTotal) {
|
||||||
const taxPerItemEnabled = props.store[props.storeProp].tax_per_item === 'YES'
|
const taxPerItemEnabled = props.store[props.storeProp].tax_per_item === 'YES'
|
||||||
const discountPerItemEnabled = props.store[props.storeProp].discount_per_item === 'NO'
|
const discountPerItemEnabled = props.store[props.storeProp].discount_per_item === 'YES'
|
||||||
if (taxPerItemEnabled && !discountPerItemEnabled){
|
if (taxPerItemEnabled && !discountPerItemEnabled){
|
||||||
return getTaxAmount()
|
return getTaxAmount()
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ const taxAmount = computed(() => {
|
|||||||
|
|
||||||
if (props.discountedTotal && localTax.percent) {
|
if (props.discountedTotal && localTax.percent) {
|
||||||
const taxPerItemEnabled = props.store[props.storeProp].tax_per_item === 'YES'
|
const taxPerItemEnabled = props.store[props.storeProp].tax_per_item === 'YES'
|
||||||
const discountPerItemEnabled = props.store[props.storeProp].discount_per_item === 'NO'
|
const discountPerItemEnabled = props.store[props.storeProp].discount_per_item === 'YES'
|
||||||
if (taxPerItemEnabled && !discountPerItemEnabled){
|
if (taxPerItemEnabled && !discountPerItemEnabled){
|
||||||
return getTaxAmount()
|
return getTaxAmount()
|
||||||
}
|
}
|
||||||
@ -181,6 +181,13 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => taxAmount.value,
|
||||||
|
() => {
|
||||||
|
updateRowTax()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
// Set SelectedTax
|
// Set SelectedTax
|
||||||
if (props.taxData.tax_type_id > 0) {
|
if (props.taxData.tax_type_id > 0) {
|
||||||
selectedTax.value = taxTypeStore.taxTypes.find(
|
selectedTax.value = taxTypeStore.taxTypes.find(
|
||||||
@ -230,6 +237,8 @@ function openTaxModal() {
|
|||||||
function removeTax(index) {
|
function removeTax(index) {
|
||||||
props.store.$patch((state) => {
|
props.store.$patch((state) => {
|
||||||
state[props.storeProp].items[props.itemIndex].taxes.splice(index, 1)
|
state[props.storeProp].items[props.itemIndex].taxes.splice(index, 1)
|
||||||
|
state[props.storeProp].items[props.itemIndex].tax = 0
|
||||||
|
state[props.storeProp].items[props.itemIndex].totalTax = 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +246,7 @@ function getTaxAmount() {
|
|||||||
let total = 0
|
let total = 0
|
||||||
let discount = 0
|
let discount = 0
|
||||||
const itemTotal = props.discountedTotal
|
const itemTotal = props.discountedTotal
|
||||||
const modelDiscount = props.store[props.storeProp].discount ? props.store[props.storeProp].discount.toFixed(2) : 0
|
const modelDiscount = props.store[props.storeProp].discount ? props.store[props.storeProp].discount : 0
|
||||||
const type = props.store[props.storeProp].discount_type
|
const type = props.store[props.storeProp].discount_type
|
||||||
if (modelDiscount > 0) {
|
if (modelDiscount > 0) {
|
||||||
props.store[props.storeProp].items.forEach((_i) => {
|
props.store[props.storeProp].items.forEach((_i) => {
|
||||||
|
|||||||
@ -191,7 +191,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, inject, ref } from 'vue'
|
import { computed, inject, ref, watch } from 'vue'
|
||||||
import Guid from 'guid'
|
import Guid from 'guid'
|
||||||
import Tax from './CreateTotalTaxes.vue'
|
import Tax from './CreateTotalTaxes.vue'
|
||||||
import TaxStub from '@/scripts/admin/stub/abilities'
|
import TaxStub from '@/scripts/admin/stub/abilities'
|
||||||
@ -227,17 +227,20 @@ const utils = inject('$utils')
|
|||||||
|
|
||||||
const companyStore = useCompanyStore()
|
const companyStore = useCompanyStore()
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.store[props.storeProp].items,
|
||||||
|
(val) => {
|
||||||
|
setDiscount()
|
||||||
|
}, { deep: true },
|
||||||
|
)
|
||||||
|
|
||||||
const totalDiscount = computed({
|
const totalDiscount = computed({
|
||||||
get: () => {
|
get: () => {
|
||||||
return props.store[props.storeProp].discount
|
return props.store[props.storeProp].discount
|
||||||
},
|
},
|
||||||
set: (newValue) => {
|
set: (newValue) => {
|
||||||
if (props.store[props.storeProp].discount_type === 'percentage') {
|
|
||||||
props.store[props.storeProp].discount_val = Math.round((props.store.getSubTotal * newValue.toFixed(2)) / 100)
|
|
||||||
} else {
|
|
||||||
props.store[props.storeProp].discount_val = Math.round(newValue * 100)
|
|
||||||
}
|
|
||||||
props.store[props.storeProp].discount = newValue
|
props.store[props.storeProp].discount = newValue
|
||||||
|
setDiscount()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -282,6 +285,19 @@ const defaultCurrency = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function setDiscount() {
|
||||||
|
const newValue = props.store[props.storeProp].discount
|
||||||
|
|
||||||
|
if (props.store[props.storeProp].discount_type === 'percentage') {
|
||||||
|
props.store[props.storeProp].discount_val
|
||||||
|
= Math.round((props.store.getSubTotal * newValue) / 100)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
props.store[props.storeProp].discount_val = Math.round(newValue * 100)
|
||||||
|
}
|
||||||
|
|
||||||
function selectFixed() {
|
function selectFixed() {
|
||||||
if (props.store[props.storeProp].discount_type === 'fixed') {
|
if (props.store[props.storeProp].discount_type === 'fixed') {
|
||||||
return
|
return
|
||||||
@ -293,11 +309,15 @@ function selectFixed() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function selectPercentage() {
|
function selectPercentage() {
|
||||||
if (props.store[props.storeProp].discount_type === 'percentage') {
|
if (props.store[props.storeProp].discount_type === 'percentage'){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
props.store[props.storeProp].discount_val =
|
|
||||||
(props.store.getSubTotal * props.store[props.storeProp].discount) / 100
|
const val = Math.round(props.store[props.storeProp].discount * 100) / 100
|
||||||
|
|
||||||
|
props.store[props.storeProp].discount_val
|
||||||
|
= Math.round((props.store.getSubTotal * val) / 100)
|
||||||
|
|
||||||
props.store[props.storeProp].discount_type = 'percentage'
|
props.store[props.storeProp].discount_type = 'percentage'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -138,22 +138,13 @@ export const useEstimateStore = (useWindow = false) => {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchEstimate(id) {
|
fetchEstimate(id, expand = []) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axios
|
axios
|
||||||
.get(`/api/v1/estimates/${id}`)
|
.get(`/api/v1/estimates/${id}`, { params: { expand } })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
Object.assign(this.newEstimate, response.data.data)
|
this.setEstimateData(response.data.data)
|
||||||
if (this.newEstimate.discount_per_item === 'NO') {
|
this.setCustomerAddresses(this.newEstimate.customer)
|
||||||
this.newEstimate.items.forEach((_i, index) => {
|
|
||||||
if (_i.discount_type === 'fixed')
|
|
||||||
this.newEstimate.items[index].discount = _i.discount / 100
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (this.newEstimate.discount_type === 'fixed')
|
|
||||||
this.newEstimate.discount = this.newEstimate.discount / 100
|
|
||||||
}
|
|
||||||
resolve(response)
|
resolve(response)
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@ -164,6 +155,41 @@ export const useEstimateStore = (useWindow = false) => {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setEstimateData(estimate) {
|
||||||
|
Object.assign(this.newEstimate, estimate)
|
||||||
|
if (this.newEstimate.tax_per_item === 'YES') {
|
||||||
|
this.newEstimate.items.forEach((_i) => {
|
||||||
|
if (_i.taxes && !_i.taxes.length){
|
||||||
|
_i.taxes.push({ ...taxStub, id: Guid.raw() })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (this.newEstimate.discount_per_item === 'YES') {
|
||||||
|
this.newEstimate.items.forEach((_i, index) => {
|
||||||
|
if (_i.discount_type === 'fixed'){
|
||||||
|
this.newEstimate.items[index].discount = _i.discount / 100
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.newEstimate.discount_type === 'fixed'){
|
||||||
|
this.newEstimate.discount = this.newEstimate.discount / 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setCustomerAddresses(customer) {
|
||||||
|
const customer_business = customer.customer_business
|
||||||
|
|
||||||
|
if (customer_business?.billing_address){
|
||||||
|
this.newEstimate.customer.billing_address = customer_business.billing_address
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customer_business?.shipping_address){
|
||||||
|
this.newEstimate.customer.shipping_address = customer_business.shipping_address
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
addSalesTaxUs() {
|
addSalesTaxUs() {
|
||||||
const taxTypeStore = useTaxTypeStore()
|
const taxTypeStore = useTaxTypeStore()
|
||||||
let salesTax = { ...taxStub }
|
let salesTax = { ...taxStub }
|
||||||
|
|||||||
@ -128,23 +128,14 @@ export const useInvoiceStore = (useWindow = false) => {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchInvoice(id) {
|
fetchInvoice(id, expand = []) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axios
|
axios
|
||||||
.get(`/api/v1/invoices/${id}`)
|
.get(`/api/v1/invoices/${id}`, { params: { expand } })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
Object.assign(this.newInvoice, response.data.data)
|
this.setInvoiceData(response.data.data)
|
||||||
this.newInvoice.customer = response.data.data.customer
|
|
||||||
if (this.newInvoice.discount_per_item === 'NO') {
|
this.setCustomerAddresses(this.newInvoice.customer)
|
||||||
this.newInvoice.items.forEach((_i, index) => {
|
|
||||||
if (_i.discount_type === 'fixed')
|
|
||||||
this.newInvoice.items[index].discount = _i.discount / 100
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (this.newInvoice.discount_type === 'fixed')
|
|
||||||
this.newInvoice.discount = this.newInvoice.discount / 100
|
|
||||||
}
|
|
||||||
resolve(response)
|
resolve(response)
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@ -154,6 +145,38 @@ export const useInvoiceStore = (useWindow = false) => {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setInvoiceData(invoice) {
|
||||||
|
Object.assign(this.newInvoice, invoice)
|
||||||
|
|
||||||
|
if (this.newInvoice.tax_per_item === 'YES') {
|
||||||
|
this.newInvoice.items.forEach((_i) => {
|
||||||
|
if (_i.taxes && !_i.taxes.length)
|
||||||
|
_i.taxes.push({ ...taxStub, id: Guid.raw() })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.newInvoice.discount_per_item === 'YES') {
|
||||||
|
this.newInvoice.items.forEach((_i, index) => {
|
||||||
|
if (_i.discount_type === 'fixed')
|
||||||
|
this.newInvoice.items[index].discount = _i.discount / 100
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.newInvoice.discount_type === 'fixed')
|
||||||
|
this.newInvoice.discount = this.newInvoice.discount / 100
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setCustomerAddresses(customer) {
|
||||||
|
const customer_business = customer.customer_business
|
||||||
|
|
||||||
|
if (customer_business?.billing_address)
|
||||||
|
this.newInvoice.customer.billing_address = customer_business.billing_address
|
||||||
|
|
||||||
|
if (customer_business?.shipping_address)
|
||||||
|
this.newInvoice.customer.shipping_address = customer_business.shipping_address
|
||||||
|
},
|
||||||
|
|
||||||
addSalesTaxUs() {
|
addSalesTaxUs() {
|
||||||
const taxTypeStore = useTaxTypeStore()
|
const taxTypeStore = useTaxTypeStore()
|
||||||
let salesTax = { ...taxStub }
|
let salesTax = { ...taxStub }
|
||||||
|
|||||||
@ -264,7 +264,7 @@ async function submitForm() {
|
|||||||
total: estimateStore.getTotal,
|
total: estimateStore.getTotal,
|
||||||
tax: estimateStore.getTotalTax,
|
tax: estimateStore.getTotalTax,
|
||||||
})
|
})
|
||||||
if (data.discount_per_item === 'NO') {
|
if (data.discount_per_item === 'YES') {
|
||||||
data.items.forEach((item, index) => {
|
data.items.forEach((item, index) => {
|
||||||
if (item.discount_type === 'fixed'){
|
if (item.discount_type === 'fixed'){
|
||||||
data.items[index].discount = Math.round(item.discount * 100)
|
data.items[index].discount = Math.round(item.discount * 100)
|
||||||
@ -277,6 +277,13 @@ async function submitForm() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!estimateStore.newEstimate.tax_per_item === 'YES'
|
||||||
|
&& data.taxes.length
|
||||||
|
){
|
||||||
|
data.tax_type_ids = data.taxes.map(_t => _t.tax_type_id)
|
||||||
|
}
|
||||||
|
|
||||||
const action = isEdit.value
|
const action = isEdit.value
|
||||||
? estimateStore.updateEstimate
|
? estimateStore.updateEstimate
|
||||||
: estimateStore.addEstimate
|
: estimateStore.addEstimate
|
||||||
|
|||||||
@ -265,7 +265,7 @@ async function submitForm() {
|
|||||||
total: invoiceStore.getTotal,
|
total: invoiceStore.getTotal,
|
||||||
tax: invoiceStore.getTotalTax,
|
tax: invoiceStore.getTotalTax,
|
||||||
})
|
})
|
||||||
if (data.discount_per_item === 'NO') {
|
if (data.discount_per_item === 'YES') {
|
||||||
data.items.forEach((item, index) => {
|
data.items.forEach((item, index) => {
|
||||||
if (item.discount_type === 'fixed'){
|
if (item.discount_type === 'fixed'){
|
||||||
data.items[index].discount = item.discount * 100
|
data.items[index].discount = item.discount * 100
|
||||||
@ -277,6 +277,12 @@ async function submitForm() {
|
|||||||
data.discount = data.discount * 100
|
data.discount = data.discount * 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
!invoiceStore.newInvoice.tax_per_item === 'YES'
|
||||||
|
&& data.taxes.length
|
||||||
|
){
|
||||||
|
data.tax_type_ids = data.taxes.map(_t => _t.tax_type_id)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const action = isEdit.value
|
const action = isEdit.value
|
||||||
|
|||||||
Reference in New Issue
Block a user