feat: import export rewrite (#290)

* WIP: initial work

* refactoring

* fix failing JS tests

* update import docs

* fix import headers

* fix column headers

* update refs on import

* remove demo status

* finnnneeeee

* formatting
This commit is contained in:
Hayden 2023-02-25 17:54:40 -09:00 committed by GitHub
parent a005fa5b9b
commit a6bcb36c5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 1616 additions and 796 deletions

View file

@ -67,6 +67,26 @@ func (iu *ItemUpdate) ClearDescription() *ItemUpdate {
return iu
}
// SetImportRef sets the "import_ref" field.
func (iu *ItemUpdate) SetImportRef(s string) *ItemUpdate {
iu.mutation.SetImportRef(s)
return iu
}
// SetNillableImportRef sets the "import_ref" field if the given value is not nil.
func (iu *ItemUpdate) SetNillableImportRef(s *string) *ItemUpdate {
if s != nil {
iu.SetImportRef(*s)
}
return iu
}
// ClearImportRef clears the value of the "import_ref" field.
func (iu *ItemUpdate) ClearImportRef() *ItemUpdate {
iu.mutation.ClearImportRef()
return iu
}
// SetNotes sets the "notes" field.
func (iu *ItemUpdate) SetNotes(s string) *ItemUpdate {
iu.mutation.SetNotes(s)
@ -713,6 +733,11 @@ func (iu *ItemUpdate) check() error {
return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "Item.description": %w`, err)}
}
}
if v, ok := iu.mutation.ImportRef(); ok {
if err := item.ImportRefValidator(v); err != nil {
return &ValidationError{Name: "import_ref", err: fmt.Errorf(`ent: validator failed for field "Item.import_ref": %w`, err)}
}
}
if v, ok := iu.mutation.Notes(); ok {
if err := item.NotesValidator(v); err != nil {
return &ValidationError{Name: "notes", err: fmt.Errorf(`ent: validator failed for field "Item.notes": %w`, err)}
@ -773,6 +798,9 @@ func (iu *ItemUpdate) sqlSave(ctx context.Context) (n int, err error) {
if iu.mutation.DescriptionCleared() {
_spec.ClearField(item.FieldDescription, field.TypeString)
}
if value, ok := iu.mutation.ImportRef(); ok {
_spec.SetField(item.FieldImportRef, field.TypeString, value)
}
if iu.mutation.ImportRefCleared() {
_spec.ClearField(item.FieldImportRef, field.TypeString)
}
@ -1302,6 +1330,26 @@ func (iuo *ItemUpdateOne) ClearDescription() *ItemUpdateOne {
return iuo
}
// SetImportRef sets the "import_ref" field.
func (iuo *ItemUpdateOne) SetImportRef(s string) *ItemUpdateOne {
iuo.mutation.SetImportRef(s)
return iuo
}
// SetNillableImportRef sets the "import_ref" field if the given value is not nil.
func (iuo *ItemUpdateOne) SetNillableImportRef(s *string) *ItemUpdateOne {
if s != nil {
iuo.SetImportRef(*s)
}
return iuo
}
// ClearImportRef clears the value of the "import_ref" field.
func (iuo *ItemUpdateOne) ClearImportRef() *ItemUpdateOne {
iuo.mutation.ClearImportRef()
return iuo
}
// SetNotes sets the "notes" field.
func (iuo *ItemUpdateOne) SetNotes(s string) *ItemUpdateOne {
iuo.mutation.SetNotes(s)
@ -1961,6 +2009,11 @@ func (iuo *ItemUpdateOne) check() error {
return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "Item.description": %w`, err)}
}
}
if v, ok := iuo.mutation.ImportRef(); ok {
if err := item.ImportRefValidator(v); err != nil {
return &ValidationError{Name: "import_ref", err: fmt.Errorf(`ent: validator failed for field "Item.import_ref": %w`, err)}
}
}
if v, ok := iuo.mutation.Notes(); ok {
if err := item.NotesValidator(v); err != nil {
return &ValidationError{Name: "notes", err: fmt.Errorf(`ent: validator failed for field "Item.notes": %w`, err)}
@ -2038,6 +2091,9 @@ func (iuo *ItemUpdateOne) sqlSave(ctx context.Context) (_node *Item, err error)
if iuo.mutation.DescriptionCleared() {
_spec.ClearField(item.FieldDescription, field.TypeString)
}
if value, ok := iuo.mutation.ImportRef(); ok {
_spec.SetField(item.FieldImportRef, field.TypeString, value)
}
if iuo.mutation.ImportRefCleared() {
_spec.ClearField(item.FieldImportRef, field.TypeString)
}

View file

@ -38,8 +38,7 @@ func (Item) Fields() []ent.Field {
return []ent.Field{
field.String("import_ref").
Optional().
MaxLen(100).
Immutable(),
MaxLen(100),
field.String("notes").
MaxLen(1000).
Optional(),

View file

@ -32,10 +32,18 @@ func ParseAssetID(s string) (AID AssetID, ok bool) {
return ParseAssetIDBytes([]byte(s))
}
func (aid AssetID) MarshalJSON() ([]byte, error) {
func (aid AssetID) String() string {
if aid.Nil() {
return ""
}
aidStr := fmt.Sprintf("%06d", aid)
aidStr = fmt.Sprintf("%s-%s", aidStr[:3], aidStr[3:])
return []byte(fmt.Sprintf(`"%s"`, aidStr)), nil
return aidStr
}
func (aid AssetID) MarshalJSON() ([]byte, error) {
return []byte(`"` + aid.String() + `"`), nil
}
func (aid *AssetID) UnmarshalJSON(d []byte) error {
@ -50,3 +58,11 @@ func (aid *AssetID) UnmarshalJSON(d []byte) error {
*aid = AssetID(aidInt)
return nil
}
func (aid AssetID) MarshalCSV() (string, error) {
return aid.String(), nil
}
func (aid *AssetID) UnmarshalCSV(d string) error {
return aid.UnmarshalJSON([]byte(d))
}

View file

@ -21,7 +21,7 @@ func TestAssetID_MarshalJSON(t *testing.T) {
{
name: "zero test",
aid: 0,
want: []byte(`"000-000"`),
want: []byte(`""`),
},
{
name: "large int",

View file

@ -59,6 +59,7 @@ type (
LocationID uuid.UUID `json:"locationId"`
LabelIDs []uuid.UUID `json:"labelIds"`
}
ItemUpdate struct {
ParentID uuid.UUID `json:"parentId" extensions:"x-nullable,x-omitempty"`
ID uuid.UUID `json:"id"`
@ -99,6 +100,12 @@ type (
Fields []ItemField `json:"fields"`
}
ItemPatch struct {
ID uuid.UUID `json:"id"`
Quantity *int `json:"quantity,omitempty" extensions:"x-nullable,x-omitempty"`
ImportRef *string `json:"importRef,omitempty" extensions:"x-nullable,x-omitempty"`
}
ItemSummary struct {
ImportRef string `json:"-"`
ID uuid.UUID `json:"id"`
@ -168,6 +175,7 @@ func mapItemSummary(item *ent.Item) ItemSummary {
ID: item.ID,
Name: item.Name,
Description: item.Description,
ImportRef: item.ImportRef,
Quantity: item.Quantity,
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
@ -285,6 +293,10 @@ func (e *ItemsRepository) CheckRef(ctx context.Context, GID uuid.UUID, ref strin
return q.Where(item.ImportRef(ref)).Exist(ctx)
}
func (e *ItemsRepository) GetByRef(ctx context.Context, GID uuid.UUID, ref string) (ItemOut, error) {
return e.getOne(ctx, item.ImportRef(ref), item.HasGroupWith(group.ID(GID)))
}
// GetOneByGroup returns a single item by ID. If the item does not exist, an error is returned.
// GetOneByGroup ensures that the item belongs to a specific group.
func (e *ItemsRepository) GetOneByGroup(ctx context.Context, gid, id uuid.UUID) (ItemOut, error) {
@ -628,6 +640,44 @@ func (e *ItemsRepository) UpdateByGroup(ctx context.Context, GID uuid.UUID, data
return e.GetOne(ctx, data.ID)
}
func (e *ItemsRepository) GetAllZeroImportRef(ctx context.Context, GID uuid.UUID) ([]uuid.UUID, error) {
var ids []uuid.UUID
err := e.db.Item.Query().
Where(
item.HasGroupWith(group.ID(GID)),
item.Or(
item.ImportRefEQ(""),
item.ImportRefIsNil(),
),
).
Select(item.FieldID).
Scan(ctx, &ids)
if err != nil {
return nil, err
}
return ids, nil
}
func (e *ItemsRepository) Patch(ctx context.Context, GID, ID uuid.UUID, data ItemPatch) error {
q := e.db.Item.Update().
Where(
item.ID(ID),
item.HasGroupWith(group.ID(GID)),
)
if data.ImportRef != nil {
q.SetImportRef(*data.ImportRef)
}
if data.Quantity != nil {
q.SetQuantity(*data.Quantity)
}
return q.Exec(ctx)
}
func (e *ItemsRepository) GetAllCustomFieldValues(ctx context.Context, GID uuid.UUID, name string) ([]string, error) {
type st struct {
Value string `json:"text_value"`

View file

@ -16,9 +16,7 @@ func getPrevMonth(now time.Time) time.Time {
// avoid infinite loop
max := 15
for t.Month() == now.Month() {
println("month is the same")
t = t.AddDate(0, 0, -1)
println(t.String())
max--
if max == 0 {

View file

@ -2,7 +2,6 @@ package repo
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
@ -81,7 +80,6 @@ func TestUserRepo_GetAll(t *testing.T) {
assert.Equal(t, len(created), len(allUsers))
for _, usr := range created {
fmt.Printf("%+v\n", usr)
for _, usr2 := range allUsers {
if usr.ID == usr2.ID {
assert.Equal(t, usr.Email, usr2.Email)

View file

@ -2,7 +2,6 @@ package types
import (
"errors"
"fmt"
"strings"
"time"
)
@ -74,9 +73,7 @@ func (d Date) MarshalJSON() ([]byte, error) {
func (d *Date) UnmarshalJSON(data []byte) (err error) {
// unescape the string if necessary `\"` -> `"`
str := strings.Trim(string(data), "\"")
fmt.Printf("str: %q\n", str)
if str == "" || str == "null" || str == `""` {
println("empty date")
*d = Date{}
return nil
}