Add label and location total price

This commit is contained in:
Jack Bailey 2024-01-25 11:46:29 +00:00
parent de4081d0d2
commit f67c98644c
No known key found for this signature in database
6 changed files with 67 additions and 5 deletions

View file

@ -6,6 +6,7 @@ import (
"errors" "errors"
"net/http" "net/http"
"strings" "strings"
"math/big"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/hay-kot/homebox/backend/internal/core/services" "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 { return func(w http.ResponseWriter, r *http.Request) error {
ctx := services.NewContext(r.Context()) ctx := services.NewContext(r.Context())
// deal with floating point precision
items, err := ctrl.repo.Items.QueryByGroup(ctx, ctx.GID, extractQuery(r)) 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 err != nil {
if errors.Is(err, sql.ErrNoRows) { if errors.Is(err, sql.ErrNoRows) {
return server.JSON(w, http.StatusOK, repo.PaginationResult[repo.ItemSummary]{ return server.JSON(w, http.StatusOK, repo.PaginationResult[repo.ItemSummary]{

View file

@ -2,6 +2,9 @@ package v1
import ( import (
"net/http" "net/http"
"fmt"
"context"
"math/big"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/hay-kot/homebox/backend/internal/core/services" "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) 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 locatinos
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 // HandleLocationGet godoc
// //
// @Summary Get Location // @Summary Get Location
@ -95,7 +124,9 @@ func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleLocationGet() errchain.HandlerFunc { func (ctrl *V1Controller) HandleLocationGet() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID) (repo.LocationOut, error) { fn := func(r *http.Request, ID uuid.UUID) (repo.LocationOut, error) {
auth := services.NewContext(r.Context()) 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) return adapters.CommandID("id", fn, http.StatusOK)

View file

@ -5,6 +5,7 @@ type PaginationResult[T any] struct {
PageSize int `json:"pageSize"` PageSize int `json:"pageSize"`
Total int `json:"total"` Total int `json:"total"`
Items []T `json:"items"` Items []T `json:"items"`
TotalPrice float64 `json:"totalPrice"`
} }
func calculateOffset(page, pageSize int) int { func calculateOffset(page, pageSize int) int {

View file

@ -49,6 +49,7 @@ type (
Parent *LocationSummary `json:"parent,omitempty"` Parent *LocationSummary `json:"parent,omitempty"`
LocationSummary LocationSummary
Children []LocationSummary `json:"children"` Children []LocationSummary `json:"children"`
TotalPrice float64 `json:"totalPrice"`
} }
) )

View file

@ -84,7 +84,7 @@
return []; return [];
} }
return resp.data.items; return resp.data;
}); });
</script> </script>
@ -111,8 +111,17 @@
</div> </div>
</div> </div>
<div> <div>
<h1 class="text-2xl pb-1"> <h1 class="text-2xl pb-1 flex items-center gap-3">
{{ label ? label.name : "" }} {{ label ? label.name : "" }}
<div
v-if="items && items.totalPrice"
class="text-xs bg-secondary text-secondary-content rounded-full px-2 py-1"
>
<div>
<Currency :amount="items.totalPrice" />
</div>
</div>
</h1> </h1>
<div class="flex gap-1 flex-wrap text-xs"> <div class="flex gap-1 flex-wrap text-xs">
<div> <div>
@ -140,7 +149,7 @@
<Markdown v-if="label && label.description" class="text-base" :source="label.description"> </Markdown> <Markdown v-if="label && label.description" class="text-base" :source="label.description"> </Markdown>
</div> </div>
<section v-if="label && items"> <section v-if="label && items">
<ItemViewSelectable :items="items" /> <ItemViewSelectable :items="items.items" />
</section> </section>
</BaseContainer> </BaseContainer>
</BaseContainer> </BaseContainer>

View file

@ -135,8 +135,17 @@
<li>{{ location.name }}</li> <li>{{ location.name }}</li>
</ul> </ul>
</div> </div>
<h1 class="text-2xl pb-1"> <h1 class="text-2xl pb-1 flex items-center gap-3">
{{ location ? location.name : "" }} {{ location ? location.name : "" }}
<div
v-if="location && location.totalPrice"
class="text-xs bg-secondary text-secondary-content rounded-full px-2 py-1"
>
<div>
<Currency :amount="location.totalPrice" />
</div>
</div>
</h1> </h1>
<div class="flex gap-1 flex-wrap text-xs"> <div class="flex gap-1 flex-wrap text-xs">
<div> <div>