| | |
| | | "errors" |
| | | "fmt" |
| | | "github.com/gin-gonic/gin" |
| | | "github.com/mitchellh/mapstructure" |
| | | "github.com/shopspring/decimal" |
| | | "gorm.io/gorm" |
| | | "strconv" |
| | |
| | | LocationID: output.LocationID, |
| | | OperationSource: constvar.OperationSourceSaleDelivery, |
| | | SalesDetailsNumber: output.SaleDetailsNumber, |
| | | WarehouseId: output.WarehouseID, |
| | | } |
| | | operations = append(operations, operation) |
| | | autoCode = models.GetAutoCode(maxAutoIncr, codeStandard) |
| | |
| | | return err |
| | | } |
| | | |
| | | if roleProduct, ok := mapLocationRoleProduct[strconv.Itoa(operation.LocationID)+v.ProductId]; ok { |
| | | if roleProduct, ok := mapLocationRoleProduct[strconv.Itoa(v.ToLocationID)+v.ProductId]; ok { |
| | | detail := &models.OperationDetails{ |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | |
| | | |
| | | if locAmount, aok := mapLocAmount[strconv.Itoa(roleProduct.LocationId)+v.ProductId]; aok { |
| | | locAmount.Amount = locAmount.Amount.Add(v.Amount) |
| | | if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil { |
| | | return res.Error |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(int(locAmount.ID)).Save(locAmount); err != nil { |
| | | return err |
| | | } |
| | | } else { |
| | | if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{ |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).Create(&models.LocationProductAmount{ |
| | | LocationId: roleProduct.LocationId, |
| | | ProductCategoryID: v.Product.CategoryId, |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | | CreateDate: time.Now().Format("2006-01-02 15:04:05"), |
| | | WarehouseId: operation.WarehouseId, |
| | | }); err != nil { |
| | | return err |
| | | } |
| | | } |
| | | } else { |
| | | if roleCategory, cok := mapLocationRoleCategory[strconv.Itoa(operation.LocationID)+strconv.Itoa(v.Product.CategoryId)]; cok { |
| | | if roleCategory, cok := mapLocationRoleCategory[strconv.Itoa(v.ToLocationID)+strconv.Itoa(v.Product.CategoryId)]; cok { |
| | | detail := &models.OperationDetails{ |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | |
| | | |
| | | if locAmount, aok := mapLocAmount[strconv.Itoa(roleCategory.LocationId)+v.ProductId]; aok { |
| | | locAmount.Amount = locAmount.Amount.Add(v.Amount) |
| | | if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil { |
| | | return res.Error |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(int(locAmount.ID)).Save(locAmount); err != nil { |
| | | return err |
| | | } |
| | | } else { |
| | | if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{ |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).Create(&models.LocationProductAmount{ |
| | | LocationId: roleCategory.LocationId, |
| | | ProductCategoryID: v.Product.CategoryId, |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | | CreateDate: time.Now().Format("2006-01-02 15:04:05"), |
| | | WarehouseId: operation.WarehouseId, |
| | | }); err != nil { |
| | | return err |
| | | } |
| | | } |
| | | } else { |
| | | if locAmount, aok := mapLocAmount[strconv.Itoa(operation.LocationID)+v.ProductId]; aok { |
| | | if locAmount, aok := mapLocAmount[strconv.Itoa(v.ToLocationID)+v.ProductId]; aok { |
| | | locAmount.Amount = locAmount.Amount.Add(v.Amount) |
| | | if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil { |
| | | return res.Error |
| | | locAmount.ID = uint(locAmount.Id) |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(int(locAmount.ID)).Save(locAmount); err != nil { |
| | | return err |
| | | } |
| | | } else { |
| | | if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{ |
| | | LocationId: operation.LocationID, |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).Create(&models.LocationProductAmount{ |
| | | LocationId: v.ToLocationID, |
| | | ProductCategoryID: v.Product.CategoryId, |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount, |
| | | CreateDate: time.Now().Format("2006-01-02 15:04:05"), |
| | | WarehouseId: operation.WarehouseId, |
| | | }); err != nil { |
| | | return err |
| | | } |
| | |
| | | BaseOperationType: constvar.BaseOperationTypeInternal, |
| | | Details: details, |
| | | CheckedBy: userInfo.Username, |
| | | WarehouseId: operation.WarehouseId, |
| | | }).Error; err != nil { |
| | | return err |
| | | } |
| | |
| | | return errors.New(fmt.Sprintf("产品:%v,库存:%v,出库:%v,数量不够,无法完成出库操作", v.Product.Name, locAmount.Amount.String(), v.Amount.String())) |
| | | } |
| | | locAmount.Amount = locAmount.Amount.Sub(v.Amount) |
| | | if err := models.NewLocationProductAmountSearch().SetID(locAmount.Id).Update(locAmount); err != nil { |
| | | if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(locAmount.Id).Save(locAmount); err != nil { |
| | | return err |
| | | } |
| | | } else { |
| | | return errors.New("当前仓库没有该产品,请先入库") |
| | | } |
| | | if v.IsInternalOutput { |
| | | internalInputDetails = append(internalInputDetails, v) |
| | | var inputDetail models.OperationDetails |
| | | mapstructure.Decode(v, &inputDetail) |
| | | inputDetail.Id = 0 |
| | | inputDetail.OperationID = 0 |
| | | internalInputDetails = append(internalInputDetails, &inputDetail) |
| | | } |
| | | } |
| | | if len(internalInputDetails) > 0 { |
| | | opTypeId, err := GetTargetOperationTypeIdByOperation(originOperation, constvar.BaseOperationTypeIncoming) |
| | | opTypeId, err := GetTargetOperationTypeIdByWarehouseId(originOperation.ToLocation.WarehouseId, constvar.BaseOperationTypeIncoming) |
| | | if err != nil { |
| | | return err |
| | | } |
| | |
| | | Comment: "库存调拨入库", |
| | | BaseOperationType: constvar.BaseOperationTypeIncoming, |
| | | Details: internalInputDetails, |
| | | LocationID: internalInputDetails[0].ToLocationID, |
| | | LocationID: originOperation.LocationID, |
| | | ToLocationID: originOperation.ToLocationID, |
| | | OperationTypeName: "库存调拨入库", |
| | | WarehouseId: originOperation.ToLocation.WarehouseId, |
| | | } |
| | | if err := models.NewOperationSearch().SetOrm(tx).Create(operation); err != nil { |
| | | return err |
| | |
| | | Comment: "库存调拨出库", |
| | | BaseOperationType: constvar.BaseOperationTypeOutgoing, |
| | | Details: outputDetails, |
| | | LocationID: outputDetails[0].FromLocationID, |
| | | LocationID: originOperation.LocationID, |
| | | ToLocationID: originOperation.ToLocationID, |
| | | OperationTypeName: "库存调拨出库", |
| | | IsInternalOutput: true, |
| | | WarehouseId: originOperation.WarehouseId, |
| | | } |
| | | if err := models.NewOperationSearch().SetOrm(tx).Create(operation); err != nil { |
| | | return err |
| | |
| | | var inputDetails []*models.OperationDetails |
| | | var outputDetails []*models.OperationDetails |
| | | for _, v := range listDetails { |
| | | if locAmount, aok := mapLocAmount[strconv.Itoa(v.ToLocationID)+v.ProductId]; aok { |
| | | if locAmount.Amount.Equal(v.Amount) { |
| | | if _, aok := mapLocAmount[strconv.Itoa(v.FromLocationID)+v.ProductId]; aok { |
| | | if v.StockAmount.Equal(v.Amount) { //盘点数量和剩余数量一致 |
| | | continue |
| | | } |
| | | if v.Amount.GreaterThan(locAmount.Amount) { |
| | | if v.Amount.GreaterThan(v.StockAmount) { |
| | | inputDetails = append(inputDetails, &models.OperationDetails{ |
| | | ProductId: v.ProductId, |
| | | Amount: v.Amount.Sub(locAmount.Amount), |
| | | FromLocationID: v.FromLocationID, |
| | | ToLocationID: v.ToLocationID, |
| | | Amount: v.Amount.Sub(v.StockAmount), |
| | | FromLocationID: 0, |
| | | ToLocationID: v.FromLocationID, |
| | | TotalGrossWeight: v.TotalGrossWeight, |
| | | TotalNetWeight: v.TotalNetWeight, |
| | | AuxiliaryAmount: v.AuxiliaryAmount, |
| | |
| | | } else { |
| | | outputDetails = append(outputDetails, &models.OperationDetails{ |
| | | ProductId: v.ProductId, |
| | | Amount: locAmount.Amount.Sub(v.Amount), |
| | | FromLocationID: v.ToLocationID, |
| | | ToLocationID: v.FromLocationID, |
| | | Amount: v.StockAmount.Sub(v.Amount), |
| | | FromLocationID: v.FromLocationID, |
| | | ToLocationID: 0, |
| | | TotalGrossWeight: v.TotalGrossWeight, |
| | | TotalNetWeight: v.TotalNetWeight, |
| | | AuxiliaryAmount: v.AuxiliaryAmount, |
| | |
| | | Details: inputDetails, |
| | | LocationID: inputDetails[0].FromLocationID, |
| | | OperationTypeName: "库存调整入库", |
| | | WarehouseId: originOperation.WarehouseId, |
| | | } |
| | | if err := models.NewOperationSearch().SetOrm(tx).Create(operation); err != nil { |
| | | return err |
| | |
| | | Details: outputDetails, |
| | | LocationID: outputDetails[0].FromLocationID, |
| | | OperationTypeName: "库存调整出库", |
| | | WarehouseId: originOperation.WarehouseId, |
| | | } |
| | | if err := models.NewOperationSearch().SetOrm(tx).Create(operation); err != nil { |
| | | return err |
| | |
| | | } |
| | | |
| | | func GetTargetOperationTypeIdByOperation(operation *models.Operation, baseOT constvar.BaseOperationType) (operationTypeId int, err error) { |
| | | oT, err := models.NewOperationTypeSearch().SetID(uint(operation.OperationTypeId)).First() |
| | | targetOT, err := models.NewOperationTypeSearch().SetBaseOperationType(baseOT).SetWarehouseId(operation.WarehouseId).First() |
| | | if err != nil { |
| | | return 0, err |
| | | } |
| | | targetOT, err := models.NewOperationTypeSearch().SetBaseOperationType(baseOT).SetWarehouseId(oT.WarehouseId).First() |
| | | return targetOT.Id, nil |
| | | } |
| | | |
| | | func GetTargetOperationTypeIdByWarehouseId(warehouseId int, baseOT constvar.BaseOperationType) (operationTypeId int, err error) { |
| | | if warehouseId == 0 { |
| | | return 0, errors.New("warehouseId miss") |
| | | } |
| | | targetOT, err := models.NewOperationTypeSearch().SetBaseOperationType(baseOT).SetWarehouseId(warehouseId).First() |
| | | if err != nil { |
| | | return 0, err |
| | | } |