From fe794b385cc1fe28cb6d0731664a3023199843ac Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期一, 01 七月 2024 21:21:56 +0800
Subject: [PATCH] 增加月度统计出入库按类型汇总报表查询接口

---
 models/month_stats.go                  |    2 
 request/report_forms_request.go        |    5 
 controllers/report_forms_controller.go |   68 ++++++
 models/warehouse_month_stats.go        |  289 ++++++++++++++++++++++++++++
 models/operation.go                    |    9 
 models/operation_details.go            |   18 +
 router/router.go                       |    2 
 service/warehouse_month_forms.go       |  151 +++++++++++++++
 8 files changed, 541 insertions(+), 3 deletions(-)

diff --git a/controllers/report_forms_controller.go b/controllers/report_forms_controller.go
index 660ebee..49e8fca 100644
--- a/controllers/report_forms_controller.go
+++ b/controllers/report_forms_controller.go
@@ -437,3 +437,71 @@
 	task.MonthStats()
 	util.ResponseFormat(c, code.Success, nil)
 }
+
+// WarehouseMonthStats
+// @Tags      鎶ヨ〃
+// @Summary   浠撳簱鏈堝害缁熻搴撳瓨鎶ヨ〃
+// @Produce   application/json
+// @Param     object  body  request.GetMonthStats true  "鏌ヨ鍙傛暟"
+// @Param     Authorization	header string true "token"
+// @Success   200 {object} util.ResponseList{data=[]models.MonthStats}	"鎴愬姛"
+// @Router    /api-wms/v1/forms/warehouseMonthStats [post]
+func (slf ReportFormsController) WarehouseMonthStats(c *gin.Context) {
+	var params request.GetMonthStats
+	if err := c.BindJSON(&params); err != nil {
+		util.ResponseFormat(c, code.RequestParamError, "鍙傛暟瑙f瀽澶辫触锛屾暟鎹被鍨嬮敊璇�")
+		return
+	}
+
+	if params.WarehouseID == 0 {
+		util.ResponseFormat(c, code.RequestParamError, "浠撳簱ID鍙傛暟缂哄け")
+		return
+	}
+
+	monthFormsService := service.NewWarehouseMonthFormsService()
+	total, err := monthFormsService.Count(params)
+	if err != nil {
+		logx.Errorf("MonthStats count err:%v", err)
+		util.ResponseFormat(c, code.InternalError, "鏌ヨ鎬绘暟澶辫触")
+		return
+	}
+
+	result, err := monthFormsService.Query(params)
+	if err != nil {
+		logx.Errorf("MonthStats query err:%v", err)
+		util.ResponseFormat(c, code.InternalError, "鏌ヨ澶辫触")
+		return
+	}
+
+	now := time.Now().Local()
+	today := now.Day()
+	nowMonth := now.Format("2006-01")
+
+	day, dateStr, _ := service.NewSystemConfigService().GetInventoryCutOffPoint()
+	if nowMonth == params.Date && today < day || today == day && now.Format("15:04") < dateStr { //鏈湀鏈嚦缁撶畻鏃堕棿鐐�
+		productIds := make([]string, 0, len(result))
+		for _, item := range result {
+			productIds = append(productIds, item.ProductId)
+		}
+		statsRecords, err := service.GetCurrentWarehouseStats(params.Date, params.WarehouseID, productIds)
+		if err != nil {
+			util.ResponseFormat(c, code.InternalError, "鍐呴儴閿欒")
+			return
+		}
+		statsMap := models.WarehouseMonthStatsMap(statsRecords)
+		for k, v := range result {
+			if statsMap[v.ProductId] == nil {
+				continue
+			}
+
+			result[k].OutputAmount = statsMap[v.ProductId].OutputAmount
+			result[k].EndAmount = statsMap[v.ProductId].EndAmount
+			result[k].InputAmount = statsMap[v.ProductId].InputAmount
+			result[k].InputItems = statsMap[v.ProductId].InputItems
+			result[k].OutputItems = statsMap[v.ProductId].OutputItems
+		}
+
+	}
+
+	util.ResponseFormatList(c, code.Success, result, int(total))
+}
diff --git a/models/month_stats.go b/models/month_stats.go
index 64e1111..f86026f 100644
--- a/models/month_stats.go
+++ b/models/month_stats.go
@@ -9,7 +9,7 @@
 )
 
 type (
-	// MonthStats 绉诲姩鍘嗗彶
+	// MonthStats 鏈堝害缁熻
 	MonthStats struct {
 		WmsModel
 		Id          int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
diff --git a/models/operation.go b/models/operation.go
index 740659d..826208d 100644
--- a/models/operation.go
+++ b/models/operation.go
@@ -196,6 +196,11 @@
 	return slf
 }
 
+func (slf *OperationSearch) SetWarehouseId(warehouseId int) *OperationSearch {
+	slf.WarehouseId = warehouseId
+	return slf
+}
+
 func (slf *OperationSearch) build() *gorm.DB {
 	var db = slf.Orm.Model(&Operation{})
 
@@ -277,6 +282,10 @@
 		db = db.Where("inventory_dealer_type in (?)", slf.InventoryDealerTypeIds)
 	}
 
+	if slf.WarehouseId != 0 {
+		db = db.Where("warehouse_id = ?", slf.WarehouseId)
+	}
+
 	return db
 }
 
diff --git a/models/operation_details.go b/models/operation_details.go
index 16f65f4..8269f76 100644
--- a/models/operation_details.go
+++ b/models/operation_details.go
@@ -29,6 +29,7 @@
 		AuxiliaryUnit    string          `json:"auxiliaryUnit" gorm:"type:varchar(191);comment:杈呭姪鍗曚綅"`
 		Remark           string          `gorm:"type:varchar(1024);comment:澶囨敞" json:"remark"`
 		IsInternalOutput bool            `json:"isInternalOutput"` //鏄惁璋冩嫧浜х敓鐨勫嚭搴�
+		DealerType       string          `json:"dealerType"`       //鍑哄叆搴撶被鍨�
 
 		Cost      decimal.Decimal `json:"cost" `      //鎴愭湰鍗曚环
 		SalePrice decimal.Decimal `json:"salePrice" ` //閿�鍞崟浠�
@@ -312,3 +313,20 @@
 	}
 	return result, nil
 }
+
+type GroupByDealerTypeWarehouse struct {
+	DealerType string
+	ProductID  string
+	Sum        decimal.Decimal
+}
+
+func (slf *OperationDetailsSearch) GroupMultiSumAmount() ([]*GroupByDealerTypeWarehouse, error) {
+	var (
+		db     = slf.build()
+		result = make([]*GroupByDealerTypeWarehouse, 0)
+	)
+	if err := db.Select("sum(amount) as sum, dealer_type, product_id").Group("product_id, dealer_type").Scan(&result).Error; err != nil {
+		return nil, fmt.Errorf("select group err: %v", err)
+	}
+	return result, nil
+}
diff --git a/models/warehouse_month_stats.go b/models/warehouse_month_stats.go
new file mode 100644
index 0000000..72f494c
--- /dev/null
+++ b/models/warehouse_month_stats.go
@@ -0,0 +1,289 @@
+package models
+
+import (
+	"fmt"
+	"github.com/shopspring/decimal"
+	"gorm.io/gorm"
+	"wms/pkg/mysqlx"
+)
+
+type (
+	// WarehouseMonthStats 鎸変粨搴撹繘琛屾湀搴︾粺璁�
+	WarehouseMonthStats struct {
+		WmsModel
+		Id          int             `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		WarehouseId int             `json:"warehouseId" gorm:"type:int;not null;default:0"`             //浠撳簱ID
+		ProductId   string          `json:"productId" gorm:"type:varchar(255);not null;comment:浜у搧id"`   //浜у搧id
+		ProductName string          `json:"productName" gorm:"type:varchar(255);not null;comment:浜у搧鍚嶇О"` //浜у搧鍚嶇О
+		Unit        string          `json:"unit" gorm:"type:char(10);not null;comment:鍗曚綅"`              //鍗曚綅
+		SalePrice   decimal.Decimal `gorm:"type:decimal(35,18);comment:閿�鍞崟浠�" json:"salePrice"`          //閿�鍞崟浠�
+
+		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:"inputMoreUnitsArr"`                                          //鍏ュ簱鏄庣粏
+
+		OutputAmount decimal.Decimal        `json:"outputAmount" gorm:"type:decimal(30,10);not null;comment:鏁伴噺"` //鍑哄簱鏁伴噺
+		OutputItems  []*WarehouseStatsItems `json:"outputMoreUnitsArr"`                                          //鍑哄簱鏄庣粏
+
+		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;"`       //鏁伴噺
+	}
+
+	WarehouseMonthStatsSearch struct {
+		WarehouseMonthStats
+		Order    string
+		PageNum  int
+		PageSize int
+		Keyword  string
+		Orm      *gorm.DB
+		Preload  bool
+		Fields   string
+	}
+)
+
+func (slf *WarehouseMonthStats) TableName() string {
+	return "wms_month_stats"
+}
+
+func NewWarehouseMonthStatsSearch() *WarehouseMonthStatsSearch {
+	return &WarehouseMonthStatsSearch{Orm: mysqlx.GetDB()}
+}
+
+func (slf *WarehouseMonthStatsSearch) SetOrm(tx *gorm.DB) *WarehouseMonthStatsSearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *WarehouseMonthStatsSearch) SetPage(page, size int) *WarehouseMonthStatsSearch {
+	slf.PageNum, slf.PageSize = page, size
+	return slf
+}
+
+func (slf *WarehouseMonthStatsSearch) SetOrder(order string) *WarehouseMonthStatsSearch {
+	slf.Order = order
+	return slf
+}
+
+func (slf *WarehouseMonthStatsSearch) SetID(id int) *WarehouseMonthStatsSearch {
+	slf.Id = id
+	return slf
+}
+
+func (slf *WarehouseMonthStatsSearch) SetKeyword(keyword string) *WarehouseMonthStatsSearch {
+	slf.Keyword = keyword
+	return slf
+}
+
+func (slf *WarehouseMonthStatsSearch) SetPreload(preload bool) *WarehouseMonthStatsSearch {
+	slf.Preload = preload
+	return slf
+}
+
+func (slf *WarehouseMonthStatsSearch) SetDate(date string) *WarehouseMonthStatsSearch {
+	slf.Date = date
+	return slf
+}
+
+func (slf *WarehouseMonthStatsSearch) SetFields(fields string) *WarehouseMonthStatsSearch {
+	slf.Fields = fields
+	return slf
+}
+
+func (slf *WarehouseMonthStatsSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&WarehouseMonthStats{})
+
+	if slf.Id != 0 {
+		db = db.Where("id = ?", slf.Id)
+	}
+
+	if slf.Order != "" {
+		db = db.Order(slf.Order)
+	}
+
+	if slf.Keyword != "" {
+		kw := fmt.Sprintf("%%%v%%", slf.Keyword)
+		db = db.Where("product_id like ? or product_name like ?", kw, kw)
+	}
+
+	if slf.Date != "" {
+		db = db.Where("date = ?", slf.Date)
+	}
+
+	if slf.Fields != "" {
+		db = db.Select(slf.Fields)
+	}
+
+	return db
+}
+
+// Create 鍗曟潯鎻掑叆
+func (slf *WarehouseMonthStatsSearch) Create(record *WarehouseMonthStats) error {
+	var db = slf.build()
+
+	if err := db.Create(record).Error; err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// CreateBatch 鎵归噺鎻掑叆
+func (slf *WarehouseMonthStatsSearch) CreateBatch(records []*WarehouseMonthStats) error {
+	var db = slf.build()
+
+	if err := db.Create(&records).Error; err != nil {
+		return fmt.Errorf("create batch err: %v, records: %+v", err, records)
+	}
+
+	return nil
+}
+
+func (slf *WarehouseMonthStatsSearch) Update(record *WarehouseMonthStats) error {
+	var db = slf.build()
+
+	if err := db.Omit("CreatedAt").Updates(record).Error; err != nil {
+		return fmt.Errorf("save err: %v, record: %+v", err, record)
+	}
+
+	return nil
+}
+
+func (slf *WarehouseMonthStatsSearch) UpdateByMap(upMap map[string]interface{}) error {
+	var (
+		db = slf.build()
+	)
+
+	if err := db.Updates(upMap).Error; err != nil {
+		return fmt.Errorf("update by map err: %v, upMap: %+v", err, upMap)
+	}
+
+	return nil
+}
+
+func (slf *WarehouseMonthStatsSearch) UpdateByQuery(query string, args []interface{}, upMap map[string]interface{}) error {
+	var (
+		db = slf.Orm.Table(slf.TableName()).Where(query, args...)
+	)
+
+	if err := db.Updates(upMap).Error; err != nil {
+		return fmt.Errorf("update by query err: %v, query: %s, args: %+v, upMap: %+v", err, query, args, upMap)
+	}
+
+	return nil
+}
+
+func (slf *WarehouseMonthStatsSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&WarehouseMonthStats{}).Error
+}
+
+func (slf *WarehouseMonthStatsSearch) First() (*WarehouseMonthStats, error) {
+	var (
+		record = new(WarehouseMonthStats)
+		db     = slf.build()
+	)
+
+	if err := db.First(record).Error; err != nil {
+		return record, err
+	}
+
+	return record, nil
+}
+
+func (slf *WarehouseMonthStatsSearch) Find() ([]*WarehouseMonthStats, int64, error) {
+	var (
+		records = make([]*WarehouseMonthStats, 0)
+		total   int64
+		db      = slf.build()
+	)
+
+	if err := db.Count(&total).Error; err != nil {
+		return records, total, fmt.Errorf("find count err: %v", err)
+	}
+	if slf.PageNum*slf.PageSize > 0 {
+		db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize)
+	}
+	if err := db.Find(&records).Error; err != nil {
+		return records, total, fmt.Errorf("find records err: %v", err)
+	}
+
+	return records, total, nil
+}
+
+func (slf *WarehouseMonthStatsSearch) FindNotTotal() ([]*WarehouseMonthStats, error) {
+	var (
+		records = make([]*WarehouseMonthStats, 0)
+		db      = slf.build()
+	)
+
+	if slf.PageNum*slf.PageSize > 0 {
+		db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize)
+	}
+	if err := db.Find(&records).Error; err != nil {
+		return records, fmt.Errorf("find records err: %v", err)
+	}
+
+	return records, nil
+}
+
+// FindByQuery 鎸囧畾鏉′欢鏌ヨ.
+func (slf *WarehouseMonthStatsSearch) FindByQuery(query string, args []interface{}) ([]*WarehouseMonthStats, int64, error) {
+	var (
+		records = make([]*WarehouseMonthStats, 0)
+		total   int64
+		db      = slf.Orm.Table(slf.TableName()).Where(query, args...)
+	)
+
+	if err := db.Count(&total).Error; err != nil {
+		return records, total, fmt.Errorf("find by query count err: %v", err)
+	}
+	if slf.PageNum*slf.PageSize > 0 {
+		db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize)
+	}
+	if err := db.Find(&records).Error; err != nil {
+		return records, total, fmt.Errorf("find by query records err: %v, query: %s, args: %+v", err, query, args)
+	}
+
+	return records, total, nil
+}
+
+// FindByQueryNotTotal 鎸囧畾鏉′欢鏌ヨ&涓嶆煡璇㈡�绘潯鏁�.
+func (slf *WarehouseMonthStatsSearch) FindByQueryNotTotal(query string, args []interface{}) ([]*WarehouseMonthStats, error) {
+	var (
+		records = make([]*WarehouseMonthStats, 0)
+		db      = slf.Orm.Table(slf.TableName()).Where(query, args...)
+	)
+
+	if slf.PageNum*slf.PageSize > 0 {
+		db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize)
+	}
+	if err := db.Find(&records).Error; err != nil {
+		return records, fmt.Errorf("find by query records err: %v, query: %s, args: %+v", err, query, args)
+	}
+
+	return records, nil
+}
+
+func WarehouseMonthStatsMap(records []*WarehouseMonthStats) (m map[string]*WarehouseMonthStats) {
+	m = make(map[string]*WarehouseMonthStats, len(records))
+	for _, record := range records {
+		m[record.ProductId] = record
+	}
+	return m
+}
+
+func (slf *WarehouseMonthStatsSearch) Count() (int64, error) {
+	var (
+		total int64
+		db    = slf.build()
+	)
+	err := db.Count(&total).Error
+	return total, err
+}
diff --git a/request/report_forms_request.go b/request/report_forms_request.go
index 71b4c81..ca92133 100644
--- a/request/report_forms_request.go
+++ b/request/report_forms_request.go
@@ -28,8 +28,9 @@
 
 type GetMonthStats struct {
 	PageInfo
-	Keyword string `json:"keyword"`
-	Date    string `json:"date"`
+	Keyword     string `json:"keyword"`
+	Date        string `json:"date"`
+	WarehouseID int    `json:"warehouseID"`
 }
 
 type DoMonthStats struct {
diff --git a/router/router.go b/router/router.go
index b76899e..f46070c 100644
--- a/router/router.go
+++ b/router/router.go
@@ -178,6 +178,8 @@
 		reportFormsAPI.POST("monthStats", reportFormsController.MonthStats)                         //鑾峰彇鏈堝害缁熻鎶ヨ〃
 		reportFormsAPI.POST("downloadMonthStats", reportFormsController.DownloadMonthStats)         //涓嬭浇鏈堝害缁熻鎶ヨ〃
 		reportFormsAPI.POST("doMonthStats", reportFormsController.DoMonthStats)                     //鎵嬪姩璺戞湀搴︾粺璁″簱瀛樻姤琛�
+
+		reportFormsAPI.POST("warehouseMonthStats", reportFormsController.WarehouseMonthStats) //鎸変粨搴撹幏鍙栨湀搴︾粺璁℃姤琛�
 	}
 
 	//閲嶈璐ц鍒�
diff --git a/service/warehouse_month_forms.go b/service/warehouse_month_forms.go
new file mode 100644
index 0000000..1885a16
--- /dev/null
+++ b/service/warehouse_month_forms.go
@@ -0,0 +1,151 @@
+package service
+
+import (
+	"github.com/shopspring/decimal"
+	"time"
+	"wms/constvar"
+	"wms/models"
+	"wms/pkg/logx"
+	"wms/request"
+	"wms/utils"
+)
+
+type WarehouseMonthFormsService struct{}
+
+func NewWarehouseMonthFormsService() *WarehouseMonthFormsService {
+	return &WarehouseMonthFormsService{}
+}
+
+func (slf *WarehouseMonthFormsService) Query(params request.GetMonthStats) (result []*models.WarehouseMonthStats, err error) {
+	search := slf.BuildSearch(params)
+	search = search.SetPage(params.Page, params.PageSize)
+	return search.FindNotTotal()
+}
+
+func (slf *WarehouseMonthFormsService) BuildSearch(params request.GetMonthStats) (search *models.WarehouseMonthStatsSearch) {
+	search = models.NewWarehouseMonthStatsSearch().SetKeyword(params.Keyword).SetDate(params.Date)
+	return search
+}
+
+func (slf *WarehouseMonthFormsService) Count(params request.GetMonthStats) (total int64, err error) {
+	search := slf.BuildSearch(params)
+	return search.Count()
+}
+
+func (slf *WarehouseMonthFormsService) FetchAll(params request.GetMonthStats) (list []*models.WarehouseMonthStats, err error) {
+	total, err := slf.Count(params)
+	if err != nil {
+		return nil, err
+	}
+	list = make([]*models.WarehouseMonthStats, 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 GetCurrentWarehouseStats(date string, warehouseId int, productIds []string) (statRecords []*models.WarehouseMonthStats, 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 := utils.GetLastMonthPeriod()
+	inputMap, err := GetStatsMulti(beginTime, endTime, constvar.BaseOperationTypeIncoming, warehouseId)
+	if err != nil {
+		logx.Errorf("MonthStats GetStatsByOperationType input err:%v", err)
+		return
+	}
+
+	outputMap, err := GetStatsMulti(beginTime, endTime, constvar.BaseOperationTypeOutgoing, warehouseId)
+	if err != nil {
+		logx.Errorf("MonthStats GetStatsByOperationType output err:%v", err)
+		return
+	}
+
+	for _, groupSum := range groupSumList {
+		productId := groupSum.Class
+		if productMap[productId] == nil {
+			continue
+		}
+		product := productMap[productId]
+
+		amount := groupSum.Sum
+		record := models.WarehouseMonthStats{
+			WarehouseId:  warehouseId,
+			ProductId:    productId,
+			ProductName:  product.Name,
+			Unit:         product.Unit,
+			SalePrice:    product.SalePrice,
+			EndAmount:    amount,
+			InputAmount:  SumMapAmount(inputMap[productId]),
+			InputItems:   GetDealerItems(inputMap[productId]),
+			OutputAmount: SumMapAmount(outputMap[productId]),
+			OutputItems:  GetDealerItems(outputMap[productId]),
+			Date:         date,
+		}
+		statRecords = append(statRecords, &record)
+	}
+
+	return
+}
+
+func GetStatsMulti(beginTime, endTime time.Time, operationType constvar.BaseOperationType, warehouseId int) (m map[string]map[string]decimal.Decimal, err error) {
+	operationIds, err := models.NewOperationSearch().SetBaseOperationType(operationType).
+		SetFields("id").SetTimeBetween(beginTime, endTime).
+		SetWarehouseId(warehouseId).
+		FindIds()
+	if err != nil {
+		return
+	}
+	groupSumList, err := models.NewOperationDetailsSearch().SetOperationIds(operationIds).
+		SetFields("product_id, dealer_type, amount").
+		GroupMultiSumAmount()
+	if err != nil {
+		return
+	}
+	m = make(map[string]map[string]decimal.Decimal)
+	for _, v := range groupSumList {
+		if m[v.ProductID] == nil {
+			m[v.ProductID] = make(map[string]decimal.Decimal)
+		}
+		m[v.ProductID][v.DealerType] = v.Sum
+	}
+	return
+}
+
+func SumMapAmount(m map[string]decimal.Decimal) (sum decimal.Decimal) {
+	for _, v := range m {
+		sum = sum.Add(v)
+	}
+	return
+}
+
+func GetDealerItems(m map[string]decimal.Decimal) (items []*models.WarehouseStatsItems) {
+	for k, v := range m {
+		items = append(items, &models.WarehouseStatsItems{
+			Name:   k,
+			Amount: v,
+		})
+	}
+	return
+}

--
Gitblit v1.8.0