forked from mirrors/homebox
137 lines
3.5 KiB
Go
137 lines
3.5 KiB
Go
|
package repo
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"time"
|
||
|
|
||
|
"github.com/google/uuid"
|
||
|
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry"
|
||
|
)
|
||
|
|
||
|
// MaintenanceEntryRepository is a repository for maintenance entries that are
|
||
|
// associated with an item in the database. An entry represents a maintenance event
|
||
|
// that has been performed on an item.
|
||
|
type MaintenanceEntryRepository struct {
|
||
|
db *ent.Client
|
||
|
}
|
||
|
type (
|
||
|
MaintenanceEntryCreate struct {
|
||
|
Date time.Time `json:"date"`
|
||
|
Name string `json:"name"`
|
||
|
Description string `json:"description"`
|
||
|
Cost float64 `json:"cost,string"`
|
||
|
}
|
||
|
|
||
|
MaintenanceEntry struct {
|
||
|
ID uuid.UUID `json:"id"`
|
||
|
Date time.Time `json:"date"`
|
||
|
Name string `json:"name"`
|
||
|
Description string `json:"description"`
|
||
|
Cost float64 `json:"cost,string"`
|
||
|
}
|
||
|
|
||
|
MaintenanceEntryUpdate struct {
|
||
|
Date time.Time `json:"date"`
|
||
|
Name string `json:"name"`
|
||
|
Description string `json:"description"`
|
||
|
Cost float64 `json:"cost,string"`
|
||
|
}
|
||
|
|
||
|
MaintenanceLog struct {
|
||
|
ItemID uuid.UUID `json:"itemId"`
|
||
|
CostAverage float64 `json:"costAverage"`
|
||
|
CostTotal float64 `json:"costTotal"`
|
||
|
Entries []MaintenanceEntry `json:"entries"`
|
||
|
}
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
mapMaintenanceEntryErr = mapTErrFunc(mapMaintenanceEntry)
|
||
|
mapEachMaintenanceEntry = mapTEachFunc(mapMaintenanceEntry)
|
||
|
)
|
||
|
|
||
|
func mapMaintenanceEntry(entry *ent.MaintenanceEntry) MaintenanceEntry {
|
||
|
return MaintenanceEntry{
|
||
|
ID: entry.ID,
|
||
|
Date: entry.Date,
|
||
|
Name: entry.Name,
|
||
|
Description: entry.Description,
|
||
|
Cost: entry.Cost,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (r *MaintenanceEntryRepository) Create(ctx context.Context, itemID uuid.UUID, input MaintenanceEntryCreate) (MaintenanceEntry, error) {
|
||
|
item, err := r.db.MaintenanceEntry.Create().
|
||
|
SetItemID(itemID).
|
||
|
SetDate(input.Date).
|
||
|
SetName(input.Name).
|
||
|
SetDescription(input.Description).
|
||
|
SetCost(input.Cost).
|
||
|
Save(ctx)
|
||
|
|
||
|
return mapMaintenanceEntryErr(item, err)
|
||
|
}
|
||
|
|
||
|
func (r *MaintenanceEntryRepository) Update(ctx context.Context, ID uuid.UUID, input MaintenanceEntryUpdate) (MaintenanceEntry, error) {
|
||
|
item, err := r.db.MaintenanceEntry.UpdateOneID(ID).
|
||
|
SetDate(input.Date).
|
||
|
SetName(input.Name).
|
||
|
SetDescription(input.Description).
|
||
|
SetCost(input.Cost).
|
||
|
Save(ctx)
|
||
|
|
||
|
return mapMaintenanceEntryErr(item, err)
|
||
|
}
|
||
|
|
||
|
func (r *MaintenanceEntryRepository) GetLog(ctx context.Context, itemID uuid.UUID) (MaintenanceLog, error) {
|
||
|
log := MaintenanceLog{
|
||
|
ItemID: itemID,
|
||
|
}
|
||
|
|
||
|
entries, err := r.db.MaintenanceEntry.Query().
|
||
|
Where(maintenanceentry.ItemID(itemID)).
|
||
|
Order(ent.Desc(maintenanceentry.FieldDate)).
|
||
|
All(ctx)
|
||
|
|
||
|
if err != nil {
|
||
|
return MaintenanceLog{}, err
|
||
|
}
|
||
|
|
||
|
log.Entries = mapEachMaintenanceEntry(entries)
|
||
|
|
||
|
var maybeTotal *float64
|
||
|
var maybeAverage *float64
|
||
|
|
||
|
q := `
|
||
|
SELECT
|
||
|
SUM(cost_total) AS total_of_totals,
|
||
|
AVG(cost_total) AS avg_of_averages
|
||
|
FROM
|
||
|
(
|
||
|
SELECT
|
||
|
strftime('%m-%Y', date) AS my,
|
||
|
SUM(cost) AS cost_total
|
||
|
FROM
|
||
|
maintenance_entries
|
||
|
WHERE
|
||
|
item_id = ?
|
||
|
GROUP BY
|
||
|
my
|
||
|
)`
|
||
|
|
||
|
row := r.db.Sql().QueryRowContext(ctx, q, itemID)
|
||
|
err = row.Scan(&maybeTotal, &maybeAverage)
|
||
|
if err != nil {
|
||
|
return MaintenanceLog{}, err
|
||
|
}
|
||
|
|
||
|
log.CostAverage = orDefault(maybeAverage, 0)
|
||
|
log.CostTotal = orDefault(maybeTotal, 0)
|
||
|
return log, nil
|
||
|
}
|
||
|
|
||
|
func (r *MaintenanceEntryRepository) Delete(ctx context.Context, ID uuid.UUID) error {
|
||
|
return r.db.MaintenanceEntry.DeleteOneID(ID).Exec(ctx)
|
||
|
}
|