forked from mirrors/homebox
fix: csv-importer (#10)
* update item fields to support import_ref * add additional rows to CSV importer * add CSV import documentation * update readme * update readme * fix failed test
This commit is contained in:
parent
90813abf76
commit
ca36e3b080
21 changed files with 447 additions and 135 deletions
|
@ -27,6 +27,8 @@ type Item struct {
|
|||
Name string `json:"name,omitempty"`
|
||||
// Description holds the value of the "description" field.
|
||||
Description string `json:"description,omitempty"`
|
||||
// ImportRef holds the value of the "import_ref" field.
|
||||
ImportRef string `json:"import_ref,omitempty"`
|
||||
// Notes holds the value of the "notes" field.
|
||||
Notes string `json:"notes,omitempty"`
|
||||
// Quantity holds the value of the "quantity" field.
|
||||
|
@ -147,7 +149,7 @@ func (*Item) scanValues(columns []string) ([]interface{}, error) {
|
|||
values[i] = new(sql.NullFloat64)
|
||||
case item.FieldQuantity:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case item.FieldName, item.FieldDescription, item.FieldNotes, item.FieldSerialNumber, item.FieldModelNumber, item.FieldManufacturer, item.FieldWarrantyDetails, item.FieldPurchaseFrom, item.FieldSoldTo, item.FieldSoldNotes:
|
||||
case item.FieldName, item.FieldDescription, item.FieldImportRef, item.FieldNotes, item.FieldSerialNumber, item.FieldModelNumber, item.FieldManufacturer, item.FieldWarrantyDetails, item.FieldPurchaseFrom, item.FieldSoldTo, item.FieldSoldNotes:
|
||||
values[i] = new(sql.NullString)
|
||||
case item.FieldCreatedAt, item.FieldUpdatedAt, item.FieldWarrantyExpires, item.FieldPurchaseTime, item.FieldSoldTime:
|
||||
values[i] = new(sql.NullTime)
|
||||
|
@ -202,6 +204,12 @@ func (i *Item) assignValues(columns []string, values []interface{}) error {
|
|||
} else if value.Valid {
|
||||
i.Description = value.String
|
||||
}
|
||||
case item.FieldImportRef:
|
||||
if value, ok := values[j].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field import_ref", values[j])
|
||||
} else if value.Valid {
|
||||
i.ImportRef = value.String
|
||||
}
|
||||
case item.FieldNotes:
|
||||
if value, ok := values[j].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field notes", values[j])
|
||||
|
@ -377,6 +385,9 @@ func (i *Item) String() string {
|
|||
builder.WriteString("description=")
|
||||
builder.WriteString(i.Description)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("import_ref=")
|
||||
builder.WriteString(i.ImportRef)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("notes=")
|
||||
builder.WriteString(i.Notes)
|
||||
builder.WriteString(", ")
|
||||
|
|
|
@ -21,6 +21,8 @@ const (
|
|||
FieldName = "name"
|
||||
// FieldDescription holds the string denoting the description field in the database.
|
||||
FieldDescription = "description"
|
||||
// FieldImportRef holds the string denoting the import_ref field in the database.
|
||||
FieldImportRef = "import_ref"
|
||||
// FieldNotes holds the string denoting the notes field in the database.
|
||||
FieldNotes = "notes"
|
||||
// FieldQuantity holds the string denoting the quantity field in the database.
|
||||
|
@ -107,6 +109,7 @@ var Columns = []string{
|
|||
FieldUpdatedAt,
|
||||
FieldName,
|
||||
FieldDescription,
|
||||
FieldImportRef,
|
||||
FieldNotes,
|
||||
FieldQuantity,
|
||||
FieldInsured,
|
||||
|
@ -164,6 +167,8 @@ var (
|
|||
NameValidator func(string) error
|
||||
// DescriptionValidator is a validator for the "description" field. It is called by the builders before save.
|
||||
DescriptionValidator func(string) error
|
||||
// ImportRefValidator is a validator for the "import_ref" field. It is called by the builders before save.
|
||||
ImportRefValidator func(string) error
|
||||
// NotesValidator is a validator for the "notes" field. It is called by the builders before save.
|
||||
NotesValidator func(string) error
|
||||
// DefaultQuantity holds the default value on creation for the "quantity" field.
|
||||
|
|
|
@ -110,6 +110,13 @@ func Description(v string) predicate.Item {
|
|||
})
|
||||
}
|
||||
|
||||
// ImportRef applies equality check predicate on the "import_ref" field. It's identical to ImportRefEQ.
|
||||
func ImportRef(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// Notes applies equality check predicate on the "notes" field. It's identical to NotesEQ.
|
||||
func Notes(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
|
@ -562,6 +569,119 @@ func DescriptionContainsFold(v string) predicate.Item {
|
|||
})
|
||||
}
|
||||
|
||||
// ImportRefEQ applies the EQ predicate on the "import_ref" field.
|
||||
func ImportRefEQ(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefNEQ applies the NEQ predicate on the "import_ref" field.
|
||||
func ImportRefNEQ(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefIn applies the In predicate on the "import_ref" field.
|
||||
func ImportRefIn(vs ...string) predicate.Item {
|
||||
v := make([]interface{}, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldImportRef), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefNotIn applies the NotIn predicate on the "import_ref" field.
|
||||
func ImportRefNotIn(vs ...string) predicate.Item {
|
||||
v := make([]interface{}, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldImportRef), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefGT applies the GT predicate on the "import_ref" field.
|
||||
func ImportRefGT(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefGTE applies the GTE predicate on the "import_ref" field.
|
||||
func ImportRefGTE(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefLT applies the LT predicate on the "import_ref" field.
|
||||
func ImportRefLT(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefLTE applies the LTE predicate on the "import_ref" field.
|
||||
func ImportRefLTE(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefContains applies the Contains predicate on the "import_ref" field.
|
||||
func ImportRefContains(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.Contains(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefHasPrefix applies the HasPrefix predicate on the "import_ref" field.
|
||||
func ImportRefHasPrefix(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.HasPrefix(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefHasSuffix applies the HasSuffix predicate on the "import_ref" field.
|
||||
func ImportRefHasSuffix(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.HasSuffix(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefIsNil applies the IsNil predicate on the "import_ref" field.
|
||||
func ImportRefIsNil() predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.IsNull(s.C(FieldImportRef)))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefNotNil applies the NotNil predicate on the "import_ref" field.
|
||||
func ImportRefNotNil() predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.NotNull(s.C(FieldImportRef)))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefEqualFold applies the EqualFold predicate on the "import_ref" field.
|
||||
func ImportRefEqualFold(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.EqualFold(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ImportRefContainsFold applies the ContainsFold predicate on the "import_ref" field.
|
||||
func ImportRefContainsFold(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
s.Where(sql.ContainsFold(s.C(FieldImportRef), v))
|
||||
})
|
||||
}
|
||||
|
||||
// NotesEQ applies the EQ predicate on the "notes" field.
|
||||
func NotesEQ(v string) predicate.Item {
|
||||
return predicate.Item(func(s *sql.Selector) {
|
||||
|
|
|
@ -74,6 +74,20 @@ func (ic *ItemCreate) SetNillableDescription(s *string) *ItemCreate {
|
|||
return ic
|
||||
}
|
||||
|
||||
// SetImportRef sets the "import_ref" field.
|
||||
func (ic *ItemCreate) SetImportRef(s string) *ItemCreate {
|
||||
ic.mutation.SetImportRef(s)
|
||||
return ic
|
||||
}
|
||||
|
||||
// SetNillableImportRef sets the "import_ref" field if the given value is not nil.
|
||||
func (ic *ItemCreate) SetNillableImportRef(s *string) *ItemCreate {
|
||||
if s != nil {
|
||||
ic.SetImportRef(*s)
|
||||
}
|
||||
return ic
|
||||
}
|
||||
|
||||
// SetNotes sets the "notes" field.
|
||||
func (ic *ItemCreate) SetNotes(s string) *ItemCreate {
|
||||
ic.mutation.SetNotes(s)
|
||||
|
@ -519,6 +533,11 @@ func (ic *ItemCreate) check() error {
|
|||
return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "Item.description": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := ic.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 := ic.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)}
|
||||
|
@ -635,6 +654,14 @@ func (ic *ItemCreate) createSpec() (*Item, *sqlgraph.CreateSpec) {
|
|||
})
|
||||
_node.Description = value
|
||||
}
|
||||
if value, ok := ic.mutation.ImportRef(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
Value: value,
|
||||
Column: item.FieldImportRef,
|
||||
})
|
||||
_node.ImportRef = value
|
||||
}
|
||||
if value, ok := ic.mutation.Notes(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
|
|
|
@ -694,6 +694,12 @@ func (iu *ItemUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
|||
Column: item.FieldDescription,
|
||||
})
|
||||
}
|
||||
if iu.mutation.ImportRefCleared() {
|
||||
_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
Column: item.FieldImportRef,
|
||||
})
|
||||
}
|
||||
if value, ok := iu.mutation.Notes(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
|
@ -1834,6 +1840,12 @@ func (iuo *ItemUpdateOne) sqlSave(ctx context.Context) (_node *Item, err error)
|
|||
Column: item.FieldDescription,
|
||||
})
|
||||
}
|
||||
if iuo.mutation.ImportRefCleared() {
|
||||
_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
Column: item.FieldImportRef,
|
||||
})
|
||||
}
|
||||
if value, ok := iuo.mutation.Notes(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
|
|
|
@ -142,6 +142,7 @@ var (
|
|||
{Name: "updated_at", Type: field.TypeTime},
|
||||
{Name: "name", Type: field.TypeString, Size: 255},
|
||||
{Name: "description", Type: field.TypeString, Nullable: true, Size: 1000},
|
||||
{Name: "import_ref", Type: field.TypeString, Nullable: true, Size: 100},
|
||||
{Name: "notes", Type: field.TypeString, Nullable: true, Size: 1000},
|
||||
{Name: "quantity", Type: field.TypeInt, Default: 1},
|
||||
{Name: "insured", Type: field.TypeBool, Default: false},
|
||||
|
@ -169,15 +170,15 @@ var (
|
|||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "items_groups_items",
|
||||
Columns: []*schema.Column{ItemsColumns[21]},
|
||||
Columns: []*schema.Column{ItemsColumns[22]},
|
||||
RefColumns: []*schema.Column{GroupsColumns[0]},
|
||||
OnDelete: schema.Cascade,
|
||||
},
|
||||
{
|
||||
Symbol: "items_locations_items",
|
||||
Columns: []*schema.Column{ItemsColumns[22]},
|
||||
Columns: []*schema.Column{ItemsColumns[23]},
|
||||
RefColumns: []*schema.Column{LocationsColumns[0]},
|
||||
OnDelete: schema.SetNull,
|
||||
OnDelete: schema.Cascade,
|
||||
},
|
||||
},
|
||||
Indexes: []*schema.Index{
|
||||
|
@ -189,17 +190,17 @@ var (
|
|||
{
|
||||
Name: "item_manufacturer",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{ItemsColumns[10]},
|
||||
Columns: []*schema.Column{ItemsColumns[11]},
|
||||
},
|
||||
{
|
||||
Name: "item_model_number",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{ItemsColumns[9]},
|
||||
Columns: []*schema.Column{ItemsColumns[10]},
|
||||
},
|
||||
{
|
||||
Name: "item_serial_number",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{ItemsColumns[8]},
|
||||
Columns: []*schema.Column{ItemsColumns[9]},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -3413,6 +3413,7 @@ type ItemMutation struct {
|
|||
updated_at *time.Time
|
||||
name *string
|
||||
description *string
|
||||
import_ref *string
|
||||
notes *string
|
||||
quantity *int
|
||||
addquantity *int
|
||||
|
@ -3712,6 +3713,55 @@ func (m *ItemMutation) ResetDescription() {
|
|||
delete(m.clearedFields, item.FieldDescription)
|
||||
}
|
||||
|
||||
// SetImportRef sets the "import_ref" field.
|
||||
func (m *ItemMutation) SetImportRef(s string) {
|
||||
m.import_ref = &s
|
||||
}
|
||||
|
||||
// ImportRef returns the value of the "import_ref" field in the mutation.
|
||||
func (m *ItemMutation) ImportRef() (r string, exists bool) {
|
||||
v := m.import_ref
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldImportRef returns the old "import_ref" field's value of the Item entity.
|
||||
// If the Item object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *ItemMutation) OldImportRef(ctx context.Context) (v string, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldImportRef is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldImportRef requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldImportRef: %w", err)
|
||||
}
|
||||
return oldValue.ImportRef, nil
|
||||
}
|
||||
|
||||
// ClearImportRef clears the value of the "import_ref" field.
|
||||
func (m *ItemMutation) ClearImportRef() {
|
||||
m.import_ref = nil
|
||||
m.clearedFields[item.FieldImportRef] = struct{}{}
|
||||
}
|
||||
|
||||
// ImportRefCleared returns if the "import_ref" field was cleared in this mutation.
|
||||
func (m *ItemMutation) ImportRefCleared() bool {
|
||||
_, ok := m.clearedFields[item.FieldImportRef]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetImportRef resets all changes to the "import_ref" field.
|
||||
func (m *ItemMutation) ResetImportRef() {
|
||||
m.import_ref = nil
|
||||
delete(m.clearedFields, item.FieldImportRef)
|
||||
}
|
||||
|
||||
// SetNotes sets the "notes" field.
|
||||
func (m *ItemMutation) SetNotes(s string) {
|
||||
m.notes = &s
|
||||
|
@ -4750,7 +4800,7 @@ func (m *ItemMutation) Type() string {
|
|||
// order to get all numeric fields that were incremented/decremented, call
|
||||
// AddedFields().
|
||||
func (m *ItemMutation) Fields() []string {
|
||||
fields := make([]string, 0, 20)
|
||||
fields := make([]string, 0, 21)
|
||||
if m.created_at != nil {
|
||||
fields = append(fields, item.FieldCreatedAt)
|
||||
}
|
||||
|
@ -4763,6 +4813,9 @@ func (m *ItemMutation) Fields() []string {
|
|||
if m.description != nil {
|
||||
fields = append(fields, item.FieldDescription)
|
||||
}
|
||||
if m.import_ref != nil {
|
||||
fields = append(fields, item.FieldImportRef)
|
||||
}
|
||||
if m.notes != nil {
|
||||
fields = append(fields, item.FieldNotes)
|
||||
}
|
||||
|
@ -4827,6 +4880,8 @@ func (m *ItemMutation) Field(name string) (ent.Value, bool) {
|
|||
return m.Name()
|
||||
case item.FieldDescription:
|
||||
return m.Description()
|
||||
case item.FieldImportRef:
|
||||
return m.ImportRef()
|
||||
case item.FieldNotes:
|
||||
return m.Notes()
|
||||
case item.FieldQuantity:
|
||||
|
@ -4876,6 +4931,8 @@ func (m *ItemMutation) OldField(ctx context.Context, name string) (ent.Value, er
|
|||
return m.OldName(ctx)
|
||||
case item.FieldDescription:
|
||||
return m.OldDescription(ctx)
|
||||
case item.FieldImportRef:
|
||||
return m.OldImportRef(ctx)
|
||||
case item.FieldNotes:
|
||||
return m.OldNotes(ctx)
|
||||
case item.FieldQuantity:
|
||||
|
@ -4945,6 +5002,13 @@ func (m *ItemMutation) SetField(name string, value ent.Value) error {
|
|||
}
|
||||
m.SetDescription(v)
|
||||
return nil
|
||||
case item.FieldImportRef:
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetImportRef(v)
|
||||
return nil
|
||||
case item.FieldNotes:
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
|
@ -5129,6 +5193,9 @@ func (m *ItemMutation) ClearedFields() []string {
|
|||
if m.FieldCleared(item.FieldDescription) {
|
||||
fields = append(fields, item.FieldDescription)
|
||||
}
|
||||
if m.FieldCleared(item.FieldImportRef) {
|
||||
fields = append(fields, item.FieldImportRef)
|
||||
}
|
||||
if m.FieldCleared(item.FieldNotes) {
|
||||
fields = append(fields, item.FieldNotes)
|
||||
}
|
||||
|
@ -5179,6 +5246,9 @@ func (m *ItemMutation) ClearField(name string) error {
|
|||
case item.FieldDescription:
|
||||
m.ClearDescription()
|
||||
return nil
|
||||
case item.FieldImportRef:
|
||||
m.ClearImportRef()
|
||||
return nil
|
||||
case item.FieldNotes:
|
||||
m.ClearNotes()
|
||||
return nil
|
||||
|
@ -5232,6 +5302,9 @@ func (m *ItemMutation) ResetField(name string) error {
|
|||
case item.FieldDescription:
|
||||
m.ResetDescription()
|
||||
return nil
|
||||
case item.FieldImportRef:
|
||||
m.ResetImportRef()
|
||||
return nil
|
||||
case item.FieldNotes:
|
||||
m.ResetNotes()
|
||||
return nil
|
||||
|
|
|
@ -227,48 +227,52 @@ func init() {
|
|||
itemDescDescription := itemMixinFields1[1].Descriptor()
|
||||
// item.DescriptionValidator is a validator for the "description" field. It is called by the builders before save.
|
||||
item.DescriptionValidator = itemDescDescription.Validators[0].(func(string) error)
|
||||
// itemDescImportRef is the schema descriptor for import_ref field.
|
||||
itemDescImportRef := itemFields[0].Descriptor()
|
||||
// item.ImportRefValidator is a validator for the "import_ref" field. It is called by the builders before save.
|
||||
item.ImportRefValidator = itemDescImportRef.Validators[0].(func(string) error)
|
||||
// itemDescNotes is the schema descriptor for notes field.
|
||||
itemDescNotes := itemFields[0].Descriptor()
|
||||
itemDescNotes := itemFields[1].Descriptor()
|
||||
// item.NotesValidator is a validator for the "notes" field. It is called by the builders before save.
|
||||
item.NotesValidator = itemDescNotes.Validators[0].(func(string) error)
|
||||
// itemDescQuantity is the schema descriptor for quantity field.
|
||||
itemDescQuantity := itemFields[1].Descriptor()
|
||||
itemDescQuantity := itemFields[2].Descriptor()
|
||||
// item.DefaultQuantity holds the default value on creation for the quantity field.
|
||||
item.DefaultQuantity = itemDescQuantity.Default.(int)
|
||||
// itemDescInsured is the schema descriptor for insured field.
|
||||
itemDescInsured := itemFields[2].Descriptor()
|
||||
itemDescInsured := itemFields[3].Descriptor()
|
||||
// item.DefaultInsured holds the default value on creation for the insured field.
|
||||
item.DefaultInsured = itemDescInsured.Default.(bool)
|
||||
// itemDescSerialNumber is the schema descriptor for serial_number field.
|
||||
itemDescSerialNumber := itemFields[3].Descriptor()
|
||||
itemDescSerialNumber := itemFields[4].Descriptor()
|
||||
// item.SerialNumberValidator is a validator for the "serial_number" field. It is called by the builders before save.
|
||||
item.SerialNumberValidator = itemDescSerialNumber.Validators[0].(func(string) error)
|
||||
// itemDescModelNumber is the schema descriptor for model_number field.
|
||||
itemDescModelNumber := itemFields[4].Descriptor()
|
||||
itemDescModelNumber := itemFields[5].Descriptor()
|
||||
// item.ModelNumberValidator is a validator for the "model_number" field. It is called by the builders before save.
|
||||
item.ModelNumberValidator = itemDescModelNumber.Validators[0].(func(string) error)
|
||||
// itemDescManufacturer is the schema descriptor for manufacturer field.
|
||||
itemDescManufacturer := itemFields[5].Descriptor()
|
||||
itemDescManufacturer := itemFields[6].Descriptor()
|
||||
// item.ManufacturerValidator is a validator for the "manufacturer" field. It is called by the builders before save.
|
||||
item.ManufacturerValidator = itemDescManufacturer.Validators[0].(func(string) error)
|
||||
// itemDescLifetimeWarranty is the schema descriptor for lifetime_warranty field.
|
||||
itemDescLifetimeWarranty := itemFields[6].Descriptor()
|
||||
itemDescLifetimeWarranty := itemFields[7].Descriptor()
|
||||
// item.DefaultLifetimeWarranty holds the default value on creation for the lifetime_warranty field.
|
||||
item.DefaultLifetimeWarranty = itemDescLifetimeWarranty.Default.(bool)
|
||||
// itemDescWarrantyDetails is the schema descriptor for warranty_details field.
|
||||
itemDescWarrantyDetails := itemFields[8].Descriptor()
|
||||
itemDescWarrantyDetails := itemFields[9].Descriptor()
|
||||
// item.WarrantyDetailsValidator is a validator for the "warranty_details" field. It is called by the builders before save.
|
||||
item.WarrantyDetailsValidator = itemDescWarrantyDetails.Validators[0].(func(string) error)
|
||||
// itemDescPurchasePrice is the schema descriptor for purchase_price field.
|
||||
itemDescPurchasePrice := itemFields[11].Descriptor()
|
||||
itemDescPurchasePrice := itemFields[12].Descriptor()
|
||||
// item.DefaultPurchasePrice holds the default value on creation for the purchase_price field.
|
||||
item.DefaultPurchasePrice = itemDescPurchasePrice.Default.(float64)
|
||||
// itemDescSoldPrice is the schema descriptor for sold_price field.
|
||||
itemDescSoldPrice := itemFields[14].Descriptor()
|
||||
itemDescSoldPrice := itemFields[15].Descriptor()
|
||||
// item.DefaultSoldPrice holds the default value on creation for the sold_price field.
|
||||
item.DefaultSoldPrice = itemDescSoldPrice.Default.(float64)
|
||||
// itemDescSoldNotes is the schema descriptor for sold_notes field.
|
||||
itemDescSoldNotes := itemFields[15].Descriptor()
|
||||
itemDescSoldNotes := itemFields[16].Descriptor()
|
||||
// item.SoldNotesValidator is a validator for the "sold_notes" field. It is called by the builders before save.
|
||||
item.SoldNotesValidator = itemDescSoldNotes.Validators[0].(func(string) error)
|
||||
// itemDescID is the schema descriptor for id field.
|
||||
|
|
|
@ -34,6 +34,10 @@ func (Item) Indexes() []ent.Index {
|
|||
// Fields of the Item.
|
||||
func (Item) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("import_ref").
|
||||
Optional().
|
||||
MaxLen(100).
|
||||
Immutable(),
|
||||
field.String("notes").
|
||||
MaxLen(1000).
|
||||
Optional(),
|
||||
|
@ -102,7 +106,10 @@ func (Item) Edges() []ent.Edge {
|
|||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
edge.From("label", Label.Type).
|
||||
Ref("items"),
|
||||
Ref("items").
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
edge.To("attachments", Attachment.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
|
|
|
@ -2,6 +2,7 @@ package schema
|
|||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/entsql"
|
||||
"entgo.io/ent/schema/edge"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/hay-kot/content/backend/ent/schema/mixins"
|
||||
|
@ -35,6 +36,9 @@ func (Label) Edges() []ent.Edge {
|
|||
Ref("labels").
|
||||
Required().
|
||||
Unique(),
|
||||
edge.To("items", Item.Type),
|
||||
edge.To("items", Item.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package schema
|
|||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/entsql"
|
||||
"entgo.io/ent/schema/edge"
|
||||
"github.com/hay-kot/content/backend/ent/schema/mixins"
|
||||
)
|
||||
|
@ -30,6 +31,9 @@ func (Location) Edges() []ent.Edge {
|
|||
Ref("locations").
|
||||
Unique().
|
||||
Required(),
|
||||
edge.To("items", Item.Type),
|
||||
edge.To("items", Item.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,12 +84,10 @@ func TestItemsRepository_Create(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, result.ID)
|
||||
|
||||
// Cleanup
|
||||
// Cleanup - Also deletes item
|
||||
err = tRepos.Locations.Delete(context.Background(), location.ID)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = tRepos.Items.Delete(context.Background(), result.ID)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestItemsRepository_Create_Location(t *testing.T) {
|
||||
|
@ -111,11 +109,9 @@ func TestItemsRepository_Create_Location(t *testing.T) {
|
|||
assert.Equal(t, result.ID, foundItem.ID)
|
||||
assert.Equal(t, location.ID, foundItem.Edges.Location.ID)
|
||||
|
||||
// Cleanup
|
||||
// Cleanup - Also deletes item
|
||||
err = tRepos.Locations.Delete(context.Background(), location.ID)
|
||||
assert.NoError(t, err)
|
||||
err = tRepos.Items.Delete(context.Background(), result.ID)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestItemsRepository_Delete(t *testing.T) {
|
||||
|
|
|
@ -156,7 +156,8 @@ func (svc *ItemService) CsvImport(ctx context.Context, gid uuid.UUID, data [][]s
|
|||
if len(row) == 0 {
|
||||
continue
|
||||
}
|
||||
if len(row) != 14 {
|
||||
|
||||
if len(row) != NumOfCols {
|
||||
return ErrInvalidCsv
|
||||
}
|
||||
|
||||
|
@ -227,15 +228,16 @@ func (svc *ItemService) CsvImport(ctx context.Context, gid uuid.UUID, data [][]s
|
|||
}
|
||||
|
||||
log.Info().
|
||||
Str("name", row.Name).
|
||||
Str("name", row.Item.Name).
|
||||
Str("location", row.Location).
|
||||
Strs("labels", row.getLabels()).
|
||||
Str("locationId", locationID.String()).
|
||||
Msgf("Creating Item: %s", row.Name)
|
||||
Msgf("Creating Item: %s", row.Item.Name)
|
||||
|
||||
result, err := svc.repo.Items.Create(ctx, gid, types.ItemCreate{
|
||||
Name: row.Name,
|
||||
Description: row.Description,
|
||||
ImportRef: row.Item.ImportRef,
|
||||
Name: row.Item.Name,
|
||||
Description: row.Item.Description,
|
||||
LabelIDs: labelIDs,
|
||||
LocationID: locationID,
|
||||
})
|
||||
|
@ -246,21 +248,36 @@ func (svc *ItemService) CsvImport(ctx context.Context, gid uuid.UUID, data [][]s
|
|||
|
||||
// Update the item with the rest of the data
|
||||
_, err = svc.repo.Items.Update(ctx, types.ItemUpdate{
|
||||
ID: result.ID,
|
||||
Name: result.Name,
|
||||
LocationID: locationID,
|
||||
LabelIDs: labelIDs,
|
||||
Description: result.Description,
|
||||
SerialNumber: row.SerialNumber,
|
||||
ModelNumber: row.ModelNumber,
|
||||
Manufacturer: row.Manufacturer,
|
||||
Notes: row.Notes,
|
||||
PurchaseFrom: row.PurchaseFrom,
|
||||
PurchasePrice: row.parsedPurchasedPrice(),
|
||||
PurchaseTime: row.parsedPurchasedAt(),
|
||||
SoldTo: row.SoldTo,
|
||||
SoldPrice: row.parsedSoldPrice(),
|
||||
SoldTime: row.parsedSoldAt(),
|
||||
// Edges
|
||||
LocationID: locationID,
|
||||
LabelIDs: labelIDs,
|
||||
|
||||
// General Fields
|
||||
ID: result.ID,
|
||||
Name: result.Name,
|
||||
Description: result.Description,
|
||||
Insured: row.Item.Insured,
|
||||
Notes: row.Item.Notes,
|
||||
|
||||
// Identifies the item as imported
|
||||
SerialNumber: row.Item.SerialNumber,
|
||||
ModelNumber: row.Item.ModelNumber,
|
||||
Manufacturer: row.Item.Manufacturer,
|
||||
|
||||
// Purchase
|
||||
PurchaseFrom: row.Item.PurchaseFrom,
|
||||
PurchasePrice: row.Item.PurchasePrice,
|
||||
PurchaseTime: row.Item.PurchaseTime,
|
||||
|
||||
// Warranty
|
||||
LifetimeWarranty: row.Item.LifetimeWarranty,
|
||||
WarrantyExpires: row.Item.WarrantyExpires,
|
||||
WarrantyDetails: row.Item.WarrantyDetails,
|
||||
|
||||
SoldTo: row.Item.SoldTo,
|
||||
SoldPrice: row.Item.SoldPrice,
|
||||
SoldTime: row.Item.SoldTime,
|
||||
SoldNotes: row.Item.SoldNotes,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -5,10 +5,14 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hay-kot/content/backend/internal/types"
|
||||
)
|
||||
|
||||
var ErrInvalidCsv = errors.New("invalid csv")
|
||||
|
||||
const NumOfCols = 21
|
||||
|
||||
func parseFloat(s string) float64 {
|
||||
if s == "" {
|
||||
return 0
|
||||
|
@ -26,60 +30,56 @@ func parseDate(s string) time.Time {
|
|||
return p
|
||||
}
|
||||
|
||||
func parseBool(s string) bool {
|
||||
switch strings.ToLower(s) {
|
||||
case "true", "yes", "1":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func parseInt(s string) int {
|
||||
i, _ := strconv.Atoi(s)
|
||||
return i
|
||||
}
|
||||
|
||||
type csvRow struct {
|
||||
Location string
|
||||
Labels string
|
||||
Name string
|
||||
Description string
|
||||
SerialNumber string
|
||||
ModelNumber string
|
||||
Manufacturer string
|
||||
Notes string
|
||||
PurchaseFrom string
|
||||
PurchasedPrice string
|
||||
PurchasedAt string
|
||||
SoldTo string
|
||||
SoldPrice string
|
||||
SoldAt string
|
||||
Item types.ItemSummary
|
||||
Location string
|
||||
LabelStr string
|
||||
}
|
||||
|
||||
func newCsvRow(row []string) csvRow {
|
||||
return csvRow{
|
||||
Location: row[0],
|
||||
Labels: row[1],
|
||||
Name: row[2],
|
||||
Description: row[3],
|
||||
SerialNumber: row[4],
|
||||
ModelNumber: row[5],
|
||||
Manufacturer: row[6],
|
||||
Notes: row[7],
|
||||
PurchaseFrom: row[8],
|
||||
PurchasedPrice: row[9],
|
||||
PurchasedAt: row[10],
|
||||
SoldTo: row[11],
|
||||
SoldPrice: row[12],
|
||||
SoldAt: row[13],
|
||||
Location: row[1],
|
||||
LabelStr: row[2],
|
||||
Item: types.ItemSummary{
|
||||
ImportRef: row[0],
|
||||
Quantity: parseInt(row[3]),
|
||||
Name: row[4],
|
||||
Description: row[5],
|
||||
Insured: parseBool(row[6]),
|
||||
SerialNumber: row[7],
|
||||
ModelNumber: row[8],
|
||||
Manufacturer: row[9],
|
||||
Notes: row[10],
|
||||
PurchaseFrom: row[11],
|
||||
PurchasePrice: parseFloat(row[12]),
|
||||
PurchaseTime: parseDate(row[13]),
|
||||
LifetimeWarranty: parseBool(row[14]),
|
||||
WarrantyExpires: parseDate(row[15]),
|
||||
WarrantyDetails: row[16],
|
||||
SoldTo: row[17],
|
||||
SoldPrice: parseFloat(row[18]),
|
||||
SoldTime: parseDate(row[19]),
|
||||
SoldNotes: row[20],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c csvRow) parsedSoldPrice() float64 {
|
||||
return parseFloat(c.SoldPrice)
|
||||
}
|
||||
|
||||
func (c csvRow) parsedPurchasedPrice() float64 {
|
||||
return parseFloat(c.PurchasedPrice)
|
||||
}
|
||||
|
||||
func (c csvRow) parsedPurchasedAt() time.Time {
|
||||
return parseDate(c.PurchasedAt)
|
||||
}
|
||||
|
||||
func (c csvRow) parsedSoldAt() time.Time {
|
||||
return parseDate(c.SoldAt)
|
||||
}
|
||||
|
||||
func (c csvRow) getLabels() []string {
|
||||
split := strings.Split(c.Labels, ";")
|
||||
split := strings.Split(c.LabelStr, ";")
|
||||
|
||||
// Trim each
|
||||
for i, s := range split {
|
||||
|
|
|
@ -8,14 +8,13 @@ import (
|
|||
)
|
||||
|
||||
const CSV_DATA = `
|
||||
Location,Labels,Name,Description,Serial Number,Mode Number,Manufacturer,Notes,Purchase From,Purchased Price,Purchased At,Sold To,Sold Price,Sold At
|
||||
Garage,IOT;Home Assistant; Z-Wave,Zooz Universal Relay ZEN17,"Zooz 700 Series Z-Wave Universal Relay ZEN17 for Awnings, Garage Doors, Sprinklers, and More | 2 NO-C-NC Relays (20A, 10A) | Signal Repeater | Hub Required (Compatible with SmartThings and Hubitat)",,ZEN17,Zooz,,Amazon,39.95,10/13/2021,,,
|
||||
Living Room,IOT;Home Assistant; Z-Wave,Zooz Motion Sensor,"Zooz Z-Wave Plus S2 Motion Sensor ZSE18 with Magnetic Mount, Works with Vera and SmartThings",,ZSE18,Zooz,,Amazon,29.95,10/15/2021,,,
|
||||
Office,IOT;Home Assistant; Z-Wave,Zooz 110v Power Switch,"Zooz Z-Wave Plus Power Switch ZEN15 for 110V AC Units, Sump Pumps, Humidifiers, and More",,ZEN15,Zooz,,Amazon,39.95,10/13/2021,,,
|
||||
Downstairs,IOT;Home Assistant; Z-Wave,Ecolink Z-Wave PIR Motion Sensor,"Ecolink Z-Wave PIR Motion Detector Pet Immune, White (PIRZWAVE2.5-ECO)",,PIRZWAVE2.5-ECO,Ecolink,,Amazon,35.58,10/21/2020,,,
|
||||
Entry,IOT;Home Assistant; Z-Wave,Yale Security Touchscreen Deadbolt,"Yale Security YRD226-ZW2-619 YRD226ZW2619 Touchscreen Deadbolt, Satin Nickel",,YRD226ZW2619,Yale,,Amazon,120.39,10/14/2020,,,
|
||||
Kitchen,IOT;Home Assistant; Z-Wave,Smart Rocker Light Dimmer,"UltraPro Z-Wave Smart Rocker Light Dimmer with QuickFit and SimpleWire, 3-Way Ready, Compatible with Alexa, Google Assistant, ZWave Hub Required, Repeater/Range Extender, White Paddle Only, 39351",,39351,Honeywell,,Amazon,65.98,09/30/0202,,,
|
||||
`
|
||||
Import Ref,Location,Labels,Quantity,Name,Description,Insured,Serial Number,Mode Number,Manufacturer,Notes,Purchase From,Purchased Price,Purchased Time,Lifetime Warranty,Warranty Expires,Warranty Details,Sold To,Sold Price,Sold Time,Sold Notes
|
||||
,Garage,IOT;Home Assistant; Z-Wave,1,Zooz Universal Relay ZEN17,"Zooz 700 Series Z-Wave Universal Relay ZEN17 for Awnings, Garage Doors, Sprinklers, and More | 2 NO-C-NC Relays (20A, 10A) | Signal Repeater | Hub Required (Compatible with SmartThings and Hubitat)",,,ZEN17,Zooz,,Amazon,39.95,10/13/2021,,,,,,,
|
||||
,Living Room,IOT;Home Assistant; Z-Wave,1,Zooz Motion Sensor,"Zooz Z-Wave Plus S2 Motion Sensor ZSE18 with Magnetic Mount, Works with Vera and SmartThings",,,ZSE18,Zooz,,Amazon,29.95,10/15/2021,,,,,,,
|
||||
,Office,IOT;Home Assistant; Z-Wave,1,Zooz 110v Power Switch,"Zooz Z-Wave Plus Power Switch ZEN15 for 110V AC Units, Sump Pumps, Humidifiers, and More",,,ZEN15,Zooz,,Amazon,39.95,10/13/2021,,,,,,,
|
||||
,Downstairs,IOT;Home Assistant; Z-Wave,1,Ecolink Z-Wave PIR Motion Sensor,"Ecolink Z-Wave PIR Motion Detector Pet Immune, White (PIRZWAVE2.5-ECO)",,,PIRZWAVE2.5-ECO,Ecolink,,Amazon,35.58,10/21/2020,,,,,,,
|
||||
,Entry,IOT;Home Assistant; Z-Wave,1,Yale Security Touchscreen Deadbolt,"Yale Security YRD226-ZW2-619 YRD226ZW2619 Touchscreen Deadbolt, Satin Nickel",,,YRD226ZW2619,Yale,,Amazon,120.39,10/14/2020,,,,,,,
|
||||
,Kitchen,IOT;Home Assistant; Z-Wave,1,Smart Rocker Light Dimmer,"UltraPro Z-Wave Smart Rocker Light Dimmer with QuickFit and SimpleWire, 3-Way Ready, Compatible with Alexa, Google Assistant, ZWave Hub Required, Repeater/Range Extender, White Paddle Only, 39351",,,39351,Honeywell,,Amazon,65.98,09/30/0202,,,,,,,`
|
||||
|
||||
func loadcsv() [][]string {
|
||||
reader := csv.NewReader(bytes.NewBuffer([]byte(CSV_DATA)))
|
||||
|
@ -30,7 +29,7 @@ func loadcsv() [][]string {
|
|||
|
||||
func Test_csvRow_getLabels(t *testing.T) {
|
||||
type fields struct {
|
||||
Labels string
|
||||
LabelStr string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -40,28 +39,28 @@ func Test_csvRow_getLabels(t *testing.T) {
|
|||
{
|
||||
name: "basic test",
|
||||
fields: fields{
|
||||
Labels: "IOT;Home Assistant;Z-Wave",
|
||||
LabelStr: "IOT;Home Assistant;Z-Wave",
|
||||
},
|
||||
want: []string{"IOT", "Home Assistant", "Z-Wave"},
|
||||
},
|
||||
{
|
||||
name: "no labels",
|
||||
fields: fields{
|
||||
Labels: "",
|
||||
LabelStr: "",
|
||||
},
|
||||
want: []string{},
|
||||
},
|
||||
{
|
||||
name: "single label",
|
||||
fields: fields{
|
||||
Labels: "IOT",
|
||||
LabelStr: "IOT",
|
||||
},
|
||||
want: []string{"IOT"},
|
||||
},
|
||||
{
|
||||
name: "trailing semicolon",
|
||||
fields: fields{
|
||||
Labels: "IOT;",
|
||||
LabelStr: "IOT;",
|
||||
},
|
||||
want: []string{"IOT"},
|
||||
},
|
||||
|
@ -69,7 +68,7 @@ func Test_csvRow_getLabels(t *testing.T) {
|
|||
{
|
||||
name: "whitespace",
|
||||
fields: fields{
|
||||
Labels: " IOT; Home Assistant; Z-Wave ",
|
||||
LabelStr: " IOT; Home Assistant; Z-Wave ",
|
||||
},
|
||||
want: []string{"IOT", "Home Assistant", "Z-Wave"},
|
||||
},
|
||||
|
@ -77,7 +76,7 @@ func Test_csvRow_getLabels(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := csvRow{
|
||||
Labels: tt.fields.Labels,
|
||||
LabelStr: tt.fields.LabelStr,
|
||||
}
|
||||
if got := c.getLabels(); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("csvRow.getLabels() = %v, want %v", got, tt.want)
|
||||
|
|
|
@ -73,21 +73,21 @@ func TestItemService_CsvImport(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, csvRow := range dataCsv {
|
||||
if csvRow.Name == item.Name {
|
||||
assert.Equal(t, csvRow.Description, item.Description)
|
||||
assert.Equal(t, csvRow.SerialNumber, item.SerialNumber)
|
||||
assert.Equal(t, csvRow.Manufacturer, item.Manufacturer)
|
||||
assert.Equal(t, csvRow.Notes, item.Notes)
|
||||
if csvRow.Item.Name == item.Name {
|
||||
assert.Equal(t, csvRow.Item.Description, item.Description)
|
||||
assert.Equal(t, csvRow.Item.SerialNumber, item.SerialNumber)
|
||||
assert.Equal(t, csvRow.Item.Manufacturer, item.Manufacturer)
|
||||
assert.Equal(t, csvRow.Item.Notes, item.Notes)
|
||||
|
||||
// Purchase Fields
|
||||
assert.Equal(t, csvRow.parsedPurchasedAt(), item.PurchaseTime)
|
||||
assert.Equal(t, csvRow.PurchaseFrom, item.PurchaseFrom)
|
||||
assert.Equal(t, csvRow.parsedPurchasedPrice(), item.PurchasePrice)
|
||||
assert.Equal(t, csvRow.Item.PurchaseTime, item.PurchaseTime)
|
||||
assert.Equal(t, csvRow.Item.PurchaseFrom, item.PurchaseFrom)
|
||||
assert.Equal(t, csvRow.Item.PurchasePrice, item.PurchasePrice)
|
||||
|
||||
// Sold Fields
|
||||
assert.Equal(t, csvRow.parsedSoldAt(), item.SoldTime)
|
||||
assert.Equal(t, csvRow.SoldTo, item.SoldTo)
|
||||
assert.Equal(t, csvRow.parsedSoldPrice(), item.SoldPrice)
|
||||
assert.Equal(t, csvRow.Item.SoldTime, item.SoldTime)
|
||||
assert.Equal(t, csvRow.Item.SoldTo, item.SoldTo)
|
||||
assert.Equal(t, csvRow.Item.SoldPrice, item.SoldPrice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
)
|
||||
|
||||
type ItemCreate struct {
|
||||
ImportRef string `json:"-"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
|
||||
|
@ -53,6 +54,7 @@ type ItemUpdate struct {
|
|||
}
|
||||
|
||||
type ItemSummary struct {
|
||||
ImportRef string `json:"-"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue