Compare commits

...

10 Commits

Author SHA1 Message Date
Simon Michael
f02a4b7359 fix: web: add form's typeahead now shows non-ascii text correctly (#1961)
Some checks failed
binaries-windows-x64 / build (push) Has been cancelled
binaries-mac-x64 / build (map[ghc:92 stack:stack --stack-yaml=stack.yaml]) (push) Has been cancelled
(Fix contributed by Arsen Arsenović)
2025-10-14 11:40:42 +03:00
f81cc8a5fe Translate to Finnish 2025-10-14 11:40:42 +03:00
Simon Michael
aa327b7a4b ;cabal: update cabal files 2022-09-18 08:57:59 -10:00
Simon Michael
c679d184a9 ;pkg: bump version to 1.27.1 2022-09-18 08:57:59 -10:00
Simon Michael
e250b03cc0 install: 1.27.1 2022-09-18 08:51:14 -10:00
Simon Michael
06989eb867 dev: cli: tests: fix fragile abbreviation 2022-09-18 08:37:31 -10:00
Simon Michael
fc858d1159 fix: balcmds: fix empty html columns fix (#1933) 2022-09-18 08:37:28 -10:00
Simon Michael
0c179c7e28 dev: lib: ReportTypes: hlint fix 2022-09-18 08:37:26 -10:00
Simon Michael
7102d6f9e8 fix: balcmds: handle an empty totals column in html output (#1933) 2022-09-18 08:37:20 -10:00
Simon Michael
1d191d13ae dev: cli: update balance.test to v3 format 2022-09-18 08:37:18 -10:00
40 changed files with 245 additions and 230 deletions

View File

@ -1 +1 @@
1.27 1.27.1

View File

@ -46,7 +46,7 @@ HERE
HLEDGER_INSTALL_TOOL=hledger-install.sh HLEDGER_INSTALL_TOOL=hledger-install.sh
# this script's version # this script's version
HLEDGER_INSTALL_VERSION=20220901 HLEDGER_INSTALL_VERSION=20220918
# stackage snapshot to use when installing with stack. # stackage snapshot to use when installing with stack.
# You can try specifying a different stackage version here, or # You can try specifying a different stackage version here, or
@ -70,10 +70,10 @@ hledger-stockquotes \
# Latest hledger package versions. # Latest hledger package versions.
# Don't forget to also bump HLEDGER_INSTALL_VERSION above. # Don't forget to also bump HLEDGER_INSTALL_VERSION above.
HLEDGER_LIB_VERSION=1.27 HLEDGER_LIB_VERSION=1.27.1
HLEDGER_VERSION=1.27 HLEDGER_VERSION=1.27.1
HLEDGER_UI_VERSION=1.27 HLEDGER_UI_VERSION=1.27.1
HLEDGER_WEB_VERSION=1.27 HLEDGER_WEB_VERSION=1.27.1
# addons: # addons:
HLEDGER_IADD_VERSION=1.3.17 HLEDGER_IADD_VERSION=1.3.17
HLEDGER_INTEREST_VERSION=1.6.4 HLEDGER_INTEREST_VERSION=1.6.4

View File

@ -1 +1 @@
1.27 1.27.1

View File

@ -1,2 +1,2 @@
m4_dnl Version number to show in manuals. Updated by "Shake setversion" m4_dnl Version number to show in manuals. Updated by "Shake setversion"
m4_define({{_version_}}, {{1.27}})m4_dnl m4_define({{_version_}}, {{1.27.1}})m4_dnl

View File

@ -89,7 +89,7 @@ data PeriodicReport a b =
} deriving (Show, Functor, Generic, ToJSON) } deriving (Show, Functor, Generic, ToJSON)
instance Bifunctor PeriodicReport where instance Bifunctor PeriodicReport where
bimap f g pr = pr{prRows = map (bimap f g) $ prRows pr, prTotals = fmap g $ prTotals pr} bimap f g pr = pr{prRows = map (bimap f g) $ prRows pr, prTotals = g <$> prTotals pr}
data PeriodicReportRow a b = data PeriodicReportRow a b =
PeriodicReportRow PeriodicReportRow

View File

@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
name: hledger-lib name: hledger-lib
version: 1.27 version: 1.27.1
synopsis: A reusable library providing the core functionality of hledger synopsis: A reusable library providing the core functionality of hledger
description: A reusable library containing hledger's core functionality. description: A reusable library containing hledger's core functionality.
This is used by most hledger* packages so that they support the same This is used by most hledger* packages so that they support the same

View File

@ -1,5 +1,5 @@
name: hledger-lib name: hledger-lib
version: 1.27 version: 1.27.1
synopsis: A reusable library providing the core functionality of hledger synopsis: A reusable library providing the core functionality of hledger
description: | description: |
A reusable library containing hledger's core functionality. A reusable library containing hledger's core functionality.

View File

@ -1 +1 @@
1.27 1.27.1

View File

@ -1,2 +1,2 @@
m4_dnl Version number to show in manuals. Updated by "Shake setversion" m4_dnl Version number to show in manuals. Updated by "Shake setversion"
m4_define({{_version_}}, {{1.27}})m4_dnl m4_define({{_version_}}, {{1.27.1}})m4_dnl

View File

@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
name: hledger-ui name: hledger-ui
version: 1.27 version: 1.27.1
synopsis: Curses-style terminal interface for the hledger accounting system synopsis: Curses-style terminal interface for the hledger accounting system
description: A simple curses-style terminal user interface for the hledger accounting system. description: A simple curses-style terminal user interface for the hledger accounting system.
It can be a more convenient way to browse your accounts than the CLI. It can be a more convenient way to browse your accounts than the CLI.
@ -63,7 +63,7 @@ executable hledger-ui
hs-source-dirs: hs-source-dirs:
./ ./
ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
build-depends: build-depends:
ansi-terminal >=0.9 ansi-terminal >=0.9
, async , async
@ -78,8 +78,8 @@ executable hledger-ui
, extra >=1.6.3 , extra >=1.6.3
, filepath , filepath
, fsnotify >=0.2.1.2 && <0.4 , fsnotify >=0.2.1.2 && <0.4
, hledger ==1.27.* , hledger >=1.27.1 && <1.28
, hledger-lib ==1.27.* , hledger-lib >=1.27.1 && <1.28
, megaparsec >=7.0.0 && <9.3 , megaparsec >=7.0.0 && <9.3
, microlens >=0.4 , microlens >=0.4
, microlens-platform >=0.2.3.1 , microlens-platform >=0.2.3.1

View File

@ -1,5 +1,5 @@
name : hledger-ui name : hledger-ui
version : 1.27 version : 1.27.1
synopsis : Curses-style terminal interface for the hledger accounting system synopsis : Curses-style terminal interface for the hledger accounting system
description : | description : |
A simple curses-style terminal user interface for the hledger accounting system. A simple curses-style terminal user interface for the hledger accounting system.
@ -38,7 +38,7 @@ flags:
manual: false manual: false
default: true default: true
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
ghc-options: ghc-options:
- -Wall - -Wall
@ -50,8 +50,8 @@ ghc-options:
dependencies: dependencies:
- base >=4.14 && <4.17 - base >=4.14 && <4.17
- hledger-lib >=1.27 && <1.28 - hledger-lib >=1.27.1 && <1.28
- hledger >=1.27 && <1.28 - hledger >=1.27.1 && <1.28
- ansi-terminal >=0.9 - ansi-terminal >=0.9
- async - async
- breakpoint - breakpoint

View File

@ -1 +1 @@
1.27 1.27.1

View File

@ -1,2 +1,2 @@
m4_dnl Version number to show in manuals. Updated by "Shake setversion" m4_dnl Version number to show in manuals. Updated by "Shake setversion"
m4_define({{_version_}}, {{1.27}})m4_dnl m4_define({{_version_}}, {{1.27.1}})m4_dnl

View File

@ -154,6 +154,7 @@ instance Yesod App where
|] |]
addScript $ StaticR js_bootstrap_min_js addScript $ StaticR js_bootstrap_min_js
addScript $ StaticR js_bootstrap_datepicker_min_js addScript $ StaticR js_bootstrap_datepicker_min_js
addScript $ StaticR js_locales_bootstrap_datepicker_fi_min_js
addScript $ StaticR js_jquery_url_js addScript $ StaticR js_jquery_url_js
addScript $ StaticR js_jquery_cookie_js addScript $ StaticR js_jquery_cookie_js
addScript $ StaticR js_jquery_hotkeys_js addScript $ StaticR js_jquery_hotkeys_js

View File

@ -31,7 +31,7 @@ postAddR :: Handler ()
postAddR = do postAddR = do
checkServerSideUiEnabled checkServerSideUiEnabled
VD{caps, j, today} <- getViewData VD{caps, j, today} <- getViewData
when (CapAdd `notElem` caps) (permissionDenied "Missing the 'add' capability") when (CapAdd `notElem` caps) (permissionDenied "Ei oikeutta lisätä kirjauksia ('add')")
((res, view), enctype) <- runFormPost $ addForm j today ((res, view), enctype) <- runFormPost $ addForm j today
case res of case res of
@ -40,7 +40,7 @@ postAddR = do
liftIO $ do liftIO $ do
ensureJournalFileExists f ensureJournalFileExists f
appendToJournalFileOrStdout f (showTransaction t') appendToJournalFileOrStdout f (showTransaction t')
setMessage "Transaction added." setMessage "Kirjaus lisätty."
redirect JournalR redirect JournalR
FormMissing -> showForm view enctype FormMissing -> showForm view enctype
FormFailure errs -> do FormFailure errs -> do
@ -49,7 +49,7 @@ postAddR = do
where where
showForm view enctype = showForm view enctype =
sendResponse =<< defaultLayout [whamlet| sendResponse =<< defaultLayout [whamlet|
<h2>Add transaction <h2>Uusi kirjaus
<div .row style="margin-top:1em"> <div .row style="margin-top:1em">
<form#addform.form.col-xs-12.col-sm-11 method=post enctype=#{enctype}> <form#addform.form.col-xs-12.col-sm-11 method=post enctype=#{enctype}>
^{view} ^{view}
@ -60,7 +60,7 @@ postAddR = do
putAddR :: Handler RepJson putAddR :: Handler RepJson
putAddR = do putAddR = do
VD{caps, j, opts} <- getViewData VD{caps, j, opts} <- getViewData
when (CapAdd `notElem` caps) (permissionDenied "Missing the 'add' capability") when (CapAdd `notElem` caps) (permissionDenied "Ei oikeutta lisätä kirjauksia ('add')")
(r :: Result Transaction) <- parseCheckJsonBody (r :: Result Transaction) <- parseCheckJsonBody
case r of case r of

View File

@ -32,20 +32,20 @@ postEditR :: FilePath -> Handler ()
postEditR f = do postEditR f = do
checkServerSideUiEnabled checkServerSideUiEnabled
VD {caps, j} <- getViewData VD {caps, j} <- getViewData
when (CapManage `notElem` caps) (permissionDenied "Missing the 'manage' capability") when (CapManage `notElem` caps) (permissionDenied "Ei oikeutta muokata kirjanpitoa ('manage')")
(f', txt) <- journalFile404 f j (f', txt) <- journalFile404 f j
((res, view), enctype) <- runFormPost (editForm f' txt) ((res, view), enctype) <- runFormPost (editForm f' txt)
newtxt <- fromFormSuccess (showForm view enctype) res newtxt <- fromFormSuccess (showForm view enctype) res
runExceptT (writeJournalTextIfValidAndChanged f newtxt) >>= \case runExceptT (writeJournalTextIfValidAndChanged f newtxt) >>= \case
Left e -> do Left e -> do
setMessage $ "Failed to load journal: " <> toHtml e setMessage $ "Kirjanpidon lataaminen epäonnistui: " <> toHtml e
showForm view enctype showForm view enctype
Right () -> do Right () -> do
setMessage $ "Saved journal " <> toHtml f <> "\n" setMessage $ "Kirjanpito tallennettu tiedostoon " <> toHtml f <> "\n"
redirect JournalR redirect JournalR
where where
showForm view enctype = showForm view enctype =
sendResponse <=< defaultLayout $ do sendResponse <=< defaultLayout $ do
setTitle "Edit journal" setTitle "Muokkaa kirjanpitoa"
[whamlet|<form method=post enctype=#{enctype}>^{view}|] [whamlet|<form method=post enctype=#{enctype}>^{view}|]

View File

@ -21,16 +21,16 @@ getJournalR :: Handler Html
getJournalR = do getJournalR = do
checkServerSideUiEnabled checkServerSideUiEnabled
VD{caps, j, m, opts, q, qopts, today} <- getViewData VD{caps, j, m, opts, q, qopts, today} <- getViewData
when (CapView `notElem` caps) (permissionDenied "Missing the 'view' capability") when (CapView `notElem` caps) (permissionDenied "Ei oikeutta katsella kirjanpitoa ('view')")
let title = case inAccount qopts of let title = case inAccount qopts of
Nothing -> "General Journal" Nothing -> "Kaikki kirjaukset"
Just (a, inclsubs) -> "Transactions in " <> a <> if inclsubs then "" else " (excluding subaccounts)" Just (a, inclsubs) -> "Tapahtumat tilillä " <> a <> if inclsubs then "" else " (poislukien alatilit)"
title' = title <> if m /= Any then ", filtered" else "" title' = title <> if m /= Any then ", suodatettu" else ""
acctlink a = (RegisterR, [("q", replaceInacct q $ accountQuery a)]) acctlink a = (RegisterR, [("q", replaceInacct q $ accountQuery a)])
rspec = (reportspec_ $ cliopts_ opts){_rsQuery = m} rspec = (reportspec_ $ cliopts_ opts){_rsQuery = m}
items = reverse $ entriesReport rspec j items = reverse $ entriesReport rspec j
transactionFrag = transactionFragment j transactionFrag = transactionFragment j
defaultLayout $ do defaultLayout $ do
setTitle "journal - hledger-web" setTitle "päiväkirja - hledger-web"
$(widgetFile "journal") $(widgetFile "journal")

View File

@ -39,16 +39,16 @@ getManageR :: Handler Html
getManageR = do getManageR = do
checkServerSideUiEnabled checkServerSideUiEnabled
VD{caps, j} <- getViewData VD{caps, j} <- getViewData
when (CapManage `notElem` caps) (permissionDenied "Missing the 'manage' capability") when (CapManage `notElem` caps) (permissionDenied "Ei oikeutta muokata kirjanpitoa ('manage')")
defaultLayout $ do defaultLayout $ do
setTitle "Manage journal" setTitle "Muokkaa kirjanpitoa"
$(widgetFile "manage") $(widgetFile "manage")
getDownloadR :: FilePath -> Handler TypedContent getDownloadR :: FilePath -> Handler TypedContent
getDownloadR f = do getDownloadR f = do
checkServerSideUiEnabled checkServerSideUiEnabled
VD{caps, j} <- getViewData VD{caps, j} <- getViewData
when (CapManage `notElem` caps) (permissionDenied "Missing the 'manage' capability") when (CapManage `notElem` caps) (permissionDenied "Ei oikeutta muokata kirjanpitoa ('manage')")
(f', txt) <- journalFile404 f j (f', txt) <- journalFile404 f j
addHeader "Content-Disposition" ("attachment; filename=\"" <> T.pack f' <> "\"") addHeader "Content-Disposition" ("attachment; filename=\"" <> T.pack f' <> "\"")
sendResponse ("text/plain" :: ByteString, toContent txt) sendResponse ("text/plain" :: ByteString, toContent txt)
@ -58,49 +58,49 @@ getDownloadR f = do
getVersionR :: Handler TypedContent getVersionR :: Handler TypedContent
getVersionR = do getVersionR = do
VD{caps} <- getViewData VD{caps} <- getViewData
when (CapView `notElem` caps) (permissionDenied "Missing the 'view' capability") when (CapView `notElem` caps) (permissionDenied "Ei oikeutta katsella kirjanpitoa ('view')")
selectRep $ do selectRep $ do
provideJson $ packageversion provideJson $ packageversion
getAccountnamesR :: Handler TypedContent getAccountnamesR :: Handler TypedContent
getAccountnamesR = do getAccountnamesR = do
VD{caps, j} <- getViewData VD{caps, j} <- getViewData
when (CapView `notElem` caps) (permissionDenied "Missing the 'view' capability") when (CapView `notElem` caps) (permissionDenied "Ei oikeutta katsella kirjanpitoa ('view')")
selectRep $ do selectRep $ do
provideJson $ journalAccountNames j provideJson $ journalAccountNames j
getTransactionsR :: Handler TypedContent getTransactionsR :: Handler TypedContent
getTransactionsR = do getTransactionsR = do
VD{caps, j} <- getViewData VD{caps, j} <- getViewData
when (CapView `notElem` caps) (permissionDenied "Missing the 'view' capability") when (CapView `notElem` caps) (permissionDenied "Ei oikeutta katsella kirjanpitoa ('view')")
selectRep $ do selectRep $ do
provideJson $ jtxns j provideJson $ jtxns j
getPricesR :: Handler TypedContent getPricesR :: Handler TypedContent
getPricesR = do getPricesR = do
VD{caps, j} <- getViewData VD{caps, j} <- getViewData
when (CapView `notElem` caps) (permissionDenied "Missing the 'view' capability") when (CapView `notElem` caps) (permissionDenied "Ei oikeutta katsella kirjanpitoa ('view')")
selectRep $ do selectRep $ do
provideJson $ map priceDirectiveToMarketPrice $ jpricedirectives j provideJson $ map priceDirectiveToMarketPrice $ jpricedirectives j
getCommoditiesR :: Handler TypedContent getCommoditiesR :: Handler TypedContent
getCommoditiesR = do getCommoditiesR = do
VD{caps, j} <- getViewData VD{caps, j} <- getViewData
when (CapView `notElem` caps) (permissionDenied "Missing the 'view' capability") when (CapView `notElem` caps) (permissionDenied "Ei oikeutta katsella kirjanpitoa ('view')")
selectRep $ do selectRep $ do
provideJson $ (M.keys . jinferredcommodities) j provideJson $ (M.keys . jinferredcommodities) j
getAccountsR :: Handler TypedContent getAccountsR :: Handler TypedContent
getAccountsR = do getAccountsR = do
VD{caps, j} <- getViewData VD{caps, j} <- getViewData
when (CapView `notElem` caps) (permissionDenied "Missing the 'view' capability") when (CapView `notElem` caps) (permissionDenied "Ei oikeutta katsella kirjanpitoa ('view')")
selectRep $ do selectRep $ do
provideJson $ laccounts $ ledgerFromJournal Any j provideJson $ laccounts $ ledgerFromJournal Any j
getAccounttransactionsR :: Text -> Handler TypedContent getAccounttransactionsR :: Text -> Handler TypedContent
getAccounttransactionsR a = do getAccounttransactionsR a = do
VD{caps, j} <- getViewData VD{caps, j} <- getViewData
when (CapView `notElem` caps) (permissionDenied "Missing the 'view' capability") when (CapView `notElem` caps) (permissionDenied "Ei oikeutta katsella kirjanpitoa ('view')")
let let
rspec = defreportspec rspec = defreportspec
thisacctq = Acct $ accountNameToAccountRegex a -- includes subs thisacctq = Acct $ accountNameToAccountRegex a -- includes subs

View File

@ -27,11 +27,11 @@ getRegisterR :: Handler Html
getRegisterR = do getRegisterR = do
checkServerSideUiEnabled checkServerSideUiEnabled
VD{caps, j, m, opts, q, qopts, today} <- getViewData VD{caps, j, m, opts, q, qopts, today} <- getViewData
when (CapView `notElem` caps) (permissionDenied "Missing the 'view' capability") when (CapView `notElem` caps) (permissionDenied "Ei oikeutta katsella kirjanpitoa ('view')")
let (a,inclsubs) = fromMaybe ("all accounts",True) $ inAccount qopts let (a,inclsubs) = fromMaybe ("kaikki tilit",True) $ inAccount qopts
s1 = if inclsubs then "" else " (excluding subaccounts)" s1 = if inclsubs then "" else " (poislukien alitilit)"
s2 = if m /= Any then ", filtered" else "" s2 = if m /= Any then ", suodatettu" else ""
header = a <> s1 <> s2 header = a <> s1 <> s2
let rspec = reportspec_ (cliopts_ opts) let rspec = reportspec_ (cliopts_ opts)
@ -47,12 +47,12 @@ getRegisterR = do
tail $ (", "<$xs) ++ [""] tail $ (", "<$xs) ++ [""]
items = accountTransactionsReport rspec{_rsQuery=m} j acctQuery items = accountTransactionsReport rspec{_rsQuery=m} j acctQuery
balancelabel balancelabel
| isJust (inAccount qopts), balanceaccum_ (_rsReportOpts rspec) == Historical = "Historical Total" | isJust (inAccount qopts), balanceaccum_ (_rsReportOpts rspec) == Historical = "Historiallinen saldo"
| isJust (inAccount qopts) = "Period Total" | isJust (inAccount qopts) = "Kauden saldo"
| otherwise = "Total" | otherwise = "Saldo"
transactionFrag = transactionFragment j transactionFrag = transactionFragment j
defaultLayout $ do defaultLayout $ do
setTitle "register - hledger-web" setTitle "kirjaukset - hledger-web"
$(widgetFile "register") $(widgetFile "register")
-- cf. Hledger.Reports.AccountTransactionsReport.accountTransactionsReportItems -- cf. Hledger.Reports.AccountTransactionsReport.accountTransactionsReportItems

View File

@ -36,7 +36,7 @@ postUploadR :: FilePath -> Handler ()
postUploadR f = do postUploadR f = do
checkServerSideUiEnabled checkServerSideUiEnabled
VD {caps, j} <- getViewData VD {caps, j} <- getViewData
when (CapManage `notElem` caps) (permissionDenied "Missing the 'manage' capability") when (CapManage `notElem` caps) (permissionDenied "Ei oikeutta muokata kirjanpitoa ('manage')")
(f', _) <- journalFile404 f j (f', _) <- journalFile404 f j
((res, view), enctype) <- runFormPost (uploadForm f') ((res, view), enctype) <- runFormPost (uploadForm f')
@ -48,20 +48,20 @@ postUploadR f = do
newtxt <- case TE.decodeUtf8' lbs of newtxt <- case TE.decodeUtf8' lbs of
Left e -> do Left e -> do
setMessage $ setMessage $
"Encoding error: '" <> toHtml (show e) <> "'. " <> "Merkistövirhe: '" <> toHtml (show e) <> "'. " <>
"If your file is not UTF-8 encoded, try the 'edit form', " <> "Jos tiedostosi ei käytä UTF-8 merkistöä, kokeile 'muokkaa'-sivua," <>
"where the transcoding should be handled by the browser." "jolla selaimesi pitäisi huolehtia merkistön muuntamisesta puolestasi."
showForm view enctype showForm view enctype
Right newtxt -> return newtxt Right newtxt -> return newtxt
runExceptT (writeJournalTextIfValidAndChanged f newtxt) >>= \case runExceptT (writeJournalTextIfValidAndChanged f newtxt) >>= \case
Left e -> do Left e -> do
setMessage $ "Failed to load journal: " <> toHtml e setMessage $ "Kirjanpidon lataaminen epäonnistui: " <> toHtml e
showForm view enctype showForm view enctype
Right () -> do Right () -> do
setMessage $ "File " <> toHtml f <> " uploaded successfully" setMessage $ "Tiedoston " <> toHtml f <> " lataaminen onnistui!"
redirect JournalR redirect JournalR
where where
showForm view enctype = showForm view enctype =
sendResponse <=< defaultLayout $ do sendResponse <=< defaultLayout $ do
setTitle "Upload journal" setTitle "Korvaa tiedosto"
[whamlet|<form method=post enctype=#{enctype}>^{view}|] [whamlet|<form method=post enctype=#{enctype}>^{view}|]

View File

@ -38,7 +38,7 @@ addModal addR j today = do
<div .modal-content> <div .modal-content>
<div .modal-header> <div .modal-header>
<button type="button" .close data-dismiss="modal" aria-hidden="true">&times; <button type="button" .close data-dismiss="modal" aria-hidden="true">&times;
<h3 .modal-title #addLabel>Add a transaction <h3 .modal-title #addLabel>Uusi kirjaus
<div .modal-body> <div .modal-body>
<form#addform.form action=@{addR} method=POST enctype=#{addEnctype}> <form#addform.form action=@{addR} method=POST enctype=#{addEnctype}>
^{addView} ^{addView}
@ -80,8 +80,8 @@ addForm j today = identifyForm "add" $ \extra -> do
| f `elem` fs = Right f | f `elem` fs = Right f
| otherwise = Left $ MsgInputNotFound $ T.pack f | otherwise = Left $ MsgInputNotFound $ T.pack f
-- field settings -- field settings
dateSettings = FieldSettings "date" Nothing Nothing (Just "date") [("class", "form-control input-lg"), ("placeholder", "Date")] dateSettings = FieldSettings "date" Nothing Nothing (Just "date") [("class", "form-control input-lg"), ("placeholder", "Päiväys")]
descSettings = FieldSettings "desc" Nothing Nothing (Just "description") [("class", "form-control input-lg typeahead"), ("placeholder", "Description"), ("size", "40")] descSettings = FieldSettings "desc" Nothing Nothing (Just "description") [("class", "form-control input-lg typeahead"), ("placeholder", "Selite"), ("size", "40")]
acctSettings = FieldSettings "account" Nothing Nothing (Just "account") [] acctSettings = FieldSettings "account" Nothing Nothing (Just "account") []
amtSettings = FieldSettings "amount" Nothing Nothing (Just "amount") [] amtSettings = FieldSettings "amount" Nothing Nothing (Just "amount") []
fileSettings = FieldSettings "file" Nothing Nothing (Just "file") [("class", "form-control input-lg")] fileSettings = FieldSettings "file" Nothing Nothing (Just "file") [("class", "form-control input-lg")]
@ -190,7 +190,8 @@ toBloodhoundJson ts =
"]" "]"
] ]
where where
b64wrap = ("atob(\""<>) . (<>"\")") . encodeBase64 -- decodeBase64EncodedText is defined in add-form.hamlet
b64wrap = ("decodeBase64EncodedText(\""<>) . (<>"\")") . encodeBase64
zipDefault :: a -> [a] -> [a] -> [(a, a)] zipDefault :: a -> [a] -> [a] -> [(a, a)]
zipDefault def (b:bs) (c:cs) = (b, c):(zipDefault def bs cs) zipDefault def (b:bs) (c:cs) = (b, c):(zipDefault def bs cs)

View File

@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
name: hledger-web name: hledger-web
version: 1.27 version: 1.27.1
synopsis: Web-based user interface for the hledger accounting system synopsis: Web-based user interface for the hledger accounting system
description: A simple web-based user interface for the hledger accounting system, description: A simple web-based user interface for the hledger accounting system,
providing a more modern UI than the command-line or terminal interfaces. providing a more modern UI than the command-line or terminal interfaces.
@ -92,6 +92,7 @@ extra-source-files:
static/js/jquery.js static/js/jquery.js
static/js/jquery.min.js static/js/jquery.min.js
static/js/jquery.url.js static/js/jquery.url.js
static/js/locales/bootstrap-datepicker.fi.min.js
static/js/typeahead.bundle.js static/js/typeahead.bundle.js
static/js/typeahead.bundle.min.js static/js/typeahead.bundle.min.js
templates/add-form.hamlet templates/add-form.hamlet
@ -151,7 +152,7 @@ library
hs-source-dirs: hs-source-dirs:
./ ./
ghc-options: -Wall -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns ghc-options: -Wall -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
build-depends: build-depends:
Decimal >=0.5.1 Decimal >=0.5.1
, aeson >=1 , aeson >=1
@ -172,8 +173,8 @@ library
, extra >=1.6.3 , extra >=1.6.3
, filepath , filepath
, hjsmin , hjsmin
, hledger ==1.27.* , hledger >=1.27.1 && <1.28
, hledger-lib ==1.27.* , hledger-lib >=1.27.1 && <1.28
, hspec , hspec
, http-client , http-client
, http-conduit , http-conduit
@ -213,7 +214,7 @@ executable hledger-web
hs-source-dirs: hs-source-dirs:
app app
ghc-options: -Wall -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns ghc-options: -Wall -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
build-depends: build-depends:
base >=4.14 && <4.17 base >=4.14 && <4.17
, breakpoint , breakpoint
@ -234,7 +235,7 @@ test-suite test
hs-source-dirs: hs-source-dirs:
test test
ghc-options: -Wall -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns ghc-options: -Wall -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
build-depends: build-depends:
base >=4.14 && <4.17 base >=4.14 && <4.17
, breakpoint , breakpoint

View File

@ -1,5 +1,5 @@
name: hledger-web name: hledger-web
version: 1.27 version: 1.27.1
synopsis: Web-based user interface for the hledger accounting system synopsis: Web-based user interface for the hledger accounting system
description: | description: |
A simple web-based user interface for the hledger accounting system, A simple web-based user interface for the hledger accounting system,
@ -83,7 +83,7 @@ dependencies:
library: library:
source-dirs: . source-dirs: .
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
exposed-modules: exposed-modules:
- Hledger.Web - Hledger.Web
- Hledger.Web.Application - Hledger.Web.Application
@ -103,8 +103,8 @@ library:
- Hledger.Web.Widget.AddForm - Hledger.Web.Widget.AddForm
- Hledger.Web.Widget.Common - Hledger.Web.Widget.Common
dependencies: dependencies:
- hledger-lib >=1.27 && <1.28 - hledger-lib >=1.27.1 && <1.28
- hledger >=1.27 && <1.28 - hledger >=1.27.1 && <1.28
- aeson >=1 - aeson >=1
- base64 - base64
- blaze-html - blaze-html
@ -153,7 +153,7 @@ executables:
hledger-web: hledger-web:
source-dirs: app source-dirs: app
main: main.hs main: main.hs
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
dependencies: dependencies:
- hledger-web - hledger-web
when: when:
@ -167,7 +167,7 @@ tests:
source-dirs: test source-dirs: test
main: test.hs main: test.hs
other-modules: [] # prevent double compilation, https://github.com/sol/hpack/issues/188 other-modules: [] # prevent double compilation, https://github.com/sol/hpack/issues/188
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
dependencies: dependencies:
- hledger-lib - hledger-lib
- hledger - hledger

View File

@ -14,6 +14,7 @@ $(document).ready(function() {
autoclose: true, autoclose: true,
format: 'yyyy-mm-dd', format: 'yyyy-mm-dd',
todayHighlight: true, todayHighlight: true,
language: 'fi',
weekStart: 1 // Monday weekStart: 1 // Monday
});; });;
@ -109,11 +110,11 @@ function registerChart($container, series) {
/* https://github.com/krzysu/flot.tooltip */ /* https://github.com/krzysu/flot.tooltip */
tooltip: true, tooltip: true,
tooltipOpts: { tooltipOpts: {
xDateFormat: "%Y/%m/%d", xDateFormat: "%d.%m.%Y",
content: content:
function(label, x, y, flotitem) { function(label, x, y, flotitem) {
var data = flotitem.series.data[flotitem.dataIndex]; var data = flotitem.series.data[flotitem.dataIndex];
return data[3]+" balance on %x after "+data[2]+" posted by transaction:<pre>"+data[4]+"</pre>"; return data[3]+" saldoa %x sen jälkeen, kun siirrettiin "+data[2]+" kirjauksella: <pre>"+data[4]+"</pre>";
}, },
onHover: function(flotitem, $tooltipel) { onHover: function(flotitem, $tooltipel) {
$tooltipel.css('border-color',flotitem.series.color); $tooltipel.css('border-color',flotitem.series.color);
@ -193,8 +194,8 @@ function addformAddPosting() {
$('#addform .account-postings').append( $('#addform .account-group:last').clone().addClass('added-row') ); $('#addform .account-postings').append( $('#addform .account-group:last').clone().addClass('added-row') );
// renumber and clear the new last account and amount fields // renumber and clear the new last account and amount fields
var n = $('#addform .account-group').length; var n = $('#addform .account-group').length;
$('.account-input:last').prop('placeholder', 'Account '+n).val(''); $('.account-input:last').prop('placeholder', 'Tili '+n).val('');
$('.amount-input:last').prop('placeholder','Amount '+n).val(''); // XXX Enable typehead on dynamically created inputs $('.amount-input:last').prop('placeholder','Summa '+n).val(''); // XXX Enable typehead on dynamically created inputs
// and move the keypress handler to the new last amount field // and move the keypress handler to the new last amount field
addformLastAmountBindKey(); addformLastAmountBindKey();
} }

View File

@ -0,0 +1 @@
!function(a){a.fn.datepicker.dates.fi={days:["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"],daysShort:["sun","maa","tii","kes","tor","per","lau"],daysMin:["su","ma","ti","ke","to","pe","la"],months:["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu","heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu"],monthsShort:["tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mar","jou"],today:"tänään",clear:"Tyhjennä",weekStart:1,format:"d.m.yyyy"}}(jQuery);

View File

@ -19,6 +19,17 @@
jQuery('input[name=description]').typeahead({ highlight: true }, { source: descriptionsSuggester.ttAdapter() }); jQuery('input[name=description]').typeahead({ highlight: true }, { source: descriptionsSuggester.ttAdapter() });
jQuery('input[name=account]').typeahead({ highlight: true }, { source: accountsSuggester.ttAdapter() }); jQuery('input[name=account]').typeahead({ highlight: true }, { source: accountsSuggester.ttAdapter() });
}); });
const utf8textdecoder = new TextDecoder();
function decodeBase64EncodedText(b64) {
const unb64 = window.atob(b64);
const arr = new Uint8Array(unb64.length);
for (let i = 0; i < arr.length; i++) {
arr[i] = unb64.charCodeAt(i);
}
return utf8textdecoder.decode(arr);
}
^{extra} ^{extra}
<div .row> <div .row>
@ -40,23 +51,23 @@
<div .form-group .row .account-group style="padding-left:1em;"> <div .form-group .row .account-group style="padding-left:1em;">
<div .col-sm-9.col-xs-9 :isJust accE:.has-error> <div .col-sm-9.col-xs-9 :isJust accE:.has-error>
<input .account-input.form-control.input-lg.typeahead type=text <input .account-input.form-control.input-lg.typeahead type=text
name=account placeholder="Account #{n}" value="#{acc}"> name=account placeholder="Tili #{n}" value="#{acc}">
$maybe err <- accE $maybe err <- accE
<span .help-block .error-block>_{err} <span .help-block .error-block>_{err}
<div .col-sm-3.col-xs-3 :isJust amtE:.has-error> <div .col-sm-3.col-xs-3 :isJust amtE:.has-error>
<input .amount-input.form-control.input-lg type=text <input .amount-input.form-control.input-lg type=text
name=amount placeholder="Amount #{n}" value="#{amt}"> name=amount placeholder="Summa #{n}" value="#{amt}">
$maybe err <- amtE $maybe err <- amtE
<span .help-block .error-block>_{err} <span .help-block .error-block>_{err}
<div .row> <div .row>
<div .col-sm-9.col-xs-9> <div .col-sm-9.col-xs-9>
$if length files > 1 $if length files > 1
Add to: Kirjaa tiedostoon:
&nbsp; &nbsp;
<div style="display:inline-block; width:auto;" .form-group :isJust (fvErrors fileView):.has-error> <div style="display:inline-block; width:auto;" .form-group :isJust (fvErrors fileView):.has-error>
^{fvInput fileView} ^{fvInput fileView}
$maybe err <- fvErrors fileView $maybe err <- fvErrors fileView
<span .help-block .error-block>#{err} <span .help-block .error-block>#{err}
<div .col-sm-3.col-xs-3 style="text-align:right;"> <div .col-sm-3.col-xs-3 style="text-align:right;">
<button type=submit .btn .btn-default .btn-lg name=submit style="font-weight:bold;">Save <button type=submit .btn .btn-default .btn-lg name=submit style="font-weight:bold;">Tallenna

View File

@ -1,8 +1,8 @@
<tr :here == journalR:.inacct> <tr :here == journalR:.inacct>
<td .top .acct> <td .top .acct>
<a href=@{journalR} :here == journalR:.inacct <a href=@{journalR} :here == journalR:.inacct
title="Show general journal entries, most recent first"> title="Näytä päiväkirjan kirjaukset uusimmasta vanhimpaan">
Journal Kirjanpito
<td .top> <td .top>
$forall (acct, adisplay, aindent, abal) <- items $forall (acct, adisplay, aindent, abal) <- items
<tr <tr
@ -12,11 +12,11 @@ $forall (acct, adisplay, aindent, abal) <- items
<div .ff-wrapper> <div .ff-wrapper>
\#{indent aindent} \#{indent aindent}
<a.acct-name href="@?{(registerR, [("q", replaceInacct q $ accountQuery acct)])}" <a.acct-name href="@?{(registerR, [("q", replaceInacct q $ accountQuery acct)])}"
title="Show transactions affecting this account and subaccounts"> title="Näytä tähän tiliin ja sen alitileihin vaikuttavat kirjaukset">
#{adisplay} #{adisplay}
$if hasSubAccounts acct $if hasSubAccounts acct
<a href="@?{(registerR, [("q", replaceInacct q $ accountOnlyQuery acct)])}" .only.hidden-sm.hidden-xs <a href="@?{(registerR, [("q", replaceInacct q $ accountOnlyQuery acct)])}" .only.hidden-sm.hidden-xs
title="Show transactions affecting this account but not subaccounts">only title="Näytä vain juuri tähän tiliin vaikuttavat kirjaukset">only
<td> <td>
^{mixedAmountAsHtml abal} ^{mixedAmountAsHtml abal}
<tr .total> <tr .total>

View File

@ -17,19 +17,19 @@ $if elem CapView caps
<div #message .alert.alert-info>#{m} <div #message .alert.alert-info>#{m}
$if elem CapView caps $if elem CapView caps
<form#searchform.input-group method=GET> <form#searchform.input-group method=GET>
<input .form-control name=q value=#{q} placeholder="Search" <input .form-control name=q value=#{q} placeholder="Hae"
title="Enter hledger search patterns to filter the data below"> title="Syötä hakuehtoja rajataksesi alla olevaa dataa">
<div .input-group-btn> <div .input-group-btn>
$if not (T.null q) $if not (T.null q)
<a href=@{here} .btn .btn-default title="Clear search terms"> <a href=@{here} .btn .btn-default title="Tyhjennä hakuehdot">
<span .glyphicon .glyphicon-remove-circle> <span .glyphicon .glyphicon-remove-circle>
<button .btn .btn-default type=submit title="Apply search terms"> <button .btn .btn-default type=submit title="Hae">
<span .glyphicon .glyphicon-search> <span .glyphicon .glyphicon-search>
$if elem CapManage caps $if elem CapManage caps
<a href="@{ManageR}" .btn.btn-default title="Manage journal files"> <a href="@{ManageR}" .btn.btn-default title="Hallinnoi kirjanpidon tiedostoja">
<span .glyphicon .glyphicon-wrench> <span .glyphicon .glyphicon-wrench>
<button .btn .btn-default type=button data-toggle="modal" data-target="#helpmodal" <button .btn .btn-default type=button data-toggle="modal" data-target="#helpmodal"
title="Show search and general help"> title="Näytä käyttöohjeita">
<span .glyphicon .glyphicon-question-sign> <span .glyphicon .glyphicon-question-sign>
^{widget} ^{widget}
@ -38,43 +38,43 @@ $if elem CapView caps
<div .modal-content> <div .modal-content>
<div .modal-header> <div .modal-header>
<button type="button" .close data-dismiss="modal" aria-hidden="true">&times; <button type="button" .close data-dismiss="modal" aria-hidden="true">&times;
<h3 .modal-title #helpLabel>Help <h3 .modal-title #helpLabel>Ohjeet
<div .modal-body> <div .modal-body>
<div .row> <div .row>
<div .col-xs-6> <div .col-xs-6>
<p> <p>
<b>Keyboard shortcuts <b>Pikanäppäimet
<ul> <ul>
<li> <code>h</code> or maybe <code>?</code> - view this help (escape or click to exit) <li> <code>h</code> tai (selaimesta riippuen) myös <code>?</code> - näytä nämä ohjeet (paina <code>esc</code> tai klikkaa ruksia poistuaksesi)
<li> <code>j</code> - go to the Journal view (home) <li> <code>j</code> - siirry päiväkirjanäkymään (etusivulle)
<li> <code>a</code> - add a transaction (escape to cancel) <li> <code>a</code> - lisää uusi kirjaus (paina <code>esc</code> peruaksesi)
<li> <code>s</code> - toggle sidebar <li> <code>s</code> - vaihda sivupalkki näkyviin/piilotetuksi
<li> <code>f</code> - focus search form ("find") <li> <code>f</code> - kohdista hakukenttään
<li> <code>e</code> - hide empty accounts in sidebar <li> <code>e</code> - piilota nollasaldoiset tilit sivupalkista
<p> <p>
<b>General <b>Yleistä
<ul> <ul>
<li> The Journal view shows general journal entries, representing zero-sum movements of money (or other commodity) between hierarchical accounts <li> Pääkirja näytää kirjauksia, jotka esittävät rahan (tai muun hyödykkeen) täydellisiä siirtoja tilien välillä. Siirron täydellisyydellä tarkoitetaan sitä, ettei siitä ole jätetty mitään osaa kirjaamatta, jolloin hyödykettä ei katoa eikä synny tyhjästä.
<li> The sidebar shows the resulting accounts and their final balances <li> Sivupalkki näyttää käytetyt tilit ja niiden loppusaldot
<li> Parent account balances include subaccount balances <li> Ylätilien saldot sisältävät niiden alatilien saldot
<li> Multiple currencies in balances are displayed one above the other <li> Eri valuutat esitetään saldoissa päällekkäin
<li> Click account name links to see transactions affecting that account, with running balance <li> Klikkaamalla tilin nimeä näet siihen vaikuttavat kirjaukset ja saldon joka siirron jälkeen
<li> Click date links to see journal entries on that date <li> Klikkaamalla päiväystä näet silloin kirjatut tapahtumat
<div .col-xs-6> <div .col-xs-6>
<p> <p>
<b>Search <b>Haku
<ul> <ul>
<li> <code>acct:REGEXP</code> - filter on to/from account <li> <code>acct:REGEXP</code> - suodata tilin nimellä
<li> <code>desc:REGEXP</code> - filter on description <li> <code>desc:REGEXP</code> - suodata selitteellä
<li> <code>date:PERIODEXP</code>, <code>date2:PERIODEXP</code> - filter on date or secondary date <li> <code>date:AIKAVÄLI</code>, <code>date2:AIKAVÄLI</code> - suodata päiväyksen tai toissijaisen päiväkysen perusteella.
<li> <code>code:REGEXP</code> - filter on transaction's code (eg check number) <li> <code>code:REGEXP</code> - suodata kirjauksen numerolla (esim. tilisiirron viitenumero)
<li> <code>status:*</code>, <code>status:!</code>, <code>status:</code> - filter on transaction's cleared status (cleared, pending, uncleared) <li> <code>status:*</code>, <code>status:!</code>, <code>status:</code> - suodata kirjauksen tilan perusteella (valmis, kesken, tarkistamaton)
<!-- <li> <code>empty:BOOL</code> - filter on whether amount is zero --> <!-- <li> <code>empty:BOOL</code> - suodata sen perusteella, onko tilin saldo nolla -->
<li> <code>amt:N</code>, <code>amt:&lt;N</code>, <code>amt:&gt;N</code> - filter on the unsigned amount magnitude. Or with a sign before N, filter on the signed value. (Single-commodity amounts only.) <li> <code>amt:N</code>, <code>amt:&lt;N</code>, <code>amt:&gt;N</code> - suodata summan (itseisarvon) suuruuden perusteella. Etumerkin + tai &minus; lisääminen luvun <code>N</code> eteen rajoittaa suodatuksen vain sen merkkisiin summiin. (ei yhdistä eri valuuttojen määriä)
<li> <code>cur:REGEXP</code> - filter on the currency/commodity symbol (must match all of it). Dollar sign must be written as <code>\$</code> <li> <code>cur:REGEXP</code> - suodata valuutan/hyödykkeen tunnuksella. (koko tunnuksen täytyy täsmätä)
<li> <code>tag:NAME</code>, <code>tag:NAME=REGEX</code> - filter on tag name, or tag name and value <li> <code>tag:NIMI</code>, <code>tag:NIMI=REGEX</code> - suodata tunnisteen nimellä tai nimellä ja arvolla
<!-- <li> <code>depth:N</code> - filter out accounts below this depth --> <!-- <li> <code>depth:N</code> - rajoita niihin tileihin, joilla on alle <code>N</code> ylätiliä -->
<li> <code>real:BOOL</code> - filter on postings' real/virtual-ness <li> <code>real:BOOL</code> - suodata siirtojen todellisuuden/näennäisyyden perusteella. Näennäissiirtojen summa ei välttämättä ole nolla, eli ne voivat hävittää kirjanpidosta rahaa tai tuoda sitä sinne tyhjästä.
<li> Enclose search patterns containing spaces in single or double quotes <li> Hakuehdot erotellaan välilyönneillä. Välilyönnin voi sisällyttää hakuehtoon ympäröimällä ehdon yksin- tai kaksinkertaisilla suorilla lainausmerkeillä (<code>"</code> tai <code>'</code>)
<li> Prepend <code>not:</code> to negate a search term <li> Lisää ehdon alkuun <code>not:</code> valitaksesi ne tapahtumat, jotka eivät toteuta ehtoa
<li> Description, account, status query terms are OR'ed, others are AND'ed. <li> Selitteen, tilin nimen ja kirjauksen tilan hakuehdoista riittää toteuttaa yksi, muista ehdoista tapahtuman pitää toteuttaa kaikki tullakseen valituksi.

View File

@ -1,9 +1,9 @@
#{extra} #{extra}
<h2> <h2>
Edit file # Muokkaa tiedostoa #
<i>#{f} <i>#{f}
<div.alert.alert-danger> <div.alert.alert-danger>
Are you sure? This will overwrite your journal! Oletko varma? Tämä korvaa vanhan tiedoston täysin!
<table.table.table-condensed> <table.table.table-condensed>
<tr> <tr>
<td colspan=2 style="border:0"> <td colspan=2 style="border:0">
@ -11,7 +11,7 @@
<tr> <tr>
<td style="border:0"> <td style="border:0">
<span.help> <span.help>
^{helplink "file-format" "File format help"} ^{helplink "file-format" "Apua tiedostomudon kanssa (englanniksi)"}
<td .text-right style="border:0"> <td .text-right style="border:0">
<a.btn.btn-default href="@{ManageR}">Go back <a.btn.btn-default href="@{ManageR}">Peruuta
<input.btn.btn-default type=submit value="Save"> <input.btn.btn-default type=submit value="Tallenna">

View File

@ -3,16 +3,16 @@
$if elem CapAdd caps $if elem CapAdd caps
<a #addformlink href="#" role="button" style="cursor:pointer; margin-top:1em;" <a #addformlink href="#" role="button" style="cursor:pointer; margin-top:1em;"
data-toggle="modal" data-target="#addmodal" title="Add a new transaction to the journal"> data-toggle="modal" data-target="#addmodal" title="Lisää uusi tapahtuma kirjanpitoon.">
Add a transaction Kirjaa tapahtuma
<div .table-responsive> <div .table-responsive>
<table .transactionsreport .table .table-condensed> <table .transactionsreport .table .table-condensed>
<thead> <thead>
<th .date style="text-align:left;">Date <th .date style="text-align:left;">Päiväys
<th .description style="text-align:left;">Description <th .description style="text-align:left;">Selite
<th .account style="text-align:left;">Account <th .account style="text-align:left;">Tili
<th .amount style="text-align:right;">Amount <th .amount style="text-align:right;">Summa
$forall torig <- items $forall torig <- items
<tr .title ##{transactionFrag torig} title="#{showTransaction torig}"> <tr .title ##{transactionFrag torig} title="#{showTransaction torig}">

View File

@ -1,12 +1,12 @@
<h2> <h2>
Your journal's files Kirjanpitosi tiedostot
<div.row> <div.row>
<div .col-md-6.col-sm-8.col-xs-12> <div .col-md-6.col-sm-8.col-xs-12>
<table .table.table-condensed> <table .table.table-condensed>
<thead> <thead>
<th> <th>
File Tiedosto
<th> <th>
<tbody> <tbody>
$forall (path, _) <- jfiles j $forall (path, _) <- jfiles j
@ -15,8 +15,8 @@
#{path} #{path}
<td style="text-align:right"> <td style="text-align:right">
<a.btn.btn-default href=@{EditR path}> <a.btn.btn-default href=@{EditR path}>
Edit Muokkaa
<a.btn.btn-default href=@{UploadR path}> <a.btn.btn-default href=@{UploadR path}>
Upload Korvaa uudella
<a.btn.btn-default href=@{DownloadR path}> <a.btn.btn-default href=@{DownloadR path}>
Download Imuroi

View File

@ -9,11 +9,11 @@
<thead> <thead>
<tr> <tr>
<th style="text-align:left;"> <th style="text-align:left;">
Date Päiväys
<span .glyphicon.glyphicon-chevron-up> <span .glyphicon.glyphicon-chevron-up>
<th style="text-align:left;">Description <th style="text-align:left;">Kuvaus
<th style="text-align:left;">To/From Account(s) <th style="text-align:left;">Tileille/Tileiltä
<th style="text-align:right; white-space:normal;">Amount Out/In <th style="text-align:right; white-space:normal;">Siirretty summa
<th style="text-align:right; white-space:normal;"> <th style="text-align:right; white-space:normal;">
#{balancelabel} #{balancelabel}

View File

@ -1,14 +1,14 @@
<h2> <h2>
Upload to file # Korvaa tiedosto #
<i>#{f} <i>#{f}
<div.alert.alert-danger> <div.alert.alert-danger>
Are you sure? This will overwrite your journal! Oletko varma? Tämä korvaa vanhan tiedoston täysin!
<div.form-group> <div.form-group>
<label .btn.btn-primary for="file"> <label .btn.btn-primary for="file">
<input type=file id=file name=file style="display:none" <input type=file id=file name=file style="display:none"
onchange="\$('#file-info').html(this.files[0].name)" /> onchange="\$('#file-info').html(this.files[0].name)" />
Select file Valitse korvattava tiedosto
<span .label.label-info id="file-info"> <span .label.label-info id="file-info">
<div.form-group> <div.form-group>
<input .btn.btn-default type=submit value="Upload"> <input .btn.btn-default type=submit value="Korvaa">
#{extra} #{extra}

View File

@ -1 +1 @@
1.27 1.27.1

View File

@ -1,2 +1,2 @@
m4_dnl Version number to show in manuals. Updated by "Shake setversion" m4_dnl Version number to show in manuals. Updated by "Shake setversion"
m4_define({{_version_}}, {{1.27}})m4_dnl m4_define({{_version_}}, {{1.27.1}})m4_dnl

View File

@ -573,14 +573,20 @@ multiBalanceReportHtmlRows ropts mbr =
-- | Render one MultiBalanceReport heading row as a HTML table row. -- | Render one MultiBalanceReport heading row as a HTML table row.
multiBalanceReportHtmlHeadRow :: ReportOpts -> [T.Text] -> Html () multiBalanceReportHtmlHeadRow :: ReportOpts -> [T.Text] -> Html ()
multiBalanceReportHtmlHeadRow _ [] = mempty -- shouldn't happen multiBalanceReportHtmlHeadRow _ [] = mempty -- shouldn't happen
multiBalanceReportHtmlHeadRow ropts (acct:rest) = multiBalanceReportHtmlHeadRow ropts (acct:cells) =
let let
defstyle = style_ "" defstyle = style_ ""
(amts,tot,avg) (amts,tot,avg)
| row_total_ ropts && average_ ropts = (init $ init rest, [last $ init rest], [last rest]) | row_total_ ropts && average_ ropts = (ini2, sndlst2, lst2)
| row_total_ ropts = (init rest, [last rest], []) | row_total_ ropts = (ini1, lst1, [])
| average_ ropts = (init rest, [], [last rest]) | average_ ropts = (ini1, [], lst1)
| otherwise = (rest, [], []) | otherwise = (cells, [], [])
where
n = length cells
(ini1,lst1) = splitAt (n-1) cells
(ini2, rest) = splitAt (n-2) cells
(sndlst2,lst2) = splitAt 1 rest
in in
tr_ $ mconcat $ tr_ $ mconcat $
td_ [class_ "account"] (toHtml acct) td_ [class_ "account"] (toHtml acct)
@ -591,14 +597,19 @@ multiBalanceReportHtmlHeadRow ropts (acct:rest) =
-- | Render one MultiBalanceReport data row as a HTML table row. -- | Render one MultiBalanceReport data row as a HTML table row.
multiBalanceReportHtmlBodyRow :: ReportOpts -> [T.Text] -> Html () multiBalanceReportHtmlBodyRow :: ReportOpts -> [T.Text] -> Html ()
multiBalanceReportHtmlBodyRow _ [] = mempty -- shouldn't happen multiBalanceReportHtmlBodyRow _ [] = mempty -- shouldn't happen
multiBalanceReportHtmlBodyRow ropts (label:rest) = multiBalanceReportHtmlBodyRow ropts (label:cells) =
let let
defstyle = style_ "text-align:right" defstyle = style_ "text-align:right"
(amts,tot,avg) (amts,tot,avg)
| row_total_ ropts && average_ ropts = (init $ init rest, [last $ init rest], [last rest]) | row_total_ ropts && average_ ropts = (ini2, sndlst2, lst2)
| row_total_ ropts = (init rest, [last rest], []) | row_total_ ropts = (ini1, lst1, [])
| average_ ropts = (init rest, [], [last rest]) | average_ ropts = (ini1, [], lst1)
| otherwise = (rest, [], []) | otherwise = (cells, [], [])
where
n = length cells
(ini1,lst1) = splitAt (n-1) cells
(ini2, rest) = splitAt (n-2) cells
(sndlst2,lst2) = splitAt 1 rest
in in
tr_ $ mconcat $ tr_ $ mconcat $
td_ [class_ "account", style_ "text-align:left"] (toHtml label) td_ [class_ "account", style_ "text-align:left"] (toHtml label)
@ -615,14 +626,19 @@ multiBalanceReportHtmlFootRow _ropts [] = mempty
-- : repeat nullmixedamt zeros -- : repeat nullmixedamt zeros
-- ++ (if row_total_ ropts then [nullmixedamt] else []) -- ++ (if row_total_ ropts then [nullmixedamt] else [])
-- ++ (if average_ ropts then [nullmixedamt] else []) -- ++ (if average_ ropts then [nullmixedamt] else [])
multiBalanceReportHtmlFootRow ropts (acct:rest) = multiBalanceReportHtmlFootRow ropts (acct:cells) =
let let
defstyle = style_ "text-align:right" defstyle = style_ "text-align:right"
(amts,tot,avg) (amts,tot,avg)
| row_total_ ropts && average_ ropts = (init $ init rest, [last $ init rest], [last rest]) | row_total_ ropts && average_ ropts = (ini2, sndlst2, lst2)
| row_total_ ropts = (init rest, [last rest], []) | row_total_ ropts = (ini1, lst1, [])
| average_ ropts = (init rest, [], [last rest]) | average_ ropts = (ini1, [], lst1)
| otherwise = (rest, [], []) | otherwise = (cells, [], [])
where
n = length cells
(ini1,lst1) = splitAt (n-1) cells
(ini2, rest) = splitAt (n-2) cells
(sndlst2,lst2) = splitAt 1 rest
in in
tr_ $ mconcat $ tr_ $ mconcat $
th_ [style_ "text-align:left"] (toHtml acct) th_ [style_ "text-align:left"] (toHtml acct)

View File

@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
name: hledger name: hledger
version: 1.27 version: 1.27.1
synopsis: Command-line interface for the hledger accounting system synopsis: Command-line interface for the hledger accounting system
description: The command-line interface for the hledger accounting system. description: The command-line interface for the hledger accounting system.
Its basic function is to read a plain text file describing Its basic function is to read a plain text file describing
@ -134,7 +134,7 @@ library
other-modules: other-modules:
Paths_hledger Paths_hledger
ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -optP-Wno-nonportable-include-path ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -optP-Wno-nonportable-include-path
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
build-depends: build-depends:
Decimal >=0.5.1 Decimal >=0.5.1
, Diff >=0.2 , Diff >=0.2
@ -152,7 +152,7 @@ library
, githash >=0.1.6.1 , githash >=0.1.6.1
, hashable >=1.2.4 , hashable >=1.2.4
, haskeline >=0.6 , haskeline >=0.6
, hledger-lib ==1.27.* , hledger-lib >=1.27.1 && <1.28
, lucid , lucid
, math-functions >=0.3.3.0 , math-functions >=0.3.3.0
, megaparsec >=7.0.0 && <9.3 , megaparsec >=7.0.0 && <9.3
@ -186,7 +186,7 @@ executable hledger
hs-source-dirs: hs-source-dirs:
app app
ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -optP-Wno-nonportable-include-path ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -optP-Wno-nonportable-include-path
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
build-depends: build-depends:
Decimal >=0.5.1 Decimal >=0.5.1
, aeson >=1 , aeson >=1
@ -203,7 +203,7 @@ executable hledger
, githash >=0.1.6.1 , githash >=0.1.6.1
, haskeline >=0.6 , haskeline >=0.6
, hledger , hledger
, hledger-lib ==1.27.* , hledger-lib >=1.27.1 && <1.28
, math-functions >=0.3.3.0 , math-functions >=0.3.3.0
, megaparsec >=7.0.0 && <9.3 , megaparsec >=7.0.0 && <9.3
, microlens >=0.4 , microlens >=0.4
@ -237,7 +237,7 @@ test-suite unittest
hs-source-dirs: hs-source-dirs:
test test
ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -optP-Wno-nonportable-include-path ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind -optP-Wno-nonportable-include-path
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
build-depends: build-depends:
Decimal >=0.5.1 Decimal >=0.5.1
, aeson >=1 , aeson >=1
@ -254,7 +254,7 @@ test-suite unittest
, githash >=0.1.6.1 , githash >=0.1.6.1
, haskeline >=0.6 , haskeline >=0.6
, hledger , hledger
, hledger-lib ==1.27.* , hledger-lib >=1.27.1 && <1.28
, math-functions >=0.3.3.0 , math-functions >=0.3.3.0
, megaparsec >=7.0.0 && <9.3 , megaparsec >=7.0.0 && <9.3
, microlens >=0.4 , microlens >=0.4
@ -303,7 +303,7 @@ benchmark bench
, githash >=0.1.6.1 , githash >=0.1.6.1
, haskeline >=0.6 , haskeline >=0.6
, hledger , hledger
, hledger-lib ==1.27.* , hledger-lib >=1.27.1 && <1.28
, html , html
, math-functions >=0.3.3.0 , math-functions >=0.3.3.0
, megaparsec >=7.0.0 && <9.3 , megaparsec >=7.0.0 && <9.3

View File

@ -1,5 +1,5 @@
name: hledger name: hledger
version: 1.27 version: 1.27.1
synopsis: Command-line interface for the hledger accounting system synopsis: Command-line interface for the hledger accounting system
description: | description: |
The command-line interface for the hledger accounting system. The command-line interface for the hledger accounting system.
@ -97,7 +97,7 @@ ghc-options:
dependencies: dependencies:
- base >=4.14 && <4.17 - base >=4.14 && <4.17
- hledger-lib >=1.27 && <1.28 - hledger-lib >=1.27.1 && <1.28
- aeson >=1 - aeson >=1
- ansi-terminal >=0.9 - ansi-terminal >=0.9
- breakpoint - breakpoint
@ -138,7 +138,7 @@ when:
- terminfo - terminfo
library: library:
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
exposed-modules: exposed-modules:
- Hledger.Cli - Hledger.Cli
- Hledger.Cli.Main - Hledger.Cli.Main
@ -187,7 +187,7 @@ executables:
hledger: hledger:
source-dirs: app source-dirs: app
main: hledger-cli.hs main: hledger-cli.hs
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
when: when:
- condition: flag(threaded) - condition: flag(threaded)
ghc-options: -threaded ghc-options: -threaded
@ -199,7 +199,7 @@ tests:
source-dirs: test source-dirs: test
main: unittest.hs main: unittest.hs
other-modules: [] # prevent double compilation, https://github.com/sol/hpack/issues/188 other-modules: [] # prevent double compilation, https://github.com/sol/hpack/issues/188
cpp-options: -DVERSION="1.27" cpp-options: -DVERSION="1.27.1"
dependencies: dependencies:
- hledger - hledger

View File

@ -1,6 +1,5 @@
# 1. # 1.
hledger -f sample.journal balance --tree $ hledger -f sample.journal balance --tree
>>>
$-1 assets $-1 assets
$1 bank:saving $1 bank:saving
$-2 cash $-2 cash
@ -13,22 +12,18 @@ hledger -f sample.journal balance --tree
$1 liabilities:debts $1 liabilities:debts
-------------------- --------------------
0 0
>>>=0
# 2. # 2.
hledger -f sample.journal balance --tree o $ hledger -f sample.journal balance --tree o
>>>
$1 expenses:food $1 expenses:food
$-2 income $-2 income
$-1 gifts $-1 gifts
$-1 salary $-1 salary
-------------------- --------------------
$-1 $-1
>>>=0
# 3. Period reporting works for a specific year # 3. Period reporting works for a specific year
hledger -f - balance -b 2016 -e 2017 -N <
<<<
2015/10/10 Client A | Invoice #1 2015/10/10 Client A | Invoice #1
assets:receivables $10,000.00 assets:receivables $10,000.00
revenue:clients:A -$10,000.00 revenue:clients:A -$10,000.00
@ -48,16 +43,13 @@ hledger -f - balance -b 2016 -e 2017 -N
2016/03/01 Deposit | Invoice #2 2016/03/01 Deposit | Invoice #2
assets:checking $10.00 assets:checking $10.00
assets:receivables -$10.00 assets:receivables -$10.00
>>> $ hledger -f - balance -b 2016 -e 2017 -N
$-40.00 assets:checking $-40.00 assets:checking
$50.00 expense:hosting $50.00 expense:hosting
$-10.00 revenue:clients:B $-10.00 revenue:clients:B
>>>2
>>>= 0
# 4. Period reporting works for two years # 4. Period reporting works for two years
hledger -f - balance --tree -b 2015 -e 2017 -N <
<<<
2015/10/10 Client A | Invoice #1 2015/10/10 Client A | Invoice #1
assets:receivables $10,000.00 assets:receivables $10,000.00
revenue:clients:A -$10,000.00 revenue:clients:A -$10,000.00
@ -77,18 +69,15 @@ hledger -f - balance --tree -b 2015 -e 2017 -N
2016/03/01 Deposit | Invoice #2 2016/03/01 Deposit | Invoice #2
assets:checking $10.00 assets:checking $10.00
assets:receivables -$10.00 assets:receivables -$10.00
>>> $ hledger -f - balance --tree -b 2015 -e 2017 -N
$9,960.00 assets:checking $9,960.00 assets:checking
$50.00 expense:hosting $50.00 expense:hosting
$-10,010.00 revenue:clients $-10,010.00 revenue:clients
$-10,000.00 A $-10,000.00 A
$-10.00 B $-10.00 B
>>>2
>>>= 0
# 5. Period reporting works for one month # 5. Period reporting works for one month
hledger -f - balance --tree -b 2015/11 -e 2015/12 -N <
<<<
2015/10/10 Client A | Invoice #1 2015/10/10 Client A | Invoice #1
assets:receivables $10,000.00 assets:receivables $10,000.00
revenue:clients:A -$10,000.00 revenue:clients:A -$10,000.00
@ -108,16 +97,13 @@ hledger -f - balance --tree -b 2015/11 -e 2015/12 -N
2016/03/01 Deposit | Invoice #2 2016/03/01 Deposit | Invoice #2
assets:checking $10.00 assets:checking $10.00
assets:receivables -$10.00 assets:receivables -$10.00
>>> $ hledger -f - balance --tree -b 2015/11 -e 2015/12 -N
0 assets 0 assets
$10,000.00 checking $10,000.00 checking
$-10,000.00 receivables $-10,000.00 receivables
>>>2
>>>= 0
# 6. Period reporting works for one month in another year # 6. Period reporting works for one month in another year
hledger -f - balance -b 2016/10 -e 2016/11 <
<<<
2015/10/10 Client A | Invoice #1 2015/10/10 Client A | Invoice #1
assets:receivables $10,000.00 assets:receivables $10,000.00
revenue:clients:A -$10,000.00 revenue:clients:A -$10,000.00
@ -137,88 +123,85 @@ hledger -f - balance -b 2016/10 -e 2016/11
2016/03/01 Deposit | Invoice #2 2016/03/01 Deposit | Invoice #2
assets:checking $10.00 assets:checking $10.00
assets:receivables -$10.00 assets:receivables -$10.00
>>> $ hledger -f - balance -b 2016/10 -e 2016/11
-------------------- --------------------
0 0
>>>2
>>>= 0
# 7. Default CSV output. # 7. Default CSV output.
hledger -f - balance -N --output-format=csv <
<<<
2021-01-01 Test 2021-01-01 Test
Assets:ABC "AB.C" 1 Assets:ABC "AB.C" 1
Assets:Cash -$1 Assets:Cash -$1
>>> $ hledger -f - balance -N --output-format=csv
"account","balance" "account","balance"
"Assets:ABC","""AB.C"" 1" "Assets:ABC","""AB.C"" 1"
"Assets:Cash","$-1" "Assets:Cash","$-1"
>>>= 0
# 8. CSV output always shows full account names, even in tree mode (#1565). # 8. CSV output always shows full account names, even in tree mode (#1565).
hledger -f - balance -N --output-format=csv --tree <
<<<
2021-01-01 Test 2021-01-01 Test
Assets:ABC "AB.C" 1 Assets:ABC "AB.C" 1
Assets:Cash -$1 Assets:Cash -$1
>>> $ hledger -f - balance -N --output-format=csv --tree
"account","balance" "account","balance"
"Assets","$-1, ""AB.C"" 1" "Assets","$-1, ""AB.C"" 1"
"Assets:ABC","""AB.C"" 1" "Assets:ABC","""AB.C"" 1"
"Assets:Cash","$-1" "Assets:Cash","$-1"
>>>= 0
# 9. CSV output always does not show thousands separators # 9. CSV output always does not show thousands separators
hledger -f - balance -N --output-format=csv <
<<<
2021-01-01 Test 2021-01-01 Test
Assets:ABC $10 000.00 Assets:ABC $10 000.00
Assets:Cash -$10 000.00 Assets:Cash -$10 000.00
>>> $ hledger -f - balance -N --output-format=csv
"account","balance" "account","balance"
"Assets:ABC","$10000.00" "Assets:ABC","$10000.00"
"Assets:Cash","$-10000.00" "Assets:Cash","$-10000.00"
>>>= 0
# 10. --declared includes all declared leaf accounts, even if they have no postings. # 10. --declared includes all declared leaf accounts, even if they have no postings.
# They are filtered, depth-clipped, and form trees like the others. # They are filtered, depth-clipped, and form trees like the others.
# (XXX Here a:ac is not declared and so not shown, even though normally a balance report clipped to depth 2 would show it. Wrong ?) # (XXX Here a:ac is not declared and so not shown, even though normally a balance report clipped to depth 2 would show it. Wrong ?)
hledger -f - balance -NE --declared --tree --depth 2 a <
<<<
account a account a
account a:aa account a:aa
account a:ab account a:ab
account a:ac:aca account a:ac:aca
account b account b
>>> $ hledger -f - balance -NE --declared --tree --depth 2 a
0 a 0 a
0 aa 0 aa
0 ab 0 ab
>>>= 0
# 11. In list mode we can see that non-leaf declared accounts are excluded. # 11. In list mode we can see that non-leaf declared accounts are excluded.
hledger -f - balance -NE --declared --flat <
<<<
account a account a
account a:aa account a:aa
account a:ab account a:ab
account a:ac:aca account a:ac:aca
account b account b
>>> $ hledger -f - balance -NE --declared --flat
0 a:aa 0 a:aa
0 a:ab 0 a:ab
0 a:ac:aca 0 a:ac:aca
0 b 0 b
>>>= 0
# 12. not:ACCT queries work with declared accounts. # 12. not:ACCT queries work with declared accounts.
hledger -f - balance -NE --declared not:a <
<<<
account a account a
account a:aa account a:aa
account a:ab account a:ab
account a:ac:aca account a:ac:aca
account b account b
>>> $ hledger -f - balance -NE --declared not:a
0 b 0 b
>>>= 0
# 13. An empty periodic report in HTML output does not break.
<
$ hledger -f- bal -M -O html
> //
# 14. An empty totals column in HTML output does not break (#1933).
<
$ hledger -f- bal -MT -O html
> //

View File

@ -1,5 +1,5 @@
# 1. all data files on the command line should be read # 1. all data files on the command line should be read
hledger inc -f personal.journal -f business.journal hledger is -f personal.journal -f business.journal
>>> >>>
Income Statement 2014-01-01..2014-01-02 Income Statement 2014-01-01..2014-01-02