{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE RecordWildCards #-} module Config.CliConfig (getCliConfig, CliConfig (..)) where import Config.Files (ConfigDirectory, getDefaultConfigDirectory) import Data.Time (Day, addDays, defaultTimeLocale, formatTime) import Data.Version (showVersion) import Dates.Parser (parseDate) import Hledger (getCurrentDay) import Options.Applicative (Parser, ParserInfo, eitherReader, fullDesc, help, helper, info, long, metavar, option, optional, progDesc, short, showDefault, showDefaultWith, simpleVersioner, strOption, switch, value, (<**>)) import Paths_fints2ledger (version) data CliConfig = CliConfig { configDirectory :: ConfigDirectory , journalFile :: Maybe FilePath , startDate :: Day , pythonExecutable :: String , isDemo :: Bool , shouldEditConfig :: Bool , fromCsvFile :: Maybe FilePath , toCsvFile :: Maybe FilePath } deriving (Show) configDirectoryOption :: ConfigDirectory -> Parser ConfigDirectory configDirectoryOption defaultDirectory = strOption $ long "files-path" <> help "directory where fints2ledger puts its config files (like config.yml)" <> metavar "PATH" <> showDefault <> value defaultDirectory journalFileOption :: Parser (Maybe FilePath) journalFileOption = optional $ strOption $ long "journal-file" <> short 'f' <> help "path to the journal file" <> metavar "FILE" <> showDefault <> value "journal.ledger" startDateOption :: Day -> Day -> Parser Day startDateOption currentDay defaultValue = option (eitherReader $ parseDate currentDay) ( long "date" <> help "Start date to pull the FinTS transactions from. Possible values are for example: '25.01.2023', '90 days ago', 'last monday'" <> metavar "DATE" <> showDefaultWith (formatTime defaultTimeLocale "%d.%m.%Y") <> value defaultValue ) demoOption :: Parser Bool demoOption = switch $ long "demo" <> help "runs with a sample set of transactions, without actually calling a FinTS endpoint" configOption :: Parser Bool configOption = switch $ long "config" <> help "show a UI for editing the config" pythonExecutableOption :: Parser FilePath pythonExecutableOption = strOption $ long "python-command" <> help "command for running python" <> showDefault <> value "python3" toCsvFileOption :: Parser (Maybe FilePath) toCsvFileOption = optional $ strOption $ long "to-csv-file" <> metavar "FILE" <> help "Write transactions to this csv file instead of to a ledger journal" fromCsvFileOption :: Parser (Maybe FilePath) fromCsvFileOption = optional $ strOption $ long "from-csv-file" <> metavar "FILE" <> help "Read transactions from this csv file instead of from a FinTS endpoint" getCliParser :: IO (Parser CliConfig) getCliParser = do defaultConfigDirectory <- getDefaultConfigDirectory currentDay <- getCurrentDay let ninetyDaysAgo = addDays (-90) currentDay return do configDirectory <- configDirectoryOption defaultConfigDirectory journalFile <- journalFileOption startDate <- startDateOption currentDay ninetyDaysAgo pythonExecutable <- pythonExecutableOption isDemo <- demoOption shouldEditConfig <- configOption toCsvFile <- toCsvFileOption fromCsvFile <- fromCsvFileOption pure CliConfig{..} getCliConfig :: IO (ParserInfo CliConfig) getCliConfig = do parser <- getCliParser return $ info (parser <**> helper <**> simpleVersioner (showVersion version)) ( fullDesc <> progDesc "Convert banking transactions from a FinTS endpoint to a ledger journal." )