浏览代码

add:出库申请

zoie 4 月之前
父节点
当前提交
a348e0c6ef

+ 3 - 3
conf/app.conf

@@ -20,10 +20,10 @@ MysqlServer_MaxOpenConnections = 200
 
 
 # Mysql Mqtt
-MysqlMqtt_UrlPort = "203.34.49.130:3306"
+MysqlMqtt_UrlPort = "192.168.0.88:3306"
 MysqlMqtt_Database = "mqtt"
-MysqlMqtt_Username = "root"
-MysqlMqtt_Password = "yjwyEckZS7rE5H"
+MysqlMqtt_Username = "cold"
+MysqlMqtt_Password = "yjwyEckZS7rE5H!"
 MysqlMqtt_MaxIdleConnections = 100
 MysqlMqtt_MaxOpenConnections = 200
 

+ 21 - 8
controllers/Contract.go

@@ -743,6 +743,7 @@ func (c *ContractController) VerifyContract_Add() {
 
 // 验证合同呢修改
 func (c *ContractController) VerifyContract_Edit() {
+	Id, _ := c.GetInt("Id")
 	T_number := c.GetString("T_number")
 	T_money, _ := c.GetFloat("T_money")
 	T_discount, _ := c.GetFloat("T_discount")
@@ -762,13 +763,24 @@ func (c *ContractController) VerifyContract_Edit() {
 	ContractDao := Contract.NewContract(o)
 	ContractProductDao := Contract.NewContractProduct(o)
 
-	contract, err := ContractDao.Read_Contract_ByT_number(T_number)
+	contract, err := ContractDao.Read_Contract_ById(Id)
 	if err != nil || contract.T_type == 1 {
 		o.Rollback()
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_number Err!"}
 		c.ServeJSON()
 		return
 	}
+	oldT_number := contract.T_number
+	if T_number != oldT_number {
+		_, err1 := ContractDao.Read_Contract_ByT_number(T_number)
+		if err1 == nil {
+			o.Rollback()
+			c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("合同编号%s已存在!", T_number)}
+			c.ServeJSON()
+			return
+		}
+		contract.T_number = T_number
+	}
 
 	if T_money > 0 {
 		contract.T_money = float32(T_money)
@@ -806,7 +818,7 @@ func (c *ContractController) VerifyContract_Edit() {
 		contract.T_submit = T_submit
 	}
 
-	err = ContractDao.Update_Contract(contract, "T_money", "T_discount", "T_date", "T_remark", "T_pdf", "T_State", "T_project",
+	err = ContractDao.Update_Contract(contract, "T_number", "T_money", "T_discount", "T_date", "T_remark", "T_pdf", "T_State", "T_project",
 		"T_recoveries", "T_recoveries_money", "T_invoice", "T_invoice_money", "T_start_date", "T_end_date", "T_submit")
 	if err != nil {
 		o.Rollback()
@@ -823,7 +835,7 @@ func (c *ContractController) VerifyContract_Edit() {
 	}
 	productList := lib.SplitString(T_product, "|")
 
-	cpl, _ := ContractProductDao.Read_ContractProductList_ByT_number(T_number)
+	cpl, _ := ContractProductDao.Read_ContractProductList_ByT_number(oldT_number)
 	needToDeleteList, allList := Check_NeedToDelete_Product_List(productList, cpl)
 	// 检查编辑时需要修改的产品
 	for k, v := range needToDeleteList {
@@ -872,15 +884,16 @@ func (c *ContractController) VerifyContract_Edit() {
 		// 修改产品总数量
 		contractProductId, _ := strconv.Atoi(strings.Split(oldContractProduct, "-")[0])
 		oldNum, _ := strconv.Atoi(strings.Split(oldContractProduct, "-")[1])
-		if oldNum == num {
+		if oldNum == num && T_number == oldT_number {
 			continue
 		}
 		cp := Contract.ContractProduct{
-			Id:              contractProductId,
-			T_product_total: num,
-			T_price:         float32(price), // 价格
+			Id:                contractProductId,
+			T_contract_number: T_number,
+			T_product_total:   num,
+			T_price:           float32(price), // 价格
 		}
-		err = ContractProductDao.Update_ContractProduct(cp, "T_product_total")
+		err = ContractProductDao.Update_ContractProduct(cp, "T_product_total", "T_contract_number")
 		if err != nil {
 			o.Rollback()
 			c.Data["json"] = lib.JSONS{Code: 203, Msg: "修改失败"}

+ 629 - 7
controllers/Stock.go

@@ -804,7 +804,7 @@ func StockIn_Edit_StockMonth(T_date string, T_depot_id int, allProductList []int
 	//	return nil
 	//}
 	//T_month := date.Format("2006-01")
-	months := generateMonthList(date)
+	months := generateMonthList(date, "in")
 	o := orm.NewOrm()
 	StockOutDao := Stock.NewStockOut(o)
 	StockMonthDao := Stock.NewStockMonth(o)
@@ -1961,6 +1961,8 @@ func (c *StockController) StockOut_Add() {
 		T_signer_phone:   T_signer_phone,
 		T_signer_date:    T_signer_date,
 		T_courier_number: T_courier_number,
+
+		T_state: Stock.StockOutAlreadyOut,
 	}
 
 	StockOutProductDao := Stock.NewStockOutProduct(o)
@@ -2041,6 +2043,7 @@ func (c *StockController) StockOut_Add() {
 			T_num:         num,    // 出库数量
 			T_date:        T_date, // 出库数量
 			T_relation_sn: T_relation_sn,
+			T_state:       1,
 		}
 		_, err = StockOutProductDao.Add_StockOutProduct(stockOutProduct)
 		if err != nil {
@@ -2217,16 +2220,17 @@ func (c *StockController) StockOut_Edit() {
 	DeviceDao := Stock.NewDevice(o)
 	IotCardDao := Property.NewIotCard(&o)
 
-	// 查询库信息
+	// 查询库信息
 	StockOut, err := StockOutDao.Read_StockOut_ByT_number(T_number)
-	T_old_date := StockOut.T_date
+
 	if err != nil {
 		o.Rollback()
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败!"}
 		c.ServeJSON()
 		return
 	}
-	// 查询入库产品信息
+	T_old_date := StockOut.T_date
+	// 查询出库产品信息
 	productOldList := StockOutProductDao.Read_StockOutProduct_List(StockOut.T_number)
 
 	var oldProductList []dto.StockProduct
@@ -2363,6 +2367,7 @@ func (c *StockController) StockOut_Edit() {
 					T_num:         v.T_num,         // 入库数量
 					T_date:        StockOut.T_date, // 入库日期
 					T_relation_sn: strings.Join(v.T_relation_sn, ","),
+					T_state:       1,
 				}
 				_, err = StockOutProductDao.Add_StockOutProduct(StockOutProduct)
 				if err != nil {
@@ -2392,6 +2397,7 @@ func (c *StockController) StockOut_Edit() {
 					T_depot_id:   StockOut.T_depot_id,
 					T_num:        productNewMap[v.T_product_id].T_num, // 入库数量
 					T_date:       StockOut.T_date,                     // 入库日期
+					T_state:      1,
 				}
 				// 出库数量比之前多,减少库存
 				var T_type int
@@ -2503,6 +2509,7 @@ func (c *StockController) StockOut_Edit() {
 				T_num:         productNewMap[diff.T_product_id].T_num, // 入库数量
 				T_date:        StockOut.T_date,                        // 入库日期
 				T_relation_sn: strings.Join(productNewMap[diff.T_product_id].T_relation_sn, ","),
+				T_state:       1,
 			}
 			// 更新产品库存表
 			err = StockOutProductDao.Update_StockOutProduct(StockOutProduct)
@@ -3014,7 +3021,7 @@ func StockOut_Edit_StockMonth(T_date string, T_depot_id int, allProductList []in
 	//	return nil
 	//}
 	//T_month := date.Format("2006-01")
-	months := generateMonthList(date)
+	months := generateMonthList(date, "out")
 	o := orm.NewOrm()
 	StockOutDao := Stock.NewStockOut(o)
 	StockMonthDao := Stock.NewStockMonth(o)
@@ -3151,12 +3158,627 @@ func Cron_StockMonth_Add() {
 
 }
 
-func generateMonthList(startMonth time.Time) []string {
+func generateMonthList(startMonth time.Time, t_type string) []string {
 	var months []string
-	endMonth := time.Now().AddDate(0, 1, 0)
+	endMonth := time.Now()
+	if t_type == "in" {
+		endMonth = endMonth.AddDate(0, 1, 0)
+	}
 	for month := startMonth; month.Before(endMonth); month = month.AddDate(0, 1, 0) {
 		fmt.Println("=========================", month.Format("2006-01"))
 		months = append(months, month.Format("2006-01"))
 	}
 	return months
 }
+
+// 出库申请
+func (c *StockController) StockOut_Apply() {
+
+	rand_x := 0
+	T_number := ""
+	o := orm.NewOrm()
+
+	StockOutDao := Stock.NewStockOut(o)
+	for true {
+		T_number = "CK-" + lib.GetRandstring(8, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", int64(rand_x))
+		_, err := StockOutDao.Read_StockOut_ByT_number(T_number)
+		if err != nil && err.Error() == orm.ErrNoRows.Error() {
+			break
+		}
+		rand_x += 1
+	}
+
+	T_contract_number := c.GetString("T_contract_number")
+	T_depot_id, _ := c.GetInt("T_depot_id")
+	T_product := c.GetString("T_product")
+	T_remark := c.GetString("T_remark")
+	//T_date := c.GetString("T_date")
+	T_project := c.GetString("T_project")
+	T_company_name := c.GetString("T_company_name")
+	T_payment_method := c.GetString("T_payment_method")
+	if len(T_company_name) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "公司名称不能为空"}
+		c.ServeJSON()
+		return
+	}
+	if len(T_payment_method) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "付款方式不能为空"}
+		c.ServeJSON()
+		return
+	}
+
+	var_ := Stock.StockOut{
+		T_number:          T_number,
+		T_contract_number: T_contract_number,
+		T_depot_id:        T_depot_id,
+		T_type:            1,
+		//T_date:            T_date,
+		T_receive:        c.User.T_uuid,
+		T_remark:         T_remark,
+		T_project:        T_project,
+		T_submit:         c.User.T_uuid,
+		T_state:          Stock.StockOutWaitAudit,
+		T_company_name:   T_company_name,
+		T_payment_method: T_payment_method,
+	}
+
+	o.Begin()
+	StockOutProductDao := Stock.NewStockOutProduct(o)
+	StockDao := Stock.NewStock(o)
+
+	_, err := StockOutDao.Add_StockOut(var_)
+	if err != nil {
+		o.Rollback()
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库失败"}
+		c.ServeJSON()
+		return
+	}
+
+	// 1、添加出库单
+
+	if len(T_product) == 0 {
+		o.Rollback()
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "产品明细不能为空"}
+		c.ServeJSON()
+		return
+	}
+
+	productList := lib.SplitString(T_product, "|")
+	allProductList := []int{}
+	for _, v := range productList {
+		product_id, _ := strconv.Atoi(strings.Split(v, "-")[0])
+		allProductList = append(allProductList, product_id)
+		product, _ := Basic.Read_Product_ById(product_id)
+
+		num, _ := strconv.Atoi(strings.Split(v, "-")[1])
+		// 2、添加出库产品清单
+		stockOutProduct := Stock.StockOutProduct{
+			T_number:     T_number,
+			T_product_id: product_id,
+			T_depot_id:   T_depot_id,
+			T_num:        num, // 出库数量
+			T_state:      2,
+		}
+		_, err = StockOutProductDao.Add_StockOutProduct(stockOutProduct)
+		if err != nil {
+			o.Rollback()
+			c.Data["json"] = lib.JSONS{Code: 203, Msg: "申请出库失败"}
+			c.ServeJSON()
+			return
+		}
+		// 3、更新产品库存列表
+		_, err = StockDao.AddOrUpdate_Occupy_Stock(T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, num, 2)
+		if err != nil {
+			o.Rollback()
+			c.Data["json"] = lib.JSONS{Code: 203, Msg: "更新占用库存失败" + err.Error()}
+			c.ServeJSON()
+			return
+		}
+
+	}
+
+	o.Commit()
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "出库申请", "出库申请", var_)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
+	c.ServeJSON()
+	return
+}
+
+// 修改出库申请
+func (c *StockController) StockOut_Apply_Edit() {
+
+	T_number := c.GetString("T_number") // 出库单号
+	//T_depot_id, _ := c.GetInt("T_depot_id")
+	T_date := c.GetString("T_date")
+	T_receive := c.GetString("T_receive")
+	T_project := c.GetString("T_project")
+	T_product := c.GetString("T_product")
+	T_remark := c.GetString("T_remark")
+	_, is := lib.DateStrToTime(T_date)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "日期格式错误!"}
+		c.ServeJSON()
+		return
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "仓库管理", "修改出库", T_product)
+	o := orm.NewOrm()
+	o.Begin()
+	StockOutDao := Stock.NewStockOut(o)
+	StockOutProductDao := Stock.NewStockOutProduct(o)
+	StockDao := Stock.NewStock(o)
+
+	// 查询入库信息
+	StockOut, err := StockOutDao.Read_StockOut_ByT_number(T_number)
+	if err != nil {
+		o.Rollback()
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败!"}
+		c.ServeJSON()
+		return
+	}
+	T_old_date := StockOut.T_date
+	// 查询入库产品信息
+	productOldList := StockOutProductDao.Read_StockOutProduct_List(StockOut.T_number)
+
+	var oldProductList []dto.StockProduct
+	var newProductList []dto.StockProduct
+	productOldMap := map[int]dto.StockProduct{}
+
+	allProductListMap := make(map[int]struct{})
+	for _, product := range productOldList {
+		stockProduct := dto.StockProduct{
+			T_product_id:  product.T_product_id,
+			T_num:         product.T_num,
+			T_relation_sn: lib.SplitString(product.T_relation_sn, ","),
+		}
+		oldProductList = append(oldProductList, stockProduct)
+		productOldMap[product.T_product_id] = stockProduct
+		if _, ok := allProductListMap[product.T_product_id]; !ok {
+			allProductListMap[product.T_product_id] = struct{}{}
+		}
+
+	}
+	productNewList := lib.SplitString(T_product, "|")
+	productNewMap := map[int]dto.StockProduct{}
+	for _, v := range productNewList {
+		product_id, _ := strconv.Atoi(strings.Split(v, "-")[0])
+		num, _ := strconv.Atoi(strings.Split(v, "-")[1])
+		T_relation_sn := strings.Split(v, "-")[2]
+		stockProduct := dto.StockProduct{
+			T_product_id:  product_id,
+			T_num:         num,
+			T_relation_sn: lib.SplitString(T_relation_sn, ","),
+		}
+		newProductList = append(newProductList, stockProduct)
+		productNewMap[product_id] = stockProduct
+		if _, ok := allProductListMap[product_id]; !ok {
+			allProductListMap[product_id] = struct{}{}
+		}
+	}
+
+	// 判断产品列表信息是否相同
+	StockProductListIsEqual, needDelete, needAdd, needEdit, _ := dto.StockProductListsEqual(oldProductList, newProductList)
+	// 两次提交的数据相同,则不用修改
+	if !StockProductListIsEqual {
+		if len(needDelete) > 0 {
+			// 删除入库产品列表
+			for _, v := range needDelete {
+				product, _ := Basic.Read_Product_ById(v.T_product_id)
+				// 删除入库产品列表
+				err = StockOutProductDao.Delete_StockOutProduct(StockOut.T_number, StockOut.T_depot_id, v.T_product_id)
+				if err != nil {
+					o.Rollback()
+					c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除产品入库信息失败!"}
+					c.ServeJSON()
+					return
+				}
+
+				// 增加库存
+				_, err = StockDao.AddOrUpdate_Occupy_Stock(StockOut.T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, v.T_num, 1)
+				if err != nil {
+					o.Rollback()
+					c.Data["json"] = lib.JSONS{Code: 203, Msg: "更新库存信息失败"}
+					c.ServeJSON()
+					return
+				}
+			}
+		}
+
+		if len(needAdd) > 0 {
+			// 新增入库产品列表
+			for _, v := range needAdd {
+				product, _ := Basic.Read_Product_ById(v.T_product_id)
+
+				StockOutProduct := Stock.StockOutProduct{
+					T_number:     T_number,
+					T_product_id: v.T_product_id,
+					T_depot_id:   StockOut.T_depot_id,
+					T_num:        v.T_num, // 出库数量
+					T_state:      1,
+				}
+				_, err = StockOutProductDao.Add_StockOutProduct(StockOutProduct)
+				if err != nil {
+					o.Rollback()
+					c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
+					c.ServeJSON()
+					return
+				}
+
+				// 减少库存
+				_, err = StockDao.AddOrUpdate_Occupy_Stock(StockOut.T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, v.T_num, 2)
+				if err != nil {
+					o.Rollback()
+					c.Data["json"] = lib.JSONS{Code: 203, Msg: "增加库存失败"}
+					c.ServeJSON()
+					return
+				}
+			}
+		}
+
+		if len(needEdit) > 0 {
+			for _, v := range needEdit {
+				product, _ := Basic.Read_Product_ById(v.T_product_id)
+				StockOutProduct := Stock.StockOutProduct{
+					T_number:     StockOut.T_number,
+					T_product_id: v.T_product_id,
+					T_depot_id:   StockOut.T_depot_id,
+					T_num:        productNewMap[v.T_product_id].T_num, // 入库数量
+					T_state:      1,
+				}
+				// 出库数量比之前多,减少库存
+				var T_type int
+				var T_num int
+
+				if productNewMap[v.T_product_id].T_num > productOldMap[v.T_product_id].T_num {
+					// 减少库存
+					T_type = 2
+					T_num = productNewMap[v.T_product_id].T_num - productOldMap[v.T_product_id].T_num
+				} else {
+					// 增加库存
+					T_type = 1
+					T_num = productOldMap[v.T_product_id].T_num - productNewMap[v.T_product_id].T_num
+				}
+
+				_, err = StockDao.AddOrUpdate_Occupy_Stock(StockOut.T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, T_num, T_type)
+				if err != nil {
+					o.Rollback()
+					c.Data["json"] = lib.JSONS{Code: 203, Msg: err.Error()}
+					c.ServeJSON()
+					return
+				}
+				// 更新产品表
+				err = StockOutProductDao.Update_StockOutProduct(StockOutProduct)
+				if err != nil {
+					o.Rollback()
+					c.Data["json"] = lib.JSONS{Code: 203, Msg: "修改出库产品信息失败"}
+					c.ServeJSON()
+					return
+				}
+			}
+		}
+
+	}
+	if len(T_remark) > 0 {
+		StockOut.T_remark = T_remark
+	}
+	if len(T_receive) > 0 {
+		StockOut.T_receive = T_receive
+	}
+	if len(T_project) > 0 {
+		StockOut.T_project = T_project
+	}
+
+	if len(T_date) > 0 {
+		StockOut.T_date = T_date
+	}
+
+	err = StockOutDao.Update_StockOut(StockOut, "T_remark", "T_receive", "T_project", "T_date")
+	if err != nil {
+		o.Rollback()
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "修改入库失败"}
+		c.ServeJSON()
+		return
+	}
+
+	o.Commit()
+	if len(T_date) > 0 && T_old_date != T_date {
+		// 修改出库产品日期
+		StockOutProductDao.Update_StockOutProduct_T_date(StockOut.T_number, T_date)
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "出库申请", "修改", StockOut)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
+	c.ServeJSON()
+	return
+}
+
+// 财务
+func (c *StockController) StockOut_Finance_List() {
+	// 分页参数 初始化
+	page, _ := c.GetInt("page")
+	if page < 1 {
+		page = 1
+	}
+	page_z, _ := c.GetInt("page_z")
+	if page_z < 1 {
+		page_z = conf.Page_size
+	}
+
+	// 查询
+	T_depot_id, _ := c.GetInt("T_depot_id")
+	T_contract_number := c.GetString("T_contract_number")
+	T_start_date := c.GetString("T_start_date")
+	T_end_date := c.GetString("T_end_date")
+	T_name := c.GetString("T_name")
+
+	userList, _ := NatsServer.Read_User_List_All()
+	Account.Read_User_All_Map(userList)
+	Basic.Read_Depot_All_Map()
+
+	StockOutDao := Stock.NewStockOut(orm.NewOrm())
+	R_List, R_cnt := StockOutDao.Read_StockOut_Audit_List(T_name, Stock.StockOutTypeFinance, T_depot_id, T_contract_number, T_start_date, T_end_date, page, page_z)
+
+	var r_jsons lib.R_JSONS
+	r_jsons.Num = R_cnt
+	r_jsons.Data = R_List
+	r_jsons.Page = page
+	r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+// 管理员
+func (c *StockController) StockOut_Manager_List() {
+	// 分页参数 初始化
+	page, _ := c.GetInt("page")
+	if page < 1 {
+		page = 1
+	}
+	page_z, _ := c.GetInt("page_z")
+	if page_z < 1 {
+		page_z = conf.Page_size
+	}
+
+	// 查询
+	T_depot_id, _ := c.GetInt("T_depot_id")
+	T_contract_number := c.GetString("T_contract_number")
+	T_start_date := c.GetString("T_start_date")
+	T_end_date := c.GetString("T_end_date")
+	T_name := c.GetString("T_name")
+
+	userList, _ := NatsServer.Read_User_List_All()
+	Account.Read_User_All_Map(userList)
+	Basic.Read_Depot_All_Map()
+
+	StockOutDao := Stock.NewStockOut(orm.NewOrm())
+	R_List, R_cnt := StockOutDao.Read_StockOut_Audit_List(T_name, Stock.StockOutTypeManager, T_depot_id, T_contract_number, T_start_date, T_end_date, page, page_z)
+
+	var r_jsons lib.R_JSONS
+	r_jsons.Num = R_cnt
+	r_jsons.Data = R_List
+	r_jsons.Page = page
+	r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+// 仓管
+func (c *StockController) StockOut_Warehouse_List() {
+	// 分页参数 初始化
+	page, _ := c.GetInt("page")
+	if page < 1 {
+		page = 1
+	}
+	page_z, _ := c.GetInt("page_z")
+	if page_z < 1 {
+		page_z = conf.Page_size
+	}
+
+	// 查询
+	T_depot_id, _ := c.GetInt("T_depot_id")
+	T_contract_number := c.GetString("T_contract_number")
+	T_start_date := c.GetString("T_start_date")
+	T_end_date := c.GetString("T_end_date")
+	T_name := c.GetString("T_name")
+
+	userList, _ := NatsServer.Read_User_List_All()
+	Account.Read_User_All_Map(userList)
+	Basic.Read_Depot_All_Map()
+
+	StockOutDao := Stock.NewStockOut(orm.NewOrm())
+	R_List, R_cnt := StockOutDao.Read_StockOut_Audit_List(T_name, Stock.StockOutTypeWarehouse, T_depot_id, T_contract_number, T_start_date, T_end_date, page, page_z)
+
+	var r_jsons lib.R_JSONS
+	r_jsons.Num = R_cnt
+	r_jsons.Data = R_List
+	r_jsons.Page = page
+	r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+// 财务审核
+func (c *StockController) StockOut_Audit() {
+
+	T_number := c.GetString("T_number") // 出库单号
+	//T_depot_id, _ := c.GetInt("T_depot_id")
+	T_audit, _ := c.GetInt("T_audit")                       // 审核 2财务通过 3财务不通过 4总经理通过 5总经理不通过 6已出库
+	T_approval_opinion := c.GetString("T_approval_opinion") // 审批意见
+	T_type := c.GetString("T_type")                         // 类型 Finance  Manager
+
+	o := orm.NewOrm()
+	o.Begin()
+	StockOutDao := Stock.NewStockOut(o)
+	StockDao := Stock.NewStock(o)
+	StockOutProductDao := Stock.NewStockOutProduct(o)
+	StockOut, err := StockOutDao.Read_StockOut_ByT_number(T_number)
+	if err != nil {
+		o.Rollback()
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败!"}
+		c.ServeJSON()
+		return
+	}
+	StockOut.T_state = T_audit
+	if T_type == Stock.StockOutTypeFinance {
+		StockOut.T_finance_approval_opinion = T_approval_opinion
+	} else {
+		StockOut.T_manager_approval_opinion = T_approval_opinion
+	}
+
+	if T_audit == Stock.StockOutAuditFinanceUnPass || T_audit == Stock.StockOutAuditManagerUnPass {
+		productList := StockOutProductDao.Read_StockOutProduct_List(StockOut.T_number)
+		for _, v := range productList {
+			product, _ := Basic.Read_Product_ById(v.T_product_id)
+			_, err = StockDao.AddOrUpdate_Occupy_Stock(StockOut.T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, v.T_num, 1)
+			if err != nil {
+				o.Rollback()
+				c.Data["json"] = lib.JSONS{Code: 203, Msg: err.Error()}
+				c.ServeJSON()
+				return
+			}
+		}
+	}
+
+	err = StockOutDao.Update_StockOut(StockOut, "T_state", "T_finance_approval_opinion", "T_manager_approval_opinion")
+	if err != nil {
+		o.Rollback()
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库审批失败"}
+		c.ServeJSON()
+		return
+	}
+	o.Commit()
+	NatsServer.AddUserLogs(c.User.T_uuid, "出库申请", "审批", StockOut)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
+	c.ServeJSON()
+	return
+}
+
+// 仓管出库
+func (c *StockController) StockOut_Warehouse() {
+
+	T_number := c.GetString("T_number") // 出库单号
+	T_date := c.GetString("T_date")
+	date, is := lib.DateStrToTime(T_date)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "日期格式错误!"}
+		c.ServeJSON()
+		return
+	}
+	NatsServer.AddUserLogs(c.User.T_uuid, "仓库管理", "确认出库", T_number)
+
+	o := orm.NewOrm()
+	o.Begin()
+	StockOutDao := Stock.NewStockOut(o)
+	StockOutProductDao := Stock.NewStockOutProduct(o)
+	DeviceDao := Stock.NewDevice(o)
+	StockDao := Stock.NewStock(o)
+
+	// 查询入库信息
+	StockOut, err := StockOutDao.Read_StockOut_ByT_number(T_number)
+	if err != nil {
+		o.Rollback()
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败!"}
+		c.ServeJSON()
+		return
+	}
+
+	T_product := c.GetString("T_product")
+	productList := lib.SplitString(T_product, "|")
+	allProductList := []int{}
+	for _, v := range productList {
+		product_id, _ := strconv.Atoi(strings.Split(v, "-")[0])
+		allProductList = append(allProductList, product_id)
+		product, _ := Basic.Read_Product_ById(product_id)
+
+		num, _ := strconv.Atoi(strings.Split(v, "-")[1])
+		T_relation_sn := strings.Split(v, "-")[2]
+		if T_relation_sn == "" && product.T_relation_sn == 1 {
+			o.Rollback()
+			c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("%s关联SN,请先添加SN!", product.T_name)}
+			c.ServeJSON()
+			return
+		}
+		// 2、更新设备状态为已出库
+		if len(T_relation_sn) > 0 {
+			snList := strings.Split(T_relation_sn, ",")
+			for _, sn := range snList {
+				mqtt := Stock.Read_MqttUser(sn)
+				device := Stock.Device{
+					T_contract_number: StockOut.T_contract_number,
+					T_product_id:      product_id,
+					T_out_number:      T_number,
+					T_sn:              sn,
+					T_iccid:           mqtt.Iccid,
+					T_imei:            mqtt.Imei,
+					T_State:           1,
+					T_project:         StockOut.T_project,
+					CreateTime:        date,
+				}
+				_, err = DeviceDao.AddOrUpdate_Device(device, 1)
+				if err != nil {
+					o.Rollback()
+					c.Data["json"] = lib.JSONS{Code: 202, Msg: "出库失败"}
+					c.ServeJSON()
+					return
+				}
+			}
+		}
+
+		// 3、添加出库产品清单
+		stockOutProduct := Stock.StockOutProduct{
+			T_number:      T_number,
+			T_product_id:  product_id,
+			T_depot_id:    StockOut.T_depot_id,
+			T_num:         num,    // 出库数量
+			T_date:        T_date, // 出库数量
+			T_relation_sn: T_relation_sn,
+			T_state:       2,
+		}
+
+		// 更新产品表
+		err = StockOutProductDao.Update_StockOutProduct(stockOutProduct)
+		if err != nil {
+			o.Rollback()
+			c.Data["json"] = lib.JSONS{Code: 203, Msg: "修改出库产品信息失败"}
+			c.ServeJSON()
+			return
+		}
+
+		// 5、更新产品库存列表
+		_, err = StockDao.Stock_Warehouse(StockOut.T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, num)
+		if err != nil {
+			o.Rollback()
+			c.Data["json"] = lib.JSONS{Code: 203, Msg: err.Error()}
+			c.ServeJSON()
+			return
+		}
+	}
+
+	StockOut.T_state = Stock.StockOutAlreadyOut
+	err = StockOutDao.Update_StockOut(StockOut, "T_state")
+	if err != nil {
+		o.Rollback()
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库审批失败"}
+		c.ServeJSON()
+		return
+	}
+
+	o.Commit()
+	StockOut_Edit_StockMonth(StockOut.T_date, StockOut.T_depot_id, allProductList)
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "出库申请", "修改", StockOut)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
+	c.ServeJSON()
+	return
+}

+ 1 - 1
go.mod

@@ -1,6 +1,6 @@
 module ERP_storage
 
-go 1.22
+go 1.21
 
 require (
 	github.com/astaxie/beego v1.12.3

+ 5 - 13
main.go

@@ -5,15 +5,9 @@ import (
 	"ERP_storage/conf"
 	"ERP_storage/controllers"
 	"ERP_storage/logs"
-	_ "ERP_storage/models"
-	_ "ERP_storage/models/Account"
+	"ERP_storage/models"
 	"ERP_storage/models/Basic"
-	_ "ERP_storage/models/Contract"
-	_ "ERP_storage/models/Percentage"
-	_ "ERP_storage/models/Property"
-	_ "ERP_storage/models/RepairWorkOrder"
 	_ "ERP_storage/models/Stock"
-	_ "ERP_storage/models/validationtool"
 	_ "ERP_storage/routers"
 	"fmt"
 	"github.com/beego/beego/v2/adapter/orm"
@@ -27,26 +21,22 @@ import (
 )
 
 func init() {
+
 	fmt.Println(runtime.GOOS)
 	orm.RegisterDriver("mysql", orm.DRMySQL)
-	//orm.RegisterDataBase("default", "mysql", "zdxq:7e5853d9178edfcc@tcp(47.108.133.234:3306)/zdxq?charset=utf8",100,200)
 	orm.RegisterDataBase("default", "mysql",
 		conf.MysqlServer_Username+":"+conf.MysqlServer_Password+"@tcp("+conf.MysqlServer_UrlPort+")/"+conf.MysqlServer_Database+"?charset=utf8mb4&loc=Local&parseTime=True",
 		conf.MysqlServer_MaxIdleConnections, conf.MysqlServer_MaxOpenConnections)
-	orm.RunSyncdb("default", false, false) // 创建数据库
-
+	orm.RunSyncdb("default", false, true) // 创建数据库
 	//Mqtt
 	orm.RegisterDriver("mysql", orm.DRMySQL)
 	orm.RegisterDataBase("mqtt", "mysql",
 		conf.MysqlMqtt_Username+":"+conf.MysqlMqtt_Password+"@tcp("+conf.MysqlMqtt_UrlPort+")/"+conf.MysqlMqtt_Database+"?charset=utf8mb4&loc=Local&parseTime=True",
 		conf.MysqlMqtt_MaxIdleConnections, conf.MysqlMqtt_MaxOpenConnections)
 	orm2.Debug = true
-	//orm.RunSyncdb("mqtt", false, false) // 创建数据库
-
 }
 
 func main() {
-
 	HTTPPort, _ := beego.AppConfig.String("HTTPPort")
 	HTTPPort_int, _ := strconv.Atoi(HTTPPort)
 
@@ -72,6 +62,8 @@ func main() {
 	beego.BConfig.RecoverPanic = true
 	beego.BConfig.RecoverFunc = RecoverPanic
 
+	// 自动迁移
+	models.AutoMigrateDB()
 	go Basic.Read_ProductClass_All_Map() // 初始化产品类型
 	go controllers.Cron_StockMonth()     // 库存明细详情定时任务
 	go controllers.Cron_VerifyContract() // 验证合同状态修改定时任务

+ 2 - 2
models/Account/Menu.go

@@ -4,11 +4,11 @@ import (
 	"ERP_storage/conf"
 	"ERP_storage/logs"
 	"fmt"
-	menulibs "gogs.baozhida.cn/zoie/ERP_libs/Menu"
-	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"github.com/astaxie/beego/cache"
 	_ "github.com/astaxie/beego/cache/redis"
 	"github.com/beego/beego/v2/adapter/orm"
+	menulibs "gogs.baozhida.cn/zoie/ERP_libs/Menu"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 )
 
 var RedisCache_API cache.Cache

+ 1 - 1
models/Account/Power.go

@@ -1,8 +1,8 @@
 package Account
 
 import (
-	powerlibs "gogs.baozhida.cn/zoie/ERP_libs/Power"
 	"github.com/beego/beego/v2/adapter/orm"
+	powerlibs "gogs.baozhida.cn/zoie/ERP_libs/Power"
 )
 
 func init() {

+ 1 - 1
models/Contract/ContractProduct.go

@@ -4,8 +4,8 @@ import (
 	"ERP_storage/logs"
 	"ERP_storage/models/Basic"
 	"fmt"
-	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	orm2 "github.com/beego/beego/v2/client/orm"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"strconv"
 	"time"
 

+ 1 - 1
models/IOTNetworkCard/IOTNetworkCard.go

@@ -37,7 +37,7 @@ var (
 
 // 物联网卡
 type IOTNetworkCard struct {
-	Id              int       `orm:"column(ID);size(11);auto;pk"`
+	Id              int       `orm:"column(ID);size(11);column(id);auto;pk"`
 	T_company_name  string    `orm:"size(256);null"`                                        // 入库日期
 	T_in_date       string    `orm:"size(256);null"`                                        // 入库日期
 	T_out_date      string    `orm:"size(256);null"`                                        // 出库日期

+ 1 - 2
models/Percentage/Percentage.go

@@ -23,7 +23,6 @@ const (
 	RemitPart       // 部分打款
 	RemitAll        // 全部打款
 	NotSubmit       // 未提交审核
-
 )
 
 var (
@@ -61,7 +60,7 @@ func Read_Audit_Get(Id int) string {
 
 // 提成
 type Percentage struct {
-	Id                    int     `orm:"column(ID);size(11);column(id);auto;pk"`
+	Id                    int     `orm:"size(11);column(id);auto;pk"`
 	T_Distributor_id      string  `orm:"size(256);column(t_distributor_id);null"` // 分销商id
 	T_task_id             string  `orm:"size(256);null"`                          // 任务id
 	T_task_name           string  `orm:"size(256);null"`                          // 任务名称

+ 1 - 1
models/Percentage/verifyCompany.go

@@ -15,7 +15,7 @@ import (
 var VerifyCompanyMap *sync.Map // 泛型
 
 type VerifyCompany struct {
-	Id                 int       `orm:"column(ID);size(11);auto;pk"`
+	Id                 int       `orm:"column(id);size(11);auto;pk"`
 	T_Distributor_id   string    `orm:"size(256);column(t_distributor_id);null"`               // 分销商id
 	T_Distributor_name string    `orm:"size(256);column(t_distributor_name);null"`             // 分销商id
 	T_uuid             string    `orm:"size(256);null"`                                        //

+ 13 - 13
models/ProjectFiling/ProjectFiling.go

@@ -11,19 +11,19 @@ import (
 
 // 验证项目
 type ProjectFiling struct {
-	Id                         int    `orm:"column(ID);size(11);auto;pk"`
-	T_date                     string `orm:"size(256);null"`      // 备案时间
-	T_sales_personnel          string `orm:"size(256);null"`      // 销售人员
-	T_customers                string `orm:"size(256);null"`      // 客户名称
-	T_customers_type           string `orm:"size(256);null"`      // 客户类型
-	T_service_type             string `orm:"size(256);null"`      // 服务类型
-	T_content                  string `orm:"size(256);null"`      // 具体内容
-	T_estimate_contract_amount string `orm:"size(256);null"`      // 预计合同金额
-	T_sign_bill_time           string `orm:"size(256);null"`      // 预计签单时间
-	T_prepare_content          string `orm:"size(256);null"`      // 提前准备内容
-	T_remark                   string `orm:"size(256);null"`      // 备注
-	T_state                    int    `orm:"size(2);default(1)"`  // 0 删除(伪删除)   1 正常
-	T_uuid                     string `orm:"index;size(32);null"` // 申请人
+	Id                         int    `orm:"column(id);size(11);auto;pk"`
+	T_date                     string `orm:"size(256);null"`     // 备案时间
+	T_sales_personnel          string `orm:"size(256);null"`     // 销售人员
+	T_customers                string `orm:"size(256);null"`     // 客户名称
+	T_customers_type           string `orm:"size(256);null"`     // 客户类型
+	T_service_type             string `orm:"size(256);null"`     // 服务类型
+	T_content                  string `orm:"size(256);null"`     // 具体内容
+	T_estimate_contract_amount string `orm:"size(256);null"`     // 预计合同金额
+	T_sign_bill_time           string `orm:"size(256);null"`     // 预计签单时间
+	T_prepare_content          string `orm:"size(256);null"`     // 提前准备内容
+	T_remark                   string `orm:"size(256);null"`     // 备注
+	T_state                    int    `orm:"size(2);default(1)"` // 0 删除(伪删除)   1 正常
+	T_uuid                     string `orm:"size(32);null"`      // 申请人
 
 }
 

+ 9 - 9
models/Purchase/Purchase.go

@@ -22,15 +22,15 @@ const (
 
 // 项目管理
 type Purchase struct {
-	Id              int    `orm:"column(ID);size(11);auto;pk"`
-	T_uuid          string `orm:"index;size(32);null"` // 申请人
-	T_dept          string `orm:"index;size(32);null"` // 申请部门
-	T_submit        string `orm:"index;size(32);null"` // 提交人
-	T_date          string `orm:"size(256);null"`      // 申请时间
-	T_detail        string `orm:"type(text);null"`     // 明细
-	T_remark        string `orm:"type(text);null"`     // 备注
-	T_approver      string `orm:"size(32);null"`       // 审批人
-	T_approver_date string `orm:"size(32);null"`       // 审批时间
+	Id              int    `orm:"column(id);size(11);auto;pk"`
+	T_uuid          string `orm:"size(32);null"`   // 申请人
+	T_dept          string `orm:"size(32);null"`   // 申请部门
+	T_submit        string `orm:"size(32);null"`   // 提交人
+	T_date          string `orm:"size(256);null"`  // 申请时间
+	T_detail        string `orm:"type(text);null"` // 明细
+	T_remark        string `orm:"type(text);null"` // 备注
+	T_approver      string `orm:"size(32);null"`   // 审批人
+	T_approver_date string `orm:"size(32);null"`   // 审批时间
 
 	T_State    int       `orm:"size(2);column(t_state);default(1)"`                    // 0 删除  1待采购  2已采购 3待审核 4未通过
 	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间

+ 1 - 1
models/RepairWorkOrder/RepairWorkOrder.go

@@ -17,7 +17,7 @@ const (
 )
 
 type RepairWorkOrder struct {
-	Id                   int    `orm:"column(ID);size(11);auto;pk"`
+	Id                   int    `orm:"column(id);size(11);auto;pk"`
 	T_order_date         string `orm:"size(256);null"`     // 下单日期
 	T_repair_date        string `orm:"size(256);null"`     // 维修日期
 	T_finish_date        string `orm:"size(256);null"`     // 完结日期

+ 104 - 0
models/Stock/Stock.go

@@ -26,6 +26,7 @@ type Stock struct {
 	T_product_model string    `orm:"size(256);null"`                                        // 产品型号
 	T_total         int       `orm:"size(20);null"`                                         // 库存数量
 	T_reality       int       `orm:"size(20);null"`                                         // 盘点数量
+	T_occupy        int       `orm:"size(20);null"`                                         // 占用库存
 	T_sort          int       `orm:"size(20);null"`                                         // 排序
 	CreateTime      time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
 	UpdateTime      time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
@@ -155,6 +156,109 @@ func (dao *StockDaoImpl) AddOrUpdate_Stock(T_depot_id, T_product_id, T_product_c
 	return
 }
 
+// T_type  1-减少占用库存 2-增加占用库存
+func (dao *StockDaoImpl) AddOrUpdate_Occupy_Stock(T_depot_id, T_product_id, T_product_class int, T_product_name, T_product_model string, T_num, T_type int) (id int64, err error) {
+
+	qs := dao.orm.QueryTable(new(Stock))
+	var stock Stock
+	err = qs.Filter("T_depot_id", T_depot_id).Filter("T_product_id", T_product_id).One(&stock)
+	if err != nil {
+		if err.Error() == orm.ErrNoRows.Error() {
+			r := Stock{
+				T_depot_id:      T_depot_id,
+				T_product_id:    T_product_id,
+				T_product_name:  T_product_name,
+				T_product_class: T_product_class,
+				T_product_model: T_product_model,
+				T_occupy:        T_num,
+			}
+			id, err = dao.orm.Insert(&r)
+			if err != nil {
+				err = errors.New("添加库存失败")
+				logs.Error(lib.FuncName(), err)
+			}
+			return
+		} else {
+			err = errors.New("查询库存失败")
+
+			logs.Error(lib.FuncName(), err)
+			return
+		}
+	}
+	// T_type 1-审核不通过 2-其他状态
+	if T_type == 1 {
+		stock.T_occupy -= T_num
+	}
+	if stock.T_reality-stock.T_occupy-T_num < 0 {
+		err = errors.New(fmt.Sprintf("%s%s库存不足", T_product_name, T_product_model))
+		logs.Error(lib.FuncName(), err.Error())
+		return
+	}
+
+	if T_type == 2 {
+		stock.T_occupy += T_num
+	}
+
+	_, err = dao.orm.Update(&stock, "T_occupy")
+	if err != nil {
+		err = errors.New(fmt.Sprintf("修改占用库存失败%s,%s", T_product_name, T_product_model))
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	return
+}
+
+// T_type  1-审核不通过(减少占用库存) 2-其他状态(增加占用库存)
+func (dao *StockDaoImpl) Stock_Warehouse(T_depot_id, T_product_id, T_product_class int, T_product_name, T_product_model string, T_num int) (id int64, err error) {
+
+	qs := dao.orm.QueryTable(new(Stock))
+	var stock Stock
+	err = qs.Filter("T_depot_id", T_depot_id).Filter("T_product_id", T_product_id).One(&stock)
+	if err != nil {
+		if err.Error() == orm.ErrNoRows.Error() {
+			r := Stock{
+				T_depot_id:      T_depot_id,
+				T_product_id:    T_product_id,
+				T_product_name:  T_product_name,
+				T_product_class: T_product_class,
+				T_product_model: T_product_model,
+				T_occupy:        T_num,
+			}
+			id, err = dao.orm.Insert(&r)
+			if err != nil {
+				err = errors.New("添加库存失败")
+				logs.Error(lib.FuncName(), err)
+			}
+			return
+		} else {
+			err = errors.New("查询库存失败")
+
+			logs.Error(lib.FuncName(), err)
+			return
+		}
+	}
+
+	stock.T_occupy -= T_num
+	stock.T_total -= T_num
+	stock.T_reality -= T_num
+
+	if stock.T_reality < 0 {
+		err = errors.New(fmt.Sprintf("%s%s库存不足", T_product_name, T_product_model))
+		logs.Error(lib.FuncName(), err.Error())
+		return
+	}
+
+	_, err = dao.orm.Update(&stock, "T_total", "T_reality", "T_occupy")
+	if err != nil {
+		err = errors.New(fmt.Sprintf("修改占用库存失败%s,%s", T_product_name, T_product_model))
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	return
+}
+
 // 获取 ById
 func (dao *StockDaoImpl) Read_Stock_ByT_depot_id_T_product_id(T_depot_id, T_product_id int) (r Stock, err error) {
 	qs := dao.orm.QueryTable(new(Stock))

+ 154 - 17
models/Stock/StockOut.go

@@ -16,6 +16,46 @@ import (
 	_ "github.com/go-sql-driver/mysql"
 )
 
+func Get_StockOut_audit_name(T_audt int) string {
+	switch T_audt {
+	case 1:
+		return "待审核"
+	case 2:
+		return "财务通过"
+	case 3:
+		return "财务驳回"
+	case 4:
+		return "总经理通过"
+	case 5:
+		return "总经理驳回"
+	case 6:
+		return "已出库"
+	default:
+		return ""
+	}
+
+}
+
+const (
+	Delete                     int = iota
+	StockOutWaitAudit              // 待审核
+	StockOutAuditFinancePass       // 财务通过
+	StockOutAuditFinanceUnPass     // 财务驳回
+	StockOutAuditManagerPass       // 总经理通过
+	StockOutAuditManagerUnPass     // 总经理驳回
+	StockOutAlreadyOut             // 已出库
+
+	StockOutTypeFinance   = "Finance"
+	StockOutTypeManager   = "Manager"
+	StockOutTypeWarehouse = "Warehouse"
+
+	// A,B 需要财务审核
+	StockOutPaymentMethodA = "A" // 先款后货
+	StockOutPaymentMethodB = "B" // 收部分定金50%
+	StockOutPaymentMethodC = "C" // 先货后款
+	StockOutPaymentMethodD = "D" // 项目支持,无同意(必须冯总同意)
+)
+
 // 入库
 type StockOut struct {
 	Id                int    `orm:"column(ID);size(11);auto;pk"`
@@ -36,6 +76,12 @@ type StockOut struct {
 	T_signer_date    string `orm:"size(256);null"` // 签收日期
 	T_courier_number string `orm:"size(256);null"` // 物流单号
 
+	T_company_name             string `orm:"size(256);null"`                     // 公司名称
+	T_payment_method           string `orm:"size(256);null"`                     // 付款方式 A先款后货 B收部分定金50% C先货后款 D项目支持,无同意
+	T_state                    int    `orm:"size(2);column(t_state);default(6)"` // 0 删除 1待审核  2财务通过 3财务不通过 4总经理通过 5总经理不通过 6已出库
+	T_finance_approval_opinion string `orm:"size(256);null"`                     // 财务审批意见
+	T_manager_approval_opinion string `orm:"size(256);null"`                     // 总经理审批意见
+
 	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
 	UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
 }
@@ -58,16 +104,22 @@ func init() {
 }
 
 type StockOut_R struct {
-	Id                int
-	T_number          string // 出库单号
-	T_contract_number string // 合同编号
-	T_depot_id        int    // 仓库id
-	T_depot_name      string // 仓库名称
-	T_type            int    // 出库类型 1-领料出库 2-销售出库
-	T_date            string // 业务日期
-	T_receive         string // 领取人
-	T_receive_name    string // 领取人名称
-	T_project         string // 关联项目
+	Id                         int
+	T_number                   string // 出库单号
+	T_contract_number          string // 合同编号
+	T_depot_id                 int    // 仓库id
+	T_depot_name               string // 仓库名称
+	T_type                     int    // 出库类型 1-领料出库 2-销售出库
+	T_date                     string // 业务日期
+	T_receive                  string // 领取人
+	T_receive_name             string // 领取人名称
+	T_project                  string // 关联项目
+	T_company_name             string // 公司名称
+	T_payment_method           string // 付款方式 A先款后货 B收部分定金50% C先货后款 D项目支持,无同意
+	T_state                    int    // 0 删除 1待审核  2财务通过 3财务不通过 4总经理通过 5总经理不通过 6已出库
+	T_state_str                string
+	T_finance_approval_opinion string // 财务审批意见
+	T_manager_approval_opinion string // 总经理审批意见
 }
 
 type StockOut_Detail struct {
@@ -85,13 +137,19 @@ type StockOut_Detail struct {
 	T_project         string // 关联项目
 	T_remark          string // 备注
 	// ----销售出库------
-	T_delivery_type  int    // 1-自送 2-自提 3-快递
-	T_signer_unit    string // 签收单位
-	T_signer         string // 签收人
-	T_signer_phone   string // 签收人联系电话
-	T_signer_date    string // 签收日期
-	T_courier_number string // 物流单号
-	T_Product        []StockOutProduct_R
+	T_delivery_type            int    // 1-自送 2-自提 3-快递
+	T_signer_unit              string // 签收单位
+	T_signer                   string // 签收人
+	T_signer_phone             string // 签收人联系电话
+	T_signer_date              string // 签收日期
+	T_courier_number           string // 物流单号
+	T_company_name             string // 公司名称
+	T_payment_method           string // 付款方式 A先款后货 B收部分定金50% C先货后款 D项目支持,无同意
+	T_state                    int    // 0 删除 1待审核  2财务通过 3财务不通过 4总经理通过 5总经理不通过 6已出库
+	T_state_str                string
+	T_finance_approval_opinion string // 财务审批意见
+	T_manager_approval_opinion string // 总经理审批意见
+	T_Product                  []StockOutProduct_R
 }
 
 func StockOutToStockOut_R(t StockOut) (r StockOut_R) {
@@ -105,6 +163,12 @@ func StockOutToStockOut_R(t StockOut) (r StockOut_R) {
 	r.T_receive = t.T_receive
 	r.T_receive_name = Account.Read_User_T_name_Get(t.T_receive)
 	r.T_project = t.T_project
+	r.T_company_name = t.T_company_name
+	r.T_payment_method = t.T_payment_method
+	r.T_state = t.T_state
+	r.T_state_str = Get_StockOut_audit_name(t.T_state)
+	r.T_finance_approval_opinion = t.T_finance_approval_opinion
+	r.T_manager_approval_opinion = t.T_manager_approval_opinion
 	return r
 }
 
@@ -126,6 +190,12 @@ func StockOutToStockOut_Detail(t StockOut, productList []StockOutProduct_R) (r S
 	r.T_signer_phone = t.T_signer_phone
 	r.T_signer_date = t.T_signer_date
 	r.T_courier_number = t.T_courier_number
+	r.T_company_name = t.T_company_name
+	r.T_payment_method = t.T_payment_method
+	r.T_state = t.T_state
+	r.T_state_str = Get_StockOut_audit_name(t.T_state)
+	r.T_finance_approval_opinion = t.T_finance_approval_opinion
+	r.T_manager_approval_opinion = t.T_manager_approval_opinion
 	r.T_Product = productList
 	return r
 }
@@ -181,6 +251,73 @@ func (dao *StockOutDaoImpl) Read_StockOut_List(T_name string, T_depot_id int, T_
 
 	// 过滤
 	cond := orm.NewCondition()
+	cond = cond.And("T_state", StockOutAlreadyOut)
+	if T_depot_id > 0 {
+		cond = cond.And("T_depot_id", T_depot_id)
+	}
+	if len(T_name) > 0 {
+		cond = cond.And("T_number__icontains", T_name)
+	}
+	if len(T_contract_number) > 0 {
+		cond = cond.And("T_contract_number", T_contract_number)
+	}
+
+	if len(T_start_date) > 0 {
+		cond = cond.And("T_date__gte", T_start_date)
+	}
+
+	if len(T_end_date) > 0 {
+		cond = cond.And("T_date__lte", T_end_date)
+	}
+
+	// 查询
+	var r []StockOut
+	_, err := qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond)).OrderBy("-Id").All(&r)
+
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	cnt, err = qs.SetCond((*orm2.Condition)(cond)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range r {
+		r_ = append(r_, StockOutToStockOut_R(v))
+	}
+
+	return r_, cnt
+}
+
+// 获取出库审核列表
+func (dao *StockOutDaoImpl) Read_StockOut_Audit_List(T_name, T_type string, T_depot_id int, T_contract_number, T_start_date, T_end_date string, page, page_z int) (r_ []StockOut_R, cnt int64) {
+	qs := dao.orm.QueryTable(new(StockOut))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	// 过滤
+	cond1 := orm.NewCondition()
+	cond := orm.NewCondition()
+	if T_type == StockOutTypeFinance {
+		cond = cond.And("T_state__in", []int{StockOutWaitAudit, StockOutAuditFinancePass, StockOutAuditFinanceUnPass})
+		cond = cond.And("T_payment_method__in", []string{StockOutPaymentMethodA, StockOutPaymentMethodB})
+	}
+	if T_type == StockOutTypeManager {
+		cond = cond.AndCond(cond1.Or("T_state__in", []int{StockOutAuditFinancePass, StockOutAuditManagerPass, StockOutAuditManagerUnPass}).
+			OrCond(cond1.And("T_state", StockOutWaitAudit).And("T_payment_method__in", []string{StockOutPaymentMethodC, StockOutPaymentMethodD})))
+	}
+
+	if T_type == StockOutTypeWarehouse {
+		cond = cond.And("T_state", StockOutAuditManagerPass)
+
+	}
 
 	if T_depot_id > 0 {
 		cond = cond.And("T_depot_id", T_depot_id)

+ 5 - 3
models/Stock/StockOutProduct.go

@@ -3,8 +3,8 @@ package Stock
 import (
 	"ERP_storage/models/Account"
 	"ERP_storage/models/Basic"
-	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	orm2 "github.com/beego/beego/v2/client/orm"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"strconv"
 	"time"
 
@@ -23,6 +23,7 @@ type StockOutProduct struct {
 	T_num         int       `orm:"size(20);null"`                                         // 入库数量
 	T_date        string    `orm:"size(256);null"`                                        // 业务日期
 	T_relation_sn string    `orm:"type(text);null"`                                       // 关联sn,20220101,20230202,
+	T_state       int       `orm:"size(2);column(t_state);default(1)"`                    // 1已出库  2待出库
 	CreateTime    time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
 	UpdateTime    time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
 }
@@ -178,8 +179,9 @@ func (dao *StockOutProductDaoImpl) Update_StockOutProduct(r StockOutProduct) err
 	product.T_depot_id = r.T_depot_id
 	product.T_num = r.T_num
 	product.T_relation_sn = r.T_relation_sn
+	product.T_state = r.T_state
 
-	_, err = dao.orm.Update(&product, "T_depot_id", "T_num", "T_relation_sn")
+	_, err = dao.orm.Update(&product, "T_depot_id", "T_num", "T_relation_sn", "T_state")
 	if err != nil {
 		logs.Error(lib.FuncName(), err)
 		return err
@@ -219,7 +221,7 @@ func (dao *StockOutProductDaoImpl) Delete_StockOutProduct(T_number string, T_dep
 
 // 根据库存id、产品id、月份获取本月出库总数量
 func (dao *StockOutProductDaoImpl) Read_StockOut_Total(T_depot_id, T_product_id int, T_date string) int {
-	sql := "SELECT SUM(t_num) FROM stock_out_product WHERE t_depot_id = " + strconv.Itoa(T_depot_id) + " AND t_product_id = " + strconv.Itoa(T_product_id) + " AND t_date like '" + T_date + "%'"
+	sql := "SELECT SUM(t_num) FROM stock_out_product WHERE t_depot_id = " + strconv.Itoa(T_depot_id) + " AND t_state=1 AND t_product_id = " + strconv.Itoa(T_product_id) + " AND t_date like '" + T_date + "%'"
 
 	var pl_lists orm2.ParamsList
 	_, err := dao.orm.Raw(sql).ValuesFlat(&pl_lists)

+ 3 - 19
models/init.go

@@ -3,19 +3,12 @@ package models
 import (
 	db "ERP_storage/initialize"
 	"ERP_storage/models/ContractReview"
-	"ERP_storage/models/IOTNetworkCard"
-	"ERP_storage/models/Percentage"
-	"ERP_storage/models/ProjectFiling"
-	"ERP_storage/models/Purchase"
-	"ERP_storage/models/RepairWorkOrder"
-	"ERP_storage/models/validationtool"
-	_ "github.com/go-sql-driver/mysql"
 	"log"
 )
 
-func init() {
-	AutoMigrateDB()
-}
+//func init() {
+//	AutoMigrateDB()
+//}
 
 func AutoMigrateDB() {
 	//自动迁移模式
@@ -25,15 +18,6 @@ func AutoMigrateDB() {
 			&ContractReview.ServiceItem{},
 			&ContractReview.ContractReview{},
 			&ContractReview.ContractReviewServiceItem{},
-			&validationtool.ValidationTool{},
-			&validationtool.ValidationToolClass{},
-			&IOTNetworkCard.IOTNetworkCard{},
-			&Percentage.VerifyCompany{},
-			&Percentage.Percentage{},
-			&RepairWorkOrder.RepairWorkOrder{},
-			&Purchase.Purchase{},
-			&validationtool.ValidationToolHistory{},
-			&ProjectFiling.ProjectFiling{},
 		)
 	if err != nil {
 		log.Fatalf("migrate db fail: %v", err)

+ 1 - 1
models/validationtool/validation.go

@@ -30,7 +30,7 @@ var (
 )
 
 type ValidationTool struct {
-	Id               int       `orm:"column(ID);size(11);auto;pk"`                           // 合同编号
+	Id               int       `orm:"column(id);size(11);auto;pk"`                           // 合同编号
 	T_class          int       `orm:"size(20);default(0)"`                                   // 产品分类 T_class=0 冷链验证 	// 产品id
 	Validationnumber string    `orm:"size(256);null"`                                        // 验证工具编号
 	T_sn             string    `orm:"size(256);null"`                                        // 设备sn

+ 1 - 1
models/validationtool/validationClass.go

@@ -12,7 +12,7 @@ import (
 
 // 验证设备分类
 type ValidationToolClass struct {
-	Id         int       `orm:"column(ID);size(11);auto;pk"`
+	Id         int       `orm:"column(id);size(11);auto;pk"`
 	T_name     string    `orm:"size(256);null"`                                        // 名称
 	T_State    int       `orm:"size(2);default(1)"`                                    // 0 删除(伪删除)   1 正常
 	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间

+ 1 - 1
models/validationtool/validationHistory.go

@@ -11,7 +11,7 @@ import (
 )
 
 type ValidationToolHistory struct {
-	Id               int       `orm:"column(ID);size(11);auto;pk"`                           // 合同编号
+	Id               int       `orm:"column(id);size(11);auto;pk"`                           // 合同编号
 	T_class          int       `orm:"size(20);default(0)"`                                   // 产品分类 T_class=0 冷链验证 	// 产品id
 	Validationnumber string    `orm:"size(256);null"`                                        // 验证工具编号
 	T_sn             string    `orm:"size(256);null"`                                        // 设备sn

+ 7 - 1
routers/Stock.go

@@ -39,7 +39,13 @@ func init() {
 		beego.NSRouter("/Edit", &controllers.StockController{}, "*:StockOut_Edit"),                             // 修改出库
 		beego.NSRouter("/Del", &controllers.StockController{}, "*:StockOut_Del"),                               // 删除出库
 		beego.NSRouter("/Excel", &controllers.StockController{}, "*:StockOut_Excel"),
-		beego.NSRouter("/Excel_Batch", &controllers.StockController{}, "*:StockOut_Excel_Batch"), // 批量导出入库
+		beego.NSRouter("/Excel_Batch", &controllers.StockController{}, "*:StockOut_Excel_Batch"),       // 批量导出入库
+		beego.NSRouter("/Apply", &controllers.StockController{}, "*:StockOut_Apply"),                   // 出库申请
+		beego.NSRouter("/Finance_List", &controllers.StockController{}, "*:StockOut_Finance_List"),     // 财务审核列表
+		beego.NSRouter("/Manager_List", &controllers.StockController{}, "*:StockOut_Manager_List"),     // 总经理审核列表
+		beego.NSRouter("/Warehouse_List", &controllers.StockController{}, "*:StockOut_Warehouse_List"), // 总经理审核列表
+		beego.NSRouter("/Audit", &controllers.StockController{}, "*:StockOut_Audit"),                   // 审核
+		beego.NSRouter("/Warehouse", &controllers.StockController{}, "*:StockOut_Warehouse"),           // 确认出库
 		// 导出出库
 	)
 	beego.AddNamespace(device, stock, stockIn, stockOut)