add: show the transaction and confirm before adding it, or allow restart
This commit is contained in:
parent
95e6dae18a
commit
5785eae38e
@ -14,14 +14,14 @@ where
|
|||||||
import Control.Exception as E
|
import Control.Exception as E
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.Trans (liftIO)
|
import Control.Monad.Trans (liftIO)
|
||||||
import Data.Char (toUpper)
|
import Data.Char (toUpper, toLower)
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Typeable (Typeable)
|
import Data.Typeable (Typeable)
|
||||||
import Safe (headDef, tailDef, headMay)
|
import Safe (headDef, tailDef, headMay)
|
||||||
import System.Console.Haskeline (InputT, runInputT, defaultSettings, setComplete, getInputLine)
|
import System.Console.Haskeline (InputT, runInputT, defaultSettings, setComplete, getInputLine)
|
||||||
import System.Console.Haskeline.Completion
|
import System.Console.Haskeline.Completion
|
||||||
import System.IO ( stderr, hPutStrLn )
|
import System.IO ( stderr, hPutStr, hPutStrLn )
|
||||||
import System.IO.Error
|
import System.IO.Error
|
||||||
import Text.ParserCombinators.Parsec
|
import Text.ParserCombinators.Parsec
|
||||||
import Text.Printf
|
import Text.Printf
|
||||||
@ -41,14 +41,14 @@ add :: CliOpts -> Journal -> IO ()
|
|||||||
add opts j
|
add opts j
|
||||||
| f == "-" = return ()
|
| f == "-" = return ()
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
hPutStrLn stderr $ unlines [
|
hPutStr stderr $ unlines [
|
||||||
"Adding transactions to journal file "++f
|
"Adding transactions to journal file "++f
|
||||||
,"Provide field values at the prompts, or press enter to accept defaults."
|
,"Provide field values at the prompts, or press enter to accept defaults."
|
||||||
,"Use readline keys to edit, use tab key to complete account names."
|
,"Use readline keys to edit, use tab key to complete account names."
|
||||||
,"A code (in parentheses) may be entered following transaction dates."
|
,"A code (in parentheses) may be entered following transaction dates."
|
||||||
,"A comment may be entered following descriptions or amounts."
|
,"A comment may be entered following descriptions or amounts."
|
||||||
,"If you make a mistake, enter < at any prompt to restart the transaction."
|
,"If you make a mistake, enter < at any prompt to restart the transaction."
|
||||||
,"To record a transaction, enter . when prompted."
|
,"To complete a transaction, enter . when prompted."
|
||||||
,"To quit, press control-d or control-c."
|
,"To quit, press control-d or control-c."
|
||||||
]
|
]
|
||||||
today <- showDate `fmap` getCurrentDay
|
today <- showDate `fmap` getCurrentDay
|
||||||
@ -66,16 +66,36 @@ add opts j
|
|||||||
-- recent transaction in the journal.
|
-- recent transaction in the journal.
|
||||||
getAndAddTransactionsLoop :: Journal -> CliOpts -> String -> [String] -> IO ()
|
getAndAddTransactionsLoop :: Journal -> CliOpts -> String -> [String] -> IO ()
|
||||||
getAndAddTransactionsLoop j opts defdate moredefs = do
|
getAndAddTransactionsLoop j opts defdate moredefs = do
|
||||||
|
hPrintf stderr "\nStarting a new transaction.\n"
|
||||||
t <- getTransaction j opts defdate moredefs
|
t <- getTransaction j opts defdate moredefs
|
||||||
j <- journalAddTransaction j opts t
|
j' <- journalAddTransaction j opts t
|
||||||
hPrintf stderr "\nRecorded transaction:\n%s" (show t)
|
hPrintf stderr "\nAdded to the journal.\n"
|
||||||
let defdate' = showDate $ tdate t
|
let defdate' = showDate $ tdate t
|
||||||
getAndAddTransactionsLoop j opts defdate' []
|
getAndAddTransactionsLoop j' opts defdate' []
|
||||||
|
|
||||||
-- | Read a single transaction from the console, with history-aware prompting.
|
-- | Read a single transaction from the console, with history-aware prompting,
|
||||||
|
-- allowing the user to restart and confirm at the end.
|
||||||
-- A default date, and zero or more defaults for subsequent fields, are provided.
|
-- A default date, and zero or more defaults for subsequent fields, are provided.
|
||||||
getTransaction :: Journal -> CliOpts -> String -> [String] -> IO Transaction
|
getTransaction :: Journal -> CliOpts -> String -> [String] -> IO Transaction
|
||||||
getTransaction j opts defdate moredefs = do
|
getTransaction j opts defdate moredefs = do
|
||||||
|
mt <- getTransactionOrRestart j opts defdate moredefs
|
||||||
|
let restart = do
|
||||||
|
hPrintf stderr "\nRestarting this transaction.\n"
|
||||||
|
getTransaction j opts defdate moredefs
|
||||||
|
case mt of
|
||||||
|
Nothing -> restart
|
||||||
|
Just t -> do
|
||||||
|
hPrintf stderr "\nTransaction entered:\n%s" (show t)
|
||||||
|
yn <- runInteractionDefault $ askFor "Accept this transaction" (Just "y") (Just $ \s -> map toLower s `elem` ["<","y","yes","n","no"])
|
||||||
|
case headMay $ map toLower yn of
|
||||||
|
Just 'y' -> return t
|
||||||
|
_ -> restart
|
||||||
|
|
||||||
|
-- | Read a single transaction from the console, with history-aware prompting,
|
||||||
|
-- or return nothing indicating that the user wants to restart entering this transaction.
|
||||||
|
-- A default date, and zero or more defaults for subsequent fields, are provided.
|
||||||
|
getTransactionOrRestart :: Journal -> CliOpts -> String -> [String] -> IO (Maybe Transaction)
|
||||||
|
getTransactionOrRestart j opts defdate moredefs = do
|
||||||
let dateandcodep = do {d <- smartdate; c <- optionMaybe code; many spacenonewline; eof; return (d, fromMaybe "" c)}
|
let dateandcodep = do {d <- smartdate; c <- optionMaybe code; many spacenonewline; eof; return (d, fromMaybe "" c)}
|
||||||
datecodestr <- runInteractionDefault $ askFor "date"
|
datecodestr <- runInteractionDefault $ askFor "date"
|
||||||
(Just defdate)
|
(Just defdate)
|
||||||
@ -88,16 +108,11 @@ getTransaction j opts defdate moredefs = do
|
|||||||
|
|
||||||
let (defdesc, moredefs') = headTailDef "" moredefs
|
let (defdesc, moredefs') = headTailDef "" moredefs
|
||||||
desc <- runInteractionDefault $ askFor "description" (Just defdesc) Nothing
|
desc <- runInteractionDefault $ askFor "description" (Just defdesc) Nothing
|
||||||
let restart = do hPrintf stderr "\nRestarting this transaction..\n\n"
|
|
||||||
getTransaction j opts defdate moredefs'
|
|
||||||
if desc == "<"
|
if desc == "<"
|
||||||
then restart
|
then return Nothing
|
||||||
else do
|
else do
|
||||||
let (description,comment) = (strip a, strip $ dropWhile (==';') b) where (a,b) = break (==';') desc
|
let (description,comment) = (strip a, strip $ dropWhile (==';') b) where (a,b) = break (==';') desc
|
||||||
mt <- getPostingsForTransactionWithHistory j opts datestr code description comment moredefs'
|
getPostingsForTransactionWithHistory j opts datestr code description comment moredefs'
|
||||||
case mt of
|
|
||||||
Nothing -> restart
|
|
||||||
Just t -> return t
|
|
||||||
|
|
||||||
data RestartEntryException = RestartEntryException deriving (Typeable,Show)
|
data RestartEntryException = RestartEntryException deriving (Typeable,Show)
|
||||||
instance Exception RestartEntryException
|
instance Exception RestartEntryException
|
||||||
@ -139,7 +154,7 @@ getPostingsForTransactionWithHistory j opts datestr code description comment def
|
|||||||
where
|
where
|
||||||
retry msg = liftIO (hPutStrLn stderr $ "\n" ++ (capitalize msg) ++ "please re-enter.") >> getvalidpostings
|
retry msg = liftIO (hPutStrLn stderr $ "\n" ++ (capitalize msg) ++ "please re-enter.") >> getvalidpostings
|
||||||
|
|
||||||
when (isJust bestmatch) $ liftIO $ hPrintf stderr "\nUsing this similar transaction for defaults:\n%s" (show $ fromJust bestmatch)
|
when (isJust bestmatch) $ liftIO $ hPrintf stderr "\nUsing this existing transaction for defaults:\n%s" (show $ fromJust bestmatch)
|
||||||
getvalidpostings `E.catch` \(_::RestartEntryException) -> return Nothing
|
getvalidpostings `E.catch` \(_::RestartEntryException) -> return Nothing
|
||||||
|
|
||||||
-- | Read postings from the command line until . is entered, generating
|
-- | Read postings from the command line until . is entered, generating
|
||||||
@ -154,7 +169,7 @@ getPostingsLoop st enteredps defargs = do
|
|||||||
defacct = maybe bestmatchacct Just $ headMay defargs
|
defacct = maybe bestmatchacct Just $ headMay defargs
|
||||||
defargs' = tailDef [] defargs
|
defargs' = tailDef [] defargs
|
||||||
ordot | null enteredps || length enteredrealps == 1 = "" :: String
|
ordot | null enteredps || length enteredrealps == 1 = "" :: String
|
||||||
| otherwise = " (or . to record)"
|
| otherwise = " (or . to complete this transaction)"
|
||||||
account <- runInteraction j $ askFor (printf "account %d%s" n ordot) defacct (Just accept)
|
account <- runInteraction j $ askFor (printf "account %d%s" n ordot) defacct (Just accept)
|
||||||
when (account=="<") $ throwIO RestartEntryException
|
when (account=="<") $ throwIO RestartEntryException
|
||||||
if account=="."
|
if account=="."
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user