diff --git a/backend/internal/data/ent/location.go b/backend/internal/data/ent/location.go index 156f8c0..598ae53 100644 --- a/backend/internal/data/ent/location.go +++ b/backend/internal/data/ent/location.go @@ -43,11 +43,22 @@ type LocationEdges struct { Children []*Location `json:"children,omitempty"` // Items holds the value of the items edge. Items []*Item `json:"items,omitempty"` + // Fields holds the value of the fields edge. + Fields []*LocationField `json:"fields,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. loadedTypes [4]bool } +// FieldsOrErr returns the Fields value or an error if the edge +// was not loaded in eager-loading. +func (e LocationEdges) FieldsOrErr() ([]*LocationField, error) { + if e.loadedTypes[5] { + return e.Fields, nil + } + return nil, &NotLoadedError{edge: "fields"} +} + // GroupOrErr returns the Group value or an error if the edge // was not loaded in eager-loading, or loaded but was not found. func (e LocationEdges) GroupOrErr() (*Group, error) { @@ -186,6 +197,11 @@ func (l *Location) QueryChildren() *LocationQuery { return NewLocationClient(l.config).QueryChildren(l) } +// QueryFields queries the "fields" edge of the Item entity. +func (i *Location) QueryFields() *LocationFieldQuery { + return NewLocationClient(i.config).QueryFields(i) +} + // QueryItems queries the "items" edge of the Location entity. func (l *Location) QueryItems() *ItemQuery { return NewLocationClient(l.config).QueryItems(l) diff --git a/backend/internal/data/ent/location/location.go b/backend/internal/data/ent/location/location.go index 420e3a3..456bdff 100644 --- a/backend/internal/data/ent/location/location.go +++ b/backend/internal/data/ent/location/location.go @@ -53,6 +53,13 @@ const ( ItemsInverseTable = "items" // ItemsColumn is the table column denoting the items relation/edge. ItemsColumn = "location_items" + // FieldsTable is the table that holds the fields relation/edge. + FieldsTable = "location_fields" + // FieldsInverseTable is the table name for the ItemField entity. + // It exists in this package in order to avoid circular dependency with the "itemfield" package. + FieldsInverseTable = "location_fields" + // FieldsColumn is the table column denoting the fields relation/edge. + FieldsColumn = "location_fields" ) // Columns holds all SQL columns for location fields. diff --git a/backend/internal/data/repo/repo_items.go b/backend/internal/data/repo/repo_items.go index 3e263cc..e9543ea 100644 --- a/backend/internal/data/repo/repo_items.go +++ b/backend/internal/data/repo/repo_items.go @@ -21,7 +21,7 @@ type ItemsRepository struct { } type ( - FieldQuery struct { + ItemFieldQuery struct { Name string Value string } @@ -29,14 +29,14 @@ type ( ItemQuery struct { Page int PageSize int - Search string `json:"search"` - AssetID AssetID `json:"assetId"` - LocationIDs []uuid.UUID `json:"locationIds"` - LabelIDs []uuid.UUID `json:"labelIds"` - SortBy string `json:"sortBy"` - IncludeArchived bool `json:"includeArchived"` - Fields []FieldQuery `json:"fields"` - OrderBy string `json:"orderBy"` + Search string `json:"search"` + AssetID AssetID `json:"assetId"` + LocationIDs []uuid.UUID `json:"locationIds"` + LabelIDs []uuid.UUID `json:"labelIds"` + SortBy string `json:"sortBy"` + IncludeArchived bool `json:"includeArchived"` + Fields []ItemFieldQuery `json:"fields"` + OrderBy string `json:"orderBy"` } ItemField struct { diff --git a/backend/internal/data/repo/repo_locations.go b/backend/internal/data/repo/repo_locations.go index 28e3968..ea3290e 100644 --- a/backend/internal/data/repo/repo_locations.go +++ b/backend/internal/data/repo/repo_locations.go @@ -18,6 +18,21 @@ type LocationRepository struct { } type ( + LocationFieldQuery struct { + Name string + Value string + } + + LocationField struct { + ID uuid.UUID `json:"id,omitempty"` + Type string `json:"type"` + Name string `json:"name"` + TextValue string `json:"textValue"` + NumberValue int `json:"numberValue"` + BooleanValue bool `json:"booleanValue"` + // TimeValue time.Time `json:"timeValue,omitempty"` + } + LocationCreate struct { Name string `json:"name"` ParentID uuid.UUID `json:"parentId" extensions:"x-nullable"` @@ -29,12 +44,14 @@ type ( ID uuid.UUID `json:"id"` Name string `json:"name"` Description string `json:"description"` + Fields []LocationFieldQuery `json:"fields"` } LocationSummary struct { ID uuid.UUID `json:"id"` Name string `json:"name"` Description string `json:"description"` + Fields []LocationFieldQuery `json:"fields"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } @@ -152,6 +169,63 @@ func (r *LocationRepository) GetAll(ctx context.Context, GID uuid.UUID, filter L return list, err } +func (e *LocationRepository) GetAllCustomFieldValues(ctx context.Context, GID uuid.UUID, name string) ([]string, error) { + type st struct { + Value string `json:"text_value"` + } + + var values []st + + err := e.db.Location.Query(). + Where( + location.HasGroupWith(group.ID(GID)), + ). + QueryFields(). + Where( + locationfield.Name(name), + ). + Unique(true). + Select(locationfield.FieldTextValue). + Scan(ctx, &values) + if err != nil { + return nil, fmt.Errorf("failed to get field values: %w", err) + } + + valueStrings := make([]string, len(values)) + for i, f := range values { + valueStrings[i] = f.Value + } + + return valueStrings, nil +} + +func (e *LocationRepository) GetAllCustomFieldNames(ctx context.Context, GID uuid.UUID) ([]string, error) { + type st struct { + Name string `json:"name"` + } + + var fields []st + + err := e.db.Location.Query(). + Where( + location.HasGroupWith(group.ID(GID)), + ). + QueryFields(). + Unique(true). + Select(locationfield.FieldName). + Scan(ctx, &fields) + if err != nil { + return nil, fmt.Errorf("failed to get custom fields: %w", err) + } + + fieldNames := make([]string, len(fields)) + for i, f := range fields { + fieldNames[i] = f.Name + } + + return fieldNames, nil +} + func (r *LocationRepository) getOne(ctx context.Context, where ...predicate.Location) (LocationOut, error) { return mapLocationOutErr(r.db.Location.Query(). Where(where...). diff --git a/backend/internal/data/repo/repo_locations_test.go b/backend/internal/data/repo/repo_locations_test.go index c5884f0..4e80369 100644 --- a/backend/internal/data/repo/repo_locations_test.go +++ b/backend/internal/data/repo/repo_locations_test.go @@ -291,7 +291,6 @@ func TestConvertLocationsToTree(t *testing.T) { } } - func TestLocationRepository_GetAllCustomFields(t *testing.T) { const FIELDS_COUNT = 5 @@ -312,11 +311,10 @@ func TestLocationRepository_GetAllCustomFields(t *testing.T) { values[i] = fields[i].TextValue } - _, err := tRepos.Locations.UpdateByGroup(context.Background(), tGroup.ID, LocationUpdate{ - ID: entity.ID, - Name: entity.Name, - LocationID: entity.Location.ID, - Fields: fields, + _, err := tRepos.Locations.UpdateByGroup(context.Background(), tGroup.ID, entity.ID, LocationUpdate{ + ID: entity.ID, + Name: entity.Name, + Fields: fields, }) require.NoError(t, err)