module Persistence.Income ( list , create , edit , delete ) where import Data.Maybe (listToMaybe) import Data.Time.Calendar (Day) import Data.Time.Clock (getCurrentTime) import Database.SQLite.Simple (FromRow (fromRow), Only (Only)) import qualified Database.SQLite.Simple as SQLite import Prelude hiding (id) import Common.Model (Income (..), IncomeId, PaymentId, UserId) import Model.Query (Query (Query)) newtype Row = Row Income instance FromRow Row where fromRow = Row <$> (Income <$> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field) list :: Query [Income] list = Query (\conn -> map (\(Row i) -> i) <$> SQLite.query_ conn "SELECT * FROM income WHERE deleted_at IS NULL" ) create :: UserId -> Day -> Int -> Query Income create userId date amount = Query (\conn -> do createdAt <- getCurrentTime SQLite.execute conn "INSERT INTO income (user_id, date, amount, created_at) VALUES (?, ?, ?, ?)" (userId, date, amount, createdAt) incomeId <- SQLite.lastInsertRowId conn return $ Income { _income_id = incomeId , _income_userId = userId , _income_date = date , _income_amount = amount , _income_createdAt = createdAt , _income_editedAt = Nothing , _income_deletedAt = Nothing } ) edit :: UserId -> IncomeId -> Day -> Int -> Query Bool edit incomeUserId incomeId incomeDate incomeAmount = Query (\conn -> do mbIncome <- fmap (\(Row i) -> i) . listToMaybe <$> SQLite.query conn "SELECT * FROM income WHERE id = ?" (Only incomeId) case mbIncome of Just income -> if _income_userId income == incomeUserId then do now <- getCurrentTime SQLite.execute conn "UPDATE income SET edited_at = ?, date = ?, amount = ? WHERE id = ?" (now, incomeDate, incomeAmount, incomeId) return True else return False Nothing -> return False ) delete :: UserId -> PaymentId -> Query () delete userId paymentId = Query (\conn -> SQLite.execute conn "UPDATE income SET deleted_at = datetime('now') WHERE id = ? AND user_id = ?" (paymentId, userId) )