module Buchhaltung.AQBanking where
import Buchhaltung.Common
import Control.Monad.RWS.Strict
import Data.Maybe
import qualified Data.Text as T
import Formatting ((%))
import qualified Formatting.ShortFormatters as F
import System.Directory
import System.FilePath
import System.Process as P
type AQM = CommonM (AQConnection, AQBankingConf)
runAQ :: FullOptions () -> AQM a -> ErrorT IO [a]
runAQ options action = fst <$> evalRWST action2 options ()
where action2 = do
user <- user
aqconf <- maybeThrow ("AQBanking not configured for user "%F.sh)
($ user) return $ aqBanking user
forM (connections aqconf) $ \conn ->
withRWST (\r s -> (r{oEnv = (conn,aqconf)}, s)) action
runProc ::
(FilePath -> [String] -> IO a)
-> [String] -> ([FilePath], FilePath)
-> AQM a
runProc run args (argsC, bin) = liftIO $ run bin $ argsC ++ args
callAqhbci :: AAQM ()
callAqhbci args = runProc callProcess args
=<< askExec aqhbciToolExecutable "aqhbci-tool4" "-C"
runAqbanking'
:: (FilePath -> [String] -> IO b) -> AAQM b
runAqbanking' prc args = do
args' <- addContext args
runProc prc args'
=<< askExec aqBankingExecutable "aqbanking-cli" "-D"
callAqbanking :: AAQM ()
callAqbanking = runAqbanking' callProcess
readAqbanking :: AAQM String
readAqbanking = runAqbanking' $ readProcess'
type AAQM a = [String] -> AQM a
aqbankingListtrans :: Bool
-> AQM T.Text
aqbankingListtrans doRequest = do
when doRequest $
callAqbanking ["request"
, "--transactions"
, "--ignoreUnsupported"
]
T.pack <$> readAqbanking ["listtrans"
]
aqbankingSetup :: AQM ()
aqbankingSetup = do
path <- askConfigPath
conn <- readConn return
exists <- liftIO $ doesPathExist path
when exists $ throwFormat
("Path '"%F.s%"' already exists. Cannot install into existing path.")
($ path)
typ <- readConn $ return . aqType
when (typ /= PinTan) $ throwError $ mconcat
["modes other than PinTan have to be setup manually. Refer to the "
,"AQBanking manual. Use the '-C' to point to the configured "
,"'configDir'."]
liftIO $ createDirectoryIfMissing True path
callAqhbci [ "adduser", "-t", "pintan", "--context=1"
, "-b", aqBlz conn
, "-u", aqUser conn
, "-s", aqUrl conn
, "-N", aqName conn
, "--hbciversion=" <> toArg (aqHbciv conn)]
callAqhbci [ "getsysid" ]
callAqhbci [ "getaccounts" ]
callAqhbci [ "listaccounts" ]
addContext :: AAQM [FilePath]
addContext [] = return []
addContext args@(cmd:_) = do
withC <- withContext cmd
fmap (args ++) $
if withC then (\x -> ["-c", x <.> "context"]) <$> askConfigPath
else return []
withContext "listbal" = return True
withContext "listtrans" = return True
withContext "request" = return True
withContext "listaccs" = return False
withContext cmd = throwFormat
("'withContext' not defined for command '"%F.s%"'.")
($ cmd)
askConfigPath :: AQM FilePath
askConfigPath = do
conn <- readConn return
makeValid . (</> aqBlz conn <> "-" <> aqUser conn)
<$> readConf (absolute . configDir)
readConn :: (AQConnection -> AQM a) -> AQM a
readConn f = f =<< reader (fst . oEnv)
readConf :: (AQBankingConf -> AQM a) -> AQM a
readConf f = f =<< reader (snd . oEnv)
askExec
:: (AQBankingConf -> Maybe FilePath)
-> FilePath
-> String
-> AQM ([FilePath], FilePath)
askExec get def arg = do
path <- askConfigPath
readConf $ return . ((,) [arg, path]) . fromMaybe def . get