|
@@ -2,31 +2,50 @@
|
|
|
package asuModels
|
|
|
|
|
|
import (
|
|
|
+ "database/sql"
|
|
|
"fmt"
|
|
|
+ "github.com/xaionaro-go/extime"
|
|
|
"html/template"
|
|
|
)
|
|
|
|
|
|
//reform:unit
|
|
|
type Unit struct {
|
|
|
- Id int `reform:"id" view:"readonly"`
|
|
|
- OrgInn string `reform:"OrgInn" view:"readonly"`
|
|
|
- Name *string `reform:"Name" view:"readonly"`
|
|
|
- ParentId *int `reform:"ParentId" view:"readonly"`
|
|
|
- LevelIdx int `reform:"LevelIdx" view:"readonly"`
|
|
|
- IsHidden int `reform:"IsHidden" view:"readonly"`
|
|
|
- OKVED *string `reform:"OKVED" view:"readonly"`
|
|
|
- BriefName *string `reform:"BriefName" view:"readonly"`
|
|
|
- CreateOrderNo *string `reform:"CreateOrderNo" view:"readonly"`
|
|
|
- CreateOrderDate *string `reform:"CreateOrderDate" view:"readonly"`
|
|
|
- CloseOrderNo *string `reform:"CloseOrderNo" view:"readonly"`
|
|
|
- CloseOrderDate *string `reform:"CloseOrderDate" view:"readonly"`
|
|
|
- ChiefName *string `reform:"ChiefName" view:"readonly"`
|
|
|
- PersNumber *int `reform:"PersNumber" view:"readonly"`
|
|
|
- Code string `reform:"Code" view:"readonly"`
|
|
|
- SortNumber *string `reform:"SortNumber" view:"readonly"`
|
|
|
- ChiefTabN *string `reform:"ChiefTabN" view:"readonly"`
|
|
|
+ Id int `reform:"id" view:"readonly"`
|
|
|
+ OrgInn string `reform:"OrgInn" view:"readonly"`
|
|
|
+ Name *string `reform:"Name" view:"readonly"`
|
|
|
+ ParentId *int `reform:"ParentId" view:"readonly"`
|
|
|
+ LevelIdx int `reform:"LevelIdx" view:"readonly"`
|
|
|
+ IsHidden int `reform:"IsHidden" view:"readonly"`
|
|
|
+ OKVED *string `reform:"OKVED" view:"readonly"`
|
|
|
+ BriefName *string `reform:"BriefName" view:"readonly"`
|
|
|
+ CreateOrderNo *string `reform:"CreateOrderNo" view:"readonly"`
|
|
|
+ CreateOrderDate *extime.Time `reform:"CreateOrderDate" view:"readonly"`
|
|
|
+ CloseOrderNo *string `reform:"CloseOrderNo" view:"readonly"`
|
|
|
+ CloseOrderDate *extime.Time `reform:"CloseOrderDate" view:"readonly"`
|
|
|
+ ChiefName *string `reform:"ChiefName" view:"readonly"`
|
|
|
+ PersNumber *int `reform:"PersNumber" view:"readonly"`
|
|
|
+ Code string `reform:"Code" view:"readonly"`
|
|
|
+ SortNumber *string `reform:"SortNumber" view:"readonly"`
|
|
|
+ ChiefTabN *string `reform:"ChiefTabN" view:"readonly"`
|
|
|
+
|
|
|
+ children []*Unit `reform:"-"`
|
|
|
+ childrenReady bool `reform:"-"`
|
|
|
+
|
|
|
+ formulars Formulars `reform:"-"`
|
|
|
+ formularsReady bool `reform:"-"`
|
|
|
+
|
|
|
+ isActive bool `reform:"-"`
|
|
|
+ isActiveReady bool `reform:"-"`
|
|
|
+}
|
|
|
+
|
|
|
+func (sql Unit) ActiveOnly() *UnitScope {
|
|
|
+ return sql.Scope().ActiveOnly()
|
|
|
+}
|
|
|
+func (sql *UnitScope) ActiveOnly() *UnitScope {
|
|
|
+ return sql.Where("(CreateOrderDate IS NULL OR CreateOrderDate < NOW()) AND (CloseOrderDate IS NULL OR CloseOrderDate+24*3600 > NOW())")
|
|
|
}
|
|
|
|
|
|
+// TODO: Remove this "VIEW" from this model
|
|
|
func (u Unit) View_readTag(fieldName string, parent interface{}, args []interface{}) template.HTML {
|
|
|
if u.Id == 0 {
|
|
|
return template.HTML(fmt.Sprintf(`Не назначено`))
|
|
@@ -42,3 +61,178 @@ func (u Unit) View_readTag(fieldName string, parent interface{}, args []interfac
|
|
|
|
|
|
return template.HTML(fmt.Sprintf(`<a href="/asu/unitsByID/%v?fullscreen=true">%v — %v</a>`, u.Id, u.Code, name))
|
|
|
}
|
|
|
+
|
|
|
+type Units []Unit
|
|
|
+
|
|
|
+func (units Units) calculateTree(strict bool) {
|
|
|
+ unitMap := map[int]*Unit{}
|
|
|
+
|
|
|
+ for idx, unit := range units {
|
|
|
+ unitMap[unit.Id] = &units[idx]
|
|
|
+ }
|
|
|
+
|
|
|
+ for idx, _ := range units {
|
|
|
+ unit := &units[idx]
|
|
|
+
|
|
|
+ if unit.ParentId == nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ parent := unitMap[*unit.ParentId]
|
|
|
+
|
|
|
+ if parent == nil {
|
|
|
+ if strict {
|
|
|
+ panic(fmt.Sprintf("Not full units list. len(units) == %v; *unit.ParentId == %v", units, *unit.ParentId))
|
|
|
+ }
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ parent.children = append(parent.children, unit)
|
|
|
+ }
|
|
|
+
|
|
|
+ for idx, _ := range units {
|
|
|
+ units[idx].childrenReady = true
|
|
|
+ }
|
|
|
+}
|
|
|
+func (units Units) CalculateTree() Units {
|
|
|
+ units.calculateTree(true)
|
|
|
+ return units
|
|
|
+}
|
|
|
+
|
|
|
+func (unit *Unit) DoRecursive(f func(*Unit, interface{}), arg interface{}) {
|
|
|
+ f(unit, arg)
|
|
|
+
|
|
|
+ for _, child := range unit.GetChildrenPtrs() {
|
|
|
+ child.DoRecursive(f, arg)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (units Units) DoRecursive(f func(*Unit, interface{}), arg interface{}) {
|
|
|
+ for _, unit := range units {
|
|
|
+ unit.DoRecursive(f, arg)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (u Unit) GetChildrenPtrs() []*Unit {
|
|
|
+ if !u.childrenReady {
|
|
|
+ panic("unit is not ready for method GetChildrenPtrs: it's required to call CalculateTree method, first")
|
|
|
+ }
|
|
|
+ return u.children
|
|
|
+}
|
|
|
+
|
|
|
+func (u *Unit) PrepareFormulars() *Unit {
|
|
|
+ var err error
|
|
|
+ u.formulars, err = FormularSQL.Select(Formular{UnitId: u.Id})
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ u.formularsReady = true
|
|
|
+ return u
|
|
|
+}
|
|
|
+
|
|
|
+func (u Unit) GetFormulars() Formulars {
|
|
|
+ if !u.formularsReady {
|
|
|
+ panic("unit is not ready for method GetFormulars: it's required to call PrepareFormulars method, first")
|
|
|
+ }
|
|
|
+ return u.formulars
|
|
|
+}
|
|
|
+
|
|
|
+func (units Units) PrepareFormulars() Units {
|
|
|
+ for idx, _ := range units {
|
|
|
+ units[idx].PrepareFormulars()
|
|
|
+ }
|
|
|
+
|
|
|
+ return units
|
|
|
+}
|
|
|
+
|
|
|
+func (units Units) GetFormulars() (formulars Formulars) {
|
|
|
+ for _, unit := range units {
|
|
|
+ formulars = append(formulars, unit.GetFormulars()...)
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+func (u *Unit) PrepareIsActive() *Unit {
|
|
|
+ now := extime.Now()
|
|
|
+
|
|
|
+ startIsGood := false
|
|
|
+ endIsGood := false
|
|
|
+
|
|
|
+ if u.CreateOrderDate != nil {
|
|
|
+ startIsGood = u.CreateOrderDate.UnixNano() <= now.UnixNano()
|
|
|
+ }
|
|
|
+
|
|
|
+ if u.CloseOrderDate == nil {
|
|
|
+ endIsGood = true
|
|
|
+ } else {
|
|
|
+ endIsGood = u.CloseOrderDate.UnixNano()+24*3600*1000*1000*1000 >= now.UnixNano()
|
|
|
+ }
|
|
|
+
|
|
|
+ u.isActive = startIsGood && endIsGood
|
|
|
+
|
|
|
+ return u
|
|
|
+}
|
|
|
+
|
|
|
+func (u Unit) IsActive() bool {
|
|
|
+ if !u.isActiveReady {
|
|
|
+ panic("unit is not ready for method IsActive: it's required to call PrepareIsReady method, first")
|
|
|
+ }
|
|
|
+ return u.isActive
|
|
|
+}
|
|
|
+
|
|
|
+func (u *Unit) PrepareChildrenTree() *Unit {
|
|
|
+ if u.childrenReady {
|
|
|
+ return u
|
|
|
+ }
|
|
|
+
|
|
|
+ children, err := UnitSQL.Select(Unit{ParentId: &u.Id})
|
|
|
+ if err == sql.ErrNoRows {
|
|
|
+ u.childrenReady = true
|
|
|
+ return u
|
|
|
+ }
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ for idx, _ := range children {
|
|
|
+ child := &children[idx]
|
|
|
+ child.PrepareChildrenTree()
|
|
|
+
|
|
|
+ u.children = append(u.children, child)
|
|
|
+ }
|
|
|
+
|
|
|
+ u.childrenReady = true
|
|
|
+
|
|
|
+ return u
|
|
|
+}
|
|
|
+func (units Units) PrepareChildrenTree() Units {
|
|
|
+ for idx, _ := range units {
|
|
|
+ units[idx].PrepareChildrenTree()
|
|
|
+ }
|
|
|
+
|
|
|
+ return units
|
|
|
+}
|
|
|
+
|
|
|
+func GetUnitsHeadedBy(empGUID int) (units Units) {
|
|
|
+ var formulars Formulars
|
|
|
+ trueValue := true
|
|
|
+ formulars, err := FormularSQL.ActiveOnly().Select(Formular{EmpGUID: empGUID, IsHead: &trueValue})
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, formular := range formulars {
|
|
|
+ if !formular.PrepareIsActive().IsActive() {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ formular.PrepareUnit()
|
|
|
+ unit := formular.GetUnit()
|
|
|
+ unit.PrepareChildrenTree()
|
|
|
+ units = append(units, unit)
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+}
|