Skip to content

Instantly share code, notes, and snippets.

@andizzle
Created November 17, 2017 03:38
Show Gist options
  • Save andizzle/a2cb185265ed901f7c5362b9adb0cff3 to your computer and use it in GitHub Desktop.
Save andizzle/a2cb185265ed901f7c5362b9adb0cff3 to your computer and use it in GitHub Desktop.
package cmds
import (
"context"
"strings"
"time"
"github.com/jinzhu/gorm"
"github.com/opensimsim/api-v3/errors"
"github.com/opensimsim/api-v3/kernel"
)
// GetAllHolidayGroupsCmd is used to fetch all of the owner's
// registered holiday groups.
type GetAllHolidayGroupsCmd struct {
ownerID string
db kernel.SQLCommon
}
// NewGetAllHolidayGroupsCmd - Creates a new GetAllHolidayGroupsCmd struct
func NewGetAllHolidayGroupsCmd(db kernel.SQLCommon, ownerID string) *GetAllHolidayGroupsCmd {
s := &GetAllHolidayGroupsCmd{
db: db,
ownerID: ownerID,
}
return s
}
type summaryResult struct {
ID string `gorm:"column:id;" json:"id"`
Name string `gorm:"column:name;" json:"name"`
GooglePlaceID string `gorm:"column:goo_place_id;" json:"google_place_id"`
}
// Handle - is the command handler for GetAllHolidayGroupsCmd
func (s *GetAllHolidayGroupsCmd) Handle(ctx context.Context) (interface{}, error) {
gormDB, err := gorm.Open("mysql", s.db)
if err != nil {
return nil, err
}
results := []summaryResult{}
gormDB = gormDB.
Table("holiday_groups").
Where("company_id = ?", s.ownerID).
Order("id")
if err := gormDB.Find(&results).Error; err != nil {
return nil, err
}
shell := map[string]interface{}{
"holidays": results,
}
return shell, nil
}
// GetDetailedHolidayGroupCmd is used to fetch detailed information of a specific holiday group
type GetDetailedHolidayGroupCmd struct {
groupID string
db kernel.SQLCommon
}
// NewGetDetailedHolidayGroupCmd - Creates struct
func NewGetDetailedHolidayGroupCmd(db kernel.SQLCommon, groupID string) *GetDetailedHolidayGroupCmd {
s := &GetDetailedHolidayGroupCmd{
db: db,
groupID: groupID,
}
return s
}
type rawResult struct {
GroupID string `gorm:"column:group_id;"`
GroupName string `gorm:"column:group_name;"`
GooglePlaceID string `gorm:"column:goo_place_id;"`
LocationID string `gorm:"column:location_id;"`
LocationName string `gorm:"column:location_name;"`
AvatarURL string `gorm:"column:avatar_url;"`
Name string `gorm:"column:name;"`
CreatedBy *string `gorm:"column:created_by;"`
Code string `gorm:"column:code;"`
City *string `gorm:"column:city;"`
Region *string `gorm:"column:region;"`
Country string `gorm:"column:country;"`
StartDate time.Time `gorm:"column:start_date;"`
EndDate time.Time `gorm:"column:end_date;"`
}
// Handle - is the command handler for GetDetailedHolidayGroupCmd
func (s *GetDetailedHolidayGroupCmd) Handle(ctx context.Context) (interface{}, error) {
gormDB, err := gorm.Open("mysql", s.db)
if err != nil {
return nil, err
}
var rawResults []rawResult
gormDB = gormDB.Table("holiday_groups").
Select("holiday_groups.id as group_id, holiday_groups.name as group_name, holiday_groups.goo_place_id, entities.id as location_id, entities.name as location_name, entities.avatar_url, holidays.*").
Joins("INNER JOIN holiday_group_locations ON holiday_groups.id = holiday_group_locations.group_id").
Joins("INNER JOIN holiday_group_codes ON holiday_group_codes.group_id = holiday_groups.id").
Joins("INNER JOIN holidays ON holiday_group_codes.holiday_code = holidays.code").
Joins("INNER JOIN entities ON entities.id = holiday_group_locations.location_id").
Where("holiday_groups.id = ?", s.groupID)
if err := gormDB.Find(&rawResults).Error; err != nil {
return nil, err
}
if len(rawResults) == 0 {
return nil, errors.NewNotFoundError("holiday_group")
}
//Process results
var (
groupID string
groupName string
groupGooglePlaceID string
)
groupID = rawResults[0].GroupID
groupName = rawResults[0].GroupName
groupGooglePlaceID = rawResults[0].GooglePlaceID
// We are using a map for testing for uniqueness
_locations := map[string]Location{}
dates := map[string]Holiday{}
currentTime := time.Now().UTC()
for _, v := range rawResults {
if _, ok := _locations[v.LocationID]; !ok {
_locations[v.LocationID] = Location{
ID: v.LocationID,
Name: v.LocationName,
AvatarURL: v.AvatarURL,
}
}
h := Holiday{
Name: v.Name,
Country: v.Country,
Code: v.Code,
Region: v.Region,
City: v.City,
Custom: v.CreatedBy != nil,
StartDate: strings.Replace(v.StartDate.Format("2006-01-02"), "Z", "", 1),
EndDate: strings.Replace(v.EndDate.Add(24*time.Hour).Add(-1*time.Second).Format("2006-01-02"), "Z", "", 1),
start: v.StartDate,
end: v.EndDate,
}
// Remove duplicate codes from origResults.
// Try and have at least 1 entry. If more than 1 entry, then always the upcoming holiday for a given code.
storedHoliday, exists := dates[v.Code]
if !exists {
//We are encountering this public holiday for the first time
dates[v.Code] = h
} else {
if !v.StartDate.After(currentTime) && v.StartDate.After(storedHoliday.start) {
//Replace
dates[v.Code] = h
} else if !v.StartDate.Before(currentTime) && v.StartDate.Before(storedHoliday.start) {
//Replace
dates[v.Code] = h
} else {
//Ignore this later day of the same holiday
continue
}
}
}
locations := []Location{}
for _, val := range _locations {
locations = append(locations, val)
}
shell := map[string]interface{}{
"holiday": map[string]interface{}{
"id": groupID,
"name": groupName,
"google_place_id": groupGooglePlaceID,
"locations": locations,
"days": dates,
},
}
return shell, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment