1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
package main
import (
"time"
)
type OfferPrice struct {
Currency string `json:"currency"`
MinQty uint32 `json:"min_qty"`
Price float32 `json:"price"`
}
type Offer struct {
Distributor string `json:"distributor_name"`
Sku string `json:"sku"`
Url string `json:"distributor_url"`
Comment string `json:"comment"`
Available uint32 `json:"avail"`
Prices []OfferPrice `json:"prices"`
}
type LineItem struct {
Manufacturer string `json:"manufacturer"`
Mpn string `json:"mpn"`
Description string `json:"description"`
FormFactor string `json:"form_factor"` // type:string
Specs string `json:"specs"` // comma seperated list
Comment string `json:"comment"`
Tag string `json:"tag"` // comma seperated list
Category string `json:"category"` // hierarchy as comma seperated list
Elements []string `json:"elements"`
Offers []Offer `json:"offers"`
AggregateInfo map[string]string `json:"miscinfo"`
}
func (li *LineItem) Id() string {
return li.Manufacturer + "::" + li.Mpn
}
// The main anchor of a BOM as a cohesive whole, with a name and permissions.
// Multiple BOMs are associated with a single BomMeta; the currently active one
// is the 'head'.
type BomMeta struct {
Name string `json:"name"`
Owner string `json:"owner_name"`
Description string `json:"description"`
HeadVersion string `json:"head_version"`
Homepage Url `json:"homepage_url"`
IsPublicView bool `json:"is_publicview",omitempty`
IsPublicEdit bool `json:"is_publicedit",omitempty`
}
// An actual list of parts/elements. Intended to be immutable once persisted.
type Bom struct {
Version string `json:"version"`
// TODO: unix timestamp?
Created time.Time `json:"created_ts"`
// "where did this BOM come from?"
Progeny string `json:"progeny",omitifempty`
LineItems []LineItem `json:"line_items"`
}
func NewBom(version string) *Bom {
return &Bom{Version: version, Created: time.Now()}
}
func (b *Bom) GetLineItem(mfg, mpn string) *LineItem {
for _, li := range b.LineItems {
if li.Manufacturer == mfg && li.Mpn == mpn {
return &li
}
}
return nil
}
func (b *Bom) AddLineItem(li *LineItem) error {
if eli := b.GetLineItem(li.Manufacturer, li.Mpn); eli != nil {
return Error("This BOM already had an identical LineItem")
}
b.LineItems = append(b.LineItems, *li)
return nil
}
func (b *Bom) Validate() error {
if !isShortName(b.Version) {
return Error("version not a ShortName: \"" + b.Version + "\"")
}
if b.Created.IsZero() {
return Error("created timestamp not defined")
}
return nil
}
func (bm *BomMeta) Validate() error {
if !isShortName(bm.Name) {
return Error("name not a ShortName: \"" + bm.Name + "\"")
}
if !isShortName(bm.Owner) {
return Error("owner name not a ShortName: \"" + bm.Owner + "\"")
}
return nil
}
// ---------- testing
func makeTestBom() (*BomMeta, *Bom) {
op1 := OfferPrice{Currency: "usd", Price: 1.0, MinQty: 1}
op2 := OfferPrice{Currency: "usd", Price: 0.8, MinQty: 100}
o := Offer{Sku: "A123", Distributor: "Acme", Prices: []OfferPrice{op1, op2}}
//o.AddOfferPrice(op1)
//o.AddOfferPrice(op2)
li := LineItem{Manufacturer: "WidgetCo",
Mpn: "WIDG0001",
Elements: []string{"W1", "W2"},
Offers: []Offer{o}}
li2 := LineItem{Manufacturer: "Texas Instruments",
Mpn: "NE555",
Elements: []string{"W1", "W2"},
Offers: []Offer{o}}
li3 := LineItem{Manufacturer: "STMicroelectronics",
Mpn: "L7905CV",
Elements: []string{"W1", "W2"},
Offers: []Offer{o}}
//li.AddOffer(o)
b := NewBom("test01")
b.AddLineItem(&li)
// tests that lines don't get duplicated
b.AddLineItem(&li)
b.AddLineItem(&li2)
b.AddLineItem(&li3)
bm := &BomMeta{Name: "Some Bom", Owner: "Some Owner", Description: "This is such a thing!", HeadVersion: b.Version, Homepage: "http://bommom.com", IsPublicView: true, IsPublicEdit: false}
return bm, b
}
|