63 lines
2.5 KiB
Haskell
63 lines
2.5 KiB
Haskell
{-# LANGUAGE DuplicateRecordFields #-}
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
|
|
module Laskutin where
|
|
|
|
import Control.Concurrent (threadDelay)
|
|
import Control.Monad (forM_, forM)
|
|
import Data.Csv (encodeByName)
|
|
import Data.List.NonEmpty (nonEmpty)
|
|
import Data.MIME (Address, renderAddresses)
|
|
import Data.Maybe (catMaybes, mapMaybe)
|
|
import Data.Text.Encoding (decodeUtf8)
|
|
import System.Exit (exitFailure)
|
|
import System.IO (stderr, hPutStrLn)
|
|
|
|
import qualified Data.ByteString.Lazy as LBS
|
|
import qualified Data.Text.IO as T
|
|
|
|
import Laskutin.CSV
|
|
import Laskutin.Email
|
|
import Laskutin.Options
|
|
import Laskutin.Types
|
|
|
|
main :: IO ()
|
|
main = do
|
|
Options {csv, command} <- parseOptions
|
|
case command of
|
|
Send sendOptions -> sendInvoicesMain csv sendOptions
|
|
UpdateTable bankCsv -> updateTableMain csv bankCsv
|
|
|
|
sendInvoicesMain :: FilePath -> SendOptions -> IO ()
|
|
sendInvoicesMain csvPath options@SendOptions {email, sendmail} = do
|
|
invoices <- readInvoices csvPath options
|
|
forM_ invoices $ \invoice@(address, _) -> do
|
|
sendEmail sendmail $ uncurry (renderEmail [email]) invoice
|
|
putStr "Lähetetty osoitteeseen: "
|
|
T.putStrLn $ decodeUtf8 $ renderAddresses address
|
|
threadDelay (3 * 1000 * 1000)
|
|
|
|
updateTableMain :: FilePath -> FilePath -> IO ()
|
|
updateTableMain invoiceCsv transactionCsv = do
|
|
(headers, csvInvoices) <- parseCsvFile invoiceCsv
|
|
(_, csvTransactions) <- parseCsvFile transactionCsv
|
|
let newInvoices = fmap (updateInvoices csvTransactions) csvInvoices
|
|
LBS.writeFile invoiceCsv $ encodeByName headers newInvoices
|
|
|
|
updateInvoices :: [CsvTransaction] -> CsvInvoice -> CsvInvoice
|
|
updateInvoices transactions invoice@CsvInvoice {isPaid, reference}
|
|
| isPaid = invoice
|
|
| otherwise = invoice {isPaid = reference `elem` transactionReferences}
|
|
where transactionReferences = catMaybes $ transactionReference <$> transactions
|
|
transactionReference CsvTransaction {referenceOrMessage = Message _} = Nothing
|
|
transactionReference CsvTransaction {referenceOrMessage = Reference ref} = Just ref
|
|
|
|
readInvoices :: FilePath -> SendOptions -> IO [([Address], Invoice)]
|
|
readInvoices csv SendOptions {account, recipient, subject, message, due} = do
|
|
(_, csvInvoices) <- parseCsvFile csv
|
|
forM csvInvoices $ \CsvInvoice {..} -> do
|
|
invoiceRows <- maybe (hPutStrLn stderr ("No invoice rows in invoice") >> exitFailure) pure $
|
|
nonEmpty $ mapMaybe invoiceRowFromCsv rows
|
|
pure ([invoiceRecipient], Invoice { rows = invoiceRows, ..})
|