月度统计定时任务按设定的时间查询相应数据&修复若干bug
| | |
| | | return |
| | | } |
| | | |
| | | params.Preload = true |
| | | monthFormsService := service.NewWarehouseMonthFormsService() |
| | | list, err := monthFormsService.FetchAll(params) |
| | | if err != nil { |
| | |
| | | BeginAmount decimal.Decimal `json:"beginAmount" gorm:"type:decimal(30,10);not null;comment:数量"` //期初数量 |
| | | EndAmount decimal.Decimal `json:"amount" gorm:"type:decimal(30,10);not null;comment:数量"` //期末结余数量 |
| | | |
| | | InputAmount decimal.Decimal `json:"inputAmount" gorm:"type:decimal(30,10);not null;comment:数量"` //入库数量 |
| | | InputItems []*WarehouseStatsItems `json:"inputItems"` //入库明细 |
| | | |
| | | InputAmount decimal.Decimal `json:"inputAmount" gorm:"type:decimal(30,10);not null;comment:数量"` //入库数量 |
| | | InputItems []*WarehouseStatsItems `json:"inputItems" gorm:"-"` //入库明细 |
| | | Items []*WarehouseStatsItems `json:"-"` |
| | | OutputAmount decimal.Decimal `json:"outputAmount" gorm:"type:decimal(30,10);not null;comment:数量"` //出库数量 |
| | | OutputItems []*WarehouseStatsItems `json:"outputItems"` //出库明细 |
| | | OutputItems []*WarehouseStatsItems `json:"outputItems" gorm:"-"` //出库明细 |
| | | |
| | | Date string `json:"date" gorm:"index;type:varchar(255); not null;default ''"` //日期 2024-04 |
| | | } |
| | | |
| | | WarehouseStatsItems struct { |
| | | WarehouseMonthStatsId int `json:"warehouseMonthStatsId"` |
| | | Name string `json:"name" gorm:"type:varchar(255);not null;default:''"` //入库来源,出库去处 |
| | | Amount decimal.Decimal `json:"amount" gorm:"type:decimal(30,10);not null;"` //数量 |
| | | WarehouseMonthStatsId int `json:"warehouseMonthStatsId"` |
| | | Type MonthStatsItemsType `json:"type" gorm:"type:tinyint;not null;default:1"` |
| | | Name string `json:"name" gorm:"type:varchar(255);not null;default:''"` //入库来源,出库去处 |
| | | Amount decimal.Decimal `json:"amount" gorm:"type:decimal(30,10);not null;"` //数量 |
| | | } |
| | | |
| | | WarehouseMonthStatsSearch struct { |
| | |
| | | } |
| | | ) |
| | | |
| | | type MonthStatsItemsType int |
| | | |
| | | const ( |
| | | MonthStatsItemsTypeInput MonthStatsItemsType = 1 //入库 |
| | | MonthStatsItemsTypeOutput MonthStatsItemsType = 2 //出库 |
| | | ) |
| | | |
| | | func (slf *WarehouseStatsItems) TableName() string { |
| | | return "wms_warehouse_month_stats_items" |
| | | } |
| | | |
| | | func (slf *WarehouseMonthStats) TableName() string { |
| | | return "wms_warehouse_month_stats" |
| | | } |
| | | |
| | | func (slf *WarehouseMonthStats) BeforeCreate(tx *gorm.DB) error { |
| | | if len(slf.InputItems) != 0 || len(slf.OutputItems) != 0 { |
| | | items := make([]*WarehouseStatsItems, 0, len(slf.InputItems)+len(slf.OutputItems)) |
| | | for _, item := range slf.InputItems { |
| | | items = append(items, &WarehouseStatsItems{ |
| | | Type: MonthStatsItemsTypeInput, |
| | | Name: item.Name, |
| | | Amount: item.Amount, |
| | | }) |
| | | } |
| | | |
| | | for _, item := range slf.OutputItems { |
| | | items = append(items, &WarehouseStatsItems{ |
| | | Type: MonthStatsItemsTypeOutput, |
| | | Name: item.Name, |
| | | Amount: item.Amount, |
| | | }) |
| | | } |
| | | |
| | | slf.Items = items |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *WarehouseMonthStats) AfterFind(tx *gorm.DB) error { |
| | | if len(slf.Items) != 0 { |
| | | inputItems := make([]*WarehouseStatsItems, 0) |
| | | outputItems := make([]*WarehouseStatsItems, 0) |
| | | for _, v := range slf.Items { |
| | | item := WarehouseStatsItems{ |
| | | Type: v.Type, |
| | | Name: v.Name, |
| | | Amount: v.Amount, |
| | | } |
| | | if v.Type == MonthStatsItemsTypeInput { |
| | | inputItems = append(inputItems, &item) |
| | | } else { |
| | | outputItems = append(outputItems, &item) |
| | | } |
| | | } |
| | | } |
| | | return nil |
| | | } |
| | | |
| | | func NewWarehouseMonthStatsSearch() *WarehouseMonthStatsSearch { |
| | |
| | | } |
| | | |
| | | if slf.Preload { |
| | | db = db.Preload("InputItems").Preload("OutputItems") |
| | | db = db.Preload("Items") |
| | | } |
| | | |
| | | return db |
| | |
| | | "wms/models" |
| | | "wms/pkg/logx" |
| | | "wms/request" |
| | | "wms/utils" |
| | | ) |
| | | |
| | | type MonthFormsService struct{} |
| | |
| | | } |
| | | productMap := models.MaterialMap(products) |
| | | |
| | | beginTime, endTime := utils.GetLastMonthPeriod() |
| | | //按配置取开始时间和结束时间 |
| | | beginTime, endTime, err := NewSystemConfigService().GetInventoryCutOffTime() |
| | | if err != nil { |
| | | logx.Errorf("MonthStats GetCurrentStats get GetInventoryCutOffTime err:%v", err) |
| | | return |
| | | } |
| | | inputMap, err := GetStatsByOperationType(beginTime, endTime, constvar.BaseOperationTypeIncoming) |
| | | if err != nil { |
| | | logx.Errorf("MonthStats GetStatsByOperationType input err:%v", err) |
| | |
| | | |
| | | import ( |
| | | "errors" |
| | | "fmt" |
| | | "github.com/spf13/cast" |
| | | "gorm.io/gorm" |
| | | "strings" |
| | |
| | | |
| | | func (slf SystemConfigService) GetInventoryCutOffPoint() (day int, timeStr string, err error) { |
| | | config, err := models.NewSystemConfigSearch().SetConfigType(constvar.SystemConfigTypeInventoryCutOffPoint).First() |
| | | if err != nil { |
| | | err = errors.New("库存结算时间点未配置") |
| | | if err == gorm.ErrRecordNotFound { |
| | | config = &models.SystemConfig{ |
| | | Val: "01-00:01", |
| | | } |
| | | } |
| | | if err != nil && err != gorm.ErrRecordNotFound { |
| | | return |
| | | } |
| | | return slf.CheckInventoryCutOffPoint(config.Val) |
| | | } |
| | | |
| | | func (slf SystemConfigService) GetInventoryCutOffTime() (beginTime, endTime time.Time, err error) { |
| | | day, timeStr, err := slf.GetInventoryCutOffPoint() |
| | | // 假设当前时间 |
| | | currentTime := time.Now() |
| | | // 解析给定的时间字符串为 time 对象 |
| | | parsedTime, err := time.Parse("15:04", timeStr) |
| | | if err != nil { |
| | | fmt.Println("时间解析错误:", err) |
| | | return |
| | | } |
| | | |
| | | // 创建一个日期时间对象,假设在当前月的给定日和时间 |
| | | endTime = time.Date(currentTime.Year(), currentTime.Month(), day, parsedTime.Hour(), parsedTime.Minute(), 0, 0, currentTime.Location()) |
| | | |
| | | // 如果给定的日期时间在当前时间之后,我们需要回到上个月 |
| | | if endTime.After(currentTime) { |
| | | lastMonth := currentTime.AddDate(0, -1, 0) |
| | | endTime = time.Date(lastMonth.Year(), lastMonth.Month(), day, parsedTime.Hour(), parsedTime.Minute(), 0, 0, currentTime.Location()) |
| | | } |
| | | lastMonth := endTime.AddDate(0, -1, 0) |
| | | beginTime = time.Date(lastMonth.Year(), lastMonth.Month(), day, parsedTime.Hour(), parsedTime.Minute(), 0, 0, currentTime.Location()) |
| | | return beginTime, endTime, nil |
| | | } |
| | |
| | | "wms/models" |
| | | "wms/pkg/logx" |
| | | "wms/request" |
| | | "wms/utils" |
| | | ) |
| | | |
| | | type WarehouseMonthFormsService struct{} |
| | |
| | | f.SetColWidth("Sheet1", "A", "F", 30) |
| | | f.SetColWidth("Sheet1", "G", getColumnAlphabet(headerLen), 15) |
| | | |
| | | inputStart := 7 |
| | | outputStart := 7 + len(inputTypes) |
| | | inputStart := 6 |
| | | outputStart := 6 + len(inputTypes) |
| | | for i, v := range dataList { |
| | | column := strconv.Itoa(i + 3) |
| | | f.SetCellValue("Sheet1", "A"+column, v.ProductId) |
| | |
| | | columnStr := strconv.Itoa(column) |
| | | sum := slf.SumItems(items) |
| | | detailMap := models.WarehouseStatsItemMap(items) |
| | | for k := range detailMap { |
| | | if k == "" { |
| | | detailMap["其他"] = detailMap[k] |
| | | delete(detailMap, k) |
| | | } |
| | | } |
| | | |
| | | for i := 0; i < len(dealerTypes); i++ { |
| | | var amount decimal.Decimal |
| | |
| | | } |
| | | productMap := models.MaterialMap(products) |
| | | |
| | | beginTime, endTime := utils.GetLastMonthPeriod() |
| | | //按配置取开始时间和结束时间 |
| | | beginTime, endTime, err := NewSystemConfigService().GetInventoryCutOffTime() |
| | | if err != nil { |
| | | logx.Errorf("MonthStats GetCurrentStats get GetInventoryCutOffTime err:%v", err) |
| | | return |
| | | } |
| | | inputMap, err := GetStatsMulti(beginTime, endTime, constvar.BaseOperationTypeIncoming, warehouseId) |
| | | if err != nil { |
| | | logx.Errorf("MonthStats GetStatsByOperationType input err:%v", err) |
| | |
| | | SalePrice: product.SalePrice, |
| | | EndAmount: amount, |
| | | InputAmount: SumMapAmount(inputMap[productId]), |
| | | InputItems: GetDealerItems(inputMap[productId]), |
| | | InputItems: GetDealerItems(inputMap[productId], models.MonthStatsItemsTypeInput), |
| | | OutputAmount: SumMapAmount(outputMap[productId]), |
| | | OutputItems: GetDealerItems(outputMap[productId]), |
| | | OutputItems: GetDealerItems(outputMap[productId], models.MonthStatsItemsTypeOutput), |
| | | Date: date, |
| | | } |
| | | statRecords = append(statRecords, &record) |
| | |
| | | } |
| | | |
| | | func GetStatsMulti(beginTime, endTime time.Time, operationType constvar.BaseOperationType, warehouseId int) (m map[string]map[string]decimal.Decimal, err error) { |
| | | m = make(map[string]map[string]decimal.Decimal) |
| | | operationIds, err := models.NewOperationSearch().SetBaseOperationType(operationType). |
| | | SetFields("id").SetTimeBetween(beginTime, endTime). |
| | | SetWarehouseId(warehouseId). |
| | | FindIds() |
| | | if err != nil { |
| | | return |
| | | } |
| | | if len(operationIds) == 0 { |
| | | return |
| | | } |
| | | groupSumList, err := models.NewOperationDetailsSearch().SetOperationIds(operationIds). |
| | |
| | | return |
| | | } |
| | | |
| | | func GetDealerItems(m map[string]decimal.Decimal) (items []*models.WarehouseStatsItems) { |
| | | func GetDealerItems(m map[string]decimal.Decimal, tp models.MonthStatsItemsType) (items []*models.WarehouseStatsItems) { |
| | | for k, v := range m { |
| | | name := k |
| | | if name == "" { |
| | | name = "其他" |
| | | } |
| | | items = append(items, &models.WarehouseStatsItems{ |
| | | Type: tp, |
| | | Name: name, |
| | | Amount: v, |
| | | }) |
| | |
| | | } |
| | | |
| | | for _, record := range statsRecords { |
| | | if len(record.InputItems) == 0 { |
| | | continue |
| | | } |
| | | record.BeginAmount = record.EndAmount |
| | | err = models.WithTransaction(func(db *gorm.DB) error { |
| | | err = models.NewWarehouseMonthStatsSearch().SetOrm(db).Create(record) |