module HAX.Germany.Gewerbe where
import HAX.Accounting
import HAX.Bookkeeping
import HAX.Common
import Control.Monad.Reader
import HAX.Germany.Subjekte
class Gewerbetreibender gt where
gwStFreibetrag :: gt -> Amount
gewerbeGewinn :: AccountingReadOnly (Gewerbe gt) Amount
type AccGW treib l w = Acc (Gewerbe treib) l w
type BetragGW treib l w = Acc (Gewerbe treib) l w Amount
type AccGWRW treib = AccountingRW (Gewerbe treib)
type BetragGWRW treib = AccountingRW (Gewerbe treib) Amount
type AccGWRO treib = AccountingReadOnly (Gewerbe treib)
type BetragGWRO treib = AccountingReadOnly (Gewerbe treib) Amount
sonstigerUeberschuss = "jUeb"
mieteUnbeweglich = "MiU"
mieteBeweglich = "MiB"
schuldZinsen = "Zins"
jahresErgebnis = "jErg"
gewerbeAccounts = [jahresErgebnis] ++ gewerbeErgebnisAccounts
gewerbeErgebnisAccounts = [sonstigerUeberschuss
, mieteUnbeweglich
, mieteBeweglich
, schuldZinsen
]
jahresErgebnis' = sum <$> mapM haben gewerbeErgebnisAccounts
data GewerbeSteuer = GWSt { gwGewinn :: Amount
, gwMessbetrag :: Amount
, gwSteuer :: Amount
}
instance Show GewerbeSteuer where
show (GWSt g m s) = printf "GWSt {gwGewinn = %v, gwMessbetrag = %v, gwSteuer = %v}"
g m s
keineGewerbeSteuer = GWSt 0 0 0
gwMesszahl = 0.035
gewerbeErtrag :: Gewerbetreibender treib => Amount -> BetragGWRO treib
gewerbeErtrag gewinn = singleResult "Gewerbeertrag" $ withBody $ \g -> do
ertrag <- return gewinn
+ hinzuRechnungen
kuerzungen
abrundenAuf100 <$> nachVerlustAbzug "GewSt" ertrag
abrundenAuf100 x = fromInteger $(100*) $ floor $ x/100
hinzuRechnungen :: BetragGWRO treib
hinzuRechnungen = singleResult "Hinzurechnungen" $ do
summe <- soll schuldZinsen
+ 0.5 * soll mieteUnbeweglich
+ 0.2 * soll mieteBeweglich
return $ 0.25 * positivePart (summe 100000)
kuerzungen :: BetragGWRO treib
kuerzungen = return 0
gewerbeSteuer :: Gewerbetreibender treib => AccGWRW treib GewerbeSteuer
gewerbeSteuer = withBody $ \g -> do
gewinn <- fixed gewerbeGewinn
ertrag <- fixed $ gewerbeErtrag gewinn
let verbleibenderErtrag = ertrag min (positivePart ertrag)
(gwStFreibetrag $ gwTreibender g)
result = GWSt gewinn (positivePart $ gwMesszahl * verbleibenderErtrag)
$ gwMessbetrag result * (gwHebesatz g)
logLedger $ printf "%v\n" (show result)
closingTx gewerbeErgebnisAccounts $ BalancingTx "Gewerbesteuer"
jahresErgebnis [(giroKonto, negate $ gwSteuer result)]
return result
runGewerbe :: Gewerbetreibender treib => AccGWRW treib a
-> Gewerbe treib
-> AccountingRW treib a
runGewerbe f gewerbe = withRWT (\e -> e{eBody=gewerbe}) f
lohnKostenMtl :: AccGWRW treib ()
lohnKostenMtl = withBody $ \g -> do
let lohn p = let gehalt = pBruttoGehaltMtl p in
gehalt + when' (pVersicherungsPflicht p)
(gehalt * (0.073
+ 0.0945
+ 0.01025
+ 0.015
+ 0.016
+ 0.0015
))
kosten = sum $ lohn <$> gwAngestellte g
fromTo kosten "Lohnkosten" giroKonto sonstigerUeberschuss
gewerbeMonatlich :: AccGWRW treib ()
gewerbeMonatlich = withBody $ \g -> do
lohnKostenMtl
autoGewerbeMtl
fromTo (gwMonatlMietkosten g) "Miete" giroKonto mieteUnbeweglich
autoGewerbeMtl :: AccGWRW treib ()
autoGewerbeMtl = withBody $ \g ->
let k = kostenAutoMonatl <$> gwWaegen g in
tx $ BalancingTx "Autokosten" giroKonto
[(mieteBeweglich,sum $ akGewerbeLeasing <$> k)
,(sonstigerUeberschuss,sum $ akGewerbe <$> k)]