package task
|
|
import (
|
"encoding/json"
|
"fmt"
|
"github.com/shopspring/decimal"
|
"time"
|
"wms/constvar"
|
"wms/models"
|
"wms/pkg/logx"
|
"wms/service"
|
)
|
|
func MonthStats() {
|
//加锁,只需要一个进程运行此任务
|
var (
|
lockName = "monthStats"
|
serviceID = "wms"
|
)
|
err := models.NewLockSearch().AcquireLock(lockName, serviceID)
|
if err != nil {
|
logx.Errorf("MonthStats AcquireLock err:%v", err)
|
return
|
}
|
defer func() {
|
err := models.NewLockSearch().ReleaseLock(lockName, serviceID)
|
if err != nil {
|
logx.Errorf("MonthStats ReleaseLock err:%v", err)
|
}
|
}()
|
|
date := time.Now().Format("2006-01")
|
lastDate := time.Now().AddDate(0, -1, 0).Format("2006-01")
|
|
oldRecords, err := models.NewMonthStatsSearch().SetDate(lastDate).SetFields("id, product_id").FindNotTotal()
|
if err != nil {
|
logx.Errorf("MonthStats get last date record err:%v", err)
|
return
|
}
|
oldRecordsMap := models.MonthStatsMap(oldRecords)
|
|
//本月期初数量/上月结余数量
|
groupSumList, err := models.NewLocationProductAmountSearch().GroupSum("product_id", "amount")
|
|
productIds := make([]string, 0, len(groupSumList))
|
|
for _, groupSum := range groupSumList {
|
productIds = append(productIds, groupSum.Class)
|
}
|
products, err := models.NewMaterialSearch().SetFields("id, name, unit, weight, more_unit, more_unit_value").SetIDs(productIds).FindNotTotal()
|
if err != nil {
|
logx.Errorf("MonthStats get products err:%v", err)
|
return
|
}
|
productMap := models.MaterialMap(products)
|
|
beginTime, endTime := GetLastMonthPeriod()
|
inputMap, err := GetStatsByOperationType(beginTime, endTime, constvar.BaseOperationTypeIncoming)
|
if err != nil {
|
logx.Errorf("MonthStats GetStatsByOperationType input err:%v", err)
|
return
|
}
|
|
outputMap, err := GetStatsByOperationType(beginTime, endTime, constvar.BaseOperationTypeOutgoing)
|
if err != nil {
|
logx.Errorf("MonthStats GetStatsByOperationType output err:%v", err)
|
return
|
}
|
var record models.MonthStats
|
for _, groupSum := range groupSumList {
|
productId := groupSum.Class
|
if productMap[productId] == nil {
|
continue
|
}
|
product := productMap[productId]
|
amount := groupSum.Sum
|
record = models.MonthStats{
|
ProductId: productId,
|
ProductName: product.Name,
|
BeginAmount: amount,
|
Unit: product.Unit,
|
Weight: product.Weight.Mul(amount),
|
Date: date,
|
}
|
|
var (
|
moreUnits string
|
inputMoreUnits string
|
outputMoreUnits string
|
)
|
if *product.MoreUnit {
|
moreValueArr := make([]models.UnitItems, 0, len(product.MoreUnitList))
|
inputMoreValueArr := make([]models.UnitItems, 0, len(product.MoreUnitList))
|
outputMoreValueArr := make([]models.UnitItems, 0, len(product.MoreUnitList))
|
for _, unitItem := range product.MoreUnitList {
|
moreValueArr = append(moreValueArr, models.UnitItems{
|
Amount: amount.Mul(unitItem.Amount),
|
Unit: unitItem.Unit,
|
Floating: unitItem.Floating,
|
})
|
bys, _ := json.Marshal(moreValueArr)
|
moreUnits = string(bys)
|
|
if !inputMap[productId].IsZero() {
|
inputMoreValueArr = append(inputMoreValueArr, models.UnitItems{
|
Amount: inputMap[productId].Mul(unitItem.Amount),
|
Unit: unitItem.Unit,
|
Floating: unitItem.Floating,
|
})
|
bys, _ = json.Marshal(inputMoreValueArr)
|
inputMoreUnits = string(bys)
|
|
}
|
|
if !outputMap[productId].IsZero() {
|
outputMoreValueArr = append(outputMoreValueArr, models.UnitItems{
|
Amount: outputMap[productId].Mul(unitItem.Amount),
|
Unit: unitItem.Unit,
|
Floating: unitItem.Floating,
|
})
|
bys, _ = json.Marshal(outputMoreValueArr)
|
outputMoreUnits = string(bys)
|
|
}
|
}
|
}
|
|
record.BeginMoreUnits = moreUnits
|
err = models.NewMonthStatsSearch().Create(&record)
|
if err != nil {
|
logx.Errorf("NewMonthStatsSearch Create err:%v, record: %+v", err, record)
|
service.SendAlarm("月度统计创建本月失败", fmt.Sprintf("NewMonthStatsSearch Create err:%v, record: %+v", err, record))
|
}
|
|
if oldRecordsMap[productId] != nil && (!inputMap[productId].IsZero() || !outputMap[productId].IsZero()) {
|
record.InputAmount = inputMap[productId]
|
record.InputMoreUnits = inputMoreUnits
|
record.OutputAmount = outputMap[productId]
|
record.OutputMoreUnits = outputMoreUnits
|
m := map[string]interface{}{
|
"input_amount": inputMap[productId],
|
"input_more_units": inputMoreUnits,
|
"output_amount": outputMap[productId],
|
"output_more_units": outputMoreUnits,
|
"end_more_units": moreUnits,
|
"end_amount": amount,
|
}
|
err = models.NewMonthStatsSearch().SetID(oldRecordsMap[productId].Id).UpdateByMap(m)
|
if err != nil {
|
logx.Errorf("NewMonthStatsSearch UpdateByMap err:%v, id:%v, m:%+v", err, oldRecordsMap[productId].ID, m)
|
service.SendAlarm("月度统计更改上月失败", fmt.Sprintf("NewMonthStatsSearch Create err:%v, record: %+v", err, record))
|
}
|
}
|
}
|
return
|
}
|
|
func GetStatsByOperationType(beginTime, endTime time.Time, operationType constvar.BaseOperationType) (m map[string]decimal.Decimal, err error) {
|
operationIds, err := models.NewOperationSearch().SetBaseOperationType(operationType).SetFields("id").SetTimeBetween(beginTime, endTime).FindIds()
|
if err != nil {
|
return
|
}
|
groupSumList, err := models.NewOperationDetailsSearch().SetOperationIds(operationIds).SetFields("product_id, amount").GroupSum("product_id", "amount")
|
if err != nil {
|
return
|
}
|
m = make(map[string]decimal.Decimal, len(groupSumList))
|
for _, v := range groupSumList {
|
m[v.Class] = v.Sum
|
}
|
return
|
}
|
|
// GetLastMonthPeriod 返回上个月的月初时间和月末时间
|
func GetLastMonthPeriod() (time.Time, time.Time) {
|
// 获取当前时间
|
now := time.Now()
|
|
// 计算上个月的年份和月份
|
lastMonth := now.AddDate(0, -1, 0)
|
lastYear, lastMonthNum, _ := lastMonth.Date()
|
|
// 获取上个月的第一天的日期(即上个月月初)
|
firstDayOfLastMonth := time.Date(lastYear, lastMonthNum, 1, 0, 0, 0, 0, now.Location())
|
|
// 获取本月第一天的日期(即本月月初)
|
firstDayOfThisMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
|
|
// 上个月月末时间即为本月月初减去一秒
|
lastDayOfLastMonth := firstDayOfThisMonth.Add(-time.Second)
|
|
return firstDayOfLastMonth, lastDayOfLastMonth
|
}
|