1
0
Fork 0
mirror of https://code.sup39.dev/repos/Wqawg synced 2025-01-10 16:16:46 +09:00
vervis/src/Vervis/Handler/Ticket.hs

235 lines
8.5 KiB
Haskell
Raw Normal View History

2016-05-01 07:32:22 +09:00
{- This file is part of Vervis.
-
- Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
-
- Copying is an act of love. Please copy, reuse and share.
-
- The author(s) have dedicated all copyright and related and neighboring
- rights to this software to the public domain worldwide. This software is
- distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along
- with this software. If not, see
- <http://creativecommons.org/publicdomain/zero/1.0/>.
-}
module Vervis.Handler.Ticket
( getTicketsR
, postTicketsR
, getTicketNewR
2016-05-01 08:02:44 +09:00
, getTicketR
, putTicketR
, deleteTicketR
, postTicketR
, getTicketEditR
2016-05-20 01:58:23 +09:00
, getTicketDiscussionR
, postTicketDiscussionR
2016-05-20 07:07:25 +09:00
, getTicketMessageR
, postTicketMessageR
, getTicketTopReplyR
, getTicketReplyR
2016-05-01 07:32:22 +09:00
)
where
import Prelude
import Control.Monad.IO.Class (liftIO)
2016-05-01 18:58:55 +09:00
import Data.Maybe (fromMaybe)
2016-05-01 07:32:22 +09:00
import Data.Text (Text)
import Data.Time.Calendar (Day (..))
import Data.Time.Clock (UTCTime (..), getCurrentTime)
2016-05-01 18:58:55 +09:00
import Data.Time.Format (formatTime, defaultTimeLocale)
2016-05-01 19:15:38 +09:00
import Database.Esqueleto hiding ((==.), (+=.), update)
2016-05-01 08:02:44 +09:00
import Database.Persist
2016-05-01 07:32:22 +09:00
import Text.Blaze.Html (Html, toHtml)
2016-05-01 18:58:55 +09:00
import Yesod.Auth (requireAuthId)
2016-05-01 07:32:22 +09:00
import Yesod.Core (defaultLayout)
import Yesod.Core.Handler (setMessage, redirect, lookupPostParam, notFound)
2016-05-01 07:32:22 +09:00
import Yesod.Form.Functions (runFormPost)
2016-05-01 19:15:38 +09:00
import Yesod.Form.Types (FormResult (..))
2016-05-01 18:58:55 +09:00
import Yesod.Persist.Core (runDB, get404, getBy404)
2016-05-01 07:32:22 +09:00
import qualified Data.Text as T (filter, intercalate, pack)
2016-05-01 18:58:55 +09:00
import qualified Database.Esqueleto as E ((==.))
2016-05-01 07:32:22 +09:00
import Vervis.Form.Ticket
import Vervis.Foundation
2016-05-20 01:58:23 +09:00
import Vervis.Handler.Discussion
import Vervis.MediaType (MediaType (Markdown))
2016-05-01 07:32:22 +09:00
import Vervis.Model
import Vervis.Render (renderSourceT)
2016-05-01 07:32:22 +09:00
import Vervis.Settings (widgetFile)
import Vervis.Widget.Discussion (discussionW)
2016-05-01 07:32:22 +09:00
getTicketsR :: Text -> Text -> Handler Html
2016-05-01 08:02:44 +09:00
getTicketsR shar proj = do
rows <- runDB $ select $ from $ \ (sharer, project, ticket) -> do
2016-05-01 18:58:55 +09:00
where_ $
sharer ^. SharerIdent E.==. val shar &&.
project ^. ProjectSharer E.==. sharer ^. SharerId &&.
project ^. ProjectIdent E.==. val proj &&.
ticket ^. TicketProject E.==. project ^. ProjectId
2016-05-01 18:58:55 +09:00
orderBy [asc $ ticket ^. TicketNumber]
return
( ticket ^. TicketNumber
, sharer ^. SharerIdent
, sharer ^. SharerName
, ticket ^. TicketTitle
, ticket ^. TicketDone
)
defaultLayout $(widgetFile "ticket/list")
2016-05-01 07:32:22 +09:00
postTicketsR :: Text -> Text -> Handler Html
2016-05-01 19:15:38 +09:00
postTicketsR shar proj = do
2016-05-20 07:07:25 +09:00
((result, widget), enctype) <- runFormPost newTicketForm
2016-05-01 19:15:38 +09:00
case result of
FormSuccess nt -> do
author <- requireAuthId
now <- liftIO getCurrentTime
tnum <- runDB $ do
Entity pid project <- do
Entity sid _sharer <- getBy404 $ UniqueSharerIdent shar
getBy404 $ UniqueProject proj sid
2016-05-18 18:44:32 +09:00
update pid [ProjectNextTicket +=. 1]
2016-05-20 01:58:23 +09:00
let discussion = Discussion
{ discussionNextMessage = 1
}
did <- insert discussion
let ticket = Ticket
{ ticketProject = pid
, ticketNumber = projectNextTicket project
, ticketCreated = now
, ticketCreator = author
, ticketTitle = ntTitle nt
, ticketDesc = ntDesc nt
, ticketDone = False
, ticketClosed = UTCTime (ModifiedJulianDay 0) 0
, ticketCloser = author
2016-05-18 18:44:32 +09:00
, ticketDiscuss = did
}
2016-05-01 19:15:38 +09:00
insert_ ticket
return $ ticketNumber ticket
2016-05-01 19:15:38 +09:00
setMessage "Ticket created."
redirect $ TicketR shar proj tnum
2016-05-01 19:15:38 +09:00
FormMissing -> do
setMessage "Field(s) missing."
defaultLayout $(widgetFile "ticket/new")
FormFailure _l -> do
setMessage "Ticket creation failed, see errors below."
defaultLayout $(widgetFile "ticket/new")
2016-05-01 07:32:22 +09:00
getTicketNewR :: Text -> Text -> Handler Html
getTicketNewR shar proj = do
((_result, widget), enctype) <- runFormPost newTicketForm
defaultLayout $(widgetFile "ticket/new")
2016-05-01 08:02:44 +09:00
getTicketR :: Text -> Text -> Int -> Handler Html
2016-05-01 18:58:55 +09:00
getTicketR shar proj num = do
2016-05-02 18:15:10 +09:00
(author, closer, ticket) <- runDB $ do
2016-05-01 18:58:55 +09:00
Entity sid _sharer <- getBy404 $ UniqueSharerIdent shar
Entity pid _project <- getBy404 $ UniqueProject proj sid
Entity _tid ticket <- getBy404 $ UniqueTicket pid num
person <- get404 $ ticketCreator ticket
author <- get404 $ personIdent person
2016-05-02 18:15:10 +09:00
closer <-
if ticketDone ticket
then do
person' <- get404 $ ticketCloser ticket
get404 $ personIdent person'
else return author
return (author, closer, ticket)
let desc = renderSourceT Markdown $ T.filter (/= '\r') $ ticketDesc ticket
2016-05-20 01:58:23 +09:00
defaultLayout $(widgetFile "ticket/one")
putTicketR :: Text -> Text -> Int -> Handler Html
2016-05-02 18:15:10 +09:00
putTicketR shar proj num = do
Entity tid ticket <- runDB $ do
Entity sid _sharer <- getBy404 $ UniqueSharerIdent shar
Entity pid _project <- getBy404 $ UniqueProject proj sid
getBy404 $ UniqueTicket pid num
user <- requireAuthId
((result, widget), enctype) <- runFormPost $ editTicketForm ticket user
case result of
FormSuccess ticket' -> do
runDB $ replace tid ticket'
2016-05-02 20:33:30 +09:00
setMessage "Ticket updated."
2016-05-02 18:15:10 +09:00
redirect $ TicketR shar proj num
FormMissing -> do
setMessage "Field(s) missing."
defaultLayout $(widgetFile "ticket/edit")
FormFailure _l -> do
setMessage "Ticket update failed, see errors below."
defaultLayout $(widgetFile "ticket/edit")
deleteTicketR :: Text -> Text -> Int -> Handler Html
2016-05-02 18:15:10 +09:00
deleteTicketR shar proj num =
--TODO: I can easily implement this, but should it even be possible to
--delete tickets?
error "Not implemented"
postTicketR :: Text -> Text -> Int -> Handler Html
postTicketR shar proj num = do
mmethod <- lookupPostParam "_method"
case mmethod of
Just "PUT" -> putTicketR shar proj num
Just "DELETE" -> deleteTicketR shar proj num
_ -> notFound
getTicketEditR :: Text -> Text -> Int -> Handler Html
2016-05-02 18:15:10 +09:00
getTicketEditR shar proj num = do
Entity _tid ticket <- runDB $ do
Entity sid _sharer <- getBy404 $ UniqueSharerIdent shar
Entity pid _project <- getBy404 $ UniqueProject proj sid
getBy404 $ UniqueTicket pid num
user <- requireAuthId
((_result, widget), enctype) <- runFormPost $ editTicketForm ticket user
2016-05-20 01:58:23 +09:00
defaultLayout $(widgetFile "ticket/edit")
2016-05-20 07:07:25 +09:00
selectDiscussionId :: Text -> Text -> Int -> AppDB DiscussionId
selectDiscussionId shar proj tnum = do
Entity sid _sharer <- getBy404 $ UniqueSharerIdent shar
Entity pid _project <- getBy404 $ UniqueProject proj sid
Entity _tid ticket <- getBy404 $ UniqueTicket pid tnum
return $ ticketDiscuss ticket
2016-05-20 01:58:23 +09:00
getTicketDiscussionR :: Text -> Text -> Int -> Handler Html
getTicketDiscussionR shar proj num =
getDiscussion
(TicketReplyR shar proj num)
(selectDiscussionId shar proj num)
2016-05-20 01:58:23 +09:00
postTicketDiscussionR :: Text -> Text -> Int -> Handler Html
postTicketDiscussionR shar proj num =
postTopReply
(TicketDiscussionR shar proj num)
(const $ TicketR shar proj num)
(selectDiscussionId shar proj num)
2016-05-20 07:07:25 +09:00
getTicketMessageR :: Text -> Text -> Int -> Int -> Handler Html
getTicketMessageR shar proj tnum cnum =
getMessage
(TicketReplyR shar proj tnum)
(selectDiscussionId shar proj tnum)
cnum
2016-05-20 07:07:25 +09:00
postTicketMessageR :: Text -> Text -> Int -> Int -> Handler Html
postTicketMessageR shar proj tnum cnum =
2016-05-20 07:07:25 +09:00
postReply
(TicketReplyR shar proj tnum)
(TicketMessageR shar proj tnum)
(const $ TicketR shar proj tnum)
(selectDiscussionId shar proj tnum)
2016-05-20 07:07:25 +09:00
cnum
getTicketTopReplyR :: Text -> Text -> Int -> Handler Html
getTicketTopReplyR shar proj num =
getTopReply $ TicketDiscussionR shar proj num
2016-05-20 07:07:25 +09:00
getTicketReplyR :: Text -> Text -> Int -> Int -> Handler Html
getTicketReplyR shar proj tnum cnum =
2016-05-20 07:07:25 +09:00
getReply
(TicketReplyR shar proj tnum)
(TicketMessageR shar proj tnum)
(selectDiscussionId shar proj tnum)
2016-05-20 07:07:25 +09:00
cnum