lishihai
2024-07-03 91d7ca06128f996844aa7d2d691d083c944bdf1d
service/operation.go
@@ -4,6 +4,7 @@
   "errors"
   "fmt"
   "github.com/gin-gonic/gin"
   "github.com/mitchellh/mapstructure"
   "github.com/shopspring/decimal"
   "gorm.io/gorm"
   "strconv"
@@ -138,11 +139,11 @@
         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,
@@ -164,11 +165,11 @@
            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,
@@ -181,11 +182,11 @@
         } else {
            if locAmount, aok := mapLocAmount[strconv.Itoa(operation.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:        operation.LocationID,
                  ProductCategoryID: v.Product.CategoryId,
                  ProductId:         v.ProductId,
@@ -223,7 +224,7 @@
}
// FinishOperationOutput 完成出库或报废
func FinishOperationOutput(tx *gorm.DB, listDetails []*models.OperationDetails, mapLocAmount map[string]*models.LocationProductAmount) (err error) {
func FinishOperationOutput(tx *gorm.DB, listDetails []*models.OperationDetails, mapLocAmount map[string]*models.LocationProductAmount, originOperation *models.Operation) (err error) {
   var internalInputDetails []*models.OperationDetails //内部调拨产生的出库验证后,生成入库单
   for k, v := range listDetails {
      if v.Product.Amount.LessThan(v.Amount) {
@@ -239,18 +240,27 @@
            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)
      if err != nil {
         return err
      }
      operation := &models.Operation{
         OperationTypeId:   opTypeId,
         Number:            strconv.FormatInt(time.Now().Unix(), 10),
         Status:            constvar.OperationStatus_Ready,
         OperationDate:     time.Now().Format("2006-01-02 15:04:05"),
@@ -269,35 +279,43 @@
}
// FinishOperationInternal 验证内部调拨生成出库单
func FinishOperationInternal(tx *gorm.DB, listDetails []*models.OperationDetails) (err error) {
func FinishOperationInternal(tx *gorm.DB, listDetails []*models.OperationDetails, originOperation *models.Operation) (err error) {
   var outputDetails []*models.OperationDetails
   for _, v := range listDetails {
      outputDetails = append(outputDetails, &models.OperationDetails{
         ProductId:        v.ProductId,
         Amount:           v.Amount,
         FromLocationID:   v.FromLocationID,
         ToLocationID:     v.ToLocationID,
         Amount:           v.Amount,
         TotalGrossWeight: v.TotalGrossWeight,
         TotalNetWeight:   v.TotalNetWeight,
         AuxiliaryAmount:  v.AuxiliaryAmount,
         AuxiliaryUnit:    v.AuxiliaryUnit,
         Remark:           v.Remark,
         IsInternalOutput: true,
         Cost:             v.Cost,
         SalePrice:        v.SalePrice,
      })
      if len(outputDetails) > 0 {
         operation := &models.Operation{
            Number:            strconv.FormatInt(time.Now().Unix(), 10),
            Status:            constvar.OperationStatus_Ready,
            OperationDate:     time.Now().Format("2006-01-02 15:04:05"),
            Comment:           "库存调拨出库",
            BaseOperationType: constvar.BaseOperationTypeOutgoing,
            Details:           outputDetails,
            LocationID:        outputDetails[0].FromLocationID,
            OperationTypeName: "库存调拨出库",
            IsInternalOutput:  true,
         }
         if err := models.NewOperationSearch().SetOrm(tx).Create(operation); err != nil {
            return err
         }
   }
   if len(outputDetails) > 0 {
      opTypeId, err := GetTargetOperationTypeIdByOperation(originOperation, constvar.BaseOperationTypeOutgoing)
      if err != nil {
         return err
      }
      operation := &models.Operation{
         OperationTypeId:   opTypeId,
         Number:            strconv.FormatInt(time.Now().Unix(), 10),
         Status:            constvar.OperationStatus_Ready,
         OperationDate:     time.Now().Format("2006-01-02 15:04:05"),
         Comment:           "库存调拨出库",
         BaseOperationType: constvar.BaseOperationTypeOutgoing,
         Details:           outputDetails,
         LocationID:        outputDetails[0].FromLocationID,
         OperationTypeName: "库存调拨出库",
         IsInternalOutput:  true,
      }
      if err := models.NewOperationSearch().SetOrm(tx).Create(operation); err != nil {
         return err
      }
   }
   return nil
@@ -306,7 +324,7 @@
// FinishOperationAdjust 完成库存调整
// 验证后生成入库单或出库单(库存减少生成出库单,库存增加生成入库单)
func FinishOperationAdjust(tx *gorm.DB, listDetails []*models.OperationDetails, mapLocAmount map[string]*models.LocationProductAmount) (err error) {
func FinishOperationAdjust(tx *gorm.DB, listDetails []*models.OperationDetails, mapLocAmount map[string]*models.LocationProductAmount, originOperation *models.Operation) (err error) {
   var inputDetails []*models.OperationDetails
   var outputDetails []*models.OperationDetails
   for _, v := range listDetails {
@@ -325,6 +343,8 @@
               AuxiliaryAmount:  v.AuxiliaryAmount,
               AuxiliaryUnit:    v.AuxiliaryUnit,
               Remark:           v.Remark,
               Cost:             v.Cost,
               SalePrice:        v.SalePrice,
            })
         } else {
            outputDetails = append(outputDetails, &models.OperationDetails{
@@ -337,6 +357,8 @@
               AuxiliaryAmount:  v.AuxiliaryAmount,
               AuxiliaryUnit:    v.AuxiliaryUnit,
               Remark:           v.Remark,
               Cost:             v.Cost,
               SalePrice:        v.SalePrice,
            })
         }
      } else {
@@ -348,54 +370,59 @@
            Remark:         v.Remark,
         })
      }
      //if locAmount, aok := mapLocAmount[strconv.Itoa(v.ToLocationID)+v.ProductId]; aok {
      //   locAmount.Amount = v.Amount
      //   if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(locAmount.Id).Save(locAmount); err != nil {
      //      return err
      //   }
      //} else {
      //   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"),
      //   }); err != nil {
      //      return err
      //   }
      //}
      if len(inputDetails) > 0 {
         operation := &models.Operation{
            Number:            strconv.FormatInt(time.Now().Unix(), 10),
            Status:            constvar.OperationStatus_Ready,
            OperationDate:     time.Now().Format("2006-01-02 15:04:05"),
            Comment:           "库存调整入库",
            BaseOperationType: constvar.BaseOperationTypeIncoming,
            Details:           inputDetails,
            LocationID:        inputDetails[0].FromLocationID,
            OperationTypeName: "库存调整入库",
         }
         if err := models.NewOperationSearch().SetOrm(tx).Create(operation); err != nil {
            return err
         }
   }
   if len(inputDetails) > 0 {
      opTypeId, err := GetTargetOperationTypeIdByOperation(originOperation, constvar.BaseOperationTypeIncoming)
      if err != nil {
         return err
      }
      if len(outputDetails) > 0 {
         operation := &models.Operation{
            Number:            strconv.FormatInt(time.Now().Unix(), 10),
            Status:            constvar.OperationStatus_Ready,
            OperationDate:     time.Now().Format("2006-01-02 15:04:05"),
            Comment:           "库存调整出库",
            BaseOperationType: constvar.BaseOperationTypeOutgoing,
            Details:           outputDetails,
            LocationID:        outputDetails[0].FromLocationID,
            OperationTypeName: "库存调整出库",
         }
         if err := models.NewOperationSearch().SetOrm(tx).Create(operation); err != nil {
            return err
         }
      operation := &models.Operation{
         OperationTypeId:   opTypeId,
         Number:            strconv.FormatInt(time.Now().Unix(), 10),
         Status:            constvar.OperationStatus_Ready,
         OperationDate:     time.Now().Format("2006-01-02 15:04:05"),
         Comment:           "库存调整入库",
         BaseOperationType: constvar.BaseOperationTypeIncoming,
         Details:           inputDetails,
         LocationID:        inputDetails[0].FromLocationID,
         OperationTypeName: "库存调整入库",
      }
      if err := models.NewOperationSearch().SetOrm(tx).Create(operation); err != nil {
         return err
      }
   }
   if len(outputDetails) > 0 {
      opTypeId, err := GetTargetOperationTypeIdByOperation(originOperation, constvar.BaseOperationTypeOutgoing)
      if err != nil {
         return err
      }
      operation := &models.Operation{
         OperationTypeId:   opTypeId,
         Number:            strconv.FormatInt(time.Now().Unix(), 10),
         Status:            constvar.OperationStatus_Ready,
         OperationDate:     time.Now().Format("2006-01-02 15:04:05"),
         Comment:           "库存调整出库",
         BaseOperationType: constvar.BaseOperationTypeOutgoing,
         Details:           outputDetails,
         LocationID:        outputDetails[0].FromLocationID,
         OperationTypeName: "库存调整出库",
      }
      if err := models.NewOperationSearch().SetOrm(tx).Create(operation); err != nil {
         return err
      }
   }
   return nil
}
func GetTargetOperationTypeIdByOperation(operation *models.Operation, baseOT constvar.BaseOperationType) (operationTypeId int, err error) {
   oT, err := models.NewOperationTypeSearch().SetID(uint(operation.OperationTypeId)).First()
   if err != nil {
      return 0, err
   }
   targetOT, err := models.NewOperationTypeSearch().SetBaseOperationType(baseOT).SetWarehouseId(oT.WarehouseId).First()
   if err != nil {
      return 0, err
   }
   return targetOT.Id, nil
}