From 8c7a256c02db249da80c8f064f37c56d4102125d Mon Sep 17 00:00:00 2001 From: ciukstar Date: Fri, 3 Nov 2023 02:17:41 +0300 Subject: [PATCH] Add docs for section Business --- README.fr.md | 10 + README.md | 10 + README.ro.md | 10 + README.ru.md | 10 + config/routes.yesodroutes | 2 +- messages/en.msg | 13 +- messages/fr.msg | 13 +- messages/ro.msg | 13 +- messages/ru.msg | 13 +- src/Admin/Business.hs | 24 +- src/Admin/Staff.hs | 13 +- src/Demo/DemoDataEN.hs | 6 + src/Demo/DemoDataFR.hs | 261 +++++++++++++++-- src/Demo/DemoDataRO.hs | 261 +++++++++++++++-- src/Demo/DemoDataRU.hs | 262 ++++++++++++++++-- src/Handler/Resources.hs | 4 +- src/Handler/Stats.hs | 31 ++- src/Model.hs | 5 + .../admin/business/calendar/calendar.hamlet | 3 +- .../admin/business/calendar/slots/slot.hamlet | 2 +- .../business/calendar/slots/slots.hamlet | 2 +- templates/admin/business/hours/hours.cassius | 8 +- templates/admin/business/hours/hours.hamlet | 16 +- .../staff/empl/calendar/calendar.cassius | 4 +- .../admin/staff/empl/calendar/calendar.hamlet | 7 +- .../staff/empl/calendar/slots/slot.hamlet | 2 +- templates/admin/staff/empl/schedule.cassius | 2 +- templates/admin/staff/empl/schedule.hamlet | 16 +- templates/resources/docs.hamlet | 8 + templates/stats/workloads/workloads.cassius | 8 +- templates/stats/workloads/workloads.hamlet | 18 +- templates/stats/workloads/workloads.julius | 2 +- 32 files changed, 923 insertions(+), 136 deletions(-) diff --git a/README.fr.md b/README.fr.md index 56fadee..9d1e73f 100644 --- a/README.fr.md +++ b/README.fr.md @@ -17,6 +17,16 @@ Chaque service peut avoir plusieurs offres avec des prix et des devises correspo Une fois le service et ses offres définis, le service peut être publié. La prestation et les offres seront présentées au client dans la rubrique [« Services »](https://salonfr-w3cpovaqka-de.a.run.app/services) et disponibles à la réservation dans la rubrique [« Prenez rendez-vous »](https://salonfr-w3cpovaqka-de.a.run.app/book). +# Entités de base + +## Entreprise + +Des informations détaillées sur l'entreprise peuvent être fournies dans la section [« Entreprise »](https://salonfr-w3cpovaqka-de.a.run.app/admin/business) du groupe « Données » du menu principal. + +De plus, dans la section [« Entreprise »](https://salonfr-w3cpovaqka-de.a.run.app/admin/business), l'horaire de travail de l'organisation pour chaque jour peut être ajouté. + +Actuellement, l'application ne prend en charge qu'une seule entreprise. Un support multi-métiers est prévu pour les futures versions de l'application. + ## Diagramme ERD ![Diagramme entité-relation](static/img/Salon-ERD.svg) diff --git a/README.md b/README.md index e9528af..aa518de 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,16 @@ Each service can have multiple offers with corresponding prices and currencies. Once the service and its offerings are defined, the service can be published. The service and offers will be displayed to the customer in the section ["Services"](https://salon-w3cpovaqka-de.a.run.app/services) and available for booking in the section ["Book appointment"](https://salon-w3cpovaqka-de.a.run.app/book). +# Basic Entities + +## Business + +Detailed information about the business can be provided in the section ["Business"](https://salon-w3cpovaqka-de.a.run.app/admin/business) of the group "Data" in the main menu. + +Additionally, in the section ["Business"](https://salon-w3cpovaqka-de.a.run.app/admin/business), the organization's work schedule for each day can be added. + +Currently, the app only supports one business. Multi-business support is planned for future versions of the application. + ## ERD Diagram ![Entity Relationship Diagram](static/img/Salon-ERD.svg) diff --git a/README.ro.md b/README.ro.md index 262cf40..15d093d 100644 --- a/README.ro.md +++ b/README.ro.md @@ -17,6 +17,16 @@ Fiecare serviciu poate avea mai multe oferte cu prețuri și valute corespunzăt Odată ce serviciul și ofertele sale sunt definite, serviciul poate fi publicat. Serviciul și ofertele vor fi afișate clientului în secțiunea [„Servicii”](https://salonro-w3cpovaqka-de.a.run.app/services) și disponibile pentru rezervare în secțiunea [„Rezervă o programare”](https://salonro-w3cpovaqka-de.a.run.app/book). +# Entităţile de bază + +## Afacere + +Informații detaliate despre afacere pot fi furnizate în secțiunea [„Afacere”](https://salonro-w3cpovaqka-de.a.run.app/admin/business) din grupul „Date” din meniul principal. + +În plus, în secțiunea [„Afaceri”](https://salonro-w3cpovaqka-de.a.run.app/admin/business), poate fi adăugat programul de lucru al organizației pentru fiecare zi. + +În prezent, aplicația acceptă o singură afacere. Asistența multi-business este planificată pentru versiunile viitoare ale aplicației. + ## Diagrama ERD ![Diagrama Entitate-Relație](static/img/Salon-ERD.svg) diff --git a/README.ru.md b/README.ru.md index 0342267..9bfcb3f 100644 --- a/README.ru.md +++ b/README.ru.md @@ -17,6 +17,16 @@ После определения службы и ее предложений ее можно опубликовать. Услуга и предложения будут отображены клиенту в разделе [«Услуги»](https://salonru-w3cpovaqka-de.a.run.app/services) и доступны для бронирования в разделе [«Записаться на приём»](https://salonru-w3cpovaqka-de.a.run.app/book). +# Основные сущности + +## Организация + +Подробную информацию об организации можно предоставить в разделе [«Организация»](https://salonru-w3cpovaqka-de.a.run.app/admin/business) группы «Данные» главного меню. + +Дополнительно в разделе [«Организация»](https://salonru-w3cpovaqka-de.a.run.app/admin/business) можно добавить график работы организации на каждый день. + +В настоящее время приложение поддерживает только один бизнес. Поддержка нескольких организаций планируется в будущих версиях приложения. + ## ER-диаграмма ![Диаграмма отношений сущностей](static/img/Salon-ERD.svg) diff --git a/config/routes.yesodroutes b/config/routes.yesodroutes index 8fae51a..313302b 100644 --- a/config/routes.yesodroutes +++ b/config/routes.yesodroutes @@ -10,7 +10,7 @@ /requests/#BookId RequestR GET POST /requests RequestsR GET -/search/appointments AppointmentsSearchR GET +/search/appointments AppointmentsSearchR GET /appointments/#BookId/approve AppointmentApproveR POST /appointments/#BookId/reschedule AppointmentRescheduleR GET /appointments/#BookId/cancel AppointmentCancelR POST diff --git a/messages/en.msg b/messages/en.msg index 29ffd6d..f0d8e5d 100644 --- a/messages/en.msg +++ b/messages/en.msg @@ -1,3 +1,8 @@ +BasicEntities: Basic Entities +BusinessDay: Business day +SortDescending: Sort descending +SortAscending: Sort ascending +Sort: Sort Workday: Workday TimeSlot: Time slot CustomerRanking: Customer ranking @@ -304,4 +309,10 @@ Doc002 hrefServices@Text: The services to be advertised are defined and publishe Doc003: Each service can have multiple offers with corresponding prices and currencies. Offers are defined for each Service in the “Services” section in the “Data” group. -Doc004 hrefServices@Text hrefBook@Text: Once the service and its offerings are defined, the service can be published. The service and offers will be displayed to the customer in the section "Services" and available for booking in the section "Book appointment". \ No newline at end of file +Doc004 hrefServices@Text hrefBook@Text: Once the service and its offerings are defined, the service can be published. The service and offers will be displayed to the customer in the section "Services" and available for booking in the section "Book appointment". + +Doc005 hrefBusiness@Text: Detailed information about the business can be provided in the section "Business" of the group "Data" in the main menu. + +Doc006 hrefBusiness@Text: Additionally, in the section "Business", the organization's work schedule for each day can be added. + +Doc007: Currently, the app only supports one business. Multi-business support is planned for future versions of the application. \ No newline at end of file diff --git a/messages/fr.msg b/messages/fr.msg index f10619b..5f695da 100644 --- a/messages/fr.msg +++ b/messages/fr.msg @@ -1,3 +1,8 @@ +BasicEntities: Entités de base +BusinessDay: Jour ouvrable +SortDescending: Trier par ordre décroissant +SortAscending: Trier par ordre croissant +Sort: Trier Workday: Journée de travail TimeSlot: Créneau horaire CustomerRanking: Classement des clients @@ -304,4 +309,10 @@ Doc002 hrefServices: Les services à annoncer sont définis et publiés dans la Doc003: Chaque service peut avoir plusieurs offres avec des prix et des devises correspondants. Les offres sont définies pour chaque Service dans la rubrique « Services » du groupe « Données ». -Doc004 hrefServices hrefBook: Une fois le service et ses offres définis, le service peut être publié. La prestation et les offres seront présentées au client dans la rubrique « Services » et disponibles à la réservation dans la rubrique « Prenez rendez-vous ». \ No newline at end of file +Doc004 hrefServices hrefBook: Une fois le service et ses offres définis, le service peut être publié. La prestation et les offres seront présentées au client dans la rubrique « Services » et disponibles à la réservation dans la rubrique « Prenez rendez-vous ». + +Doc005 hrefBusiness: Des informations détaillées sur l'entreprise peuvent être fournies dans la section « Entreprise » du groupe « Données » du menu principal. + +Doc006 hrefBusiness: De plus, dans la section « Affaires », l'horaire de travail de l'organisation pour chaque jour peut être ajouté. + +Doc007: Actuellement, l'application ne prend en charge qu'une seule entreprise. Un support multi-métiers est prévu pour les futures versions de l'application. \ No newline at end of file diff --git a/messages/ro.msg b/messages/ro.msg index 3aa343c..1050a34 100644 --- a/messages/ro.msg +++ b/messages/ro.msg @@ -1,3 +1,8 @@ +BasicEntities: Entităţile de bază +BusinessDay: Zi de lucru +SortDescending: Sortează descrescător +SortAscending: Sortare ascendentă +Sort: Sortează Workday: Zi de lucru TimeSlot: Interval de timp CustomerRanking: Clasamentul clienților @@ -304,4 +309,10 @@ Doc002 hrefServices: Serviciile care vor fi promovate sunt definite și publicat Doc003: Fiecare serviciu poate avea mai multe oferte cu prețuri și valute corespunzătoare. Ofertele sunt definite pentru fiecare Serviciu în secțiunea „Servicii” din grupul „Date”. -Doc004 hrefServices hrefBook: Odată ce serviciul și ofertele sale sunt definite, serviciul poate fi publicat. Serviciul și ofertele vor fi afișate clientului în secțiunea „Servicii” și disponibile pentru rezervare în secțiunea „Rezervă o programare”. \ No newline at end of file +Doc004 hrefServices hrefBook: Odată ce serviciul și ofertele sale sunt definite, serviciul poate fi publicat. Serviciul și ofertele vor fi afișate clientului în secțiunea „Servicii” și disponibile pentru rezervare în secțiunea „Rezervă o programare”. + +Doc005 hrefBusiness: Informații detaliate despre afacere pot fi furnizate în secțiunea „Afacere” din grupul „Date” din meniul principal. + +Doc006 hrefBusiness: În plus, în secțiunea „Afaceri”, poate fi adăugat programul de lucru al organizației pentru fiecare zi. + +Doc007: În prezent, aplicația acceptă o singură afacere. Asistența multi-business este planificată pentru versiunile viitoare ale aplicației. \ No newline at end of file diff --git a/messages/ru.msg b/messages/ru.msg index e156ee7..aa752e7 100644 --- a/messages/ru.msg +++ b/messages/ru.msg @@ -1,3 +1,8 @@ +BasicEntities: Основные сущности +BusinessDay: Рабочий день +SortDescending: Сортировать по убыванию +SortAscending: Сортировать по возрастанию +Sort: Сортировать Workday: Рабочий день TimeSlot: Временной интервал CustomerRanking: Рейтинг клиентов @@ -304,4 +309,10 @@ Doc002 hrefServices: Рекламируемые услуги определен Doc003: Каждая услуга может иметь несколько предложений с соответствующими ценами и валютами. Предложения определены для каждой Услуги в разделе «Услуги» в группе «Данные». -Doc004 hrefServices hrefBook: После определения службы и ее предложений ее можно опубликовать. Услуга и предложения будут отображены клиенту в разделе «Услуги» и доступны для бронирования в разделе «Записаться на приём». \ No newline at end of file +Doc004 hrefServices hrefBook: После определения службы и ее предложений ее можно опубликовать. Услуга и предложения будут отображены клиенту в разделе «Услуги» и доступны для бронирования в разделе «Записаться на приём». + +Doc005 hrefBusiness: Подробную информацию об организации можно предоставить в разделе «Организация» группы «Данные» главного меню. + +Doc006 hrefBusiness: Дополнительно в разделе «Организация» можно добавить график работы организации на каждый день. + +Doc007: В настоящее время приложение поддерживает только один бизнес. Поддержка нескольких организаций планируется в будущих версиях приложения. \ No newline at end of file diff --git a/src/Admin/Business.hs b/src/Admin/Business.hs index 7443021..95d05fa 100644 --- a/src/Admin/Business.hs +++ b/src/Admin/Business.hs @@ -34,9 +34,8 @@ import Control.Monad.IO.Class (liftIO) import Data.Bifunctor (first) import Data.Fixed (mod') import qualified Data.Map.Lazy as M (fromListWith, lookup) -import Data.Maybe (isNothing, isJust) +import Data.Maybe (isNothing, isJust, fromMaybe) import Data.Text (Text, pack, unpack, intercalate) -import Text.Shakespeare.I18N (renderMessage) import Data.Time.Clock ( NominalDiffTime, getCurrentTime, utctDay, secondsToNominalDiffTime ) import Data.Time.Calendar @@ -50,13 +49,18 @@ import Data.Time.LocalTime ) import Data.Time.Format (formatTime, defaultTimeLocale) import Text.Hamlet (Html) +import Text.Shakespeare.I18N (renderMessage) +import Text.Read (readMaybe) import Yesod.Auth (maybeAuth, Route (LoginR)) import Yesod.Core ( Yesod(defaultLayout), getMessages, SomeMessage (SomeMessage) , redirect, addMessageI, newIdent ) -import Yesod.Core.Handler (setUltDestCurrent, getCurrentRoute, getYesod, languages) +import Yesod.Core.Handler + ( setUltDestCurrent, getCurrentRoute, getYesod, languages + ) import Yesod.Core.Widget (setTitleI) +import Yesod.Form.Input (runInputGet, iopt) import Yesod.Form.Fields ( textField, emailField, textareaField, intField, dayField, timeField , hiddenField @@ -101,7 +105,8 @@ import Foundation , MsgNoBusinessScheduleYet, MsgBusinessHours, MsgStartTime, MsgEndTime , MsgDayType, MsgWeekday, MsgWeekend, MsgHoliday, MsgInvalidTimeInterval , MsgList, MsgCalendar, MsgMon, MsgTue, MsgWed, MsgThu, MsgFri, MsgSat, MsgSun - , MsgSymbolHour, MsgSymbolMinute, MsgToday + , MsgSymbolHour, MsgSymbolMinute, MsgToday, MsgBusinessDay, MsgSortAscending + , MsgSortDescending ) ) @@ -123,6 +128,7 @@ import Model , BusinessHoursDayType ) , DayType (Weekday, Weekend, Holiday) + , SortOrder (SortOrderAsc, SortOrderDesc) ) import Settings (widgetFile) @@ -136,7 +142,6 @@ getBusinessCalendarSlotR bid day sid = do where_ $ x ^. BusinessHoursId ==. val sid return x dlgSlotDelete <- newIdent - let month = (\(y,m,_) -> YearMonth y m) . toGregorian defaultLayout $ do setTitleI MsgBusinessHours $(widgetFile "admin/business/calendar/slots/slot") @@ -243,12 +248,11 @@ getBusinessCalendarSlotsR bid day = do x <- from $ table @BusinessHours where_ $ x ^. BusinessHoursDay ==. val day return x - dlgSlotDelete <- newIdent let month = (\(y,m,_) -> YearMonth y m) . toGregorian fabSlotCreate <- newIdent msgs <- getMessages defaultLayout $ do - setTitleI MsgBusinessHours + setTitleI MsgBusinessDay $(widgetFile "admin/business/calendar/slots/slots") @@ -389,15 +393,19 @@ postBusinessHoursR bid = do getBusinessHoursR :: BusinessId -> Handler Html getBusinessHoursR bid = do + sort <- fromMaybe SortOrderDesc . (readMaybe . unpack =<<) <$> runInputGet (iopt textField "sort") slots <- runDB $ select $ do x <- from $ table @BusinessHours - orderBy [desc (x ^. BusinessHoursDay), asc (x ^. BusinessHoursOpen)] + case sort of + SortOrderAsc -> orderBy [asc (x ^. BusinessHoursDay), asc (x ^. BusinessHoursOpen)] + _ -> orderBy [desc (x ^. BusinessHoursDay), desc (x ^. BusinessHoursOpen)] return x user <- maybeAuth curr <- getCurrentRoute month <- (\(y,m,_) -> YearMonth y m) . toGregorian . utctDay <$> liftIO getCurrentTime setUltDestCurrent msgs <- getMessages + toolbarTop <- newIdent fabBusinessHoursCreate <- newIdent defaultLayout $ do setTitleI MsgBusinessDays diff --git a/src/Admin/Staff.hs b/src/Admin/Staff.hs index 71409ad..ae95ac4 100644 --- a/src/Admin/Staff.hs +++ b/src/Admin/Staff.hs @@ -63,6 +63,7 @@ import Data.Time.Clock import Data.Time.Format (formatTime, defaultTimeLocale, parseTimeM) import Data.Time.LocalTime (TimeOfDay, LocalTime (LocalTime), diffLocalTime) import Text.Hamlet (Html) +import Text.Read (readMaybe) import Data.FileEmbed (embedFile) import Data.Maybe (isJust, fromMaybe) import Control.Monad (forM) @@ -142,7 +143,7 @@ import Foundation , MsgWorkingHours, MsgDay, MsgStartTime, MsgEndTime, MsgDetails, MsgToday , MsgInvalidTimeInterval, MsgMon, MsgTue, MsgWed, MsgThu, MsgFri, MsgSat , MsgSun, MsgSymbolHour, MsgSymbolMinute, MsgInvalidFormData, MsgAdd - , MsgCompletionTime, MsgWorkday + , MsgCompletionTime, MsgWorkday, MsgSortAscending, MsgSortDescending ) ) @@ -161,6 +162,7 @@ import Model , ServiceId, Service (Service) , UserId, User (User), UserPhoto (UserPhoto) , EmplStatus (EmplStatusUnavailable, EmplStatusAvailable) + , SortOrder (SortOrderAsc, SortOrderDesc) ) import Settings.StaticFiles (img_add_photo_alternate_FILL0_wght400_GRAD0_opsz48_svg) @@ -299,7 +301,6 @@ $forall (v,icon) <- [(startV,"schedule"),(endV,"schedule")] getEmplCalendarSlotR :: StaffId -> ScheduleId -> Day -> Handler Html getEmplCalendarSlotR eid wid day = do - let month = (\(y,m,_) -> YearMonth y m) . toGregorian slot <- runDB $ selectOne $ do x <- from $ table @Schedule where_ $ x ^. ScheduleId ==. val wid @@ -401,6 +402,8 @@ getAdmEmplCalendarR eid month = do let next = addMonths 1 month let prev = addMonths (-1) month today <- (\(y,m,_) -> YearMonth y m) . toGregorian . utctDay <$> liftIO getCurrentTime + toolbarTop <- newIdent + calendarPage <- newIdent defaultLayout $ do setTitleI MsgEmployee $(widgetFile "admin/staff/empl/calendar/calendar") @@ -412,6 +415,7 @@ getAdmEmplCalendarR eid month = do getAdmScheduleR :: StaffId -> Handler Html getAdmScheduleR eid = do + sort <- fromMaybe SortOrderDesc . (readMaybe . unpack =<<) <$> runInputGet (iopt textField "sort") mwid <- runInputGet $ iopt textField "wid" scrollY <- runInputGet $ iopt textField "y" stati <- reqGetParams <$> getRequest @@ -423,12 +427,15 @@ getAdmScheduleR eid = do schedule <- runDB $ select $ do x <- from $ table @Schedule where_ $ x ^. ScheduleStaff ==. val eid - orderBy [desc (x ^. ScheduleWorkDay), desc (x ^. ScheduleWorkStart), desc (x ^. ScheduleWorkEnd)] + case sort of + SortOrderAsc -> orderBy [asc (x ^. ScheduleWorkDay), asc (x ^. ScheduleWorkStart)] + _ -> orderBy [desc (x ^. ScheduleWorkDay), desc (x ^. ScheduleWorkStart)] return x curr <- getCurrentRoute msgs <- getMessages touchTargetWrapperAddSchedule <- newIdent month <- (\(y,m,_) -> YearMonth y m) . toGregorian . utctDay <$> liftIO getCurrentTime + toolbarTop <- newIdent defaultLayout $ do setTitleI MsgEmployee $(widgetFile "admin/staff/empl/schedule") diff --git a/src/Demo/DemoDataEN.hs b/src/Demo/DemoDataEN.hs index 56d18b5..c1218d6 100644 --- a/src/Demo/DemoDataEN.hs +++ b/src/Demo/DemoDataEN.hs @@ -229,6 +229,12 @@ We will continue to offer the latest treatments, the most innovative techniques , scheduleWorkEnd = TimeOfDay 18 0 0 } + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = addDays 2 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + pass2 <- liftIO $ makePassword "marylopez" 17 let user2 = User { userName = "marylopez" , userPassword = decodeUtf8 pass2 diff --git a/src/Demo/DemoDataFR.hs b/src/Demo/DemoDataFR.hs index 959f601..a1f689e 100644 --- a/src/Demo/DemoDataFR.hs +++ b/src/Demo/DemoDataFR.hs @@ -14,7 +14,7 @@ import Data.Text.Lazy (toStrict) import Data.Time.Calendar (addDays) import Data.Time.Clock (getCurrentTime, UTCTime (utctDay,utctDayTime), DiffTime) import Data.Time.Format (parseTimeM, defaultTimeLocale) -import Data.Time.LocalTime (timeToTimeOfDay, TimeZone (TimeZone)) +import Data.Time.LocalTime (TimeOfDay (TimeOfDay), timeToTimeOfDay, TimeZone (TimeZone)) import Control.Monad.IO.Class (MonadIO (liftIO)) import ClassyPrelude.Yesod (ReaderT) import Yesod.Form.Fields (Textarea (Textarea)) @@ -58,6 +58,13 @@ import Model ( Hist, histBook, histLogtime, histDay, histTime, histAddr, histTzo , histStatus, histUser, histTz, histRoleName, histStaffName ) + , Schedule + ( Schedule, scheduleStaff, scheduleWorkDay, scheduleWorkStart, scheduleWorkEnd) + , BusinessHours + ( BusinessHours, businessHoursBusiness, businessHoursDay, businessHoursOpen + , businessHoursClose, businessHoursDayType + ) + , DayType (Weekday, Holiday) ) import Data.FileEmbed (embedFile) import Demo.DemoPhotos @@ -81,7 +88,35 @@ populateFR = do , businessEmail = Just "salon@mail.fr" } - insert_ business + b <- insert business + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = addDays (-1) today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 17 45 0 + , businessHoursDayType = Holiday + } + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 18 0 0 + , businessHoursDayType = Weekday + } + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = addDays 1 today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 18 0 0 + , businessHoursDayType = Weekday + } + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = addDays 2 today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 18 0 0 + , businessHoursDayType = Weekday + } insert_ $ Contents { contentsSection = "CONTACTS" , contentsContent = Textarea $ toStrict $ renderHtml [shamlet| @@ -175,6 +210,30 @@ Nous continuerons d'offrir les derniers traitements, les techniques les plus inn , userPhotoMime = "image/avif" } + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = addDays (-1) today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = addDays 1 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = addDays 2 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + pass2 <- liftIO $ makePassword "bernardj" 17 let user2 = User { userName = "bernardj" , userPassword = decodeUtf8 pass2 @@ -338,13 +397,15 @@ Nous continuerons d'offrir les derniers traitements, les techniques les plus inn , staffPhotoMime = "image/avif" } - e9 <- insert $ Staff { staffName = "Laurent Adam" - , staffStatus = EmplStatusAvailable - , staffPhone = businessPhone business - , staffMobile = businessMobile business - , staffEmail = Just "laurenta@mail.fr" - , staffUser = Nothing - } + let empl9 = Staff { staffName = "Laurent Adam" + , staffStatus = EmplStatusAvailable + , staffPhone = businessPhone business + , staffMobile = businessMobile business + , staffEmail = Just "laurenta@mail.fr" + , staffUser = Nothing + } + + e9 <- insert empl9 case B64.decode man05 of Left _ -> return () @@ -353,6 +414,42 @@ Nous continuerons d'offrir les derniers traitements, les techniques les plus inn , staffPhotoMime = "image/avif" } + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays (-2) today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays (-1) today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 0 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 1 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 2 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 3 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + e10 <- insert $ Staff { staffName = "Simon Maël Lucas" , staffStatus = EmplStatusAvailable , staffPhone = businessPhone business @@ -1215,13 +1312,13 @@ Votre visage est une toile expressive qui montre l'expérience et l'émotion. Da , serviceGroup = Just s2 } - insert_ $ Offer { offerService = s25 - , offerName = "Prix" - , offerPrice = 100 - , offerPrefix = Nothing - , offerSuffix = Just "€" - , offerDescr = Nothing - } + o251 <- insert $ Offer { offerService = s25 + , offerName = "Prix" + , offerPrice = 100 + , offerPrefix = Nothing + , offerSuffix = Just "€" + , offerDescr = Nothing + } insert_ $ Offer { offerService = s25 , offerName = "Forfait" @@ -1238,12 +1335,14 @@ Votre visage est une toile expressive qui montre l'expérience et l'émotion. Da Designed by Freepik|] } - insert_ $ Role { roleStaff = e9 - , roleService = s25 - , roleName = "Esthéticien" - , roleDuration = 60 * (1 * 60 + 15) - , roleRating = Just 5 - } + let role925 = Role { roleStaff = e9 + , roleService = s25 + , roleName = "Esthéticien" + , roleDuration = 60 * (1 * 60 + 15) + , roleRating = Just 5 + } + + r925 <- insert role925 insert_ $ Role { roleStaff = e10 , roleService = s25 @@ -1362,13 +1461,13 @@ Le Scientia Derma Roller est un appareil incroyable qui augmente naturellement l , serviceGroup = Just s3 } - insert_ $ Offer { offerService = s32 - , offerName = "Prix" - , offerPrice = 330 - , offerPrefix = Nothing - , offerSuffix = Just "€" - , offerDescr = Nothing - } + o321 <- insert $ Offer { offerService = s32 + , offerName = "Prix" + , offerPrice = 330 + , offerPrefix = Nothing + , offerSuffix = Just "€" + , offerDescr = Nothing + } insert_ $ Role { roleStaff = e7 , roleService = s32 @@ -2865,6 +2964,110 @@ Mise en forme du corps : Abdomen et taille, hanches et cuisses, jambes et bras , histRoleName = Nothing , histStaffName = Nothing } + + let book4 = Book { bookOffer = o251 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 1 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b4 <- insert book4 + + insert_ $ Hist { histBook = b4 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book4 + , histTime = bookTime book4 + , histAddr = bookAddr book4 + , histTzo = bookTzo book4 + , histTz = bookTz book4 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } + + let book5 = Book { bookOffer = o321 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 1 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b5 <- insert book5 + + insert_ $ Hist { histBook = b5 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book5 + , histTime = bookTime book5 + , histAddr = bookAddr book5 + , histTzo = bookTzo book5 + , histTz = bookTz book5 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } + + let book6 = Book { bookOffer = o321 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 2 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b6 <- insert book6 + + insert_ $ Hist { histBook = b6 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book6 + , histTime = bookTime book6 + , histAddr = bookAddr book6 + , histTzo = bookTzo book6 + , histTz = bookTz book6 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } + + let book7 = Book { bookOffer = o321 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 3 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b7 <- insert book7 + + insert_ $ Hist { histBook = b7 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book7 + , histTime = bookTime book7 + , histAddr = bookAddr book7 + , histTzo = bookTzo book7 + , histTz = bookTz book7 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } return () where duration :: String -> Maybe DiffTime diff --git a/src/Demo/DemoDataRO.hs b/src/Demo/DemoDataRO.hs index 773b7d3..5b190cd 100644 --- a/src/Demo/DemoDataRO.hs +++ b/src/Demo/DemoDataRO.hs @@ -14,7 +14,7 @@ import Data.Text.Lazy (toStrict) import Data.Time.Calendar (addDays) import Data.Time.Clock (getCurrentTime, UTCTime (utctDay,utctDayTime), DiffTime) import Data.Time.Format (parseTimeM, defaultTimeLocale) -import Data.Time.LocalTime (timeToTimeOfDay, TimeZone (TimeZone)) +import Data.Time.LocalTime (TimeOfDay (TimeOfDay), timeToTimeOfDay, TimeZone (TimeZone)) import Control.Monad.IO.Class (MonadIO (liftIO)) import ClassyPrelude.Yesod (ReaderT) import Yesod.Form.Fields (Textarea (Textarea)) @@ -58,6 +58,13 @@ import Model ( Hist, histBook, histLogtime, histDay, histTime, histAddr, histTzo , histStatus, histUser, histTz, histRoleName, histStaffName ) + , Schedule + ( Schedule, scheduleStaff, scheduleWorkDay, scheduleWorkStart, scheduleWorkEnd) + , BusinessHours + ( BusinessHours, businessHoursBusiness, businessHoursDay, businessHoursOpen + , businessHoursClose, businessHoursDayType + ) + , DayType (Weekday, Holiday) ) import Data.FileEmbed (embedFile) import Demo.DemoPhotos @@ -81,7 +88,35 @@ populateRO = do , businessEmail = Just "salon@mail.ro" } - insert_ business + b <- insert business + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = addDays (-1) today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 17 45 0 + , businessHoursDayType = Holiday + } + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 18 0 0 + , businessHoursDayType = Weekday + } + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = addDays 1 today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 18 0 0 + , businessHoursDayType = Weekday + } + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = addDays 2 today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 18 0 0 + , businessHoursDayType = Weekday + } insert_ $ Contents { contentsSection = "CONTACTS" , contentsContent = Textarea $ toStrict $ renderHtml [shamlet| @@ -172,6 +207,30 @@ populateRO = do , userPhotoMime = "image/avif" } + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = addDays (-1) today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = addDays 1 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = addDays 2 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + pass2 <- liftIO $ makePassword "raduam" 17 let user2 = User { userName = "raduam" , userPassword = decodeUtf8 pass2 @@ -335,13 +394,15 @@ populateRO = do , staffPhotoMime = "image/avif" } - e9 <- insert $ Staff { staffName = "Lazar Mihai" - , staffStatus = EmplStatusAvailable - , staffPhone = businessPhone business - , staffMobile = businessMobile business - , staffEmail = Just "lazarm@mail.ro" - , staffUser = Nothing - } + let empl9 = Staff { staffName = "Lazar Mihai" + , staffStatus = EmplStatusAvailable + , staffPhone = businessPhone business + , staffMobile = businessMobile business + , staffEmail = Just "lazarm@mail.ro" + , staffUser = Nothing + } + + e9 <- insert empl9 case B64.decode man05 of Left _ -> return () @@ -350,6 +411,42 @@ populateRO = do , staffPhotoMime = "image/avif" } + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays (-2) today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays (-1) today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 0 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 1 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 2 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 3 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + e10 <- insert $ Staff { staffName = "Ciobanu Ionuţ Ştefan" , staffStatus = EmplStatusAvailable , staffPhone = businessPhone business @@ -1214,13 +1311,13 @@ Fața ta este o pânză expresivă care arată experiența și emoția. Într-un , serviceGroup = Just s2 } - insert_ $ Offer { offerService = s25 - , offerName = "Preț" - , offerPrice = 100 - , offerPrefix = Nothing - , offerSuffix = Just "RON" - , offerDescr = Nothing - } + o251 <- insert $ Offer { offerService = s25 + , offerName = "Preț" + , offerPrice = 100 + , offerPrefix = Nothing + , offerSuffix = Just "RON" + , offerDescr = Nothing + } insert_ $ Offer { offerService = s25 , offerName = "Pachet" @@ -1237,12 +1334,14 @@ Fața ta este o pânză expresivă care arată experiența și emoția. Într-un Designed by Freepik|] } - insert_ $ Role { roleStaff = e9 - , roleService = s25 - , roleName = "Cosmetician" - , roleDuration = 60 * (1 * 60 + 15) - , roleRating = Just 5 - } + let role925 = Role { roleStaff = e9 + , roleService = s25 + , roleName = "Cosmetician" + , roleDuration = 60 * (1 * 60 + 15) + , roleRating = Just 5 + } + + r925 <- insert role925 insert_ $ Role { roleStaff = e10 , roleService = s25 @@ -1361,13 +1460,13 @@ Scientia Derma Roller este un dispozitiv incredibil care crește în mod natural , serviceGroup = Just s3 } - insert_ $ Offer { offerService = s32 - , offerName = "Preț" - , offerPrice = 330 - , offerPrefix = Nothing - , offerSuffix = Just "RON" - , offerDescr = Nothing - } + o321 <- insert $ Offer { offerService = s32 + , offerName = "Preț" + , offerPrice = 330 + , offerPrefix = Nothing + , offerSuffix = Just "RON" + , offerDescr = Nothing + } insert_ $ Role { roleStaff = e7 , roleService = s32 @@ -2864,6 +2963,110 @@ Pachetul include: machiaj de mireasă, up-do, tratament facial și manichiură , histRoleName = Nothing , histStaffName = Nothing } + + let book4 = Book { bookOffer = o251 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 1 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b4 <- insert book4 + + insert_ $ Hist { histBook = b4 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book4 + , histTime = bookTime book4 + , histAddr = bookAddr book4 + , histTzo = bookTzo book4 + , histTz = bookTz book4 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } + + let book5 = Book { bookOffer = o321 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 1 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b5 <- insert book5 + + insert_ $ Hist { histBook = b5 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book5 + , histTime = bookTime book5 + , histAddr = bookAddr book5 + , histTzo = bookTzo book5 + , histTz = bookTz book5 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } + + let book6 = Book { bookOffer = o321 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 2 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b6 <- insert book6 + + insert_ $ Hist { histBook = b6 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book6 + , histTime = bookTime book6 + , histAddr = bookAddr book6 + , histTzo = bookTzo book6 + , histTz = bookTz book6 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } + + let book7 = Book { bookOffer = o321 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 3 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b7 <- insert book7 + + insert_ $ Hist { histBook = b7 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book7 + , histTime = bookTime book7 + , histAddr = bookAddr book7 + , histTzo = bookTzo book7 + , histTz = bookTz book7 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } return () where duration :: String -> Maybe DiffTime diff --git a/src/Demo/DemoDataRU.hs b/src/Demo/DemoDataRU.hs index e1cc90a..7b29a60 100644 --- a/src/Demo/DemoDataRU.hs +++ b/src/Demo/DemoDataRU.hs @@ -14,7 +14,7 @@ import Data.Text.Lazy (toStrict) import Data.Time.Calendar (addDays) import Data.Time.Clock (getCurrentTime, UTCTime (utctDay,utctDayTime), DiffTime) import Data.Time.Format (parseTimeM, defaultTimeLocale) -import Data.Time.LocalTime (timeToTimeOfDay, TimeZone (TimeZone)) +import Data.Time.LocalTime (TimeOfDay (TimeOfDay), timeToTimeOfDay, TimeZone (TimeZone)) import Control.Monad.IO.Class (MonadIO (liftIO)) import ClassyPrelude.Yesod (ReaderT) import Yesod.Form.Fields (Textarea (Textarea)) @@ -52,6 +52,13 @@ import Model ( Hist, histBook, histLogtime, histDay, histTime, histAddr, histTzo , histStatus, histUser, histTz, histRoleName, histStaffName ) + , Schedule + ( Schedule, scheduleStaff, scheduleWorkDay, scheduleWorkStart, scheduleWorkEnd) + , BusinessHours + ( BusinessHours, businessHoursBusiness, businessHoursDay, businessHoursOpen + , businessHoursClose, businessHoursDayType + ) + , DayType (Weekday, Holiday) ) import Data.FileEmbed (embedFile) import Demo.DemoPhotos @@ -76,7 +83,35 @@ populateRU = do , businessEmail = Just "salon@mail.ru" } - insert_ business + b <- insert business + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = addDays (-1) today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 17 45 0 + , businessHoursDayType = Holiday + } + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 18 0 0 + , businessHoursDayType = Weekday + } + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = addDays 1 today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 18 0 0 + , businessHoursDayType = Weekday + } + + insert_ $ BusinessHours { businessHoursBusiness = b + , businessHoursDay = addDays 2 today + , businessHoursOpen = TimeOfDay 9 0 0 + , businessHoursClose = TimeOfDay 18 0 0 + , businessHoursDayType = Weekday + } insert_ $ Contents { contentsSection = "CONTACTS" , contentsContent = Textarea $ toStrict $ renderHtml [shamlet| @@ -170,6 +205,30 @@ populateRU = do , userPhotoMime = "image/avif" } + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = addDays (-1) today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = addDays 1 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e1 + , scheduleWorkDay = addDays 2 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + pass2 <- liftIO $ makePassword "bulanovalm" 17 let user2 = User { userName = "bulanovalm" , userPassword = decodeUtf8 pass2 @@ -334,14 +393,51 @@ populateRU = do , staffPhotoPhoto = x , staffPhotoMime = "image/avif" } + let empl9 = Staff { staffName = "Кузнецов Артем Сергеевич" + , staffStatus = EmplStatusAvailable + , staffPhone = businessPhone business + , staffMobile = businessMobile business + , staffEmail = Just "kuznetsovas@mail.ru" + , staffUser = Nothing + } - e9 <- insert $ Staff { staffName = "Кузнецов Артем Сергеевич" - , staffStatus = EmplStatusAvailable - , staffPhone = businessPhone business - , staffMobile = businessMobile business - , staffEmail = Just "kuznetsovas@mail.ru" - , staffUser = Nothing - } + e9 <- insert empl9 + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays (-2) today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays (-1) today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 0 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 1 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 2 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } + + insert_ $ Schedule { scheduleStaff = e9 + , scheduleWorkDay = addDays 3 today + , scheduleWorkStart = TimeOfDay 9 0 0 + , scheduleWorkEnd = TimeOfDay 18 0 0 + } case B64.decode man05 of Left _ -> return () @@ -1218,13 +1314,13 @@ populateRU = do , serviceGroup = Just s2 } - insert_ $ Offer { offerService = s25 - , offerName = "Цена" - , offerPrice = 10000 - , offerPrefix = Nothing - , offerSuffix = Just "₽" - , offerDescr = Nothing - } + o251 <- insert $ Offer { offerService = s25 + , offerName = "Цена" + , offerPrice = 10000 + , offerPrefix = Nothing + , offerSuffix = Just "₽" + , offerDescr = Nothing + } insert_ $ Offer { offerService = s25 , offerName = "Пакет" @@ -1241,12 +1337,14 @@ populateRU = do Designed by Freepik|] } - insert_ $ Role { roleStaff = e9 - , roleService = s25 - , roleName = "Косметолог" - , roleDuration = 60 * (1 * 60 + 15) - , roleRating = Just 5 - } + let role925 = Role { roleStaff = e9 + , roleService = s25 + , roleName = "Косметолог" + , roleDuration = 60 * (1 * 60 + 15) + , roleRating = Just 5 + } + + r925 <- insert role925 insert_ $ Role { roleStaff = e10 , roleService = s25 @@ -1364,13 +1462,13 @@ Milk Peel включает в себя натуральный экстракт , serviceGroup = Just s3 } - insert_ $ Offer { offerService = s32 - , offerName = "Цена" - , offerPrice = 33000 - , offerPrefix = Nothing - , offerSuffix = Just "₽" - , offerDescr = Nothing - } + o321 <- insert $ Offer { offerService = s32 + , offerName = "Цена" + , offerPrice = 33000 + , offerPrefix = Nothing + , offerSuffix = Just "₽" + , offerDescr = Nothing + } insert_ $ Role { roleStaff = e7 , roleService = s32 @@ -2866,7 +2964,111 @@ Collagen 90-II — это уважаемое и востребованное а , histStatus = BookStatusRequest , histRoleName = Nothing , histStaffName = Nothing - } + } + + let book4 = Book { bookOffer = o251 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 1 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b4 <- insert book4 + + insert_ $ Hist { histBook = b4 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book4 + , histTime = bookTime book4 + , histAddr = bookAddr book4 + , histTzo = bookTzo book4 + , histTz = bookTz book4 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } + + let book5 = Book { bookOffer = o321 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 1 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b5 <- insert book5 + + insert_ $ Hist { histBook = b5 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book5 + , histTime = bookTime book5 + , histAddr = bookAddr book5 + , histTzo = bookTzo book5 + , histTz = bookTz book5 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } + + let book6 = Book { bookOffer = o321 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 2 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b6 <- insert book6 + + insert_ $ Hist { histBook = b6 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book6 + , histTime = bookTime book6 + , histAddr = bookAddr book6 + , histTzo = bookTzo book6 + , histTz = bookTz book6 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } + + let book7 = Book { bookOffer = o321 + , bookRole = Just r925 + , bookCustomer = c1 + , bookDay = addDays 3 today + , bookTime = time + , bookAddr = businessAddr business + , bookTzo = businessTzo business + , bookTz = businessTz business + , bookStatus = BookStatusRequest + } + + b7 <- insert book7 + + insert_ $ Hist { histBook = b7 + , histUser = c1 + , histLogtime = now + , histDay = bookDay book7 + , histTime = bookTime book7 + , histAddr = bookAddr book7 + , histTzo = bookTzo book7 + , histTz = bookTz book7 + , histStatus = BookStatusRequest + , histRoleName = Just $ roleName role925 + , histStaffName = Just $ staffName empl9 + } return () where diff --git a/src/Handler/Resources.hs b/src/Handler/Resources.hs index 27e4eb4..193ce43 100644 --- a/src/Handler/Resources.hs +++ b/src/Handler/Resources.hs @@ -19,11 +19,13 @@ import Foundation ( StaticR, AuthR, PhotoPlaceholderR, AccountPhotoR , ProfileR, AdminR, HomeR, ServicesR, BookOffersR ) - , AdminR (AdmServicesR) + , AdminR (AdmServicesR, BusinessR) , AppMessage ( MsgDocumentation, MsgPhoto, MsgNavigationMenu, MsgLogin, MsgUserProfile , MsgErdDiagram, MsgBookingStateDiagram, MsgAppointmentStateDiagram + , MsgBasicEntities, MsgBusiness , MsgAppName, MsgOverview, MsgDoc001, MsgDoc002, MsgDoc003, MsgDoc004 + , MsgDoc005, MsgDoc006, MsgDoc007 ) ) diff --git a/src/Handler/Stats.hs b/src/Handler/Stats.hs index 59e59d0..54e4614 100644 --- a/src/Handler/Stats.hs +++ b/src/Handler/Stats.hs @@ -15,6 +15,7 @@ module Handler.Stats import Control.Monad.IO.Class (liftIO) import Data.Bifunctor (second) import Data.Foldable (find) +import Data.List (sortBy) import Data.Maybe (fromMaybe, isJust) import Data.Text (pack, unpack, intercalate) import Data.Time.Calendar @@ -28,6 +29,7 @@ import Data.Time.LocalTime (timeOfDayToTime) import qualified Data.Map.Lazy as M (fromListWith, fromList, toList) import qualified Data.Map.Merge.Lazy as ML (merge, mapMissing, zipWithMatched) import Text.Hamlet (Html) +import Text.Read (readMaybe) import Text.Shakespeare.I18N (SomeMessage (SomeMessage), renderMessage) import Yesod.Auth (maybeAuth, Route (LoginR)) import Yesod.Core (defaultLayout) @@ -36,7 +38,7 @@ import Yesod.Core.Handler ) import Yesod.Core.Widget (setTitleI, whamlet) import Yesod.Form.Input (runInputGet, iopt) -import Yesod.Form.Fields (dayField) +import Yesod.Form.Fields (dayField, textField) import Yesod.Form.Functions (check, generateFormGet', runFormGet, mreq) import Yesod.Form.Types ( Field, MForm, FormResult (FormSuccess, FormMissing, FormFailure) @@ -65,7 +67,8 @@ import Foundation , MsgSelect, MsgCancel, MsgPeriod, MsgBetweenFrom, MsgBetweenTo, MsgBack , MsgInvalidFormData, MsgInvalidTimeInterval, MsgNoDataFound, MsgMon , MsgTue, MsgWed, MsgThu, MsgFri, MsgSat, MsgSun, MsgTotalBookedTime - , MsgTotalScheduledTime, MsgSymbolMinute, MsgSymbolHour + , MsgTotalScheduledTime, MsgSymbolMinute, MsgSymbolHour, MsgSortAscending + , MsgSortDescending ) ) @@ -77,6 +80,7 @@ import Model , StaffId, BookDay, RoleDuration, ScheduleStaff, ScheduleWorkDay, ScheduleWorkEnd , ScheduleWorkStart, StaffName ) + , SortOrder (SortOrderAsc, SortOrderDesc) ) import Settings (widgetFile) @@ -189,12 +193,12 @@ getWorkloadEmplMonthR eid month = do getWorkloadsR :: Handler Html getWorkloadsR = do - stati <- reqGetParams <$> getRequest + stati <- filter ((/= "sort") . fst) . reqGetParams <$> getRequest today <- liftIO (utctDay <$> getCurrentTime) start <- fromMaybe today <$> runInputGet (iopt dayField "start") end <- fromMaybe today <$> runInputGet (iopt dayField "end") - + sort <- fromMaybe SortOrderDesc . (readMaybe . unpack =<<) <$> runInputGet (iopt textField "sort") booked <- (unwrap <$>) <$> runDB ( select $ do b :& r :& e <- from $ table @Book @@ -213,7 +217,7 @@ getWorkloadsR = do where_ $ s ^. ScheduleWorkDay `between` (val start, val end) return (e ^. StaffId, e ^. StaffName, s ^. ScheduleWorkStart, s ^. ScheduleWorkEnd) ) ) - let ratios = M.toList $ ML.merge + let ratios = sortBy (choose sort) . M.toList $ ML.merge (ML.mapMissing $ \ _ _ -> 0) (ML.mapMissing $ \ _ _ -> 0) (ML.zipWithMatched $ \ _ x y -> (if 0 == y then 0 else x / y :: Double)) @@ -222,11 +226,11 @@ getWorkloadsR = do user <- maybeAuth setUltDestCurrent - toolbar <- newIdent + toolbarTop <- newIdent dlgTimeFrame <- newIdent formTimeFrame <- newIdent - ((fr,fw),et) <- runFormGet $ formPeriod start end + ((fr,fw0),et0) <- runFormGet $ formPeriod start end case fr of FormMissing -> do (fw,et) <- generateFormGet' $ formPeriod start end @@ -234,14 +238,17 @@ getWorkloadsR = do setTitleI MsgWorkload $(widgetFile "stats/workloads/workloads") - _ -> defaultLayout $ do - setTitleI MsgWorkload - $(widgetFile "stats/workloads/workloads") - - + _ -> do + let (fw,et) = (fw0,et0) + defaultLayout $ do + setTitleI MsgWorkload + $(widgetFile "stats/workloads/workloads") where + choose SortOrderAsc (_,x) (_,y) = x `compare` y + choose SortOrderDesc (_,x) (_,y) = y `compare` x + unwrap (Value eid,Value ename,Value dur) = ((eid,ename),dur) calcdur (Value eid,Value ename,Value start,Value end) = diff --git a/src/Model.hs b/src/Model.hs index a62d4f1..14da431 100644 --- a/src/Model.hs +++ b/src/Model.hs @@ -212,6 +212,11 @@ instance HashDBUser User where setPasswordHash :: Text -> User -> User setPasswordHash h u = u { userPassword = h } + +data SortOrder = SortOrderAsc | SortOrderDesc + deriving (Eq, Show, Read) + + instance SqlString Textarea diff --git a/templates/admin/business/calendar/calendar.hamlet b/templates/admin/business/calendar/calendar.hamlet index 1aa0401..f0f60f7 100644 --- a/templates/admin/business/calendar/calendar.hamlet +++ b/templates/admin/business/calendar/calendar.hamlet @@ -79,7 +79,8 @@ list _{MsgList} - + today diff --git a/templates/admin/business/calendar/slots/slot.hamlet b/templates/admin/business/calendar/slots/slot.hamlet index ac97599..61acc35 100644 --- a/templates/admin/business/calendar/slots/slot.hamlet +++ b/templates/admin/business/calendar/slots/slot.hamlet @@ -2,7 +2,7 @@ + href=@{AdminR $ BusinessCalendarSlotsR bid day}> arrow_back diff --git a/templates/admin/business/calendar/slots/slots.hamlet b/templates/admin/business/calendar/slots/slots.hamlet index 44313e8..6aa7a4e 100644 --- a/templates/admin/business/calendar/slots/slots.hamlet +++ b/templates/admin/business/calendar/slots/slots.hamlet @@ -6,7 +6,7 @@ arrow_back - _{MsgBusinessHours} + _{MsgBusinessDay} diff --git a/templates/admin/business/hours/hours.cassius b/templates/admin/business/hours/hours.cassius index 7f0d55d..cc258cc 100644 --- a/templates/admin/business/hours/hours.cassius +++ b/templates/admin/business/hours/hours.cassius @@ -15,8 +15,12 @@ header height: 56px main - div.toolbar - margin-left: 1rem + ##{toolbarTop} + display: flex + flex-direction: row + justify-content: space-between + align-items: center + margin: 1rem 1rem 0 1rem a.mdc-segmented-button__segment border-width: 1px border-style: solid diff --git a/templates/admin/business/hours/hours.hamlet b/templates/admin/business/hours/hours.hamlet index 27f28c5..b3b0699 100644 --- a/templates/admin/business/hours/hours.hamlet +++ b/templates/admin/business/hours/hours.hamlet @@ -62,7 +62,7 @@ close - + list _{MsgList} + $case sort + $of SortOrderAsc + + + + sort + $of SortOrderDesc + + + + sort + $if null slots
∅ diff --git a/templates/admin/staff/empl/calendar/calendar.cassius b/templates/admin/staff/empl/calendar/calendar.cassius index ad972c7..f48ca43 100644 --- a/templates/admin/staff/empl/calendar/calendar.cassius +++ b/templates/admin/staff/empl/calendar/calendar.cassius @@ -14,7 +14,7 @@ main .mdc-tab-indicator.mdc-tab-indicator--active .mdc-tab-indicator__content--underline border-color: var(--mdc-theme-on-primary) - div.toolbar + ##{toolbarTop} padding: 1rem 1rem 0.5rem 1rem display: flex flex-direction: row @@ -24,7 +24,7 @@ main border-width: 1px border-style: solid - div.calendar + ##{calendarPage} display: grid gap: 0.5rem padding: 0 0.5rem diff --git a/templates/admin/staff/empl/calendar/calendar.hamlet b/templates/admin/staff/empl/calendar/calendar.hamlet index 031b51f..eac886a 100644 --- a/templates/admin/staff/empl/calendar/calendar.hamlet +++ b/templates/admin/staff/empl/calendar/calendar.hamlet @@ -49,7 +49,7 @@ - + list _{MsgList} - + today - + diff --git a/templates/admin/staff/empl/calendar/slots/slot.hamlet b/templates/admin/staff/empl/calendar/slots/slot.hamlet index 776aa75..b775981 100644 --- a/templates/admin/staff/empl/calendar/slots/slot.hamlet +++ b/templates/admin/staff/empl/calendar/slots/slot.hamlet @@ -2,7 +2,7 @@ + href=@{AdminR $ EmplCalendarSlotsR eid day}> arrow_back diff --git a/templates/admin/staff/empl/schedule.cassius b/templates/admin/staff/empl/schedule.cassius index 9389a5e..cc1b544 100644 --- a/templates/admin/staff/empl/schedule.cassius +++ b/templates/admin/staff/empl/schedule.cassius @@ -14,7 +14,7 @@ main .mdc-tab-indicator.mdc-tab-indicator--active .mdc-tab-indicator__content--underline border-color: var(--mdc-theme-on-primary) - div.toolbar + ##{toolbarTop} padding: 1rem 1rem 0.5rem 1rem display: flex flex-direction: row diff --git a/templates/admin/staff/empl/schedule.hamlet b/templates/admin/staff/empl/schedule.hamlet index 5960d1b..03b9f33 100644 --- a/templates/admin/staff/empl/schedule.hamlet +++ b/templates/admin/staff/empl/schedule.hamlet @@ -49,7 +49,7 @@ - + list _{MsgList} + $case sort + $of SortOrderAsc + + + + sort + $of SortOrderDesc + + + + sort + $if null schedule
diff --git a/templates/resources/docs.hamlet b/templates/resources/docs.hamlet index 378f69e..331cb00 100644 --- a/templates/resources/docs.hamlet +++ b/templates/resources/docs.hamlet @@ -30,6 +30,14 @@

_{MsgDoc003}

#{preEscapedToMarkup $ renderMessage app langs (MsgDoc004 (rndr ServicesR) (rndr BookOffersR))} + + _{MsgBasicEntities} + + _{MsgBusiness} +

#{preEscapedToMarkup $ renderMessage app langs (MsgDoc005 (rndr $ AdminR BusinessR))} +

#{preEscapedToMarkup $ renderMessage app langs (MsgDoc006 (rndr $ AdminR BusinessR))} +

_{MsgDoc007} + _{MsgErdDiagram} _{MsgErdDiagram} diff --git a/templates/stats/workloads/workloads.cassius b/templates/stats/workloads/workloads.cassius index db47787..5c0f519 100644 --- a/templates/stats/workloads/workloads.cassius +++ b/templates/stats/workloads/workloads.cassius @@ -1,7 +1,11 @@ main - ##{toolbar} - padding: 1rem + ##{toolbarTop} + margin: 1rem 1rem 1rem 0 + display: flex + flex-direction: row + justify-content: space-between + align-items: center ##{dlgTimeFrame} ##{formTimeFrame} diff --git a/templates/stats/workloads/workloads.hamlet b/templates/stats/workloads/workloads.hamlet index 113a5c3..d381dca 100644 --- a/templates/stats/workloads/workloads.hamlet +++ b/templates/stats/workloads/workloads.hamlet @@ -38,7 +38,7 @@ close $of _ -

+ @@ -50,6 +50,20 @@ #{e} arrow_drop_down + $case sort + $of SortOrderAsc + + + + sort + $of SortOrderDesc + + + + sort + $if null ratios
@@ -58,7 +72,7 @@ $else $forall ((eid,ename),ratio) <- ratios + href=@?{(StatsR $ WorkloadEmplMonthR eid (dayPeriod end),((++) [("sort",pack $ show sort)] stati))}> _{MsgPhoto} diff --git a/templates/stats/workloads/workloads.julius b/templates/stats/workloads/workloads.julius index 96150be..afacc0c 100644 --- a/templates/stats/workloads/workloads.julius +++ b/templates/stats/workloads/workloads.julius @@ -1,6 +1,6 @@ Array.from( - document.getElementById(#{toolbar}).querySelectorAll('time.period') + document.getElementById(#{toolbarTop}).querySelectorAll('time.period') ).forEach(function (x) { x.textContent = new Date(x.getAttribute('datetime')).toLocaleDateString( navigator.language,