package budget import ( "encoding/json" "errors" "math" "reflect" "strings" "time" "zhiyuan/models/budget" "zhiyuan/models/final" "zhiyuan/pkg/db" "zhiyuan/pkg/logger" "zhiyuan/services/admin" "github.com/Knetic/govaluate" ) func argParse(args []interface{}, parse func(interface{})) { for _, arg := range args { if array, ok := arg.([]interface{}); ok { argParse(array, parse) } else { parse(arg) } } } func (context *Context) Functions() map[string]govaluate.ExpressionFunction { return map[string]govaluate.ExpressionFunction{ "JsonEncode": context.funcJsonEncode, "JsonDecode": context.funcJsonDecode, "use": context.funcUse, "sum": context.funcSum, "len": context.funcLen, "name": context.funcName, "show": context.funcShow, "id": context.funcId, "index": context.funcIndex, "SubIndex": context.funcSubIndex, "count": context.funcCount, "instances": context.funcInstances, "round": context.funcRound, "ceil": context.funcCeil, "current": context.funcCurrent, "quote": context.funcQuote, "parent": context.funcParent, "filter": context.funcFilter, "sub": context.funcSub, "row": context.funcRow, "group": context.funcGroup, "module": context.funcModule, "table": context.funcTable, "eval": context.funcEval, "IsNull": context.funcIsNull, "StringIndex": context.funcStringIndex, "Index": context.funcCompoundIndex, "Array": context.funcArray, "InArray": context.funcInArray, "ArrayFilter": context.funcArrayFilter, "ArrayDedup": context.funcArrayDedup, "ArrayIndex": context.funcCompoundIndex, "ArrayMap": context.funcArrayMap, "ArraySplice": context.funcArraySplice, "ArrayMerge": context.funcArrayMerge, "Map": context.funcMap, "MapKeys": context.funcMapKeys, "MapValues": context.funcMapValues, "MapIndex": context.funcCompoundIndex, "MapMap": context.funcCompoundMap, "MapMerge": context.funcMapMerge, "SetProp": context.funcSetProp, "Control": context.funcControl, "Input": context.funcControlInput, "Number": context.funcControlNumber, "Checkbox": context.funcControlCheckbox, "Select": context.funcControlSelect, "Text": context.funcControlText, "SelectMat": context.funcControlSelectMat, "SelectItem": context.funcControlSelectItem, "Button": context.funcControlButton, "Group": context.funcControlGroup, "Popover": context.funcControlPopover, "GetMatTypeForName": context.funcGetMatTypeForName, "MatName": context.funcMatName, "MatType": context.funcMatType, "MatPrice": context.funcMatPrice, "MatControlPrice": context.funcMatControlPrice, "MatSalesPrice": context.funcMatSalesPrice, "MatPurchasePrice": context.funcMatPurchasePrice, "MatSupplier": context.funcMatSupplier, "GetMatTopType": context.funcGetMatTopType, "MatTypeName": context.funcMatTypeName, "MatTypeUnit": context.funcMatTypeUnit, "DataType": context.funcDataType, "debug": context.funcDebug, "CheckAuth": context.funcCheckAuth, "customer": context.funcCustomer, "phone": context.funcPhone, "address": context.funcAddress, "admin": context.funcAdmin, "GetItemTypeForName": context.funcGetItemTypeForName, "ItemTypeName": context.funcItemTypeName, "GetItemForType": context.funcGetItemForType, "GetSupplierForName": context.funcGetSupplierForName, "SupplierName": context.funcSupplierName, "now": context.funcNow, } } func (context *Context) funcJsonEncode(args ...interface{}) (interface{}, error) { if len(args) < 1 { return nil, errors.New("not enough arguments in call to call") } str, err := json.Marshal(args[0]) if err != nil { return nil, err } return string(str), nil } func (context *Context) funcJsonDecode(args ...interface{}) (interface{}, error) { if len(args) < 1 { return nil, errors.New("not enough arguments in call to call") } var dest interface{} decoder := json.NewDecoder(strings.NewReader(string(db.ToString(args[0])))) decoder.UseNumber() err := decoder.Decode(&dest) return dest, err } func (context *Context) funcUse(args ...interface{}) (interface{}, error) { return "", nil } func (context *Context) funcSum(args ...interface{}) (interface{}, error) { var result float64 argParse(args, func(arg interface{}) { ret, _ := db.ToFloat64(arg) result += ret }) /*for _, arg := range args { ret, _ := db.ToFloat64(arg) result += ret }*/ return result, nil } func (context *Context) funcLen(args ...interface{}) (interface{}, error) { return float64(len(args)), nil } func (context *Context) funcName(args ...interface{}) (interface{}, error) { names := make([]interface{}, 0) for _, arg := range args { if instance, ok := arg.(*InstanceData); ok { nameResult, err := context.LoadNameResult(instance) if err != nil { return nil, err } if nameResult == nil { names = append(names, nil) } else { names = append(names, filterValue(nameResult.Result)) } } else { names = append(names, nil) } } if len(names) == 0 { nameResult, err := context.LoadNameResult(context.Current) if err != nil { return nil, err } if nameResult == nil { return nil, nil } return filterValue(nameResult.Result), nil } if len(names) == 1 { return names[0], nil } return names, nil } func (context *Context) funcShow(args ...interface{}) (interface{}, error) { shows := make([]interface{}, 0) for _, arg := range args { if instance, ok := arg.(*InstanceData); ok { context.LoadShowResult(instance) shows = append(shows, instance.GetShowResultBool()) } else { shows = append(shows, nil) } } if len(shows) == 0 { context.LoadShowResult(context.Current) shows = append(shows, context.Current.GetShowResultBool()) } if len(shows) == 1 { return shows[0], nil } return shows, nil } func (context *Context) funcId(args ...interface{}) (interface{}, error) { ids := make([]interface{}, 0) for _, arg := range args { if instance, ok := arg.(*InstanceData); ok { ids = append(ids, filterValue(instance.GetID())) } else { ids = append(ids, nil) } } if len(ids) == 0 { return filterValue(context.Current.GetID()), nil } if len(ids) == 1 { return ids[0], nil } return ids, nil } func (context *Context) funcIndex(args ...interface{}) (interface{}, error) { indexs := make([]interface{}, 0) for _, arg := range args { if instance, ok := arg.(*InstanceData); ok { indexs = append(indexs, filterValue(instance.Index)) } else { indexs = append(indexs, 0) } } if len(indexs) == 0 { return filterValue(context.Current.Index), nil } if len(indexs) == 1 { return indexs[0], nil } return indexs, nil } func getSubIndex(instance *InstanceData) int { parent := instance.Parent if parent == nil { return 0 } for n, i := range parent.GetSub() { if i.GetID() == instance.GetID() && i.Index == instance.Index { return n } } return 0 } func (context *Context) funcSubIndex(args ...interface{}) (interface{}, error) { indexs := make([]interface{}, 0) for _, arg := range args { if instance, ok := arg.(*InstanceData); ok { indexs = append(indexs, filterValue(getSubIndex(instance))) } else { indexs = append(indexs, 0) } } if len(indexs) == 0 { return filterValue(getSubIndex(context.Current)), nil } if len(indexs) == 1 { return indexs[0], nil } return indexs, nil } func (context *Context) funcCount(args ...interface{}) (interface{}, error) { counts := make([]interface{}, 0) for _, arg := range args { if instance, ok := arg.(*InstanceData); ok { if instance.Object == nil { counts = append(counts, 1) } else { counts = append(counts, filterValue(len(instance.Object.Instances))) } } else { counts = append(counts, 0) } } if len(counts) == 0 { if context.Current.Object == nil { return filterValue(1), nil } else { return filterValue(len(context.Current.Object.Instances)), nil } } if len(counts) == 1 { return counts[0], nil } return counts, nil } func (context *Context) funcInstances(args ...interface{}) (interface{}, error) { names := make([]string, 0) instances := make([]*InstanceData, 0) argParse(args, func(arg interface{}) { if instance, ok := arg.(*InstanceData); ok { instances = append(instances, instance) } else { names = append(names, db.ToString(arg)) } }) /*for _, arg := range args { if ss, ok := arg.([]interface{}); ok { for _, s := range ss { if instance, ok := s.(Instance); ok { instances = append(instances, instance) } else if instance, ok := s.(*Instance); ok { instances = append(instances, *instance) } else { names = append(names, db.ToString(s)) } } } else if instance, ok := arg.(Instance); ok { instances = append(instances, instance) } else if instance, ok := arg.(*Instance); ok { instances = append(instances, *instance) } else { names = append(names, db.ToString(arg)) } }*/ if len(instances) == 0 { instances = append(instances, context.Current) } resultss := make([]interface{}, 0) for _, instance := range instances { results := make([]interface{}, 0) if instance.Object == nil { if len(names) == 0 { results = append(results, instance) } else { for _, name := range names { if instance.NameResult != nil && db.ToString(instance.NameResult.Result) == name { results = append(results, instance) } } } } else { for i, _ := range instance.Object.Instances { if len(names) == 0 { err := context.LoadInstance(&instance.Object.Instances[i]) if err != nil { return nil, err } results = append(results, &instance.Object.Instances[i]) } else { _, err := context.LoadNameResult(&instance.Object.Instances[i]) if err != nil { return nil, err } for _, name := range names { if instance.Object.Instances[i].NameResult != nil && db.ToString(instance.Object.Instances[i].NameResult.Result) == name { err = context.LoadInstance(&instance.Object.Instances[i]) if err != nil { return nil, err } results = append(results, &instance.Object.Instances[i]) } } } } } if len(results) == 0 { resultss = append(resultss, nil) } else if len(results) == 1 { resultss = append(resultss, results[0]) } else { resultss = append(resultss, results) } } if len(resultss) == 0 { return nil, nil } if len(resultss) == 1 { return resultss[0], nil } return resultss, nil } func (context *Context) funcRound(args ...interface{}) (interface{}, error) { if len(args) < 1 { return nil, errors.New("not enough arguments in call to call") } p, _ := db.ToInt64(args[0]) precision := math.Pow10(int(p)) numbers := make([]interface{}, 0) for _, arg := range args[1:] { number, _ := db.ToFloat64(arg) numbers = append(numbers, filterValue(float64(math.Round(number*precision)/precision))) } if len(numbers) == 0 { return nil, nil } if len(numbers) == 1 { return numbers[0], nil } return numbers, nil } func (context *Context) funcCeil(args ...interface{}) (interface{}, error) { if len(args) < 1 { return nil, errors.New("not enough arguments in call to call") } p, _ := db.ToInt64(args[0]) precision := math.Pow10(int(p)) precision2 := math.Pow10(int(p + 2)) numbers := make([]interface{}, 0) for _, arg := range args[1:] { number, _ := db.ToFloat64(arg) numbers = append(numbers, filterValue(float64(math.Ceil(math.Round(number*precision2)/100)/precision))) } if len(numbers) == 0 { return nil, nil } if len(numbers) == 1 { return numbers[0], nil } return numbers, nil } func (context *Context) funcCurrent(args ...interface{}) (interface{}, error) { return context.Current, nil } func (context *Context) funcQuote(args ...interface{}) (interface{}, error) { return context.Order.Form, nil } func (context *Context) funcParent(args ...interface{}) (interface{}, error) { parents := make([]interface{}, 0) for _, arg := range args { if instance, ok := arg.(*InstanceData); ok { parents = append(parents, instance.Parent) } else { parents = append(parents, nil) } } if len(parents) == 0 { return context.Current.Parent, nil } if len(parents) == 1 { return parents[0], nil } return parents, nil } func (context *Context) funcFilter(args ...interface{}) (interface{}, error) { expressions := make([]string, 0) instances := make([]*InstanceData, 0) argParse(args, func(arg interface{}) { if instance, ok := arg.(*InstanceData); ok { instances = append(instances, instance) } else { expressions = append(expressions, db.ToString(arg)) } }) /*for _, arg := range args { if ss, ok := arg.([]interface{}); ok { for _, s := range ss { if instance, ok := s.(Instance); ok { instances = append(instances, instance) } else if instance, ok := s.(*Instance); ok { instances = append(instances, *instance) } else { expressions = append(expressions, db.ToString(s)) } } } else if instance, ok := arg.(Instance); ok { instances = append(instances, instance) } else if instance, ok := arg.(*Instance); ok { instances = append(instances, *instance) } else { expressions = append(expressions, db.ToString(arg)) } }*/ results := make([]interface{}, 0) for _, instance := range instances { ok := true for _, expression := range expressions { result, err := context.ParseValueinInstance(expression, instance) if err != nil { ok = false } else { ok = db.ToBool(result) } if !ok { break } } if ok { results = append(results, instance) } } if len(results) == 0 { return nil, nil } if len(results) == 1 { return results[0], nil } return results, nil } func (context *Context) findInstance(names []string, instance *InstanceData, typ int) ([]interface{}, error) { instances := make([]interface{}, 0) //logger.Sugar.Infof("instance.GetID(): %v %v", instance.GetID(), instance.Type()) if typ == Base || instance.Type == typ { if len(names) == 0 { err := context.LoadInstance(instance) if err != nil { return nil, err } instances = append(instances, instance) } else { _, err := context.LoadNameResult(instance) if err != nil { return nil, err } for _, name := range names { nameResult := instance.NameResult if nameResult != nil && db.ToString(nameResult.Result) == name { err = context.LoadInstance(instance) if err != nil { return nil, err } instances = append(instances, instance) break } } } } else { err := context.LoadInstance(instance) if err != nil { return nil, err } for _, sub := range instance.GetSub() { ss, err := context.findInstance(names, sub, typ) if err != nil { return nil, err } instances = append(instances, ss...) } } return instances, nil } func (context *Context) findInstances(typ int, dinstance *InstanceData, args ...interface{}) (interface{}, error) { names := make([]string, 0) instances := make([]*InstanceData, 0) argParse(args, func(arg interface{}) { if arg != nil { if instance, ok := arg.(*InstanceData); ok { instances = append(instances, instance) } else { names = append(names, db.ToString(arg)) } } }) /*for _, arg := range args { if ss, ok := arg.([]interface{}); ok { for _, s := range ss { if instance, ok := s.(Instance); ok { instances = append(instances, instance) } else if instance, ok := s.(*Instance); ok { instances = append(instances, *instance) } else { names = append(names, db.ToString(s)) } } } else if instance, ok := arg.(Instance); ok { instances = append(instances, instance) } else if instance, ok := arg.(*Instance); ok { instances = append(instances, *instance) } else { names = append(names, db.ToString(arg)) } }*/ if len(instances) == 0 { instances = append(instances, dinstance) } //logger.Sugar.Infof("instances: %v %v %v", instances, typ, names) subss := make([]interface{}, 0) for _, instance := range instances { var subs []interface{} if typ == Base { subs = make([]interface{}, 0) err := context.LoadInstance(instance) if err != nil { return nil, err } for _, sub := range instance.GetSub() { ss, err := context.findInstance(names, sub, typ) if err != nil { return nil, err } subs = append(subs, ss...) } } else { ss, err := context.findInstance(names, instance, typ) if err != nil { return nil, err } subs = ss } /*if len(subs) == 0 { subss = append(subss, nil) } else if len(subs) == 1 { subss = append(subss, subs[0]) } else { subss = append(subss, subs) }*/ subss = append(subss, subs...) } //logger.Sugar.Infof("instancesend: %v", instances) if len(subss) == 0 { return nil, nil } if len(subss) == 1 { return subss[0], nil } return subss, nil } func (context *Context) funcSub(args ...interface{}) (interface{}, error) { return context.findInstances(Base, context.Current, args...) } func (context *Context) funcRow(args ...interface{}) (interface{}, error) { return context.findInstances(Row, context.Order.Form, args...) } func (context *Context) funcGroup(args ...interface{}) (interface{}, error) { return context.findInstances(Group, context.Order.Form, args...) } func (context *Context) funcModule(args ...interface{}) (interface{}, error) { return context.findInstances(Module, context.Order.Form, args...) } func (context *Context) funcTable(args ...interface{}) (interface{}, error) { return context.findInstances(Table, context.Order.Form, args...) } func (context *Context) funcEval(args ...interface{}) (interface{}, error) { expressions := make([]string, 0) instances := make([]*InstanceData, 0) var globalProp map[string]interface{} argParse(args, func(arg interface{}) { if mp, ok := arg.(map[string]interface{}); ok { globalProp = mp } else if instance, ok := arg.(*InstanceData); ok { instances = append(instances, instance) } else { expressions = append(expressions, db.ToString(arg)) } }) /*for _, arg := range args { if ss, ok := arg.([]interface{}); ok { for _, s := range ss { if instance, ok := s.(Instance); ok { instances = append(instances, instance) } else if instance, ok := s.(*Instance); ok { instances = append(instances, *instance) } else { expressions = append(expressions, db.ToString(s)) } } } else if mp, ok := arg.(map[string]interface{}); ok { globalProp = mp } else if instance, ok := arg.(Instance); ok { instances = append(instances, instance) } else if instance, ok := arg.(*Instance); ok { instances = append(instances, *instance) } else { expressions = append(expressions, db.ToString(arg)) } }*/ if len(instances) == 0 { instances = append(instances, context.Current) } resultss := make([]interface{}, 0) for _, instance := range instances { results := make([]interface{}, 0) for _, expression := range expressions { if globalProp == nil { result, err := context.ParseValueinInstance(expression, instance) if err != nil { results = append(results, nil) } else { results = append(results, filterValue(result)) } } else { result, err := context.ParseValueInInstanceAndGlobalProp(expression, instance, globalProp) if err != nil { results = append(results, nil) } else { results = append(results, filterValue(result)) } } } if len(results) == 0 { resultss = append(resultss, nil) } else if len(results) == 1 { resultss = append(resultss, results[0]) } else { resultss = append(resultss, results) } } if len(resultss) == 0 { return nil, nil } if len(resultss) == 1 { return resultss[0], nil } return resultss, nil } func (context *Context) funcIsNull(args ...interface{}) (interface{}, error) { iss := make([]interface{}, 0) for _, arg := range args { iss = append(iss, arg == nil) } if len(iss) == 0 { return true, nil } if len(iss) == 1 { return iss[0], nil } return iss, nil } func (context *Context) funcArray(args ...interface{}) (interface{}, error) { if len(args) == 0 { return []interface{}{}, nil } return []interface{}{args}, nil } func (context *Context) funcInArray(args ...interface{}) (interface{}, error) { if len(args) < 2 { return nil, errors.New("not enough arguments in call to call") } index := db.ToString(args[0]) if array, ok := args[1].([]interface{}); ok { for _, item := range array { if index == db.ToString(item) { return true, nil } } } else { return index == db.ToString(args[1]), nil } return false, nil } func (context *Context) funcStringIndex(args ...interface{}) (interface{}, error) { if len(args) < 2 { return nil, errors.New("not enough arguments in call to call") } s := db.ToString(args[0]) sub := db.ToString(args[1]) return filterValue(strings.Index(s, sub)), nil } func (context *Context) funcCompoundIndex(args ...interface{}) (interface{}, error) { if len(args) < 1 { return nil, errors.New("not enough arguments in call to call") } indexs := args[:len(args)-1] object := args[len(args)-1] values := make([]interface{}, 0) if array, ok := object.([]interface{}); ok { for _, index := range indexs { key, _ := db.ToInt64(index) if key < int64(len(array)) { values = append(values, filterValue(array[key])) } else { values = append(values, nil) } } } if mp, ok := object.(map[string]interface{}); ok { for _, index := range indexs { key := db.ToString(index) values = append(values, filterValue(mp[key])) } } if str, ok := object.(string); ok { for _, index := range indexs { key, _ := db.ToInt64(index) if key < int64(len(str)) { values = append(values, filterValue(string(str[key]))) } else { values = append(values, nil) } } } if len(values) == 0 { return object, nil } if len(values) == 1 { return values[0], nil } return values, nil /* indexs := make([]interface{}, 0) objects := make([]interface{}, 0) for _, arg := range args { if array, ok := arg.([]interface{}); ok { objects = append(objects, array) } else if mp, ok := arg.(map[string]interface{}); ok { objects = append(objects, mp) } else { indexs = append(indexs, arg) } } resultss := make([]interface{}, 0) for _, object := range objects { results := make([]interface{}, 0) if array, ok := object.([]interface{}); ok { for _, index := range indexs { key, _ := db.ToInt64(index) if key < int64(len(array)) { results = append(values, array[key]) } else { results = append(values, nil) } } } else if mp, ok := object.(map[string]interface{}); ok { for _, index := range indexs { key := db.ToString(index) results = append(values, mp[key]) } } if len(results) == 0 { resultss = append(resultss, nil) } else if len(results) == 1 { resultss = append(resultss, results[0]) } else { resultss = append(resultss, results) } } if len(resultss) == 0 { return nil, nil } if len(resultss) == 1 { return resultss[0], nil } return resultss, nil*/ } func (context *Context) funcArrayMap(args ...interface{}) (interface{}, error) { expressions := make([]string, 0) objects := make([]interface{}, 0) for _, arg := range args { if array, ok := arg.([]interface{}); ok { objects = append(objects, array) } else if expression, ok := arg.(string); ok { expressions = append(expressions, expression) } else { objects = append(objects, []interface{}{arg}) } } resultsss := make([]interface{}, 0) for _, object := range objects { resultss := make([]interface{}, 0) if array, ok := object.([]interface{}); ok { for k, v := range array { results := make([]interface{}, 0) globalProp := map[string]interface{}{ "key": float64(k), "value": v, } for _, expression := range expressions { result, err := context.ParseValueinGlobalProp(expression, globalProp) if err != nil { results = append(results, nil) } else { results = append(results, filterValue(result)) } } if len(results) == 0 { resultss = append(resultss, nil) } else if len(results) == 1 { resultss = append(resultss, results[0]) } else { resultss = append(resultss, results) } } } else if mp, ok := object.(map[string]interface{}); ok { for k, v := range mp { results := make([]interface{}, 0) globalProp := map[string]interface{}{ "key": k, "value": v, } for _, expression := range expressions { result, err := context.ParseValueinGlobalProp(expression, globalProp) if err != nil { results = append(results, nil) } else { results = append(results, filterValue(result)) } } if len(results) == 0 { resultss = append(resultss, nil) } else if len(results) == 1 { resultss = append(resultss, results[0]) } else { resultss = append(resultss, results) } } } if len(resultss) == 0 { resultsss = append(resultsss, nil) } else if len(resultss) == 1 { resultsss = append(resultsss, resultss[0]) } else { resultsss = append(resultsss, resultss) } } if len(resultsss) == 0 { return nil, nil } if len(resultsss) == 1 { return resultsss[0], nil } return resultsss, nil } func (context *Context) funcCompoundMap(args ...interface{}) (interface{}, error) { expressions := make([]string, 0) objects := make([]interface{}, 0) for _, arg := range args { if array, ok := arg.([]interface{}); ok { objects = append(objects, array) } else if mp, ok := arg.(map[string]interface{}); ok { objects = append(objects, mp) } else { expressions = append(expressions, db.ToString(arg)) } } resultsss := make([]interface{}, 0) for _, object := range objects { resultss := make([]interface{}, 0) if array, ok := object.([]interface{}); ok { for k, v := range array { results := make([]interface{}, 0) globalProp := map[string]interface{}{ "key": float64(k), "value": v, } for _, expression := range expressions { result, err := context.ParseValueinGlobalProp(expression, globalProp) if err != nil { results = append(results, nil) } else { results = append(results, filterValue(result)) } } if len(results) == 0 { resultss = append(resultss, nil) } else if len(results) == 1 { resultss = append(resultss, results[0]) } else { resultss = append(resultss, results) } } } else if mp, ok := object.(map[string]interface{}); ok { for k, v := range mp { results := make([]interface{}, 0) globalProp := map[string]interface{}{ "key": k, "value": v, } for _, expression := range expressions { result, err := context.ParseValueinGlobalProp(expression, globalProp) if err != nil { results = append(results, nil) } else { results = append(results, filterValue(result)) } } if len(results) == 0 { resultss = append(resultss, nil) } else if len(results) == 1 { resultss = append(resultss, results[0]) } else { resultss = append(resultss, results) } } } if len(resultss) == 0 { resultsss = append(resultsss, nil) } else if len(resultss) == 1 { resultsss = append(resultsss, resultss[0]) } else { resultsss = append(resultsss, resultss) } } if len(resultsss) == 0 { return nil, nil } if len(resultsss) == 1 { return resultsss[0], nil } return resultsss, nil } func (context *Context) funcArrayFilter(args ...interface{}) (interface{}, error) { array := make([]interface{}, 0) for _, arg := range args { if db.ToBool(arg) { array = append(array, filterValue(arg)) } } return array, nil } func (context *Context) funcArrayDedup(args ...interface{}) (interface{}, error) { tmp := make(map[string]int) array := make([]interface{}, 0) for _, arg := range args { s := db.ToString(arg) if _, ok := tmp[s]; !ok { array = append(array, filterValue(arg)) tmp[s] = 1 } } return array, nil } func (context *Context) funcArraySplice(args ...interface{}) (interface{}, error) { if len(args) < 2 { return nil, errors.New("not enough arguments in call to call") } index, _ := db.ToInt64(args[0]) array := []interface{}{} if a, ok := args[1].([]interface{}); ok { array = a } else { array = append(array, args[1]) } n := int64(len(array)) - index if len(args) > 2 { n, _ = db.ToInt64(args[2]) } if index < int64(len(array)) && index >= 0 { before := array[:index] after := []interface{}{} if n <= 0 { after = append(after, array[index:]...) } else if index+n < int64(len(array)) { after = append(after, array[index+n:]...) } array = before for n := 3; n < len(args); n++ { array = append(array, args[n]) } array = append(array, after...) } return array, nil } func (context *Context) funcArrayMerge(args ...interface{}) (interface{}, error) { array := make([]interface{}, 0) for _, arg := range args { if s, ok := arg.([]interface{}); ok { array = append(array, s...) } else { array = append(array, arg) } } return array, nil } func (context *Context) funcMap(args ...interface{}) (interface{}, error) { m := make(map[string]interface{}) for i := 0; i < len(args)-1; i += 2 { m[db.ToString(args[i])] = filterValue(args[i+1]) } return m, nil } func (context *Context) funcMapKeys(args ...interface{}) (interface{}, error) { if len(args) < 1 { return nil, errors.New("not enough arguments in call to call") } keys := make([]interface{}, 0) if mp, ok := args[0].(map[string]interface{}); ok { for key, _ := range mp { keys = append(keys, key) } } return keys, nil } func (context *Context) funcMapValues(args ...interface{}) (interface{}, error) { if len(args) < 1 { return nil, errors.New("not enough arguments in call to call") } values := make([]interface{}, 0) if mp, ok := args[0].(map[string]interface{}); ok { for _, value := range mp { values = append(values, filterValue(value)) } } return values, nil } func (context *Context) funcMapMerge(args ...interface{}) (interface{}, error) { mp := make(map[string]interface{}) for _, arg := range args { if m, ok := arg.(map[string]interface{}); ok { for k, v := range m { mp[k] = filterValue(v) } } } return mp, nil } func (context *Context) funcSetProp(args ...interface{}) (interface{}, error) { if len(args) < 2 { return nil, errors.New("not enough arguments in call to call") } name := db.ToString(args[0]) prop, err := context.GetProp(name) if prop == nil { return nil, err } prop.Result = args[1] context.ModifyAfter(prop.Key) return prop.Result, nil } func (context *Context) funcControl(args ...interface{}) (interface{}, error) { if len(args) < 1 { return nil, errors.New("not enough arguments in call to call") } var control Control control.PraseForArgs(args...) return control, nil } func (context *Context) funcControlInput(args ...interface{}) (interface{}, error) { var control Control control.PraseForArgs(append([]interface{}{"input"}, args...)...) return control, nil } func (context *Context) funcControlNumber(args ...interface{}) (interface{}, error) { var control Control control.PraseForArgs(append([]interface{}{"number"}, args...)...) return control, nil } func (context *Context) funcControlCheckbox(args ...interface{}) (interface{}, error) { var value interface{} if len(args) > 0 { value = args[0] } var param map[string]interface{} if len(args) > 2 { if p, ok := args[2].(map[string]interface{}); ok { param = p } else { param = make(map[string]interface{}) } } else { param = make(map[string]interface{}) } if len(args) > 1 { param["label"] = args[1] } if len(args) > 3 { args = args[3:] } else { args = make([]interface{}, 0) } var control Control control.PraseForArgs(append([]interface{}{"checkbox", value, param}, args...)...) return control, nil } func (context *Context) funcControlText(args ...interface{}) (interface{}, error) { var control Control var value interface{} if len(args) > 1 { value = args[1] } var param map[string]interface{} if len(args) > 2 { if p, ok := args[2].(map[string]interface{}); ok { param = p } else { param = make(map[string]interface{}) } } else { param = make(map[string]interface{}) } if len(args) > 0 { param["label"] = args[0] } var event map[string]string if len(args) > 3 { if e, ok := args[3].(map[string]string); ok { event = e } else { event = make(map[string]string) if e, ok := args[3].(map[string]interface{}); ok { for key, val := range e { event[key] = db.ToString(val) } } } } else { event = make(map[string]string) } last := false if len(args) > 4 { if p, ok := args[4].(bool); ok { last = p } } control.PraseForArgs("text", value, param, event, last) return control, nil } func (context *Context) funcControlSelect(args ...interface{}) (interface{}, error) { var value interface{} if len(args) > 1 { value = args[1] } var param map[string]interface{} if len(args) > 2 { if p, ok := args[2].(map[string]interface{}); ok { param = p } else { param = make(map[string]interface{}) } } else { param = make(map[string]interface{}) } if len(args) > 0 { if p, ok := args[0].([]interface{}); ok { param["options"] = p } else { param["options"] = make([]interface{}, 0) } } if len(args) > 3 { args = args[3:] } else { args = make([]interface{}, 0) } var control Control control.PraseForArgs(append([]interface{}{"select", value, param}, args...)...) return control, nil } func (context *Context) funcControlGroup(args ...interface{}) (interface{}, error) { controls := make([]Control, 0) values := make([]interface{}, 0) for _, arg := range args { var control Control if c, ok := arg.(Control); ok { control = c } else if c, ok := arg.(*Control); ok { control = *c } else if c, ok := arg.(map[string]interface{}); ok { control.PraseForMap(c) } controls = append(controls, control) values = append(values, control.Value) } var control Control control.Type = "group" control.Value = values control.Param = map[string]interface{}{ "controls": controls, } control.Event = make(map[string]string) control.Last = true return control, nil } func (context *Context) funcControlPopover(args ...interface{}) (interface{}, error) { var param map[string]interface{} if len(args) > 1 { if p, ok := args[1].(map[string]interface{}); ok { param = p } else { param = make(map[string]interface{}) } } else { param = make(map[string]interface{}) } if len(args) > 0 { param["label"] = args[0] } if len(args) > 2 { args = args[2:] } else { args = make([]interface{}, 0) } controls := make([]Control, 0) values := make([]interface{}, 0) last := true for _, arg := range args { if control, ok := arg.(Control); ok { controls = append(controls, control) values = append(values, control.Value) } else if control, ok := arg.(*Control); ok { controls = append(controls, *control) values = append(values, control.Value) } else if c, ok := arg.(map[string]interface{}); ok { var control Control control.PraseForMap(c) controls = append(controls, control) values = append(values, control.Value) } else if c, ok := arg.(bool); ok { last = c } } param["controls"] = controls var control Control control.Type = "popover" control.Value = values control.Param = param control.Event = make(map[string]string) control.Last = last return control, nil } func (context *Context) funcControlSelectMat(args ...interface{}) (interface{}, error) { var control Control var value interface{} if len(args) > 1 { value = args[1] } var param map[string]interface{} if len(args) > 2 { if p, ok := args[2].(map[string]interface{}); ok { param = p } else { param = make(map[string]interface{}) } } else { param = make(map[string]interface{}) } if len(args) > 0 { if s, ok := args[0].([]interface{}); ok { param["type"] = s } else { id, _ := db.ToInt64(args[0]) param["type"] = []interface{}{id} } } if len(args) > 3 { args = args[3:] } else { args = make([]interface{}, 0) } control.PraseForArgs(append([]interface{}{"selectmat", value, param}, args...)...) return control, nil } func (context *Context) funcControlSelectItem(args ...interface{}) (interface{}, error) { var control Control var value interface{} if len(args) > 1 { value = args[1] } var param map[string]interface{} if len(args) > 2 { if p, ok := args[2].(map[string]interface{}); ok { param = p } else { param = make(map[string]interface{}) } } else { param = make(map[string]interface{}) } if len(args) > 0 { if s, ok := args[0].([]interface{}); ok { param["type"] = s } else { id, _ := db.ToInt64(args[0]) param["type"] = []interface{}{id} } } if len(args) > 3 { args = args[3:] } else { args = make([]interface{}, 0) } control.PraseForArgs(append([]interface{}{"selectitem", value, param}, args...)...) return control, nil } func (context *Context) funcControlButton(args ...interface{}) (interface{}, error) { var param map[string]interface{} if len(args) > 2 { if p, ok := args[2].(map[string]interface{}); ok { param = p } else { param = make(map[string]interface{}) } } else { param = make(map[string]interface{}) } var event map[string]string if len(args) > 3 { if e, ok := args[3].(map[string]string); ok { event = e } else { event = make(map[string]string) if event, ok := args[3].(map[string]interface{}); ok { for key, val := range event { event[key] = db.ToString(val) } } } } else { event = make(map[string]string) } if len(args) > 0 { param["label"] = args[0] } if len(args) > 1 { event["click"] = db.ToString(args[1]) } if len(args) > 4 { args = args[4:] } else { args = make([]interface{}, 0) } var control Control control.PraseForArgs(append([]interface{}{"button", nil, param, event}, args...)...) return control, nil } func (context *Context) funcGetMatTypeForName(args ...interface{}) (interface{}, error) { context.MatTypeInit() pids := make([]interface{}, 0) for _, arg := range args { typs := strings.Split(db.ToString(arg), "/") pid := int64(0) for _, name := range typs { if name == "" { continue } if nameCache, ok := context.MatTypePidNameCache[pid]; ok { if typ, ok := nameCache[name]; ok { pid = typ.ID } } } if pid == 0 { pids = append(pids, nil) } else { pids = append(pids, filterValue(pid)) } } if len(pids) == 0 { return nil, nil } if len(pids) == 1 { return pids[0], nil } return pids, nil } func (context *Context) funcMatName(args ...interface{}) (interface{}, error) { names := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) mat := context.GetMat(id) if mat != nil { name := mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color names = append(names, name) } else { names = append(names, nil) } } if len(names) == 0 { return nil, nil } if len(names) == 1 { return names[0], nil } return names, nil } func (context *Context) funcMatType(args ...interface{}) (interface{}, error) { types := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) mat := context.GetMat(id) if mat != nil { types = append(types, filterValue(mat.TypeId)) } else { types = append(types, nil) } } if len(types) == 0 { return nil, nil } if len(types) == 1 { return types[0], nil } return types, nil } func (context *Context) funcMatPrice(args ...interface{}) (interface{}, error) { prices := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) mat := context.GetMat(id) if mat != nil { prices = append(prices, filterValue(mat.Price)) } else { prices = append(prices, nil) } } if len(prices) == 0 { return nil, nil } if len(prices) == 1 { return prices[0], nil } return prices, nil } func (context *Context) funcMatControlPrice(args ...interface{}) (interface{}, error) { prices := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) mat := context.GetMat(id) if mat != nil { prices = append(prices, filterValue(final.ControlPrice(mat.ControlPrice, mat.Price))) } else { prices = append(prices, nil) } } if len(prices) == 0 { return nil, nil } if len(prices) == 1 { return prices[0], nil } return prices, nil } func (context *Context) funcMatSalesPrice(args ...interface{}) (interface{}, error) { prices := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) mat := context.GetMat(id) if mat != nil { prices = append(prices, filterValue(final.SalesPrice(mat.SalesPrice, mat.Price))) } else { prices = append(prices, nil) } } if len(prices) == 0 { return nil, nil } if len(prices) == 1 { return prices[0], nil } return prices, nil } func (context *Context) funcMatPurchasePrice(args ...interface{}) (interface{}, error) { prices := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) mat := context.GetMat(id) if mat != nil { prices = append(prices, filterValue(final.PurchasePrice(mat.PurchasePrice, mat.Price))) } else { prices = append(prices, nil) } } if len(prices) == 0 { return nil, nil } if len(prices) == 1 { return prices[0], nil } return prices, nil } func (context *Context) funcMatSupplier(args ...interface{}) (interface{}, error) { suppliers := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) mat := context.GetMat(id) if mat != nil { suppliers = append(suppliers, filterValue(mat.SupplierId)) } else { suppliers = append(suppliers, nil) } } if len(suppliers) == 0 { return nil, nil } if len(suppliers) == 1 { return suppliers[0], nil } return suppliers, nil } func (context *Context) funcGetMatTopType(args ...interface{}) (interface{}, error) { context.MatTypeInit() types := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) for { if typ, ok := context.MatTypeCache[id]; ok { if typ.Pid != 0 { id = typ.Pid } else { break } } else { break } } types = append(types, filterValue(id)) } if len(types) == 0 { return nil, nil } if len(types) == 1 { return types[0], nil } return types, nil } func (context *Context) funcMatTypeName(args ...interface{}) (interface{}, error) { context.MatTypeInit() names := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) if typ, ok := context.MatTypeCache[id]; ok { names = append(names, typ.Name) } else { names = append(names, nil) } } if len(names) == 0 { return nil, nil } if len(names) == 1 { return names[0], nil } return names, nil } func (context *Context) funcMatTypeUnit(args ...interface{}) (interface{}, error) { context.MatTypeInit() types := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) if typ, ok := context.MatTypeCache[id]; ok { types = append(types, typ.Unit) } else { types = append(types, "") } } if len(types) == 0 { return nil, nil } if len(types) == 1 { return types[0], nil } return types, nil } func (context *Context) funcDataType(args ...interface{}) (interface{}, error) { types := make([]interface{}, 0) for _, arg := range args { typ := reflect.TypeOf(arg) if typ == nil { types = append(types, nil) } else { types = append(types, typ.String()) } } if len(types) == 0 { return nil, nil } if len(types) == 1 { return types[0], nil } return types, nil } func (context *Context) funcDebug(args ...interface{}) (interface{}, error) { logger.Sugar.Infof("Debug %v: %v arg", context.Calls[len(context.Calls)-1].Expression, len(args)) for n, arg := range args { typ := reflect.TypeOf(arg) typs := "" if typ == nil { } else { typs = typ.String() } logger.Sugar.Infof("arg[%v]: %+v %v", n, arg, typs) } if len(args) == 1 { return args[0], nil } return args, nil } func (context *Context) funcCheckAuth(args ...interface{}) (interface{}, error) { auths := make([]string, 0) argParse(args, func(arg interface{}) { auths = append(auths, db.ToString(arg)) }) return admin.CheckAuth(auths, context.C.GetInt("adminID")), nil } func (context *Context) funcCustomer(args ...interface{}) (interface{}, error) { customer := context.Customer() if customer != nil { return customer.Username, nil } return "", nil } func (context *Context) funcPhone(args ...interface{}) (interface{}, error) { customer := context.Customer() if customer != nil { return customer.Phone, nil } return "", nil } func (context *Context) funcAddress(args ...interface{}) (interface{}, error) { customer := context.Customer() if customer != nil { return customer.Address + " " + customer.Village + " " + customer.RoomNo, nil } return "", nil } func (context *Context) funcAdmin(args ...interface{}) (interface{}, error) { admin := context.Admin() if admin != nil { return admin.Username, nil } return "", nil } func (context *Context) funcGetItemTypeForName(args ...interface{}) (interface{}, error) { context.ItemTypeInit() pids := make([]interface{}, 0) for _, arg := range args { typs := strings.Split(db.ToString(arg), "/") pid := int64(0) for _, name := range typs { if name == "" { continue } if nameCache, ok := context.ItemTypePidNameCache[pid]; ok { if typ, ok := nameCache[name]; ok { pid = typ.ID } } } if pid == 0 { pids = append(pids, nil) } else { pids = append(pids, filterValue(pid)) } } if len(pids) == 0 { return nil, nil } if len(pids) == 1 { return pids[0], nil } return pids, nil } func (context *Context) funcItemTypeName(args ...interface{}) (interface{}, error) { context.ItemTypeInit() names := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) if typ, ok := context.ItemTypeCache[id]; ok { names = append(names, typ.Name) } else { names = append(names, nil) } } if len(names) == 0 { return nil, nil } if len(names) == 1 { return names[0], nil } return names, nil } func (context *Context) funcGetItemForType(args ...interface{}) (interface{}, error) { ids := make([]interface{}, 0) for _, arg := range args { typid, _ := db.ToInt64(arg) tids := budget.AllItemTypes([]int64{typid}) items, _ := budget.GetItemModels(map[string]interface{}{ "typeId in": tids, "deleted_at": 0, }) for _, item := range items { if _, ok := context.Order.Models[Item][item.ID]; !ok { context.Order.Models[Item][item.ID] = item } ids = append(ids, filterValue(item.ID)) } } if len(ids) == 1 { return ids[0], nil } return ids, nil } func (context *Context) funcGetSupplierForName(args ...interface{}) (interface{}, error) { context.SupplierInit() ids := make([]interface{}, 0) for _, arg := range args { name := db.ToString(arg) if supplier, ok := context.SupplierNameCache[name]; ok { ids = append(ids, filterValue(supplier.ID)) } else { ids = append(ids, nil) } } if len(ids) == 0 { return nil, nil } if len(ids) == 1 { return ids[0], nil } return ids, nil } func (context *Context) funcSupplierName(args ...interface{}) (interface{}, error) { context.SupplierInit() names := make([]interface{}, 0) for _, arg := range args { id, _ := db.ToInt64(arg) if supplier, ok := context.SupplierCache[id]; ok { names = append(names, supplier.Name) } else { names = append(names, nil) } } if len(names) == 0 { return nil, nil } if len(names) == 1 { return names[0], nil } return names, nil } func (context *Context) funcNow(args ...interface{}) (interface{}, error) { return float64(time.Now().Unix()), nil }