产品库存增加多单位存储,完成出入库操作时更改多单位剩余数量
| | |
| | | } |
| | | |
| | | // Finish |
| | | // deprecated |
| | | // |
| | | // @Tags 库存盘点 |
| | | // @Summary 应用、验证 |
| | |
| | | package models |
| | | |
| | | import ( |
| | | "encoding/json" |
| | | "fmt" |
| | | "github.com/shopspring/decimal" |
| | | "gorm.io/gorm" |
| | |
| | | ProductId string `json:"productId" gorm:"type:varchar(191);not null;comment:产品id"` //产品id |
| | | Product Material `json:"product" gorm:"foreignKey:ProductId;references:ID"` |
| | | Amount decimal.Decimal `json:"amount" gorm:"type:decimal(20,2);not null;comment:库存数量"` //库存数量 |
| | | CreateDate string `json:"createDate" gorm:"type:varchar(63);comment:日期"` //日期 |
| | | MoreUnitList []UnitItems `json:"amountMoreUnits" gorm:"-"` //在库数量多单位 |
| | | MoreUnitValue string `json:"-" gorm:"type:varchar(255);comment:多单位值"` |
| | | CreateDate string `json:"createDate" gorm:"type:varchar(63);comment:日期"` //日期 |
| | | } |
| | | |
| | | LocationProductAmountSearch struct { |
| | |
| | | return "wms_location_product_amount" |
| | | } |
| | | |
| | | func (slf *LocationProductAmount) AfterFind(tx *gorm.DB) (err error) { |
| | | if slf.MoreUnitValue != "" { |
| | | var arr []UnitItems |
| | | err := json.Unmarshal([]byte(slf.MoreUnitValue), &arr) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | slf.MoreUnitList = arr |
| | | } |
| | | |
| | | return |
| | | } |
| | | |
| | | func (slf *LocationProductAmount) BeforeCreate(tx *gorm.DB) (err error) { |
| | | if len(slf.MoreUnitList) != 0 { |
| | | items := make([]UnitItems, 0) |
| | | for k, item := range slf.MoreUnitList { |
| | | if item.Unit != "" && !item.Amount.IsZero() { |
| | | items = append(items, slf.MoreUnitList[k]) |
| | | } |
| | | } |
| | | |
| | | str, err := json.Marshal(items) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | slf.MoreUnitValue = string(str) |
| | | } |
| | | return |
| | | } |
| | | |
| | | func NewLocationProductAmountSearch() *LocationProductAmountSearch { |
| | | return &LocationProductAmountSearch{Orm: mysqlx.GetDB()} |
| | | } |
| | |
| | | locationProductAmountController := new(controllers.LocationProductAmountController) |
| | | locationProductAmountAPI := r.Group(urlPrefix + "/locationProductAmount") |
| | | { |
| | | locationProductAmountAPI.POST("add", locationProductAmountController.Add) //添加库存盘点信息 |
| | | locationProductAmountAPI.POST("list", locationProductAmountController.List) //查看库存盘点列表 |
| | | locationProductAmountAPI.POST("locationProductList", locationProductAmountController.LocationProductList) //查看产品库存列表 |
| | | locationProductAmountAPI.POST("update", locationProductAmountController.Update) //修改库存盘点信息 |
| | | locationProductAmountAPI.POST("finish", locationProductAmountController.Finish) //应用、验证库存盘点信息 |
| | | locationProductAmountAPI.POST("add", locationProductAmountController.Add) //添加库存盘点信息 |
| | | locationProductAmountAPI.POST("list", locationProductAmountController.List) //查看库存盘点列表 |
| | | locationProductAmountAPI.POST("locationProductList", locationProductAmountController.LocationProductList) //查看产品库存列表 |
| | | locationProductAmountAPI.POST("update", locationProductAmountController.Update) //修改库存盘点信息 |
| | | //locationProductAmountAPI.POST("finish", locationProductAmountController.Finish) //应用、验证库存盘点信息 |
| | | locationProductAmountAPI.POST("getRuleList", locationProductAmountController.GetRuleList) //获取上架规则 |
| | | locationProductAmountAPI.POST("getLocationProductAmount", locationProductAmountController.GetLocationProductAmount) //获取位置产品信息 |
| | | } |
| | |
| | | return moreValueArr |
| | | } |
| | | |
| | | func AddMoreUnit(units []models.UnitItems, units2 []models.UnitItems) []models.UnitItems { |
| | | moreValueArr := make([]models.UnitItems, 0, len(units)) |
| | | for _, unitItem1 := range units { |
| | | for _, unitItem2 := range units2 { |
| | | if unitItem1.Unit == unitItem2.Unit { |
| | | moreValueArr = append(moreValueArr, models.UnitItems{ |
| | | Amount: unitItem1.Amount.Add(unitItem2.Amount), |
| | | Unit: unitItem1.Unit, |
| | | Floating: unitItem1.Floating, |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | return moreValueArr |
| | | } |
| | | |
| | | // MoreUnitIsEnough 多单位库存是否足够 |
| | | func MoreUnitIsEnough(units []models.UnitItems, units2 []models.UnitItems) bool { |
| | | for _, unitItem1 := range units { |
| | | for _, unitItem2 := range units2 { |
| | | if unitItem1.Amount.LessThan(unitItem2.Amount) { |
| | | return false |
| | | } |
| | | } |
| | | } |
| | | return true |
| | | } |
| | | |
| | | func SubMoreUnit(units []models.UnitItems, units2 []models.UnitItems) []models.UnitItems { |
| | | moreValueArr := make([]models.UnitItems, 0, len(units)) |
| | | for _, unitItem1 := range units { |
| | | for _, unitItem2 := range units2 { |
| | | if unitItem1.Unit == unitItem2.Unit { |
| | | moreValueArr = append(moreValueArr, models.UnitItems{ |
| | | Amount: unitItem1.Amount.Sub(unitItem2.Amount), |
| | | Unit: unitItem1.Unit, |
| | | Floating: unitItem1.Floating, |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | return moreValueArr |
| | | } |
| | | |
| | | func FillMoreUnitToExcel(amount decimal.Decimal, units []models.UnitItems, startIndex int, column int, f *excelize.File) { |
| | | columnStr := strconv.Itoa(column) |
| | | for _, v := range units { |
| | |
| | | var details []*models.OperationDetails |
| | | for k, v := range listDetails { |
| | | listDetails[k].Product.Amount = listDetails[k].Product.Amount.Add(v.Amount) |
| | | listDetails[k].Product.MoreUnitList = AddMoreUnit(listDetails[k].Product.MoreUnitList, v.MoreUnitList) |
| | | if err := tx.Save(&listDetails[k].Product).Error; err != nil { |
| | | return err |
| | | } |
| | |
| | | detail := &models.OperationDetails{ |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | | MoreUnitList: v.MoreUnitList, |
| | | FromLocationID: roleProduct.AreaId, |
| | | ToLocationID: roleProduct.LocationId, |
| | | } |
| | |
| | | |
| | | if locAmount, aok := mapLocAmount[strconv.Itoa(roleProduct.LocationId)+v.ProductId]; aok { |
| | | locAmount.Amount = locAmount.Amount.Add(v.Amount) |
| | | locAmount.MoreUnitList = AddMoreUnit(locAmount.MoreUnitList, v.MoreUnitList) |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(int(locAmount.ID)).Save(locAmount); err != nil { |
| | | return err |
| | | } |
| | |
| | | ProductCategoryID: v.Product.CategoryId, |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | | MoreUnitList: v.MoreUnitList, |
| | | CreateDate: time.Now().Format("2006-01-02 15:04:05"), |
| | | WarehouseId: operation.WarehouseId, |
| | | }); err != nil { |
| | |
| | | detail := &models.OperationDetails{ |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | | MoreUnitList: v.MoreUnitList, |
| | | FromLocationID: roleCategory.AreaId, |
| | | ToLocationID: roleCategory.LocationId, |
| | | } |
| | |
| | | |
| | | if locAmount, aok := mapLocAmount[strconv.Itoa(roleCategory.LocationId)+v.ProductId]; aok { |
| | | locAmount.Amount = locAmount.Amount.Add(v.Amount) |
| | | locAmount.MoreUnitList = AddMoreUnit(locAmount.MoreUnitList, v.MoreUnitList) |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(int(locAmount.ID)).Save(locAmount); err != nil { |
| | | return err |
| | | } |
| | |
| | | ProductCategoryID: v.Product.CategoryId, |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | | MoreUnitList: v.MoreUnitList, |
| | | CreateDate: time.Now().Format("2006-01-02 15:04:05"), |
| | | WarehouseId: operation.WarehouseId, |
| | | }); err != nil { |
| | |
| | | } else { |
| | | if locAmount, aok := mapLocAmount[strconv.Itoa(v.ToLocationID)+v.ProductId]; aok { |
| | | locAmount.Amount = locAmount.Amount.Add(v.Amount) |
| | | locAmount.MoreUnitList = AddMoreUnit(locAmount.MoreUnitList, v.MoreUnitList) |
| | | locAmount.ID = uint(locAmount.Id) |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(int(locAmount.ID)).Save(locAmount); err != nil { |
| | | return err |
| | |
| | | ProductCategoryID: v.Product.CategoryId, |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | | MoreUnitList: v.MoreUnitList, |
| | | CreateDate: time.Now().Format("2006-01-02 15:04:05"), |
| | | WarehouseId: operation.WarehouseId, |
| | | }); err != nil { |
| | |
| | | if v.Product.Amount.LessThan(v.Amount) { |
| | | return errors.New(fmt.Sprintf("产品:%v,库存:%v,出库:%v,数量不够,无法完成出库操作", v.Product.Name, v.Product.Amount.String(), v.Amount.String())) |
| | | } |
| | | if !MoreUnitIsEnough(v.Product.MoreUnitList, v.MoreUnitList) { |
| | | return errors.New(fmt.Sprintf("产品:%v, 多单位数量不够,无法完成出库操作", v.Product.Name)) |
| | | } |
| | | listDetails[k].Product.Amount = listDetails[k].Product.Amount.Sub(v.Amount) |
| | | if err := models.NewMaterialSearch().SetOrm(tx).Save(&listDetails[k].Product); err != nil { |
| | | return err |
| | |
| | | if locAmount.Amount.LessThan(v.Amount) { |
| | | return errors.New(fmt.Sprintf("产品:%v,库存:%v,出库:%v,数量不够,无法完成出库操作", v.Product.Name, locAmount.Amount.String(), v.Amount.String())) |
| | | } |
| | | if !MoreUnitIsEnough(locAmount.MoreUnitList, v.MoreUnitList) { |
| | | return errors.New(fmt.Sprintf("产品:%v, 多单位数量不够,无法完成出库操作", v.Product.Name)) |
| | | } |
| | | locAmount.Amount = locAmount.Amount.Sub(v.Amount) |
| | | locAmount.MoreUnitList = SubMoreUnit(locAmount.MoreUnitList, v.MoreUnitList) |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(locAmount.Id).Save(locAmount); err != nil { |
| | | return err |
| | | } |
| | |
| | | outputDetails = append(outputDetails, &models.OperationDetails{ |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | | MoreUnitList: v.MoreUnitList, |
| | | DealerType: v.DealerType, |
| | | FromLocationID: v.FromLocationID, |
| | | ToLocationID: v.ToLocationID, |
| | | TotalGrossWeight: v.TotalGrossWeight, |