330 lines
7.6 KiB
Plaintext
330 lines
7.6 KiB
Plaintext
let Map =
|
|
https://prelude.dhall-lang.org/v21.1.0/Map/Type
|
|
sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
|
|
|
|
let CurID = Text
|
|
|
|
let AcntID = Text
|
|
|
|
let TagID = Text
|
|
|
|
let SqlConfig {- TODO pgsql -} = < Sqlite : Text | Postgres >
|
|
|
|
let Currency = { curSymbol : CurID, curFullname : Text }
|
|
|
|
let Tag = { tagID : TagID, tagDesc : Text }
|
|
|
|
let Gregorian = { gYear : Natural, gMonth : Natural, gDay : Natural }
|
|
|
|
let GregorianM = { gmYear : Natural, gmMonth : Natural }
|
|
|
|
let Interval = { intStart : Gregorian, intEnd : Optional Gregorian }
|
|
|
|
let Global = { budgetInterval : Interval, statementInterval : Interval }
|
|
|
|
let TimeUnit = < Day | Week | Month | Year >
|
|
|
|
let Weekday = < Mon | Tue | Wed | Thu | Fri | Sat | Sun >
|
|
|
|
let RepeatPat =
|
|
{ rpStart : Natural, rpBy : Natural, rpRepeats : Optional Natural }
|
|
|
|
let MDYPat =
|
|
< Single : Natural
|
|
| Multi : List Natural
|
|
| Repeat : RepeatPat
|
|
| After : Natural
|
|
| Before : Natural
|
|
| Between : { _between1 : Natural, _between2 : Natural }
|
|
>
|
|
|
|
let ModPat =
|
|
{ Type =
|
|
{ mpStart : Optional Gregorian
|
|
, mpBy : Natural
|
|
, mpUnit : TimeUnit
|
|
, mpRepeats : Optional Natural
|
|
}
|
|
, default = { mpStart = None Gregorian, mpRepeats = None Natural }
|
|
}
|
|
|
|
let WeekdayPat = < OnDay : Weekday | OnDays : List Weekday >
|
|
|
|
let CronPat =
|
|
{ Type =
|
|
{ cronWeekly : Optional WeekdayPat
|
|
, cronYear : Optional MDYPat
|
|
, cronMonth : Optional MDYPat
|
|
, cronDay : Optional MDYPat
|
|
}
|
|
, default =
|
|
{ cronWeekly = None WeekdayPat
|
|
, cronYear = None MDYPat
|
|
, cronMonth = None MDYPat
|
|
, cronDay = None MDYPat
|
|
}
|
|
}
|
|
|
|
let DatePat = < Cron : CronPat.Type | Mod : ModPat.Type >
|
|
|
|
let Decimal =
|
|
{ whole : Natural, decimal : Natural, precision : Natural, sign : Bool }
|
|
|
|
let TxOpts =
|
|
{ Type =
|
|
{ toDate : Text
|
|
, toAmount : Text
|
|
, toDesc : Text
|
|
, toOther : List Text
|
|
, toDateFmt : Text
|
|
, toAmountFmt : Text
|
|
}
|
|
, default =
|
|
{ toDate = "Date"
|
|
, toAmount = "Amount"
|
|
, toDesc = "Description"
|
|
, toOther = [] : List Text
|
|
, toDateFmt = "%0m/%0d/%Y"
|
|
, toAmountFmt = "([-+])?([0-9]+)\\.?([0-9]+)?"
|
|
}
|
|
}
|
|
|
|
let Field = \(k : Type) -> \(v : Type) -> { fKey : k, fVal : v }
|
|
|
|
let FieldMap = \(k : Type) -> \(v : Type) -> Field k (Map k v)
|
|
|
|
let MatchVal =
|
|
{ Type =
|
|
{ mvSign : Optional Bool
|
|
, mvNum : Optional Natural
|
|
, mvDen : Optional Natural
|
|
, mvPrec : Natural
|
|
}
|
|
, default =
|
|
{ mvSign = None Bool
|
|
, mvNum = None Natural
|
|
, mvDen = None Natural
|
|
, mvPrec = 2
|
|
}
|
|
}
|
|
|
|
let MatchYMD = < Y : Natural | YM : GregorianM | YMD : Gregorian >
|
|
|
|
let MatchDate = < On : MatchYMD | In : { _1 : MatchYMD, _2 : Natural } >
|
|
|
|
let MatchOther = < Desc : Field Text Text | Val : Field Text MatchVal.Type >
|
|
|
|
let SplitNum = < LookupN : Text | ConstN : Decimal | AmountN >
|
|
|
|
let SplitText =
|
|
\(t : Type) ->
|
|
< ConstT : t
|
|
| LookupT : Text
|
|
| MapT : FieldMap Text t
|
|
| Map2T : FieldMap { _1 : Text, _2 : Text } t
|
|
>
|
|
|
|
let SplitCur = SplitText CurID
|
|
|
|
let SplitAcnt = SplitText AcntID
|
|
|
|
let Split =
|
|
\(a : Type) ->
|
|
\(v : Type) ->
|
|
\(c : Type) ->
|
|
\(t : Type) ->
|
|
{ sAcnt : a
|
|
, sValue : v
|
|
, sCurrency : c
|
|
, sComment : Text
|
|
, sTags : List t
|
|
}
|
|
|
|
let ExpSplit =
|
|
{ Type = Split SplitAcnt (Optional SplitNum) SplitCur TagID
|
|
, default = { sValue = None SplitNum, sComment = "" }
|
|
}
|
|
|
|
let ToTx =
|
|
{ ttCurrency : SplitCur
|
|
, ttPath : SplitAcnt
|
|
, ttSplit : List ExpSplit.Type
|
|
}
|
|
|
|
let Match =
|
|
{ Type =
|
|
{ mDate : Optional MatchDate
|
|
, mVal : MatchVal.Type
|
|
, mDesc : Optional Text
|
|
, mOther : List MatchOther
|
|
, mTx : Optional ToTx
|
|
, mTimes : Optional Natural
|
|
, mPriority : Integer
|
|
}
|
|
, default =
|
|
{ mDate = None MatchDate
|
|
, mVal = MatchVal::{=}
|
|
, mDesc = None Text
|
|
, mOther = [] : List MatchOther
|
|
, mTx = None ToTx
|
|
, mTimes = None Natural
|
|
, mPriority = +0
|
|
}
|
|
}
|
|
|
|
let Manual =
|
|
{ manualDate : DatePat
|
|
, manualFrom : AcntID
|
|
, manualTo : AcntID
|
|
, manualValue : Decimal
|
|
, manualDesc : Text
|
|
, manualCurrency : CurID
|
|
}
|
|
|
|
let Import =
|
|
{ impPaths : List Text
|
|
, impMatches : List Match.Type
|
|
, impDelim : Natural
|
|
, impTxOpts : TxOpts.Type
|
|
, impSkipLines : Natural
|
|
}
|
|
|
|
let Statement = < StmtManual : Manual | StmtImport : Import >
|
|
|
|
let Amount = { amtValue : Decimal, amtDesc : Text }
|
|
|
|
let AmountType = < FixedAmt | Percent | Target >
|
|
|
|
let TimeAmount =
|
|
\(t : Type) -> { taWhen : t, taAmt : Amount, taAmtType : AmountType }
|
|
|
|
let DateAmount = TimeAmount DatePat
|
|
|
|
let Exchange =
|
|
{ xFromCur : CurID, xToCur : CurID, xAcnt : AcntID, xRate : Decimal }
|
|
|
|
let BudgetCurrency = < NoX : CurID | X : Exchange >
|
|
|
|
let TaggedAcnt = { taAcnt : AcntID, taTags : List TagID }
|
|
|
|
let Allocation_ =
|
|
\(t : Type) ->
|
|
{ alloTo : TaggedAcnt, alloAmts : List t, alloCur : BudgetCurrency }
|
|
|
|
let Allocation = Allocation_ Amount
|
|
|
|
let IntervalAllocation = Allocation_ (TimeAmount Interval)
|
|
|
|
let Income =
|
|
{ incGross : Decimal
|
|
, incCurrency : CurID
|
|
, incWhen : DatePat
|
|
, incPretax : List Allocation
|
|
, incTaxes : List Allocation
|
|
, incPosttax : List Allocation
|
|
, incFrom :
|
|
{- this must be an income AcntID, and is the only place income
|
|
accounts may be specified in the entire budget -}
|
|
TaggedAcnt
|
|
, incToBal : TaggedAcnt
|
|
}
|
|
|
|
let Transfer =
|
|
{ transFrom : TaggedAcnt
|
|
, transTo : TaggedAcnt
|
|
, transAmounts : List DateAmount
|
|
, transCurrency : BudgetCurrency
|
|
}
|
|
|
|
let AcntSet =
|
|
{ Type = { asList : List AcntID, asInclude : Bool }
|
|
, default = { asList = [] : List AcntID, asInclude = False }
|
|
}
|
|
|
|
let ShadowMatch =
|
|
{ Type =
|
|
{ smFrom : AcntSet.Type
|
|
, smTo : AcntSet.Type
|
|
, smDate : Optional MatchDate
|
|
, smVal : MatchVal.Type
|
|
}
|
|
, default =
|
|
{ smFrom = AcntSet.default
|
|
, smTo = AcntSet.default
|
|
, smDate = None MatchDate
|
|
, smVal = MatchVal.default
|
|
}
|
|
}
|
|
|
|
let ShadowTransfer =
|
|
{ stFrom : TaggedAcnt
|
|
, stTo : TaggedAcnt
|
|
, stCurrency : CurID
|
|
, stDesc : Text
|
|
, stMatch : ShadowMatch.Type
|
|
, stRatio : Decimal
|
|
}
|
|
|
|
let Budget =
|
|
{ budgetLabel : Text
|
|
, incomes : List Income
|
|
, pretax : List IntervalAllocation
|
|
, tax : List IntervalAllocation
|
|
, posttax : List IntervalAllocation
|
|
, transfers : List Transfer
|
|
, shadowTransfers : List ShadowTransfer
|
|
}
|
|
|
|
in { CurID
|
|
, AcntID
|
|
, SqlConfig
|
|
, Currency
|
|
, Tag
|
|
, TagID
|
|
, Interval
|
|
, Global
|
|
, Gregorian
|
|
, GregorianM
|
|
, TimeUnit
|
|
, Weekday
|
|
, RepeatPat
|
|
, MDYPat
|
|
, ModPat
|
|
, WeekdayPat
|
|
, CronPat
|
|
, DatePat
|
|
, Decimal
|
|
, TxOpts
|
|
, Match
|
|
, MatchVal
|
|
, MatchYMD
|
|
, MatchDate
|
|
, MatchOther
|
|
, SplitNum
|
|
, Field
|
|
, FieldMap
|
|
, Split
|
|
, ExpSplit
|
|
, SplitText
|
|
, SplitCur
|
|
, SplitAcnt
|
|
, ToTx
|
|
, Import
|
|
, Manual
|
|
, Statement
|
|
, Transfer
|
|
, Income
|
|
, Budget
|
|
, Allocation
|
|
, IntervalAllocation
|
|
, Amount
|
|
, TimeAmount
|
|
, AmountType
|
|
, ShadowMatch
|
|
, ShadowTransfer
|
|
, AcntSet
|
|
, BudgetCurrency
|
|
, Exchange
|
|
, TaggedAcnt
|
|
}
|