package service

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

func AddSigleDealer(dealer *models.Dealer) (error, *models.Dealer) {
	err := writeDb.Create(&dealer).Error
	return err, dealer
}

func ModifyDealer(dealer *models.Dealer) error {
	err := writeDb.Model(&models.Dealer{}).Where("id = ? AND status = 1", dealer.ID).Updates(map[string]interface{}{
		"dealer_name":     dealer.DealerName,
		"contact":         dealer.Contact,
		"contact_phone":   dealer.ContactPhone,
		"platform_number": dealer.PlatformNumber,
		"email":           dealer.Email,
		"contact_address": dealer.ContactAddress,
		"modifier":        dealer.Modifier,
		"mtime":           time.Now().Unix(),
		"remark":          dealer.Remark,
	}).Error

	return err
}

func FindAllDealerTotal(orgId int64) (total int64) {
	db := readDb.Model(&models.Dealer{})
	db = db.Where("org_id = ? ", orgId).Count(&total)
	return
}

func FindAllDealerList(orgId int64, page int64, limit int64) (list []*models.Dealer, total int64, err error) {
	offset := (page - 1) * limit
	db := readDb.Model(&models.Dealer{})
	db = db.Where("org_id = ? AND status = 1", orgId)
	err = db.Count(&total).Offset(offset).Limit(limit).Order("ctime desc").Find(&list).Error
	return
}

func DeleteDealerById(id int64) error {
	err := writeDb.Model(&models.Dealer{}).Where("id = ? AND status = 1", id).Updates(map[string]interface{}{"mtime": time.Now().Unix(), "status": 0}).Error
	return err
}

func FindDealerById(id int64) (*models.Dealer, error) {
	dealer := &models.Dealer{}
	err := readDb.Model(&models.Dealer{}).Where("id = ? AND status = 1", id).First(&dealer).Error
	return dealer, err
}

func AddSigleManufacturer(manufacturer *models.Manufacturer) (error, *models.Manufacturer) {
	err := writeDb.Create(&manufacturer).Error
	return err, manufacturer
}

func ModifyManufacturer(manufacturer *models.Manufacturer) error {
	err := writeDb.Model(&models.Manufacturer{}).Where("id = ? AND status = 1", manufacturer.ID).Updates(map[string]interface{}{
		"manufacturer_name": manufacturer.ManufacturerName,
		"contact":           manufacturer.Contact,
		"contact_phone":     manufacturer.ContactPhone,
		"platform_number":   manufacturer.PlatformNumber,
		"email":             manufacturer.Email,
		"contact_address":   manufacturer.ContactAddress,
		"modifier":          manufacturer.Modifier,
		"mtime":             time.Now().Unix(),
		"remark":            manufacturer.Remark,
	}).Error

	return err
}

func FindAllManufacturerList(orgId int64, page int64, limit int64) (list []*models.Manufacturer, total int64, err error) {
	offset := (page - 1) * limit
	db := readDb.Model(&models.Manufacturer{})
	db = db.Where("org_id = ? AND status = 1", orgId)
	err = db.Count(&total).Offset(offset).Limit(limit).Order("ctime desc").Find(&list).Error
	return
}

func DeleteManufacturerById(id int64) error {
	err := writeDb.Model(&models.Manufacturer{}).Where("id = ? AND status = 1", id).Updates(map[string]interface{}{"mtime": time.Now().Unix(), "status": 0}).Error
	return err
}

func FindManufacturerById(id int64) (*models.Manufacturer, error) {
	dealer := &models.Manufacturer{}
	err := readDb.Model(&models.Manufacturer{}).Where("id = ? AND status = 1", id).First(&dealer).Error
	return dealer, err
}

func FindManufacturerTotal(orgId int64) (total int64) {
	db := readDb.Model(&models.Manufacturer{})
	db = db.Where("org_id = ?", orgId).Count(&total)
	return
}

func FindAllDealer(orgId int64) (dealers []*models.Dealer, err error) {
	err = readDb.Model(&models.Dealer{}).Where("org_id = ? AND status = 1", orgId).Find(&dealers).Error
	return dealers, err
}

func FindAllManufacturer(orgId int64) (manufacturer []*models.Manufacturer, err error) {
	err = readDb.Model(&models.Manufacturer{}).Where("org_id = ? AND status = 1", orgId).Find(&manufacturer).Error
	return manufacturer, err
}

func FindAllGoodTypeTotal(orgId int64) (total int64) {
	db := readDb.Model(&models.GoodsType{})
	db = db.Where("org_id = ?", orgId).Count(&total)
	return
}

func AddSigleGoodType(goodType *models.GoodsType) (error, *models.GoodsType) {
	err := writeDb.Create(&goodType).Error
	return err, goodType

}

func ModifyGoodType(goodType *models.GoodsType) (error, *models.GoodsType) {
	err := writeDb.Model(&models.GoodsType{}).Where("id = ? AND status = 1", goodType.ID).Updates(map[string]interface{}{
		"modifier":  goodType.Modifier,
		"mtime":     time.Now().Unix(),
		"remark":    goodType.Remark,
		"type_name": goodType.TypeName,
	}).Error
	return err, goodType

}

func FindAllGoodTypeList(orgId int64, page int64, limit int64, keyword string) (list []*models.GoodsType, total int64, err error) {
	offset := (page - 1) * limit
	db := readDb.Model(&models.GoodsType{})
	db = db.Where("(org_id=? AND status = 1) OR (type = 1 AND status = 1)", orgId)
	if len(keyword) > 0 {
		likeKey := "%" + keyword + "%"
		db = db.Where("type_code LIKE ? OR type_name LIKE ?", likeKey, likeKey)
	}

	err = db.Count(&total).Offset(offset).Limit(limit).Order("ctime desc").Find(&list).Error
	return
}

func DeleteGoodTypeById(id int64, operateId int64) error {
	err := writeDb.Model(&models.GoodsType{}).Where("id = ? AND status = 1", id).Updates(map[string]interface{}{"mtime": time.Now().Unix(), "status": 0, "modifier": operateId}).Error
	writeDb.Model(&models.GoodInfo{}).Where("good_type_id = ? AND status = 1", id).Updates(map[string]interface{}{"mtime": time.Now().Unix(), "status": 0, "modifier": operateId})
	return err
}

func FindGoodTypeById(id int64) (*models.GoodsType, error) {
	goodType := &models.GoodsType{}
	err := readDb.Model(&models.GoodsType{}).Where("id = ? AND status = 1", id).First(&goodType).Error
	return goodType, err
}

func FindAllGoodInfoTotal(orgId int64) (total int64) {
	db := readDb.Model(&models.GoodInfo{})
	db = db.Where("org_id = ?", orgId).Count(&total)
	return
}

func AddSigleGoodInfo(goodInfo *models.GoodInfo) (error, *models.GoodInfo) {
	err := writeDb.Create(&goodInfo).Error
	return err, goodInfo

}

func ModifyGoodInfo(goodInfo *models.GoodInfo) (error, *models.GoodInfo) {
	err := writeDb.Model(&models.GoodInfo{}).Where("id = ? AND status = 1", goodInfo.ID).Updates(map[string]interface{}{
		"modifier":                   goodInfo.Modifier,
		"mtime":                      time.Now().Unix(),
		"remark":                     goodInfo.Remark,
		"specification_name":         goodInfo.SpecificationName,
		"good_unit":                  goodInfo.GoodUnit,
		"buy_price":                  goodInfo.BuyPrice,
		"sell_price":                 goodInfo.SellPrice,
		"manufacturer":               goodInfo.Manufacturer,
		"dealer":                     goodInfo.Dealer,
		"expiry_date_warn_day_count": goodInfo.ExpiryDateWarnDayCount,
		"stock_warn_count":           goodInfo.StockWarnCount,
		"is_reuse":                   goodInfo.IsReuse,
	}).Error
	return err, goodInfo

}

func FindGoodInfoList(orgId int64, page int64, limit int64, keyword string) (list []*models.GoodInfo, total int64, err error) {
	offset := (page - 1) * limit
	db := readDb.Model(&models.GoodInfo{})
	db = db.Where("org_id = ? AND status = 1", orgId)
	if len(keyword) > 0 {
		likeKey := "%" + keyword + "%"
		db = db.Where("good_code LIKE ? OR specification_name LIKE ?", likeKey, likeKey)
	}
	err = db.Count(&total).Offset(offset).Limit(limit).Order("ctime desc").Find(&list).Error
	return
}

func DeleteGoodInfoById(id int64, operateId int64) error {
	err := writeDb.Model(&models.GoodInfo{}).Where("id = ? AND status = 1", id).Updates(map[string]interface{}{"mtime": time.Now().Unix(), "status": 0, "modifier": operateId}).Error
	return err
}

func FindGoodInfoByGoodId(id int64) (list []*models.GoodInfo, err error) {
	err = readDb.Model(&models.GoodInfo{}).Where("good_type_id = ? AND status = 1", id).Find(&list).Error
	return list, err
}

func FindGoodInfoById(id int64) (*models.GoodInfo, error) {
	goodInfo := &models.GoodInfo{}
	err := readDb.Model(&models.GoodInfo{}).Where("id = ? AND status = 1", id).First(&goodInfo).Error
	return goodInfo, err
}

func FindAllGoodType(org_id int64) (goodType []*models.GoodsType, err error) {
	err = readDb.Model(&models.GoodsType{}).Where("(org_id = ? AND status = 1) OR (type = 1 AND status = 1)", org_id).Find(&goodType).Error
	return goodType, err
}

func FindAllGoodInfo(org_id int64) (goodInfo []*models.GoodInfo, err error) {
	err = readDb.Model(&models.GoodInfo{}).Where("org_id = ? AND status = 1", org_id).Find(&goodInfo).Error
	return goodInfo, err
}

func FindAllWarehouseTotal(org_id int64) (total int64, err error) {
	err = readDb.Model(&models.Warehousing{}).Where("org_id = ?", org_id).Count(&total).Error
	return total, err
}
func AddSigleWarehouse(warehouse *models.Warehousing) error {
	err := writeDb.Create(&warehouse).Error
	return err

}

func AddSigleSalesReturn(salesReturn *models.SalesReturn) error {
	err := writeDb.Create(&salesReturn).Error
	return err

}

func UpDateGoodReturnStatus(ids []string) {
	writeDb.Model(&models.WarehousingInfo{}).Where("id IN (?)", ids).Update(map[string]interface{}{"is_return": 1})

}

func UpDateCanCelStockStatus(ids []string) {
	writeDb.Model(&models.WarehouseOutInfo{}).Where("id IN (?)", ids).Update(map[string]interface{}{"is_cancel": 1})

}

func CreateWarehousingInfo(warehousingInfo []*models.WarehousingInfo) (err error) {
	if len(warehousingInfo) > 0 {
		utx := writeDb.Begin()
		if len(warehousingInfo) > 0 {
			thisSQL := "INSERT INTO xt_warehouse_info (warehousing_id, good_id, good_type_id, number, product_date,expiry_date,warehousing_count,price,total_price,dealer,manufacturer,remark,ctime,mtime,status,org_id,warehousing_order,type) VALUES "
			insertParams := make([]string, 0)
			insertData := make([]interface{}, 0)
			for _, info := range warehousingInfo {
				insertParams = append(insertParams, "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
				insertData = append(insertData, info.WarehousingId)
				insertData = append(insertData, info.GoodId)
				insertData = append(insertData, info.GoodTypeId)
				insertData = append(insertData, info.Number)
				insertData = append(insertData, info.ProductDate)
				insertData = append(insertData, info.ExpiryDate)
				insertData = append(insertData, info.WarehousingCount)
				insertData = append(insertData, info.Price)
				insertData = append(insertData, info.TotalPrice)
				insertData = append(insertData, info.Dealer)
				insertData = append(insertData, info.Manufacturer)
				insertData = append(insertData, info.Remark)
				insertData = append(insertData, info.Ctime)
				insertData = append(insertData, info.Mtime)
				insertData = append(insertData, info.Status)
				insertData = append(insertData, info.OrgId)
				insertData = append(insertData, info.WarehousingOrder)
				insertData = append(insertData, info.Type)

			}
			thisSQL += strings.Join(insertParams, ", ")
			err = utx.Exec(thisSQL, insertData...).Error
			if err != nil {
				utx.Rollback()
				return
			}
		}
		utx.Commit()
	}
	return

}

func FindLastWarehousingInfo(order string) (info models.WarehousingInfo, err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Where("warehousing_order = ? AND status = 1", order).Last(&info).Error

	return info, err

}

func FindAllWarehousingList(orgId int64, page int64, limit int64, startTime int64, endTime int64, types int64, keywords string) (list []*models.Warehousing, total int64, err error) {
	db := readDb.Model(&models.Warehousing{})
	db = db.Where("xt_warehouse.org_id = ? AND xt_warehouse.status = 1 AND xt_warehouse.type = ?", orgId, types)

	if len(keywords) > 0 {
		likeKey := "%" + keywords + "%"
		db = db.Joins("join sgj_users.sgj_user_admin_role on sgj_user_admin_role.admin_user_id = xt_warehouse.creater")
		db = db.Joins("join xt_manufacturer on xt_manufacturer.id = xt_warehouse.manufacturer")
		db = db.Where("xt_manufacturer.manufacturer_name LIKE ? OR sgj_user_admin_role.user_name LIKE ? OR xt_warehouse.warehousing_order LIKE ?", likeKey, likeKey, likeKey).Group("xt_warehouse.id")
	}

	if startTime > 0 {
		db = db.Where("xt_warehouse.operation_time >=?", startTime)
	}
	if endTime > 0 {
		db = db.Where("xt_warehouse.operation_time<= ?", endTime)
	}
	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("xt_warehouse.ctime desc").Find(&list).Error
	return
}

func FindWarehousingInfoById(id int64) (list []*models.WarehousingInfo, err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Where("warehousing_id = ? AND status = 1", id).Find(&list).Error
	return list, err
}

func FindWarehousingById(id int64) (warehousing models.Warehousing, err error) {
	err = readDb.Model(&models.Warehousing{}).Where("id = ? AND status = 1 ", id).First(&warehousing).Error
	return warehousing, err

}

func GetInfoByIds(ids []string) (info []*models.WarehousingInfo, err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Preload("Warehousing", "status = 1").Where("id in (?) AND status = 1", ids).Find(&info).Error
	return
}

func GetWarehousOutInfoByIds(ids []string) (info []*models.WarehouseOutInfo, err error) {
	err = readDb.Model(&models.WarehouseOutInfo{}).Preload("WarehouseOut", "status = 1").Where("id in (?) AND status = 1", ids).Find(&info).Error
	return
}

func CreateSalesReturnInfo(salesReturnInfo []*models.SalesReturnInfo) (err error) {
	if len(salesReturnInfo) > 0 {
		utx := writeDb.Begin()
		if len(salesReturnInfo) > 0 {
			thisSQL := "INSERT INTO xt_sales_return_info (good_id, sales_return_id, good_type_id, count, price,total,ctime,status,org_id,order_number,type,dealer,manufacturer) VALUES "
			insertParams := make([]string, 0)
			insertData := make([]interface{}, 0)
			for _, info := range salesReturnInfo {
				insertParams = append(insertParams, "(?,?,?,?,?,?,?,?,?,?,?,?,?)")
				insertData = append(insertData, info.GoodId)
				insertData = append(insertData, info.SalesReturnId)
				insertData = append(insertData, info.GoodTypeId)
				insertData = append(insertData, info.Count)
				insertData = append(insertData, info.Price)
				insertData = append(insertData, info.Total)
				insertData = append(insertData, info.Ctime)
				insertData = append(insertData, info.Status)
				insertData = append(insertData, info.OrgId)
				insertData = append(insertData, info.OrderNumber)
				insertData = append(insertData, info.Type)
				insertData = append(insertData, info.Dealer)
				insertData = append(insertData, info.Manufacturer)
			}
			thisSQL += strings.Join(insertParams, ", ")
			err = utx.Exec(thisSQL, insertData...).Error
			if err != nil {
				utx.Rollback()
				return
			}
		}
		utx.Commit()
	}
	return

}

func FindAllSalesReturnTotal(org_id int64) (total int64, err error) {
	err = readDb.Model(&models.SalesReturn{}).Where("org_id = ?", org_id).Count(&total).Error
	return total, err

}

func FindAllCancelStockTotal(org_id int64) (total int64, err error) {
	err = readDb.Model(&models.CancelStock{}).Where("org_id = ?", org_id).Count(&total).Error
	return total, err

}

func FindAllReturnList(orgId int64, page int64, limit int64, startTime int64, endTime int64, types int64, keywords string) (list []*models.SalesReturn, total int64, err error) {
	db := readDb.Model(&models.SalesReturn{})
	db = db.Where("xt_sales_return.org_id = ? AND xt_sales_return.status = 1 AND xt_sales_return.type = ?", orgId, types)

	if len(keywords) > 0 {
		likeKey := "%" + keywords + "%"
		db = db.Joins("join sgj_users.sgj_user_admin_role on sgj_user_admin_role.admin_user_id = xt_sales_return.creater")
		db = db.Joins("join xt_manufacturer on xt_manufacturer.id = xt_sales_return.manufacturer")
		db = db.Where("xt_manufacturer.manufacturer_name LIKE ? OR sgj_user_admin_role.user_name LIKE ? OR xt_sales_return.order_number LIKE ?", likeKey, likeKey, likeKey).Group("xt_sales_return.id")
	}

	if startTime > 0 {
		db = db.Where("xt_sales_return.opera_time >=?", startTime)
	}
	if endTime > 0 {
		db = db.Where("xt_sales_return.opera_time<= ?", endTime)
	}
	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("xt_sales_return.ctime desc").Find(&list).Error
	return
}

func FindReturnInfoById(id int64) (list []*models.SalesReturnInfo, err error) {
	err = readDb.Model(&models.SalesReturnInfo{}).Where("sales_return_id = ? AND status = 1", id).Find(&list).Error
	return list, err
}

func FindCancelStockInfoById(id int64) (list []*models.CancelStockInfo, err error) {
	err = readDb.Model(&models.CancelStockInfo{}).Where("cancel_stock_id = ? AND status = 1", id).Find(&list).Error
	return list, err
}

func FindAllWarehousingInfo(orgId int64, page int64, limit int64, startTime int64, endTime int64) (list []*models.WarehousingInfo, total int64, err error) {
	db := readDb.Model(&models.WarehousingInfo{})
	db = db.Where("org_id = ? AND status = 1", orgId)
	db = db.Preload("Warehousing", "status = 1 AND org_id = ?", orgId)

	if startTime > 0 {
		db = db.Where("ctime >=?", startTime)
	}
	if endTime > 0 {
		db = db.Where("ctime<= ?", endTime)
	}
	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("ctime desc").Find(&list).Error
	return list, total, err
}

func FindAllWarehouseOut(org_id int64) (total int64, err error) {
	err = readDb.Model(&models.WarehouseOut{}).Where("org_id = ?", org_id).Count(&total).Error
	return total, err

}

func AddSigleWarehouseOut(warehouseOut *models.WarehouseOut) error {
	err := writeDb.Create(&warehouseOut).Error
	return err

}

func CreateWarehousingOutInfo(warehouseOutInfo []*models.WarehouseOutInfo) (err error) {
	if len(warehouseOutInfo) > 0 {
		utx := writeDb.Begin()
		if len(warehouseOutInfo) > 0 {
			thisSQL := "INSERT INTO xt_warehouse_out_info (warehouse_out_id, good_id, good_type_id, product_date,expiry_date,count,price,total_price,remark,ctime,status,org_id,warehouse_out_order_number,type,dealer,manufacturer) VALUES "
			insertParams := make([]string, 0)
			insertData := make([]interface{}, 0)
			for _, info := range warehouseOutInfo {
				insertParams = append(insertParams, "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
				insertData = append(insertData, info.WarehouseOutId)
				insertData = append(insertData, info.GoodId)
				insertData = append(insertData, info.GoodTypeId)
				insertData = append(insertData, info.ProductDate)
				insertData = append(insertData, info.ExpiryDate)
				insertData = append(insertData, info.Count)
				insertData = append(insertData, info.Price)
				insertData = append(insertData, info.TotalPrice)
				insertData = append(insertData, info.Remark)
				insertData = append(insertData, info.Ctime)
				insertData = append(insertData, info.Status)
				insertData = append(insertData, info.OrgId)
				insertData = append(insertData, info.WarehouseOutOrderNumber)
				insertData = append(insertData, info.Type)
				insertData = append(insertData, info.Dealer)
				insertData = append(insertData, info.Manufacturer)

			}
			thisSQL += strings.Join(insertParams, ", ")
			err = utx.Exec(thisSQL, insertData...).Error
			if err != nil {
				utx.Rollback()
				return
			}
		}
		utx.Commit()
	}
	return

}

func FindLastWarehousingOutInfo(order string) (info models.WarehouseOutInfo, err error) {
	err = readDb.Model(&models.WarehouseOutInfo{}).Where("warehouse_out_order_number = ? AND status = 1", order).Last(&info).Error

	return info, err

}

func FindAllWarehouseOutList(orgId int64, page int64, limit int64, startTime int64, endTime int64, types int64, keywords string) (list []*models.WarehouseOut, total int64, err error) {
	db := readDb.Model(&models.WarehouseOut{})
	db = db.Where("xt_warehouse_out.org_id = ? AND xt_warehouse_out.status = 1 AND xt_warehouse_out.type = ?", orgId, types)

	if len(keywords) > 0 {
		likeKey := "%" + keywords + "%"
		db = db.Joins("join sgj_users.sgj_user_admin_role on sgj_user_admin_role.admin_user_id = xt_warehouse_out.creater")
		db = db.Joins("join xt_manufacturer on xt_manufacturer.id = xt_warehouse_out.manufacturer")
		db = db.Where("xt_manufacturer.manufacturer_name LIKE ? OR sgj_user_admin_role.user_name LIKE ? OR xt_warehouse_out.warehouse_out_order_number LIKE ?", likeKey, likeKey, likeKey).Group("xt_warehouse_out.id")
	}

	if startTime > 0 {
		db = db.Where("xt_warehouse_out.ctime >=?", startTime)
	}
	if endTime > 0 {
		db = db.Where("xt_warehouse_out.ctime<= ?", endTime)
	}
	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("xt_warehouse_out.ctime desc").Find(&list).Error
	return list, total, err

	return
}

func FindWarehouseOutInfoById(id int64) (list []*models.WarehouseOutInfo, err error) {
	err = readDb.Model(&models.WarehouseOutInfo{}).Where("warehouse_out_id = ? AND status = 1 AND count <> 0 AND good_id <> 0", id).Order("good_type_id desc").Find(&list).Error
	return list, err
}

func FindWarehouseInfoByGoodId(good_id int64) (int64, *models.WarehousingInfo) {
	info := &models.WarehousingInfo{}
	type WarehouseInfoCountAmount struct {
		Total int64
	}
	var result WarehouseInfoCountAmount
	readDb.Model(&models.WarehousingInfo{}).Where("good_id = ? AND status = 1", good_id).Select("sum(warehousing_count) as total").Scan(&result)
	readDb.Model(&models.WarehousingInfo{}).Where("good_id = ? AND status = 1", good_id).First(info)

	return result.Total, info

}

func FindAllSalesReturnCountByGoodId(good_id int64) (int64, error) {
	type SalesReturnCountAmount struct {
		Total int64
	}
	var result SalesReturnCountAmount
	err = readDb.Model(&models.SalesReturnInfo{}).Where("good_id = ? AND status = 1", good_id).Select("sum(count) as total").Scan(&result).Error
	return result.Total, err
}

func FindAllWarehouseOutInfoByGoodId(good_id int64) (int64, error) {
	type WarehouseOutInfoCountAmount struct {
		Total int64
	}
	var result WarehouseOutInfoCountAmount
	err = readDb.Model(&models.WarehouseOutInfo{}).Where("good_id = ? AND status = 1", good_id).Select("sum(count) as total").Scan(&result).Error
	return result.Total, err
}

func FindAllCancleStockInfoByGoodId(good_id int64) (int64, error) {
	type CancleStockoCountAmount struct {
		Total int64
	}
	var result CancleStockoCountAmount
	err = readDb.Model(&models.CancelStockInfo{}).Where("good_id = ? AND status = 1", good_id).Select("sum(count) as total").Scan(&result).Error
	return result.Total, err
}

func FindWarehouseInfoByGoodTypeId(good_type_id int64) (models.WarehousingInfo, error) {
	info := models.WarehousingInfo{}
	err := readDb.Model(&models.WarehousingInfo{}).Where("good_type_id = ? AND status = 1", good_type_id).First(&info).Error
	return info, err

}

func AddSigleCancelStock(cancelStock *models.CancelStock) error {
	err := writeDb.Create(&cancelStock).Error
	return err

}

func CreateCancelStockInfo(cancelStockInfo []*models.CancelStockInfo) (err error) {
	if len(cancelStockInfo) > 0 {
		utx := writeDb.Begin()
		if len(cancelStockInfo) > 0 {
			thisSQL := "INSERT INTO xt_cancel_stock_info (good_id, cancel_stock_id, good_type_id, count, price,total,ctime,status,org_id,order_number,type,dealer,manufacturer) VALUES "
			insertParams := make([]string, 0)
			insertData := make([]interface{}, 0)
			for _, info := range cancelStockInfo {
				insertParams = append(insertParams, "(?,?,?,?,?,?,?,?,?,?,?,?,?)")
				insertData = append(insertData, info.GoodId)
				insertData = append(insertData, info.CancelStockId)
				insertData = append(insertData, info.GoodTypeId)
				insertData = append(insertData, info.Count)
				insertData = append(insertData, info.Price)
				insertData = append(insertData, info.Total)
				insertData = append(insertData, info.Ctime)
				insertData = append(insertData, info.Status)
				insertData = append(insertData, info.OrgId)
				insertData = append(insertData, info.OrderNumber)
				insertData = append(insertData, info.Type)
				insertData = append(insertData, info.Dealer)
				insertData = append(insertData, info.Manufacturer)
			}
			thisSQL += strings.Join(insertParams, ", ")
			err = utx.Exec(thisSQL, insertData...).Error
			if err != nil {
				utx.Rollback()
				return
			}
		}
		utx.Commit()
	}
	return

}

func FindAllCancelStockList(orgId int64) (list []*models.CancelStock, err error) {
	db := readDb.Model(&models.CancelStock{})
	db = db.Where("org_id = ? AND status = 1", orgId)
	err = db.Order("ctime desc").Find(&list).Error
	return
}

func FindAllStockOutList(orgId int64, page int64, limit int64, startTime int64, endTime int64) (list []*models.WarehouseOutInfo, total int64, err error) {

	db := readDb.Model(&models.WarehousingInfo{})
	db = db.Where("org_id = ? AND status = 1", orgId)
	db = db.Preload("WarehouseOut", "status = 1 AND org_id = ?", orgId)

	if startTime > 0 {
		db = db.Where("ctime >=?", startTime)
	}
	if endTime > 0 {
		db = db.Where("ctime<= ?", endTime)
	}
	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("ctime desc").Find(&list).Error

	return
}

func FindAllStockInfo(orgId int64, page int64, limit int64, keyword string) (list []*models.StockInfo, total int64, err error) {

	db := readDb.Model(&models.StockInfo{})
	db = db.Where("xt_good_information.org_id = ? AND xt_good_information.status = 1", orgId)
	db = db.Joins("JOIN xt_warehouse_info AS info ON info.good_id=xt_good_information.id AND info.status = 1").Group("xt_good_information.id")
	db = db.Preload("QueryWarehousingInfo", func(db *gorm.DB) *gorm.DB {
		return db.Where("org_id = ? AND status = 1", orgId)
	})
	db = db.Preload("QuerySalesReturnInfo", "org_id = ? AND status = 1", orgId)
	db = db.Preload("QueryWarehouseOutInfo", func(db *gorm.DB) *gorm.DB {
		return db.Where("org_id = ? AND status = 1", orgId)
	})
	db = db.Preload("QueryCancelStockInfo", "org_id = ? AND status = 1", orgId)
	db = db.Preload("GoodsType", "(org_id = ? AND status = 1) OR (status = 1 AND type = 1)", orgId)

	if len(keyword) > 0 {
		likeKey := "%" + keyword + "%"
		db = db.Joins("join xt_goods_type on xt_goods_type.id = xt_good_information.good_type_id  AND ((xt_goods_type.org_id = ? AND xt_goods_type.status = 1) OR (xt_goods_type.type = 1 AND xt_goods_type.status = 1))", orgId)
		db = db.Where("xt_good_information.good_code LIKE ? OR xt_good_information.specification_name LIKE ? OR xt_goods_type.type_name LIKE ?", likeKey, likeKey, likeKey).Group("xt_good_information.id")
	}

	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("ctime desc").Find(&list).Error
	return
}

func FindWarehouseInfoTotalByGoodId(goodId int64) (total int64, err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Where("good_id = ? AND status = 1", goodId).Count(&total).Error
	return
}

func UpDateWarehouse(warehouse *models.Warehousing) (err error) {
	err = readDb.Model(&models.Warehousing{}).Where("warehousing_order = ? AND status = 1", warehouse.WarehousingOrder).Update(map[string]interface{}{"operation_time": warehouse.OperationTime, "mtime": warehouse.Mtime, "modifier": warehouse.Modifier}).Error
	return
}
func UpDateWarehouseOut(warehouseOut *models.WarehouseOut) (err error) {
	err = readDb.Model(&models.WarehouseOut{}).Where("warehouse_out_order_number = ? AND status = 1", warehouseOut.WarehouseOutOrderNumber).Update(map[string]interface{}{"operation_time": warehouseOut.OperationTime, "mtime": warehouseOut.Mtime, "modifier": warehouseOut.Modifier}).Error
	return
}

func UpDateWarehouseInfo(warehouseInfo *models.WarehousingInfo) (err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Where("warehousing_order = ? AND status = 1", warehouseInfo.WarehousingOrder).Update(map[string]interface{}{"good_type_id": warehouseInfo.GoodTypeId,
		"good_id":           warehouseInfo.GoodId,
		"number":            warehouseInfo.Number,
		"product_date":      warehouseInfo.ProductDate,
		"expiry_date":       warehouseInfo.ExpiryDate,
		"warehousing_count": warehouseInfo.WarehousingCount,
		"price":             warehouseInfo.Price,
		"total_price":       warehouseInfo.TotalPrice,
		"mtime":             warehouseInfo.Mtime,
		"remark":            warehouseInfo.Remark,
	}).Error
	return
}

func UpDateWarehouseStatus(id int64) (err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Where("id = ? AND status = 1", id).Update(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	return
}

func DeleteWarehouse(ids []string) (err error) {
	ut := writeDb.Begin()
	err = ut.Model(&models.Warehousing{}).Where("id IN (?)", ids).Updates(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	if err != nil {
		ut.Rollback()
		return
	}
	err = ut.Model(&models.WarehousingInfo{}).Where("warehousing_id IN (?)", ids).Updates(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	if err != nil {
		ut.Rollback()
		return
	}
	ut.Commit()
	return
}

func FindWareHouseById(orderNumber string) (*models.Warehousing, error) {
	warehouse := &models.Warehousing{}
	err := readDb.Model(&models.Warehousing{}).Where("warehousing_order = ? AND status = 1", orderNumber).First(&warehouse).Error
	return warehouse, err
}
func FindWareHouseOutById(id int64) (*models.WarehouseOut, error) {
	warehouseOut := &models.WarehouseOut{}
	err := readDb.Model(&models.WarehouseOut{}).Where("id = ? AND status = 1", id).First(&warehouseOut).Error
	return warehouseOut, err
}

func FindWarehouseInfoByOrderNumber(orderNumber string) (info []*models.WarehousingInfo, err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Where("warehousing_order = ? AND status = 1", orderNumber).Find(&info).Error
	return

}

func FindWarehouseOutInfoByOrderNumber(orderNumber string) (info []*models.WarehouseOutInfo, err error) {
	err = readDb.Model(&models.WarehouseOutInfo{}).Where("warehouse_out_order_number = ? AND status = 1", orderNumber).Find(&info).Error
	return

}

func DeleteStockInRecordByOrderNumber(orderNumber string, id int64) (err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Where("id = ? AND status = 1", id).Update(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	err = readDb.Model(&models.Warehousing{}).Where("warehousing_order = ? AND status = 1", orderNumber).Update(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	return
}

func DeleteStockInRecordByReocordId(id int64) (err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Where("id = ? AND status = 1", id).Update(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	return
}

func FindAllGoodByManufactureId(manufacturer_id int64, dealer_id int64, org_id int64) (goodInfo []*models.GoodInfo, err error) {
	db := readDb.Model(&models.GoodInfo{}).Where("org_id = ? AND status = 1", org_id)
	if manufacturer_id > 0 {
		db = db.Where("manufacturer = ?", manufacturer_id)
	}
	if dealer_id > 0 {
		db = db.Where("dealer = ?", dealer_id)
	}
	err = db.Preload("GoodsType", "status = 1 AND (org_id = ? OR type = 1)", org_id).Find(&goodInfo).Error
	return goodInfo, err
}

func FindAllWarehouseByKeyword(orgId int64, page int64, limit int64, keywords string) (list []*models.Warehousing, total int64, err error) {
	db := readDb.Model(&models.Warehousing{})
	likekey := "%" + keywords + "%"
	db = db.Where("org_id = ? AND status = 1 ", orgId)
	db = db.Where("warehousing_order LIKE ? ", likekey)
	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("ctime desc").Find(&list).Error
	return
}

func UpDateWarehousingInfo(info *models.WarehousingInfo) (err error) {
	err = writeDb.Save(&info).Error
	return err
}

func EditWarehousing(warehouse models.Warehousing) {
	err = readDb.Model(&models.Warehousing{}).Where("warehousing_order = ? AND status = 1", warehouse.WarehousingOrder).Update(map[string]interface{}{"mtime": time.Now().Unix(), "warehousing_time": warehouse.WarehousingTime, "modifier": warehouse.Modifier, "dealer": warehouse.Dealer, "manufacturer": warehouse.Manufacturer}).Error

}

func FindAllWarehouse(org_id int64, types int64) (list []*models.Warehousing, err error) {
	err = readDb.Model(&models.Warehousing{}).Preload("Manufacturers", "status = 1 AND org_id = ?", org_id).Preload("Dealers", "status = 1 AND org_id = ? ", org_id).Where("org_id = ? AND status = 1 AND type = ?", org_id, types).Find(&list).Error
	return list, err
}

func FindAllWarehouseInfo(org_id int64, types int64) (list []*models.WarehousingInfoConfig, err error) {
	err = readDb.Model(&models.WarehousingInfoConfig{}).Preload("WarehousingGoodInfo", func(db *gorm.DB) *gorm.DB {
		return db.Where("status = 1 AND org_id = ?", org_id).Preload("GoodsType", "(status = 1 AND org_id = ?)OR(type = 1 AND status = 1)", org_id).Preload("Manufacturers", "status = 1 AND org_id = ?", org_id).Preload("Dealers", "status = 1 AND org_id = ?", org_id)
	}).Where("org_id = ? AND status = 1 AND type = ?", org_id, types).Find(&list).Error
	return list, err
}

func DeleteSalesReturn(ids []string) (err error) {
	ut := writeDb.Begin()
	err = ut.Model(&models.SalesReturn{}).Where("id IN (?)", ids).Updates(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	if err != nil {
		ut.Rollback()
		return
	}
	err = ut.Model(&models.SalesReturnInfo{}).Where("sales_return_id IN (?)", ids).Updates(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	if err != nil {
		ut.Rollback()
		return
	}
	ut.Commit()
	return
}

func FindAllSalesReturnInfoById(id int64) (list []*models.SalesReturnInfo, err error) {
	err = readDb.Model(&models.SalesReturnInfo{}).Where("sales_return_id = ? AND status = 1", id).Find(&list).Error
	return
}

func FindAllSalesReturnById(id int64) (salesReturn models.SalesReturn, err error) {
	err = readDb.Model(&models.SalesReturnInfo{}).Where("id = ? AND status = 1", id).First(&salesReturn).Error
	return
}
func UpDateSaleReturnStatus(id int64) (err error) {
	err = readDb.Model(&models.SalesReturnInfo{}).Where("id = ? AND status = 1", id).Update(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	return
}

func FindSalesReturnById(id int64) (salesReturn models.SalesReturn, err error) {
	err = readDb.Model(&models.SalesReturn{}).Where("id = ? AND status = 1", id).First(&salesReturn).Error
	return salesReturn, err

}

func EditSaleReturn(sales models.SalesReturn) {
	err = readDb.Model(&models.SalesReturn{}).Where("id = ? AND status = 1", sales.ID).Update(map[string]interface{}{"mtime": time.Now().Unix(), "return_time": sales.ReturnTime, "dealer": sales.Dealer, "manufacturer": sales.Manufacturer}).Error

}
func UpDateSalesReturnInfo(info *models.SalesReturnInfo) (err error) {
	err = writeDb.Save(&info).Error
	return err
}

func DeleteWarehouseOut(ids []string) (err error) {
	ut := writeDb.Begin()
	err = ut.Model(&models.WarehouseOut{}).Where("id IN (?)", ids).Updates(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	if err != nil {
		ut.Rollback()
		return
	}
	err = ut.Model(&models.WarehouseOutInfo{}).Where("warehouse_out_id IN (?)", ids).Updates(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	if err != nil {
		ut.Rollback()
		return
	}
	ut.Commit()
	return
}
func UpDateWarehouseOutStatus(id int64) (err error) {
	err = readDb.Model(&models.WarehouseOutInfo{}).Where("id = ? AND status = 1", id).Update(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	return
}

func EditWarehouseOut(warehouseOut models.WarehouseOut) {
	err = readDb.Model(&models.WarehouseOut{}).Where("id = ? AND status = 1", warehouseOut.ID).Update(map[string]interface{}{"mtime": time.Now().Unix(), "warehouse_out_time": warehouseOut.WarehouseOutTime, "dealer": warehouseOut.Dealer, "manufacturer": warehouseOut.Manufacturer}).Error
}

func UpDateWarehouseOutInfo(info *models.WarehouseOutInfo) (err error) {
	err = writeDb.Save(&info).Error
	return err
}

func FindAllCancelList(orgId int64, page int64, limit int64, startTime int64, endTime int64, types int64, keywords string) (list []*models.CancelStock, total int64, err error) {
	db := readDb.Model(&models.CancelStock{})
	db = db.Where("xt_cancel_stock.org_id = ? AND xt_cancel_stock.status = 1 AND xt_cancel_stock.type = ?", orgId, types)
	if len(keywords) > 0 {
		likeKey := "%" + keywords + "%"
		db = db.Joins("join sgj_users.sgj_user_admin_role on sgj_user_admin_role.admin_user_id = xt_cancel_stock.creater")
		db = db.Joins("join xt_manufacturer on xt_manufacturer.id = xt_cancel_stock.manufacturer")
		db = db.Where("xt_manufacturer.manufacturer_name LIKE ? OR sgj_user_admin_role.user_name LIKE ? OR xt_cancel_stock.order_number LIKE ?", likeKey, likeKey, likeKey).Group("xt_cancel_stock.id")
	}

	if startTime > 0 {
		db = db.Where("xt_cancel_stock.opera_time >=?", startTime)
	}
	if endTime > 0 {
		db = db.Where("xt_cancel_stock.opera_time<= ?", endTime)
	}
	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("xt_cancel_stock.ctime desc").Find(&list).Error
	return
}

func DeleteCancelStock(ids []string) (err error) {
	ut := writeDb.Begin()
	err = ut.Model(&models.CancelStock{}).Where("id IN (?)", ids).Updates(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	if err != nil {
		ut.Rollback()
		return
	}
	err = ut.Model(&models.CancelStockInfo{}).Where("cancel_stock_id IN (?)", ids).Updates(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	if err != nil {
		ut.Rollback()
		return
	}
	ut.Commit()
	return
}

func UpDateCancleStockStatus(id int64) (err error) {
	err = readDb.Model(&models.CancelStockInfo{}).Where("id = ? AND status = 1", id).Update(map[string]interface{}{"status": 0, "mtime": time.Now().Unix()}).Error
	return
}

func EditCancelStock(sales models.CancelStock) {
	err = readDb.Model(&models.CancelStock{}).Where("id = ? AND status = 1", sales.ID).Update(map[string]interface{}{"mtime": time.Now().Unix(), "return_time": sales.ReturnTime, "dealer": sales.Dealer, "manufacturer": sales.Manufacturer}).Error

}

func FindCancelStockById(id int64) (cancelStock models.CancelStock, err error) {
	err = readDb.Model(&models.CancelStock{}).Where("id = ? AND status = 1", id).First(&cancelStock).Error
	return cancelStock, err

}

func UpDateCancelStockInfo(info *models.CancelStockInfo) (err error) {
	err = writeDb.Save(&info).Error
	return err
}

func FindWarehouseOutList(org_id int64, types int64) (list []*models.WarehouseOut, err error) {
	err = readDb.Model(&models.WarehouseOut{}).Preload("Manufacturers", "status = 1 AND org_id = ?", org_id).Preload("Dealers", "status = 1 AND org_id = ? ", org_id).Where("org_id = ? AND status = 1 AND type = ?", org_id, types).Find(&list).Error
	return list, err
}

func FindAllWarehouseOutInfo(org_id int64, types int64) (list []*models.WarehousingOutInfoConfig, err error) {
	err = readDb.Model(&models.WarehousingOutInfoConfig{}).Preload("WarehousingGoodInfo", func(db *gorm.DB) *gorm.DB {
		return db.Where("status = 1 AND org_id = ?", org_id).Preload("GoodsType", "(status = 1 AND org_id = ?) OR (status = 1 AND type = 1) ", org_id).Preload("Manufacturers", "status = 1 AND org_id = ?", org_id).Preload("Dealers", "status = 1 AND org_id = ?", org_id)
	}).Where("org_id = ? AND status = 1 AND type = ?", org_id, types).Find(&list).Error
	return list, err

}

type StockDetailModel struct {
	GoodId           int64   `gorm:"good_id" json:"good_id"`
	GoodTypeId       int64   `gorm:"good_type_id" json:"good_type_id"`
	WarehousingOrder string  `gorm:"warehousing_order" json:"warehousing_order"`
	Price            float64 `gorm:"price" json:"price"`
	WarehousingCount int64   `gorm:"warehousing_count" json:"warehousing_count"`
	Type             int     `gorm:"type" json:"type"`
	Creater          int64   `gorm:"creater" json:"creater"`
	WarehousingTime  int64   `gorm:"warehousing_time" json:"warehousing_time"`
	Types            int64   `gorm:"types" json:"types"`
}

func FindStockInDetailList(orgId int64, page int64, limit int64, startTime int64, endTime int64, keywords string, manufacturer int64, order_type int64, dealer int64) (list []*models.WarehousingInfo, total int64, err error) {
	db := readDb.Model(&models.WarehousingInfo{})
	db = db.Where("xt_warehouse_info.org_id = ? AND xt_warehouse_info.status = 1", orgId)
	if len(keywords) > 0 {
		likeKey := "%" + keywords + "%"
		//db = db.Joins("join xt_warehouse on xt_warehouse.id = xt_warehouse_info.warehousing_id AND ")
		db = db.Joins("join xt_warehouse on xt_warehouse.id = xt_warehouse_info.warehousing_id AND xt_warehouse.warehousing_time >=? AND xt_warehouse.warehousing_time<= ? AND xt_warehouse.status = 1 AND xt_warehouse.org_id = ?", startTime, endTime, orgId)
		db = db.Joins("join sgj_users.sgj_user_admin_role on sgj_user_admin_role.admin_user_id = xt_warehouse.creater")
		db = db.Joins("join xt_good_information on xt_good_information.id = xt_warehouse_info.good_id")
		//db = db.Joins("join xt_manufacturer on xt_manufacturer.id = xt_warehouse.manufacturer")
		//db = db.Where(" sgj_user_admin_role.user_name LIKE ?", likeKey).Group("xt_warehouse_info.id")

		db = db.Where(" sgj_user_admin_role.user_name LIKE ? OR xt_warehouse_info.warehousing_order LIKE ? OR xt_good_information.specification_name LIKE ?", likeKey, likeKey, likeKey).Group("xt_warehouse_info.id")
	} else {
		db = db.Joins("join xt_warehouse on xt_warehouse.id = xt_warehouse_info.warehousing_id AND xt_warehouse.warehousing_time >=? AND xt_warehouse.warehousing_time<= ? AND xt_warehouse.status = 1 AND xt_warehouse.org_id = ?", startTime, endTime, orgId)
	}

	if manufacturer > 0 {
		db = db.Joins("join xt_warehouse as wa on wa.id = xt_warehouse_info.warehousing_id AND wa.manufacturer =?", manufacturer)
	}

	if order_type > 0 {
		db = db.Where("xt_warehouse_info.type = ?", order_type)
	}

	db = db.Preload("Warehousing", "status = 1 AND org_id = ?", orgId)
	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("xt_warehouse_info.ctime desc").Find(&list).Error
	return
}

func GetStockInDetailTotal(orgId int64, startTime int64, endTime int64, keywords string, manufacturer int64, order_type int64, dealer int64) (err error, totalPrice float64) {
	db := readDb.Model(&models.WarehousingInfo{})
	db = db.Where("xt_warehouse_info.org_id = ? AND xt_warehouse_info.status = 1", orgId)
	if len(keywords) > 0 {
		likeKey := "%" + keywords + "%"
		//db = db.Joins("join xt_warehouse on xt_warehouse.id = xt_warehouse_info.warehousing_id AND ")
		db = db.Joins("join xt_warehouse on xt_warehouse.id = xt_warehouse_info.warehousing_id AND xt_warehouse.warehousing_time >=? AND xt_warehouse.warehousing_time<= ? AND xt_warehouse.status = 1 AND xt_warehouse.org_id = ?", startTime, endTime, orgId)
		db = db.Joins("join sgj_users.sgj_user_admin_role on sgj_user_admin_role.admin_user_id = xt_warehouse.creater")
		db = db.Joins("join xt_good_information on xt_good_information.id = xt_warehouse_info.good_id")
		db = db.Where("sgj_user_admin_role.user_name LIKE ? OR xt_warehouse_info.warehousing_order LIKE ? OR xt_good_information.specification_name LIKE ?", likeKey, likeKey, likeKey).Group("xt_warehouse_info.id")
	} else {
		db = db.Joins("join xt_warehouse on xt_warehouse.id = xt_warehouse_info.warehousing_id AND xt_warehouse.warehousing_time >=? AND xt_warehouse.warehousing_time<= ? AND xt_warehouse.status = 1 AND xt_warehouse.org_id = ?", startTime, endTime, orgId)
	}
	if manufacturer > 0 {
		db = db.Joins("join xt_warehouse as wa on wa.id = xt_warehouse_info.warehousing_id AND wa.manufacturer =?", manufacturer)
	}
	if order_type > 0 {
		db = db.Where("xt_warehouse_info.type = ?", order_type)
	}
	type PriceAmount struct {
		Total float64
	}
	var result []PriceAmount
	err = db.Select("total_price as total").Scan(&result).Error
	var total float64
	for _, value := range result {
		total = total + value.Total
	}
	total, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", total), 64)
	return err, total
}

func FloatRound(f float64, n int) float64 {
	format := "%." + strconv.Itoa(n) + "f"
	res, _ := strconv.ParseFloat(fmt.Sprintf(format, f), 64)
	return res
}

func FindStockOutDetailList(orgId int64, page int64, limit int64, startTime int64, endTime int64, keywords string, manufacturer int64, order_type int64, dealer int64) (list []*models.WarehouseOutInfo, total int64, err error) {
	db := readDb.Model(&models.WarehouseOutInfo{})
	db = db.Where("xt_warehouse_out_info.org_id = ? AND xt_warehouse_out_info.status = 1 AND xt_warehouse_out_info.good_id <> 0 AND xt_warehouse_out_info.count <> 0 ", orgId)

	if len(keywords) > 0 {
		likeKey := "%" + keywords + "%"
		db = db.Joins("join xt_warehouse_out on xt_warehouse_out.id = xt_warehouse_out_info.warehouse_out_id AND xt_warehouse_out.warehouse_out_time >=? AND xt_warehouse_out.warehouse_out_time<= ? AND xt_warehouse_out.status = 1 AND xt_warehouse_out.org_id = ?", startTime, endTime, orgId)
		db = db.Joins("join sgj_users.sgj_user_admin_role on sgj_user_admin_role.admin_user_id = xt_warehouse_out.creater")
		db = db.Joins("join xt_good_information on xt_good_information.id = xt_warehouse_out_info.good_id")

		db = db.Where("sgj_user_admin_role.user_name LIKE ? OR xt_warehouse_out_info.warehouse_out_order_number LIKE ?  OR xt_good_information.specification_name LIKE ?", likeKey, likeKey, likeKey).Group("xt_warehouse_out_info.id")
	} else {
		db = db.Joins("join xt_warehouse_out on xt_warehouse_out.id = xt_warehouse_out_info.warehouse_out_id AND xt_warehouse_out.warehouse_out_time >=? AND xt_warehouse_out.warehouse_out_time<= ? AND xt_warehouse_out.status = 1 AND xt_warehouse_out.org_id = ?", startTime, endTime, orgId)
	}

	if manufacturer > 0 {
		db = db.Joins("join xt_warehouse_out as wa on wa.id = xt_warehouse_out_info.warehouse_out_id AND wa.manufacturer =?", manufacturer)
	}

	if order_type > 0 {
		db = db.Where("xt_warehouse_out_info.type = ?", order_type)
	}

	db = db.Preload("WarehouseOut", "status = 1 AND org_id = ?", orgId)
	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("xt_warehouse_out_info.ctime desc").Find(&list).Error
	return
}

func GetStockOutDetailTotal(orgId int64, startTime int64, endTime int64, keywords string, manufacturer int64, order_type int64, dealer int64) (err error, totalPrice float64) {
	db := readDb.Model(&models.WarehouseOutInfo{})
	db = db.Where("xt_warehouse_out_info.org_id = ? AND xt_warehouse_out_info.status = 1  AND xt_warehouse_out_info.good_id <> 0 AND xt_warehouse_out_info.count <> 0", orgId)

	if len(keywords) > 0 {
		likeKey := "%" + keywords + "%"
		db = db.Joins("join xt_warehouse_out on xt_warehouse_out.id = xt_warehouse_out_info.warehouse_out_id AND xt_warehouse_out.warehouse_out_time >=? AND xt_warehouse_out.warehouse_out_time<= ? AND xt_warehouse_out.status = 1 AND xt_warehouse_out.org_id = ?", startTime, endTime, orgId)
		db = db.Joins("join sgj_users.sgj_user_admin_role on sgj_user_admin_role.admin_user_id = xt_warehouse_out.creater")
		db = db.Joins("join xt_good_information on xt_good_information.id = xt_warehouse_out_info.good_id")

		db = db.Where("sgj_user_admin_role.user_name LIKE ? OR xt_warehouse_out_info.warehouse_out_order_number LIKE ?", likeKey, likeKey).Group("xt_warehouse_out_info.id")
	} else {
		db = db.Joins("join xt_warehouse_out on xt_warehouse_out.id = xt_warehouse_out_info.warehouse_out_id AND xt_warehouse_out.warehouse_out_time >=? AND xt_warehouse_out.warehouse_out_time<= ? AND xt_warehouse_out.status = 1 AND xt_warehouse_out.org_id = ?", startTime, endTime, orgId)
	}

	if manufacturer > 0 {
		db = db.Joins("join xt_warehouse_out as wa on wa.id = xt_warehouse_out_info.warehouse_out_id AND wa.manufacturer =?", manufacturer)
	}

	if order_type > 0 {
		db = db.Where("xt_warehouse_out_info.type = ?", order_type)
	}

	type PriceAmount struct {
		Total float64
	}
	var result []PriceAmount
	err = db.Select("(count * price) as total").Scan(&result).Error
	var total float64
	for _, value := range result {
		total = total + value.Total
	}
	total, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", total), 64)
	fmt.Println(total)
	return err, total
}

func FindSalesReturnDetailList(orgId int64, page int64, limit int64, startTime int64, endTime int64, keywords string, manufacturer int64, order_type int64, dealer int64) (list []*models.SalesReturnInfo, total int64, err error) {
	db := readDb.Model(&models.SalesReturnInfo{})
	db = db.Where("xt_sales_return_info.org_id = ? AND xt_sales_return_info.status = 1", orgId)
	if len(keywords) > 0 {
		likeKey := "%" + keywords + "%"
		db = db.Joins("join xt_sales_return on xt_sales_return.id = xt_sales_return_info.sales_return_id AND xt_sales_return.return_time >=? AND xt_sales_return.return_time<= ? AND xt_sales_return.status = 1 AND xt_sales_return.org_id = ?", startTime, endTime, orgId)
		db = db.Joins("join sgj_users.sgj_user_admin_role on sgj_user_admin_role.admin_user_id = xt_sales_return.creater")
		db = db.Joins("join xt_good_information on xt_good_information.id = xt_sales_return_info.good_id")

		db = db.Where("sgj_user_admin_role.user_name LIKE ? OR xt_sales_return_info.order_number LIKE ? OR xt_good_information.specification_name LIKE ?", likeKey, likeKey, likeKey).Group("xt_sales_return_info.id")
	} else {
		db = db.Joins("join xt_sales_return on xt_sales_return.id = xt_sales_return_info.sales_return_id AND xt_sales_return.return_time >=? AND xt_sales_return.return_time<= ? AND xt_sales_return.status = 1 AND xt_sales_return.org_id = ?", startTime, endTime, orgId)
	}

	if manufacturer > 0 {
		db = db.Joins("join xt_sales_return as sr on sr.id = xt_sales_return_info.sales_return_id AND sr.manufacturer =?", manufacturer)
	}

	if order_type > 0 {
		db = db.Where("xt_sales_return_info.type = ?", order_type)
	}

	db = db.Preload("SalesReturn", "status = 1 AND org_id = ?", orgId)
	offset := (page - 1) * limit
	db = db.Count(&total)

	err = db.Offset(offset).Limit(limit).Order("xt_sales_return_info.ctime desc").Find(&list).Error

	return
}

func FindCancelDetailList(orgId int64, page int64, limit int64, startTime int64, endTime int64, keywords string, manufacturer int64, order_type int64, dealer int64) (list []*models.CancelStockInfo, total int64, err error) {
	db := readDb.Model(&models.CancelStockInfo{})
	db = db.Where("xt_cancel_stock_info.org_id = ? AND xt_cancel_stock_info.status = 1", orgId)
	if len(keywords) > 0 {
		likeKey := "%" + keywords + "%"
		db = db.Joins("join xt_cancel_stock on xt_cancel_stock.id = xt_cancel_stock_info.cancel_stock_id AND xt_cancel_stock.return_time >=? AND xt_cancel_stock.return_time<= ? AND xt_cancel_stock.status = 1 AND xt_cancel_stock.org_id = ?", startTime, endTime, orgId)
		db = db.Joins("join sgj_users.sgj_user_admin_role on sgj_user_admin_role.admin_user_id = xt_cancel_stock.creater")
		db = db.Joins("join xt_good_information on xt_good_information.id = xt_cancel_stock_info.good_id")

		db = db.Where("sgj_user_admin_role.user_name LIKE ? OR xt_cancel_stock_info.order_number LIKE ? OR xt_good_information.specification_name LIKE ?", likeKey, likeKey, likeKey).Group("xt_cancel_stock_info.id")
	} else {
		db = db.Joins("join xt_cancel_stock on xt_cancel_stock.id = xt_cancel_stock_info.cancel_stock_id AND xt_cancel_stock.return_time >=? AND xt_cancel_stock.return_time<= ? ", startTime, endTime)
	}

	if manufacturer > 0 {
		db = db.Joins("join xt_cancel_stock as cs on cs.id = xt_cancel_stock_info.cancel_stock_id AND cs.manufacturer =?", manufacturer)
	}

	if order_type > 0 {
		db = db.Where("xt_cancel_stock_info.type = ?", order_type)
	}

	db = db.Preload("CancelStock", "status = 1 AND org_id = ?", orgId)
	db = db.Count(&total)
	offset := (page - 1) * limit
	err = db.Offset(offset).Limit(limit).Order("xt_cancel_stock_info.ctime desc").Find(&list).Error
	return
}

func FindStockInByDealerId(id int64) (total int64, err error) {
	err = readDb.Model(&models.Warehousing{}).Where("dealer = ? AND status = 1", id).Count(&total).Error
	return
}

func FindStockInByManufacturerId(id int64) (total int64, err error) {
	err = readDb.Model(&models.Warehousing{}).Where("manufacturer = ? AND status = 1", id).Count(&total).Error
	return
}

func FindGoodTypeByName(name string, org_id int64) (total int64) {
	readDb.Model(&models.GoodsType{}).Where("(org_id = ? OR type = 1) AND status = 1 AND type_name = ? ", org_id, name).Count(&total)
	return
}
func FindGoodInfoByName(name string, org_id int64) (total int64) {
	readDb.Model(&models.GoodInfo{}).Where("org_id = ? AND status = 1 AND specification_name = ? ", org_id, name).Count(&total)
	return
}

func FindAllGoodTypeByType(types int64) (goodType []*models.GoodsType, err error) {
	err = readDb.Model(&models.GoodsType{}).Where("type = ? AND status = 1", types).Find(&goodType).Error
	return goodType, err
}

func FindWarehouseInfoByGoodType(good_type_id int64, org_id int64) (info []*models.WarehousingInfo, err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Preload("GoodInfo", "status = 1 AND org_id = ?", org_id).Where("good_type_id = ? AND status = 1 AND org_id = ?", good_type_id, org_id).Find(&info).Error
	return info, err

}

func FindStockOutByIsSys(org_id int64, is_sys int, record_time int64) (out models.WarehouseOut, err error) {
	err = readDb.Model(&models.WarehouseOut{}).Where("is_sys = ? AND status = 1 AND org_id = ? AND warehouse_out_time = ?", is_sys, org_id, record_time).First(&out).Error
	return

}

func FindLastStockInInfoRecord(good_id int64, org_id int64) (in models.WarehousingInfo, err error) {
	err = readDb.Model(&models.WarehousingInfo{}).Where("status = 1 AND org_id = ? AND good_id = ?", org_id, good_id).Last(&in).Error
	return

}

func AddSigleWarehouseOutInfo(info *models.WarehouseOutInfo) error {
	err := writeDb.Create(&info).Error
	return err

}

func AddSigleAutoReduceRecordInfo(detail *models.AutomaticReduceDetail) error {
	err := writeDb.Create(&detail).Error
	return err

}

func FindStockOutInfoByTypeId(org_id int64, good_type_id int64, good_id int64, number string) (out models.WarehouseOutInfo, err error) {
	err = readDb.Model(&models.WarehouseOutInfo{}).Where("status = 1 AND org_id = ? AND good_type_id = ? AND good_id = ? AND is_sys = 1 AND  warehouse_out_order_number = ?", org_id, good_type_id, good_id, number).First(&out).Error
	return
}

func UpdateStockOutInfoCount(org_id int64, id int64) {
	writeDb.Model(&models.WarehouseOutInfo{}).Where("status = 1 AND org_id = ? AND id = ?", org_id, id).UpdateColumn("count", gorm.Expr("count + ?", 1))

}

func FindUserDetailById(org_id int64, id int64) (user []*models.AutomaticReduceDetail, err error, total int64) {
	db := readDb.Model(&models.AutomaticReduceDetail{})
	db = db.Preload("GoodInfo", "org_id = ? AND status = 1", org_id)
	db = db.Preload("GoodsType", "type = 1 AND status = 1")
	db = db.Preload("Patients", "user_org_id = ? AND status = 1", org_id)
	db = db.Where("status = 1 AND org_id = ? AND warehouse_out_id = ? AND good_id != 0", org_id, id)
	db = db.Count(&total)
	err = db.Find(&user).Error
	return
}
