mirror of
https://github.com/hay-kot/homebox.git
synced 2024-12-19 05:26:31 +00:00
Add label and location total price
This commit is contained in:
parent
de4081d0d2
commit
f67c98644c
6 changed files with 67 additions and 5 deletions
|
@ -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]{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue