2022-12-14 23:59:23 -05:00
|
|
|
let Map =
|
|
|
|
https://prelude.dhall-lang.org/v21.1.0/Map/Type
|
|
|
|
sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
|
|
|
|
|
|
|
|
let CurID = Text
|
|
|
|
|
|
|
|
let AcntID = Text
|
|
|
|
|
|
|
|
let SqlConfig {- TODO pgsql -} = < Sqlite : Text | Postgres >
|
|
|
|
|
|
|
|
let Currency = { curSymbol : CurID, curFullname : Text }
|
|
|
|
|
|
|
|
let Gregorian = { gYear : Natural, gMonth : Natural, gDay : Natural }
|
|
|
|
|
|
|
|
let GregorianM = { gmYear : Natural, gmMonth : Natural }
|
|
|
|
|
2023-02-05 10:34:26 -05:00
|
|
|
let Interval = { intStart : Gregorian, intEnd : Optional Gregorian }
|
2022-12-14 23:59:23 -05:00
|
|
|
|
|
|
|
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 }
|
|
|
|
|
2023-02-09 20:01:43 -05:00
|
|
|
let MDYPat =
|
|
|
|
< Single : Natural
|
|
|
|
| Multi : List Natural
|
|
|
|
| Repeat : RepeatPat
|
|
|
|
| After : Natural
|
|
|
|
| Before : Natural
|
|
|
|
| Between : { _between1 : Natural, _between2 : Natural }
|
|
|
|
>
|
2022-12-14 23:59:23 -05:00
|
|
|
|
|
|
|
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 } >
|
|
|
|
|
2022-12-24 17:54:20 -05:00
|
|
|
let MatchOther = < Desc : Field Text Text | Val : Field Text MatchVal.Type >
|
2022-12-14 23:59:23 -05:00
|
|
|
|
|
|
|
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) ->
|
|
|
|
{ sAcnt : a, sValue : v, sCurrency : c, sComment : Text }
|
|
|
|
|
|
|
|
let ExpSplit =
|
|
|
|
{ Type = Split SplitAcnt (Optional SplitNum) SplitCur
|
|
|
|
, default = { sValue = None SplitNum, sComment = "" }
|
|
|
|
}
|
|
|
|
|
|
|
|
let ToTx =
|
|
|
|
{ ttCurrency : SplitCur
|
|
|
|
, ttPath : SplitAcnt
|
|
|
|
, ttSplit : List ExpSplit.Type
|
|
|
|
}
|
|
|
|
|
|
|
|
let Match =
|
|
|
|
{ Type =
|
|
|
|
{ mDate : Optional MatchDate
|
|
|
|
, mVal : MatchVal.Type
|
2022-12-24 17:54:20 -05:00
|
|
|
, mDesc : Optional Text
|
2022-12-14 23:59:23 -05:00
|
|
|
, mOther : List MatchOther
|
|
|
|
, mTx : Optional ToTx
|
|
|
|
, mTimes : Optional Natural
|
|
|
|
, mPriority : Integer
|
|
|
|
}
|
|
|
|
, default =
|
|
|
|
{ mDate = None MatchDate
|
|
|
|
, mVal = MatchVal::{=}
|
2022-12-24 17:54:20 -05:00
|
|
|
, mDesc = None Text
|
2022-12-14 23:59:23 -05:00
|
|
|
, 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 >
|
|
|
|
|
2023-01-30 20:13:25 -05:00
|
|
|
let ExpenseBucket = < Fixed | Investment | Savings | Guiltless >
|
2022-12-14 23:59:23 -05:00
|
|
|
|
2023-01-30 20:13:25 -05:00
|
|
|
let IncomeBucket = < PreTax | IntraTax | PostTax >
|
2022-12-14 23:59:23 -05:00
|
|
|
|
2023-01-30 20:13:25 -05:00
|
|
|
let Amount = { amtValue : Decimal, amtDesc : Text }
|
|
|
|
|
2023-02-12 16:23:32 -05:00
|
|
|
let AmountType = < FixedAmt | Percent | Target >
|
|
|
|
|
|
|
|
let TimeAmount = { taWhen : DatePat, taAmt : Amount, taAmtType : AmountType }
|
2022-12-14 23:59:23 -05:00
|
|
|
|
|
|
|
let Tax = { taxAcnt : AcntID, taxValue : Decimal }
|
|
|
|
|
2023-02-12 21:52:41 -05:00
|
|
|
let TransferTarget =
|
|
|
|
< ExpenseTarget :
|
|
|
|
{ _1xtarget :
|
|
|
|
{- this is the only place expense accounts may be specified -}
|
|
|
|
AcntID
|
|
|
|
, _2xtarget : ExpenseBucket
|
|
|
|
}
|
|
|
|
| GenericTarget : AcntID
|
|
|
|
>
|
|
|
|
|
2022-12-14 23:59:23 -05:00
|
|
|
let Allocation =
|
2023-02-12 21:52:41 -05:00
|
|
|
{ alloPath : TransferTarget
|
2023-01-30 20:13:25 -05:00
|
|
|
, alloAmts : List Amount
|
|
|
|
, alloCurrency : CurID
|
|
|
|
}
|
2023-01-29 18:04:24 -05:00
|
|
|
|
2022-12-14 23:59:23 -05:00
|
|
|
let Income =
|
|
|
|
{ incGross : Decimal
|
|
|
|
, incCurrency : CurID
|
|
|
|
, incWhen : DatePat
|
2023-02-12 21:52:41 -05:00
|
|
|
, incFrom :
|
|
|
|
{- this must be an income AcntID, and is the only place income
|
|
|
|
accounts may be specified in the entire budget -}
|
|
|
|
AcntID
|
2023-01-30 20:13:25 -05:00
|
|
|
, incPretax : List Allocation
|
2022-12-14 23:59:23 -05:00
|
|
|
, incTaxes : List Tax
|
2023-01-30 20:13:25 -05:00
|
|
|
, incPosttax : List Allocation
|
2023-02-12 21:52:41 -05:00
|
|
|
, incToBal : TransferTarget
|
2022-12-14 23:59:23 -05:00
|
|
|
}
|
|
|
|
|
2023-01-30 21:12:08 -05:00
|
|
|
let Transfer =
|
|
|
|
{ transFrom : AcntID
|
2023-02-12 21:52:41 -05:00
|
|
|
, transTo : TransferTarget
|
2023-01-30 21:12:08 -05:00
|
|
|
, transAmounts : List TimeAmount
|
|
|
|
, transCurrency : CurID
|
2022-12-14 23:59:23 -05:00
|
|
|
}
|
|
|
|
|
2023-02-13 19:57:39 -05:00
|
|
|
let ShadowMatch =
|
|
|
|
{ Type =
|
|
|
|
{ smFrom : List AcntID
|
|
|
|
, smTo : List AcntID
|
|
|
|
, smDate : Optional MatchDate
|
|
|
|
, smVal : MatchVal.Type
|
|
|
|
}
|
|
|
|
, default =
|
|
|
|
{ smFrom = [] : List AcntID
|
|
|
|
, smTo = [] : List AcntID
|
|
|
|
, smDate = None MatchDate
|
|
|
|
, smVal = MatchVal.default
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let ShadowTransfer =
|
|
|
|
{ stFrom : AcntID
|
|
|
|
, stTo : AcntID
|
|
|
|
, stCurrency : CurID
|
|
|
|
, stDesc : Text
|
|
|
|
, stMatch : ShadowMatch.Type
|
|
|
|
, stRatio : Decimal
|
|
|
|
}
|
|
|
|
|
2023-02-05 18:45:56 -05:00
|
|
|
let Budget =
|
2023-02-13 19:57:39 -05:00
|
|
|
{ budgetLabel : Text
|
|
|
|
, income : List Income
|
|
|
|
, transfers : List Transfer
|
|
|
|
, shadowTransfers : List ShadowTransfer
|
|
|
|
}
|
2022-12-14 23:59:23 -05:00
|
|
|
|
|
|
|
in { CurID
|
|
|
|
, AcntID
|
|
|
|
, SqlConfig
|
|
|
|
, Currency
|
|
|
|
, 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
|
2023-01-30 21:12:08 -05:00
|
|
|
, Transfer
|
2022-12-15 22:55:12 -05:00
|
|
|
, Income
|
2023-01-30 20:13:25 -05:00
|
|
|
, IncomeBucket
|
|
|
|
, ExpenseBucket
|
2022-12-14 23:59:23 -05:00
|
|
|
, Budget
|
|
|
|
, Tax
|
2023-01-29 18:04:24 -05:00
|
|
|
, Allocation
|
2023-01-29 18:14:00 -05:00
|
|
|
, Amount
|
|
|
|
, TimeAmount
|
2023-02-12 16:23:32 -05:00
|
|
|
, AmountType
|
2023-02-12 21:52:41 -05:00
|
|
|
, TransferTarget
|
2023-02-13 19:57:39 -05:00
|
|
|
, ShadowMatch
|
|
|
|
, ShadowTransfer
|
2022-12-14 23:59:23 -05:00
|
|
|
}
|