diff --git a/backend/app/api/main.go b/backend/app/api/main.go
index 0fd69187..245315b2 100644
--- a/backend/app/api/main.go
+++ b/backend/app/api/main.go
@@ -4,14 +4,15 @@ import (
"bytes"
"context"
"fmt"
- "github.com/google/uuid"
- "github.com/sysadminsmedia/homebox/backend/internal/sys/analytics"
"net/http"
"os"
"path/filepath"
"strings"
"time"
+ "github.com/google/uuid"
+ "github.com/sysadminsmedia/homebox/backend/internal/sys/analytics"
+
atlas "ariga.io/atlas/sql/migrate"
"entgo.io/ent/dialect/sql/schema"
"github.com/go-chi/chi/v5"
@@ -203,7 +204,7 @@ func run(cfg *config.Config) error {
currencies, err := currencies.CollectionCurrencies(collectFuncs...)
if err != nil {
- go log.Error().
+ log.Error().
Err(err).
Msg("failed to collect currencies")
return err
diff --git a/backend/app/api/static/docs/docs.go b/backend/app/api/static/docs/docs.go
index ee155891..b8eb2883 100644
--- a/backend/app/api/static/docs/docs.go
+++ b/backend/app/api/static/docs/docs.go
@@ -2241,6 +2241,9 @@ const docTemplate = `{
"parentId": {
"type": "string",
"x-nullable": true
+ },
+ "quantity": {
+ "type": "integer"
}
}
},
@@ -2466,6 +2469,10 @@ const docTemplate = `{
"quantity": {
"type": "integer"
},
+ "soldTime": {
+ "description": "Sale details",
+ "type": "string"
+ },
"updatedAt": {
"type": "string"
}
diff --git a/backend/app/api/static/docs/swagger.json b/backend/app/api/static/docs/swagger.json
index 88fde4e7..8cca9565 100644
--- a/backend/app/api/static/docs/swagger.json
+++ b/backend/app/api/static/docs/swagger.json
@@ -2239,6 +2239,9 @@
"parentId": {
"type": "string",
"x-nullable": true
+ },
+ "quantity": {
+ "type": "integer"
}
}
},
@@ -2464,6 +2467,10 @@
"quantity": {
"type": "integer"
},
+ "soldTime": {
+ "description": "Sale details",
+ "type": "string"
+ },
"updatedAt": {
"type": "string"
}
diff --git a/backend/app/api/static/docs/swagger.yaml b/backend/app/api/static/docs/swagger.yaml
index 8e5c5bd6..9e377c6e 100644
--- a/backend/app/api/static/docs/swagger.yaml
+++ b/backend/app/api/static/docs/swagger.yaml
@@ -98,6 +98,8 @@ definitions:
parentId:
type: string
x-nullable: true
+ quantity:
+ type: integer
required:
- name
type: object
@@ -248,6 +250,9 @@ definitions:
type: number
quantity:
type: integer
+ soldTime:
+ description: Sale details
+ type: string
updatedAt:
type: string
type: object
diff --git a/backend/internal/data/repo/repo_items.go b/backend/internal/data/repo/repo_items.go
index 86180caa..04b7238b 100644
--- a/backend/internal/data/repo/repo_items.go
+++ b/backend/internal/data/repo/repo_items.go
@@ -60,6 +60,7 @@ type (
ImportRef string `json:"-"`
ParentID uuid.UUID `json:"parentId" extensions:"x-nullable"`
Name string `json:"name" validate:"required,min=1,max=255"`
+ Quantity int `json:"quantity"`
Description string `json:"description" validate:"max=1000"`
AssetID AssetID `json:"-"`
@@ -575,6 +576,7 @@ func (e *ItemsRepository) Create(ctx context.Context, gid uuid.UUID, data ItemCr
q := e.db.Item.Create().
SetImportRef(data.ImportRef).
SetName(data.Name).
+ SetQuantity(data.Quantity).
SetDescription(data.Description).
SetGroupID(gid).
SetLocationID(data.LocationID).
diff --git a/backend/internal/data/repo/repo_locations_test.go b/backend/internal/data/repo/repo_locations_test.go
index 4b3ab21a..940875e4 100644
--- a/backend/internal/data/repo/repo_locations_test.go
+++ b/backend/internal/data/repo/repo_locations_test.go
@@ -58,9 +58,10 @@ func TestLocationRepositoryGetAllWithCount(t *testing.T) {
ctx := context.Background()
result := useLocations(t, 1)[0]
- _, err := tRepos.Items.Create(ctx, tGroup.ID, ItemCreate{
+ item, err := tRepos.Items.Create(ctx, tGroup.ID, ItemCreate{
Name: fk.Str(10),
Description: fk.Str(100),
+ Quantity: fk.Num(1, 10),
LocationID: result.ID,
})
@@ -71,7 +72,7 @@ func TestLocationRepositoryGetAllWithCount(t *testing.T) {
for _, loc := range results {
if loc.ID == result.ID {
- assert.Equal(t, 1, loc.ItemCount)
+ assert.Equal(t, item.Quantity, loc.ItemCount)
}
}
}
diff --git a/docs/en/api/openapi-2.0.json b/docs/en/api/openapi-2.0.json
index 88fde4e7..8cca9565 100644
--- a/docs/en/api/openapi-2.0.json
+++ b/docs/en/api/openapi-2.0.json
@@ -2239,6 +2239,9 @@
"parentId": {
"type": "string",
"x-nullable": true
+ },
+ "quantity": {
+ "type": "integer"
}
}
},
@@ -2464,6 +2467,10 @@
"quantity": {
"type": "integer"
},
+ "soldTime": {
+ "description": "Sale details",
+ "type": "string"
+ },
"updatedAt": {
"type": "string"
}
diff --git a/docs/en/api/openapi-2.0.yaml b/docs/en/api/openapi-2.0.yaml
index 8e5c5bd6..9e377c6e 100644
--- a/docs/en/api/openapi-2.0.yaml
+++ b/docs/en/api/openapi-2.0.yaml
@@ -98,6 +98,8 @@ definitions:
parentId:
type: string
x-nullable: true
+ quantity:
+ type: integer
required:
- name
type: object
@@ -248,6 +250,9 @@ definitions:
type: number
quantity:
type: integer
+ soldTime:
+ description: Sale details
+ type: string
updatedAt:
type: string
type: object
diff --git a/frontend/components/Item/CreateModal.vue b/frontend/components/Item/CreateModal.vue
index da65e1c5..fbc00a15 100644
--- a/frontend/components/Item/CreateModal.vue
+++ b/frontend/components/Item/CreateModal.vue
@@ -11,6 +11,7 @@
:max-length="255"
:min-length="1"
/>
+
0 ? locations.value[0] : ({} as LocationOut),
name: "",
+ quantity: 1,
description: "",
color: "",
labels: [] as string[],
@@ -238,6 +240,7 @@
const out: ItemCreate = {
parentId: null,
name: form.name,
+ quantity: form.quantity,
description: form.description,
locationId: form.location.id as string,
labelIds: form.labels,
@@ -278,6 +281,7 @@
}
form.name = "";
+ form.quantity = 1;
form.description = "";
form.color = "";
form.photos = [];
diff --git a/frontend/lib/api/__test__/user/items.test.ts b/frontend/lib/api/__test__/user/items.test.ts
index 196c6c51..5407d563 100644
--- a/frontend/lib/api/__test__/user/items.test.ts
+++ b/frontend/lib/api/__test__/user/items.test.ts
@@ -38,6 +38,7 @@ describe("user should be able to create an item and add an attachment", () => {
name: "test-item",
labelIds: [],
description: "test-description",
+ quantity: 2,
locationId: location.id,
});
expect(response.status).toBe(201);
@@ -72,6 +73,7 @@ describe("user should be able to create an item and add an attachment", () => {
name: faker.vehicle.model(),
labelIds: [],
description: faker.lorem.paragraph(1),
+ quantity: 2,
locationId: location.id,
});
expect(response.status).toBe(201);
@@ -126,6 +128,7 @@ describe("user should be able to create an item and add an attachment", () => {
name: faker.vehicle.model(),
labelIds: [],
description: faker.lorem.paragraph(1),
+ quantity: 2,
locationId: location.id,
});
expect(response.status).toBe(201);
@@ -177,6 +180,7 @@ describe("user should be able to create an item and add an attachment", () => {
name: faker.vehicle.model(),
labelIds: [],
description: faker.lorem.paragraph(1),
+ quantity: 2,
locationId: lastLocationId,
});
expect(response.status).toBe(201);
@@ -201,6 +205,7 @@ describe("user should be able to create an item and add an attachment", () => {
name: "parent-item",
labelIds: [],
description: "test-description",
+ quantity: 2,
locationId: parentLocation.id,
});
expect(parentResponse.status).toBe(201);
@@ -210,6 +215,7 @@ describe("user should be able to create an item and add an attachment", () => {
name: "child1-item",
labelIds: [],
description: "test-description",
+ quantity: 2,
locationId: childsLocation.id,
});
expect(child1Response.status).toBe(201);
@@ -226,6 +232,7 @@ describe("user should be able to create an item and add an attachment", () => {
name: "child2-item",
labelIds: [],
description: "test-description",
+ quantity: 2,
locationId: childsLocation.id,
});
expect(child2Response.status).toBe(201);
diff --git a/frontend/lib/api/types/data-contracts.ts b/frontend/lib/api/types/data-contracts.ts
index e06fdd85..76cc94cc 100644
--- a/frontend/lib/api/types/data-contracts.ts
+++ b/frontend/lib/api/types/data-contracts.ts
@@ -1,7 +1,6 @@
/* post-processed by ./scripts/process-types.go */
/* eslint-disable */
/* tslint:disable */
-// @ts-nocheck
/*
* ---------------------------------------------------------------
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
@@ -11,17 +10,6 @@
* ---------------------------------------------------------------
*/
-export enum MaintenanceFilterStatus {
- MaintenanceFilterStatusScheduled = "scheduled",
- MaintenanceFilterStatusCompleted = "completed",
- MaintenanceFilterStatusBoth = "both",
-}
-
-export enum ItemType {
- ItemTypeLocation = "location",
- ItemTypeItem = "item",
-}
-
export interface CurrenciesCurrency {
code: string;
local: string;
@@ -84,6 +72,7 @@ export interface ItemCreate {
*/
name: string;
parentId?: string | null;
+ quantity: number;
}
export interface ItemField {
@@ -160,9 +149,16 @@ export interface ItemSummary {
name: string;
purchasePrice: number;
quantity: number;
+ /** Sale details */
+ soldTime: Date | string;
updatedAt: Date | string;
}
+export enum ItemType {
+ ItemTypeLocation = "location",
+ ItemTypeItem = "item",
+}
+
export interface ItemUpdate {
archived: boolean;
assetId: string;
@@ -313,6 +309,12 @@ export interface MaintenanceEntryWithDetails {
scheduledDate: Date | string;
}
+export enum MaintenanceFilterStatus {
+ MaintenanceFilterStatusScheduled = "scheduled",
+ MaintenanceFilterStatusCompleted = "completed",
+ MaintenanceFilterStatusBoth = "both",
+}
+
export interface NotifierCreate {
isActive: boolean;
/**
diff --git a/frontend/locales/en.json b/frontend/locales/en.json
index 30887583..48c6b11c 100644
--- a/frontend/locales/en.json
+++ b/frontend/locales/en.json
@@ -65,6 +65,7 @@
"create_modal": {
"item_description": "Item Description",
"item_name": "Item Name",
+ "item_quantity": "Item Quantity",
"item_photo": "Item Photo 📷",
"title": "Create Item",
"upload_photos": "Upload Photos"
diff --git a/frontend/pages/item/[id]/index.vue b/frontend/pages/item/[id]/index.vue
index c8fd697e..1fd38b09 100644
--- a/frontend/pages/item/[id]/index.vue
+++ b/frontend/pages/item/[id]/index.vue
@@ -463,6 +463,7 @@
const { error, data } = await api.items.create({
name: `${item.value.name} Copy`,
description: item.value.description,
+ quantity: item.value.quantity,
locationId: item.value.location!.id,
parentId: item.value.parent?.id,
labelIds: item.value.labels.map(l => l.id),