package service
|
|
import (
|
"encoding/json"
|
"fmt"
|
"github.com/shopspring/decimal"
|
"github.com/xuri/excelize/v2"
|
"strconv"
|
"time"
|
"wms/constvar"
|
"wms/models"
|
"wms/pkg/logx"
|
"wms/request"
|
)
|
|
type MonthFormsService struct{}
|
|
func NewMonthFormsService() *MonthFormsService {
|
return &MonthFormsService{}
|
}
|
|
func (slf *MonthFormsService) Query(params request.GetMonthStats) (result []*models.MonthStats, err error) {
|
search := slf.BuildSearch(params)
|
search = search.SetPage(params.Page, params.PageSize)
|
return search.FindNotTotal()
|
}
|
|
func (slf *MonthFormsService) BuildSearch(params request.GetMonthStats) (search *models.MonthStatsSearch) {
|
search = models.NewMonthStatsSearch().SetKeyword(params.Keyword).SetDate(params.Date)
|
return search
|
}
|
|
func (slf *MonthFormsService) Count(params request.GetMonthStats) (total int64, err error) {
|
search := slf.BuildSearch(params)
|
return search.Count()
|
}
|
|
func (slf *MonthFormsService) FetchAll(params request.GetMonthStats) (list []*models.MonthStats, err error) {
|
total, err := slf.Count(params)
|
if err != nil {
|
return nil, err
|
}
|
list = make([]*models.MonthStats, 0, total)
|
params.PageSize = 500
|
page := 1
|
for {
|
params.Page = page
|
data, err := slf.Query(params)
|
if err != nil {
|
return nil, err
|
}
|
if len(data) == 0 {
|
break
|
}
|
list = append(list, data...)
|
page++
|
}
|
return
|
}
|
|
func (slf *MonthFormsService) Export(dataList []*models.MonthStats) (filename string, err error) {
|
// 创建一个新的 Excel 文件
|
f := excelize.NewFile()
|
|
if err != nil {
|
logx.Errorf("NewSheet err:%v", err)
|
return "", err
|
}
|
|
unitData, unitIndexMap := GetAllUnits()
|
unitLen := len(unitData)
|
|
// 自定义表头
|
headers := []interface{}{"产品编码", "产品名称", map[string][]string{"期初库存": unitData}, map[string][]string{"本月入库": unitData}, map[string][]string{"本月出库": unitData}, map[string][]string{"期末库存": unitData}}
|
lastColumnNumber, err := SetExcelHeaders(headers, f)
|
if err != nil {
|
return "", err
|
}
|
|
f.MergeCell("Sheet1", "A1", "A2") // 合并单元格
|
f.MergeCell("Sheet1", "B1", "B2") // 合并单元格
|
|
titleStyle, err := SetHeaderStyle(f)
|
if err != nil {
|
return "", err
|
}
|
|
lastColumn := getColumnAlphabet(lastColumnNumber)
|
f.SetCellStyle("Sheet1", "A1", lastColumn+"2", titleStyle)
|
// 设置列宽
|
f.SetColWidth("Sheet1", "A", "B", 30)
|
f.SetColWidth("Sheet1", "C", lastColumn, 15)
|
|
for i, v := range dataList {
|
row := strconv.Itoa(i + 3)
|
f.SetCellValue("Sheet1", "A"+row, v.ProductId)
|
f.SetCellValue("Sheet1", "B"+row, v.ProductName)
|
|
v.BeginMoreUnitsArr = append(v.BeginMoreUnitsArr, models.UnitItems{Amount: v.BeginAmount, Unit: v.Unit})
|
for _, v := range v.BeginMoreUnitsArr {
|
f.SetCellValue("Sheet1", getColumnAlphabet(3+unitIndexMap[v.Unit])+row, v.Amount)
|
}
|
|
v.InputMoreUnitsArr = append(v.InputMoreUnitsArr, models.UnitItems{Amount: v.InputAmount, Unit: v.Unit})
|
for _, v := range v.InputMoreUnitsArr {
|
f.SetCellValue("Sheet1", getColumnAlphabet(3+unitLen*1+unitIndexMap[v.Unit])+row, v.Amount)
|
}
|
|
v.OutputMoreUnitsArr = append(v.OutputMoreUnitsArr, models.UnitItems{Amount: v.OutputAmount, Unit: v.Unit})
|
for _, v := range v.OutputMoreUnitsArr {
|
f.SetCellValue("Sheet1", getColumnAlphabet(3+unitLen*2+unitIndexMap[v.Unit])+row, v.Amount)
|
}
|
|
v.EndMoreUnitsArr = append(v.EndMoreUnitsArr, models.UnitItems{Amount: v.EndAmount, Unit: v.Unit})
|
for _, v := range v.EndMoreUnitsArr {
|
f.SetCellValue("Sheet1", getColumnAlphabet(3+unitLen*3+unitIndexMap[v.Unit])+row, v.Amount)
|
}
|
}
|
|
fileName := fmt.Sprintf("月度统计报表%s.xlsx", time.Now().Format("2006-01-02-1504"))
|
if err := f.SaveAs(fileName); err != nil {
|
return fileName, err
|
}
|
|
return fileName, nil
|
}
|
|
func GetCurrentStats(date string, productIds []string) (statRecords []*models.MonthStats, err error) {
|
//本月期初数量/上月结余数量
|
groupSumList, err := models.NewLocationProductAmountSearch().SetProductIds(productIds).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 GetCurrentStats get products err:%v", err)
|
return
|
}
|
productMap := models.MaterialMap(products)
|
|
//按配置取开始时间和结束时间
|
beginTime, endTime, err := NewSystemConfigService().GetInventoryCutOffTime()
|
if err != nil {
|
logx.Errorf("MonthStats GetCurrentStats get GetInventoryCutOffTime err:%v", err)
|
return
|
}
|
inputMap, inputProductMoreUnit, err := GetStatsByOperationType(beginTime, endTime, productIds, constvar.BaseOperationTypeIncoming)
|
if err != nil {
|
logx.Errorf("MonthStats GetStatsByOperationType input err:%v", err)
|
return
|
}
|
|
outputMap, outputProductMoreUnit, err := GetStatsByOperationType(beginTime, endTime, productIds, constvar.BaseOperationTypeOutgoing)
|
if err != nil {
|
logx.Errorf("MonthStats GetStatsByOperationType output err:%v", err)
|
return
|
}
|
|
productMoreUnit, err := GetProductMoreUnitMap(productIds)
|
|
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,
|
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))
|
if !amount.IsZero() {
|
moreValueArr = productMoreUnit[productId]
|
}
|
if !inputMap[productId].IsZero() {
|
inputMoreValueArr = inputProductMoreUnit[productId]
|
}
|
|
if !outputMap[productId].IsZero() {
|
outputMoreValueArr = outputProductMoreUnit[productId]
|
}
|
bys, _ := json.Marshal(moreValueArr)
|
moreUnits = string(bys)
|
bys, _ = json.Marshal(inputMoreValueArr)
|
inputMoreUnits = string(bys)
|
bys, _ = json.Marshal(outputMoreValueArr)
|
outputMoreUnits = string(bys)
|
}
|
|
record.InputAmount = inputMap[productId]
|
record.InputMoreUnits = inputMoreUnits
|
record.OutputAmount = outputMap[productId]
|
record.OutputMoreUnits = outputMoreUnits
|
record.EndAmount = amount
|
record.EndMoreUnits = moreUnits
|
statRecords = append(statRecords, &record)
|
}
|
|
return
|
}
|
|
func GetStatsByOperationType(beginTime, endTime time.Time, productIds []string, operationType constvar.BaseOperationType) (m map[string]decimal.Decimal, productMoreUnit map[string][]models.UnitItems, err error) {
|
operationIds, err := models.NewOperationSearch().SetBaseOperationType(operationType).SetFields("id").SetTimeBetween(beginTime, endTime).FindIds()
|
if err != nil {
|
return
|
}
|
|
productMoreUnit = make(map[string][]models.UnitItems)
|
detailProducts, err := models.NewOperationDetailsSearch().
|
SetProductIds(productIds).SetOperationIds(operationIds).
|
SetFields("product_id, amount, more_unit_value").FindAll()
|
m = make(map[string]decimal.Decimal, 0)
|
if err != nil {
|
logx.Errorf("MonthStats GetMoreUnitRecords err:%v", err)
|
return
|
}
|
|
for _, v := range detailProducts {
|
m[v.ProductId] = m[v.ProductId].Add(v.Amount)
|
if v.MoreUnitValue == "" {
|
continue
|
}
|
if productMoreUnit[v.ProductId] == nil {
|
productMoreUnit[v.ProductId] = v.MoreUnitList
|
continue
|
}
|
productMoreUnit[v.ProductId] = AddMoreUnit(productMoreUnit[v.ProductId], v.MoreUnitList)
|
}
|
|
return
|
}
|
|
func GetProductMoreUnitMap(productIds []string) (m map[string][]models.UnitItems, err error) {
|
m = make(map[string][]models.UnitItems)
|
locAmountRecords, err := models.NewLocationProductAmountSearch().SetProductIds(productIds).
|
SetFields("product_id, more_unit_value").FindAll()
|
if err != nil {
|
logx.Errorf("MonthStats GetMoreUnitRecords err:%v", err)
|
return
|
}
|
|
for _, v := range locAmountRecords {
|
if v.MoreUnitValue == "" {
|
continue
|
}
|
if m[v.ProductId] == nil {
|
m[v.ProductId] = v.MoreUnitList
|
continue
|
}
|
m[v.ProductId] = AddMoreUnit(m[v.ProductId], v.MoreUnitList)
|
}
|
return
|
}
|