Added missing files
This commit is contained in:
162
frontend/composables/useTaxEvaluation.ts
Normal file
162
frontend/composables/useTaxEvaluation.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
import dayjs from "dayjs"
|
||||
import customParseFormat from "dayjs/plugin/customParseFormat"
|
||||
|
||||
dayjs.extend(customParseFormat)
|
||||
|
||||
export const TAX_EVALUATION_PERIOD_OPTIONS = [
|
||||
{ label: "Monatlich", value: "monthly" },
|
||||
{ label: "Quartalsweise", value: "quarterly" },
|
||||
{ label: "Jährlich", value: "yearly" },
|
||||
]
|
||||
|
||||
export const normalizeTaxEvaluationPeriod = (value?: string) => {
|
||||
if (value === "quarterly" || value === "yearly") return value
|
||||
return "monthly"
|
||||
}
|
||||
|
||||
const ZERO_BREAKDOWN = () => ({
|
||||
net19: 0,
|
||||
tax19: 0,
|
||||
net7: 0,
|
||||
tax7: 0,
|
||||
net0: 0,
|
||||
})
|
||||
|
||||
const isTaxFreeDocument = (taxType?: string | null) => {
|
||||
return ["13b UStG", "19 UStG", "12.3 UStG"].includes(String(taxType || ""))
|
||||
}
|
||||
|
||||
export const getTaxEvaluationPeriodBounds = (
|
||||
referenceDate: dayjs.ConfigType,
|
||||
period: string
|
||||
) => {
|
||||
const normalized = normalizeTaxEvaluationPeriod(period)
|
||||
const base = dayjs(referenceDate)
|
||||
|
||||
if (normalized === "yearly") {
|
||||
return {
|
||||
start: base.startOf("year"),
|
||||
end: base.endOf("year"),
|
||||
}
|
||||
}
|
||||
|
||||
if (normalized === "quarterly") {
|
||||
const quarterStartMonth = Math.floor(base.month() / 3) * 3
|
||||
const start = base.month(quarterStartMonth).startOf("month")
|
||||
|
||||
return {
|
||||
start,
|
||||
end: start.add(2, "month").endOf("month"),
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
start: base.startOf("month"),
|
||||
end: base.endOf("month"),
|
||||
}
|
||||
}
|
||||
|
||||
export const shiftTaxEvaluationPeriodStart = (
|
||||
periodStart: dayjs.ConfigType,
|
||||
period: string,
|
||||
offset: number
|
||||
) => {
|
||||
const normalized = normalizeTaxEvaluationPeriod(period)
|
||||
const base = dayjs(periodStart)
|
||||
|
||||
if (normalized === "yearly") return base.add(offset, "year").startOf("year")
|
||||
if (normalized === "quarterly") return base.add(offset * 3, "month").startOf("month")
|
||||
return base.add(offset, "month").startOf("month")
|
||||
}
|
||||
|
||||
export const formatTaxEvaluationPeriodLabel = (
|
||||
periodStart: dayjs.ConfigType,
|
||||
period: string
|
||||
) => {
|
||||
const { start, end } = getTaxEvaluationPeriodBounds(periodStart, period)
|
||||
const normalized = normalizeTaxEvaluationPeriod(period)
|
||||
|
||||
if (normalized === "yearly") {
|
||||
return start.format("YYYY")
|
||||
}
|
||||
|
||||
if (normalized === "quarterly") {
|
||||
return `Q${Math.floor(start.month() / 3) + 1} ${start.format("YYYY")}`
|
||||
}
|
||||
|
||||
return start.format("MMMM YYYY")
|
||||
}
|
||||
|
||||
export const formatTaxEvaluationPeriodRange = (
|
||||
periodStart: dayjs.ConfigType,
|
||||
period: string
|
||||
) => {
|
||||
const { start, end } = getTaxEvaluationPeriodBounds(periodStart, period)
|
||||
return `${start.format("DD.MM.YYYY")} - ${end.format("DD.MM.YYYY")}`
|
||||
}
|
||||
|
||||
export const getCreatedDocumentTaxBreakdown = (doc: any) => {
|
||||
const breakdown = ZERO_BREAKDOWN()
|
||||
|
||||
if (!doc || isTaxFreeDocument(doc.taxType)) {
|
||||
return breakdown
|
||||
}
|
||||
|
||||
;(doc.rows || []).forEach((row: any) => {
|
||||
if (!row || ["pagebreak", "title", "text"].includes(row.mode)) return
|
||||
|
||||
const quantity = Number(row.quantity || 0)
|
||||
const price = Number(row.price || 0)
|
||||
const discountPercent = Number(row.discountPercent || 0)
|
||||
const taxPercent = Number(row.taxPercent || 0)
|
||||
const net = Number((quantity * price * (1 - discountPercent / 100)).toFixed(2))
|
||||
|
||||
if (!Number.isFinite(net) || net === 0) return
|
||||
|
||||
if (taxPercent === 19) {
|
||||
breakdown.net19 += net
|
||||
breakdown.tax19 += Number((net * 0.19).toFixed(2))
|
||||
} else if (taxPercent === 7) {
|
||||
breakdown.net7 += net
|
||||
breakdown.tax7 += Number((net * 0.07).toFixed(2))
|
||||
} else {
|
||||
breakdown.net0 += net
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
net19: Number(breakdown.net19.toFixed(2)),
|
||||
tax19: Number(breakdown.tax19.toFixed(2)),
|
||||
net7: Number(breakdown.net7.toFixed(2)),
|
||||
tax7: Number(breakdown.tax7.toFixed(2)),
|
||||
net0: Number(breakdown.net0.toFixed(2)),
|
||||
}
|
||||
}
|
||||
|
||||
export const getIncomingInvoiceTaxBreakdown = (invoice: any) => {
|
||||
const breakdown = ZERO_BREAKDOWN()
|
||||
|
||||
;(invoice?.accounts || []).forEach((account: any) => {
|
||||
const taxType = String(account?.taxType || "")
|
||||
const amountNet = Number(account?.amountNet || 0)
|
||||
const amountTax = Number(account?.amountTax || 0)
|
||||
|
||||
if (taxType === "19") {
|
||||
breakdown.net19 += amountNet
|
||||
breakdown.tax19 += amountTax
|
||||
} else if (taxType === "7") {
|
||||
breakdown.net7 += amountNet
|
||||
breakdown.tax7 += amountTax
|
||||
} else {
|
||||
breakdown.net0 += amountNet
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
net19: Number(breakdown.net19.toFixed(2)),
|
||||
tax19: Number(breakdown.tax19.toFixed(2)),
|
||||
net7: Number(breakdown.net7.toFixed(2)),
|
||||
tax7: Number(breakdown.tax7.toFixed(2)),
|
||||
net0: Number(breakdown.net0.toFixed(2)),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user