Skip to content

Commit

Permalink
Tax calculation issue (InvoiceShelf#38)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
4 people committed Feb 18, 2024
1 parent 0d00684 commit 8788f3d
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 96 deletions.
8 changes: 8 additions & 0 deletions app/Http/Requests/EstimatesRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,21 @@ public function rules()
'nullable',
],
'discount' => [
'numeric',
'required',
],
'discount_val' => [
'integer',
'required',
],
'sub_total' => [
'integer',
'required',
],
'total' => [
'integer',
'numeric',
'max:99999999',
'required',
],
'tax' => [
Expand All @@ -77,9 +83,11 @@ public function rules()
'required',
],
'items.*.quantity' => [
'integer',
'required',
],
'items.*.price' => [
'integer',
'required',
],
];
Expand Down
8 changes: 8 additions & 0 deletions app/Http/Requests/InvoicesRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,21 @@ public function rules()
'nullable',
],
'discount' => [
'numeric',
'required',
],
'discount_val' => [
'integer',
'required',
],
'sub_total' => [
'integer',
'required',
],
'total' => [
'integer',
'numeric',
'max:99999999',
'required',
],
'tax' => [
Expand All @@ -77,9 +83,11 @@ public function rules()
'required',
],
'items.*.quantity' => [
'integer',
'required',
],
'items.*.price' => [
'integer',
'required',
],
];
Expand Down
6 changes: 6 additions & 0 deletions app/Http/Requests/RecurringInvoiceRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,21 @@ public function rules()
'nullable',
],
'discount' => [
'numeric',
'required',
],
'discount_val' => [
'integer',
'required',
],
'sub_total' => [
'integer',
'required',
],
'total' => [
'integer',
'numeric',
'max:99999999',
'required',
],
'tax' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
},
})
Expand All @@ -313,26 +309,15 @@ 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
})
)
})
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: {
Expand Down Expand Up @@ -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]
Expand All @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
Expand All @@ -171,6 +171,13 @@ watch(
}
)
watch(
() => taxAmount.value,
() => {
updateRowTax()
},
)
// Set SelectedTax
if (props.taxData.tax_type_id > 0) {
selectedTax.value = taxTypeStore.taxTypes.find(
Expand All @@ -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()
Expand Down Expand Up @@ -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>
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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()
},
})
Expand All @@ -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,
})
Expand All @@ -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
Expand All @@ -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
)
Expand All @@ -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,
}
Expand Down
Loading

0 comments on commit 8788f3d

Please sign in to comment.