Explorar o código

ADD:导出出入库单,库存明细添加排序

zoie hai 6 meses
pai
achega
7114936a8a

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 695 - 98
controllers/Stock.go


+ 0 - 1
controllers/test.go

@@ -1 +0,0 @@
-package controllers

+ 76 - 0
dto/Stock.go

@@ -0,0 +1,76 @@
+package dto
+
+import (
+	"git.baozhida.cn/ERP_libs/lib"
+	"sort"
+)
+
+// 入库产品mingxi
+
+type StockProduct struct {
+	T_product_id  int
+	T_num         int
+	T_relation_sn []string
+}
+
+type StockProductRelationSn struct {
+	T_product_id         int
+	T_delete_relation_sn []string
+	T_add_relation_sn    []string
+}
+
+// 比较两个StockProduct列表是否相等
+func StockProductListsEqual(a, b []StockProduct) (isEqual bool, needDelete, needAdd, needEdit map[int]StockProduct, snDiff map[int]StockProductRelationSn) {
+	needDelete = make(map[int]StockProduct)
+	needAdd = make(map[int]StockProduct)
+	needEdit = make(map[int]StockProduct)
+	snDiff = make(map[int]StockProductRelationSn)
+	isEqual = true
+	// 原始数据
+	aMap := make(map[int]StockProduct)
+	aProductList := []int{}
+	for _, item := range a {
+		sort.Strings(item.T_relation_sn)
+		aMap[item.T_product_id] = item
+		aProductList = append(aProductList, item.T_product_id)
+	}
+	// 修改提交的数据
+	bMap := make(map[int]StockProduct)
+	bProductList := []int{}
+	for _, item := range b {
+		sort.Strings(item.T_relation_sn)
+		bMap[item.T_product_id] = item
+		bProductList = append(bProductList, item.T_product_id)
+	}
+
+	// 查询需要删除的产品 和需要添加的产品
+	_, commonIds, needDeleteIds, needAddIds := lib.IntListCompare(aProductList, bProductList)
+
+	for _, product_id := range commonIds {
+		equal, _, T_delete_relation_sn, T_add_relation_sn := lib.StringListCompare(aMap[product_id].T_relation_sn, bMap[product_id].T_relation_sn)
+		snDiff[product_id] = StockProductRelationSn{
+			T_product_id:         product_id,
+			T_delete_relation_sn: T_delete_relation_sn,
+			T_add_relation_sn:    T_add_relation_sn,
+		}
+		if bMap[product_id].T_num != aMap[product_id].T_num && len(bMap[product_id].T_relation_sn) == 0 {
+			needEdit[product_id] = bMap[product_id]
+		}
+
+		if !equal {
+			isEqual = false
+		}
+	}
+
+	if len(needDelete) == 0 && len(needAdd) == 0 && len(needEdit) == 0 && isEqual {
+		isEqual = true
+	}
+	for _, id := range needDeleteIds {
+		needDelete[id] = aMap[id]
+	}
+	for _, id := range needAddIds {
+		needAdd[id] = bMap[id]
+	}
+
+	return isEqual, needDelete, needAdd, needEdit, snDiff
+}

+ 212 - 0
dto/search/Stock_test.go

@@ -0,0 +1,212 @@
+package search
+
+import (
+	"fmt"
+	"reflect"
+	"sort"
+	"testing"
+)
+
+// 对比两个列表数据是否相同
+func StringListCompare(list1, list2 []string) (isEqual bool, common, onlyList1, onlyList2 []string) {
+	if len(list1) != len(list2) {
+		isEqual = false
+	}
+
+	// 创建map来存储list1列表中的元素
+	AMap := make(map[string]int)
+	for _, item := range list1 {
+		AMap[item]++
+	}
+
+	// 检查B列表中的元素是否在AMap中
+	for _, item := range list2 {
+		if count, exists := AMap[item]; !exists || count == 0 {
+			isEqual = false
+		}
+		AMap[item]--
+	}
+	if !isEqual {
+		// 创建一个map来存储A列表中的元素
+		list1Map := make(map[string]struct{})
+		for _, a := range list1 {
+			list1Map[a] = struct{}{}
+		}
+
+		// 查找list2列表中存在但list1列表中不存在的元素
+		for _, v := range list2 {
+			if _, exists := list1Map[v]; !exists {
+				onlyList2 = append(onlyList2, v)
+			} else {
+				common = append(common, v)
+			}
+		}
+
+		// 创建一个map来存储B列表中的元素
+		list2Map := make(map[string]struct{})
+		for _, b := range list2 {
+			list2Map[b] = struct{}{}
+		}
+
+		// 查找list1列表中存在但list2列表中不存在的元素
+		for _, a := range list1 {
+			if _, exists := list2Map[a]; !exists {
+				onlyList1 = append(onlyList1, a)
+			}
+		}
+
+	}
+
+	isEqual = true
+	return
+}
+func IntListCompare(list1, list2 []int) (isEqual bool, common, onlyList1, onlyList2 []int) {
+	if len(list1) != len(list2) {
+		isEqual = false
+	}
+
+	// 创建map来存储list1列表中的元素
+	AMap := make(map[int]int)
+	for _, item := range list1 {
+		AMap[item]++
+	}
+
+	// 检查B列表中的元素是否在AMap中
+	for _, item := range list2 {
+		if count, exists := AMap[item]; !exists || count == 0 {
+			isEqual = false
+		}
+		AMap[item]--
+	}
+	if !isEqual {
+		// 创建一个map来存储A列表中的元素
+		list1Map := make(map[int]struct{})
+		for _, a := range list1 {
+			list1Map[a] = struct{}{}
+		}
+
+		// 查找list2列表中存在但list1列表中不存在的元素
+		for _, v := range list2 {
+			if _, exists := list1Map[v]; !exists {
+				onlyList2 = append(onlyList2, v)
+			} else {
+				common = append(common, v)
+			}
+		}
+
+		// 创建一个map来存储B列表中的元素
+		list2Map := make(map[int]struct{})
+		for _, b := range list2 {
+			list2Map[b] = struct{}{}
+		}
+
+		// 查找list1列表中存在但list2列表中不存在的元素
+		for _, a := range list1 {
+			if _, exists := list2Map[a]; !exists {
+				onlyList1 = append(onlyList1, a)
+			}
+		}
+
+	}
+
+	isEqual = true
+	return
+}
+
+type StockProduct struct {
+	T_product_id  int
+	T_num         int
+	T_relation_sn []string
+}
+
+type StockProductRelationSn struct {
+	T_product_id         int
+	T_delete_relation_sn []string
+	T_add_relation_sn    []string
+}
+
+// 比较两个StockProduct列表是否相等
+func StockProductListsEqual(a, b []StockProduct) (isEqual bool, cDiff map[int]StockProductRelationSn) {
+	cDiff = make(map[int]StockProductRelationSn)
+	isEqual = true
+	// 创建一个map来存储a列表中的StockProduct
+	aMap := make(map[int]StockProduct)
+	aProductList := []int{}
+	for _, item := range a {
+		sort.Strings(item.T_relation_sn)
+		aMap[item.T_product_id] = item
+		aProductList = append(aProductList, item.T_product_id)
+	}
+	bMap := make(map[int]StockProduct)
+	bProductList := []int{}
+	for _, item := range b {
+		sort.Strings(item.T_relation_sn)
+		bMap[item.T_product_id] = item
+		bProductList = append(bProductList, item.T_product_id)
+	}
+
+	// 查找两个元素相同
+	_, common, needDelete, needAdd := IntListCompare(aProductList, bProductList)
+	fmt.Println("needDelete:", needDelete)
+	fmt.Println("needAdd:", needAdd)
+	for _, product_id := range common {
+		//_, _, aDiff[product_id], bDiff[product_id] = StringListCompare(aMap[product_id].T_relation_sn, bMap[product_id].T_relation_sn)
+		equal, _, T_delete_relation_sn, T_add_relation_sn := StringListCompare(aMap[product_id].T_relation_sn, bMap[product_id].T_relation_sn)
+		cDiff[product_id] = StockProductRelationSn{
+			T_product_id:         product_id,
+			T_delete_relation_sn: T_delete_relation_sn,
+			T_add_relation_sn:    T_add_relation_sn,
+		}
+		fmt.Println("equal:", equal)
+
+		if !equal {
+			isEqual = false
+		}
+	}
+
+	if len(needDelete) == 0 && len(needAdd) == 0 && isEqual {
+		isEqual = true
+	} else {
+		isEqual = false
+	}
+
+	return isEqual, cDiff
+}
+
+// 比较两个StockProduct是否相等
+func stockProductEqual(a, b StockProduct) bool {
+	return a.T_product_id == b.T_product_id && a.T_num == b.T_num && reflect.DeepEqual(a.T_relation_sn, b.T_relation_sn)
+}
+
+func TestStockProductListsEqual(t *testing.T) {
+	// 定义两个StockProduct列表
+	A := []StockProduct{
+		{T_product_id: 1, T_num: 10, T_relation_sn: []string{"20220101", "20230202"}},
+		{T_product_id: 2, T_num: 20, T_relation_sn: []string{"20220303", "20230404"}},
+	}
+	B := []StockProduct{
+		//{T_product_id: 1, T_num: 10, T_relation_sn: []string{"20220101", "20230202"}},
+		//{T_product_id: 2, T_num: 20, T_relation_sn: []string{"20220303", "20230404"}},
+	}
+	//B := []StockProduct{
+	//	{T_product_id: 1, T_num: 10, T_relation_sn: []string{"20220101", "202302"}},
+	//	{T_product_id: 2, T_num: 20, T_relation_sn: []string{"20230404", "20220303"}},
+	//	{T_product_id: 3, T_num: 20, T_relation_sn: []string{"20240404", "20240303"}},
+	//}
+
+	//查找两个StockProduct列表中T_relation_sn不相同的元素
+	//aDiff, bDiff := StockProductListsEqual(A, B)
+	////打印结果
+	//fmt.Println("A列表中T_relation_sn不相同的元素:", aDiff)
+	//fmt.Println("B列表中T_relation_sn不相同的元素:", bDiff)
+	isEqual, aDiff := StockProductListsEqual(A, B)
+	//打印结果
+	fmt.Println("是否相等:", isEqual)
+	fmt.Println("A列表中T_relation_sn不相同的元素:", aDiff)
+
+	//_, c, d, a := StringListCompare([]string{"20220101", "20230202"}, []string{"20230202", "20220103"})
+	//fmt.Println("共同元素:", c)
+	//fmt.Println("仅A列表中:", d)
+	//fmt.Println("仅B列表中:", a)
+
+}

+ 1 - 0
main.go

@@ -75,6 +75,7 @@ func main() {
 	go controllers.Cron_VerifyContract() // 验证合同状态修改定时任务
 	//go controllers.Cron_Device_Add()      // 重写设备表 只执行一次
 	go controllers.CheckPowerUniformity() // 检查角色是否与用户系统一致,不存在则添加
+	//go controllers.Cron_StockMonth_Add()  // 统计库存明细,测试使用
 	beego.Run()
 
 }

+ 1 - 1
models/Basic/Product.go

@@ -157,7 +157,7 @@ func Read_Product_ByT_name(T_name, T_model, T_spec string) (r Product, err error
 
 	o := orm.NewOrm()
 	qs := o.QueryTable(new(Product))
-	err = qs.Filter("T_name", T_name).Filter("T_model", T_model).Filter("T_spec", T_spec).Filter("T_class__gt", 0).One(&r)
+	err = qs.Filter("T_name", T_name).Filter("T_model", T_model).Filter("T_spec", T_spec).Filter("T_class__gt", 0).Filter("T_State", 1).One(&r)
 	if err != nil {
 		logs.Error(lib.FuncName(), err)
 		return

+ 212 - 2
models/Stock/Device.go

@@ -3,11 +3,13 @@ package Stock
 import (
 	"ERP_storage/logs"
 	"ERP_storage/models/Basic"
+	"errors"
 	"fmt"
 	"git.baozhida.cn/ERP_libs/lib"
 	_ "github.com/astaxie/beego/cache/redis"
 	"github.com/beego/beego/v2/adapter/orm"
 	orm2 "github.com/beego/beego/v2/client/orm"
+	"strconv"
 	"time"
 )
 
@@ -103,6 +105,15 @@ func (dao *DeviceDaoImpl) Add_Device(r Device) (id int64, err error) {
 // T_type 1-出库 2-入库
 func (dao *DeviceDaoImpl) AddOrUpdate_Device(r Device, T_type int) (id int64, err error) {
 
+	id, err = dao.orm.Insert(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return
+
+}
+func (dao *DeviceDaoImpl) AddOrUpdate_Device1(r Device, T_type int) (id int64, err error) {
+
 	qs := dao.orm.QueryTable(new(Device))
 	var device Device
 
@@ -159,10 +170,17 @@ func (dao *DeviceDaoImpl) AddOrUpdate_Device(r Device, T_type int) (id int64, er
 
 func (dao *DeviceDaoImpl) Read_Device_ByT_sn(T_sn string) (r Device, err error) {
 	qs := dao.orm.QueryTable(new(Device))
-	err = qs.Filter("T_sn", T_sn).One(&r)
+	var list []Device
+	_, err = qs.Limit(1, 0).Filter("T_sn", T_sn).OrderBy("-CreateTime").All(&list)
 	if err != nil {
 		logs.Error(lib.FuncName(), err)
 	}
+	if len(list) == 0 {
+		return r, orm.ErrNoRows
+	}
+	if len(list) > 0 {
+		r = list[0]
+	}
 	return
 }
 
@@ -195,7 +213,7 @@ func (dao *DeviceDaoImpl) Read_DeviceSn_List(T_contract_number string, T_product
 	return
 }
 
-func (dao *DeviceDaoImpl) Read_Device_List(T_name string, T_State, page, page_z int) (r []Device_R, cnt int64) {
+func (dao *DeviceDaoImpl) Read_Device_List1(T_name string, T_State, page, page_z int) (r []Device_R, cnt int64) {
 	qs := dao.orm.QueryTable(new(Device))
 	var offset int64
 	if page <= 1 {
@@ -237,3 +255,195 @@ func (dao *DeviceDaoImpl) Read_Device_List(T_name string, T_State, page, page_z
 
 	return
 }
+func (dao *DeviceDaoImpl) Read_Device_List(T_name string, T_State, page, page_z int) (r []Device_R, cnt int64) {
+	var offset int
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = (page - 1) * page_z
+	}
+	// 过滤
+
+	sqlWhere := " WHERE d.t__state > 0"
+	if len(T_name) > 0 {
+		sqlWhere += " AND (d.t_contract_number like \"%" + T_name + "%\" or d.t_out_number like \"%" + T_name +
+			"%\" or d.t_sn like \"%" + T_name + "%\" or d.t_iccid like \"%" + T_name + "%\" or d.t_project like \"%" + T_name + "%\")"
+	}
+	if T_State > 0 {
+		sqlWhere += fmt.Sprintf(" AND d.t__state = %d", T_State)
+	}
+	var maps_z []orm2.ParamsList
+	// 获取总条数
+	sql := "SELECT COUNT(*) FROM device d JOIN (SELECT t_sn, MAX(create_time) AS max_create_time FROM device GROUP BY t_sn) latest " +
+		"ON d.t_sn = latest.t_sn AND d.create_time = latest.max_create_time"
+	sql = sql + sqlWhere
+	fmt.Println(sql)
+	_, err := dao.orm.Raw(sql).ValuesList(&maps_z)
+	if err != nil {
+		return r, 0
+	}
+	if len(maps_z) == 0 {
+		return r, 0
+	}
+	sql = "SELECT * FROM device d JOIN (SELECT t_sn, MAX(create_time) AS max_create_time FROM device GROUP BY t_sn) latest " +
+		"ON d.t_sn = latest.t_sn AND d.create_time = latest.max_create_time"
+
+	sql = sql + sqlWhere
+
+	sql += " ORDER BY d.create_time DESC"
+
+	sql += " LIMIT " + strconv.Itoa(offset) + "," + strconv.Itoa(page_z)
+
+	fmt.Println(sql)
+	var maps []Device
+	_, err = dao.orm.Raw(sql).QueryRows(&maps)
+	if err != nil {
+		return r, 0
+	}
+	for _, v := range maps {
+		v.T_remark, v.T_project_log = dao.Read_Device_History(v.T_sn)
+		r = append(r, DeviceToDevice_R(v))
+
+	}
+	count, _ := strconv.Atoi(maps_z[0][0].(string))
+	return r, int64(count)
+}
+func (dao *DeviceDaoImpl) Read_Device_History(T_sn string) (T_remark string, T_project string) {
+	qs := dao.orm.QueryTable(new(Device))
+	var maps []Device
+	_, err := qs.Filter("T_sn", T_sn).OrderBy("CreateTime").All(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range maps {
+		if v.T_State == 1 {
+			T_remark += fmt.Sprintf("%s:%s(%s)|", v.CreateTime.Format("2006-01-02"), "出库", v.T_out_number)
+			if len(v.T_project) > 0 {
+				T_project += fmt.Sprintf("%s:%s(%s):%s|", v.CreateTime.Format("2006-01-02"), "出库", v.T_out_number, v.T_project)
+			}
+		}
+		if v.T_State == 2 {
+			T_remark += fmt.Sprintf("%s:%s(%s)|", v.CreateTime.Format("2006-01-02"), "入库", v.T_in_number)
+		}
+
+	}
+
+	return
+}
+
+func (dao *DeviceDaoImpl) Delete_Device_ByT_in_number(T_number, T_sn string) (err error) {
+	qs := dao.orm.QueryTable(new(Device))
+	var device Device
+	err = qs.Filter("T_sn", T_sn).Filter("T_in_number", T_number).One(&device)
+	if err != nil {
+		return
+	}
+
+	var count int64
+	count, err = qs.Filter("T_sn", T_sn).Filter("CreateTime__gt", device.CreateTime).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	if count > 1 {
+		return errors.New("设备已出库,无法删除")
+	}
+	_, err = dao.orm.Delete(&device)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	return err
+}
+func (dao *DeviceDaoImpl) Delete_Device_ByT_out_number(T_number, T_sn string) (err error) {
+	qs := dao.orm.QueryTable(new(Device))
+	var device Device
+	err = qs.Filter("T_sn", T_sn).Filter("T_out_number", T_number).One(&device)
+	if err != nil {
+		return
+	}
+
+	var count int64
+	count, err = qs.Filter("T_sn", T_sn).Filter("CreateTime__gt", device.CreateTime).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	if count > 1 {
+		return errors.New("设备已入库,无法删除")
+	}
+	_, err = dao.orm.Delete(&device)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	return err
+}
+
+func (dao *DeviceDaoImpl) Update_Device_ByT_out_number_T_project(T_number, T_project string) error {
+	qs := dao.orm.QueryTable(new(Device))
+	var list []Device
+	_, err := qs.Filter("T_out_number", T_number).All(&list)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	for _, deivce := range list {
+		deivce.T_project = T_project
+		_, err = dao.orm.Update(&deivce, "T_project")
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (dao *DeviceDaoImpl) Update_Device_CreateTimeByT_out_number(T_number, T_date string) error {
+	now := time.Now().Format("15:04:05")
+	date, _ := lib.TimeStrToTime(T_date + " " + now)
+	qs := dao.orm.QueryTable(new(Device))
+	var list []Device
+	_, err := qs.Filter("T_out_number", T_number).All(&list)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	for _, device := range list {
+		//device.CreateTime = date
+		//_, err = dao.orm.Update(&device, "CreateTime")
+		_, err = dao.orm.Raw("UPDATE device SET create_time = ? WHERE id = ?", date, device.Id).Exec()
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+			return err
+		}
+	}
+
+	return nil
+}
+func (dao *DeviceDaoImpl) Update_Device_CreateTimeByT_in_number(T_number, T_date string) error {
+	now := time.Now().Format("15:04:05")
+	date, _ := lib.TimeStrToTime(T_date + " " + now)
+
+	qs := dao.orm.QueryTable(new(Device))
+	var list []Device
+	_, err := qs.Filter("T_in_number", T_number).All(&list)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	for _, device := range list {
+		//device.CreateTime = date
+		//_, err = dao.orm.Update(&device, "CreateTime")
+		_, err = dao.orm.Raw("UPDATE device SET create_time = ? WHERE id = ?", date, device.Id).Exec()
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+			return err
+		}
+	}
+
+	return nil
+}

+ 27 - 2
models/Stock/Stock.go

@@ -2,6 +2,7 @@ package Stock
 
 import (
 	"ERP_storage/models/Basic"
+	"errors"
 	"fmt"
 	"git.baozhida.cn/ERP_libs/lib"
 	orm2 "github.com/beego/beego/v2/client/orm"
@@ -25,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_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 保存时都会对时间自动更新
 }
@@ -54,6 +56,7 @@ type Stock_R struct {
 	T_depot_id int // 仓库id
 	T_total    int // 库存数量
 	T_reality  int // 实际库存数量
+	T_sort     int // 排序
 
 	// ---------产品信息-----------
 	T_product_id          int
@@ -71,6 +74,7 @@ func StockToStock_R(t Stock) (r Stock_R) {
 	r.T_depot_id = t.T_depot_id
 	r.T_total = t.T_total
 	r.T_reality = t.T_reality
+	r.T_sort = t.T_sort
 
 	r.T_product_id = t.T_product_id
 	r.T_product_class = t.T_product_class
@@ -112,10 +116,13 @@ func (dao *StockDaoImpl) AddOrUpdate_Stock(T_depot_id, T_product_id, T_product_c
 			}
 			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
 		}
@@ -125,6 +132,12 @@ func (dao *StockDaoImpl) AddOrUpdate_Stock(T_depot_id, T_product_id, T_product_c
 		stock.T_total -= T_num
 		stock.T_reality -= T_num
 	}
+	if stock.T_total < 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_total += T_num
 		stock.T_reality += T_num
@@ -132,6 +145,7 @@ func (dao *StockDaoImpl) AddOrUpdate_Stock(T_depot_id, T_product_id, T_product_c
 
 	_, err = dao.orm.Update(&stock, "T_total", "T_reality")
 	if err != nil {
+		err = errors.New(fmt.Sprintf("修改库存失败", T_product_name, T_product_model))
 		logs.Error(lib.FuncName(), err)
 		return
 	}
@@ -159,6 +173,17 @@ func (dao *StockDaoImpl) Read_Stock_List_ByT_product_id(T_product_id int) (r []S
 	return
 }
 
+// 获取 ById
+func (dao *StockDaoImpl) Read_Stock_ById(Id int) (r Stock, err error) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(Stock))
+	err = qs.Filter("Id", Id).One(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return
+}
+
 // 修改
 func (dao *StockDaoImpl) Update_Stock(m Stock, cols ...string) error {
 	_, err := dao.orm.Update(&m, cols...)
@@ -202,9 +227,9 @@ func (dao *StockDaoImpl) Read_Stock_List(T_depot_id, T_product_class int, T_prod
 	var r []Stock
 	var err error
 	if page_z == 9999 {
-		_, err = qs.SetCond((*orm2.Condition)(cond)).OrderBy("-Id").All(&r)
+		_, err = qs.SetCond((*orm2.Condition)(cond)).OrderBy("T_sort").All(&r)
 	} else {
-		_, err = qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond)).OrderBy("-Id").All(&r)
+		_, err = qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond)).OrderBy("T_sort").All(&r)
 	}
 
 	if err != nil {

+ 15 - 0
models/Stock/StockIn.go

@@ -19,6 +19,7 @@ import (
 type StockIn struct {
 	Id         int       `orm:"column(ID);size(11);auto;pk"`
 	T_number   string    `orm:"size(256);null"`                                        // 入库单号
+	T_type     int       `orm:"size(256);;default(1)"`                                 // 入库类型 1-入库 2-退库
 	T_depot_id int       `orm:"size(20);null"`                                         // 仓库id
 	T_date     string    `orm:"size(256);null"`                                        // 业务日期
 	T_submit   string    `orm:"size(256);null"`                                        // 经办人
@@ -47,6 +48,7 @@ func init() {
 type StockIn_R struct {
 	Id            int
 	T_number      string
+	T_type        int
 	T_depot_id    int
 	T_depot_name  string
 	T_date        string
@@ -58,6 +60,7 @@ type StockIn_R struct {
 type StockIn_Detail struct {
 	Id            int
 	T_number      string
+	T_type        int
 	T_depot_id    int
 	T_depot_name  string
 	T_date        string
@@ -70,6 +73,7 @@ type StockIn_Detail struct {
 func StockInToStockIn_R(t StockIn) (r StockIn_R) {
 	r.Id = t.Id
 	r.T_number = t.T_number
+	r.T_type = t.T_type
 	r.T_depot_id = t.T_depot_id
 	r.T_depot_name = Basic.Read_Depot_Get(t.T_depot_id)
 	r.T_date = t.T_date
@@ -82,6 +86,7 @@ func StockInToStockIn_R(t StockIn) (r StockIn_R) {
 func StockInToStockIn_Detail(t StockIn, productList []StockInProduct_R) (r StockIn_Detail) {
 	r.Id = t.Id
 	r.T_number = t.T_number
+	r.T_type = t.T_type
 	r.T_depot_id = t.T_depot_id
 	r.T_depot_name = Basic.Read_Depot_Get(t.T_depot_id)
 	r.T_date = t.T_date
@@ -122,6 +127,16 @@ func (dao *StockInDaoImpl) Update_StockIn(m StockIn, cols ...string) error {
 	return nil
 }
 
+// 删除
+func (dao *StockInDaoImpl) Delete_StockIn(m StockIn) error {
+	_, err := dao.orm.Delete(&m)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	return nil
+}
+
 // 获取列表
 func (dao *StockInDaoImpl) Read_StockIn_List(T_depot_id int, T_start_date, T_end_date string, page, page_z int) (r_ []StockIn_R, cnt int64) {
 	qs := dao.orm.QueryTable(new(StockIn))

+ 53 - 2
models/Stock/StockInProduct.go

@@ -154,8 +154,59 @@ func (dao *StockInProductDaoImpl) Read_StockInProduct_List_ByT_number(T_number s
 }
 
 // 修改
-func (dao *StockInProductDaoImpl) Update_StockInProduct(m StockInProduct, cols ...string) error {
-	_, err := dao.orm.Update(&m, cols...)
+func (dao *StockInProductDaoImpl) Update_StockInProduct(r StockInProduct) error {
+	qs := dao.orm.QueryTable(new(StockInProduct))
+	var product StockInProduct
+	err := qs.Filter("T_number", r.T_number).Filter("T_product_id", r.T_product_id).One(&product)
+	if err != nil {
+		if err.Error() == orm.ErrNoRows.Error() {
+			_, err = dao.orm.Insert(&product)
+			if err != nil {
+				logs.Error(lib.FuncName(), err)
+				return err
+			} else {
+				return nil
+			}
+		}
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	product.T_depot_id = r.T_depot_id
+	product.T_num = r.T_num
+	product.T_relation_sn = r.T_relation_sn
+
+	_, err = dao.orm.Update(&product, "T_depot_id", "T_num", "T_relation_sn")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	return nil
+}
+
+func (dao *StockInProductDaoImpl) Update_StockInProduct_T_date(T_number, T_date string) error {
+	qs := dao.orm.QueryTable(new(StockInProduct))
+	var list []StockInProduct
+	_, err := qs.Filter("T_number", T_number).All(&list)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	for _, product := range list {
+		product.T_date = T_date
+		_, err = dao.orm.Update(&product, "T_date")
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+			return err
+		}
+	}
+
+	return nil
+}
+
+// 删除
+func (dao *StockInProductDaoImpl) Delete_StockInProduct(T_number string, T_depot_id, T_product_id int) error {
+	qs := dao.orm.QueryTable(new(StockInProduct))
+	_, err := qs.Filter("T_number", T_number).Filter("T_depot_id", T_depot_id).Filter("T_product_id", T_product_id).Delete()
 	if err != nil {
 		logs.Error(lib.FuncName(), err)
 		return err

+ 15 - 3
models/Stock/StockMonth.go

@@ -92,8 +92,8 @@ func (dao *StockMonthDaoImpl) Add_StockMonth(r StockMonth) (id int64, err error)
 	return id, err
 }
 
-// 获取 ById
-func (dao *StockMonthDaoImpl) Read_StockMonth_ByT_depot_id_T_product_id(T_depot_id, T_product_id int, T_month string) (r []StockMonth) {
+// 获取 上月数据
+func (dao *StockMonthDaoImpl) Read_LastMonth_StockMonth_ByT_depot_id_T_product_id(T_depot_id, T_product_id int, T_month string) (r []StockMonth) {
 	qs := dao.orm.QueryTable(new(StockMonth))
 	var maps []StockMonth
 	_, err := qs.Limit(1, 0).Filter("T_depot_id", T_depot_id).Filter("T_product_id", T_product_id).
@@ -104,6 +104,18 @@ func (dao *StockMonthDaoImpl) Read_StockMonth_ByT_depot_id_T_product_id(T_depot_
 	return maps
 }
 
+// 获取本月数据
+func (dao *StockMonthDaoImpl) Read_StockMonth_ByT_depot_id_T_product_id(T_depot_id, T_product_id int, T_month string) (r StockMonth) {
+	qs := dao.orm.QueryTable(new(StockMonth))
+	var maps StockMonth
+	err := qs.Filter("T_depot_id", T_depot_id).Filter("T_product_id", T_product_id).
+		Filter("T_month", T_month).OrderBy("-T_month").One(&maps)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return maps
+}
+
 // 获取列表
 func (dao *StockMonthDaoImpl) Read_StockMonth_List(T_depot_id, T_product_id, T_product_class int, start_date, end_date string) (r_ []StockMonth_R) {
 	qs := dao.orm.QueryTable(new(StockMonth))
@@ -133,7 +145,7 @@ func (dao *StockMonthDaoImpl) Read_StockMonth_List(T_depot_id, T_product_id, T_p
 
 	// 查询
 	var r []StockMonth
-	_, err := qs.SetCond((*orm2.Condition)(cond)).OrderBy("T_product_id").All(&r)
+	_, err := qs.SetCond((*orm2.Condition)(cond)).OrderBy("T_product_id").OrderBy("T_month").All(&r)
 
 	if err != nil {
 		logs.Error(lib.FuncName(), err)

+ 35 - 2
models/Stock/StockOut.go

@@ -79,9 +79,9 @@ type StockOut_Detail struct {
 	T_type            int    // 出库类型 1-领料出库 2-销售出库
 	T_date            string // 业务日期
 	T_receive         string // 领取人
-	T_receive_name    string // 领取人
+	T_receive_name    string // 领取人名称
 	T_submit          string // 经办人
-	T_submit_name     string // 经办人
+	T_submit_name     string // 经办人名称
 	T_project         string // 关联项目
 	T_remark          string // 备注
 	// ----销售出库------
@@ -159,6 +159,16 @@ func (dao *StockOutDaoImpl) Update_StockOut(m StockOut, cols ...string) error {
 	return nil
 }
 
+// 删除
+func (dao *StockOutDaoImpl) Delete_StockOut(m StockOut) error {
+	_, err := dao.orm.Delete(&m)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	return nil
+}
+
 // 获取列表
 func (dao *StockOutDaoImpl) Read_StockOut_List(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))
@@ -228,6 +238,29 @@ func (dao *StockOutDaoImpl) Read_StockOut_T_contract_number(T_depot_id, T_produc
 	return strings.Join(r, ",")
 
 }
+func (dao *StockOutDaoImpl) Read_StockOut_T_project(T_depot_id, T_product_id int, T_date string) []string {
+	sql := "SELECT DISTINCT(t_project) FROM stock_out WHERE t_number in (SELECT t_number 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 + "%')"
+
+	var pl_lists orm2.ParamsList
+	_, err := dao.orm.Raw(sql).ValuesFlat(&pl_lists)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return []string{}
+	}
+
+	var r []string
+	var j = 1
+	for _, v := range pl_lists {
+		if v == nil || len(v.(string)) == 0 {
+			continue
+		}
+		r = append(r, fmt.Sprintf("%d、%s", j, strings.Trim(v.(string), "\r\n")))
+		j += 1
+	}
+
+	return r
+
+}
 
 // 通过入库编号查询入库产品列表
 func (dao *StockOutDaoImpl) Read_StockOutProduct_List(T_name, T_start_date, T_end_date string, T_depot_id int, page int, page_z int) (

+ 52 - 2
models/Stock/StockOutProduct.go

@@ -158,8 +158,58 @@ func (dao *StockOutProductDaoImpl) Read_StockOutProduct_List(T_number string) (r
 }
 
 // 修改
-func (dao *StockOutProductDaoImpl) Update_StockOutProduct(m StockOutProduct, cols ...string) error {
-	_, err := dao.orm.Update(&m, cols...)
+func (dao *StockOutProductDaoImpl) Update_StockOutProduct(r StockOutProduct) error {
+	qs := dao.orm.QueryTable(new(StockOutProduct))
+	var product StockOutProduct
+	err := qs.Filter("T_number", r.T_number).Filter("T_product_id", r.T_product_id).One(&product)
+	if err != nil {
+		if err.Error() == orm.ErrNoRows.Error() {
+			_, err = dao.orm.Insert(&product)
+			if err != nil {
+				logs.Error(lib.FuncName(), err)
+				return err
+			} else {
+				return nil
+			}
+		}
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	product.T_depot_id = r.T_depot_id
+	product.T_num = r.T_num
+	product.T_relation_sn = r.T_relation_sn
+
+	_, err = dao.orm.Update(&product, "T_depot_id", "T_num", "T_relation_sn")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	return nil
+}
+func (dao *StockOutProductDaoImpl) Update_StockOutProduct_T_date(T_number, T_date string) error {
+	qs := dao.orm.QueryTable(new(StockOutProduct))
+	var list []StockOutProduct
+	_, err := qs.Filter("T_number", T_number).All(&list)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	for _, product := range list {
+		product.T_date = T_date
+		_, err = dao.orm.Update(&product, "T_date")
+		if err != nil {
+			logs.Error(lib.FuncName(), err)
+			return err
+		}
+	}
+
+	return nil
+}
+
+// 删除
+func (dao *StockOutProductDaoImpl) Delete_StockOutProduct(T_number string, T_depot_id, T_product_id int) error {
+	qs := dao.orm.QueryTable(new(StockOutProduct))
+	_, err := qs.Filter("T_number", T_number).Filter("T_depot_id", T_depot_id).Filter("T_product_id", T_product_id).Delete()
 	if err != nil {
 		logs.Error(lib.FuncName(), err)
 		return err

+ 13 - 5
routers/Stock.go

@@ -13,6 +13,7 @@ func init() {
 	)
 	stock := beego.NewNamespace("/Stock",
 		beego.NSRouter("/List", &controllers.StockController{}, "*:Stock_List"),                 // 库存列表
+		beego.NSRouter("/Edit_Sort", &controllers.StockController{}, "*:Stock_Edit_Sort"),       // 修改排序
 		beego.NSRouter("/Detail_List", &controllers.StockController{}, "*:Stock_Detail_List"),   // 库存明细列表
 		beego.NSRouter("/Detail_Excel", &controllers.StockController{}, "*:Stock_Detail_Excel"), // 导出库存明细列表
 	)
@@ -21,13 +22,20 @@ func init() {
 		beego.NSRouter("/List_Product", &controllers.StockController{}, "*:StockIn_List_Product"), // 入库列表 - 带产品明细
 		beego.NSRouter("/Get", &controllers.StockController{}, "*:StockIn_Get"),                   // 入库详情
 		beego.NSRouter("/Add", &controllers.StockController{}, "*:StockIn_Add"),                   // 入库
+		beego.NSRouter("/Edit", &controllers.StockController{}, "*:StockIn_Edit"),                 // 修改入库
+		beego.NSRouter("/Del", &controllers.StockController{}, "*:StockIn_Del"),                   // 删除入库
+		beego.NSRouter("/Excel", &controllers.StockController{}, "*:StockIn_Excel"),               // 导出入库
+
 	)
 	stockOut := beego.NewNamespace("/StockOut",
-		beego.NSRouter("/List", &controllers.StockController{}, "*:StockOut_List"),                 // 出库列表
-		beego.NSRouter("/List_Product", &controllers.StockController{}, "*:StockOut_List_Product"), // 出库列表 - 带产品明细
-		beego.NSRouter("/Get", &controllers.StockController{}, "*:StockOut_Get"),                   // 出库详情
-		beego.NSRouter("/Add", &controllers.StockController{}, "*:StockOut_Add"),                   // 出库
-		beego.NSRouter("/Edit", &controllers.StockController{}, "*:StockOut_Edit"),                 // 修改发货单
+		beego.NSRouter("/List", &controllers.StockController{}, "*:StockOut_List"),                   // 出库列表
+		beego.NSRouter("/List_Product", &controllers.StockController{}, "*:StockOut_List_Product"),   // 出库列表 - 带产品明细
+		beego.NSRouter("/Get", &controllers.StockController{}, "*:StockOut_Get"),                     // 出库详情
+		beego.NSRouter("/Add", &controllers.StockController{}, "*:StockOut_Add"),                     // 出库
+		beego.NSRouter("/Edit_Delivery", &controllers.StockController{}, "*:StockOut_Edit_Delivery"), // 修改发货单
+		beego.NSRouter("/Edit", &controllers.StockController{}, "*:StockOut_Edit"),                   // 修改出库
+		beego.NSRouter("/Del", &controllers.StockController{}, "*:StockOut_Del"),                     // 删除出库
+		beego.NSRouter("/Excel", &controllers.StockController{}, "*:StockOut_Excel"),                 // 导出出库
 	)
 	beego.AddNamespace(device, stock, stockIn, stockOut)
 }

+ 3 - 3
services/ContractReview.go

@@ -327,9 +327,9 @@ func (e *ContractReview) Delete(c *dto.ContractReviewDeleteReq) error {
 		logs.Error("db error: %s", err)
 		return dto.GetFailedErr
 	}
-	if contractReview.T_audit == 3 || contractReview.T_audit == 5 {
-		return errors.New("审核通过后不可删除")
-	}
+	//if contractReview.T_audit == 3 || contractReview.T_audit == 5 {
+	//	return errors.New("审核通过后不可删除")
+	//}
 	contractReview.T_State = 0
 	err = db.DB.Save(&contractReview).Error
 	if err != nil {

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio