mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-04-07 13:41:23 +00:00
Tax calculation issue (#38)
* fix initial tax per item issue * remove commit in estimate storage * add changes in tax per item calculation * add validation on requests * fix minimum total issue * fix table pagination filter issue * minor fix * remove compound interest and remove unused code --------- Co-authored-by: yashkanakiya <yashkanakiya281297@gmail.com> Co-authored-by: dhruvbhattt <dhruvbhatt7790@gmail.com> Co-authored-by: gdarko <dg@darkog.com>
This commit is contained in:
committed by
GitHub
parent
0d006846d5
commit
8788f3d504
@@ -271,23 +271,19 @@ const price = computed({
|
||||
} else {
|
||||
updateItemAttribute('price', newValue)
|
||||
}
|
||||
setDiscount()
|
||||
},
|
||||
})
|
||||
|
||||
const subtotal = computed(() => props.itemData.price * props.itemData.quantity)
|
||||
const subtotal = computed(() => Math.round(props.itemData.price * props.itemData.quantity))
|
||||
|
||||
const discount = computed({
|
||||
get: () => {
|
||||
return props.itemData.discount
|
||||
},
|
||||
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)
|
||||
setDiscount()
|
||||
},
|
||||
})
|
||||
|
||||
@@ -313,7 +309,7 @@ const showRemoveButton = computed(() => {
|
||||
const totalSimpleTax = computed(() => {
|
||||
return Math.round(
|
||||
sumBy(props.itemData.taxes, function (tax) {
|
||||
if (!tax.compound_tax) {
|
||||
if (tax.amount) {
|
||||
return tax.amount
|
||||
}
|
||||
return 0
|
||||
@@ -321,18 +317,7 @@ const totalSimpleTax = computed(() => {
|
||||
)
|
||||
})
|
||||
|
||||
const totalCompoundTax = computed(() => {
|
||||
return Math.round(
|
||||
sumBy(props.itemData.taxes, function (tax) {
|
||||
if (tax.compound_tax) {
|
||||
return tax.amount
|
||||
}
|
||||
return 0
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
const totalTax = computed(() => totalSimpleTax.value + totalCompoundTax.value)
|
||||
const totalTax = computed(() => totalSimpleTax.value)
|
||||
|
||||
const rules = {
|
||||
name: {
|
||||
@@ -399,7 +384,7 @@ const v$ = useVuelidate(
|
||||
|
||||
function updateTax(data) {
|
||||
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]
|
||||
@@ -416,6 +401,16 @@ function updateTax(data) {
|
||||
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) {
|
||||
updateItemAttribute('name', val)
|
||||
}
|
||||
@@ -485,10 +480,12 @@ function syncItemToStore() {
|
||||
total: total.value,
|
||||
sub_total: subtotal.value,
|
||||
totalSimpleTax: totalSimpleTax.value,
|
||||
totalCompoundTax: totalCompoundTax.value,
|
||||
totalTax: totalTax.value,
|
||||
tax: totalTax.value,
|
||||
taxes: [...itemTaxes],
|
||||
tax_type_ids: itemTaxes.flatMap(_t =>
|
||||
_t.tax_type_id ? _t.tax_type_id : [],
|
||||
),
|
||||
}
|
||||
|
||||
props.store.updateItem(data)
|
||||
|
||||
@@ -146,14 +146,14 @@ const filteredTypes = computed(() => {
|
||||
})
|
||||
|
||||
const taxAmount = computed(() => {
|
||||
if (localTax.compound_tax && props.discountedTotal) {
|
||||
return ((props.discountedTotal + props.totalTax) * localTax.percent) / 100
|
||||
}
|
||||
|
||||
if (props.discountedTotal && localTax.percent) {
|
||||
const taxPerItemEnabled = props.store[props.storeProp].tax_per_item === 'YES'
|
||||
const discountPerItemEnabled = props.store[props.storeProp].discount_per_item === 'YES'
|
||||
if (taxPerItemEnabled && !discountPerItemEnabled){
|
||||
return getTaxAmount()
|
||||
}
|
||||
return (props.discountedTotal * localTax.percent) / 100
|
||||
}
|
||||
|
||||
return 0
|
||||
})
|
||||
|
||||
@@ -171,6 +171,13 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => taxAmount.value,
|
||||
() => {
|
||||
updateRowTax()
|
||||
},
|
||||
)
|
||||
|
||||
// Set SelectedTax
|
||||
if (props.taxData.tax_type_id > 0) {
|
||||
selectedTax.value = taxTypeStore.taxTypes.find(
|
||||
@@ -183,7 +190,6 @@ updateRowTax()
|
||||
function onSelectTax(val) {
|
||||
localTax.percent = val.percent
|
||||
localTax.tax_type_id = val.id
|
||||
localTax.compound_tax = val.compound_tax
|
||||
localTax.name = val.name
|
||||
|
||||
updateRowTax()
|
||||
@@ -220,6 +226,27 @@ function openTaxModal() {
|
||||
function removeTax(index) {
|
||||
props.store.$patch((state) => {
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
function getTaxAmount() {
|
||||
let total = 0
|
||||
let discount = 0
|
||||
const itemTotal = props.discountedTotal
|
||||
const modelDiscount = props.store[props.storeProp].discount ? props.store[props.storeProp].discount : 0
|
||||
const type = props.store[props.storeProp].discount_type
|
||||
if (modelDiscount > 0) {
|
||||
props.store[props.storeProp].items.forEach((_i) => {
|
||||
total += _i.total
|
||||
})
|
||||
const proportion = (itemTotal / total).toFixed(2)
|
||||
discount = type === 'fixed' ? modelDiscount * 100 : (total * modelDiscount) / 100
|
||||
const itemDiscount = Math.round(discount * proportion)
|
||||
const discounted = itemTotal - itemDiscount
|
||||
return Math.round((discounted * localTax.percent) / 100)
|
||||
}
|
||||
return Math.round((props.discountedTotal * localTax.percent) / 100)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, inject, ref } from 'vue'
|
||||
import { computed, inject, ref, watch } from 'vue'
|
||||
import Guid from 'guid'
|
||||
import Tax from './CreateTotalTaxes.vue'
|
||||
import TaxStub from '@/scripts/admin/stub/abilities'
|
||||
@@ -227,19 +227,20 @@ const utils = inject('$utils')
|
||||
|
||||
const companyStore = useCompanyStore()
|
||||
|
||||
watch(
|
||||
() => props.store[props.storeProp].items,
|
||||
(val) => {
|
||||
setDiscount()
|
||||
}, { deep: true },
|
||||
)
|
||||
|
||||
const totalDiscount = computed({
|
||||
get: () => {
|
||||
return props.store[props.storeProp].discount
|
||||
},
|
||||
set: (newValue) => {
|
||||
if (props.store[props.storeProp].discount_type === 'percentage') {
|
||||
props.store[props.storeProp].discount_val = Math.round(
|
||||
(props.store.getSubTotal * newValue) / 100
|
||||
)
|
||||
} else {
|
||||
props.store[props.storeProp].discount_val = Math.round(newValue * 100)
|
||||
}
|
||||
props.store[props.storeProp].discount = newValue
|
||||
setDiscount()
|
||||
},
|
||||
})
|
||||
|
||||
@@ -265,7 +266,7 @@ const itemWiseTaxes = computed(() => {
|
||||
} else if (tax.tax_type_id) {
|
||||
taxes.push({
|
||||
tax_type_id: tax.tax_type_id,
|
||||
amount: tax.amount,
|
||||
amount: Math.round(tax.amount),
|
||||
percent: tax.percent,
|
||||
name: tax.name,
|
||||
})
|
||||
@@ -284,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() {
|
||||
if (props.store[props.storeProp].discount_type === 'fixed') {
|
||||
return
|
||||
@@ -295,24 +309,21 @@ function selectFixed() {
|
||||
}
|
||||
|
||||
function selectPercentage() {
|
||||
if (props.store[props.storeProp].discount_type === 'percentage') {
|
||||
if (props.store[props.storeProp].discount_type === 'percentage'){
|
||||
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'
|
||||
}
|
||||
|
||||
function onSelectTax(selectedTax) {
|
||||
let amount = 0
|
||||
|
||||
if (selectedTax.compound_tax && props.store.getSubtotalWithDiscount) {
|
||||
amount = Math.round(
|
||||
((props.store.getSubtotalWithDiscount + props.store.getTotalSimpleTax) *
|
||||
selectedTax.percent) /
|
||||
100
|
||||
)
|
||||
} else if (props.store.getSubtotalWithDiscount && selectedTax.percent) {
|
||||
if (props.store.getSubtotalWithDiscount && selectedTax.percent) {
|
||||
amount = Math.round(
|
||||
(props.store.getSubtotalWithDiscount * selectedTax.percent) / 100
|
||||
)
|
||||
@@ -323,7 +334,6 @@ function onSelectTax(selectedTax) {
|
||||
id: Guid.raw(),
|
||||
name: selectedTax.name,
|
||||
percent: selectedTax.percent,
|
||||
compound_tax: selectedTax.compound_tax,
|
||||
tax_type_id: selectedTax.id,
|
||||
amount,
|
||||
}
|
||||
|
||||
@@ -77,17 +77,6 @@
|
||||
@input="v$.currentTaxType.description.$touch()"
|
||||
/>
|
||||
</BaseInputGroup>
|
||||
|
||||
<BaseInputGroup
|
||||
:label="$t('tax_types.compound_tax')"
|
||||
variant="horizontal"
|
||||
class="flex flex-row-reverse"
|
||||
>
|
||||
<BaseSwitch
|
||||
v-model="taxTypeStore.currentTaxType.compound_tax"
|
||||
class="flex items-center"
|
||||
/>
|
||||
</BaseInputGroup>
|
||||
</BaseInputGrid>
|
||||
</div>
|
||||
<div
|
||||
@@ -209,14 +198,7 @@ async function submitTaxTypeData() {
|
||||
|
||||
function SelectTax(taxData) {
|
||||
let amount = 0
|
||||
if (taxData.compound_tax && estimateStore.getSubtotalWithDiscount) {
|
||||
amount = Math.round(
|
||||
((estimateStore.getSubtotalWithDiscount +
|
||||
estimateStore.getTotalSimpleTax) *
|
||||
taxData.percent) /
|
||||
100
|
||||
)
|
||||
} else if (estimateStore.getSubtotalWithDiscount && taxData.percent) {
|
||||
if (estimateStore.getSubtotalWithDiscount && taxData.percent) {
|
||||
amount = Math.round(
|
||||
(estimateStore.getSubtotalWithDiscount * taxData.percent) / 100
|
||||
)
|
||||
@@ -226,7 +208,6 @@ function SelectTax(taxData) {
|
||||
id: Guid.raw(),
|
||||
name: taxData.name,
|
||||
percent: taxData.percent,
|
||||
compound_tax: taxData.compound_tax,
|
||||
tax_type_id: taxData.id,
|
||||
amount,
|
||||
}
|
||||
@@ -242,7 +223,6 @@ function selectItemTax(taxData) {
|
||||
id: Guid.raw(),
|
||||
name: taxData.name,
|
||||
percent: taxData.percent,
|
||||
compound_tax: taxData.compound_tax,
|
||||
tax_type_id: taxData.id,
|
||||
}
|
||||
modalStore.refreshData(data)
|
||||
|
||||
Reference in New Issue
Block a user