103 lines
3.2 KiB
Go
103 lines
3.2 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
const (
|
|
RecurrenceNone = "none"
|
|
RecurrenceDaily = "daily"
|
|
RecurrenceWeekly = "weekly"
|
|
RecurrenceMonthly = "monthly"
|
|
)
|
|
|
|
const (
|
|
EndTypeNever = "never"
|
|
EndTypeCount = "count"
|
|
EndTypeDate = "date"
|
|
)
|
|
|
|
const (
|
|
EditBehaviorThisOnly = "this_only"
|
|
EditBehaviorThisAndFuture = "this_and_future"
|
|
EditBehaviorAll = "all"
|
|
)
|
|
|
|
type RecurringAssignment struct {
|
|
ID uint `gorm:"primarykey" json:"id"`
|
|
UserID uint `gorm:"not null;index" json:"user_id"`
|
|
Title string `gorm:"not null" json:"title"`
|
|
Description string `json:"description"`
|
|
Subject string `json:"subject"`
|
|
Priority string `gorm:"not null;default:medium" json:"priority"`
|
|
|
|
RecurrenceType string `gorm:"not null;default:none" json:"recurrence_type"`
|
|
RecurrenceInterval int `gorm:"not null;default:1" json:"recurrence_interval"`
|
|
RecurrenceWeekday *int `json:"recurrence_weekday,omitempty"`
|
|
RecurrenceDay *int `json:"recurrence_day,omitempty"`
|
|
DueTime string `gorm:"not null" json:"due_time"`
|
|
|
|
EndType string `gorm:"not null;default:never" json:"end_type"`
|
|
EndCount *int `json:"end_count,omitempty"`
|
|
EndDate *time.Time `json:"end_date,omitempty"`
|
|
GeneratedCount int `gorm:"default:0" json:"generated_count"`
|
|
EditBehavior string `gorm:"not null;default:this_only" json:"edit_behavior"`
|
|
|
|
ReminderEnabled bool `gorm:"default:false" json:"reminder_enabled"`
|
|
ReminderOffset *int `json:"reminder_offset,omitempty"`
|
|
UrgentReminderEnabled bool `gorm:"default:true" json:"urgent_reminder_enabled"`
|
|
IsActive bool `gorm:"default:true" json:"is_active"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
|
|
|
User *User `gorm:"foreignKey:UserID" json:"user,omitempty"`
|
|
Assignments []Assignment `gorm:"foreignKey:RecurringAssignmentID" json:"assignments,omitempty"`
|
|
}
|
|
|
|
func (r *RecurringAssignment) ShouldGenerateNext() bool {
|
|
if !r.IsActive || r.RecurrenceType == RecurrenceNone {
|
|
return false
|
|
}
|
|
|
|
switch r.EndType {
|
|
case EndTypeCount:
|
|
if r.EndCount != nil && r.GeneratedCount >= *r.EndCount {
|
|
return false
|
|
}
|
|
case EndTypeDate:
|
|
if r.EndDate != nil && time.Now().After(*r.EndDate) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (r *RecurringAssignment) CalculateNextDueDate(lastDueDate time.Time) time.Time {
|
|
var nextDate time.Time
|
|
|
|
switch r.RecurrenceType {
|
|
case RecurrenceDaily:
|
|
nextDate = lastDueDate.AddDate(0, 0, r.RecurrenceInterval)
|
|
case RecurrenceWeekly:
|
|
nextDate = lastDueDate.AddDate(0, 0, 7*r.RecurrenceInterval)
|
|
case RecurrenceMonthly:
|
|
nextDate = lastDueDate.AddDate(0, r.RecurrenceInterval, 0)
|
|
if r.RecurrenceDay != nil {
|
|
day := *r.RecurrenceDay
|
|
lastDayOfMonth := time.Date(nextDate.Year(), nextDate.Month()+1, 0, 0, 0, 0, 0, nextDate.Location()).Day()
|
|
if day > lastDayOfMonth {
|
|
day = lastDayOfMonth
|
|
}
|
|
nextDate = time.Date(nextDate.Year(), nextDate.Month(), day, nextDate.Hour(), nextDate.Minute(), 0, 0, nextDate.Location())
|
|
}
|
|
default:
|
|
return lastDueDate
|
|
}
|
|
|
|
return nextDate
|
|
}
|