{-# LANGUAGE OverloadedStrings #-} module Model.Income ( IncomeId , Income(..) , list , create , editOwn , deleteOwn , modifiedDuring ) where import Data.Int (Int64) import Data.Maybe (listToMaybe) import Data.Time.Calendar (Day) import Data.Time.Clock (UTCTime, getCurrentTime) import Database.SQLite.Simple (Only(Only), FromRow(fromRow)) import Prelude hiding (id) import qualified Database.SQLite.Simple as SQLite import Model.Query (Query(Query)) import Model.User (User, UserId) import qualified Model.User as User import Resource (Resource, resourceCreatedAt, resourceEditedAt, resourceDeletedAt) type IncomeId = Int64 data Income = Income { id :: IncomeId , userId :: UserId , date :: Day , amount :: Int , createdAt :: UTCTime , editedAt :: Maybe UTCTime , deletedAt :: Maybe UTCTime } deriving Show instance Resource Income where resourceCreatedAt = createdAt resourceEditedAt = editedAt resourceDeletedAt = deletedAt instance FromRow Income where fromRow = Income <$> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field <*> SQLite.field list :: Query [Income] list = Query (\conn -> SQLite.query_ conn "SELECT * FROM income WHERE deleted_at IS NULL") create :: UserId -> Day -> Int -> Query IncomeId create incomeUserId incomeDate incomeAmount = Query (\conn -> do now <- getCurrentTime SQLite.execute conn "INSERT INTO income (user_id, date, amount, created_at) VALUES (?, ?, ?, ?)" (incomeUserId, incomeDate, incomeAmount, now) SQLite.lastInsertRowId conn ) editOwn :: UserId -> IncomeId -> Day -> Int -> Query Bool editOwn incomeUserId incomeId incomeDate incomeAmount = Query (\conn -> do mbIncome <- listToMaybe <$> SQLite.query conn "SELECT * FROM income WHERE id = ?" (Only incomeId) case mbIncome of Just income -> if 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 ) deleteOwn :: User -> IncomeId -> Query Bool deleteOwn user incomeId = Query (\conn -> do mbIncome <- listToMaybe <$> SQLite.query conn "SELECT * FROM income WHERE id = ?" (Only incomeId) case mbIncome of Just income -> if userId income == User.id user then do now <- getCurrentTime SQLite.execute conn "UPDATE income SET deleted_at = ? WHERE id = ?" (now, incomeId) return True else return False Nothing -> return False ) modifiedDuring :: UTCTime -> UTCTime -> Query [Income] modifiedDuring start end = Query (\conn -> SQLite.query conn "SELECT * FROM income WHERE (created_at >= ? AND created_at <= ?) OR (edited_at >= ? AND edited_at <= ?) OR (deleted_at >= ? AND deleted_at <= ?)" (start, end, start, end, start, end) )