package service

import (
	"XT_New/models"
	"XT_New/utils"
	"errors"
	"fmt"
	_ "fmt"
	"github.com/jinzhu/gorm"
	"math"
	"strconv"
	"strings"
	"time"
)

// 药品出库

func DrugsDelivery(orgID int64, creater int64, advice *models.DoctorAdvice) (err error) {
	// 1.判断药品是否来自专用字典的药品库
	// 2.判断当天当前机构有没有创建出库单，没有则创建
	// 3.创建出库流程
	// 3.1 实现先进先出逻辑 由于药品执行后，不可以修改和删除，所以不考虑出库后的退库和修改出库数量等
	isHasWay := false
	record_time := int64(0)
	if advice.Way == 1 {
		isHasWay = true
		record_time = advice.RecordDate
	}

	if isHasWay {
		//判断当天当前机构有没有创建出库单，没有则创建
		out, err := FindDrugStockOutByIsSys(orgID, 1, record_time)
		if err == gorm.ErrRecordNotFound {
			timeStr := time.Now().Format("2006-01-02")
			timeArr := strings.Split(timeStr, "-")
			total, _ := FindAllDrugWarehouseOut(orgID)
			total = total + 1
			warehousing_out_order := strconv.FormatInt(orgID, 10) + timeArr[0] + timeArr[1] + timeArr[2] + "000"
			number, _ := strconv.ParseInt(warehousing_out_order, 10, 64)
			number = number + total
			warehousing_out_order = "YPCKD" + strconv.FormatInt(number, 10)
			storeConfig, _ := GetAllStoreHouseConfig(orgID)
			warehouseOut := models.DrugWarehouseOut{
				WarehouseOutOrderNumber: warehousing_out_order,
				OperationTime:           time.Now().Unix(),
				OrgId:                   orgID,
				Creater:                 creater,
				Ctime:                   time.Now().Unix(),
				Status:                  1,
				WarehouseOutTime:        record_time,
				Dealer:                  0,
				Manufacturer:            0,
				Type:                    1,
				IsSys:                   1,
				StorehouseId:            storeConfig.DrugStorehouseOut,
				IsCheck:                 1,
			}
			err := AddSigleDrugWarehouseOut(&warehouseOut)
			if err != nil {
				utils.TraceLog("创建出库单失败 err = %v", err)
				return err
			} else {
				out = warehouseOut
			}
		}

		// 出库流程
		// 1.查询该药品在药品库的规格信息，并将处方里的规格进行换算（尽量将拆零单位转换成包装单位）
		drup, _ := FindBaseDrugLibRecord(orgID, advice.DrugId)
		if drup.ID > 0 {
			prescribingNumber := advice.PrescribingNumber

			DrugDeliverInfo(orgID, prescribingNumber, &out, &drup, advice)

		} else {
			return errors.New("药品信息不存在")
		}

	}

	return
}

// 药品自动出库 递归方式
func DrugDeliverInfo(orgID int64, prescribingNumber float64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DoctorAdvice) (err error) {

	// 判断处方里药品单位是拆零单位还是包装单位,	如果是包装单位，则根据规格，将包装数量转为拆零数量
	var deliver_number int64 = 0
	var stock_number int64 = 0

	prescribingNumber_temp := strconv.FormatFloat(math.Abs(prescribingNumber), 'f', 0, 64)
	count, _ := strconv.ParseInt(prescribingNumber_temp, 10, 64)

	var drug_price float64
	if advice.PrescribingNumberUnit == drup.MaxUnit {
		deliver_number = count * drup.MinNumber

	} else {
		deliver_number = count

	}

	if advice.PrescribingNumberUnit == drup.MaxUnit {
		drug_price = drup.RetailPrice
	}
	fmt.Println(drug_price)

	if advice.PrescribingNumberUnit == drup.MinUnit {
		drug_price = drup.MinPrice
	}

	if advice.PrescribingNumberUnit != drup.MaxUnit || advice.PrescribingNumberUnit != drup.MinUnit {
		drug_price = drup.RetailPrice
	}

	// 根据先进先出原则，查询最先入库的批次，进行出库
	// 如果没有对应的库存，则报错
	storeConfig, _ := GetAllStoreHouseConfig(advice.UserOrgId)
	lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)
	if lastWarehouse.StockMinNumber >= drup.MinNumber {
		var stockMax int64
		var stockMin int64
		stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
		stockMin = lastWarehouse.StockMinNumber % drup.MinNumber

		ChangeMaxNumber(lastWarehouse.ID, stockMax)
		UpdateMinNumber(lastWarehouse.ID, stockMin)
	}
	warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)

	if err != nil {

		return err
	}

	// 将该批次的剩余库存数量转换为拆零数量

	stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

	//查找药品信息
	//baseInfo, _ := FindBaseDrugLibRecord(advice.UserOrgId, advice.DrugId)

	// 当库存数量大于或等于出库数量的话，则正常出库该批次

	if stock_number >= deliver_number {

		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  warehouse.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   1,
			SysRecordTime:           advice.RecordDate,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Price:                   warehouse.RetailPrice,
			CountUnit:               drup.MinUnit,
			RetailPrice:             warehouse.RetailPrice,
			ProductDate:             warehouse.ProductDate,
			ExpiryDate:              warehouse.ExpiryDate,
			PatientId:               advice.PatientId,
			Count:                   deliver_number, //出最小单位
			WarehouseInfoId:         warehouse.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
			IsCheck:                 1,
		}

		drugflow := models.DrugFlow{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			Count:                   deliver_number, //按最小单位计算,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               orgID,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          3,
			IsEdit:                  1,
			Creator:                 advice.ExecutionStaff,
			IsSys:                   1,
			PatientId:               advice.PatientId,
			SystemTime:              advice.AdviceDate,
			WarehousingDetailId:     warehouse.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}

		CreateDrugFlowOne(drugflow)

		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		fmt.Println(errOne)
		//查询是否存在数据

		details := &models.DrugAutomaticReduceDetail{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			PatientId:               advice.PatientId,
			Ctime:                   time.Now().Unix(),
			Mtime:                   time.Now().Unix(),
			Status:                  1,
			RecordTime:              advice.RecordDate,
			OrgId:                   orgID,
			DrugId:                  advice.DrugId,
			Count:                   deliver_number,
			CountUnit:               drup.MinUnit,
			WarehouseInfoId:         warehouse.ID,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}
		errTwo := AddSigleDrugAutoReduceRecordInfo(details)
		if errTwo != nil {
			return errTwo
		}

		var maxNumber int64 = 0
		var minNumber int64 = 0
		//var stock_max_number int64 = 0
		//stock_max_number = warehouse.StockMaxNumber

		maxNumber = deliver_number / drup.MinNumber
		minNumber = deliver_number % drup.MinNumber

		if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
			minNumber = maxNumber
		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < maxNumber && warehouse.StockMinNumber < minNumber {
				return errors.New("库存数量不足")
			}
		}

		warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber

		if warehouse.StockMaxNumber < 0 {
			warehouse.StockMaxNumber = 0
		}
		if warehouse.StockMinNumber < 0 {
			warehouse.StockMinNumber = 0
		}

		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockMinNumber < minNumber {

			warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
			warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
		} else {
			if minNumber > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
			}

			if minNumber == 0 && maxNumber != 1 && warehouse.StockMaxNumber <= 0 {
				if warehouse.StockMinNumber > 0 {
					warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
				}

			}

		}

		if maxNumber == 1 && minNumber == 0 && drup.MaxUnit != drup.MinUnit {
			if (warehouse.StockMinNumber - deliver_number) > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
			}

		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < 0 && warehouse.StockMinNumber < 0 {
				return errors.New("库存数量不足")
			}
		}
		if warehouse.StockMinNumber <= 0 {
			warehouse.StockMinNumber = 0
		}

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)

		if errThree != nil {
			return errThree
		}

		return nil
	} else {

		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  warehouse.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   1,
			SysRecordTime:           advice.RecordDate,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Price:                   warehouse.RetailPrice,
			CountUnit:               drup.MinUnit,
			ProductDate:             warehouse.ProductDate,
			ExpiryDate:              warehouse.ExpiryDate,
			PatientId:               advice.PatientId,
			Count:                   stock_number,
			WarehouseInfoId:         warehouse.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
			IsCheck:                 1,
		}
		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		details := &models.DrugAutomaticReduceDetail{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
			PatientId:               advice.PatientId,
			Ctime:                   time.Now().Unix(),
			Mtime:                   time.Now().Unix(),
			Status:                  1,
			RecordTime:              advice.RecordDate,
			OrgId:                   orgID,
			DrugId:                  advice.DrugId,
			Count:                   stock_number,
			CountUnit:               drup.MinUnit,
			WarehouseInfoId:         warehouse.ID,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}
		errTwo := AddSigleDrugAutoReduceRecordInfo(details)
		if errTwo != nil {
			return errTwo
		}

		info := models.XtDrugWarehouseInfo{
			ID:                warehouse.ID,
			WarehousingId:     warehouse.WarehousingId,
			DrugId:            warehouse.DrugId,
			Number:            warehouse.Number,
			ProductDate:       warehouse.ProductDate,
			ExpiryDate:        warehouse.ExpiryDate,
			WarehousingCount:  warehouse.WarehousingCount,
			Price:             warehouse.RetailPrice,
			TotalPrice:        warehouse.TotalPrice,
			Dealer:            warehouse.Dealer,
			Manufacturer:      warehouse.Manufacturer,
			Remark:            warehouse.Remark,
			Ctime:             warehouse.Ctime,
			Mtime:             warehouse.Mtime,
			Status:            1,
			OrgId:             warehouse.OrgId,
			IsReturn:          warehouse.IsReturn,
			WarehousingOrder:  warehouse.WarehousingOrder,
			Type:              warehouse.Type,
			RetailPrice:       warehouse.RetailPrice,
			RetailTotalPrice:  warehouse.RetailPrice,
			StockMaxNumber:    0,
			StockMinNumber:    0,
			BatchNumber:       warehouse.BatchNumber,
			MaxUnit:           warehouse.MaxUnit,
			WarehousingInfoId: warehouse.WarehousingInfoId,
			SupplyWarehouseId: warehouse.SupplyWarehouseId,
			StorehouseId:      storeConfig.DrugStorehouseOut,
			IsCheck:           1,
		}
		//扣减库存
		errThree := UpDateDrugWarehouseInfoByStock(&info)

		if errThree != nil {
			return errThree
		}

		drugflow := models.DrugFlow{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			Count:                   stock_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               orgID,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          3,
			IsEdit:                  1,
			Creator:                 advice.ExecutionStaff,
			IsSys:                   1,
			PatientId:               advice.PatientId,
			WarehousingDetailId:     warehouse.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}

		CreateDrugFlowOne(drugflow)

		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		prescribingNumber_two_temp := deliver_number - stock_number

		overPlusNumber := float64(prescribingNumber_two_temp)

		advice.PrescribingNumber = float64(prescribingNumber_two_temp)
		advice.PrescribingNumberUnit = drup.MinUnit

		DrugDeliverInfo(orgID, overPlusNumber, warehouseout, drup, advice)
	}

	return
}

// 药品出库

func HisDrugsDelivery(orgID int64, creater int64, advice *models.HisDoctorAdviceInfo) (err error) {

	// 1.判断药品是否来自专用字典的药品库
	// 2.判断当天当前机构有没有创建出库单，没有则创建
	// 3.创建出库流程
	// 3.1 实现先进先出逻辑 由于药品执行后，不可以修改和删除，所以不考虑出库后的退库和修改出库数量等
	isHasWay := false
	record_time := int64(0)
	isHasWay = true
	record_time = advice.RecordDate

	if isHasWay {
		//判断当天当前机构有没有创建出库单，没有则创建
		out, err := FindDrugStockOutByIsSys(orgID, 1, record_time)
		houseConfig, _ := GetAllStoreHouseConfig(orgID)
		if err == gorm.ErrRecordNotFound {
			timeStr := time.Now().Format("2006-01-02")
			timeArr := strings.Split(timeStr, "-")
			total, _ := FindAllDrugWarehouseOut(orgID)
			total = total + 1
			warehousing_out_order := strconv.FormatInt(orgID, 10) + timeArr[0] + timeArr[1] + timeArr[2] + "000"
			number, _ := strconv.ParseInt(warehousing_out_order, 10, 64)
			number = number + total
			warehousing_out_order = "YPCKD" + strconv.FormatInt(number, 10)

			warehouseOut := models.DrugWarehouseOut{
				WarehouseOutOrderNumber: warehousing_out_order,
				OperationTime:           time.Now().Unix(),
				OrgId:                   orgID,
				Creater:                 creater,
				Ctime:                   time.Now().Unix(),
				Status:                  1,
				WarehouseOutTime:        record_time,
				Dealer:                  0,
				Manufacturer:            0,
				Type:                    1,
				IsSys:                   1,
				StorehouseId:            houseConfig.DrugStorehouseOut,
				IsCheck:                 1,
			}
			err := AddSigleDrugWarehouseOut(&warehouseOut)
			if err != nil {
				utils.TraceLog("创建出库单失败 err = %v", err)
				return err
			} else {
				out = warehouseOut
			}
		}

		// 出库流程
		// 1.查询改药品在药品库的规格信息，并将处方里的规格进行换算（尽量将拆零单位转换成包装单位）
		drup, _ := FindBaseDrugLibRecord(orgID, advice.DrugId)
		if drup.ID > 0 {
			prescribingNumber := advice.PrescribingNumber
			HisDrugDeliverInfo(orgID, prescribingNumber, &out, &drup, advice)

		} else {
			return errors.New("药品信息不存在")
		}

	}

	return
}

// 药品出库 递归方式
func HisDrugDeliverInfo(orgID int64, prescribingNumber float64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.HisDoctorAdviceInfo) (err error) {

	// 判断处方里药品单位是拆零单位还是包装单位,	如果是包装单位，则根据规格，将包装数量转为拆零数量
	var deliver_number int64 = 0
	var stock_number int64 = 0

	prescribingNumber_temp := strconv.FormatFloat(math.Abs(prescribingNumber), 'f', 0, 64)
	count, _ := strconv.ParseInt(prescribingNumber_temp, 10, 64)

	if advice.PrescribingNumberUnit == drup.MaxUnit {
		deliver_number = count * drup.MinNumber
	} else {
		deliver_number = count
	}

	var min_price float64

	if advice.PrescribingNumberUnit == drup.MaxUnit {
		min_price = drup.RetailPrice
	}
	if advice.PrescribingNumberUnit == drup.MinUnit {
		min_price = drup.MinPrice
	}

	if advice.PrescribingNumberUnit != drup.MaxUnit && advice.PrescribingNumberUnit != drup.MinUnit {
		min_price = drup.RetailPrice
	}
	fmt.Println(min_price)
	// 根据先进先出原则，查询最先入库的批次，进行出库
	// 如果没有对应的库存，则报错

	//查询默认仓库
	storeConfig, _ := GetAllStoreHouseConfig(orgID)
	lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)
	if lastWarehouse.StockMinNumber >= drup.MinNumber {
		var stockMax int64
		var stockMin int64
		stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
		stockMin = lastWarehouse.StockMinNumber % drup.MinNumber

		ChangeMaxNumber(lastWarehouse.ID, stockMax)
		UpdateMinNumber(lastWarehouse.ID, stockMin)
	}
	warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)

	if err != nil {

		return err
	}

	// 将该批次的剩余库存数量转换为拆零数量

	stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  warehouse.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   1,
			SysRecordTime:           advice.RecordDate,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Price:                   warehouse.RetailPrice,
			CountUnit:               drup.MinUnit,
			RetailPrice:             warehouse.RetailPrice,
			ProductDate:             warehouse.ProductDate,
			ExpiryDate:              warehouse.ExpiryDate,
			PatientId:               advice.PatientId,
			WarehouseInfoId:         warehouse.ID,
			Count:                   deliver_number,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
			IsCheck:                 1,
		}
		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		lastDrugOutInfo, _ := FindLastDrugWarehouseOutInfo(orgID)
		if errOne != nil {
			return errOne
		}
		drugflow := models.DrugFlow{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			Count:                   deliver_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               orgID,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          3,
			IsEdit:                  1,
			Creator:                 advice.ExecutionStaff,
			IsSys:                   1,
			PatientId:               advice.PatientId,
			SystemTime:              advice.AdviceDate,
			WarehousingDetailId:     warehouse.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
			WarehouseOutDetailId:    lastDrugOutInfo.ID,
		}

		CreateDrugFlowOne(drugflow)

		details := &models.DrugAutomaticReduceDetail{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			PatientId:               advice.PatientId,
			Ctime:                   time.Now().Unix(),
			Mtime:                   time.Now().Unix(),
			Status:                  1,
			RecordTime:              advice.RecordDate,
			OrgId:                   orgID,
			DrugId:                  advice.DrugId,
			Count:                   deliver_number,
			CountUnit:               drup.MinUnit,
			WarehouseInfoId:         warehouse.ID,
			AdviceId:                advice.ID,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}
		errTwo := AddSigleDrugAutoReduceRecordInfo(details)
		if errTwo != nil {
			return errTwo
		}

		// 出库完成后，要减去对应批次的库存数量
		// 判断处方里药品单位是拆零单位还是包装单位,	如果是拆零单位，则根据规格，将拆零数量转为包装数量
		var maxNumber int64 = 0
		var minNumber int64 = 0

		maxNumber = deliver_number / drup.MinNumber
		minNumber = deliver_number % drup.MinNumber
		//fmt.Println("maxNumber2323233232323232323232", maxNumber)
		//fmt.Println("minNumber2323233232323232323232", minNumber)
		if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
			minNumber = maxNumber
		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < maxNumber && warehouse.StockMinNumber < minNumber {
				return errors.New("库存数量不足")
			}
		}

		warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber

		if warehouse.StockMaxNumber < 0 {
			warehouse.StockMaxNumber = 0
		}
		if warehouse.StockMinNumber < 0 {
			warehouse.StockMinNumber = 0
		}

		warehouse.Mtime = time.Now().Unix()
		//fmt.Println("warehouse.StockMinNumber", warehouse.StockMinNumber)
		//fmt.Println("minNumber", minNumber)
		//fmt.Println("maxNumber", maxNumber)
		if warehouse.StockMinNumber < minNumber {

			warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
			warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
		} else {

			if minNumber > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
			}

			//fmt.Println("warehouse.StockMaxNumber233323232323232", warehouse.StockMaxNumber)
			//出错修改
			//if minNumber == 0 && maxNumber != 1 && warehouse.StockMaxNumber <= 0 {
			//	if warehouse.StockMinNumber > 0 {
			//		warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
			//	}
			//
			//}
		}

		if maxNumber == 1 && minNumber == 0 && drup.MaxUnit != drup.MinUnit {
			if (warehouse.StockMinNumber - deliver_number) > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
			}
		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < 0 && warehouse.StockMinNumber < 0 {
				return errors.New("库存数量不足")
			}
		}
		if warehouse.StockMinNumber <= 0 {
			warehouse.StockMinNumber = 0
		}
		//扣减库存
		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)

		if errThree != nil {
			return errThree
		}

		return nil
	} else {
		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  warehouse.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   1,
			SysRecordTime:           advice.RecordDate,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Price:                   warehouse.RetailPrice,
			RetailPrice:             warehouse.RetailPrice,
			ProductDate:             warehouse.ProductDate,
			ExpiryDate:              warehouse.ExpiryDate,
			PatientId:               advice.PatientId,
			WarehouseInfoId:         warehouse.ID,
			Count:                   stock_number,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
			IsCheck:                 1,
		}
		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}
		drugflow := models.DrugFlow{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			Count:                   stock_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               orgID,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          3,
			IsEdit:                  1,
			Creator:                 advice.ExecutionStaff,
			IsSys:                   1,
			PatientId:               advice.PatientId,
			SystemTime:              advice.AdviceDate,
			WarehousingDetailId:     warehouse.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
			WarehouseOutDetailId:    lastWarehouse.ID,
		}

		CreateDrugFlowOne(drugflow)

		//查询是否存在数据

		details := &models.DrugAutomaticReduceDetail{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			PatientId:               advice.PatientId,
			Ctime:                   time.Now().Unix(),
			Mtime:                   time.Now().Unix(),
			Status:                  1,
			RecordTime:              advice.RecordDate,
			OrgId:                   orgID,
			DrugId:                  advice.DrugId,
			Count:                   stock_number,
			CountUnit:               drup.MinUnit,
			WarehouseInfoId:         warehouse.ID,
			AdviceId:                advice.ID,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}
		errTwo := AddSigleDrugAutoReduceRecordInfo(details)
		if errTwo != nil {
			return errTwo
		}

		info := models.XtDrugWarehouseInfo{
			ID:                warehouse.ID,
			WarehousingId:     warehouse.WarehousingId,
			DrugId:            warehouse.DrugId,
			Number:            warehouse.Number,
			ProductDate:       warehouse.ProductDate,
			ExpiryDate:        warehouse.ExpiryDate,
			WarehousingCount:  warehouse.WarehousingCount,
			Price:             warehouse.Price,
			TotalPrice:        warehouse.TotalPrice,
			Dealer:            warehouse.Dealer,
			Manufacturer:      warehouse.Manufacturer,
			Remark:            warehouse.Remark,
			Ctime:             warehouse.Ctime,
			Mtime:             warehouse.Mtime,
			Status:            1,
			OrgId:             warehouse.OrgId,
			IsReturn:          warehouse.IsReturn,
			WarehousingOrder:  warehouse.WarehousingOrder,
			Type:              warehouse.Type,
			RetailPrice:       warehouse.RetailPrice,
			RetailTotalPrice:  warehouse.RetailPrice,
			StockMaxNumber:    0,
			StockMinNumber:    0,
			BatchNumber:       warehouse.BatchNumber,
			MaxUnit:           warehouse.MaxUnit,
			MinUnit:           warehouse.MinUnit,
			WarehousingInfoId: warehouse.WarehousingInfoId,
			StorehouseId:      storeConfig.DrugStorehouseOut,
			IsCheck:           1,
		}
		errThree := UpDateDrugWarehouseInfoByStock(&info)

		if errThree != nil {
			return errThree
		}
		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		prescribingNumber_two_temp := deliver_number - stock_number

		overPlusNumber := float64(prescribingNumber_two_temp)

		advice.PrescribingNumber = float64(prescribingNumber_two_temp)

		advice.PrescribingNumberUnit = drup.MinUnit

		HisDrugDeliverInfo(orgID, overPlusNumber, warehouseout, drup, advice)
	}

	return
}

// 药品出库 递归方式
func AutoDrugDeliverInfo(orgID int64, prescribingNumber int64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DrugWarehouseOutInfo) (err error) {

	// 判断处方里药品单位是拆零单位还是包装单位,	如果是包装单位，则根据规格，将包装数量转为拆零数量
	var deliver_number int64 = 0
	var stock_number int64 = 0

	if advice.CountUnit == drup.MaxUnit {
		deliver_number = prescribingNumber * drup.MinNumber
	} else {
		deliver_number = prescribingNumber
	}

	// 根据先进先出原则，查询最先入库的批次，进行出库
	// 如果没有对应的库存，则报错
	//开启事物

	storeConfig, _ := GetAllStoreHouseConfig(orgID)
	lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)
	if lastWarehouse.StockMinNumber >= drup.MinNumber {
		var stockMax int64
		var stockMin int64
		stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
		stockMin = lastWarehouse.StockMinNumber % drup.MinNumber
		ChangeMaxNumber(lastWarehouse.ID, stockMax)
		UpdateMinNumber(lastWarehouse.ID, stockMin)
	}

	warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)

	if err != nil {

		return err
	}

	// 将该批次的剩余库存数量转换为拆零数量

	stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {

		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  advice.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   0,
			SysRecordTime:           advice.Ctime,
			DrugId:                  advice.DrugId,
			ExpiryDate:              advice.ExpiryDate,
			ProductDate:             advice.ProductDate,
			Number:                  advice.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   deliver_number,
			RetailPrice:             advice.RetailPrice,
			Price:                   warehouse.RetailPrice,
			WarehouseInfoId:         warehouse.ID,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
			IsCheck:                 1,
		}

		warehouseOutInfo.Count = prescribingNumber
		warehouseOutInfo.CountUnit = advice.CountUnit

		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             advice.ProductDate,
			ExpireDate:              advice.ExpiryDate,
			Count:                   deliver_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  advice.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          2,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   0,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
		}

		CreateDrugFlowOne(drugflow)
		// 出库完成后，要减去对应批次的库存数量
		// 判断处方里药品单位是拆零单位还是包装单位,	如果是拆零单位，则根据规格，将拆零数量转为包装数量
		var maxNumber int64 = 0
		var minNumber int64 = 0
		if advice.CountUnit == drup.MinUnit {
			maxNumber = prescribingNumber / drup.MinNumber
			minNumber = prescribingNumber % drup.MinNumber
			if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
				minNumber = maxNumber
			}
		} else {
			maxNumber = prescribingNumber
		}

		if warehouse.StockMaxNumber < maxNumber {

			return errors.New("库存数量不足")
		}

		warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber
		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockMinNumber < minNumber {
			warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
			warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
		} else {
			warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
		}

		if warehouse.StockMaxNumber == 1 && warehouse.StockMinNumber == 1 && drup.MaxUnit == drup.MinUnit {
			warehouse.StockMinNumber = 0
		}

		if warehouse.StockMaxNumber < 0 {
			return errors.New("库存数量不足")
		}

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
		if errThree != nil {
			return errThree
		}

		//查询默认仓库
		houseConfig, _ := GetAllStoreHouseConfig(orgID)
		//查询默认仓库剩余多少库存
		list, _ := GetDrugSumCountByStorehouseId(houseConfig.DrugStorehouseOut, orgID, warehouse.DrugId)
		var sum_count int64
		var sum_in_count int64
		for _, it := range list {
			baseDrug, _ := GetBaseDrugMedical(it.DrugId)
			if it.MaxUnit == baseDrug.MaxUnit {
				it.StockMaxNumber = it.StockMaxNumber * baseDrug.MinNumber
				it.WarehousingCount = it.WarehousingCount * baseDrug.MinNumber
			}
			sum_count += it.StockMaxNumber + it.StockMinNumber
			sum_in_count += it.WarehousingCount
		}
		UpdateMedicalSumCount(warehouse.DrugId, sum_count, sum_in_count, orgID)

		return nil

	} else {
		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  advice.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   0,
			SysRecordTime:           advice.Ctime,
			DrugId:                  advice.DrugId,
			ExpiryDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   stock_number,
			RetailPrice:             advice.RetailPrice,
			Price:                   warehouse.RetailPrice,
			WarehouseInfoId:         warehouse.ID,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
			IsCheck:                 1,
		}
		warehouseOutInfo.Count = stock_number

		//warehouseOutInfo.CountUnit = advice.CountUnit

		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}
		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             advice.ProductDate,
			ExpireDate:              advice.ExpiryDate,
			Count:                   stock_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  advice.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          2,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   0,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
		}
		CreateDrugFlowOne(drugflow)
		// 出库完成后，要将该批次库存清零
		//扣减库存

		warehouse.StockMaxNumber = 0
		warehouse.StockMinNumber = 0
		warehouse.Mtime = time.Now().Unix()

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)

		//查询默认仓库
		houseConfig, _ := GetAllStoreHouseConfig(orgID)
		//查询默认仓库剩余多少库存
		list, _ := GetDrugSumCountByStorehouseId(houseConfig.DrugStorehouseOut, orgID, warehouse.DrugId)
		var sum_count int64
		var sum_in_count int64
		for _, it := range list {
			baseDrug, _ := GetBaseDrugMedical(it.DrugId)
			if it.MaxUnit == baseDrug.MaxUnit {
				it.StockMaxNumber = it.StockMaxNumber * baseDrug.MinNumber
				it.WarehousingCount = it.WarehousingCount * baseDrug.MinNumber
				sum_count += it.StockMaxNumber + it.StockMinNumber
				sum_in_count += it.WarehousingCount
			}
		}
		UpdateMedicalSumCount(warehouse.DrugId, sum_count, sum_in_count, orgID)
		if errThree != nil {
			return errThree
		}
		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		prescribingNumber_two_temp := deliver_number - stock_number

		advice.CountUnit = drup.MinUnit

		AutoDrugDeliverInfo(orgID, prescribingNumber_two_temp, warehouseout, drup, advice)
	}

	return
}

// 耗材出库
func ConsumablesDeliveryTotal(orgID int64, patient_id int64, record_time int64, goods []*models.DialysisBeforePrepareGoods, goodOne []*models.NewDialysisBeforePrepareGoods, creator int64) (err error) {

	//查询该患者当天已经出库的耗材信息
	goods_yc, _ := FindConsumablesByDateTwo(orgID, patient_id, record_time)
	// 和新请求的出库数据进行对比，分出那些是继续出库的，那些是需要删除出库的
	for i := len(goods_yc) - 1; i >= 0; i-- {
		goods_yc_temp := goods_yc[i]
		for j := len(goods) - 1; j >= 0; j-- {
			goods_temp := goods[j]
			// 已经出库和新请求出库都存在该耗材，则判断出库数量，分成是继续出库，还是删除出库
			if goods_yc_temp.GoodTypeId == goods_temp.GoodTypeId && goods_yc_temp.GoodId == goods_temp.GoodId {
				// 已经出库和新请求出库的出库数量一致，则清除两个结构体里的数据（既不出库，也不删除出库）
				if goods_yc_temp.Count == goods_temp.Count {
					goods_yc = append(goods_yc[:i], goods_yc[i+1:]...)
					goods = append(goods[:j], goods[j+1:]...)
					break
				}
				// 如果已经出库的数量 大于 新请求出库的数量，则代表需要删除出库
				if goods_yc_temp.Count > goods_temp.Count {

					temp_count := goods_yc_temp.Count - goods_temp.Count
					goods_yc[i].Count = temp_count
					goods = append(goods[:j], goods[j+1:]...)
					break
				}
				// 如果已经出库的数量 小于 新请求出库的梳理，则代表需要增加出库
				if goods_yc_temp.Count < goods_temp.Count {
					temp_count := goods_temp.Count - goods_yc_temp.Count

					goods[j].Count = temp_count
					goods_yc = append(goods_yc[:i], goods_yc[i+1:]...)

					break
				}
			}
		}
	}

	// goods_yc 这个数据就是需要已经出库了，但是现在需要删除出库的耗材数据
	// goods 这个数据就是需要出库的耗材的数据(新增的数据)

	if len(goods) > 0 {
		out, err := FindStockOutByIsSys(orgID, 1, record_time)
		houseConfig, _ := GetAllStoreHouseConfig(orgID)
		if err == gorm.ErrRecordNotFound {
			//没有记录，则创建出库单
			timeStr := time.Now().Format("2006-01-02")
			timeArr := strings.Split(timeStr, "-")
			total, _ := FindAllWarehouseOut(orgID)
			total = total + 1
			warehousing_out_order := strconv.FormatInt(orgID, 10) + timeArr[0] + timeArr[1] + timeArr[2] + "000"
			number, _ := strconv.ParseInt(warehousing_out_order, 10, 64)
			number = number + total
			warehousing_out_order = "CKD" + strconv.FormatInt(number, 10)

			warehouseOut := models.WarehouseOut{
				WarehouseOutOrderNumber: warehousing_out_order,
				OperationTime:           time.Now().Unix(),
				OrgId:                   orgID,
				Creater:                 creator,
				Ctime:                   time.Now().Unix(),
				Status:                  1,
				WarehouseOutTime:        record_time,
				Dealer:                  0,
				Manufacturer:            0,
				Type:                    1,
				IsSys:                   1,
				StorehouseId:            houseConfig.StorehouseOutInfo,
				IsCheck:                 1,
			}
			err := AddSigleWarehouseOut(&warehouseOut)
			if err != nil {
				utils.TraceLog("创建出库单失败 err = %v", err)
				return err
			} else {
				out = warehouseOut
			}
		}

		for _, item := range goods {
			var newCount int64 = 0
			for _, it := range goodOne {
				if item.GoodTypeId == it.GoodTypeId && item.GoodId == it.GoodId {
					newCount = it.Count
				}
			}
			prepare := models.DialysisBeforePrepare{
				GoodTypeId:   item.GoodTypeId,
				GoodId:       item.GoodId,
				Count:        item.Count,
				ProjectId:    item.ProjectId,
				StorehouseId: houseConfig.StorehouseOutInfo,
			}

			ConsumablesDelivery(orgID, patient_id, record_time, &prepare, &out, newCount)

		}

	}

	if len(goods_yc) > 0 {
		for _, good_yc := range goods_yc {
			out, _ := FindStockOutByIsSys(orgID, 1, record_time)
			ConsumablesDeliveryDelete(orgID, patient_id, record_time, good_yc, &out)
		}
	}

	return nil
}

//耗材出库
func ConsumablesDelivery(orgID int64, patient_id int64, record_time int64, goods *models.DialysisBeforePrepare, warehouseOut *models.WarehouseOut, count int64) (err error) {

	//开事务
	//tx := XTWriteDB().Begin()
	var deliver_number int64 = 0
	var stock_number int64 = 0
	var maxNumber int64 = 0

	deliver_number = goods.Count

	// 根据先进先出原则，查询最先入库的批次，进行出库
	// 如果没有对应的库存，则报错

	warehouse, err := FindFirstWarehousingInfoByStock(goods.GoodId, goods.GoodTypeId, goods.StorehouseId)
	if err != nil {

		return errors.New("库存数量不足")
	}

	stock_number = warehouse.StockCount

	//获取耗材信息
	info, _ := GetGoodInformationByGoodId(goods.GoodId)
	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {
		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseOut.ID,
			WarehouseInfotId:        warehouse.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  warehouse.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   1,
			SysRecordTime:           record_time,
			GoodTypeId:              goods.GoodTypeId,
			GoodId:                  goods.GoodId,
			PatientId:               patient_id,
			Number:                  warehouse.Number,
			LicenseNumber:           warehouse.LicenseNumber,
			Price:                   warehouse.PackingPrice,
			ExpiryDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			ProjectId:               goods.ProjectId,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            goods.StorehouseId,
			IsCheck:                 1,
		}
		warehouseOutInfo.Count = count

		_, errcodes := GetWarehouseOutInfoIsExistOne(goods.GoodId, patient_id, record_time)
		if errcodes == gorm.ErrRecordNotFound {
			errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
			if errOne != nil {
				return errOne
			}
		} else if errcodes == nil {
			UpdatedWarehouseOutInfo(warehouseOutInfo, goods.GoodId, patient_id, record_time)
		}

		details := models.BloodAutomaticReduceDetail{
			WarehouseOutId:          warehouseOutInfo.ID,
			WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
			PatientId:               patient_id,
			Ctime:                   time.Now().Unix(),
			Mtime:                   time.Now().Unix(),
			Status:                  1,
			RecordTime:              record_time,
			OrgId:                   orgID,
			GoodId:                  goods.GoodId,
			GoodTypeId:              goods.GoodTypeId,
			Count:                   count,
			ProjectId:               goods.ProjectId,
			StorehouseId:            goods.StorehouseId,
		}
		//查询当天耗材是否已经存在数据
		_, errcode := GetAutoMaticReduceDetail(orgID, patient_id, record_time, goods.GoodId, goods.GoodTypeId)

		if errcode == gorm.ErrRecordNotFound {
			errTwo := CreateAutoReduceRecord(&details)
			if errTwo != nil {
				return errTwo
			}
			//插入库存流水表
			flow := models.VmStockFlow{
				WarehouseOutId:          warehouseOut.ID,
				WarehousingId:           warehouse.ID,
				GoodId:                  goods.GoodId,
				Number:                  warehouse.Number,
				ProductDate:             warehouse.ProductDate,
				ExpireDate:              warehouse.ExpiryDate,
				Count:                   deliver_number,
				Price:                   warehouse.PackingPrice,
				Status:                  1,
				Ctime:                   time.Now().Unix(),
				UserOrgId:               orgID,
				Manufacturer:            info.Manufacturer,
				Dealer:                  info.Dealer,
				LicenseNumber:           warehouse.LicenseNumber,
				IsEdit:                  2,
				Creator:                 warehouseOut.Creater,
				SystemTime:              record_time,
				ConsumableType:          3,
				WarehouseOutDetailId:    warehouseOutInfo.ID,
				WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
				IsSys:                   1,
				PatientId:               patient_id,
				ProjectId:               goods.ProjectId,
				SupplyWarehouseId:       warehouse.SupplyWarehouseId,
				StorehouseId:            goods.StorehouseId,
			}
			//查询流水是否存在
			exsit, errflow := GetStockFlowIsExsit(warehouse.ID, patient_id, record_time, goods.GoodId)

			if errflow == gorm.ErrRecordNotFound {
				errThre := CreateStockFlowOne(flow)
				if errThre != nil {
					return errThre
				}
			} else if errflow == nil {
				flow := models.VmStockFlow{
					ID:                      exsit.ID,
					WarehouseOutId:          warehouseOut.ID,
					WarehousingId:           warehouse.ID,
					GoodId:                  goods.GoodId,
					Number:                  warehouse.Number,
					ProductDate:             warehouse.ProductDate,
					ExpireDate:              warehouse.ExpiryDate,
					Count:                   exsit.Count + goods.Count,
					Price:                   warehouse.PackingPrice,
					Status:                  1,
					Ctime:                   time.Now().Unix(),
					UserOrgId:               orgID,
					Manufacturer:            info.Manufacturer,
					Dealer:                  info.Dealer,
					LicenseNumber:           warehouse.LicenseNumber,
					IsEdit:                  2,
					Creator:                 warehouseOut.Creater,
					SystemTime:              record_time,
					ConsumableType:          3,
					WarehouseOutDetailId:    warehouseOutInfo.ID,
					WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
					IsSys:                   1,
					PatientId:               patient_id,
					ReturnCount:             exsit.Count + (exsit.Count + deliver_number),
					ProjectId:               goods.ProjectId,
					StorehouseId:            goods.StorehouseId,
				}

				errFour := UpdatedStockFlowOne(flow, warehouse.ID, patient_id, record_time, goods.GoodId)
				if errFour != nil {
					return errFour
				}
			}

		} else if errcode == nil {
			flow := models.VmStockFlow{
				WarehouseOutId:          warehouseOut.ID,
				WarehousingId:           warehouse.ID,
				GoodId:                  goods.GoodId,
				Number:                  warehouse.Number,
				ProductDate:             warehouse.ProductDate,
				ExpireDate:              warehouse.ExpiryDate,
				Count:                   deliver_number,
				Price:                   warehouse.PackingPrice,
				Status:                  1,
				Ctime:                   time.Now().Unix(),
				UserOrgId:               orgID,
				Manufacturer:            info.Manufacturer,
				Dealer:                  info.Dealer,
				LicenseNumber:           warehouse.LicenseNumber,
				IsEdit:                  2,
				Creator:                 warehouseOut.Creater,
				SystemTime:              record_time,
				ConsumableType:          3,
				WarehouseOutDetailId:    warehouseOutInfo.ID,
				WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
				IsSys:                   1,
				PatientId:               patient_id,
				ProjectId:               goods.ProjectId,
				SupplyWarehouseId:       warehouse.SupplyWarehouseId,
				StorehouseId:            goods.StorehouseId,
			}
			//查询流水是否存在
			exsit, errflow := GetStockFlowIsExsit(warehouse.ID, patient_id, record_time, goods.GoodId)

			if errflow == gorm.ErrRecordNotFound {
				CreateStockFlowOne(flow)
				DeleteAutoRedeceDetailTwo(orgID, patient_id, record_time, goods.GoodId, goods.GoodTypeId)
				CreateAutoReduceRecord(&details)
			} else if errflow == nil {
				flow := models.VmStockFlow{
					ID:                      exsit.ID,
					WarehouseOutId:          warehouseOut.ID,
					WarehousingId:           warehouse.ID,
					GoodId:                  goods.GoodId,
					Number:                  warehouse.Number,
					ProductDate:             warehouse.ProductDate,
					ExpireDate:              warehouse.ExpiryDate,
					Count:                   exsit.Count + goods.Count,
					Price:                   warehouse.PackingPrice,
					Status:                  1,
					Ctime:                   time.Now().Unix(),
					UserOrgId:               orgID,
					Manufacturer:            info.Manufacturer,
					Dealer:                  info.Dealer,
					LicenseNumber:           warehouse.LicenseNumber,
					IsEdit:                  2,
					Creator:                 warehouseOut.Creater,
					SystemTime:              record_time,
					ConsumableType:          3,
					WarehouseOutDetailId:    warehouseOutInfo.ID,
					WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
					IsSys:                   1,
					PatientId:               patient_id,
					ReturnCount:             exsit.Count + (exsit.Count + deliver_number),
					ProjectId:               goods.ProjectId,
					SupplyWarehouseId:       warehouse.SupplyWarehouseId,
					StorehouseId:            goods.StorehouseId,
				}
				//UpdatedStockFlow(flow)
				UpdatedStockFlowOne(flow, warehouse.ID, patient_id, record_time, goods.GoodId)
				DeleteAutoRedeceDetailTwo(orgID, patient_id, record_time, goods.GoodId, goods.GoodTypeId)
				CreateAutoReduceRecord(&details)
			}

		}

		maxNumber = goods.Count

		if warehouse.StockCount < maxNumber {
			return errors.New("库存数量不足")
		}

		warehouse.StockCount = warehouse.StockCount - maxNumber

		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockCount < 0 {
			return errors.New("库存数量不足")
		}
		ModifyGoodReduceInformationSix(goods.GoodId, goods.Count, orgID, warehouse.PackingPrice)
		errThree := UpDateWarehouseInfoByStock(&warehouse)
		if errThree != nil {
			return errThree
		}
		//if errThree != nil {
		//	utils.ErrorLog("事务失败,原因为: %v", err.Error())
		//	tx.Rollback()
		//} else {
		//	tx.Commit()
		//}

		return nil
	} else {

		// 当刚批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseOut.ID,
			WarehouseInfotId:        warehouse.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  warehouse.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   1,
			SysRecordTime:           record_time,
			GoodTypeId:              goods.GoodTypeId,
			GoodId:                  goods.GoodId,
			PatientId:               patient_id,
			Number:                  warehouse.Number,
			LicenseNumber:           warehouse.LicenseNumber,
			Price:                   warehouse.PackingPrice,
			ExpiryDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			ProjectId:               goods.ProjectId,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            goods.StorehouseId,
			IsCheck:                 1,
		}
		warehouseOutInfo.Count = stock_number

		_, errcodes := GetWarehouseOutInfoIsExistOne(goods.GoodId, goods.PatientId, record_time)

		if errcodes == gorm.ErrRecordNotFound {
			errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)

			if errOne != nil {
				return errOne
			}
			//插入库存流水表
			flow := models.VmStockFlow{
				WarehouseOutId:          warehouseOut.ID,
				WarehousingId:           warehouse.ID,
				GoodId:                  goods.GoodId,
				Number:                  warehouse.Number,
				ProductDate:             warehouse.ProductDate,
				ExpireDate:              warehouse.ExpiryDate,
				Count:                   stock_number,
				Price:                   warehouse.PackingPrice,
				Status:                  1,
				Ctime:                   time.Now().Unix(),
				UserOrgId:               orgID,
				Manufacturer:            info.Manufacturer,
				Dealer:                  info.Dealer,
				LicenseNumber:           warehouse.LicenseNumber,
				IsEdit:                  2,
				Creator:                 warehouseOut.Creater,
				SystemTime:              record_time,
				ConsumableType:          3,
				WarehouseOutDetailId:    warehouseOutInfo.ID,
				WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
				IsSys:                   1,
				PatientId:               patient_id,
				ProjectId:               goods.ProjectId,
				SupplyWarehouseId:       warehouse.SupplyWarehouseId,
				StorehouseId:            goods.StorehouseId,
			}
			//查询流水是否存在
			exsit, errflows := GetStockFlowIsExsit(warehouse.ID, patient_id, record_time, goods.GoodId)

			if errflows == gorm.ErrRecordNotFound {
				CreateStockFlowOne(flow)
			} else if errflows == nil {
				flow := models.VmStockFlow{
					ID:                      exsit.ID,
					WarehouseOutId:          warehouseOut.ID,
					WarehousingId:           warehouse.ID,
					GoodId:                  goods.GoodId,
					Number:                  warehouse.Number,
					ProductDate:             warehouse.ProductDate,
					ExpireDate:              warehouse.ExpiryDate,
					Count:                   exsit.Count + goods.Count,
					Price:                   warehouse.PackingPrice,
					Status:                  1,
					Ctime:                   time.Now().Unix(),
					UserOrgId:               orgID,
					Manufacturer:            info.Manufacturer,
					Dealer:                  info.Dealer,
					LicenseNumber:           warehouse.LicenseNumber,
					IsEdit:                  2,
					Creator:                 warehouseOut.Creater,
					SystemTime:              record_time,
					ConsumableType:          3,
					WarehouseOutDetailId:    warehouseOutInfo.ID,
					WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
					IsSys:                   1,
					PatientId:               patient_id,
					ReturnCount:             exsit.Count + (exsit.Count + deliver_number),
					ProjectId:               goods.ProjectId,
					SupplyWarehouseId:       warehouse.SupplyWarehouseId,
					StorehouseId:            goods.StorehouseId,
				}
				//UpdatedStockFlow(flow)
				UpdatedStockFlowOne(flow, warehouse.ID, patient_id, record_time, goods.GoodId)
			}

		} else if errcodes == nil {

			goods.Count = deliver_number - stock_number
			//更新数量为  该批次剩余数量  + 还有未出的数量
			warehouseOutInfo.Count = stock_number
			UpdatedWarehouseOutInfo(warehouseOutInfo, goods.GoodId, goods.PatientId, record_time)
			//插入库存流水表
			flow := models.VmStockFlow{
				WarehouseOutId:          warehouseOut.ID,
				WarehousingId:           warehouse.ID,
				GoodId:                  goods.GoodId,
				Number:                  warehouse.Number,
				ProductDate:             warehouse.ProductDate,
				ExpireDate:              warehouse.ExpiryDate,
				Count:                   stock_number,
				Price:                   warehouse.PackingPrice,
				Status:                  1,
				Ctime:                   time.Now().Unix(),
				UserOrgId:               orgID,
				Manufacturer:            info.Manufacturer,
				Dealer:                  info.Dealer,
				LicenseNumber:           warehouse.LicenseNumber,
				IsEdit:                  2,
				Creator:                 warehouseOut.Creater,
				SystemTime:              record_time,
				ConsumableType:          3,
				WarehouseOutDetailId:    warehouseOutInfo.ID,
				WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
				IsSys:                   1,
				PatientId:               patient_id,
				ProjectId:               goods.ProjectId,
				SupplyWarehouseId:       warehouse.SupplyWarehouseId,
				StorehouseId:            goods.StorehouseId,
			}
			//查询流水是否存在
			exsit, errflows := GetStockFlowIsExsit(warehouse.ID, patient_id, record_time, goods.GoodId)
			if errflows == gorm.ErrRecordNotFound {
				CreateStockFlowOne(flow)
			} else if errflows == nil {

				flow := models.VmStockFlow{
					ID:                      exsit.ID,
					WarehouseOutId:          warehouseOut.ID,
					WarehousingId:           warehouse.ID,
					GoodId:                  goods.GoodId,
					Number:                  warehouse.Number,
					ProductDate:             warehouse.ProductDate,
					ExpireDate:              warehouse.ExpiryDate,
					Count:                   exsit.Count + goods.Count,
					Price:                   warehouse.PackingPrice,
					Status:                  1,
					Ctime:                   time.Now().Unix(),
					UserOrgId:               orgID,
					Manufacturer:            info.Manufacturer,
					Dealer:                  info.Dealer,
					LicenseNumber:           warehouse.LicenseNumber,
					IsEdit:                  2,
					Creator:                 warehouseOut.Creater,
					SystemTime:              record_time,
					ConsumableType:          3,
					WarehouseOutDetailId:    warehouseOutInfo.ID,
					WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
					IsSys:                   1,
					PatientId:               patient_id,
					ProjectId:               goods.ProjectId,
					SupplyWarehouseId:       warehouse.SupplyWarehouseId,
					StorehouseId:            goods.StorehouseId,
				}
				//UpdatedStockFlow(flow)
				UpdatedStockFlowOne(flow, warehouse.ID, patient_id, record_time, goods.GoodId)
			}
		}

		// 出库完成后，要将该批次库存清零
		ModifyGoodReduceInformationSix(warehouse.GoodId, warehouse.StockCount, orgID, warehouse.PackingPrice)
		warehouse.StockCount = 0

		warehouse.Mtime = time.Now().Unix()
		errThree := UpDateWarehouseInfoByStock(&warehouse)
		if errThree != nil {
			return errThree
		}
		//if errThree != nil {
		//	utils.ErrorLog("事务失败,原因为: %v", err.Error())
		//	tx.Rollback()
		//} else {
		//	tx.Commit()
		//}

		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		goods.Count = deliver_number - stock_number

		ConsumablesDelivery(orgID, patient_id, record_time, goods, warehouseOut, count)

	}
	return nil
}

//耗材出库删除
func ConsumablesDeliveryDelete(orgID int64, patient_id int64, record_time int64, good_yc *models.DialysisBeforePrepare, warehouseOut *models.WarehouseOut) (err error) {

	// 先根据相关信息查询当天该耗材的出库信息
	warehouseOutInfos, err := FindStockOutInfoByStock(orgID, good_yc.GoodTypeId, good_yc.GoodId, record_time, patient_id)
	if err != nil {
		return err
	}

	var delete_count int64 = 0

	for _, ware := range warehouseOutInfos {
		// 判断当前出库的数据和删除出库数量
		if good_yc.Count <= ware.Count {
			delete_count = good_yc.Count
		} else {
			delete_count = ware.Count
		}
		houseConfig, _ := GetAllStoreHouseConfig(orgID)
		// 在出库记录表里记录退库详情
		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseOut.ID,
			//WarehouseInfoId:		 warehouse.ID,
			Status:        1,
			Ctime:         time.Now().Unix(),
			Remark:        "",
			OrgId:         orgID,
			Type:          1,
			Manufacturer:  0,
			Dealer:        0,
			IsSys:         2,
			SysRecordTime: record_time,
			GoodTypeId:    good_yc.GoodTypeId,
			GoodId:        good_yc.GoodId,
			PatientId:     patient_id,
			StorehouseId:  houseConfig.StorehouseOutInfo,
		}
		warehouseOutInfo.Count = ware.Count - delete_count
		stockInInfo, _ := FindLastStockInInfoRecord(good_yc.GoodId, orgID)
		warehouseOutInfo.Price = stockInInfo.Price
		errOne := UpdateAutoMaticReduceDetail(good_yc.GoodId, good_yc.GoodTypeId, record_time, patient_id, orgID, warehouseOutInfo)
		if errOne != nil {
			return errOne
		} else {
			details := &models.AutomaticReduceDetail{
				WarehouseOutId:          warehouseOutInfo.ID,
				WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
				PatientId:               patient_id,
				Ctime:                   time.Now().Unix(),
				Mtime:                   time.Now().Unix(),
				Status:                  1,
				RecordTime:              record_time,
				OrgId:                   orgID,
				GoodId:                  good_yc.GoodId,
				GoodTypeId:              good_yc.GoodTypeId,
				Count:                   warehouseOutInfo.Count,
				Type:                    2,
				StorehouseId:            houseConfig.StorehouseOutInfo,
			}
			//查询是否当天已经存在数据
			_, errcode := GetAutoMaticReduceDetail(orgID, patient_id, record_time, good_yc.GoodId, good_yc.GoodTypeId)
			if errcode == gorm.ErrRecordNotFound {
				errTwo := AddSigleAutoReduceRecordInfo(details)
				if errTwo != nil {
					return errTwo
				}
			} else if errcode == nil {
				DeleteAutoRedeceDetailTwo(orgID, patient_id, record_time, good_yc.GoodId, good_yc.GoodTypeId)

				AddSigleAutoReduceRecordInfo(details)
			}
		}

		// 删除出库完成后，要增加对应批次的库存数量

		errThree := UpDateWarehouseInfoByStockDelete(ware.WarehouseInfotId, delete_count)
		if errThree != nil {
			return errThree
		}

		// 增加了对应的库存后，看看还有多少需要退库的
		good_yc.Count = good_yc.Count - delete_count
		if good_yc.Count == 0 {
			return nil
		}
	}

	if good_yc.Count == 0 {
		return nil
	} else {
		return errors.New("退库和出库数据不匹配")
	}
}

func GetAutoReduceRecordInfoByPatientId(orgid int64, patient_id int64, recordTime int64) (autoReduce []*models.AutomaticReduceDetail, err error) {

	err = XTReadDB().Model(&autoReduce).Where("org_id = ? and patient_id = ? and record_time = ? and status = 1", orgid, patient_id, recordTime).Find(&autoReduce).Error
	return autoReduce, err
}

func DeleteDialysisBefor(orgid int64, patient_id int64, record_date int64, goodid int64, goodtypeid int64) error {
	prepare := models.DialysisBeforePrepare{}
	err := XTWriteDB().Model(&prepare).Where("user_org_id = ? and patient_id = ? and record_date = ? and status = 1 and good_id = ? and good_type_id = ?", orgid, patient_id, record_date, goodid, goodtypeid).Updates(map[string]interface{}{"status": 0, "count": 0, "mtime": time.Now().Unix()}).Error
	return err
}

func DeleteDialysisBeforThree(orgid int64, patient_id int64, record_date int64) error {
	prepare := models.DialysisBeforePrepare{}
	err := XTWriteDB().Model(&prepare).Where("user_org_id = ? and patient_id = ? and record_date = ? and status = 1", orgid, patient_id, record_date).Updates(map[string]interface{}{"status": 0, "count": 0, "mtime": time.Now().Unix()}).Error
	return err
}

func GetWarehouseById(id int64) (models.WarehouseOut, error) {
	out := models.WarehouseOut{}
	err := XTReadDB().Where("id=? and status = 1", id).Find(&out).Error
	return out, err
}

//耗材出库
func ConsumablesDeliveryOne(orgID int64, record_time int64, goods *models.WarehouseOutInfo, warehouseOut *models.WarehouseOut, count int64, creator int64) (err error) {

	////开事务
	//tx := XTWriteDB().Begin()

	var deliver_number int64 = 0
	var stock_number int64 = 0
	var maxNumber int64 = 0

	deliver_number = goods.Count

	// 根据先进先出原则，查询最先入库的批次，进行出库

	// 如果没有对应的库存，则报错
	warehouse, err := FindFirstWarehousingInfoByStock(goods.GoodId, goods.GoodTypeId, goods.StorehouseId)
	if err != nil {

		return err
	}

	stock_number = warehouse.StockCount

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {

		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseOut.ID,
			WarehouseInfotId:        warehouse.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  goods.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			IsSys:                   0,
			SysRecordTime:           record_time,
			GoodTypeId:              goods.GoodTypeId,
			GoodId:                  goods.GoodId,
			ExpiryDate:              goods.ExpiryDate,
			ProductDate:             goods.ProductDate,
			Number:                  warehouse.Number,
			Price:                   goods.Price,
			LicenseNumber:           goods.LicenseNumber,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            goods.StorehouseId,
			AdminUserId:             goods.AdminUserId,
			BuyPrice:                warehouse.Price,
			StockCount:              goods.StockCount,
		}
		warehouseOutInfo.Count = goods.Count
		//添加出库单详情
		errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		stockFlow := models.VmStockFlow{
			WarehousingId:           warehouse.ID,
			GoodId:                  goods.GoodId,
			Number:                  warehouse.Number,
			LicenseNumber:           goods.LicenseNumber,
			Count:                   goods.Count,
			UserOrgId:               goods.OrgId,
			PatientId:               goods.PatientId,
			SystemTime:              record_time,
			ConsumableType:          2,
			IsSys:                   goods.IsSys,
			WarehousingOrder:        "",
			WarehouseOutId:          warehouseOut.ID,
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			IsEdit:                  1,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			Creator:                 creator,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.PackingPrice,
			WarehousingDetailId:     0,
			WarehouseOutDetailId:    warehouseOutInfo.ID,
			CancelOutDetailId:       0,
			ProductDate:             goods.ProductDate,
			ExpireDate:              goods.ExpiryDate,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            warehouse.StorehouseId,
			AdminUserId:             goods.AdminUserId,
			BuyPrice:                warehouse.Price,
			StockCount:              goods.StockCount,
		}

		//创建出库流水
		CreateStockFlowOne(stockFlow)

		maxNumber = goods.Count

		if warehouse.StockCount < maxNumber {
			return errors.New("库存数量不足")
		}

		warehouse.StockCount = warehouse.StockCount - maxNumber
		warehouse.Mtime = time.Now().Unix()

		//扣减库存
		errThree := UpDateWarehouseInfoByStock(&warehouse)
		fmt.Println(errThree)
		//if errThree != nil {
		//	utils.ErrorLog("事务失败,原因为: %v", errThree.Error())
		//	tx.Rollback()
		//} else {
		//	tx.Commit()
		//}

		//查询该机构默认仓库
		storeConfig, _ := GetAllStoreHouseConfig(goods.OrgId)
		//查询剩余库存
		goodList, _ := GetGoodSumCountByStoreId(storeConfig.StorehouseOutInfo, goods.GoodId, goods.OrgId)
		var sum_count int64
		var sum_in_count int64
		for _, item := range goodList {
			sum_count += item.StockCount
			sum_in_count += item.WarehousingCount
		}
		UpdateGoodByGoodId(goods.GoodId, sum_count, sum_in_count, goods.OrgId)
		if errThree != nil {
			return errThree
		}

	} else {

		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseOut.ID,
			WarehouseInfotId:        warehouse.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  goods.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			IsSys:                   0,
			SysRecordTime:           record_time,
			GoodTypeId:              goods.GoodTypeId,
			GoodId:                  goods.GoodId,
			ExpiryDate:              goods.ExpiryDate,
			ProductDate:             goods.ProductDate,
			Number:                  warehouse.Number,
			Price:                   warehouse.PackingPrice,
			LicenseNumber:           goods.LicenseNumber,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            warehouse.StorehouseId,
			AdminUserId:             goods.AdminUserId,
			BuyPrice:                warehouse.Price,
			StockCount:              goods.StockCount,
			IsCheck:                 1,
		}
		warehouseOutInfo.Count = stock_number

		//查询是否已经生成出库单
		info, errcodes := GetStockInRecoredByGoodIdOne(goods.GoodId, goods.GoodTypeId, goods.SysRecordTime, goods.OrgId)
		if errcodes == gorm.ErrRecordNotFound {
			//创建出库单
			errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
			if errOne != nil {
				return errOne
			}
		} else {
			warehouseOutInfo.Count = info.Count + stock_number

			UpdateAutoMaticReduceDetailOne(goods.GoodId, goods.GoodTypeId, goods.SysRecordTime, goods.OrgId, warehouseOutInfo)
		}

		stockFlow := models.VmStockFlow{
			WarehousingId:           warehouse.ID,
			GoodId:                  goods.GoodId,
			Number:                  warehouse.Number,
			LicenseNumber:           goods.LicenseNumber,
			Count:                   stock_number,
			UserOrgId:               goods.OrgId,
			PatientId:               0,
			SystemTime:              record_time,
			ConsumableType:          2,
			IsSys:                   0,
			WarehousingOrder:        "",
			WarehouseOutId:          warehouseOut.ID,
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			IsEdit:                  1,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			Creator:                 creator,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.PackingPrice,
			WarehousingDetailId:     0,
			WarehouseOutDetailId:    warehouseOutInfo.ID,
			CancelOutDetailId:       0,
			ProductDate:             goods.ProductDate,
			ExpireDate:              goods.ExpiryDate,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            goods.StorehouseId,
			AdminUserId:             goods.AdminUserId,
			BuyPrice:                warehouse.Price,
			StockCount:              goods.StockCount,
		}

		//创建出库明细
		CreateStockFlowOne(stockFlow)
		//查询该机构默认仓库
		storeConfig, _ := GetAllStoreHouseConfig(goods.OrgId)
		//查询剩余库存
		goodList, _ := GetGoodSumCountByStoreId(storeConfig.StorehouseOutInfo, goods.GoodId, goods.OrgId)
		var sum_count int64
		var sum_in_count int64
		for _, item := range goodList {
			sum_count += item.StockCount
			sum_in_count += item.WarehousingCount
		}
		UpdateGoodByGoodId(goods.GoodId, sum_count, sum_in_count, goods.OrgId)
		// 出库完成后，要将该批次库存清零
		warehouse.StockCount = 0
		warehouse.Mtime = time.Now().Unix()

		errThree := UpDateWarehouseInfoByStock(&warehouse)
		fmt.Println(errThree)
		//if errThree != nil {
		//	utils.ErrorLog("事务失败,原因为: %v", errThree.Error())
		//	tx.Rollback()
		//} else {
		//	tx.Commit()
		//}
		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		goods.Count = deliver_number - stock_number
		ConsumablesDeliveryOne(orgID, record_time, goods, warehouseOut, count, creator)

	}
	return nil
}

//退库逻辑
func ConsumablesDeliveryTwo(orgID int64, goods *models.WarehouseOutInfo, count int64) (err error) {

	////开事务
	//tx := XTWriteDB().Begin()
	var deliver_number int64 = 0
	var stock_number int64 = 0
	var maxNumber int64 = 0

	deliver_number = goods.Count

	// 根据先进先出原则，查询最先入库的批次，进行出库
	warehouse, err := FindFirstWarehousingInfoByGoodId(goods.GoodId, goods.ID, goods.StorehouseId)

	if err != nil {
		return err
	}

	stock_number = warehouse.StockCount

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {
		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: goods.WarehouseOutOrderNumber,
			WarehouseOutId:          goods.ID,
			WarehouseInfotId:        warehouse.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  goods.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			IsSys:                   0,
			GoodTypeId:              goods.GoodTypeId,
			GoodId:                  goods.GoodId,
			ExpiryDate:              goods.ExpiryDate,
			ProductDate:             goods.ProductDate,
			Number:                  goods.Number,
			Price:                   warehouse.PackingPrice,
			LicenseNumber:           goods.LicenseNumber,
			ConsumableType:          2,
		}
		warehouseOutInfo.Count = goods.Count

		errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		maxNumber = goods.Count

		if warehouse.StockCount < maxNumber { //这段逻辑根本不会执行，因为当库存数量大于或等于出库数量才会进入这个分支
			return errors.New("库存数量不足")
		}

		warehouse.StockCount = warehouse.StockCount - maxNumber
		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockCount <= 0 {

			return errors.New("库存数量不足")
		}
		errThree := UpDateWarehouseInfoByStock(&warehouse)
		fmt.Println(errThree)
		//if errThree != nil {
		//	utils.ErrorLog("事务失败,原因为: %v", err.Error())
		//	tx.Rollback()
		//} else {
		//	tx.Commit()
		//}

		return
	} else {

		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: goods.WarehouseOutOrderNumber,
			WarehouseOutId:          goods.ID,
			WarehouseInfotId:        warehouse.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  goods.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			IsSys:                   0,
			GoodTypeId:              goods.GoodTypeId,
			GoodId:                  goods.GoodId,
			ExpiryDate:              goods.ExpiryDate,
			ProductDate:             goods.ProductDate,
			Number:                  goods.Number,
			Price:                   warehouse.PackingPrice,
			LicenseNumber:           goods.LicenseNumber,
			ConsumableType:          2,
			IsCheck:                 1,
			StorehouseId:            goods.StorehouseId,
		}
		warehouseOutInfo.Count = stock_number

		errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}
		// 出库完成后，要将该批次库存清零
		warehouse.StockCount = 0
		warehouse.Mtime = time.Now().Unix()
		errThree := UpDateWarehouseInfoByStock(&warehouse)
		//if errThree != nil {
		//	utils.ErrorLog("事务失败,原因为: %v", err.Error())
		//	tx.Rollback()
		//} else {
		//	tx.Commit()
		//}

		fmt.Println(errThree)
		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		goods.Count = deliver_number - stock_number

		ConsumablesDeliveryTwo(orgID, goods, count)

	}
	return nil
}

func DeleteWarehouseInfo(id int64) error {
	err := XTWriteDB().Model(models.WarehousingInfo{}).Where("id = ? and status = 1", id).Updates(map[string]interface{}{"stock_count": 0}).Error
	return err
}

// 药品出库 递归方式
func NewDrugDeliverInfo(orgID int64, prescribingNumber float64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DoctorAdvice) (err error) {

	// 判断处方里药品单位是拆零单位还是包装单位,	如果是包装单位，则根据规格，将包装数量转为拆零数量
	var deliver_number int64 = 0
	var stock_number int64 = 0

	prescribingNumber_temp := strconv.FormatFloat(math.Abs(prescribingNumber), 'f', 0, 64)
	count, _ := strconv.ParseInt(prescribingNumber_temp, 10, 64)

	var drug_price float64

	//按最小单位数据计算
	deliver_number = count

	if advice.PrescribingNumberUnit == drup.MaxUnit {
		drug_price = drup.RetailPrice
	}

	if advice.PrescribingNumberUnit == drup.MinUnit {
		drug_price = drup.MinPrice
	}

	if advice.PrescribingNumberUnit != drup.MaxUnit || advice.PrescribingNumberUnit != drup.MinUnit {
		drug_price = drup.RetailPrice
	}

	// 根据先进先出原则，查询最先入库的批次，进行出库
	// 如果没有对应的库存，则报错
	//查询默认仓库
	storeConfig, _ := GetAllStoreHouseConfig(advice.UserOrgId)
	lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)
	if lastWarehouse.StockMinNumber >= drup.MinNumber {
		var stockMax int64
		var stockMin int64
		stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
		stockMin = lastWarehouse.StockMinNumber % drup.MinNumber
		ChangeMaxNumber(lastWarehouse.ID, stockMax)
		UpdateMinNumber(lastWarehouse.ID, stockMin)
	}

	warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)

	if err != nil {

		return err
	}

	// 将该批次的剩余库存数量转换为拆零数量

	stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  warehouse.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   1,
			SysRecordTime:           advice.RecordDate,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Price:                   warehouse.RetailPrice,
			CountUnit:               drup.MinUnit,
			RetailPrice:             drug_price,
			ProductDate:             warehouse.ProductDate,
			ExpiryDate:              warehouse.ExpiryDate,
			PatientId:               advice.PatientId,
			Count:                   deliver_number, //出最小单位
			WarehouseInfoId:         warehouse.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
			IsCheck:                 1,
		}

		drugflow := models.DrugFlow{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			Count:                   deliver_number, //按最小单位计算,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               orgID,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          3,
			IsEdit:                  1,
			Creator:                 advice.ExecutionStaff,
			IsSys:                   1,
			PatientId:               advice.PatientId,
			WarehousingDetailId:     warehouse.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}

		CreateDrugFlowOne(drugflow)
		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}
		//查询是否存在数据

		details := &models.DrugAutomaticReduceDetail{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			PatientId:               advice.PatientId,
			Ctime:                   time.Now().Unix(),
			Mtime:                   time.Now().Unix(),
			Status:                  1,
			RecordTime:              advice.RecordDate,
			OrgId:                   orgID,
			DrugId:                  advice.DrugId,
			Count:                   deliver_number,
			CountUnit:               drup.MinUnit,
			WarehouseInfoId:         warehouse.ID,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}
		errTwo := AddSigleDrugAutoReduceRecordInfo(details)
		if errTwo != nil {
			return errTwo
		}

		// 出库完成后，要减去对应批次的库存数量
		// 判断处方里药品单位是拆零单位还是包装单位,	如果是拆零单位，则根据规格，将拆零数量转为包装数量
		var maxNumber int64 = 0
		var minNumber int64 = 0
		//var stock_max_number int64 = 0
		//stock_max_number = warehouse.StockMaxNumber

		maxNumber = deliver_number / drup.MinNumber
		minNumber = deliver_number % drup.MinNumber

		if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
			minNumber = maxNumber
		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < maxNumber && warehouse.StockMinNumber < minNumber {
				return errors.New("库存数量不足")
			}
		}

		warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber

		if warehouse.StockMaxNumber < 0 {
			warehouse.StockMaxNumber = 0
		}
		if warehouse.StockMinNumber < 0 {
			warehouse.StockMinNumber = 0
		}

		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockMinNumber < minNumber {

			warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
			warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
		} else {

			if minNumber > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
			}

			if minNumber == 0 && maxNumber != 1 {
				if warehouse.StockMinNumber > 0 {
					warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
				}

			}
		}

		if maxNumber == 1 && minNumber == 0 && drup.MaxUnit != drup.MinUnit {
			if (warehouse.StockMinNumber - deliver_number) > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number

				//if warehouse.StockMinNumber == 0 {
				//  warehouse.StockMaxNumber = stock_max_number
				//}
			}

		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < 0 && warehouse.StockMinNumber < 0 {
				return errors.New("库存数量不足")
			}
		}
		if warehouse.StockMinNumber <= 0 {
			warehouse.StockMinNumber = 0
		}

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)

		if errThree != nil {
			return errThree
		}

		return nil
	} else {
		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  warehouse.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   1,
			SysRecordTime:           advice.RecordDate,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Price:                   warehouse.RetailPrice,
			CountUnit:               drup.MinUnit,
			ProductDate:             warehouse.ProductDate,
			ExpiryDate:              warehouse.ExpiryDate,
			PatientId:               advice.PatientId,
			Count:                   deliver_number,
			WarehouseInfoId:         warehouse.ID,
			AdviceId:                advice.ID,
			StorehouseId:            storeConfig.DrugStorehouseOut,
			IsCheck:                 1,
		}
		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		details := &models.DrugAutomaticReduceDetail{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
			PatientId:               advice.PatientId,
			Ctime:                   time.Now().Unix(),
			Mtime:                   time.Now().Unix(),
			Status:                  1,
			RecordTime:              advice.RecordDate,
			OrgId:                   orgID,
			DrugId:                  advice.DrugId,
			Count:                   deliver_number,
			CountUnit:               drup.MinUnit,
			WarehouseInfoId:         warehouse.ID,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}
		errTwo := AddSigleDrugAutoReduceRecordInfo(details)
		if errTwo != nil {
			return errTwo
		}

		// 出库完成后，要将该批次库存清零
		warehouse.StockMaxNumber = 0
		warehouse.StockMinNumber = 0
		warehouse.Mtime = time.Now().Unix()

		info := models.XtDrugWarehouseInfo{
			ID:                warehouse.ID,
			WarehousingId:     warehouse.WarehousingId,
			DrugId:            warehouse.DrugId,
			Number:            warehouse.Number,
			ProductDate:       warehouse.ProductDate,
			ExpiryDate:        warehouse.ExpiryDate,
			WarehousingCount:  warehouse.WarehousingCount,
			Price:             warehouse.Price,
			TotalPrice:        warehouse.TotalPrice,
			Dealer:            warehouse.Dealer,
			Manufacturer:      warehouse.Manufacturer,
			Remark:            warehouse.Remark,
			Ctime:             warehouse.Ctime,
			Mtime:             warehouse.Mtime,
			Status:            1,
			OrgId:             warehouse.OrgId,
			IsReturn:          warehouse.IsReturn,
			WarehousingOrder:  warehouse.WarehousingOrder,
			Type:              warehouse.Type,
			RetailPrice:       warehouse.RetailPrice,
			RetailTotalPrice:  warehouse.RetailPrice,
			StockMaxNumber:    0,
			StockMinNumber:    0,
			BatchNumber:       warehouse.BatchNumber,
			MaxUnit:           warehouse.MaxUnit,
			WarehousingInfoId: warehouse.WarehousingInfoId,
			SupplyWarehouseId: warehouse.SupplyWarehouseId,
			StorehouseId:      storeConfig.DrugStorehouseOut,
			IsCheck:           1,
		}
		//扣减库存
		errThree := UpDateDrugWarehouseInfoByStock(&info)

		if errThree != nil {
			return errThree
		}

		drugflow := models.DrugFlow{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			Count:                   deliver_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               orgID,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          3,
			IsEdit:                  1,
			Creator:                 advice.ExecutionStaff,
			IsSys:                   1,
			PatientId:               advice.PatientId,
			WarehousingDetailId:     warehouse.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}

		CreateDrugFlowOne(drugflow)

		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		prescribingNumber_two_temp := deliver_number - stock_number

		overPlusNumber := float64(prescribingNumber_two_temp)

		advice.PrescribingNumber = float64(prescribingNumber_two_temp)
		advice.PrescribingNumberUnit = advice.PrescribingNumberUnit

		NewDrugDeliverInfo(orgID, overPlusNumber, warehouseout, drup, advice)
	}

	return
}

// 药品出库 递归方式
func NewHisDrugDeliverInfo(orgID int64, prescribingNumber float64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.HisDoctorAdviceInfo) (err error) {

	// 判断处方里药品单位是拆零单位还是包装单位,	如果是包装单位，则根据规格，将包装数量转为拆零数量
	var deliver_number int64 = 0
	var stock_number int64 = 0

	prescribingNumber_temp := strconv.FormatFloat(math.Abs(prescribingNumber), 'f', 0, 64)
	count, _ := strconv.ParseInt(prescribingNumber_temp, 10, 64)

	deliver_number = count

	var min_price float64

	if advice.PrescribingNumberUnit == drup.MaxUnit {
		min_price = drup.RetailPrice
	}
	if advice.PrescribingNumberUnit == drup.MinUnit {
		min_price = drup.MinPrice
	}

	if advice.PrescribingNumberUnit != drup.MaxUnit && advice.PrescribingNumberUnit != drup.MinUnit {
		min_price = drup.RetailPrice
	}

	fmt.Println(min_price)
	// 根据先进先出原则，查询最先入库的批次，进行出库
	// 如果没有对应的库存，则报错
	//开启事物
	storeConfig, _ := GetAllStoreHouseConfig(advice.UserOrgId)
	lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)
	if lastWarehouse.StockMinNumber >= drup.MinNumber {
		var stockMax int64
		var stockMin int64
		stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
		stockMin = lastWarehouse.StockMinNumber % drup.MinNumber
		ChangeMaxNumber(lastWarehouse.ID, stockMax)
		UpdateMinNumber(lastWarehouse.ID, stockMin)
	}
	warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)
	//查找药品信息

	if err != nil {

		return err
	}

	// 将该批次的剩余库存数量转换为拆零数量

	stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  warehouse.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   1,
			SysRecordTime:           advice.RecordDate,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Price:                   warehouse.RetailPrice,
			CountUnit:               drup.MinUnit,
			RetailPrice:             warehouse.RetailPrice,
			ProductDate:             warehouse.ProductDate,
			ExpiryDate:              warehouse.ExpiryDate,
			PatientId:               advice.PatientId,
			WarehouseInfoId:         warehouse.ID,
			Count:                   deliver_number,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
			IsCheck:                 1,
		}

		drugflow := models.DrugFlow{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			Count:                   deliver_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               orgID,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          3,
			IsEdit:                  1,
			Creator:                 advice.ExecutionStaff,
			IsSys:                   1,
			PatientId:               advice.PatientId,
			SystemTime:              advice.RecordDate,
			WarehousingDetailId:     warehouse.ID,
			AdviceId:                advice.ID,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}

		CreateDrugFlowOne(drugflow)
		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		details := &models.DrugAutomaticReduceDetail{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			PatientId:               advice.PatientId,
			Ctime:                   time.Now().Unix(),
			Mtime:                   time.Now().Unix(),
			Status:                  1,
			RecordTime:              advice.RecordDate,
			OrgId:                   orgID,
			DrugId:                  advice.DrugId,
			Count:                   deliver_number,
			CountUnit:               drup.MinUnit,
			WarehouseInfoId:         warehouse.ID,
			AdviceId:                advice.ID,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}
		errTwo := AddSigleDrugAutoReduceRecordInfo(details)
		if errTwo != nil {
			return errTwo
		}

		// 出库完成后，要减去对应批次的库存数量
		// 判断处方里药品单位是拆零单位还是包装单位,	如果是拆零单位，则根据规格，将拆零数量转为包装数量

		var maxNumber int64 = 0
		var minNumber int64 = 0
		//var stock_max_number int64 = 0
		//stock_max_number = warehouse.StockMaxNumber

		maxNumber = deliver_number / drup.MinNumber
		minNumber = deliver_number % drup.MinNumber

		if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
			minNumber = maxNumber
		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < maxNumber && warehouse.StockMinNumber < minNumber {
				return errors.New("库存数量不足")
			}
		}

		warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber

		if warehouse.StockMaxNumber < 0 {
			warehouse.StockMaxNumber = 0
		}
		if warehouse.StockMinNumber < 0 {
			warehouse.StockMinNumber = 0
		}

		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockMinNumber < minNumber {

			warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
			warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
		} else {

			if minNumber > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
			}

			if minNumber == 0 && maxNumber != 1 {
				if warehouse.StockMinNumber > 0 {
					warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
				}

			}
		}

		if maxNumber == 1 && minNumber == 0 && drup.MaxUnit != drup.MinUnit {
			if (warehouse.StockMinNumber - deliver_number) > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number

				//if warehouse.StockMinNumber == 0 {
				//  warehouse.StockMaxNumber = stock_max_number
				//}
			}

		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < 0 && warehouse.StockMinNumber < 0 {
				return errors.New("库存数量不足")
			}
		}
		if warehouse.StockMinNumber <= 0 {
			warehouse.StockMinNumber = 0
		}

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)

		if errThree != nil {
			return errThree
		}

		return nil
	} else {
		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  warehouse.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   1,
			SysRecordTime:           advice.RecordDate,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Price:                   warehouse.RetailPrice,
			RetailPrice:             warehouse.RetailPrice,
			ProductDate:             warehouse.ProductDate,
			ExpiryDate:              warehouse.ExpiryDate,
			PatientId:               advice.PatientId,
			WarehouseInfoId:         warehouse.ID,
			Count:                   stock_number,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
			IsCheck:                 1,
		}

		drugflow := models.DrugFlow{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			Count:                   stock_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               orgID,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          3,
			IsEdit:                  1,
			Creator:                 advice.ExecutionStaff,
			IsSys:                   1,
			PatientId:               advice.PatientId,
			SystemTime:              advice.RecordDate,
			WarehousingDetailId:     warehouse.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}

		CreateDrugFlowOne(drugflow)
		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		details := &models.DrugAutomaticReduceDetail{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			PatientId:               advice.PatientId,
			Ctime:                   time.Now().Unix(),
			Mtime:                   time.Now().Unix(),
			Status:                  1,
			RecordTime:              advice.RecordDate,
			OrgId:                   orgID,
			DrugId:                  advice.DrugId,
			Count:                   stock_number,
			CountUnit:               drup.MinUnit,
			WarehouseInfoId:         warehouse.ID,
			AdviceId:                advice.ID,
			StorehouseId:            storeConfig.DrugStorehouseOut,
		}
		errTwo := AddSigleDrugAutoReduceRecordInfo(details)
		if errTwo != nil {
			return errTwo
		}

		info := models.XtDrugWarehouseInfo{
			ID:                warehouse.ID,
			WarehousingId:     warehouse.WarehousingId,
			DrugId:            warehouse.DrugId,
			Number:            warehouse.Number,
			ProductDate:       warehouse.ProductDate,
			ExpiryDate:        warehouse.ExpiryDate,
			WarehousingCount:  warehouse.WarehousingCount,
			Price:             warehouse.RetailPrice,
			TotalPrice:        warehouse.TotalPrice,
			Dealer:            warehouse.Dealer,
			Manufacturer:      warehouse.Manufacturer,
			Remark:            warehouse.Remark,
			Ctime:             warehouse.Ctime,
			Mtime:             warehouse.Mtime,
			Status:            1,
			OrgId:             warehouse.OrgId,
			IsReturn:          warehouse.IsReturn,
			WarehousingOrder:  warehouse.WarehousingOrder,
			Type:              warehouse.Type,
			RetailPrice:       warehouse.RetailPrice,
			RetailTotalPrice:  warehouse.RetailPrice,
			StockMaxNumber:    0,
			StockMinNumber:    0,
			BatchNumber:       warehouse.BatchNumber,
			MaxUnit:           warehouse.MaxUnit,
			WarehousingInfoId: warehouse.WarehousingInfoId,
			SupplyWarehouseId: warehouse.SupplyWarehouseId,
			StorehouseId:      storeConfig.DrugStorehouseOut,
			IsCheck:           1,
		}
		errThree := UpDateDrugWarehouseInfoByStock(&info)
		if errThree != nil {
			return errThree
		}
		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		prescribingNumber_two_temp := deliver_number - stock_number
		overPlusNumber := float64(prescribingNumber_two_temp)
		advice.PrescribingNumber = float64(prescribingNumber_two_temp)
		advice.PrescribingNumberUnit = advice.PrescribingNumberUnit

		NewHisDrugDeliverInfo(orgID, overPlusNumber, warehouseout, drup, advice)
	}

	return
}

// 药品出库 递归方式
func HisAuToReduce(orgID int64, prescribingNumber float64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.HisDoctorAdviceInfo) (err error) {

	//查询最后一次出库数据
	drugInfo, _ := GetDrugWarehouseOutInfoIsExit(advice.DrugId, advice.PatientId, advice.RecordDate)

	prescribingNumber_temp := strconv.FormatFloat(math.Abs(prescribingNumber), 'f', 0, 64)
	count, _ := strconv.ParseInt(prescribingNumber_temp, 10, 64)
	var count_number int64
	var device_number int64
	if advice.PrescribingNumberUnit == drup.MaxUnit {
		device_number = count * drup.MinNumber
	}
	if advice.PrescribingNumberUnit == drup.MinUnit {
		device_number = count
	}

	if drugInfo.CountUnit == drup.MaxUnit {
		count_number = drugInfo.Count * drup.MinNumber
	}
	if drugInfo.CountUnit == drup.MinUnit {
		count_number = drugInfo.Count
	}

	//  比较数据大小
	//如果当期医嘱数量小于最后一次出库则退库
	if device_number < count_number {
		var cha_number int64
		var maxNumber int64
		var minNumber int64
		cha_number = count_number - device_number
		maxNumber = cha_number / drup.MinNumber
		minNumber = cha_number % drup.MinNumber
		//更改库存
		ModifyDrugWarehouse(drugInfo.WarehouseInfoId, maxNumber, minNumber)

		//修改出库表
		info := models.DrugWarehouseOutInfo{
			Count:     device_number,
			CountUnit: advice.PrescribingNumberUnit,
		}

		ModifyDrugWarehouseOutInfo(info, advice.DrugId, advice.PatientId, advice.RecordDate)

		//修改自动出库表
		detail := models.DrugAutomaticReduceDetail{
			Count:     device_number,
			CountUnit: advice.PrescribingNumberUnit,
		}
		ModifyAutoMaticReduce(detail, advice.PatientId, advice.RecordDate, advice.DrugId)
		//修改流水
		flow := models.DrugFlow{
			Count:   device_number,
			MaxUnit: drup.MinUnit,
		}
		ModifyDrugFlow(flow, drugInfo.WarehouseOutOrderNumber, advice.DrugId, advice.PatientId)

	}

	//如果当期医嘱数量大于最后一次出库则需要出库
	if device_number > count_number {
		var cha_number int64
		cha_number = device_number - count_number

		// 根据先进先出原则，查询最先入库的批次，进行出库

		storeConfig, _ := GetAllStoreHouseConfig(advice.UserOrgId)
		lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)
		if lastWarehouse.StockMinNumber >= drup.MinNumber {
			var stockMax int64
			var stockMin int64
			stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
			stockMin = lastWarehouse.StockMinNumber % drup.MinNumber
			ChangeMaxNumber(lastWarehouse.ID, stockMax)
			UpdateMinNumber(lastWarehouse.ID, stockMin)
		}
		warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)
		//查找药品信息
		//baseInfo, _ := FindBaseDrugLibRecord(advice.UserOrgId, advice.DrugId)
		if err != nil {
			return err
		}

		// 将该批次的剩余库存数量转换为拆零数量
		var stock_number int64
		var maxNumber int64
		var minNumber int64
		stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

		//如果库存数量大于出库数据,正常出库
		if stock_number >= cha_number {
			//扣减库存
			maxNumber = cha_number / drup.MinNumber
			minNumber = cha_number % drup.MinNumber

			if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
				minNumber = maxNumber
			}

			if drup.MaxUnit != drup.MinUnit {
				if warehouse.StockMaxNumber < maxNumber {
					return errors.New("库存数量不足")
				}
			}

			warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber
			if warehouse.StockMaxNumber < 0 {
				warehouse.StockMaxNumber = 0
			}

			warehouse.Mtime = time.Now().Unix()

			if warehouse.StockMinNumber < minNumber {
				warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
				warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
			} else {

				warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber

			}

			if drup.MaxUnit != drup.MinUnit {
				if warehouse.StockMaxNumber < 0 {
					return errors.New("库存数量不足")
				}
			}

			//扣减库存232332332332
			errThree := UpDateDrugWarehouseInfoByStock(&warehouse)

			if errThree != nil {
				return errThree
			}

			//修改出库表
			info := models.DrugWarehouseOutInfo{
				Count:     device_number,
				CountUnit: advice.PrescribingNumberUnit,
			}
			ModifyDrugWarehouseOutInfoOne(info, advice.DrugId, advice.PatientId, advice.RecordDate, warehouse.ID)
			//修改自动出库表
			detail := models.DrugAutomaticReduceDetail{
				Count:     device_number,
				CountUnit: advice.PrescribingNumberUnit,
			}
			ModifyAutoMaticReduceOne(detail, advice.PatientId, advice.RecordDate, advice.DrugId, warehouse.ID)
			//修改流水
			flow := models.DrugFlow{
				Count:   device_number,
				MaxUnit: advice.PrescribingNumberUnit,
			}
			ModifyDrugFlowOne(flow, drugInfo.WarehouseOutOrderNumber, advice.DrugId, advice.PatientId, warehouse.ID)
		}
		//如果库存数量小于出库数据,则需要出库到下一个批次
		if stock_number < cha_number {

			//修改出库表
			info := models.DrugWarehouseOutInfo{
				Count:     cha_number,
				CountUnit: advice.PrescribingNumberUnit,
			}
			ModifyDrugWarehouseOutInfoOne(info, advice.DrugId, advice.PatientId, advice.RecordDate, warehouse.ID)
			//修改自动出库表
			detail := models.DrugAutomaticReduceDetail{
				Count:     cha_number,
				CountUnit: advice.PrescribingNumberUnit,
			}
			ModifyAutoMaticReduceOne(detail, advice.PatientId, advice.RecordDate, advice.DrugId, warehouse.ID)
			//修改流水
			flow := models.DrugFlow{
				Count:   cha_number,
				MaxUnit: advice.PrescribingNumberUnit,
			}
			ModifyDrugFlowOne(flow, drugInfo.WarehouseOutOrderNumber, advice.DrugId, advice.PatientId, warehouse.ID)

			druginfo := &models.XtDrugWarehouseInfo{
				ID:                warehouse.ID,
				WarehousingId:     warehouse.WarehousingId,
				DrugId:            warehouse.DrugId,
				Number:            warehouse.Number,
				ProductDate:       warehouse.ProductDate,
				ExpiryDate:        warehouse.ExpiryDate,
				WarehousingCount:  warehouse.WarehousingCount,
				Price:             warehouse.Price,
				TotalPrice:        warehouse.TotalPrice,
				Dealer:            warehouse.Dealer,
				Manufacturer:      warehouse.Manufacturer,
				Remark:            warehouse.Remark,
				Ctime:             warehouse.Ctime,
				Mtime:             warehouse.Mtime,
				Status:            1,
				OrgId:             warehouse.OrgId,
				IsReturn:          warehouse.IsReturn,
				WarehousingOrder:  warehouse.WarehousingOrder,
				Type:              warehouse.Type,
				RetailPrice:       warehouse.RetailPrice,
				RetailTotalPrice:  warehouse.RetailPrice,
				StockMaxNumber:    0,
				StockMinNumber:    0,
				BatchNumber:       warehouse.BatchNumber,
				MaxUnit:           warehouse.MaxUnit,
				WarehousingInfoId: warehouse.WarehousingInfoId,
				StorehouseId:      storeConfig.DrugStorehouseOut,
				IsCheck:           1,
			}
			errThree := UpDateDrugWarehouseInfoByStock(druginfo)
			if errThree != nil {
				return errThree
			}

			// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
			prescribingNumber_two_temp := cha_number - stock_number

			overPlusNumber := float64(prescribingNumber_two_temp)

			advice.PrescribingNumber = float64(prescribingNumber_two_temp)

			advice.PrescribingNumberUnit = advice.PrescribingNumberUnit

			NewHisDrugDeliverInfo(orgID, overPlusNumber, warehouseout, drup, advice)

		}
	}

	return
}

//采购管理耗材出库逻辑
func ConsumablesDeliveryNight(orgID int64, record_time int64, goods *models.WarehouseOutInfo, warehouseOut *models.WarehouseOut, count int64, creator int64, warehouse_out_id int64, cancel_out_id int64) (err error) {

	var deliver_number int64 = 0
	var stock_number int64 = 0
	var maxNumber int64 = 0

	deliver_number = goods.Count

	// 根据先进先出原则，查询最先入库的批次，进行出库
	houseConfig, _ := GetAllStoreHouseConfig(orgID)
	// 如果没有对应的库存，则报错
	warehouse, err := FindFirstWarehousingInfoByStockNight(goods.GoodId, goods.GoodTypeId, warehouse_out_id, goods.IsSource, houseConfig.StorehouseOutInfo)
	if err != nil {

		return err
	}

	stock_number = warehouse.StockCount

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {

		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			WarehouseOutId:          goods.WarehouseOutId,
			WarehouseInfotId:        warehouse.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  goods.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			IsSys:                   0,
			SysRecordTime:           record_time,
			GoodTypeId:              goods.GoodTypeId,
			GoodId:                  goods.GoodId,
			ExpiryDate:              goods.ExpiryDate,
			ProductDate:             goods.ProductDate,
			Number:                  warehouse.Number,
			Price:                   goods.Price,
			LicenseNumber:           goods.LicenseNumber,
			SupplyCancelOutId:       warehouseOut.SupplyCancelOutId,
			StorehouseId:            warehouse.StorehouseId,
			IsCheck:                 1,
		}
		warehouseOutInfo.Count = goods.Count
		//添加出库单详情
		errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		stockFlow := models.VmStockFlow{
			WarehousingId:           warehouse.ID,
			GoodId:                  goods.GoodId,
			Number:                  warehouse.Number,
			LicenseNumber:           goods.LicenseNumber,
			Count:                   goods.Count,
			UserOrgId:               goods.OrgId,
			PatientId:               goods.PatientId,
			SystemTime:              record_time,
			ConsumableType:          2,
			IsSys:                   goods.IsSys,
			WarehousingOrder:        "",
			WarehouseOutId:          goods.WarehouseOutId,
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			IsEdit:                  1,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			Creator:                 creator,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.PackingPrice,
			WarehousingDetailId:     0,
			WarehouseOutDetailId:    warehouseOutInfo.ID,
			CancelOutDetailId:       0,
			ProductDate:             goods.ProductDate,
			ExpireDate:              goods.ExpiryDate,
			SupplyCancelOutId:       warehouseOut.SupplyCancelOutId,
			SupplyWarehouseId:       warehouseOut.SupplyWarehouseId,
			StorehouseId:            warehouse.StorehouseId,
		}

		//创建出库流水
		CreateStockFlowOne(stockFlow)

		maxNumber = goods.Count

		if warehouse.StockCount < maxNumber {
			return errors.New("库存数量不足")
		}

		warehouse.StockCount = warehouse.StockCount - maxNumber
		warehouse.Mtime = time.Now().Unix()

		//扣减库存
		errThree := UpDateWarehouseInfoByStock(&warehouse)
		ModifyGoodReduceInformationSix(warehouse.GoodId, maxNumber, warehouse.OrgId, warehouse.PackingPrice)
		if errThree != nil {
			return errThree
		}

	} else {

		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			WarehouseOutId:          goods.WarehouseOutId,
			WarehouseInfotId:        warehouse.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  goods.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			IsSys:                   0,
			SysRecordTime:           record_time,
			GoodTypeId:              goods.GoodTypeId,
			GoodId:                  goods.GoodId,
			ExpiryDate:              goods.ExpiryDate,
			ProductDate:             goods.ProductDate,
			Number:                  warehouse.Number,
			Price:                   warehouse.PackingPrice,
			LicenseNumber:           goods.LicenseNumber,
			SupplyCancelOutId:       warehouseOut.SupplyCancelOutId,
			StorehouseId:            warehouse.StorehouseId,
			IsCheck:                 1,
		}
		warehouseOutInfo.Count = stock_number

		//查询是否已经生成出库单
		info, errcodes := GetStockInRecoredByGoodIdOne(goods.GoodId, goods.GoodTypeId, goods.SysRecordTime, goods.OrgId)
		if errcodes == gorm.ErrRecordNotFound {
			//创建出库单
			errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
			if errOne != nil {
				return errOne
			}
		} else {
			warehouseOutInfo.Count = info.Count + stock_number

			UpdateAutoMaticReduceDetailOne(goods.GoodId, goods.GoodTypeId, goods.SysRecordTime, goods.OrgId, warehouseOutInfo)
		}

		stockFlow := models.VmStockFlow{
			WarehousingId:           warehouse.ID,
			GoodId:                  goods.GoodId,
			Number:                  warehouse.Number,
			LicenseNumber:           goods.LicenseNumber,
			Count:                   stock_number,
			UserOrgId:               goods.OrgId,
			PatientId:               0,
			SystemTime:              record_time,
			ConsumableType:          2,
			IsSys:                   0,
			WarehousingOrder:        "",
			WarehouseOutId:          goods.WarehouseOutId,
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			IsEdit:                  1,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			Creator:                 creator,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.PackingPrice,
			WarehousingDetailId:     0,
			WarehouseOutDetailId:    warehouseOutInfo.ID,
			CancelOutDetailId:       0,
			ProductDate:             goods.ProductDate,
			ExpireDate:              goods.ExpiryDate,
			SupplyCancelOutId:       warehouseOut.SupplyCancelOutId,
			SupplyWarehouseId:       warehouseOut.SupplyWarehouseId,
			StorehouseId:            warehouse.StorehouseId,
		}

		//创建出库明细
		CreateStockFlowOne(stockFlow)
		// 出库完成后，要将该批次库存清零
		ModifyGoodReduceInformationSix(warehouse.GoodId, warehouse.StockCount, warehouse.OrgId, warehouse.PackingPrice)
		warehouse.StockCount = 0
		warehouse.Mtime = time.Now().Unix()

		errThree := UpDateWarehouseInfoByStock(&warehouse)

		if errThree != nil {
			return errThree
		}
		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		goods.Count = deliver_number - stock_number

		ConsumablesDeliveryNight(orgID, record_time, goods, warehouseOut, count, creator, warehouse_out_id, cancel_out_id)

	}
	return nil
}

func FindFirstWarehousingInfoByStockNight(good_id int64, good_type_id int64, warehouse_out_id int64, is_source int64, storehouse_id int64) (info models.WarehousingInfo, err error) {

	if is_source == 1 {
		err = readDb.Model(&models.WarehousingInfo{}).Where("good_id = ? AND good_type_id = ? AND status = 1 and stock_count > 0 and supply_warehouse_id = ? and storehouse_id = ?", good_id, good_type_id, warehouse_out_id, storehouse_id).Order("ctime").First(&info).Error

	}
	if is_source == 2 || is_source == 0 {
		err = readDb.Model(&models.WarehousingInfo{}).Where("good_id = ? AND good_type_id = ? AND status = 1 and stock_count > 0 and storehouse_id = ?", good_id, good_type_id, storehouse_id).Order("ctime").First(&info).Error
	}
	return info, err
}

// 药品出库 递归方式
func AutoDrugDeliverInfoNight(orgID int64, prescribingNumber int64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DrugWarehouseOutInfo, warehouse_out_id int64, cancel_out_id int64) (err error) {

	houseConfig, _ := GetAllStoreHouseConfig(orgID)
	// 判断处方里药品单位是拆零单位还是包装单位,	如果是包装单位，则根据规格，将包装数量转为拆零数量
	var deliver_number int64 = 0
	var stock_number int64 = 0

	if advice.CountUnit == drup.MaxUnit {
		deliver_number = prescribingNumber * drup.MinNumber
	} else {
		deliver_number = prescribingNumber
	}

	// 根据先进先出原则，查询最先入库的批次，进行出库
	// 如果没有对应的库存，则报错
	//开启事物
	lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, houseConfig.DrugStorehouseOut)
	if lastWarehouse.StockMinNumber >= drup.MinNumber {
		var stockMax int64
		var stockMin int64
		stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
		stockMin = lastWarehouse.StockMinNumber % drup.MinNumber
		ChangeMaxNumber(lastWarehouse.ID, stockMax)
		UpdateMinNumber(lastWarehouse.ID, stockMin)
	}

	warehouse, err := FindLastDrugWarehousingInfoByIDSix(advice.DrugId, warehouse_out_id, advice.IsSource, houseConfig.DrugStorehouseOut)

	if err != nil {

		return err
	}

	// 将该批次的剩余库存数量转换为拆零数量

	stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {

		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          advice.WarehouseOutId,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  advice.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   0,
			SysRecordTime:           advice.SysRecordTime,
			DrugId:                  advice.DrugId,
			ExpiryDate:              advice.ExpiryDate,
			ProductDate:             advice.ProductDate,
			Number:                  advice.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   deliver_number,
			RetailPrice:             advice.RetailPrice,
			Price:                   advice.Price,
			WarehouseInfoId:         warehouse.ID,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyCancelOutId:       warehouseout.SupplyCancelOutId,
			SupplyWarehouseId:       warehouseout.SupplyWarehouseId,
			StorehouseId:            warehouse.StorehouseId,
			IsCheck:                 1,
		}

		warehouseOutInfo.Count = prescribingNumber
		warehouseOutInfo.CountUnit = advice.CountUnit

		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutId:          advice.WarehouseOutId,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             advice.ProductDate,
			ExpireDate:              advice.ExpiryDate,
			Count:                   deliver_number,
			Price:                   advice.Price,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  advice.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          2,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   0,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyCancelOutId:       warehouseout.SupplyCancelOutId,
			SupplyWarehouseId:       warehouseout.SupplyWarehouseId,
			SystemTime:              advice.SysRecordTime,
			StorehouseId:            warehouse.StorehouseId,
		}

		CreateDrugFlowOne(drugflow)
		// 出库完成后，要减去对应批次的库存数量
		// 判断处方里药品单位是拆零单位还是包装单位,	如果是拆零单位，则根据规格，将拆零数量转为包装数量
		var maxNumber int64 = 0
		var minNumber int64 = 0
		if advice.CountUnit == drup.MinUnit {
			maxNumber = prescribingNumber / drup.MinNumber
			minNumber = prescribingNumber % drup.MinNumber
			if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
				minNumber = maxNumber
			}
		} else {
			maxNumber = prescribingNumber
		}

		if warehouse.StockMaxNumber < maxNumber {

			return errors.New("库存数量不足")
		}

		warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber
		if warehouse.StockMaxNumber < 0 {
			warehouse.StockMaxNumber = 0
		}

		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockMinNumber < minNumber {
			warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
			warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
		} else {
			warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
		}

		if warehouse.StockMaxNumber < 0 {
			return errors.New("库存数量不足")
		}
		if warehouse.StockMaxNumber == 1 && warehouse.StockMinNumber == 1 && drup.MaxUnit == drup.MinUnit {
			warehouse.StockMinNumber = 0
		}

		if warehouse.StockMaxNumber > 0 {
			var sum_count int64
			sum_count = maxNumber * drup.MinNumber
			ModifyDrugReduceInformationSix(warehouse.DrugId, sum_count, warehouse.OrgId, warehouse.RetailPrice)
		}

		if warehouse.StockMinNumber > 0 {
			ModifyDrugReduceInformationSix(warehouse.DrugId, minNumber, warehouse.OrgId, warehouse.RetailPrice)
		}

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
		if errThree != nil {
			return errThree
		}

		return nil
	} else {
		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          advice.WarehouseOutId,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  advice.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   0,
			SysRecordTime:           advice.SysRecordTime,
			DrugId:                  advice.DrugId,
			ExpiryDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   stock_number,
			RetailPrice:             advice.RetailPrice,
			Price:                   advice.Price,
			WarehouseInfoId:         warehouse.ID,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyCancelOutId:       warehouseout.SupplyCancelOutId,
			SupplyWarehouseId:       warehouseout.SupplyWarehouseId,
			StorehouseId:            warehouse.StorehouseId,
			IsCheck:                 1,
		}
		warehouseOutInfo.Count = stock_number

		//warehouseOutInfo.CountUnit = advice.CountUnit

		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}
		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutId:          advice.WarehouseOutId,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             advice.ProductDate,
			ExpireDate:              advice.ExpiryDate,
			Count:                   stock_number,
			Price:                   advice.Price,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  advice.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          2,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   0,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyCancelOutId:       warehouseout.SupplyCancelOutId,
			SupplyWarehouseId:       warehouseout.SupplyWarehouseId,
			SystemTime:              advice.SysRecordTime,
			StorehouseId:            warehouse.StorehouseId,
		}
		CreateDrugFlowOne(drugflow)
		if warehouse.StockMaxNumber > 0 {
			var sum_count int64
			sum_count = warehouse.StockMaxNumber * drup.MinNumber
			ModifyDrugReduceInformationSix(warehouse.DrugId, sum_count, warehouse.OrgId, warehouse.RetailPrice)
		}

		if warehouse.StockMinNumber > 0 {
			ModifyDrugReduceInformationSix(warehouse.DrugId, warehouse.StockMinNumber, warehouse.OrgId, warehouse.RetailPrice)
		}

		// 出库完成后，要将该批次库存清零
		warehouse.StockMaxNumber = 0
		warehouse.StockMinNumber = 0
		warehouse.Mtime = time.Now().Unix()

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
		if errThree != nil {
			return errThree
		}
		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		prescribingNumber_two_temp := deliver_number - stock_number
		advice.CountUnit = drup.MinUnit

		AutoDrugDeliverInfoNight(orgID, prescribingNumber_two_temp, warehouseout, drup, advice, warehouse_out_id, cancel_out_id)
	}

	return
}

//调拨出库逻辑
func ConsumablesDeliveryTwelve(orgID int64, record_time int64, goods *models.WarehouseOutInfo, warehouseOut *models.WarehouseOut, count int64, creator int64, warehouseInfo *models.WarehousingInfo) (err error) {

	var deliver_number int64 = 0
	var stock_number int64 = 0
	var maxNumber int64 = 0

	deliver_number = goods.Count

	// 根据先进先出原则，查询最先入库的批次，进行出库

	// 如果没有对应的库存，则报错
	warehouse, err := FindFirstWarehousingInfoByStock(goods.GoodId, goods.GoodTypeId, goods.StorehouseId)
	if err != nil {

		return err
	}

	stock_number = warehouse.StockCount

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {

		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: goods.WarehouseOutOrderNumber,
			WarehouseOutId:          goods.WarehouseOutId,
			WarehouseInfotId:        warehouse.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  goods.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   0,
			SysRecordTime:           record_time,
			GoodTypeId:              warehouse.GoodTypeId,
			GoodId:                  warehouse.GoodId,
			ExpiryDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			Number:                  warehouse.Number,
			Price:                   warehouse.PackingPrice,
			LicenseNumber:           warehouse.LicenseNumber,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            goods.StorehouseId,
			SecondWarehouseInfoId:   goods.SecondWarehouseInfoId,
			IsCheck:                 1,
		}

		warehouseOutInfo.Count = goods.Count
		//添加出库单详情
		errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		stockFlow := models.VmStockFlow{
			WarehousingId:           warehouse.ID,
			GoodId:                  goods.GoodId,
			Number:                  warehouse.Number,
			LicenseNumber:           goods.LicenseNumber,
			Count:                   goods.Count,
			UserOrgId:               goods.OrgId,
			PatientId:               goods.PatientId,
			SystemTime:              record_time,
			ConsumableType:          12,
			IsSys:                   goods.IsSys,
			WarehousingOrder:        "",
			WarehouseOutOrderNumber: goods.WarehouseOutOrderNumber,
			WarehouseOutId:          goods.WarehouseOutId,
			IsEdit:                  1,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			Creator:                 creator,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.PackingPrice,
			WarehousingDetailId:     0,
			WarehouseOutDetailId:    warehouseOutInfo.ID,
			CancelOutDetailId:       0,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            warehouse.StorehouseId,
			SecondWarehouseInfoId:   goods.SecondWarehouseInfoId,
		}

		//创建出库流水
		CreateStockFlowOne(stockFlow)

		maxNumber = goods.Count

		if warehouse.StockCount < maxNumber {
			return errors.New("库存数量不足")
		}

		warehouse.StockCount = warehouse.StockCount - maxNumber
		warehouse.Mtime = time.Now().Unix()

		//扣减库存
		errThree := UpDateWarehouseInfoByStock(&warehouse)

		//入库
		warehouseInfo := &models.WarehousingInfo{
			WarehousingOrder:      warehouseInfo.WarehousingOrder,
			WarehousingId:         warehouseInfo.WarehousingId,
			GoodId:                warehouse.GoodId,
			Number:                warehouse.Number,
			GoodTypeId:            warehouse.GoodTypeId,
			ProductDate:           warehouse.ProductDate,
			ExpiryDate:            warehouse.ExpiryDate,
			WarehousingCount:      goods.Count,
			Price:                 warehouse.Price,
			TotalPrice:            0,
			Status:                1,
			Ctime:                 warehouse.Ctime,
			Remark:                goods.Remark,
			OrgId:                 warehouse.OrgId,
			Type:                  1,
			Manufacturer:          warehouse.Manufacturer,
			StockCount:            goods.Count,
			Dealer:                warehouse.Dealer,
			LicenseNumber:         "",
			PackingPrice:          warehouse.PackingPrice,
			StorehouseId:          warehouseInfo.StorehouseId,
			SecondWarehouseInfoId: warehouseInfo.SecondWarehouseInfoId,
			IsCheck:               1,
		}

		AddWarehosingInfo(warehouseInfo)

		stockInfoFlow := models.VmStockFlow{
			WarehousingId:           warehouseInfo.WarehousingId,
			GoodId:                  goods.GoodId,
			Number:                  warehouse.Number,
			LicenseNumber:           goods.LicenseNumber,
			Count:                   goods.Count,
			UserOrgId:               goods.OrgId,
			PatientId:               goods.PatientId,
			SystemTime:              record_time,
			ConsumableType:          13,
			IsSys:                   goods.IsSys,
			WarehousingOrder:        warehouseInfo.WarehousingOrder,
			WarehouseOutId:          0,
			WarehouseOutOrderNumber: "",
			IsEdit:                  1,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			Creator:                 creator,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.Price,
			WarehousingDetailId:     0,
			WarehouseOutDetailId:    warehouseOutInfo.ID,
			CancelOutDetailId:       0,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            warehouseInfo.StorehouseId,
			SecondWarehouseInfoId:   warehouseInfo.SecondWarehouseInfoId,
		}

		//创建入库流水
		CreateStockFlowOne(stockInfoFlow)

		if errThree != nil {
			return errThree
		}

	} else {

		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseOutOrderNumber: goods.WarehouseOutOrderNumber,
			WarehouseOutId:          goods.WarehouseOutId,
			WarehouseInfotId:        warehouse.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  goods.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   0,
			SysRecordTime:           record_time,
			GoodTypeId:              warehouse.GoodTypeId,
			GoodId:                  warehouse.GoodId,
			ExpiryDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			Number:                  warehouse.Number,
			Price:                   warehouse.PackingPrice,
			LicenseNumber:           warehouse.LicenseNumber,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            warehouse.StorehouseId,
			SecondWarehouseInfoId:   goods.SecondWarehouseInfoId,
			IsCheck:                 1,
		}
		warehouseOutInfo.Count = warehouse.StockCount

		//查询是否已经生成出库单
		info, errcodes := GetStockInRecoredByGoodIdOne(goods.GoodId, goods.GoodTypeId, goods.SysRecordTime, goods.OrgId)
		if errcodes == gorm.ErrRecordNotFound {
			//创建出库单
			errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
			if errOne != nil {
				return errOne
			}
		} else {
			warehouseOutInfo.Count = info.Count + stock_number

			UpdateAutoMaticReduceDetailOne(goods.GoodId, goods.GoodTypeId, goods.SysRecordTime, goods.OrgId, warehouseOutInfo)
		}

		stockFlow := models.VmStockFlow{
			WarehousingId:           warehouse.ID,
			GoodId:                  goods.GoodId,
			Number:                  warehouse.Number,
			LicenseNumber:           goods.LicenseNumber,
			Count:                   warehouse.StockCount,
			UserOrgId:               goods.OrgId,
			PatientId:               0,
			SystemTime:              record_time,
			ConsumableType:          12,
			IsSys:                   0,
			WarehousingOrder:        "",
			WarehouseOutOrderNumber: goods.WarehouseOutOrderNumber,
			WarehouseOutId:          goods.WarehouseOutId,
			IsEdit:                  1,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			Creator:                 creator,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.PackingPrice,
			WarehousingDetailId:     0,
			WarehouseOutDetailId:    warehouseOutInfo.ID,
			CancelOutDetailId:       0,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            goods.StorehouseId,
			SecondWarehouseInfoId:   goods.SecondWarehouseInfoId,
		}

		//创建出库明细
		CreateStockFlowOne(stockFlow)

		//入库
		warehouseInfo := &models.WarehousingInfo{
			WarehousingOrder:      warehouseInfo.WarehousingOrder,
			WarehousingId:         warehouseInfo.WarehousingId,
			GoodId:                warehouse.GoodId,
			Number:                warehouse.Number,
			GoodTypeId:            warehouse.GoodTypeId,
			ProductDate:           warehouse.ProductDate,
			ExpiryDate:            warehouse.ExpiryDate,
			WarehousingCount:      warehouse.StockCount,
			Price:                 warehouse.Price,
			TotalPrice:            0,
			Status:                1,
			Ctime:                 warehouse.Ctime,
			Remark:                goods.Remark,
			OrgId:                 warehouse.OrgId,
			Type:                  1,
			Manufacturer:          warehouse.Manufacturer,
			StockCount:            warehouse.StockCount,
			Dealer:                warehouse.Dealer,
			LicenseNumber:         "",
			PackingPrice:          warehouse.PackingPrice,
			StorehouseId:          warehouseInfo.StorehouseId,
			SecondWarehouseInfoId: warehouseInfo.SecondWarehouseInfoId,
			IsCheck:               1,
		}

		AddWarehosingInfo(warehouseInfo)

		stockInfoFlow := models.VmStockFlow{
			WarehousingId:           warehouseInfo.WarehousingId,
			GoodId:                  goods.GoodId,
			Number:                  warehouse.Number,
			LicenseNumber:           goods.LicenseNumber,
			Count:                   warehouse.StockCount,
			UserOrgId:               goods.OrgId,
			PatientId:               goods.PatientId,
			SystemTime:              record_time,
			ConsumableType:          13,
			IsSys:                   goods.IsSys,
			WarehousingOrder:        warehouseInfo.WarehousingOrder,
			WarehouseOutId:          warehouseOut.ID,
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			IsEdit:                  1,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			Creator:                 creator,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.Price,
			WarehousingDetailId:     0,
			WarehouseOutDetailId:    warehouseOutInfo.ID,
			CancelOutDetailId:       0,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            warehouseInfo.StorehouseId,
			SecondWarehouseInfoId:   warehouseInfo.SecondWarehouseInfoId,
		}

		//创建出库流水
		CreateStockFlowOne(stockInfoFlow)
		// 出库完成后，要将该批次库存清零
		warehouse.StockCount = 0
		warehouse.Mtime = time.Now().Unix()

		errThree := UpDateWarehouseInfoByStock(&warehouse)

		if errThree != nil {
			return errThree
		}
		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		goods.Count = deliver_number - stock_number

		ConsumablesDeliveryTwelve(orgID, record_time, goods, warehouseOut, count, creator, warehouseInfo)

	}
	return nil
}

func AddWarehosingInfo(info *models.WarehousingInfo) error {

	err = XTWriteDB().Create(&info).Error
	return err
}

// 药品出库 递归方式
func AutoDrugDeliverInfoTwelve(orgID int64, prescribingNumber int64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DrugWarehouseOutInfo, drugWarehouse *models.DrugWarehouseInfo) (err error) {

	// 判断处方里药品单位是拆零单位还是包装单位,	如果是包装单位，则根据规格，将包装数量转为拆零数量
	var deliver_number int64 = 0
	var stock_number int64 = 0

	if advice.CountUnit == drup.MaxUnit {
		deliver_number = prescribingNumber * drup.MinNumber
	} else {
		deliver_number = prescribingNumber
	}

	// 根据先进先出原则，查询最先入库的批次，进行出库
	// 如果没有对应的库存，则报错
	//开启事物
	storeConfig, _ := GetAllStoreHouseConfig(orgID)
	lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)
	if lastWarehouse.StockMinNumber >= drup.MinNumber {
		var stockMax int64
		var stockMin int64
		stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
		stockMin = lastWarehouse.StockMinNumber % drup.MinNumber
		ChangeMaxNumber(lastWarehouse.ID, stockMax)
		UpdateMinNumber(lastWarehouse.ID, stockMin)
	}

	warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId, warehouseout.StorehouseId)

	if err != nil {

		return err
	}

	// 将该批次的剩余库存数量转换为拆零数量

	stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {

		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: advice.WarehouseOutOrderNumber,
			WarehouseOutId:          advice.WarehouseOutId,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  advice.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   12,
			SysRecordTime:           advice.Ctime,
			DrugId:                  advice.DrugId,
			ExpiryDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   deliver_number,
			RetailPrice:             warehouse.RetailPrice,
			Price:                   warehouse.RetailPrice,
			WarehouseInfoId:         warehouse.ID,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			SecondWarehouseInfoId:   advice.SecondWarehouseInfoId,
			IsCheck:                 1,
		}

		warehouseOutInfo.Count = prescribingNumber
		warehouseOutInfo.CountUnit = advice.CountUnit

		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutOrderNumber: advice.WarehouseOutOrderNumber,
			WarehouseOutId:          advice.WarehouseOutId,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			Count:                   deliver_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          12,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   12,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			SecondWarehouseInfoId:   advice.SecondWarehouseInfoId,
		}

		CreateDrugFlowOne(drugflow)
		// 出库完成后，要减去对应批次的库存数量
		// 判断处方里药品单位是拆零单位还是包装单位,	如果是拆零单位，则根据规格，将拆零数量转为包装数量
		var maxNumber int64 = 0
		var minNumber int64 = 0
		if advice.CountUnit == drup.MinUnit {
			maxNumber = prescribingNumber / drup.MinNumber
			minNumber = prescribingNumber % drup.MinNumber
			if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
				minNumber = maxNumber
			}
		} else {
			maxNumber = prescribingNumber
		}

		if warehouse.StockMaxNumber < maxNumber {

			return errors.New("库存数量不足")
		}

		warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber
		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockMinNumber < minNumber {
			warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
			warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
		} else {
			warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
		}

		if warehouse.StockMaxNumber == 1 && warehouse.StockMinNumber == 1 && drup.MaxUnit == drup.MinUnit {
			warehouse.StockMinNumber = 0
		}

		if warehouse.StockMaxNumber < 0 {
			return errors.New("库存数量不足")
		}

		////扣减库存
		//if(warehouse.StockMaxNumber > 0){
		//  var sum_count int64
		//  sum_count = maxNumber * drup.MinNumber
		//  ModifyDrugReduceInformationSix(warehouse.DrugId,sum_count,warehouse.OrgId,warehouse.RetailPrice)
		//}
		//if(warehouse.StockMinNumber > 0){
		//  var sum_count int64
		//  sum_count = minNumber
		//  ModifyDrugReduceInformationSix(warehouse.DrugId,sum_count,warehouse.OrgId,warehouse.RetailPrice)
		//}

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)

		if errThree != nil {
			return errThree
		}

		//入库
		drugInfo := models.DrugWarehouseInfo{
			WarehousingOrder:      drugWarehouse.WarehousingOrder,
			WarehousingId:         drugWarehouse.WarehousingId,
			DrugId:                warehouse.DrugId,
			Number:                warehouse.Number,
			ProductDate:           warehouse.ProductDate,
			ExpiryDate:            warehouse.ExpiryDate,
			WarehousingCount:      deliver_number,
			Price:                 warehouse.RetailPrice,
			TotalPrice:            warehouse.TotalPrice,
			Status:                1,
			Ctime:                 warehouse.Ctime,
			Remark:                "",
			OrgId:                 warehouse.OrgId,
			Type:                  13,
			Manufacturer:          warehouse.Manufacturer,
			Dealer:                warehouse.Dealer,
			StockMaxNumber:        0,
			StockMinNumber:        deliver_number,
			BatchNumber:           warehouse.BatchNumber,
			MaxUnit:               drup.MinUnit,
			MinUnit:               drup.MinUnit,
			RetailPrice:           warehouse.RetailPrice,
			StorehouseId:          drugWarehouse.StorehouseId,
			SecondWarehouseInfoId: drugWarehouse.SecondWarehouseInfoId,
			IsCheck:               1,
		}

		CreateDrugWarehouseInfo(drugInfo)

		flow := models.DrugFlow{
			WarehousingId:           drugWarehouse.WarehousingId,
			DrugId:                  warehouse.DrugId,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   deliver_number,
			UserOrgId:               warehouse.OrgId,
			PatientId:               0,
			SystemTime:              0,
			ConsumableType:          13,
			IsSys:                   13,
			WarehousingOrder:        drugWarehouse.WarehousingOrder,
			WarehouseOutId:          0,
			WarehouseOutOrderNumber: "",
			IsEdit:                  0,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			Creator:                 0,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.RetailPrice,
			WarehousingDetailId:     warehouse.ID,
			WarehouseOutDetailId:    0,
			CancelOutDetailId:       0,
			ExpireDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			MaxUnit:                 drup.MinUnit,
			MinUnit:                 drup.MinUnit,
			StockMaxNumber:          0,
			StockMinNumber:          deliver_number,
			StorehouseId:            drugWarehouse.StorehouseId,
			SecondWarehouseInfoId:   drugWarehouse.SecondWarehouseInfoId,
		}

		CreateDrugFlowOne(flow)

		return nil
	} else {
		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: advice.WarehouseOutOrderNumber,
			WarehouseOutId:          advice.WarehouseOutId,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  advice.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   12,
			SysRecordTime:           advice.Ctime,
			DrugId:                  advice.DrugId,
			ExpiryDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   stock_number,
			RetailPrice:             advice.RetailPrice,
			Price:                   warehouse.RetailPrice,
			WarehouseInfoId:         warehouse.ID,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			SecondWarehouseInfoId:   advice.SecondWarehouseInfoId,
			IsCheck:                 1,
		}
		warehouseOutInfo.Count = stock_number

		//warehouseOutInfo.CountUnit = advice.CountUnit

		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}
		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutOrderNumber: advice.WarehouseOutOrderNumber,
			WarehouseOutId:          advice.WarehouseOutId,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             warehouse.ProductDate,
			ExpireDate:              warehouse.ExpiryDate,
			Count:                   stock_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          12,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   12,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			SecondWarehouseInfoId:   advice.SecondWarehouseInfoId,
		}
		CreateDrugFlowOne(drugflow)
		// 出库完成后，要将该批次库存清零

		//入库
		drugInfo := models.DrugWarehouseInfo{
			WarehousingOrder:      drugWarehouse.WarehousingOrder,
			WarehousingId:         drugWarehouse.WarehousingId,
			DrugId:                warehouse.DrugId,
			Number:                warehouse.Number,
			ProductDate:           warehouse.ProductDate,
			ExpiryDate:            warehouse.ExpiryDate,
			WarehousingCount:      stock_number,
			Price:                 warehouse.RetailPrice,
			TotalPrice:            warehouse.TotalPrice,
			Status:                1,
			Ctime:                 warehouse.Ctime,
			Remark:                "",
			OrgId:                 warehouse.OrgId,
			Type:                  13,
			Manufacturer:          warehouse.Manufacturer,
			Dealer:                warehouse.Dealer,
			StockMaxNumber:        0,
			StockMinNumber:        stock_number,
			RetailTotalPrice:      0,
			BatchNumber:           warehouse.BatchNumber,
			MaxUnit:               drup.MinUnit,
			MinUnit:               drup.MinUnit,
			RetailPrice:           warehouse.RetailPrice,
			StorehouseId:          drugWarehouse.StorehouseId,
			SecondWarehouseInfoId: drugWarehouse.SecondWarehouseInfoId,
		}

		CreateDrugWarehouseInfo(drugInfo)

		flow := models.DrugFlow{
			WarehousingId:           drugWarehouse.WarehousingId,
			DrugId:                  warehouse.DrugId,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   stock_number,
			UserOrgId:               warehouse.OrgId,
			PatientId:               0,
			SystemTime:              0,
			ConsumableType:          13,
			IsSys:                   13,
			WarehousingOrder:        drugWarehouse.WarehousingOrder,
			WarehouseOutId:          0,
			WarehouseOutOrderNumber: "",
			IsEdit:                  0,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            warehouse.Manufacturer,
			Dealer:                  warehouse.Dealer,
			Creator:                 0,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.RetailPrice,
			WarehousingDetailId:     warehouse.ID,
			WarehouseOutDetailId:    0,
			CancelOutDetailId:       0,
			ExpireDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			MaxUnit:                 drup.MinUnit,
			MinUnit:                 drup.MinUnit,
			StockMaxNumber:          0,
			StockMinNumber:          stock_number,
			StorehouseId:            drugWarehouse.StorehouseId,
			SecondWarehouseInfoId:   drugWarehouse.SecondWarehouseInfoId,
		}

		CreateDrugFlowOne(flow)

		warehouse.StockMaxNumber = 0
		warehouse.StockMinNumber = 0
		warehouse.Mtime = time.Now().Unix()

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
		if errThree != nil {
			return errThree
		}

		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		prescribingNumber_two_temp := deliver_number - stock_number

		advice.CountUnit = drup.MinUnit

		AutoDrugDeliverInfoTwelve(orgID, prescribingNumber_two_temp, warehouseout, drup, advice, drugWarehouse)
	}

	return
}

// 药品手动出库 递归方式
func AutoDrugDeliverInfoTwenty(orgID int64, prescribingNumber int64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DrugWarehouseOutInfo) (err error) {

	// 判断处方里药品单位是拆零单位还是包装单位,	如果是包装单位，则根据规格，将包装数量转为拆零数量
	var deliver_number int64 = 0
	var stock_number int64 = 0

	if advice.CountUnit == drup.MaxUnit {
		deliver_number = prescribingNumber * drup.MinNumber
	} else {
		deliver_number = prescribingNumber
	}

	// 根据先进先出原则，查询最先入库的批次，进行出库
	// 如果没有对应的库存，则报错
	//开启事物
	lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, warehouseout.StorehouseId)
	if lastWarehouse.StockMinNumber >= drup.MinNumber {
		var stockMax int64
		var stockMin int64
		stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
		stockMin = lastWarehouse.StockMinNumber % drup.MinNumber
		ChangeMaxNumber(lastWarehouse.ID, stockMax)
		UpdateMinNumber(lastWarehouse.ID, stockMin)
	}

	warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId, warehouseout.StorehouseId)

	if err != nil {

		return err
	}

	// 将该批次的剩余库存数量转换为拆零数量

	stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {

		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  advice.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   0,
			SysRecordTime:           advice.Ctime,
			DrugId:                  advice.DrugId,
			ExpiryDate:              advice.ExpiryDate,
			ProductDate:             advice.ProductDate,
			Number:                  advice.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   deliver_number,
			RetailPrice:             advice.RetailPrice,
			Price:                   warehouse.RetailPrice,
			WarehouseInfoId:         warehouse.ID,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
			IsCheck:                 1,
		}

		if warehouse.RetailPrice == 0 {
			warehouseOutInfo.Price = advice.Price
		}

		warehouseOutInfo.Count = prescribingNumber
		warehouseOutInfo.CountUnit = advice.CountUnit

		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             advice.ProductDate,
			ExpireDate:              advice.ExpiryDate,
			Count:                   deliver_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  advice.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          2,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   0,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
		}
		if warehouse.RetailPrice == 0 {
			drugflow.Price = advice.Price
		}

		CreateDrugFlowOne(drugflow)
		// 出库完成后，要减去对应批次的库存数量
		// 判断处方里药品单位是拆零单位还是包装单位,	如果是拆零单位，则根据规格，将拆零数量转为包装数量
		var maxNumber int64 = 0
		var minNumber int64 = 0
		//var stock_max_number int64 = 0
		//stock_max_number = warehouse.StockMaxNumber

		maxNumber = deliver_number / drup.MinNumber
		minNumber = deliver_number % drup.MinNumber

		if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
			minNumber = maxNumber
		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < maxNumber && warehouse.StockMinNumber < minNumber {
				return errors.New("库存数量不足")
			}
		}

		warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber

		if warehouse.StockMaxNumber < 0 {
			warehouse.StockMaxNumber = 0
		}
		if warehouse.StockMinNumber < 0 {
			warehouse.StockMinNumber = 0
		}

		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockMinNumber < minNumber {

			warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
			warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
		} else {
			if minNumber > 0 {
				if minNumber == 1 && maxNumber == 1 && drup.MaxUnit != drup.MinUnit {
					warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
				} else {
					warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
				}
			}

			if minNumber == 0 && maxNumber != 1 {
				if warehouse.StockMinNumber > 0 {
					warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
				}

			}

		}

		if maxNumber == 1 && minNumber == 0 && drup.MaxUnit != drup.MinUnit {
			if (warehouse.StockMinNumber - deliver_number) > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number

				//if warehouse.StockMinNumber == 0 {
				//  warehouse.StockMaxNumber = stock_max_number
				//}
			}

		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < 0 && warehouse.StockMinNumber < 0 {
				return errors.New("库存数量不足")
			}
		}
		if warehouse.StockMinNumber <= 0 {
			warehouse.StockMinNumber = 0
		}

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)

		if errThree != nil {
			return errThree
		}

		//查询默认仓库
		houseConfig, _ := GetAllStoreHouseConfig(orgID)
		//查询默认仓库剩余多少库存
		list, _ := GetDrugSumCountByStorehouseId(houseConfig.DrugStorehouseOut, orgID, warehouse.DrugId)
		var sum_count int64
		var sum_in_count int64
		for _, it := range list {
			baseDrug, _ := GetBaseDrugMedical(it.DrugId)
			if it.MaxUnit == baseDrug.MaxUnit {
				it.StockMaxNumber = it.StockMaxNumber * baseDrug.MinNumber
				it.WarehousingCount = it.WarehousingCount * baseDrug.MinNumber
				sum_count += it.StockMaxNumber + it.StockMinNumber
				sum_in_count += it.WarehousingCount
			}
		}
		UpdateMedicalSumCount(warehouse.DrugId, sum_count, sum_in_count, orgID)

		return nil

	} else {
		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  advice.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   0,
			SysRecordTime:           advice.Ctime,
			DrugId:                  advice.DrugId,
			ExpiryDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   stock_number,
			RetailPrice:             advice.RetailPrice,
			Price:                   warehouse.RetailPrice,
			WarehouseInfoId:         warehouse.ID,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
			IsCheck:                 1,
		}
		if warehouse.RetailPrice == 0 {
			warehouseOutInfo.Price = advice.Price
		}
		warehouseOutInfo.Count = stock_number

		//warehouseOutInfo.CountUnit = advice.CountUnit

		errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
		if errOne != nil {
			return errOne
		}
		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             advice.ProductDate,
			ExpireDate:              advice.ExpiryDate,
			Count:                   stock_number,
			Price:                   warehouse.RetailPrice,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  advice.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          2,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   0,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
		}
		if warehouse.RetailPrice == 0 {
			drugflow.Price = advice.Price
		}
		CreateDrugFlowOne(drugflow)
		// 出库完成后，要将该批次库存清零
		//扣减库存

		warehouse.StockMaxNumber = 0
		warehouse.StockMinNumber = 0
		warehouse.Mtime = time.Now().Unix()

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)

		//查询默认仓库
		houseConfig, _ := GetAllStoreHouseConfig(orgID)
		//查询默认仓库剩余多少库存
		list, _ := GetDrugSumCountByStorehouseId(houseConfig.DrugStorehouseOut, orgID, warehouse.DrugId)
		var sum_count int64
		var sum_in_count int64
		for _, it := range list {
			baseDrug, _ := GetBaseDrugMedical(it.DrugId)
			if it.MaxUnit == baseDrug.MaxUnit {
				it.StockMaxNumber = it.StockMaxNumber * baseDrug.MinNumber
				it.WarehousingCount = it.WarehousingCount * baseDrug.MinNumber
				sum_count += it.StockMaxNumber + it.StockMinNumber
				sum_in_count += it.WarehousingCount
			}
		}
		UpdateMedicalSumCount(warehouse.DrugId, sum_count, sum_in_count, orgID)
		if errThree != nil {
			return errThree
		}
		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		prescribingNumber_two_temp := deliver_number - stock_number

		advice.CountUnit = drup.MinUnit

		AutoDrugDeliverInfoTwenty(orgID, prescribingNumber_two_temp, warehouseout, drup, advice)
	}

	return
}

// 药品手动出库 递归方式
func AutoDrugDeliverInfoTwentyOne(orgID int64, prescribingNumber int64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DrugWarehouseOutInfo) (err error) {
	//开事务
	//tx := XTWriteDB().Begin()
	// 判断处方里药品单位是拆零单位还是包装单位,	如果是包装单位，则根据规格，将包装数量转为拆零数量
	var deliver_number int64 = 0
	var stock_number int64 = 0

	if advice.CountUnit == drup.MaxUnit {
		deliver_number = prescribingNumber * drup.MinNumber
	} else {
		deliver_number = prescribingNumber
	}

	// 根据先进先出原则，查询最先入库的批次，进行出库
	// 如果没有对应的库存，则报错
	//开启事物
	storeConfig, _ := GetAllStoreHouseConfig(orgID)
	lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, storeConfig.DrugStorehouseOut)
	if lastWarehouse.StockMinNumber >= drup.MinNumber {
		var stockMax int64
		var stockMin int64
		stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
		stockMin = lastWarehouse.StockMinNumber % drup.MinNumber
		ChangeMaxNumber(lastWarehouse.ID, stockMax)
		UpdateMinNumber(lastWarehouse.ID, stockMin)
	}
	warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId, warehouseout.StorehouseId)

	if err != nil {

		return err
	}

	// 将该批次的剩余库存数量转换为拆零数量

	stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {

		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  advice.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   0,
			SysRecordTime:           advice.Ctime,
			DrugId:                  advice.DrugId,
			ExpiryDate:              advice.ExpiryDate,
			ProductDate:             advice.ProductDate,
			Number:                  advice.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   deliver_number,
			RetailPrice:             advice.RetailPrice,
			Price:                   advice.Price,
			WarehouseInfoId:         warehouse.ID,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
			LastPrice:               warehouse.Price,
			StockCount:              advice.StockCount,
			IsCheck:                 1,
		}

		warehouseOutInfo.Count = prescribingNumber
		warehouseOutInfo.CountUnit = advice.CountUnit

		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             advice.ProductDate,
			ExpireDate:              advice.ExpiryDate,
			Count:                   deliver_number,
			Price:                   advice.Price,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  advice.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          2,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   0,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
			LastPrice:               warehouse.Price,
			StockCount:              advice.StockCount,
		}
		if warehouse.RetailPrice == 0 {
			drugflow.Price = advice.Price
		}

		CreateDrugFlowOne(drugflow)
		// 出库完成后，要减去对应批次的库存数量
		// 判断处方里药品单位是拆零单位还是包装单位,	如果是拆零单位，则根据规格，将拆零数量转为包装数量
		var maxNumber int64 = 0
		var minNumber int64 = 0
		//var stock_max_number int64 = 0
		//stock_max_number = warehouse.StockMaxNumber

		maxNumber = deliver_number / drup.MinNumber
		minNumber = deliver_number % drup.MinNumber

		if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
			minNumber = maxNumber
		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < maxNumber && warehouse.StockMinNumber < minNumber {
				return errors.New("库存数量不足")
			}
		}

		warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber

		if warehouse.StockMaxNumber < 0 {
			warehouse.StockMaxNumber = 0
		}
		if warehouse.StockMinNumber < 0 {
			warehouse.StockMinNumber = 0
		}

		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockMinNumber < minNumber {

			warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
			warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
		} else {
			if minNumber > 0 {
				if minNumber == 1 && maxNumber == 1 && drup.MaxUnit != drup.MinUnit {
					warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
				} else {
					warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
				}
			}

			if minNumber == 0 && maxNumber != 1 {
				if warehouse.StockMinNumber > 0 {
					warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
				}

			}

		}

		if maxNumber == 1 && minNumber == 0 && drup.MaxUnit != drup.MinUnit {
			if (warehouse.StockMinNumber - deliver_number) > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number

				//if warehouse.StockMinNumber == 0 {
				//  warehouse.StockMaxNumber = stock_max_number
				//}
			}

		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < 0 && warehouse.StockMinNumber < 0 {
				return errors.New("库存数量不足")
			}
		}
		if warehouse.StockMinNumber <= 0 {
			warehouse.StockMinNumber = 0
		}

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
		fmt.Println(errThree)
		//if errThree != nil {
		//	utils.ErrorLog("事务失败,原因为: %v", err.Error())
		//	tx.Rollback()
		//} else {
		//	tx.Commit()
		//}

		//查询默认仓库
		houseConfig, _ := GetAllStoreHouseConfig(orgID)
		//查询默认仓库剩余多少库存
		list, _ := GetDrugSumCountByStorehouseId(houseConfig.DrugStorehouseOut, orgID, warehouse.DrugId)
		var sum_count int64
		var sum_in_count int64
		for _, it := range list {
			baseDrug, _ := GetBaseDrugMedical(it.DrugId)
			if it.MaxUnit == baseDrug.MaxUnit {
				it.StockMaxNumber = it.StockMaxNumber * baseDrug.MinNumber
				it.WarehousingCount = it.WarehousingCount * baseDrug.MinNumber
				sum_count += it.StockMaxNumber + it.StockMinNumber
				sum_in_count += it.WarehousingCount
			}
		}
		UpdateMedicalSumCount(warehouse.DrugId, sum_count, sum_in_count, orgID)

		return nil

	} else {
		// 当该批次的库存数量小于出库数量的话，则先把该批次出库完后，再进行递归出库
		warehouseOutInfo := &models.DrugWarehouseOutInfo{
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			WarehouseOutId:          warehouseout.ID,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Remark:                  advice.Remark,
			OrgId:                   orgID,
			Type:                    1,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  warehouse.Dealer,
			IsSys:                   0,
			SysRecordTime:           advice.Ctime,
			DrugId:                  advice.DrugId,
			ExpiryDate:              warehouse.ExpiryDate,
			ProductDate:             warehouse.ProductDate,
			Number:                  warehouse.Number,
			BatchNumber:             warehouse.BatchNumber,
			Count:                   stock_number,
			RetailPrice:             advice.RetailPrice,
			Price:                   advice.Price,
			WarehouseInfoId:         warehouse.ID,
			CountUnit:               drup.MinUnit,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
			LastPrice:               warehouse.Price,
			StockCount:              advice.StockCount,
			IsCheck:                 1,
		}

		warehouseOutInfo.Count = stock_number

		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)

		drugflow := models.DrugFlow{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             advice.ProductDate,
			ExpireDate:              advice.ExpiryDate,
			Count:                   stock_number,
			Price:                   advice.Price,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  advice.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          2,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   0,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
			LastPrice:               warehouse.Price,
			StockCount:              advice.StockCount,
		}

		CreateDrugFlowOne(drugflow)
		// 出库完成后，要将该批次库存清零
		//扣减库存

		warehouse.StockMaxNumber = 0
		warehouse.StockMinNumber = 0
		warehouse.Mtime = time.Now().Unix()

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
		fmt.Println(errThree)
		//if errThree != nil {
		//	utils.ErrorLog("事务失败,原因为: %v", err.Error())
		//	tx.Rollback()
		//} else {
		//	tx.Commit()
		//}

		//查询默认仓库
		houseConfig, _ := GetAllStoreHouseConfig(orgID)
		//查询默认仓库剩余多少库存
		list, _ := GetDrugSumCountByStorehouseId(houseConfig.DrugStorehouseOut, orgID, warehouse.DrugId)
		var sum_count int64
		var sum_in_count int64
		for _, it := range list {
			baseDrug, _ := GetBaseDrugMedical(it.DrugId)
			if it.MaxUnit == baseDrug.MaxUnit {
				it.StockMaxNumber = it.StockMaxNumber * baseDrug.MinNumber
				it.WarehousingCount = it.WarehousingCount * baseDrug.MinNumber
				sum_count += it.StockMaxNumber + it.StockMinNumber
				sum_in_count += it.WarehousingCount
			}
		}
		UpdateMedicalSumCount(warehouse.DrugId, sum_count, sum_in_count, orgID)
		if errThree != nil {
			return errThree
		}
		// 清零完该库存后，还有剩余出库未出完，进行对应的递归操作
		prescribingNumber_two_temp := deliver_number - stock_number

		advice.CountUnit = drup.MinUnit

		AutoDrugDeliverInfoTwentyOne(orgID, prescribingNumber_two_temp, warehouseout, drup, advice)
	}

	return
}

//耗材出库
func ConsumablesDeliveryThirty(orgID int64, record_time int64, goods *models.WarehouseOutInfo, warehouseOut *models.WarehouseOut, count int64, creator int64) (err error) {

	var deliver_number int64 = 0
	var stock_number int64 = 0
	var maxNumber int64 = 0

	deliver_number = goods.Count

	// 根据先进先出原则，查询最先入库的批次，进行出库

	// 如果没有对应的库存，则报错
	warehouse, err := FindFirstWarehousingInfoByStock(goods.GoodId, goods.GoodTypeId, goods.StorehouseId)
	if err != nil {

		return err
	}

	stock_number = warehouse.StockCount

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {
		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseInfotId: warehouse.ID,
		}
		//添加出库单详情
		errOne := UpdatedSigleWarehouseOutInfo(goods.ID, warehouseOutInfo)
		if errOne != nil {
			return errOne
		}

		stockFlow := models.VmStockFlow{
			WarehousingId:           warehouse.ID,
			GoodId:                  goods.GoodId,
			Number:                  warehouse.Number,
			LicenseNumber:           goods.LicenseNumber,
			Count:                   goods.Count,
			UserOrgId:               goods.OrgId,
			PatientId:               goods.PatientId,
			SystemTime:              record_time,
			ConsumableType:          2,
			IsSys:                   goods.IsSys,
			WarehousingOrder:        "",
			WarehouseOutId:          warehouseOut.ID,
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			IsEdit:                  1,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			Creator:                 creator,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.PackingPrice,
			WarehousingDetailId:     0,
			WarehouseOutDetailId:    warehouseOutInfo.ID,
			CancelOutDetailId:       0,
			ProductDate:             goods.ProductDate,
			ExpireDate:              goods.ExpiryDate,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            warehouse.StorehouseId,
			AdminUserId:             goods.AdminUserId,
			BuyPrice:                warehouse.Price,
			StockCount:              goods.StockCount,
		}
		//创建出库流水
		CreateStockFlowOne(stockFlow)

		UpdateGoodWarehouseOutById(goods.ID, warehouse.ID, goods.OrgId)

		maxNumber = goods.Count

		if warehouse.StockCount < maxNumber {
			return errors.New("库存数量不足")
		}
		warehouse.StockCount = warehouse.StockCount - maxNumber
		warehouse.Mtime = time.Now().Unix()

		//扣减库存
		errThree := UpDateWarehouseInfoByStock(&warehouse)
		fmt.Println(errThree)

		//查询该机构默认仓库
		storeConfig, _ := GetAllStoreHouseConfig(goods.OrgId)
		//查询剩余库存
		goodList, _ := GetGoodSumCountByStoreId(storeConfig.StorehouseOutInfo, goods.GoodId, goods.OrgId)
		var sum_count int64
		var sum_in_count int64
		for _, item := range goodList {
			sum_count += item.StockCount
			sum_in_count += item.WarehousingCount
		}
		UpdateGoodByGoodId(goods.GoodId, sum_count, sum_in_count, goods.OrgId)
		if errThree != nil {
			return errThree
		}
		return nil
	} else {
		warehouseOutInfo := &models.WarehouseOutInfo{
			WarehouseInfotId: warehouse.ID,
		}
		//添加出库单详情
		errOne := UpdatedSigleWarehouseOutInfo(goods.ID, warehouseOutInfo)

		if errOne != nil {
			return errOne
		}

		stockFlow := models.VmStockFlow{
			WarehousingId:           warehouse.ID,
			GoodId:                  goods.GoodId,
			Number:                  warehouse.Number,
			LicenseNumber:           goods.LicenseNumber,
			Count:                   stock_number,
			UserOrgId:               goods.OrgId,
			PatientId:               goods.PatientId,
			SystemTime:              record_time,
			ConsumableType:          2,
			IsSys:                   goods.IsSys,
			WarehousingOrder:        "",
			WarehouseOutId:          warehouseOut.ID,
			WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
			IsEdit:                  1,
			CancelStockId:           0,
			CancelOrderNumber:       "",
			Manufacturer:            goods.Manufacturer,
			Dealer:                  goods.Dealer,
			Creator:                 creator,
			UpdateCreator:           0,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			Mtime:                   0,
			Price:                   warehouse.PackingPrice,
			WarehousingDetailId:     0,
			WarehouseOutDetailId:    warehouseOutInfo.ID,
			CancelOutDetailId:       0,
			ProductDate:             goods.ProductDate,
			ExpireDate:              goods.ExpiryDate,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            warehouse.StorehouseId,
			AdminUserId:             goods.AdminUserId,
			BuyPrice:                warehouse.Price,
			StockCount:              goods.StockCount,
		}
		//创建出库流水
		CreateStockFlowOne(stockFlow)
		UpdateGoodWarehouseOutById(goods.ID, warehouse.ID, goods.OrgId)
	}

	//查询该机构默认仓库
	storeConfig, _ := GetAllStoreHouseConfig(goods.OrgId)
	//查询剩余库存
	goodList, _ := GetGoodSumCountByStoreId(storeConfig.StorehouseOutInfo, goods.GoodId, goods.OrgId)
	var sum_count int64
	var sum_in_count int64
	for _, item := range goodList {
		sum_count += item.StockCount
		sum_in_count += item.WarehousingCount
	}
	UpdateGoodByGoodId(goods.GoodId, sum_count, sum_in_count, goods.OrgId)
	// 出库完成后，要将该批次库存清零
	warehouse.StockCount = 0
	warehouse.Mtime = time.Now().Unix()

	errThree := UpDateWarehouseInfoByStock(&warehouse)
	fmt.Println(errThree)

	goods.Count = deliver_number - stock_number
	ConsumablesDeliveryThirty(orgID, record_time, goods, warehouseOut, count, creator)

	return nil
}

// 药品手动出库 递归方式
func AutoDrugDeliverInfoFourtyOne(orgID int64, prescribingNumber int64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DrugWarehouseOutInfo) (err error) {
	//开事务
	// 判断处方里药品单位是拆零单位还是包装单位,	如果是包装单位，则根据规格，将包装数量转为拆零数量
	var deliver_number int64 = 0
	var stock_number int64 = 0

	deliver_number = prescribingNumber

	//开启事物
	lastWarehouse, _ := FindLastDrugWarehousingInfoByID(advice.DrugId, warehouseout.StorehouseId)
	if lastWarehouse.StockMinNumber >= drup.MinNumber {
		var stockMax int64
		var stockMin int64
		stockMax = lastWarehouse.StockMinNumber / drup.MinNumber
		stockMin = lastWarehouse.StockMinNumber % drup.MinNumber
		ChangeMaxNumber(lastWarehouse.ID, stockMax)
		UpdateMinNumber(lastWarehouse.ID, stockMin)
	}

	warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId, warehouseout.StorehouseId)

	if err != nil {

		return err
	}

	// 将该批次的剩余库存数量转换为拆零数量

	stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber

	// 当库存数量大于或等于出库数量的话，则正常出库该批次
	if stock_number >= deliver_number {

		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             advice.ProductDate,
			ExpireDate:              advice.ExpiryDate,
			Count:                   deliver_number,
			Price:                   advice.Price,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  advice.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          2,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   0,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
			LastPrice:               warehouse.Price,
			StockCount:              advice.StockCount,
		}
		if warehouse.RetailPrice == 0 {
			drugflow.Price = advice.Price
		}

		CreateDrugFlowOne(drugflow)

		//更新出库id
		UpdateDrugWarehouseOutInfo(advice.ID, warehouse.ID, advice.OrgId)

		// 出库完成后，要减去对应批次的库存数量
		// 判断处方里药品单位是拆零单位还是包装单位,	如果是拆零单位，则根据规格，将拆零数量转为包装数量
		var maxNumber int64 = 0
		var minNumber int64 = 0
		//var stock_max_number int64 = 0
		//stock_max_number = warehouse.StockMaxNumber

		maxNumber = deliver_number / drup.MinNumber
		minNumber = deliver_number % drup.MinNumber

		if warehouse.StockMaxNumber == 0 && drup.MaxUnit == drup.MinUnit {
			minNumber = maxNumber
		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < maxNumber && warehouse.StockMinNumber < minNumber {
				return errors.New("库存数量不足")
			}
		}

		warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber

		if warehouse.StockMaxNumber < 0 {
			warehouse.StockMaxNumber = 0
		}
		if warehouse.StockMinNumber < 0 {
			warehouse.StockMinNumber = 0
		}

		warehouse.Mtime = time.Now().Unix()

		if warehouse.StockMinNumber < minNumber {

			warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
			warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
		} else {
			if minNumber > 0 {
				if minNumber == 1 && maxNumber == 1 && drup.MaxUnit != drup.MinUnit {
					warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
				} else {
					warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
				}
			}

			if minNumber == 0 && maxNumber != 1 {
				if warehouse.StockMinNumber > 0 {
					warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
				}

			}

		}

		if maxNumber == 1 && minNumber == 0 && drup.MaxUnit != drup.MinUnit {
			if (warehouse.StockMinNumber - deliver_number) > 0 {
				warehouse.StockMinNumber = warehouse.StockMinNumber - deliver_number
				//if warehouse.StockMinNumber == 0 {
				//  warehouse.StockMaxNumber = stock_max_number
				//}
			}

		}

		if drup.MaxUnit != drup.MinUnit {
			if warehouse.StockMaxNumber < 0 && warehouse.StockMinNumber < 0 {
				return errors.New("库存数量不足")
			}
		}
		if warehouse.StockMinNumber <= 0 {
			warehouse.StockMinNumber = 0
		}

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
		fmt.Println(errThree)

		return nil

	} else {
		drugWareInfo, _ := GetLastWarehouseOutInfoById(advice.DrugId)
		drugflow := models.DrugFlow{
			WarehouseOutId:          warehouseout.ID,
			WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
			DrugId:                  advice.DrugId,
			Number:                  warehouse.Number,
			ProductDate:             advice.ProductDate,
			ExpireDate:              advice.ExpiryDate,
			Count:                   stock_number,
			Price:                   advice.Price,
			Status:                  1,
			Ctime:                   time.Now().Unix(),
			UserOrgId:               advice.OrgId,
			Manufacturer:            advice.Manufacturer,
			Dealer:                  advice.Dealer,
			BatchNumber:             warehouse.BatchNumber,
			MaxUnit:                 drup.MinUnit,
			ConsumableType:          2,
			IsEdit:                  1,
			Creator:                 0,
			IsSys:                   0,
			WarehouseOutDetailId:    drugWareInfo.ID,
			AdviceId:                advice.ID,
			SupplyWarehouseId:       warehouse.SupplyWarehouseId,
			StorehouseId:            advice.StorehouseId,
			AdminUserId:             advice.AdminUserId,
			LastPrice:               warehouse.Price,
			StockCount:              advice.StockCount,
		}

		CreateDrugFlowOne(drugflow)
		//更新出库id
		UpdateDrugWarehouseOutInfo(advice.ID, warehouse.ID, advice.OrgId)
		// 出库完成后，要将该批次库存清零
		//扣减库存

		warehouse.StockMaxNumber = 0
		warehouse.StockMinNumber = 0
		warehouse.Mtime = time.Now().Unix()

		errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
		fmt.Println(errThree)

		if errThree != nil {
			return errThree
		}

		prescribingNumber_two_temp := deliver_number - stock_number

		advice.CountUnit = drup.MinUnit

		AutoDrugDeliverInfoFourtyOne(orgID, prescribingNumber_two_temp, warehouseout, drup, advice)
	}

	return
}

func UpdateDrugWarehouseOutInfo(id int64, warehouse_info_id int64, org_id int64) error {

	err = XTWriteDB().Model(&models.DrugWarehouseOutInfo{}).Where("id = ? and org_id = ? and status = 1", id, org_id).Update(map[string]interface{}{"warehouse_info_id": warehouse_info_id}).Error
	return err
}

func UpdateGoodWarehouseOutById(id int64, warehouse_info_id int64, org_id int64) error {

	err := XTWriteDB().Model(models.WarehouseOutInfo{}).Where("id = ?  and org_id = ? and status = 1", id, org_id).Update(map[string]interface{}{"warehouse_info_id": warehouse_info_id}).Error
	return err
}

func ChangeMaxNumber(id int64, count int64) error {

	err = XTWriteDB().Model(&models.DrugWarehouseInfo{}).Where("id = ? and status = 1 and is_check = 1", id).UpdateColumn("stock_max_number", gorm.Expr("stock_max_number + ?", count)).Error
	return err

}

func UpdateMinNumber(id int64, count int64) error {

	err := XTWriteDB().Model(&models.DrugWarehouseInfo{}).Where("id = ? and status = 1 and is_check = 1", id).Update(map[string]interface{}{"stock_min_number": count}).Error
	return err
}

func FindLastDrugWarehouseOutInfo(orgid int64) (models.DrugWarehouseOutInfo, error) {
	info := models.DrugWarehouseOutInfo{}
	err := XTReadDB().Where("org_id = ? and status = 1", orgid).Last(&info).Error
	return info, err
}
