diff --git a/cmd/server/calendar.go b/cmd/server/calendar.go
index 6512453..0419f28 100644
--- a/cmd/server/calendar.go
+++ b/cmd/server/calendar.go
@@ -13,14 +13,16 @@ func buildTasksForDay(plans []Plan, crops []Crop, products []Product, stepMap ma
return tasks
}
-func buildCalendar(plans []Plan, crops []Crop, products []Product, stepMap map[int64][]CropStep, customTasks []CustomTask, doneMap map[string]bool, startMonth, startDay, daysPerMonth, spanMonths int) []CalendarMonth {
+func buildCalendar(plans []Plan, crops []Crop, products []Product, stepMap map[int64][]CropStep, customTasks []CustomTask, doneMap map[string]bool, startPeriod, startDay, daysPerMonth, spanMonths int) []CalendarMonth {
var out []CalendarMonth
+ startCycle := periodCycle(startPeriod)
for offset := 0; offset < spanMonths; offset++ {
- month := wrapMonth(startMonth + offset)
- yearOffset := (startMonth - 1 + offset) / 12
+ period := startPeriod + offset
+ month := periodMonth(period)
+ yearOffset := periodCycle(period) - startCycle
label := monthNames[month-1]
if yearOffset > 0 {
- label = fmt.Sprintf("%s (+%d Jahr)", label, yearOffset)
+ label = fmt.Sprintf("%s (+%d Zyklus)", label, yearOffset)
}
fromDay := 1
@@ -30,7 +32,7 @@ func buildCalendar(plans []Plan, crops []Crop, products []Product, stepMap map[i
var days []CalendarDay
for d := fromDay; d <= daysPerMonth; d++ {
- items := collectTasksForDate(plans, crops, products, stepMap, customTasks, month, d, yearOffset)
+ items := collectTasksForDate(plans, crops, products, stepMap, customTasks, period, d, yearOffset)
applyCompletion(items, doneMap)
sortTasks(items)
days = append(days, CalendarDay{Day: d, Tasks: items, Groups: groupTasksByField(items)})
@@ -65,11 +67,12 @@ func groupTasksByField(tasks []Task) []FieldTaskGroup {
return out
}
-func collectTasksForDate(plans []Plan, crops []Crop, products []Product, stepMap map[int64][]CropStep, customTasks []CustomTask, month, day, yearOffset int) []Task {
+func collectTasksForDate(plans []Plan, crops []Crop, products []Product, stepMap map[int64][]CropStep, customTasks []CustomTask, period, day, yearOffset int) []Task {
var tasks []Task
+ month := periodMonth(period)
for _, p := range plans {
- tasks = append(tasks, expandPlanDayTasks(p, stepMap[p.CropID], month, day, yearOffset)...)
+ tasks = append(tasks, expandPlanDayTasks(p, stepMap[p.CropID], period, day, yearOffset)...)
}
if day == 1 {
for _, c := range crops {
@@ -102,7 +105,7 @@ func collectTasksForDate(plans []Plan, crops []Crop, products []Product, stepMap
}
}
for _, c := range customTasks {
- if c.Month == month && c.Day == day && c.YearOffset == yearOffset {
+ if c.TaskPeriod == period && c.Day == day {
field := c.TargetName
if strings.TrimSpace(field) == "" {
field = "Allgemein"
@@ -113,13 +116,13 @@ func collectTasksForDate(plans []Plan, crops []Crop, products []Product, stepMap
}
tasks = append(tasks, Task{
UID: fmt.Sprintf("custom:%d", c.ID),
- Type: "Aufgabe",
- Field: field,
- Message: msg,
- Month: month,
- Day: day,
- YearOffset: yearOffset,
- SortOrder: 40,
+ Type: "Aufgabe",
+ Field: field,
+ Message: msg,
+ Month: periodMonth(period),
+ Day: day,
+ YearOffset: yearOffset,
+ SortOrder: 40,
})
}
}
@@ -127,18 +130,18 @@ func collectTasksForDate(plans []Plan, crops []Crop, products []Product, stepMap
return tasks
}
-func expandPlanDayTasks(p Plan, steps []CropStep, month, day, yearOffset int) []Task {
+func expandPlanDayTasks(p Plan, steps []CropStep, period, day, yearOffset int) []Task {
field := p.TargetName
if strings.TrimSpace(field) == "" {
field = "Unbekanntes Feld"
}
+ month := periodMonth(period)
var out []Task
- baseHarvest := p.HarvestMonth
- if p.StartMonth == month && p.StartDay == day && yearOffset == 0 {
+ if p.StartPeriod == period && p.StartDay == day {
out = append(out, Task{
- UID: fmt.Sprintf("plan:%d:sow:0", p.ID),
+ UID: fmt.Sprintf("plan:%d:sow:%d", p.ID, p.StartPeriod),
Type: "Aussaat",
Field: field,
Message: withOptionalNote(fmt.Sprintf("Aussaat %s", p.CropName), p.Notes),
@@ -149,21 +152,21 @@ func expandPlanDayTasks(p Plan, steps []CropStep, month, day, yearOffset int) []
})
}
- harvestMonths := []int{baseHarvest}
+ harvestPeriods := []int{p.HarvestPeriod}
if p.RegrowEnabled {
maxExtra := p.RegrowCycles
if maxExtra == 0 {
maxExtra = 24
}
for i := 1; i <= maxExtra; i++ {
- harvestMonths = append(harvestMonths, wrapMonth(baseHarvest+(i*p.HarvestDistance())))
+ harvestPeriods = append(harvestPeriods, p.HarvestPeriod+(i*p.HarvestDistance()))
}
}
- harvestMonths = uniqueMonths(harvestMonths)
+ harvestPeriods = uniquePeriods(harvestPeriods)
- for idx, hm := range harvestMonths {
- if hm == month && p.HarvestDay == day {
- uid := fmt.Sprintf("plan:%d:harvest:%d", p.ID, idx)
+ for _, harvestPeriod := range harvestPeriods {
+ if harvestPeriod == period && p.HarvestDay == day {
+ uid := fmt.Sprintf("plan:%d:harvest:%d", p.ID, harvestPeriod)
out = append(out, Task{
UID: uid,
Type: "Ernte",
@@ -180,10 +183,10 @@ func expandPlanDayTasks(p Plan, steps []CropStep, month, day, yearOffset int) []
for _, s := range steps {
switch s.Phase {
case "pre":
- taskMonth := wrapMonth(p.StartMonth - s.MonthOffset)
- if taskMonth == month && p.StartDay == day && yearOffset == 0 {
+ taskPeriod := p.StartPeriod - s.MonthOffset
+ if taskPeriod == period && p.StartDay == day {
out = append(out, Task{
- UID: fmt.Sprintf("plan:%d:pre:%d", p.ID, s.ID),
+ UID: fmt.Sprintf("plan:%d:pre:%d:%d", p.ID, s.ID, taskPeriod),
Type: "Vorbereitung",
Field: field,
Message: s.Title,
@@ -194,11 +197,11 @@ func expandPlanDayTasks(p Plan, steps []CropStep, month, day, yearOffset int) []
})
}
case "post":
- for idx, hm := range harvestMonths {
- taskMonth := wrapMonth(hm + s.MonthOffset)
- if taskMonth == month && p.HarvestDay == day {
+ for _, harvestPeriod := range harvestPeriods {
+ taskPeriod := harvestPeriod + s.MonthOffset
+ if taskPeriod == period && p.HarvestDay == day {
out = append(out, Task{
- UID: fmt.Sprintf("plan:%d:post:%d:%d", p.ID, s.ID, idx),
+ UID: fmt.Sprintf("plan:%d:post:%d:%d", p.ID, s.ID, taskPeriod),
Type: "Nachbereitung",
Field: field,
Message: s.Title,
@@ -252,7 +255,7 @@ func sortTasks(tasks []Task) {
})
}
-func uniqueMonths(values []int) []int {
+func uniquePeriods(values []int) []int {
seen := make(map[int]bool)
var out []int
for _, v := range values {
diff --git a/cmd/server/db.go b/cmd/server/db.go
index 9d0def6..52b7548 100644
--- a/cmd/server/db.go
+++ b/cmd/server/db.go
@@ -11,12 +11,15 @@ func ensureSchema(db *sql.DB) error {
id TINYINT PRIMARY KEY,
days_per_month INT NOT NULL DEFAULT 2,
current_month TINYINT NOT NULL DEFAULT 1,
+ current_cycle INT NOT NULL DEFAULT 0,
current_day TINYINT NOT NULL DEFAULT 1
)`,
`ALTER TABLE settings ADD COLUMN IF NOT EXISTS current_month TINYINT NOT NULL DEFAULT 1`,
+ `ALTER TABLE settings ADD COLUMN IF NOT EXISTS current_cycle INT NOT NULL DEFAULT 0`,
`ALTER TABLE settings ADD COLUMN IF NOT EXISTS current_day TINYINT NOT NULL DEFAULT 1`,
- `INSERT INTO settings(id,days_per_month,current_month,current_day) VALUES (1,2,1,1) ON DUPLICATE KEY UPDATE id=id`,
+ `INSERT INTO settings(id,days_per_month,current_month,current_cycle,current_day) VALUES (1,2,1,0,1) ON DUPLICATE KEY UPDATE id=id`,
`UPDATE settings SET current_month=1 WHERE current_month < 1 OR current_month > 12`,
+ `UPDATE settings SET current_cycle=0 WHERE current_cycle < 0`,
`UPDATE settings SET current_day=1 WHERE current_day < 1`,
`CREATE TABLE IF NOT EXISTS fields(
@@ -71,6 +74,7 @@ func ensureSchema(db *sql.DB) error {
id BIGINT AUTO_INCREMENT PRIMARY KEY,
template_id BIGINT NULL,
title VARCHAR(140) NOT NULL,
+ task_period INT NOT NULL DEFAULT 0,
month TINYINT NOT NULL,
day TINYINT NOT NULL,
year_offset SMALLINT NOT NULL DEFAULT 0,
@@ -95,8 +99,10 @@ func ensureSchema(db *sql.DB) error {
target_ref VARCHAR(80) NOT NULL DEFAULT '',
target_name VARCHAR(140) NOT NULL DEFAULT '',
crop_id BIGINT NOT NULL,
+ start_period INT NOT NULL DEFAULT 0,
start_month TINYINT NOT NULL,
start_day TINYINT NOT NULL,
+ harvest_period INT NOT NULL DEFAULT 0,
harvest_month TINYINT NOT NULL,
harvest_day TINYINT NOT NULL,
notes VARCHAR(255) NOT NULL DEFAULT '',
@@ -107,6 +113,12 @@ func ensureSchema(db *sql.DB) error {
`ALTER TABLE plans MODIFY COLUMN field_id BIGINT NULL`,
`ALTER TABLE plans ADD COLUMN IF NOT EXISTS target_ref VARCHAR(80) NOT NULL DEFAULT '' AFTER field_id`,
`ALTER TABLE plans ADD COLUMN IF NOT EXISTS target_name VARCHAR(140) NOT NULL DEFAULT '' AFTER target_ref`,
+ `ALTER TABLE plans ADD COLUMN IF NOT EXISTS start_period INT NOT NULL DEFAULT 0 AFTER crop_id`,
+ `ALTER TABLE plans ADD COLUMN IF NOT EXISTS harvest_period INT NOT NULL DEFAULT 0 AFTER start_day`,
+ `UPDATE plans SET start_period = start_month - 1 WHERE start_period = 0 AND start_month <> 1`,
+ `UPDATE plans SET harvest_period = start_period + (CASE WHEN harvest_month >= start_month THEN harvest_month - start_month ELSE harvest_month + 12 - start_month END) WHERE harvest_period = 0`,
+ `ALTER TABLE custom_tasks ADD COLUMN IF NOT EXISTS task_period INT NOT NULL DEFAULT 0 AFTER title`,
+ `UPDATE custom_tasks SET task_period = (year_offset * 12) + (month - 1) WHERE task_period = 0 AND (year_offset <> 0 OR month <> 1)`,
}
for _, stmt := range stmts {
if _, err := db.Exec(stmt); err != nil {
@@ -118,8 +130,8 @@ func ensureSchema(db *sql.DB) error {
func (a *App) getSettings() (Settings, error) {
var s Settings
- err := a.db.QueryRow(`SELECT days_per_month,current_month,current_day FROM settings WHERE id=1`).
- Scan(&s.DaysPerMonth, &s.CurrentMonth, &s.CurrentDay)
+ err := a.db.QueryRow(`SELECT days_per_month,current_month,current_cycle,current_day FROM settings WHERE id=1`).
+ Scan(&s.DaysPerMonth, &s.CurrentMonth, &s.CurrentCycle, &s.CurrentDay)
return s, err
}
@@ -199,10 +211,10 @@ func (a *App) listProducts() ([]Product, error) {
func (a *App) listPlans() ([]Plan, error) {
rows, err := a.db.Query(`
- SELECT p.id,p.field_id,COALESCE(p.target_ref,''),COALESCE(p.target_name,''),p.crop_id,COALESCE(c.name,''),COALESCE(c.grow_months,1),p.start_month,p.start_day,p.harvest_month,p.harvest_day,COALESCE(p.notes,''),COALESCE(c.regrow_enabled,0),COALESCE(c.regrow_cycles,0)
+ SELECT p.id,p.field_id,COALESCE(p.target_ref,''),COALESCE(p.target_name,''),p.crop_id,COALESCE(c.name,''),COALESCE(c.grow_months,1),p.start_period,p.start_month,p.start_day,p.harvest_period,p.harvest_month,p.harvest_day,COALESCE(p.notes,''),COALESCE(c.regrow_enabled,0),COALESCE(c.regrow_cycles,0)
FROM plans p
JOIN crops c ON c.id=p.crop_id
- ORDER BY p.start_month,p.start_day,p.id DESC`)
+ ORDER BY p.start_period,p.start_day,p.id DESC`)
if err != nil {
return nil, err
}
@@ -210,9 +222,11 @@ func (a *App) listPlans() ([]Plan, error) {
var out []Plan
for rows.Next() {
var p Plan
- if err := rows.Scan(&p.ID, &p.FieldID, &p.TargetRef, &p.TargetName, &p.CropID, &p.CropName, &p.GrowMonths, &p.StartMonth, &p.StartDay, &p.HarvestMonth, &p.HarvestDay, &p.Notes, &p.RegrowEnabled, &p.RegrowCycles); err != nil {
+ if err := rows.Scan(&p.ID, &p.FieldID, &p.TargetRef, &p.TargetName, &p.CropID, &p.CropName, &p.GrowMonths, &p.StartPeriod, &p.StartMonth, &p.StartDay, &p.HarvestPeriod, &p.HarvestMonth, &p.HarvestDay, &p.Notes, &p.RegrowEnabled, &p.RegrowCycles); err != nil {
return nil, err
}
+ p.StartCycle = periodCycle(p.StartPeriod)
+ p.HarvestCycle = periodCycle(p.HarvestPeriod)
out = append(out, p)
}
return out, rows.Err()
@@ -272,9 +286,9 @@ func (a *App) listCustomTaskTemplates() ([]CustomTaskTemplate, error) {
func (a *App) listCustomTasks() ([]CustomTask, error) {
rows, err := a.db.Query(`
- SELECT id,template_id,title,month,day,year_offset,COALESCE(target_name,''),COALESCE(notes,'')
+ SELECT id,template_id,title,task_period,month,day,year_offset,COALESCE(target_name,''),COALESCE(notes,'')
FROM custom_tasks
- ORDER BY year_offset, month, day, title`)
+ ORDER BY task_period, day, title`)
if err != nil {
return nil, err
}
@@ -283,9 +297,11 @@ func (a *App) listCustomTasks() ([]CustomTask, error) {
var out []CustomTask
for rows.Next() {
var t CustomTask
- if err := rows.Scan(&t.ID, &t.TemplateID, &t.Title, &t.Month, &t.Day, &t.YearOffset, &t.TargetName, &t.Notes); err != nil {
+ if err := rows.Scan(&t.ID, &t.TemplateID, &t.Title, &t.TaskPeriod, &t.Month, &t.Day, &t.YearOffset, &t.TargetName, &t.Notes); err != nil {
return nil, err
}
+ t.Month = periodMonth(t.TaskPeriod)
+ t.Cycle = periodCycle(t.TaskPeriod)
out = append(out, t)
}
return out, rows.Err()
diff --git a/cmd/server/domain.go b/cmd/server/domain.go
index a5d8d50..9afa95e 100644
--- a/cmd/server/domain.go
+++ b/cmd/server/domain.go
@@ -90,6 +90,20 @@ func monthOptions() []MonthOption {
return out
}
+func cycleOffsetOptions(maxOffset int) []CycleOption {
+ if maxOffset < 0 {
+ maxOffset = 0
+ }
+ out := make([]CycleOption, 0, maxOffset+1)
+ for i := 0; i <= maxOffset; i++ {
+ out = append(out, CycleOption{
+ Value: i,
+ Label: fmt.Sprintf("+%d Zyklus", i),
+ })
+ }
+ return out
+}
+
func monthInWindow(month, start, end int) bool {
if start <= end {
return month >= start && month <= end
@@ -105,6 +119,14 @@ func wrapMonth(v int) int {
return m
}
+func periodMonth(period int) int {
+ return (period % 12) + 1
+}
+
+func periodCycle(period int) int {
+ return period / 12
+}
+
func validateCropInput(name string, start, end, grow, regrowCycles int) error {
if name == "" {
return errors.New("Name der Feldfrucht fehlt")
diff --git a/cmd/server/handlers_actions.go b/cmd/server/handlers_actions.go
index 835dd0c..ba0895d 100644
--- a/cmd/server/handlers_actions.go
+++ b/cmd/server/handlers_actions.go
@@ -46,12 +46,13 @@ func (a *App) handleSetCurrentTime(w http.ResponseWriter, r *http.Request) {
return
}
month := mustInt(r.FormValue("current_month"), 1)
+ cycle := mustInt(r.FormValue("current_cycle"), settings.CurrentCycle)
day := mustInt(r.FormValue("current_day"), 1)
- if month < 1 || month > 12 || day < 1 || day > settings.DaysPerMonth {
+ if month < 1 || month > 12 || cycle < 0 || day < 1 || day > settings.DaysPerMonth {
redirectWithMessage(w, r, "/", "error", "Ingame-Zeit ungültig")
return
}
- if _, err := a.db.Exec(`UPDATE settings SET current_month=?, current_day=? WHERE id=1`, month, day); err != nil {
+ if _, err := a.db.Exec(`UPDATE settings SET current_month=?, current_cycle=?, current_day=? WHERE id=1`, month, cycle, day); err != nil {
redirectWithMessage(w, r, "/", "error", "Ingame-Zeit nicht gespeichert")
return
}
@@ -369,6 +370,7 @@ func (a *App) handleCreatePlan(w http.ResponseWriter, r *http.Request) {
targetRef := strings.TrimSpace(r.FormValue("target_ref"))
cropID := mustInt64(r.FormValue("crop_id"), 0)
startMonth := mustInt(r.FormValue("start_month"), 1)
+ cycleOffset := mustInt(r.FormValue("cycle_offset"), 0)
startDay := mustInt(r.FormValue("start_day"), 1)
notes := strings.TrimSpace(r.FormValue("notes"))
if targetRef == "" || cropID <= 0 {
@@ -381,7 +383,7 @@ func (a *App) handleCreatePlan(w http.ResponseWriter, r *http.Request) {
redirectWithMessage(w, r, "/planning", "error", "Einstellungen nicht lesbar")
return
}
- if startMonth < 1 || startMonth > 12 || startDay < 1 || startDay > settings.DaysPerMonth {
+ if startMonth < 1 || startMonth > 12 || cycleOffset < 0 || cycleOffset > 20 || startDay < 1 || startDay > settings.DaysPerMonth {
redirectWithMessage(w, r, "/planning", "error", "Startdatum ungültig")
return
}
@@ -404,11 +406,13 @@ func (a *App) handleCreatePlan(w http.ResponseWriter, r *http.Request) {
return
}
- harvestMonth := wrapMonth(startMonth + c.GrowMonths)
+ startPeriod := ((settings.CurrentCycle + cycleOffset) * 12) + (startMonth - 1)
+ harvestPeriod := startPeriod + c.GrowMonths
+ harvestMonth := periodMonth(harvestPeriod)
harvestDay := startDay
_, err = a.db.Exec(
- `INSERT INTO plans(field_id,target_ref,target_name,crop_id,start_month,start_day,harvest_month,harvest_day,notes) VALUES (?,?,?,?,?,?,?,?,?)`,
- fieldID, targetRef, targetName, cropID, startMonth, startDay, harvestMonth, harvestDay, notes,
+ `INSERT INTO plans(field_id,target_ref,target_name,crop_id,start_period,start_month,start_day,harvest_period,harvest_month,harvest_day,notes) VALUES (?,?,?,?,?,?,?,?,?,?,?)`,
+ fieldID, targetRef, targetName, cropID, startPeriod, startMonth, startDay, harvestPeriod, harvestMonth, harvestDay, notes,
)
if err != nil {
redirectWithMessage(w, r, "/planning", "error", "Plan nicht gespeichert")
@@ -508,7 +512,7 @@ func (a *App) handleCreateCustomTask(w http.ResponseWriter, r *http.Request) {
title := strings.TrimSpace(r.FormValue("title"))
month := mustInt(r.FormValue("month"), 0)
day := mustInt(r.FormValue("day"), 0)
- yearOffset := mustInt(r.FormValue("year_offset"), 0)
+ cycleOffset := mustInt(r.FormValue("cycle_offset"), 0)
targetName := strings.TrimSpace(r.FormValue("target_name"))
notes := strings.TrimSpace(r.FormValue("notes"))
settings, err := a.getSettings()
@@ -516,7 +520,7 @@ func (a *App) handleCreateCustomTask(w http.ResponseWriter, r *http.Request) {
redirectWithMessage(w, r, "/planning", "error", "Einstellungen nicht lesbar")
return
}
- if month < 1 || month > 12 || day < 1 || day > settings.DaysPerMonth || yearOffset < 0 || yearOffset > 4 {
+ if month < 1 || month > 12 || day < 1 || day > settings.DaysPerMonth || cycleOffset < 0 || cycleOffset > 20 {
redirectWithMessage(w, r, "/planning", "error", "Aufgaben-Datum ungültig")
return
}
@@ -531,8 +535,9 @@ func (a *App) handleCreateCustomTask(w http.ResponseWriter, r *http.Request) {
return
}
- if _, err = a.db.Exec(`INSERT INTO custom_tasks(template_id,title,month,day,year_offset,target_name,notes) VALUES (?,?,?,?,?,?,?)`,
- nullInt64(templateID), title, month, day, yearOffset, targetName, notes); err != nil {
+ taskPeriod := ((settings.CurrentCycle + cycleOffset) * 12) + (month - 1)
+ if _, err = a.db.Exec(`INSERT INTO custom_tasks(template_id,title,task_period,month,day,year_offset,target_name,notes) VALUES (?,?,?,?,?,?,?,?)`,
+ nullInt64(templateID), title, taskPeriod, month, day, cycleOffset, targetName, notes); err != nil {
redirectWithMessage(w, r, "/planning", "error", "Aufgabe konnte nicht gespeichert werden")
return
}
diff --git a/cmd/server/handlers_pages.go b/cmd/server/handlers_pages.go
index ef1dfe3..4e43f75 100644
--- a/cmd/server/handlers_pages.go
+++ b/cmd/server/handlers_pages.go
@@ -64,8 +64,8 @@ func (a *App) handleDashboard(w http.ResponseWriter, r *http.Request) {
},
Settings: settings,
CurrentMonth: monthNames[settings.CurrentMonth-1],
- TodayTasks: buildTasksForDay(plans, crops, products, stepMap, customTasks, doneMap, settings.CurrentMonth, settings.CurrentDay),
- Calendar: buildCalendar(plans, crops, products, stepMap, customTasks, doneMap, settings.CurrentMonth, settings.CurrentDay, settings.DaysPerMonth, 14),
+ TodayTasks: buildTasksForDay(plans, crops, products, stepMap, customTasks, doneMap, (settings.CurrentCycle*12)+(settings.CurrentMonth-1), settings.CurrentDay),
+ Calendar: buildCalendar(plans, crops, products, stepMap, customTasks, doneMap, (settings.CurrentCycle*12)+(settings.CurrentMonth-1), settings.CurrentDay, settings.DaysPerMonth, 14),
PlanningCount: len(plans),
}
data.TodayGroups = groupTasksByField(data.TodayTasks)
@@ -170,6 +170,7 @@ func (a *App) handlePlanningPage(w http.ResponseWriter, r *http.Request) {
},
Settings: settings,
Months: monthOptions(),
+ CycleOffsets: cycleOffsetOptions(8),
Crops: crops,
Plans: plans,
PlanningTargets: buildPlanningTargets(fields),
diff --git a/cmd/server/main.go b/cmd/server/main.go
index 1de5076..c55411c 100644
--- a/cmd/server/main.go
+++ b/cmd/server/main.go
@@ -1,4 +1,4 @@
-package main
+package main
import (
"database/sql"
@@ -99,3 +99,4 @@ func withLogging(next http.Handler) http.Handler {
log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start).Round(time.Millisecond))
})
}
+
diff --git a/cmd/server/types.go b/cmd/server/types.go
index 6601e54..a7017ff 100644
--- a/cmd/server/types.go
+++ b/cmd/server/types.go
@@ -5,6 +5,7 @@ import "database/sql"
type Settings struct {
DaysPerMonth int
CurrentMonth int
+ CurrentCycle int
CurrentDay int
}
@@ -48,10 +49,14 @@ type Plan struct {
CropID int64
CropName string
GrowMonths int
+ StartPeriod int
StartMonth int
StartDay int
+ StartCycle int
+ HarvestPeriod int
HarvestMonth int
HarvestDay int
+ HarvestCycle int
Notes string
RegrowEnabled bool
RegrowCycles int
@@ -75,9 +80,11 @@ type CustomTask struct {
ID int64
TemplateID sql.NullInt64
Title string
+ TaskPeriod int
Month int
Day int
YearOffset int
+ Cycle int
TargetName string
Notes string
}
@@ -104,6 +111,11 @@ type MonthOption struct {
Label string
}
+type CycleOption struct {
+ Value int
+ Label string
+}
+
type CalendarDay struct {
Day int
Tasks []Task
@@ -156,6 +168,7 @@ type PlanningPage struct {
BasePage
Settings Settings
Months []MonthOption
+ CycleOffsets []CycleOption
Crops []Crop
Plans []Plan
PlanningTargets []PlanningTarget
diff --git a/templates/dashboard.html b/templates/dashboard.html
index df09c77..5608ae7 100644
--- a/templates/dashboard.html
+++ b/templates/dashboard.html
@@ -1,4 +1,4 @@
-
+
@@ -24,7 +24,7 @@
Aktuelle Ingame-Zeit
- {{.CurrentMonth}} Tag {{.Settings.CurrentDay}} bei {{.Settings.DaysPerMonth}} Tagen pro Monat.
+ {{.CurrentMonth}} Tag {{.Settings.CurrentDay}} im Zyklus {{.Settings.CurrentCycle}} bei {{.Settings.DaysPerMonth}} Tagen pro Monat.
{{.PlanningCount}} Plan-Einträge insgesamt.