120 lines
3.7 KiB
Go
120 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
syncsvc "verstak/internal/core/sync"
|
|
"verstak/internal/core/worklog"
|
|
)
|
|
|
|
func (a *App) ListWorklog(nodeID string) ([]WorklogDTO, error) {
|
|
list, err := a.worklog.ListByNode(nodeID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return toWorklogDTOs(list), nil
|
|
}
|
|
|
|
func (a *App) CreateWorklog(nodeID, summary string, minutes int) (*WorklogDTO, error) {
|
|
return a.CreateWorklogFull(nodeID, summary, "", "", minutes, false, false)
|
|
}
|
|
|
|
func (a *App) CreateWorklogFull(nodeID, summary, details, date string, minutes int, approximate, billable bool) (*WorklogDTO, error) {
|
|
if date == "" {
|
|
entry, err := a.worklog.Add(nodeID, summary, details, minutes, approximate, billable)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_ = a.sync.RecordOp(syncsvc.EntityWorklog, entry.ID, syncsvc.OpCreate, worklogPayload(entry))
|
|
return entryToDTO(entry), nil
|
|
}
|
|
entry, err := a.worklog.AddWithDate(nodeID, summary, details, date, minutes, approximate, billable)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_ = a.sync.RecordOp(syncsvc.EntityWorklog, entry.ID, syncsvc.OpCreate, worklogPayload(entry))
|
|
return entryToDTO(entry), nil
|
|
}
|
|
|
|
// --- report bindings ---
|
|
|
|
func (a *App) ListWorklogReport(dateFrom, dateTo, nodeID string, includeChildren bool, billableFilter, approxFilter string) ([]worklog.ReportRow, error) {
|
|
f := buildWorklogFilter(dateFrom, dateTo, nodeID, includeChildren, billableFilter, approxFilter)
|
|
rows, err := a.worklog.ListReport(f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
a.worklog.BuildReportPaths(rows)
|
|
return rows, nil
|
|
}
|
|
|
|
func (a *App) WorklogReportSummary(dateFrom, dateTo, nodeID string, includeChildren bool, billableFilter, approxFilter string) (*worklog.ReportSummary, error) {
|
|
f := buildWorklogFilter(dateFrom, dateTo, nodeID, includeChildren, billableFilter, approxFilter)
|
|
return a.worklog.Summary(f)
|
|
}
|
|
|
|
func (a *App) ExportWorklogCSV(dateFrom, dateTo, nodeID string, includeChildren bool, billableFilter, approxFilter string) (string, error) {
|
|
f := buildWorklogFilter(dateFrom, dateTo, nodeID, includeChildren, billableFilter, approxFilter)
|
|
return a.worklog.ExportCSV(f)
|
|
}
|
|
|
|
func (a *App) ExportWorklogMarkdown(dateFrom, dateTo, nodeID string, includeChildren bool, billableFilter, approxFilter string) (string, error) {
|
|
f := buildWorklogFilter(dateFrom, dateTo, nodeID, includeChildren, billableFilter, approxFilter)
|
|
return a.worklog.ExportMarkdown(f)
|
|
}
|
|
|
|
func (a *App) ExportWorklogPDF(dateFrom, dateTo, nodeID string, includeChildren bool, billableFilter, approxFilter string) ([]byte, error) {
|
|
f := buildWorklogFilter(dateFrom, dateTo, nodeID, includeChildren, billableFilter, approxFilter)
|
|
return a.worklog.ExportPDF(f)
|
|
}
|
|
|
|
func boolPtr(s string) *bool {
|
|
switch s {
|
|
case "yes":
|
|
v := true
|
|
return &v
|
|
case "no":
|
|
v := false
|
|
return &v
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func buildWorklogFilter(dateFrom, dateTo, nodeID string, includeChildren bool, billableFilter, approxFilter string) worklog.ReportFilter {
|
|
return worklog.ReportFilter{
|
|
DateFrom: dateFrom,
|
|
DateTo: dateTo,
|
|
NodeID: nodeID,
|
|
IncludeChildren: includeChildren,
|
|
Billable: boolPtr(billableFilter),
|
|
Approximate: boolPtr(approxFilter),
|
|
}
|
|
}
|
|
|
|
// --- helpers ---
|
|
|
|
func toWorklogDTOs(list []worklog.Entry) []WorklogDTO {
|
|
result := make([]WorklogDTO, len(list))
|
|
for i := range list {
|
|
result[i] = *entryToDTO(&list[i])
|
|
}
|
|
return result
|
|
}
|
|
|
|
func entryToDTO(e *worklog.Entry) *WorklogDTO {
|
|
mins := 0
|
|
if e.Minutes != nil {
|
|
mins = *e.Minutes
|
|
}
|
|
return &WorklogDTO{
|
|
ID: e.ID,
|
|
NodeID: e.NodeID,
|
|
Summary: e.Summary,
|
|
Minutes: mins,
|
|
Date: e.Date,
|
|
Details: e.Details,
|
|
Approximate: e.Approximate,
|
|
Billable: e.Billable,
|
|
CreatedAt: e.CreatedAt.Format("2006-01-02T15:04:05Z"),
|
|
}
|
|
}
|