123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572 |
- package budget
- import (
- "encoding/json"
- "errors"
- "strings"
- "zhiyuan/models"
- "zhiyuan/models/budget"
- "zhiyuan/models/final"
- "zhiyuan/pkg/db"
- "zhiyuan/pkg/logger"
- "github.com/Knetic/govaluate"
- "github.com/gin-gonic/gin"
- )
- var evaluableExpressionCache map[string]*govaluate.EvaluableExpression
- type Call struct {
- Expression string
- //Instance Instance
- Instance *InstanceData
- }
- type Context struct {
- Order *Order
- //Current Instance
- Current *InstanceData
- Calls []Call
- Modify bool
- C *gin.Context
- MatTypeCache map[int64]final.FinalMatType
- MatTypePidNameCache map[int64]map[string]final.FinalMatType
- MatCache map[int64]final.FinalMat
- CustomerCache *budget.Customer
- AdminCache *models.Admin
- GlobalProp map[string]interface{}
- LoadInstanceMap map[*InstanceData]bool
- ItemTypeCache map[int64]budget.ItemType
- ItemTypePidNameCache map[int64]map[string]budget.ItemType
- SupplierCache map[int64]final.FinalSupplier
- SupplierNameCache map[string]final.FinalSupplier
- CurrentPropKey uint64
- }
- func NewContext(order *Order, c *gin.Context) *Context {
- if evaluableExpressionCache == nil {
- evaluableExpressionCache = make(map[string]*govaluate.EvaluableExpression)
- }
- context := new(Context)
- context.Order = order
- context.Calls = make([]Call, 0)
- context.C = c
- context.GlobalProp = make(map[string]interface{})
- context.Current = context.Order.Form
- context.LoadInstanceMap = make(map[*InstanceData]bool)
- return context
- }
- func filterValue(value interface{}) interface{} {
- switch val := value.(type) {
- case float32:
- return float64(val)
- case int:
- return float64(val)
- case uint:
- return float64(val)
- case int8:
- return float64(val)
- case uint8:
- return float64(val)
- case int16:
- return float64(val)
- case uint16:
- return float64(val)
- case int32:
- return float64(val)
- case uint32:
- return float64(val)
- case int64:
- return float64(val)
- case uint64:
- return float64(val)
- case json.Number:
- if ret, err := val.Float64(); err == nil {
- return ret
- }
- }
- return value
- }
- func (context *Context) ModifyAfter(key uint64) {
- context.Modify = true
- for key := range context.Order.Prop {
- context.Order.Prop[key].UseKeys = make([]uint64, 0)
- }
- /*if prop, ok := context.Order.Prop[key]; ok {
- if useKeys := context.Order.PropUseCahce[prop.Key]; ok {
- for _, k := range useKeys {
- if useProp, ok := context.Order.Prop[k]; ok {
- for i, uk := range useProp.UseKeys {
- if uk == prop.Key {
- useProp.UseKeys = append(useProp.UseKeys[:i], useProp.UseKeys[i+1:]...)
- break
- }
- }
- }
- }
- context.Order.PropUseCahce[prop.Key] = make([]uint64, 0)
- }
- tmpKeys := append([]uint64{}, prop.UseKeys...)
- for _, k := range tmpKeys {
- context.ModifyAfter(k)
- }
- prop.UseKeys = make([]uint64, 0)
- }*/
- context.LoadInstanceMap = make(map[*InstanceData]bool)
- }
- func (context *Context) Customer() *budget.Customer {
- if context.CustomerCache == nil {
- db.GetModel(map[string]interface{}{"id": context.Order.CustomerId}, &context.CustomerCache)
- }
- return context.CustomerCache
- }
- func (context *Context) Admin() *models.Admin {
- if context.AdminCache == nil {
- db.GetModel(map[string]interface{}{"id": context.Order.AdminId}, &context.AdminCache)
- }
- return context.AdminCache
- }
- func (context *Context) ItemTypeInit() {
- if context.ItemTypeCache == nil {
- context.ItemTypeCache = make(map[int64]budget.ItemType)
- context.ItemTypePidNameCache = make(map[int64]map[string]budget.ItemType)
- types := make([]budget.ItemType, 0)
- db.GetModel(map[string]interface{}{
- "deleted_at": 0,
- }, &types)
- for _, typ := range types {
- if _, ok := context.ItemTypePidNameCache[typ.Pid]; !ok {
- context.ItemTypePidNameCache[typ.Pid] = make(map[string]budget.ItemType)
- }
- context.ItemTypeCache[typ.ID] = typ
- context.ItemTypePidNameCache[typ.Pid][typ.Name] = typ
- }
- }
- }
- func (context *Context) MatTypeInit() {
- if context.MatTypeCache == nil {
- context.MatTypeCache = make(map[int64]final.FinalMatType)
- context.MatTypePidNameCache = make(map[int64]map[string]final.FinalMatType)
- types := make([]final.FinalMatType, 0)
- db.GetModel(map[string]interface{}{
- "deleted_at": 0,
- }, &types)
- for _, typ := range types {
- if _, ok := context.MatTypePidNameCache[typ.Pid]; !ok {
- context.MatTypePidNameCache[typ.Pid] = make(map[string]final.FinalMatType)
- }
- context.MatTypeCache[typ.ID] = typ
- context.MatTypePidNameCache[typ.Pid][typ.Name] = typ
- }
- }
- }
- func (context *Context) SupplierInit() {
- if context.SupplierCache == nil {
- context.SupplierCache = make(map[int64]final.FinalSupplier)
- context.SupplierNameCache = make(map[string]final.FinalSupplier)
- suppliers := make([]final.FinalSupplier, 0)
- db.GetModel(map[string]interface{}{
- "deleted_at": 0,
- }, &suppliers)
- for _, supplier := range suppliers {
- context.SupplierCache[supplier.ID] = supplier
- context.SupplierNameCache[supplier.Name] = supplier
- }
- }
- }
- func (context *Context) GetMat(id int64) *final.FinalMat {
- if context.MatCache == nil {
- context.MatCache = make(map[int64]final.FinalMat)
- }
- if _, ok := context.MatCache[id]; !ok {
- var mat final.FinalMat
- db.GetModel(map[string]interface{}{
- "id": id,
- "deleted_at": 0,
- }, &mat)
- if mat.ID != 0 {
- context.MatCache[id] = mat
- }
- }
- if mat, ok := context.MatCache[id]; ok {
- return &mat
- }
- return nil
- }
- /*func (context *Context) GetProp(name string) (*PropForm, error) {
- last := context.Current
- defer func() {
- context.Current = last
- }()
- for instance := context.Current; instance != nil; instance = instance.GetParent() {
- var expression string
- ok := false
- switch val := instance.(type) {
- case *QuoteForm:
- expression, ok = context.Order.Quote.Prop[name]
- case *TableInstance:
- expression, ok = context.Order.Table[val.GetID()].Prop[name]
- case *ModuleInstance:
- expression, ok = context.Order.Module[val.GetID()].Prop[name]
- case *GroupInstance:
- expression, ok = context.Order.Group[val.GetID()].Prop[name]
- case *RowInstance:
- expression, ok = context.Order.Row[val.GetID()].Prop[name]
- if !ok {
- err := context.LoadInstance(instance)
- if err != nil {
- return nil, err
- }
- if val.Item != nil {
- expression, ok = context.Order.Item[val.Item.ID].Prop[name]
- if !ok {
- expression, ok = context.Order.Item[val.Item.ID].ParentProp[name]
- }
- if ok {
- instance = val.Item
- }
- }
- }
- case *ItemInstance:
- expression, ok = context.Order.Item[val.GetID()].Prop[name]
- if !ok {
- expression, ok = context.Order.Item[val.GetID()].ParentProp[name]
- }
- }
- if ok {
- context.Current = instance
- prop := instance.GetPropResult(name)
- result, err := context.GetForm(expression, prop)
- if err != nil {
- return nil, err
- }
- prop = result
- instance.SetPropResult(name, prop)
- return prop, nil
- }
- }
- //return nil, errors.New("undeclared name: " + name)
- return nil, nil
- }*/
- func (context *Context) GetProp(name string) (*PropForm, error) {
- last := context.Current
- defer func() {
- context.Current = last
- }()
- for instance := context.Current; instance != nil; instance = instance.Parent {
- var expression string
- ok := false
- if model, ok1 := context.Order.Models[instance.Type]; ok1 {
- if data, ok2 := model[instance.GetID()]; ok2 {
- expression, ok = data.GetProp(name)
- }
- }
- if !ok && instance.Type == Row {
- err := context.LoadInstance(instance)
- if err != nil {
- return nil, err
- }
- if instance.Item != nil {
- if model, ok1 := context.Order.Models[instance.Item.Type]; ok1 {
- if data, ok2 := model[instance.Item.GetID()]; ok2 {
- expression, ok = data.GetProp(name)
- }
- }
- if ok {
- instance = instance.Item
- }
- }
- }
- if ok {
- context.Current = instance
- prop := instance.GetPropResult(name)
- result, err := context.GetForm(expression, prop)
- if err != nil {
- return nil, err
- }
- prop = result
- instance.SetPropResult(name, prop)
- return prop, nil
- }
- /*switch instance.Type {
- case Quote:
- expression, ok = context.Order.Quote.Prop[name]
- case Table:
- expression, ok = context.Order.Table[instance.GetID()].Prop[name]
- case Module:
- expression, ok = context.Order.Module[instance.GetID()].Prop[name]
- case Group:
- expression, ok = context.Order.Group[instance.GetID()].Prop[name]
- case Row:
- expression, ok = context.Order.Row[instance.GetID()].Prop[name]
- if !ok {
- err := context.LoadInstance(instance)
- if err != nil {
- return nil, err
- }
- if instance.Item != nil {
- expression, ok = context.Order.Item[instance.Item.ID].Prop[name]
- if !ok {
- expression, ok = context.Order.Item[instance.Item.ID].ParentProp[name]
- }
- if ok {
- instance = instance.Item
- }
- }
- }
- case Item:
- expression, ok = context.Order.Item[instance.GetID()].Prop[name]
- if !ok {
- expression, ok = context.Order.Item[instance.GetID()].ParentProp[name]
- }
- }
- if ok {
- context.Current = instance
- prop := instance.GetPropResult(name)
- result, err := context.GetForm(expression, prop)
- if err != nil {
- return nil, err
- }
- prop = result
- instance.SetPropResult(name, prop)
- return prop, nil
- }*/
- }
- //return nil, errors.New("undeclared name: " + name)
- return nil, nil
- }
- func (context *Context) Get(name string) (interface{}, error) {
- if value, ok := context.GlobalProp[name]; ok {
- return filterValue(value), nil
- }
- prop, err := context.GetProp(name)
- if prop == nil {
- return nil, err
- }
- return filterValue(prop.Result), err
- }
- func (context *Context) Error(err error) {
- //logger.Sugar.Infof("context.Current: %v", context.Current)
- logger.Sugar.Infof("context.Current.Type(): %v", context.Current.Type)
- //logger.Sugar.Infof("context.Current.GetObject(): %v", context.Current.GetObject())
- logger.Sugar.Infof("context.Calls: %v", context.Calls)
- logger.Sugar.Infof("err: %v", err)
- }
- func (context *Context) EvaluableExpression(expression string) (interface{}, error) {
- for _, call := range context.Calls {
- if call.Instance == context.Current && call.Expression == expression {
- return nil, errors.New("circular reference: " + expression)
- }
- }
- context.Calls = append(context.Calls, Call{expression, context.Current})
- defer func() { context.Calls = context.Calls[:len(context.Calls)-1] }()
- //logger.Sugar.Infof("expression: %v", expression)
- expr, ok := evaluableExpressionCache[expression]
- if !ok {
- s, err := govaluate.NewEvaluableExpressionWithFunctions(expression, context.Functions())
- if err != nil {
- context.Error(err)
- return nil, err
- }
- expr = s
- }
- result, err := expr.Eval(context)
- if err != nil {
- context.Error(err)
- return nil, err
- }
- //logger.Sugar.Infof("expressionend: %v", expression)
- return result, nil
- }
- func (context *Context) Exec(expression string) (interface{}, error) {
- return context.EvaluableExpression(expression)
- }
- func (context *Context) ParseValue(value string) (interface{}, error) {
- if len(value) == 0 {
- return "", nil
- }
- switch value[0] {
- case '.':
- n, _ := db.ToFloat64(value[1:])
- return n, nil
- case '\'':
- return db.ToString(value[1:]), nil
- case '=':
- return context.Exec(value[1:])
- case '@':
- var count string
- var val string
- n := strings.Index(value[1:], "@")
- if n == -1 {
- count = value[1:]
- } else {
- count = value[1 : n+1]
- val = value[n+2:]
- }
- countResult, err := context.ParseValue(count)
- if err != nil {
- return nil, err
- }
- counts, _ := db.ToInt64(countResult)
- results := make([]interface{}, counts)
- for i := range results {
- globalProp := map[string]interface{}{
- "key": float64(i),
- }
- result, err := context.ParseValueinGlobalProp(val, globalProp)
- if err != nil {
- return nil, err
- }
- results[i] = result
- }
- return results, nil
- default:
- return db.ToString(value), nil
- }
- }
- // func (context *Context) ParseValueinInstance(value string, instance Instance) (interface{}, error) {
- func (context *Context) ParseValueinInstance(value string, instance *InstanceData) (interface{}, error) {
- last := context.Current
- context.Current = instance
- defer func() {
- context.Current = last
- }()
- return context.ParseValue(value)
- }
- func (context *Context) ParseValueinGlobalProp(value string, globalProp map[string]interface{}) (interface{}, error) {
- last := context.GlobalProp
- context.GlobalProp = make(map[string]interface{})
- for k, v := range last {
- context.GlobalProp[k] = v
- }
- for k, v := range globalProp {
- context.GlobalProp[k] = v
- }
- defer func() {
- context.GlobalProp = last
- }()
- return context.ParseValue(value)
- }
- // func (context *Context) ParseValueInInstanceAndGlobalProp(value string, instance Instance, globalProp map[string]interface{}) (interface{}, error) {
- func (context *Context) ParseValueInInstanceAndGlobalProp(value string, instance *InstanceData, globalProp map[string]interface{}) (interface{}, error) {
- lastCurrent := context.Current
- lastGlobalProp := context.GlobalProp
- context.Current = instance
- context.GlobalProp = make(map[string]interface{})
- for k, v := range lastGlobalProp {
- context.GlobalProp[k] = v
- }
- for k, v := range globalProp {
- context.GlobalProp[k] = v
- }
- defer func() {
- context.Current = lastCurrent
- context.GlobalProp = lastGlobalProp
- }()
- return context.ParseValue(value)
- }
- func (context *Context) ParseForm(value string) (*PropForm, error) {
- prop := new(PropForm)
- prop.Instance = context.Current
- if len(value) != 0 {
- switch value[0] {
- case '!':
- prop.Cycle = Immediate
- value = value[1:]
- case '%':
- prop.Cycle = Save
- value = value[1:]
- }
- }
- results, err := context.ParseValue(value)
- if err != nil {
- return prop, err
- }
- if control, ok := results.(Control); ok {
- prop.Control = &control
- prop.Result = control.Value
- } else if control, ok := results.(*Control); ok {
- prop.Control = control
- prop.Result = control.Value
- } else {
- prop.Result = results
- }
- return prop, nil
- }
- func (context *Context) GetForm(value string, prop *PropForm) (*PropForm, error) {
- lastPropKey := context.CurrentPropKey
- defer func() { context.CurrentPropKey = lastPropKey }()
- if prop == nil || prop.Result == nil || len(prop.UseKeys) == 0 && (prop.Cycle == Immediate || prop.Cycle == Modify && context.Modify) {
- if prop != nil {
- context.CurrentPropKey = prop.Key
- } else {
- context.CurrentPropKey = context.Order.NewPropKey()
- }
- props, err := context.ParseForm(value)
- if err != nil {
- return nil, err
- }
- props.Key = context.CurrentPropKey
- if prop != nil {
- props.UseKeys = prop.UseKeys
- }
- if prop != nil && props.Control != nil && props.Control.Last {
- props.Result = prop.Result
- }
- prop = props
- context.Order.Prop[prop.Key] = prop
- }
- prop.AddUseKey(lastPropKey)
- context.Order.SetPropUse(lastPropKey, prop.Key)
- return prop, nil
- }
- /*func (context *Context) CreateObject(id int64, name string, parent Instance) (BaseObject, error) {
- var object BaseObject
- object.ID = id
- object.Init(parent, context.Order)
- prop, err := context.GetForm(name, nil)
- if err != nil {
- return object, err
- }
- object.NameResult = prop
- return object, nil
- }
- func (context *Context) CreateInstance(object Object, name interface{}, index int) (BaseInstance, error) {
- var instance BaseInstance
- instance.Init(object, index, context.Order)
- if nameMap, ok := name.(map[string]interface{}); ok {
- instance.Name = db.ToString(nameMap["name"])
- instance.Show = db.ToString(nameMap["show"])
- instance.ItemId, _ = db.ToInt64(nameMap["item"])
- instance.Key = db.ToString(nameMap["key"])
- } else {
- instance.Name = db.ToString(name)
- instance.Show = ""
- }
- return instance, nil
- }
- func (context *Context) CreateInstances(object Object, name interface{}) ([]BaseInstance, error) {
- instances := make([]BaseInstance, 0)
- if names, ok := name.([]interface{}); ok {
- for i, name := range names {
- instance, err := context.CreateInstance(object, name, i)
- if err != nil {
- return instances, err
- }
- instances = append(instances, instance)
- }
- } else {
- instance, err := context.CreateInstance(object, name, 0)
- if err != nil {
- return instances, err
- }
- instances = append(instances, instance)
- }
- return instances, nil
- }
- func (context *Context) CreateObject(id int64, name string, parent *InstanceData) (*ObjectData, error) {
- object := new(ObjectData)
- object.ID = id
- typ := parent.Type + 1
- if parent.Type == Table {
- typ = Module
- }
- object.Init(parent, typ, context.Order)
- prop, err := context.GetForm(name, nil)
- if err != nil {
- return object, err
- }
- object.NameResult = prop
- return object, nil
- }
- func (context *Context) CreateInstance(object *ObjectData, name interface{}, index int) (*InstanceData, error) {
- instance := new(InstanceData)
- instance.Init(object, object.Type, index, context.Order)
- if nameMap, ok := name.(map[string]interface{}); ok {
- instance.Name = db.ToString(nameMap["name"])
- instance.Show = db.ToString(nameMap["show"])
- instance.ItemId, _ = db.ToInt64(nameMap["item"])
- instance.Key = db.ToString(nameMap["key"])
- } else {
- instance.Name = db.ToString(name)
- instance.Show = ""
- }
- return instance, nil
- }
- func (context *Context) CreateInstances(object *ObjectData, name interface{}) ([]InstanceData, error) {
- instances := make([]InstanceData, 0)
- if names, ok := name.([]interface{}); ok {
- for i, name := range names {
- instance, err := context.CreateInstance(object, name, i)
- if err != nil {
- return instances, err
- }
- instances = append(instances, *instance)
- }
- } else {
- instance, err := context.CreateInstance(object, name, 0)
- if err != nil {
- return instances, err
- }
- instances = append(instances, *instance)
- }
- return instances, nil
- }
- func (context *Context) LoadInstance(instance Instance) error {
- last := context.Current
- context.Current = instance
- defer func() {
- context.Current = last
- }()
- if load, ok := context.LoadInstanceMap[instance]; ok && load {
- switch val := instance.(type) {
- case *QuoteForm:
- for _, qdata := range val.Tables {
- if qdata.NameResult != nil {
- qdata.NameResult.AddUseKey(context.CurrentPropKey)
- }
- }
- case *TableInstance:
- for _, qdata := range val.Headers {
- if qdata.NameResult != nil {
- qdata.NameResult.AddUseKey(context.CurrentPropKey)
- }
- }
- for _, qdata := range val.Modules {
- if qdata.NameResult != nil {
- qdata.NameResult.AddUseKey(context.CurrentPropKey)
- }
- }
- case *HeaderInstance:
- val.Result.AddUseKey(context.CurrentPropKey)
- case *ModuleInstance:
- for _, qdata := range val.Groups {
- if qdata.NameResult != nil {
- qdata.NameResult.AddUseKey(context.CurrentPropKey)
- }
- }
- case *GroupInstance:
- for _, qdata := range val.Rows {
- if qdata.NameResult != nil {
- qdata.NameResult.AddUseKey(context.CurrentPropKey)
- }
- }
- }
- return nil
- }
- switch val := instance.(type) {
- case *QuoteForm:
- tables := make([]TableObject, 0)
- for _, qtable := range context.Order.Quote.Tables {
- var object *TableObject
- for i, table := range val.Tables {
- if table.ID == qtable.ID {
- object = &val.Tables[i]
- }
- }
- if object == nil {
- o, err := context.CreateObject(qtable.ID, qtable.Name, instance)
- if err != nil {
- return err
- }
- object = new(TableObject)
- object.BaseObject = o
- object.Init(instance, context.Order)
- }
- nameResult, err := context.GetForm(context.Order.Table[object.ID].Name, object.NameResult)
- if err != nil {
- return err
- }
- object.NameResult = nameResult
- instances, err := context.CreateInstances(object, object.NameResult.Result)
- if err != nil {
- return err
- }
- objectInstances := make(map[int]TableInstance)
- objectInstanceMap := make(map[string]TableInstance)
- for _, instance := range object.Instances {
- objectInstances[instance.Index] = instance
- if instance.Key != "" {
- objectInstanceMap[instance.Key] = instance
- }
- }
- //object.Instances = make([]TableInstance, 0)
- for _, instance := range instances {
- var objectInstance *TableInstance
- if instance.Key == "" {
- if i, ok := objectInstances[instance.Index]; ok {
- objectInstance = &i
- }
- } else {
- if i, ok := objectInstanceMap[instance.Key]; ok {
- objectInstance = &i
- }
- }
- if objectInstance == nil {
- objectInstance = new(TableInstance)
- objectInstance.BaseInstance = instance
- } else {
- delete(objectInstances, objectInstance.Index)
- delete(objectInstanceMap, objectInstance.Key)
- objectInstance.Name = instance.Name
- objectInstance.Show = instance.Show
- objectInstance.ItemId = instance.ItemId
- objectInstance.Key = instance.Key
- }
- objectInstance.Init(object, instance.Index, context.Order)
- if len(object.Instances) > instance.Index {
- object.Instances[instance.Index] = *objectInstance
- } else {
- object.Instances = append(object.Instances, *objectInstance)
- }
- }
- if len(object.Instances) > len(instances) {
- object.Instances = object.Instances[:len(instances)]
- }
- tables = append(tables, *object)
- }
- val.Tables = tables
- case *TableInstance:
- headers := make([]HeaderObject, 0)
- for _, qdata := range context.Order.Table[val.GetID()].Headers {
- var object *HeaderObject
- for i, o := range val.Headers {
- if o.ID == qdata.ID {
- object = &val.Headers[i]
- }
- }
- if object == nil {
- o, err := context.CreateObject(qdata.ID, qdata.Name, instance)
- if err != nil {
- return err
- }
- object = new(HeaderObject)
- object.BaseObject = o
- object.Init(instance, context.Order)
- }
- nameResult, err := context.GetForm(context.Order.Header[object.ID].Name, object.NameResult)
- if err != nil {
- return err
- }
- object.NameResult = nameResult
- instances, err := context.CreateInstances(object, object.NameResult.Result)
- if err != nil {
- return err
- }
- objectInstances := make(map[int]HeaderInstance)
- objectInstanceMap := make(map[string]HeaderInstance)
- for _, instance := range object.Instances {
- objectInstances[instance.Index] = instance
- if instance.Key != "" {
- objectInstanceMap[instance.Key] = instance
- }
- }
- //object.Instances = make([]HeaderInstance, 0)
- for _, instance := range instances {
- var objectInstance *HeaderInstance
- if instance.Key == "" {
- if i, ok := objectInstances[instance.Index]; ok {
- objectInstance = &i
- }
- } else {
- if i, ok := objectInstanceMap[instance.Key]; ok {
- objectInstance = &i
- }
- }
- if objectInstance == nil {
- objectInstance = new(HeaderInstance)
- objectInstance.BaseInstance = instance
- } else {
- delete(objectInstances, objectInstance.Index)
- delete(objectInstanceMap, objectInstance.Key)
- objectInstance.Name = instance.Name
- objectInstance.Show = instance.Show
- objectInstance.ItemId = instance.ItemId
- objectInstance.Key = instance.Key
- }
- objectInstance.Init(object, instance.Index, context.Order)
- if len(object.Instances) > instance.Index {
- object.Instances[instance.Index] = *objectInstance
- } else {
- object.Instances = append(object.Instances, *objectInstance)
- }
- }
- if len(object.Instances) > len(instances) {
- object.Instances = object.Instances[:len(instances)]
- }
- headers = append(headers, *object)
- }
- val.Headers = headers
- modules := make([]ModuleObject, 0)
- for _, qdata := range context.Order.Table[val.GetID()].Modules {
- var object *ModuleObject
- for i, o := range val.Modules {
- if o.ID == qdata.ID {
- object = &val.Modules[i]
- }
- }
- if object == nil {
- o, err := context.CreateObject(qdata.ID, qdata.Name, instance)
- if err != nil {
- return err
- }
- object = new(ModuleObject)
- object.BaseObject = o
- object.Init(instance, context.Order)
- }
- nameResult, err := context.GetForm(context.Order.Module[object.ID].Name, object.NameResult)
- if err != nil {
- return err
- }
- object.NameResult = nameResult
- instances, err := context.CreateInstances(object, object.NameResult.Result)
- if err != nil {
- return err
- }
- objectInstances := make(map[int]ModuleInstance)
- objectInstanceMap := make(map[string]ModuleInstance)
- for _, instance := range object.Instances {
- objectInstances[instance.Index] = instance
- if instance.Key != "" {
- objectInstanceMap[instance.Key] = instance
- }
- }
- //object.Instances = make([]ModuleInstance, 0)
- for _, instance := range instances {
- var objectInstance *ModuleInstance
- if instance.Key == "" {
- if i, ok := objectInstances[instance.Index]; ok {
- objectInstance = &i
- }
- } else {
- if i, ok := objectInstanceMap[instance.Key]; ok {
- objectInstance = &i
- }
- }
- if objectInstance == nil {
- objectInstance = new(ModuleInstance)
- objectInstance.BaseInstance = instance
- } else {
- delete(objectInstances, objectInstance.Index)
- delete(objectInstanceMap, objectInstance.Key)
- objectInstance.Name = instance.Name
- objectInstance.Show = instance.Show
- objectInstance.ItemId = instance.ItemId
- objectInstance.Key = instance.Key
- }
- objectInstance.Init(object, instance.Index, context.Order)
- if len(object.Instances) > instance.Index {
- object.Instances[instance.Index] = *objectInstance
- } else {
- object.Instances = append(object.Instances, *objectInstance)
- }
- }
- if len(object.Instances) > len(instances) {
- object.Instances = object.Instances[:len(instances)]
- }
- modules = append(modules, *object)
- }
- val.Modules = modules
- case *HeaderInstance:
- prop, err := context.GetForm(context.Order.Header[val.GetID()].Value, val.Result)
- if err != nil {
- return err
- }
- val.Result = prop
- case *ModuleInstance:
- groups := make([]GroupObject, 0)
- for _, qdata := range context.Order.Module[val.GetID()].Groups {
- var object *GroupObject
- for i, o := range val.Groups {
- if o.ID == qdata.ID {
- object = &val.Groups[i]
- }
- }
- if object == nil {
- o, err := context.CreateObject(qdata.ID, qdata.Name, instance)
- if err != nil {
- return err
- }
- object = new(GroupObject)
- object.BaseObject = o
- object.Init(instance, context.Order)
- }
- nameResult, err := context.GetForm(context.Order.Group[object.ID].Name, object.NameResult)
- if err != nil {
- return err
- }
- object.NameResult = nameResult
- instances, err := context.CreateInstances(object, object.NameResult.Result)
- if err != nil {
- return err
- }
- objectInstances := make(map[int]GroupInstance)
- objectInstanceMap := make(map[string]GroupInstance)
- for _, instance := range object.Instances {
- objectInstances[instance.Index] = instance
- if instance.Key != "" {
- objectInstanceMap[instance.Key] = instance
- }
- }
- //object.Instances = make([]GroupInstance, 0)
- for _, instance := range instances {
- var objectInstance *GroupInstance
- if instance.Key == "" {
- if i, ok := objectInstances[instance.Index]; ok {
- objectInstance = &i
- }
- } else {
- if i, ok := objectInstanceMap[instance.Key]; ok {
- objectInstance = &i
- }
- }
- if objectInstance == nil {
- objectInstance = new(GroupInstance)
- objectInstance.BaseInstance = instance
- } else {
- delete(objectInstances, objectInstance.Index)
- delete(objectInstanceMap, objectInstance.Key)
- objectInstance.Name = instance.Name
- objectInstance.Show = instance.Show
- objectInstance.ItemId = instance.ItemId
- objectInstance.Key = instance.Key
- }
- objectInstance.Init(object, instance.Index, context.Order)
- if len(object.Instances) > instance.Index {
- object.Instances[instance.Index] = *objectInstance
- } else {
- object.Instances = append(object.Instances, *objectInstance)
- }
- }
- if len(object.Instances) > len(instances) {
- object.Instances = object.Instances[:len(instances)]
- }
- groups = append(groups, *object)
- }
- val.Groups = groups
- case *GroupInstance:
- rows := make([]RowObject, 0)
- for _, qdata := range context.Order.Group[val.GetID()].Rows {
- var object *RowObject
- for i, o := range val.Rows {
- if o.ID == qdata.ID {
- object = &val.Rows[i]
- }
- }
- if object == nil {
- o, err := context.CreateObject(qdata.ID, qdata.Name, instance)
- if err != nil {
- return err
- }
- object = new(RowObject)
- object.BaseObject = o
- object.Init(instance, context.Order)
- }
- nameResult, err := context.GetForm(context.Order.Row[object.ID].Name, object.NameResult)
- if err != nil {
- return err
- }
- object.NameResult = nameResult
- instances, err := context.CreateInstances(object, object.NameResult.Result)
- if err != nil {
- return err
- }
- objectInstances := make(map[int]RowInstance)
- objectInstanceMap := make(map[string]RowInstance)
- for _, instance := range object.Instances {
- objectInstances[instance.Index] = instance
- if instance.Key != "" {
- objectInstanceMap[instance.Key] = instance
- }
- }
- //object.Instances = make([]RowInstance, 0)
- for _, instance := range instances {
- var objectInstance *RowInstance
- if instance.Key == "" {
- if i, ok := objectInstances[instance.Index]; ok {
- objectInstance = &i
- }
- } else {
- if i, ok := objectInstanceMap[instance.Key]; ok {
- objectInstance = &i
- }
- }
- if objectInstance == nil {
- objectInstance = new(RowInstance)
- objectInstance.BaseInstance = instance
- } else {
- delete(objectInstances, objectInstance.Index)
- delete(objectInstanceMap, objectInstance.Key)
- objectInstance.Name = instance.Name
- objectInstance.Show = instance.Show
- objectInstance.ItemId = instance.ItemId
- objectInstance.Key = instance.Key
- }
- objectInstance.Init(object, instance.Index, context.Order)
- if len(object.Instances) > instance.Index {
- object.Instances[instance.Index] = *objectInstance
- } else {
- object.Instances = append(object.Instances, *objectInstance)
- }
- }
- if len(object.Instances) > len(instances) {
- object.Instances = object.Instances[:len(instances)]
- }
- rows = append(rows, *object)
- }
- val.Rows = rows
- case *RowInstance:
- if val.ItemId != 0 {
- if _, ok := context.Order.Item[val.ItemId]; !ok {
- items := budget.GetItemModels(map[string]interface{}{
- "id": val.ItemId,
- "deleted_at": 0,
- })
- if len(items) != 0 {
- context.Order.Item[val.ItemId] = items[0]
- }
- }
- }
- itemId := int64(0)
- if val.ItemId != 0 {
- if item, ok := context.Order.Item[val.ItemId]; ok {
- itemId = item.ID
- }
- } else if context.Order.Row[val.GetID()].Item != nil {
- itemId = context.Order.Row[val.GetID()].Item.ID
- }
- if itemId == 0 {
- val.Item = nil
- } else {
- if val.Item == nil || itemId != val.Item.ID {
- val.Item = new(ItemInstance)
- val.Item.ID = itemId
- val.Item.Init(val.Object, 0, context.Order)
- }
- val.Item.Row = val
- }
- }
- context.LoadInstanceMap[instance] = true
- return nil
- }*/
- func (context *Context) LoadInstance(instance *InstanceData) error {
- last := context.Current
- context.Current = instance
- defer func() {
- context.Current = last
- }()
- if load, ok := context.LoadInstanceMap[instance]; ok && load {
- if instance.Subs != nil {
- for _, sub := range instance.Subs {
- if sub.NameResult != nil {
- sub.NameResult.AddUseKey(context.CurrentPropKey)
- context.Order.SetPropUse(context.CurrentPropKey, sub.NameResult.Key)
- }
- }
- }
- if instance.Headers != nil {
- for _, header := range instance.Headers {
- if header.NameResult != nil {
- header.NameResult.AddUseKey(context.CurrentPropKey)
- context.Order.SetPropUse(context.CurrentPropKey, header.NameResult.Key)
- }
- }
- }
- if instance.Result != nil {
- instance.Result.AddUseKey(context.CurrentPropKey)
- context.Order.SetPropUse(context.CurrentPropKey, instance.Result.Key)
- }
- return nil
- }
- if model, ok := context.Order.Models[instance.Type]; ok {
- if data, ok := model[instance.GetID()]; ok {
- var err error
- qsubs := data.GetSubs()
- if qsubs != nil {
- if instance.Subs == nil {
- instance.Subs = make([]ObjectData, 0)
- }
- subType := instance.Type + 1
- if instance.Type == Table {
- subType = Module
- }
- instance.Subs, err = context.LoadSubs(instance, subType, &instance.Subs, qsubs)
- if err != nil {
- return err
- }
- }
- qheaders := data.GetHeaders()
- if qheaders != nil {
- if instance.Headers == nil {
- instance.Headers = make([]ObjectData, 0)
- }
- instance.Headers, err = context.LoadSubs(instance, Header, &instance.Headers, qheaders)
- if err != nil {
- return err
- }
- }
- itemId := int64(0)
- if instance.ItemId != 0 {
- item := context.LoadItem(instance.ItemId)
- if item != nil {
- itemId = item.GetID()
- }
- } else if data.GetItem() != nil {
- itemId = data.GetItem().GetID()
- }
- if itemId == 0 {
- instance.Item = nil
- } else {
- if instance.Item == nil || itemId != instance.Item.ID {
- instance.Item = new(InstanceData)
- instance.Item.ID = itemId
- instance.Item.Init(instance, instance.Object, Item, instance.Index, context.Order)
- }
- }
- if instance.Type == Header {
- prop, err := context.GetForm(data.GetValue(), instance.Result)
- if err != nil {
- return err
- }
- instance.Result = prop
- }
- }
- }
- context.LoadInstanceMap[instance] = true
- return nil
- }
- func (context *Context) LoadItem(itemId int64) budget.QuoteData {
- if _, ok := context.Order.Models[Item][itemId]; !ok {
- _, items := budget.GetItemModels(map[string]interface{}{
- "id": itemId,
- "deleted_at": 0,
- })
- if len(items) != 0 {
- context.Order.Models[Item][itemId] = items[0]
- }
- }
- if item, ok := context.Order.Models[Item][itemId]; ok {
- return item
- }
- return nil
- }
- func (context *Context) LoadSubs(instance *InstanceData, typ int, oldSubs *[]ObjectData, quoteDatas *[]budget.QuoteData) ([]ObjectData, error) {
- subs := make([]ObjectData, 0)
- for _, qsub := range *quoteDatas {
- var object *ObjectData
- for i, sub := range *oldSubs {
- if sub.ID == qsub.GetID() {
- object = &(*oldSubs)[i]
- }
- }
- if object == nil {
- object = new(ObjectData)
- object.ID = qsub.GetID()
- object.Init(instance, typ, context.Order)
- }
- nameResult, err := context.GetForm(qsub.GetName(), object.NameResult)
- if err != nil {
- return nil, err
- }
- object.NameResult = nameResult
- var instanceNames []interface{}
- if names, ok := object.NameResult.Result.([]interface{}); ok {
- instanceNames = names
- } else {
- instanceNames = []interface{}{object.NameResult.Result}
- }
- objectInstanceMap := make(map[string]*InstanceData)
- for i, instance := range object.Instances {
- if instance.Key != "" {
- objectInstanceMap[instance.Key] = &object.Instances[i]
- }
- }
- subInstances := make([]InstanceData, 0)
- for i, instanceName := range instanceNames {
- var subInstance *InstanceData
- var name, show, key string
- var itemid int64
- if nameMap, ok := instanceName.(map[string]interface{}); ok {
- name = db.ToString(nameMap["name"])
- show = db.ToString(nameMap["show"])
- itemid, _ = db.ToInt64(nameMap["item"])
- key = db.ToString(nameMap["key"])
- } else {
- name = db.ToString(instanceName)
- }
- if key == "" {
- if len(object.Instances) > i {
- subInstance = &object.Instances[i]
- }
- } else {
- if i, ok := objectInstanceMap[key]; ok {
- subInstance = i
- }
- }
- if subInstance == nil {
- subInstance = new(InstanceData)
- } else {
- delete(objectInstanceMap, subInstance.Key)
- }
- subInstance.Name = name
- subInstance.Show = show
- subInstance.ItemId = itemid
- subInstance.Key = key
- subInstance.Init(instance, object, object.Type, i, context.Order)
- subInstances = append(subInstances, *subInstance)
- }
- object.Instances = subInstances
- subs = append(subs, *object)
- }
- return subs, nil
- }
- func (context *Context) LoadNameResult(instance *InstanceData) (*PropForm, error) {
- last := context.Current
- context.Current = instance
- defer func() {
- context.Current = last
- }()
- nameResult, err := context.GetForm(instance.Name, instance.NameResult)
- if err != nil {
- return nil, err
- }
- if nameResult != nil && instance.Object != nil && instance.Object.NameResult != nil {
- instance.Object.NameResult.AddUseKey(nameResult.Key)
- context.Order.SetPropUse(nameResult.Key, instance.Object.NameResult.Key)
- }
- instance.SetNameResult(nameResult)
- return nameResult, nil
- }
- func (context *Context) LoadShowResult(instance *InstanceData) (*PropForm, error) {
- last := context.Current
- context.Current = instance
- defer func() {
- context.Current = last
- }()
- showResult, err := context.GetForm(instance.Show, instance.ShowResult)
- if err != nil {
- return nil, err
- }
- if showResult != nil && instance.Object != nil && instance.Object.NameResult != nil {
- instance.Object.NameResult.AddUseKey(showResult.Key)
- context.Order.SetPropUse(showResult.Key, instance.Object.NameResult.Key)
- }
- instance.SetShowResult(showResult)
- return showResult, nil
- }
- func (context *Context) EvalRowHeaderResult(row *InstanceData, table *InstanceData) error {
- last := context.Current
- context.Current = row
- defer func() {
- context.Current = last
- }()
- for _, header := range table.Headers {
- row.HeaderResult[header.ID] = make([]*PropForm, 0)
- for _, hInstance := range header.Instances {
- if hInstance.Result == nil {
- row.HeaderResult[header.ID] = append(row.HeaderResult[header.ID], nil)
- continue
- }
- prop, err := context.GetProp(db.ToString(hInstance.Result.Result))
- if err != nil {
- return err
- }
- if prop != nil {
- prop.Header = true
- }
- row.HeaderResult[header.ID] = append(row.HeaderResult[header.ID], prop)
- }
- }
- return nil
- }
- func (context *Context) EvalResult() error {
- err := context.LoadInstance(context.Order.Form)
- if err != nil {
- return err
- }
- for i := range context.Order.Form.Subs {
- table := &context.Order.Form.Subs[i]
- for tableIndex := 0; tableIndex < len(table.Instances); tableIndex++ {
- tableInstance := &table.Instances[tableIndex]
- _, err := context.LoadNameResult(tableInstance)
- if err != nil {
- return err
- }
- _, err = context.LoadShowResult(tableInstance)
- if err != nil {
- return err
- }
- err = context.LoadInstance(tableInstance)
- if err != nil {
- return err
- }
- for i := range tableInstance.Headers {
- header := &tableInstance.Headers[i]
- for headerIndex := 0; headerIndex < len(header.Instances); headerIndex++ {
- _, err := context.LoadNameResult(&header.Instances[headerIndex])
- if err != nil {
- return err
- }
- _, err = context.LoadShowResult(&header.Instances[headerIndex])
- if err != nil {
- return err
- }
- err = context.LoadInstance(&header.Instances[headerIndex])
- if err != nil {
- return err
- }
- }
- }
- for i := range tableInstance.Subs {
- module := &tableInstance.Subs[i]
- for moduleIndex := 0; moduleIndex < len(module.Instances); moduleIndex++ {
- moduleInstance := &module.Instances[moduleIndex]
- _, err := context.LoadNameResult(moduleInstance)
- if err != nil {
- return err
- }
- _, err = context.LoadShowResult(moduleInstance)
- if err != nil {
- return err
- }
- err = context.LoadInstance(moduleInstance)
- if err != nil {
- return err
- }
- for i := range moduleInstance.Subs {
- group := &moduleInstance.Subs[i]
- for groupIndex := 0; groupIndex < len(group.Instances); groupIndex++ {
- groupInstance := &group.Instances[groupIndex]
- _, err := context.LoadNameResult(groupInstance)
- if err != nil {
- return err
- }
- _, err = context.LoadShowResult(groupInstance)
- if err != nil {
- return err
- }
- err = context.LoadInstance(groupInstance)
- if err != nil {
- return err
- }
- for i := range groupInstance.Subs {
- row := &groupInstance.Subs[i]
- for rowIndex := 0; rowIndex < len(row.Instances); rowIndex++ {
- rowInstance := &row.Instances[rowIndex]
- _, err := context.LoadNameResult(rowInstance)
- if err != nil {
- return err
- }
- _, err = context.LoadShowResult(rowInstance)
- if err != nil {
- return err
- }
- err = context.LoadInstance(rowInstance)
- if err != nil {
- return err
- }
- err = context.EvalRowHeaderResult(rowInstance, tableInstance)
- if err != nil {
- return err
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return nil
- }
- func (context *Context) Eval() error {
- //if context.Current == nil {
- /*err := context.LoadInstance(context.Order.Form)
- if err != nil {
- return err
- }*/
- return context.EvalResult()
- //}
- return nil
- }
- func (context *Context) Handle(key uint64, typ string, value interface{}) error {
- if prop, ok := context.Order.Prop[key]; ok {
- last := context.Current
- context.Current = prop.Instance
- defer func() {
- context.Current = last
- }()
- if prop.Control == nil {
- return errors.New("undeclared control: " + db.ToString(key))
- }
- err := prop.Control.Handle(typ, value, prop, context)
- if err != nil {
- context.Error(err)
- return err
- }
- } else {
- return errors.New("undeclared object: " + db.ToString(key))
- }
- return nil
- }
|