diff --git a/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go b/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go
index 63c8fb6d..e9f1f97c 100644
--- a/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go
+++ b/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go
@@ -15,13 +15,14 @@ import (
// @Summary Get Maintenance Log
// @Tags Item Maintenance
// @Produce json
-// @Success 200 {object} repo.MaintenanceLog
+// @Param filters query repo.MaintenanceFilters false "which maintenance to retrieve"
+// @Success 200 {array} repo.MaintenanceEntryWithDetails[]
// @Router /v1/items/{id}/maintenance [GET]
// @Security Bearer
func (ctrl *V1Controller) HandleMaintenanceLogGet() errchain.HandlerFunc {
- fn := func(r *http.Request, ID uuid.UUID, q repo.MaintenanceLogQuery) (repo.MaintenanceLog, error) {
+ fn := func(r *http.Request, ID uuid.UUID, filters repo.MaintenanceFilters) ([]repo.MaintenanceEntryWithDetails, error) {
auth := services.NewContext(r.Context())
- return ctrl.repo.MaintEntry.GetLog(auth, auth.GID, ID, q)
+ return ctrl.repo.MaintEntry.GetMaintenanceByItemID(auth, auth.GID, ID, filters)
}
return adapters.QueryID("id", fn, http.StatusOK)
diff --git a/backend/app/api/static/docs/docs.go b/backend/app/api/static/docs/docs.go
index 7fef44b3..e72b0e56 100644
--- a/backend/app/api/static/docs/docs.go
+++ b/backend/app/api/static/docs/docs.go
@@ -920,11 +920,31 @@ const docTemplate = `{
"Item Maintenance"
],
"summary": "Get Maintenance Log",
+ "parameters": [
+ {
+ "enum": [
+ "scheduled",
+ "completed",
+ "both"
+ ],
+ "type": "string",
+ "x-enum-varnames": [
+ "MaintenanceFilterStatusScheduled",
+ "MaintenanceFilterStatusCompleted",
+ "MaintenanceFilterStatusBoth"
+ ],
+ "name": "status",
+ "in": "query"
+ }
+ ],
"responses": {
"200": {
"description": "OK",
"schema": {
- "$ref": "#/definitions/repo.MaintenanceLog"
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/repo.MaintenanceEntryWithDetails"
+ }
}
}
}
@@ -2701,26 +2721,6 @@ const docTemplate = `{
"MaintenanceFilterStatusBoth"
]
},
- "repo.MaintenanceLog": {
- "type": "object",
- "properties": {
- "costAverage": {
- "type": "number"
- },
- "costTotal": {
- "type": "number"
- },
- "entries": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/repo.MaintenanceEntry"
- }
- },
- "itemId": {
- "type": "string"
- }
- }
- },
"repo.NotifierCreate": {
"type": "object",
"required": [
diff --git a/backend/app/api/static/docs/swagger.json b/backend/app/api/static/docs/swagger.json
index 6c642d8d..4601140a 100644
--- a/backend/app/api/static/docs/swagger.json
+++ b/backend/app/api/static/docs/swagger.json
@@ -913,11 +913,31 @@
"Item Maintenance"
],
"summary": "Get Maintenance Log",
+ "parameters": [
+ {
+ "enum": [
+ "scheduled",
+ "completed",
+ "both"
+ ],
+ "type": "string",
+ "x-enum-varnames": [
+ "MaintenanceFilterStatusScheduled",
+ "MaintenanceFilterStatusCompleted",
+ "MaintenanceFilterStatusBoth"
+ ],
+ "name": "status",
+ "in": "query"
+ }
+ ],
"responses": {
"200": {
"description": "OK",
"schema": {
- "$ref": "#/definitions/repo.MaintenanceLog"
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/repo.MaintenanceEntryWithDetails"
+ }
}
}
}
@@ -2694,26 +2714,6 @@
"MaintenanceFilterStatusBoth"
]
},
- "repo.MaintenanceLog": {
- "type": "object",
- "properties": {
- "costAverage": {
- "type": "number"
- },
- "costTotal": {
- "type": "number"
- },
- "entries": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/repo.MaintenanceEntry"
- }
- },
- "itemId": {
- "type": "string"
- }
- }
- },
"repo.NotifierCreate": {
"type": "object",
"required": [
diff --git a/backend/app/api/static/docs/swagger.yaml b/backend/app/api/static/docs/swagger.yaml
index d6275708..6c2d5222 100644
--- a/backend/app/api/static/docs/swagger.yaml
+++ b/backend/app/api/static/docs/swagger.yaml
@@ -511,19 +511,6 @@ definitions:
- MaintenanceFilterStatusScheduled
- MaintenanceFilterStatusCompleted
- MaintenanceFilterStatusBoth
- repo.MaintenanceLog:
- properties:
- costAverage:
- type: number
- costTotal:
- type: number
- entries:
- items:
- $ref: '#/definitions/repo.MaintenanceEntry'
- type: array
- itemId:
- type: string
- type: object
repo.NotifierCreate:
properties:
isActive:
@@ -1249,13 +1236,27 @@ paths:
- Items Attachments
/v1/items/{id}/maintenance:
get:
+ parameters:
+ - enum:
+ - scheduled
+ - completed
+ - both
+ in: query
+ name: status
+ type: string
+ x-enum-varnames:
+ - MaintenanceFilterStatusScheduled
+ - MaintenanceFilterStatusCompleted
+ - MaintenanceFilterStatusBoth
produces:
- application/json
responses:
"200":
description: OK
schema:
- $ref: '#/definitions/repo.MaintenanceLog'
+ items:
+ $ref: '#/definitions/repo.MaintenanceEntryWithDetails'
+ type: array
security:
- Bearer: []
summary: Get Maintenance Log
diff --git a/backend/internal/data/repo/repo_maintenance_entry.go b/backend/internal/data/repo/repo_maintenance_entry.go
index 565ed0f8..6f5c135b 100644
--- a/backend/internal/data/repo/repo_maintenance_entry.go
+++ b/backend/internal/data/repo/repo_maintenance_entry.go
@@ -59,13 +59,6 @@ type (
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 (
@@ -130,76 +123,32 @@ func (r *MaintenanceEntryRepository) Update(ctx context.Context, id uuid.UUID, i
return mapMaintenanceEntryErr(item, err)
}
-type MaintenanceLogQuery struct {
- Completed bool `json:"completed" schema:"completed"`
- Scheduled bool `json:"scheduled" schema:"scheduled"`
-}
-
-func (r *MaintenanceEntryRepository) GetLog(ctx context.Context, groupID, itemID uuid.UUID, query MaintenanceLogQuery) (MaintenanceLog, error) {
- log := MaintenanceLog{
- ItemID: itemID,
- }
-
- q := r.db.MaintenanceEntry.Query().Where(
+func (r *MaintenanceEntryRepository) GetMaintenanceByItemID(ctx context.Context, groupID, itemID uuid.UUID, filters MaintenanceFilters) ([]MaintenanceEntryWithDetails, error) {
+ query := r.db.MaintenanceEntry.Query().Where(
maintenanceentry.ItemID(itemID),
maintenanceentry.HasItemWith(
item.HasGroupWith(group.IDEQ(groupID)),
),
)
-
- if query.Completed {
- q = q.Where(maintenanceentry.And(
- maintenanceentry.DateNotNil(),
- maintenanceentry.DateNEQ(time.Time{}),
+ if filters.Status == MaintenanceFilterStatusScheduled {
+ query = query.Where(maintenanceentry.Or(
+ maintenanceentry.DateIsNil(),
+ maintenanceentry.DateEQ(time.Time{}),
))
- } else if query.Scheduled {
- q = q.Where(maintenanceentry.And(
- maintenanceentry.Or(
+ } else if filters.Status == MaintenanceFilterStatusCompleted {
+ query = query.Where(
+ maintenanceentry.Not(maintenanceentry.Or(
maintenanceentry.DateIsNil(),
- maintenanceentry.DateEQ(time.Time{}),
- ),
- maintenanceentry.ScheduledDateNotNil(),
- maintenanceentry.ScheduledDateNEQ(time.Time{}),
- ))
+ maintenanceentry.DateEQ(time.Time{})),
+ ))
}
+ entries, err := query.WithItem().Order(maintenanceentry.ByScheduledDate()).All(ctx)
- entries, err := q.Order(ent.Desc(maintenanceentry.FieldDate)).
- All(ctx)
if err != nil {
- return MaintenanceLog{}, err
+ return []MaintenanceEntryWithDetails{}, err
}
- log.Entries = mapEachMaintenanceEntry(entries)
-
- var maybeTotal *float64
- var maybeAverage *float64
-
- statement := `
-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, statement, 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
+ return mapEachMaintenanceEntryWithDetails(entries), nil
}
func (r *MaintenanceEntryRepository) Delete(ctx context.Context, id uuid.UUID) error {
diff --git a/backend/internal/data/repo/repo_maintenance_entry_test.go b/backend/internal/data/repo/repo_maintenance_entry_test.go
index 0c101ab1..6f6bc0fd 100644
--- a/backend/internal/data/repo/repo_maintenance_entry_test.go
+++ b/backend/internal/data/repo/repo_maintenance_entry_test.go
@@ -60,27 +60,14 @@ func TestMaintenanceEntryRepository_GetLog(t *testing.T) {
}
// Get the log for the item
- log, err := tRepos.MaintEntry.GetLog(context.Background(), tGroup.ID, item.ID, MaintenanceLogQuery{
- Completed: true,
- })
+ log, err := tRepos.MaintEntry.GetMaintenanceByItemID(context.Background(), tGroup.ID, item.ID, MaintenanceFilters{Status: MaintenanceFilterStatusCompleted})
if err != nil {
t.Fatalf("failed to get maintenance log: %v", err)
}
- assert.Equal(t, item.ID, log.ItemID)
- assert.Len(t, log.Entries, 10)
+ assert.Len(t, log, 10)
- // Calculate the average cost
- var total float64
-
- for _, entry := range log.Entries {
- total += entry.Cost
- }
-
- assert.InDelta(t, total, log.CostTotal, .001, "total cost should be equal to the sum of all entries")
- assert.InDelta(t, total/2, log.CostAverage, 001, "average cost should be the average of the two months")
-
- for _, entry := range log.Entries {
+ for _, entry := range log {
err := tRepos.MaintEntry.Delete(context.Background(), entry.ID)
require.NoError(t, err)
}
diff --git a/docs/docs/api/openapi-2.0.json b/docs/docs/api/openapi-2.0.json
index 6c642d8d..4601140a 100644
--- a/docs/docs/api/openapi-2.0.json
+++ b/docs/docs/api/openapi-2.0.json
@@ -913,11 +913,31 @@
"Item Maintenance"
],
"summary": "Get Maintenance Log",
+ "parameters": [
+ {
+ "enum": [
+ "scheduled",
+ "completed",
+ "both"
+ ],
+ "type": "string",
+ "x-enum-varnames": [
+ "MaintenanceFilterStatusScheduled",
+ "MaintenanceFilterStatusCompleted",
+ "MaintenanceFilterStatusBoth"
+ ],
+ "name": "status",
+ "in": "query"
+ }
+ ],
"responses": {
"200": {
"description": "OK",
"schema": {
- "$ref": "#/definitions/repo.MaintenanceLog"
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/repo.MaintenanceEntryWithDetails"
+ }
}
}
}
@@ -2694,26 +2714,6 @@
"MaintenanceFilterStatusBoth"
]
},
- "repo.MaintenanceLog": {
- "type": "object",
- "properties": {
- "costAverage": {
- "type": "number"
- },
- "costTotal": {
- "type": "number"
- },
- "entries": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/repo.MaintenanceEntry"
- }
- },
- "itemId": {
- "type": "string"
- }
- }
- },
"repo.NotifierCreate": {
"type": "object",
"required": [
diff --git a/frontend/components/Maintenance/EditModal.vue b/frontend/components/Maintenance/EditModal.vue
index 8176bbe5..5773aeda 100644
--- a/frontend/components/Maintenance/EditModal.vue
+++ b/frontend/components/Maintenance/EditModal.vue
@@ -136,7 +136,7 @@
}
async function complete(maintenanceEntry: MaintenanceEntry) {
- const { error } = await api.maintenances.update(maintenanceEntry.id, {
+ const { error } = await api.maintenance.update(maintenanceEntry.id, {
name: maintenanceEntry.name,
completedDate: new Date(Date.now()),
scheduledDate: maintenanceEntry.scheduledDate ?? "null",
@@ -144,7 +144,7 @@
cost: maintenanceEntry.cost,
});
if (error) {
- toast.error(t("maintenances.toast.failed_to_update"));
+ toast.error(t("maintenance.toast.failed_to_update"));
}
emit("changed");
}
diff --git a/frontend/lib/api/types/data-contracts.ts b/frontend/lib/api/types/data-contracts.ts
index 12727f0f..62c1286f 100644
--- a/frontend/lib/api/types/data-contracts.ts
+++ b/frontend/lib/api/types/data-contracts.ts
@@ -306,13 +306,6 @@ export enum MaintenanceFilterStatus {
MaintenanceFilterStatusBoth = "both",
}
-export interface MaintenanceLog {
- costAverage: number;
- costTotal: number;
- entries: MaintenanceEntry[];
- itemId: string;
-}
-
export interface NotifierCreate {
isActive: boolean;
/**
diff --git a/frontend/pages/maintenance.vue b/frontend/pages/maintenance.vue
index 60b05169..f566402f 100644
--- a/frontend/pages/maintenance.vue
+++ b/frontend/pages/maintenance.vue
@@ -127,7 +127,7 @@
- {{ $t("maintenances.list.complete") }}
+ {{ $t("maintenance.list.complete") }}
- {{ $t("maintenances.list.complete_and_duplicate") }}
+ {{ $t("maintenance.list.complete_and_duplicate") }}