diff --git a/backend/api b/backend/api new file mode 100755 index 0000000..2aa21de Binary files /dev/null and b/backend/api differ diff --git a/backend/app/api/handlers/v1/v1_ctrl_items.go b/backend/app/api/handlers/v1/v1_ctrl_items.go index 6a25663..c504f2b 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_items.go +++ b/backend/app/api/handlers/v1/v1_ctrl_items.go @@ -6,6 +6,7 @@ import ( "errors" "net/http" "strings" + "math/big" "github.com/google/uuid" "github.com/hay-kot/homebox/backend/internal/core/services" @@ -79,7 +80,17 @@ func (ctrl *V1Controller) HandleItemsGetAll() errchain.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) error { ctx := services.NewContext(r.Context()) + // deal with floating point precision items, err := ctrl.repo.Items.QueryByGroup(ctx, ctx.GID, extractQuery(r)) + totalPrice := new(big.Int) + for _, item := range items.Items { + totalPrice.Add(totalPrice, big.NewInt(int64(item.PurchasePrice * 100))) + } + + totalPriceFloat := new(big.Float).SetInt(totalPrice) + totalPriceFloat.Quo(totalPriceFloat, big.NewFloat(100)) + items.TotalPrice, _ = totalPriceFloat.Float64() + if err != nil { if errors.Is(err, sql.ErrNoRows) { return server.JSON(w, http.StatusOK, repo.PaginationResult[repo.ItemSummary]{ diff --git a/backend/app/api/handlers/v1/v1_ctrl_locations.go b/backend/app/api/handlers/v1/v1_ctrl_locations.go index d84ce31..d1c7cc3 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_locations.go +++ b/backend/app/api/handlers/v1/v1_ctrl_locations.go @@ -2,6 +2,9 @@ package v1 import ( "net/http" + "fmt" + "context" + "math/big" "github.com/google/uuid" "github.com/hay-kot/homebox/backend/internal/core/services" @@ -83,6 +86,32 @@ func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc { return adapters.CommandID("id", fn, http.StatusNoContent) } +func (ctrl *V1Controller) GetLocationWithPrice(auth context.Context, GID uuid.UUID, ID uuid.UUID) (repo.LocationOut, error) { + var location, err = ctrl.repo.Locations.GetOneByGroup(auth, GID, ID) + + // Add direct child items price + totalPrice := new(big.Int) + items, err := ctrl.repo.Items.QueryByGroup(auth, GID, repo.ItemQuery{LocationIDs: []uuid.UUID{ID}}) + for _, item := range items.Items { + totalPrice.Add(totalPrice, big.NewInt(int64(item.PurchasePrice * 100))) + } + + totalPriceFloat := new(big.Float).SetInt(totalPrice) + totalPriceFloat.Quo(totalPriceFloat, big.NewFloat(100)) + location.TotalPrice, _ = totalPriceFloat.Float64() + + // Add price from child locations + for _, childLocation := range location.Children { + var childLocation, err = ctrl.GetLocationWithPrice(auth, GID, childLocation.ID) + if err != nil { + fmt.Println(err) + } + location.TotalPrice += childLocation.TotalPrice + } + + return location, err +} + // HandleLocationGet godoc // // @Summary Get Location @@ -95,7 +124,9 @@ func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc { func (ctrl *V1Controller) HandleLocationGet() errchain.HandlerFunc { fn := func(r *http.Request, ID uuid.UUID) (repo.LocationOut, error) { auth := services.NewContext(r.Context()) - return ctrl.repo.Locations.GetOneByGroup(auth, auth.GID, ID) + var location, err = ctrl.GetLocationWithPrice(auth, auth.GID, ID) + + return location, err } return adapters.CommandID("id", fn, http.StatusOK) diff --git a/backend/app/api/static/docs/swagger.json b/backend/app/api/static/docs/swagger.json index b10c93a..0fdec55 100644 --- a/backend/app/api/static/docs/swagger.json +++ b/backend/app/api/static/docs/swagger.json @@ -2469,6 +2469,9 @@ "parent": { "$ref": "#/definitions/repo.LocationSummary" }, + "totalPrice": { + "type": "number" + }, "updatedAt": { "type": "string" } @@ -2707,6 +2710,9 @@ }, "total": { "type": "integer" + }, + "totalPrice": { + "type": "number" } } }, diff --git a/backend/internal/data/repo/pagination.go b/backend/internal/data/repo/pagination.go index d8878d0..5f540ee 100644 --- a/backend/internal/data/repo/pagination.go +++ b/backend/internal/data/repo/pagination.go @@ -5,6 +5,7 @@ type PaginationResult[T any] struct { PageSize int `json:"pageSize"` Total int `json:"total"` Items []T `json:"items"` + TotalPrice float64 `json:"totalPrice"` } func calculateOffset(page, pageSize int) int { diff --git a/backend/internal/data/repo/repo_locations.go b/backend/internal/data/repo/repo_locations.go index fd98fd7..a877507 100644 --- a/backend/internal/data/repo/repo_locations.go +++ b/backend/internal/data/repo/repo_locations.go @@ -49,6 +49,7 @@ type ( Parent *LocationSummary `json:"parent,omitempty"` LocationSummary Children []LocationSummary `json:"children"` + TotalPrice float64 `json:"totalPrice"` } ) diff --git a/docs/docs/api/openapi-2.0.json b/docs/docs/api/openapi-2.0.json index b10c93a..0fdec55 100644 --- a/docs/docs/api/openapi-2.0.json +++ b/docs/docs/api/openapi-2.0.json @@ -2469,6 +2469,9 @@ "parent": { "$ref": "#/definitions/repo.LocationSummary" }, + "totalPrice": { + "type": "number" + }, "updatedAt": { "type": "string" } @@ -2707,6 +2710,9 @@ }, "total": { "type": "integer" + }, + "totalPrice": { + "type": "number" } } }, diff --git a/frontend/lib/api/types/data-contracts.ts b/frontend/lib/api/types/data-contracts.ts index 384ffb6..3b4674d 100644 --- a/frontend/lib/api/types/data-contracts.ts +++ b/frontend/lib/api/types/data-contracts.ts @@ -232,6 +232,7 @@ export interface LocationOut { id: string; name: string; parent: LocationSummary; + totalPrice: number; updatedAt: Date | string; } @@ -329,6 +330,7 @@ export interface PaginationResultItemSummary { page: number; pageSize: number; total: number; + totalPrice: number; } export interface TotalsByOrganizer { diff --git a/frontend/pages/label/[id].vue b/frontend/pages/label/[id].vue index 5824888..ce8c2d9 100644 --- a/frontend/pages/label/[id].vue +++ b/frontend/pages/label/[id].vue @@ -88,7 +88,7 @@ return []; } - return resp.data.items; + return resp.data; }); @@ -115,8 +115,17 @@
-

+

{{ label ? label.name : "" }} + +
+
+ +
+

@@ -144,7 +153,7 @@
- +
diff --git a/frontend/pages/location/[id].vue b/frontend/pages/location/[id].vue index 5f7f1a1..4733880 100644 --- a/frontend/pages/location/[id].vue +++ b/frontend/pages/location/[id].vue @@ -138,8 +138,17 @@
  • {{ location.name }}
  • -

    +

    {{ location ? location.name : "" }} + +
    +
    + +
    +