2024-02-20 09:59:43 +00:00
|
|
|
|
package models
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
2024-02-26 10:18:23 +00:00
|
|
|
|
"github.com/xuri/excelize/v2"
|
2024-02-20 09:59:43 +00:00
|
|
|
|
orm "go-admin/common/global"
|
|
|
|
|
"go-admin/logger"
|
2024-02-26 10:18:23 +00:00
|
|
|
|
"go-admin/tools/config"
|
2024-02-20 09:59:43 +00:00
|
|
|
|
"gorm.io/gorm"
|
2024-03-27 10:01:38 +00:00
|
|
|
|
"math"
|
2024-02-20 09:59:43 +00:00
|
|
|
|
"math/rand"
|
2024-03-06 02:07:55 +00:00
|
|
|
|
"sort"
|
|
|
|
|
"strconv"
|
2024-02-26 10:18:23 +00:00
|
|
|
|
"strings"
|
2024-02-23 10:06:21 +00:00
|
|
|
|
"sync"
|
2024-02-20 09:59:43 +00:00
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
ErpPurchaseOrderUnAudit = 1 // 待审核
|
|
|
|
|
ErpPurchaseOrderWaitInventory = 2 // 待入库
|
|
|
|
|
ErpPurchaseOrderWaitReject = 3 // 待退货
|
|
|
|
|
ErpPurchaseOrderFinished = 4 // 已完成
|
|
|
|
|
ErpPurchaseOrderEnd = 5 // 已终止
|
|
|
|
|
|
|
|
|
|
ErpProcureOrder = "procure" // 采购入库订单
|
|
|
|
|
ErpRejectOrder = "reject" // 采购退货订单
|
2024-02-23 10:06:21 +00:00
|
|
|
|
|
|
|
|
|
ErpDemandStateWait = 1 // 待采购
|
|
|
|
|
ErpDemandStateFinish = 2 // 完成采购
|
2024-02-20 09:59:43 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseOrder 采购订单表
|
|
|
|
|
type ErpPurchaseOrder struct {
|
|
|
|
|
Model
|
2024-03-18 11:53:42 +00:00
|
|
|
|
SerialNumber string `json:"serial_number" gorm:"index"` // 单据编号
|
|
|
|
|
PurchaseType string `json:"purchase_type"` // 类型:procure-采购 reject-退货
|
|
|
|
|
StoreId uint32 `json:"store_id" gorm:"index"` // 门店id
|
|
|
|
|
StoreName string `json:"store_name"` // 门店名称
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"` // 供应商id
|
|
|
|
|
ErpSupplierName string `json:"erp_supplier_name"` // 供应商名称
|
|
|
|
|
HandlerId uint32 `json:"handler_id" gorm:"index"` // 经手人id
|
|
|
|
|
HandlerName string `json:"handler_name"` // 经手人名称
|
|
|
|
|
MakerTime *time.Time `json:"maker_time"` // 制单时间
|
|
|
|
|
MakerId uint32 `json:"maker_id" gorm:"index"` // 制单人id
|
|
|
|
|
MakerName string `json:"maker_name"` // 制单人名称
|
|
|
|
|
AuditTime *time.Time `json:"audit_time"` // 审核时间
|
|
|
|
|
AuditorId uint32 `json:"auditor_id" gorm:"index"` // 审核人id
|
|
|
|
|
AuditorName string `json:"auditor_name"` // 审核人名称
|
2024-03-27 10:01:38 +00:00
|
|
|
|
State uint32 `json:"state"` // 1-待审核 2-待入库 3-待退货 4-已完成 5-已终止
|
2024-03-18 11:53:42 +00:00
|
|
|
|
RejectedSerialNumber string `json:"rejected_serial_number"` // 退货的采购订单单据编号
|
|
|
|
|
ErpCashierId uint32 `json:"erp_cashier_id"` // 付款方式/收款方式id
|
|
|
|
|
ErpCashierName string `json:"erp_cashier_name"` // 付款方式/收款方式名称
|
|
|
|
|
AccountHolder string `json:"account_holder"` // 收款人
|
|
|
|
|
OpeningBank string `json:"opening_bank"` // 开户行
|
|
|
|
|
BankAccount string `json:"bank_account"` // 银行卡号
|
|
|
|
|
DeliveryTime string `json:"delivery_time"` // 交货日期,如:2024-02-23
|
|
|
|
|
DeliveryAddress string `json:"delivery_address"` // 交货地址
|
|
|
|
|
Remark string `json:"remark"` // 备注
|
|
|
|
|
Commodities []ErpPurchaseCommodity `json:"commodities" gorm:"-"` //
|
|
|
|
|
InventoryId uint32 `json:"inventory_id" gorm:"-"` // 最近入库人id
|
|
|
|
|
InventoryName string `json:"inventory_name" gorm:"-"` // 最近入库人名称
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseCommodity 采购订单商品表
|
|
|
|
|
type ErpPurchaseCommodity struct {
|
|
|
|
|
Model
|
2024-02-23 10:06:21 +00:00
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" gorm:"index"` // 采购订单id
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编号
|
|
|
|
|
IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码
|
|
|
|
|
IMEI string `json:"imei"` // 商品串码
|
|
|
|
|
RetailPrice uint32 `json:"retail_price"` // 指导零售价
|
|
|
|
|
Count uint32 `json:"count"` // 计划采购数量
|
|
|
|
|
Price float64 `json:"price"` // 计划采购单价
|
|
|
|
|
Amount float64 `json:"amount"` // 计划采购金额
|
|
|
|
|
Remark string `json:"remark"` // 备注
|
|
|
|
|
RejectedPrice float64 `json:"rejected_price"` // 计划退货单价
|
|
|
|
|
RejectedCount uint32 `json:"rejected_count"` // 计划退货数量
|
|
|
|
|
RejectedAmount float64 `json:"rejected_amount"` // 计划退货金额
|
|
|
|
|
InventoryCount int32 `json:"inventory_count"` // 入库数量(=执行数量)
|
|
|
|
|
ExecutionCount uint32 `json:"execute_count" gorm:"-"` // 执行数量
|
|
|
|
|
ExecutionPrice float64 `json:"execute_price" gorm:"-"` // 平均采购单价
|
|
|
|
|
ExecutionEmployeePrice float64 `json:"execute_employee_price" gorm:"-"` // 平均员工成本价
|
|
|
|
|
ExecutionAmount float64 `json:"execute_amount" gorm:"-"` // 执行金额
|
2024-03-16 08:19:12 +00:00
|
|
|
|
DefaultEmployeePrice float64 `json:"default_employee_price" gorm:"-"` // 默认员工成本价
|
2024-03-27 10:01:38 +00:00
|
|
|
|
EffectiveCount uint32 `json:"effective_count" gorm:"-"` // 有效数量(该商品实际库存详情处剩余有效数,不包含已出库的数量)
|
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id" gorm:"-"` // 商品分类id
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name" gorm:"-"` // 商品分类名称
|
2024-02-23 10:06:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseInventory 采购入库执行信息
|
2024-02-20 09:59:43 +00:00
|
|
|
|
type ErpPurchaseInventory struct {
|
|
|
|
|
Model
|
2024-02-23 10:06:21 +00:00
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" gorm:"index"` // 商品采购订单id
|
|
|
|
|
ErpPurchaseCommodityId uint32 `json:"erp_purchase_commodity_id" gorm:"index"` // 采购订单商品表id
|
|
|
|
|
PurchaseType string `json:"purchase_type" binding:"required"` // 采购类型:procure-采购 reject-退货
|
|
|
|
|
SerialNumber string `json:"serial_number" gorm:"index"` // 入库编号
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编号
|
2024-03-06 02:07:55 +00:00
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id" gorm:"index"` // 商品分类id
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"` // 商品分类名称
|
2024-03-27 10:01:38 +00:00
|
|
|
|
IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加)
|
2024-02-23 10:06:21 +00:00
|
|
|
|
IMEI string `json:"imei"` // 商品串码
|
|
|
|
|
Count uint32 `json:"count"` // 执行数量
|
|
|
|
|
ImplementationPrice float64 `json:"implementation_price"` // 执行单价
|
|
|
|
|
Amount float64 `json:"amount"` // 执行金额
|
|
|
|
|
EmployeePrice float64 `json:"employee_price"` // 员工成本价
|
2024-03-18 11:53:42 +00:00
|
|
|
|
InventoryId uint32 `json:"inventory_id"` // 最近入库人id
|
|
|
|
|
InventoryName string `json:"inventory_name"` // 最近入库人名称
|
2024-03-27 10:01:38 +00:00
|
|
|
|
ErpStockCommodityID uint32 `json:"erp_stock_commodity_id"` // 库存商品表主键id
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// ErpPurchaseCreateReq 新建采购订单入参
|
2024-02-20 09:59:43 +00:00
|
|
|
|
type ErpPurchaseCreateReq struct {
|
2024-03-06 02:07:55 +00:00
|
|
|
|
PurchaseType string `json:"purchase_type" binding:"required"` // 采购类型:procure-采购 reject-退货
|
2024-03-16 08:19:12 +00:00
|
|
|
|
PurchaseOrderSn string `json:"purchase_order_sn"` // 采购退货订单号:出库必传
|
|
|
|
|
StoreId uint32 `json:"store_id"` // 门店id:入库必传
|
|
|
|
|
DeliveryAddress string `json:"delivery_address"` // 交货地址:入库必传
|
|
|
|
|
HandlerId uint32 `json:"handler_id" binding:"required"` // 经手人id
|
2024-03-06 02:07:55 +00:00
|
|
|
|
HandlerName string `json:"handler_name"` // 经手人名称
|
2024-03-16 08:19:12 +00:00
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id:入库必传
|
|
|
|
|
ErpCashierId uint32 `json:"erp_cashier_id" binding:"required"` // 付款方式
|
|
|
|
|
AccountHolder string `json:"account_holder"` // 收款人:入库必传
|
|
|
|
|
OpeningBank string `json:"opening_bank"` // 开户行:入库必传
|
|
|
|
|
BankAccount string `json:"bank_account" ` // 银行卡号:入库必传
|
|
|
|
|
DeliveryTime string `json:"delivery_time" ` // 交货日期:入库必传
|
2024-03-06 02:07:55 +00:00
|
|
|
|
Remark string `json:"remark"` // 备注
|
|
|
|
|
ErpPurchaseCommodities []ErpPurchaseCommodity `json:"erp_purchase_commodity" binding:"required"` // 采购商品信息
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// ErpPurchaseEditReq 编辑采购订单入参
|
2024-02-20 09:59:43 +00:00
|
|
|
|
type ErpPurchaseEditReq struct {
|
2024-03-06 02:07:55 +00:00
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" binding:"required"` // 采购订单id
|
|
|
|
|
PurchaseType string `json:"purchase_type" binding:"required"` // 采购类型:procure-采购 reject-退货
|
2024-03-16 08:19:12 +00:00
|
|
|
|
PurchaseOrderSn string `json:"purchase_order_sn"` // 采购退货订单号:出库必传
|
|
|
|
|
StoreId uint32 `json:"store_id"` // 门店id:入库必传
|
|
|
|
|
DeliveryAddress string `json:"delivery_address"` // 交货地址:入库必传
|
|
|
|
|
HandlerId uint32 `json:"handler_id" binding:"required"` // 经手人id
|
2024-03-06 02:07:55 +00:00
|
|
|
|
HandlerName string `json:"handler_name"` // 经手人名称
|
2024-03-16 08:19:12 +00:00
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id:入库必传
|
2024-03-06 02:07:55 +00:00
|
|
|
|
ErpCashierId uint32 `json:"erp_cashier_id" binding:"required"` // 付款方式
|
2024-03-16 08:19:12 +00:00
|
|
|
|
AccountHolder string `json:"account_holder"` // 收款人:入库必传
|
|
|
|
|
OpeningBank string `json:"opening_bank"` // 开户行:入库必传
|
|
|
|
|
BankAccount string `json:"bank_account" ` // 银行卡号:入库必传
|
|
|
|
|
DeliveryTime string `json:"delivery_time"` // 交货日期:入库必传
|
2024-03-06 02:07:55 +00:00
|
|
|
|
Remark string `json:"remark"` // 备注
|
|
|
|
|
ErpPurchaseCommodities []ErpPurchaseCommodity `json:"erp_purchase_commodity" binding:"required"` // 采购商品信息
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// ErpPurchaseOrderListReq 查询采购订单列表入参
|
2024-02-20 09:59:43 +00:00
|
|
|
|
type ErpPurchaseOrderListReq struct {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
SerialNumber string `json:"serial_number"` // 单据编号
|
|
|
|
|
PurchaseType string `json:"purchase_type"` // 采购类型:procure-采购 reject-退货
|
|
|
|
|
StoreId uint32 `json:"store_id"` // 门店id
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id
|
|
|
|
|
AuditTimeStart string `json:"audit_time_start"` // 审核开始时间
|
|
|
|
|
AuditTimeEnd string `json:"audit_time_end"` // 审核结束时间
|
|
|
|
|
AuditFlag string `json:"audit_flag"` // 审核标记(默认展示所有):ON-订单只展示已审核的采购入库订单,含待入库/已终止/已完成/入库中
|
|
|
|
|
State []uint32 `json:"state"` // 状态:1-待审核 2-待入库 3-待退货 4-已完成 5-已终止
|
|
|
|
|
HandlerId uint32 `json:"handler_id"` // 经手人id
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// ErpPurchaseOrderListResp 查询采购订单列表出参
|
2024-02-20 09:59:43 +00:00
|
|
|
|
type ErpPurchaseOrderListResp struct {
|
|
|
|
|
List []ErpPurchaseOrder `json:"list"`
|
|
|
|
|
Total int `json:"total"` // 总条数
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// ErpPurchaseDetailReq 查询采购订单详情入参
|
2024-02-20 09:59:43 +00:00
|
|
|
|
type ErpPurchaseDetailReq struct {
|
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" binding:"required"` // 采购订单id
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
// ErpPurchaseInventoryReq 入库(退货)入参
|
2024-02-20 09:59:43 +00:00
|
|
|
|
type ErpPurchaseInventoryReq struct {
|
2024-03-18 11:53:42 +00:00
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" binding:"required"` // 采购订单id
|
|
|
|
|
PurchaseType string `json:"purchase_type" binding:"required"` // 采购类型:procure-采购 reject-退货
|
2024-03-27 10:01:38 +00:00
|
|
|
|
InventoryId uint32 `json:"inventory_id"` // 最近入库人id
|
|
|
|
|
InventoryName string `json:"inventory_name"` // 最近入库人名称
|
2024-03-18 11:53:42 +00:00
|
|
|
|
Inventories []ErpPurchaseInventory `json:"inventories" binding:"required"` // 采购入库执行信息
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseExecuteReq 执行(入库/退货)入参
|
|
|
|
|
type ErpPurchaseExecuteReq struct {
|
2024-02-20 09:59:43 +00:00
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" binding:"required"` // 采购订单id
|
2024-02-23 10:06:21 +00:00
|
|
|
|
PurchaseType string `json:"purchase_type" binding:"required"` // 采购类型:procure-采购 reject-退货
|
2024-02-20 09:59:43 +00:00
|
|
|
|
Inventories []ErpPurchaseInventory `json:"inventories" binding:"required"` // 采购入库执行信息
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseAuditReq 审核采购订单入参
|
|
|
|
|
type ErpPurchaseAuditReq struct {
|
|
|
|
|
SerialNumber string `json:"serial_number" binding:"required"` // 单据编号
|
|
|
|
|
State int `json:"state" binding:"required"` // 审核操作: 1-审核 2-取消审核
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseTerminateReq 终止采购入参
|
|
|
|
|
type ErpPurchaseTerminateReq struct {
|
|
|
|
|
SerialNumber string `json:"serial_number" binding:"required"` // 单据编号
|
2024-02-26 10:18:23 +00:00
|
|
|
|
Remark string `json:"remark" binding:"required"` // 备注
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-16 08:19:12 +00:00
|
|
|
|
// ErpPurchaseDeleteReq 删除采购单入参
|
|
|
|
|
type ErpPurchaseDeleteReq struct {
|
|
|
|
|
SerialNumber string `json:"serial_number" binding:"required"` // 单据编号
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 09:59:43 +00:00
|
|
|
|
// ErpPurchaseExecuteResp 执行(入库/退货)出参
|
|
|
|
|
type ErpPurchaseExecuteResp struct {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
List []ExecuteData `json:"list"`
|
|
|
|
|
Total int `json:"total"` // 总条数
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// ExecuteData 库存执行数据
|
2024-02-20 09:59:43 +00:00
|
|
|
|
type ExecuteData struct {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" gorm:"index"` // 商品采购订单id
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编号
|
|
|
|
|
IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码
|
|
|
|
|
IMEI string `json:"imei"` // 商品串码
|
|
|
|
|
Count uint32 `json:"count"` // 数量
|
|
|
|
|
ImplementationPrice float64 `json:"implementation_price"` // 执行单价
|
|
|
|
|
EmployeePrice float64 `json:"employee_price"` // 员工成本价
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// ErpPurchaseDemand 采购需求表
|
2024-02-23 10:06:21 +00:00
|
|
|
|
type ErpPurchaseDemand struct {
|
|
|
|
|
Model
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id
|
|
|
|
|
ErpCommoditySerialNumber string `json:"erp_commodity_serial_number"` // 商品编号
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name" gorm:"index"` // 商品名称
|
|
|
|
|
StoreId uint32 `json:"store_id"` // 门店id
|
|
|
|
|
StoreName string `json:"store_name"` // 门店名称
|
|
|
|
|
Count uint32 `json:"count"` // 需采购数量
|
|
|
|
|
State uint32 `json:"state"` // 1-待采购 2-已采购
|
|
|
|
|
MakerId uint32 `json:"maker_id"` // 制单人id
|
|
|
|
|
FinishTime *time.Time `json:"finish_time"` // 完成采购时间
|
2024-03-27 10:01:38 +00:00
|
|
|
|
//PurchaserId uint32 `json:"purchaser_id"` // 采购人id
|
|
|
|
|
//Remark string `json:"remark"` // 备注
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseDemandRemark 采购需求备注表
|
|
|
|
|
type ErpPurchaseDemandRemark struct {
|
|
|
|
|
Model
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id
|
|
|
|
|
State uint32 `json:"state"` // 1-待采购 2-已采购
|
|
|
|
|
MakerId uint32 `json:"maker_id"` // 制单人id
|
|
|
|
|
FinishTime *time.Time `json:"finish_time"` // 完成采购时间
|
|
|
|
|
Remark string `json:"remark"` // 备注
|
2024-02-23 10:06:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// GetErpPurchaseDemandReq 获取采购需求入参
|
2024-02-23 10:06:21 +00:00
|
|
|
|
type GetErpPurchaseDemandReq struct {
|
2024-02-26 10:18:23 +00:00
|
|
|
|
ErpCategoryId uint32 `json:"erp_category_id"` // 商品分类id
|
|
|
|
|
ErpCommoditySerialNumber string `json:"erp_commodity_serial_number"` // 商品编号
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
HideFlag string `json:"hide_flag"` // 隐藏标记(默认关闭):ON-开启,隐藏无采购需求的商品,OFF-关闭,展示所有
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 每页展示数据条数
|
|
|
|
|
IsExport uint32 `json:"is_export"` // 1-导出
|
2024-02-23 10:06:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// DemandData 采购需求数据
|
2024-02-23 10:06:21 +00:00
|
|
|
|
type DemandData struct {
|
|
|
|
|
ErpCommodityID uint32 `json:"erp_commodity_id"` // 商品id
|
|
|
|
|
ErpCommoditySerialNumber string `json:"erp_commodity_serial_number"` // 商品编号
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"` // 商品分类名称
|
|
|
|
|
RetailPrice uint32 `json:"retail_price"` // 指导零售价
|
|
|
|
|
LastWholesalePrice float64 `json:"last_wholesale_price"` // 最近采购价
|
|
|
|
|
TotalCount uint32 `json:"total_count"` // 需采购总数量
|
|
|
|
|
TotalAmount float64 `json:"total_amount"` // 需采购总金额
|
2024-02-26 10:18:23 +00:00
|
|
|
|
Remark string `json:"remark"` // 备注
|
2024-02-23 10:06:21 +00:00
|
|
|
|
StoreList []struct {
|
|
|
|
|
StoreID uint32 `json:"store_id"` // 门店id
|
|
|
|
|
StoreName string `json:"store_name"` // 门店名称
|
|
|
|
|
LastMonthSales uint32 `json:"last_month_sales"` // 上月销售数
|
|
|
|
|
StockCount uint32 `json:"stock_count"` // 库存数量
|
|
|
|
|
NeedCount uint32 `json:"need_count"` // 需采购数
|
|
|
|
|
} `json:"store_list"`
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// GetErpPurchaseDemandResp 获取采购需求出参
|
2024-02-23 10:06:21 +00:00
|
|
|
|
type GetErpPurchaseDemandResp struct {
|
|
|
|
|
List []DemandData `json:"list"`
|
|
|
|
|
Total int64 `json:"total"` // 数据总条数
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 每页展示条数
|
|
|
|
|
ExportUrl string `json:"export_url"` // 文件路径
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// CreateErpPurchaseDemandReq 创建采购需求入参
|
2024-02-23 10:06:21 +00:00
|
|
|
|
type CreateErpPurchaseDemandReq struct {
|
|
|
|
|
ErpCommodityID uint32 `json:"erp_commodity_id"` // 商品id
|
|
|
|
|
ErpCommoditySerialNumber string `json:"erp_commodity_serial_number"` // 商品编号
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
Remark string `json:"remark"` // 备注
|
|
|
|
|
List []struct {
|
|
|
|
|
StoreID uint32 `json:"store_id"` // 门店id
|
|
|
|
|
StoreName string `json:"store_name"` // 门店名称
|
|
|
|
|
NeedCount uint32 `json:"need_count"` // 需采购数
|
|
|
|
|
} `json:"list"`
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// FinishErpPurchaseDemandReq 完成采购需求入参
|
2024-02-23 10:06:21 +00:00
|
|
|
|
type FinishErpPurchaseDemandReq struct {
|
|
|
|
|
ErpCommodityID uint32 `json:"erp_commodity_id" binding:"required"` // 商品id
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// ErpPurchaseReportByOrderReq 采购报表(按单)入参
|
|
|
|
|
type ErpPurchaseReportByOrderReq struct {
|
2024-03-18 11:53:42 +00:00
|
|
|
|
SerialNumber string `json:"serial_number"` // 单据编号
|
|
|
|
|
PurchaseType string `json:"purchase_type"` // 采购类型:procure-采购 reject-退货
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id
|
|
|
|
|
StoreId []uint32 `json:"store_id"` // 门店id
|
|
|
|
|
HandlerId uint32 `json:"handler_id"` // 经手人id
|
|
|
|
|
ErpSupplierId []uint32 `json:"erp_supplier_id"` // 供应商id
|
2024-03-27 10:01:38 +00:00
|
|
|
|
State uint32 `json:"state"` // 2-待入库 3-待退货 4-已完成 5-已终止
|
2024-03-18 11:53:42 +00:00
|
|
|
|
AuditTimeStart string `json:"audit_time_start"` // 审核开始时间
|
|
|
|
|
AuditTimeEnd string `json:"audit_time_end"` // 审核结束时间
|
|
|
|
|
IsExport uint32 `json:"is_export"` // 1-导出
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseReportByOrderResp 采购报表(按单)出参
|
|
|
|
|
type ErpPurchaseReportByOrderResp struct {
|
|
|
|
|
Total int `json:"total"` // 总条数
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
|
|
|
|
Amount float64 `json:"amount"` // 已执行金额
|
2024-03-27 10:01:38 +00:00
|
|
|
|
Count int32 `json:"count"` // 已执行数量
|
2024-03-06 02:07:55 +00:00
|
|
|
|
ExportUrl string `json:"export_url"` // 导出excel路径
|
|
|
|
|
List []ReportByOrderData `json:"list"` // 采购报表信息
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ReportByOrderData struct {
|
|
|
|
|
CommonData
|
|
|
|
|
State uint32 `json:"state"` // 1-待审核 2-待入库 3-待退货 4-已完成 5-已终止
|
|
|
|
|
Remark string `json:"remark"` // 备注
|
|
|
|
|
Amount float64 `json:"amount"` // 已执行金额
|
|
|
|
|
Price float64 `json:"price"` // 执行单价
|
2024-03-27 10:01:38 +00:00
|
|
|
|
Count int32 `json:"count"` // 已执行数量
|
2024-03-06 02:07:55 +00:00
|
|
|
|
CommodityData []ErpPurchaseCommodityData `json:"commodity_data"` // 商品信息
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CommodityData struct {
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id"` // 商品id
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"` // 商品分类名称
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CommonData struct {
|
2024-03-18 11:53:42 +00:00
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id"` // 采购订单id
|
|
|
|
|
SerialNumber string `json:"serial_number"` // 单据编号
|
|
|
|
|
PurchaseType string `json:"purchase_type"` // 单据类型:procure-采购 reject-退货
|
|
|
|
|
StoreId uint32 `json:"store_id"` // 门店id
|
|
|
|
|
StoreName string `json:"store_name"` // 门店名称
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id
|
|
|
|
|
ErpSupplierName string `json:"erp_supplier_name"` // 供应商名称
|
|
|
|
|
HandlerId uint32 `json:"handler_id"` // 经手人id
|
|
|
|
|
HandlerName string `json:"handler_name"` // 经手人名称
|
|
|
|
|
MakerTime *time.Time `json:"maker_time"` // 制单时间
|
|
|
|
|
MakerId uint32 `json:"maker_id"` // 制单人id
|
|
|
|
|
MakerName string `json:"maker_name"` // 制单人名称
|
|
|
|
|
AuditTime *time.Time `json:"audit_time"` // 审核时间
|
|
|
|
|
AuditorId uint32 `json:"auditor_id"` // 审核人id
|
|
|
|
|
AuditorName string `json:"auditor_name"` // 审核人名称
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseCommodityData 采购订单商品信息
|
|
|
|
|
type ErpPurchaseCommodityData struct {
|
|
|
|
|
CommodityData
|
|
|
|
|
Amount float64 `json:"amount"` // 已执行金额
|
|
|
|
|
Price float64 `json:"price"` // 已执行单价
|
2024-03-27 10:01:38 +00:00
|
|
|
|
Count int32 `json:"count"` // 已执行数量
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseReportByCommodityReq 采购报表(按商品)入参
|
|
|
|
|
type ErpPurchaseReportByCommodityReq struct {
|
2024-03-18 11:53:42 +00:00
|
|
|
|
SerialNumber string `json:"serial_number"` // 单据编号
|
|
|
|
|
PurchaseType string `json:"purchase_type"` // 采购类型:procure-采购 reject-退货
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id
|
|
|
|
|
StoreId []uint32 `json:"store_id"` // 门店id
|
|
|
|
|
HandlerId uint32 `json:"handler_id"` // 经手人id
|
|
|
|
|
ErpSupplierId []uint32 `json:"erp_supplier_id"` // 供应商id
|
2024-03-27 10:01:38 +00:00
|
|
|
|
State uint32 `json:"state"` // 2-待入库 3-待退货 4-已完成 5-已终止
|
2024-03-18 11:53:42 +00:00
|
|
|
|
AuditTimeStart string `json:"audit_time_start"` // 审核开始时间
|
|
|
|
|
AuditTimeEnd string `json:"audit_time_end"` // 审核结束时间
|
|
|
|
|
IsExport uint32 `json:"is_export"` // 1-导出
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseReportByCommodityResp 采购报表(按商品)出参
|
|
|
|
|
type ErpPurchaseReportByCommodityResp struct {
|
|
|
|
|
Total int `json:"total"` // 总条数
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
|
|
|
|
PurchaseData
|
|
|
|
|
ExportUrl string `json:"export_url"` // 导出excel路径
|
|
|
|
|
List []ReportByCommodityData `json:"list"` // 采购报表信息
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ReportByCommodityData struct {
|
|
|
|
|
CommodityData
|
|
|
|
|
PurchaseData
|
|
|
|
|
OrderInfo []ErpCommodityPurchaseOrderData `json:"order_info"` // 采购订单信息
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpCommodityPurchaseOrderData 采购商品的订单信息
|
|
|
|
|
type ErpCommodityPurchaseOrderData struct {
|
|
|
|
|
CommonData
|
|
|
|
|
PurchaseData
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type TempData struct {
|
|
|
|
|
CommodityData
|
|
|
|
|
ErpCommodityPurchaseOrderData
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PurchaseData 采购金额和数量
|
|
|
|
|
type PurchaseData struct {
|
|
|
|
|
OrderId uint32 `json:"order_id"` // 采购订单id
|
2024-03-27 10:01:38 +00:00
|
|
|
|
PlanCount int32 `json:"plan_count"` // 计划采购数量
|
2024-03-06 02:07:55 +00:00
|
|
|
|
PlanPrice float64 `json:"plan_price"` // 计划采购单价
|
|
|
|
|
PlanAmount float64 `json:"plan_amount"` // 计划采购金额
|
|
|
|
|
Amount float64 `json:"amount"` // 已执行金额
|
|
|
|
|
Price float64 `json:"price"` // 已执行单价
|
2024-03-27 10:01:38 +00:00
|
|
|
|
Count int32 `json:"count"` // 已执行数量
|
2024-03-06 02:07:55 +00:00
|
|
|
|
NonExecutionAmount float64 `json:"non_execution_amount"` // 未执行金额
|
2024-03-27 10:01:38 +00:00
|
|
|
|
NonExecutionCount int32 `json:"non_execution_count"` // 未执行数量
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseReportBySupplierReq 供应商采购汇总入参
|
|
|
|
|
type ErpPurchaseReportBySupplierReq struct {
|
2024-03-16 08:19:12 +00:00
|
|
|
|
PurchaseType string `json:"purchase_type"` // 采购类型:procure-采购 reject-退货
|
|
|
|
|
ErpCommodityName []string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryID []uint32 `json:"erp_category_id"` // 商品分类id
|
|
|
|
|
ErpSupplierId []uint32 `json:"erp_supplier_id"` // 供应商id
|
|
|
|
|
StartTime string `json:"start_time"` // 入/出库,开始时间
|
|
|
|
|
EndTime string `json:"end_time"` // 入/出库,结束时间
|
|
|
|
|
IsExport uint32 `json:"is_export"` // 1-导出
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
|
|
|
|
StoreList []uint32 `json:"store_list"` // 门店复选
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseReportBySupplierResp 供应商采购汇总出参
|
|
|
|
|
type ErpPurchaseReportBySupplierResp struct {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
Total int `json:"total"` // 总条数
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
|
|
|
|
Count uint32 `json:"count"` // 采购数量
|
|
|
|
|
Amount float64 `json:"amount"` // 采购金额
|
|
|
|
|
RejectAmount float64 `json:"reject_amount"` // 退货金额
|
|
|
|
|
Difference float64 `json:"difference"` // 差额
|
|
|
|
|
ExportUrl string `json:"export_url"` // 导出excel路径
|
|
|
|
|
List []PurchaseReportData `json:"list"` // 供应商采购汇总信息
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PurchaseReportData struct {
|
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id"` // 采购订单id
|
|
|
|
|
StoreId uint32 `json:"store_id"` // 门店id
|
|
|
|
|
StoreName string `json:"store_name"` // 门店名称
|
|
|
|
|
PurchaseType string `json:"purchase_type"` // 采购类型:procure-采购 reject-退货
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id
|
|
|
|
|
ErpSupplierName string `json:"erp_supplier_name"` // 供应商名称
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id"` // 商品id
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"` // 商品分类名称
|
|
|
|
|
Count uint32 `json:"count"` // 采购数量
|
|
|
|
|
Amount float64 `json:"amount"` // 采购金额
|
|
|
|
|
RejectAmount float64 `json:"reject_amount"` // 退货金额
|
|
|
|
|
Difference float64 `json:"difference"` // 差额
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseReportDetailReq 采购明细入参
|
|
|
|
|
type ErpPurchaseReportDetailReq struct {
|
2024-03-18 11:53:42 +00:00
|
|
|
|
SerialNumber string `json:"serial_number"` // 单据编号
|
|
|
|
|
PurchaseType string `json:"purchase_type"` // 采购类型:procure-采购 reject-退货
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id
|
|
|
|
|
StartTime string `json:"startTime"` // 入/出库,开始时间
|
|
|
|
|
EndTime string `json:"endTime"` // 入/出库,结束时间
|
|
|
|
|
IsExport uint32 `json:"is_export"` // 1-导出
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
|
|
|
|
StoreId []uint32 `json:"store_id"` // 门店id
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpPurchaseReportDetailResp 采购明细出参
|
|
|
|
|
type ErpPurchaseReportDetailResp struct {
|
|
|
|
|
Total int `json:"total"` // 总条数
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
|
|
|
|
Price float64 `json:"price"` // 采购价
|
|
|
|
|
EmployeePrice float64 `json:"employee_price"` // 员工成本价
|
|
|
|
|
RejectPrice float64 `json:"reject_price"` // 退货价
|
|
|
|
|
DifferencePrice float64 `json:"difference_price"` // 差价
|
|
|
|
|
ExportUrl string `json:"export_url"` // 导出excel路径
|
|
|
|
|
List []struct {
|
2024-03-18 11:53:42 +00:00
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id"` // 采购订单id
|
|
|
|
|
OrderSerialNumber string `json:"order_serial_number"` // 单据编号
|
2024-03-27 10:01:38 +00:00
|
|
|
|
SerialNumber string `json:"serial_number"` // 采购入库编号
|
2024-03-18 11:53:42 +00:00
|
|
|
|
PurchaseType string `json:"purchase_type"` // 单据类型:procure-采购 reject-退货
|
|
|
|
|
ExecuteTime *time.Time `json:"execute_time"` // 出/入库时间
|
|
|
|
|
StoreId uint32 `json:"store_id"` // 门店id
|
|
|
|
|
StoreName string `json:"store_name"` // 门店名称
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id
|
|
|
|
|
ErpSupplierName string `json:"erp_supplier_name"` // 供应商名称
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id"` // 商品id
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"` // 商品分类名称
|
|
|
|
|
IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码
|
|
|
|
|
IMEI string `json:"imei"` // 商品串码
|
|
|
|
|
Price float64 `json:"price"` // 采购价
|
|
|
|
|
EmployeePrice float64 `json:"employee_price"` // 员工成本价
|
|
|
|
|
RejectPrice float64 `json:"reject_price"` // 退货价
|
|
|
|
|
DifferencePrice float64 `json:"difference_price"` // 差价
|
2024-03-06 02:07:55 +00:00
|
|
|
|
} `json:"list"` // 采购明细信息
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// List 查询采购订单列表
|
2024-02-20 09:59:43 +00:00
|
|
|
|
func (m *ErpPurchaseOrderListReq) List() (*ErpPurchaseOrderListResp, error) {
|
|
|
|
|
resp := &ErpPurchaseOrderListResp{
|
|
|
|
|
PageIndex: m.PageIndex,
|
|
|
|
|
PageSize: m.PageSize,
|
|
|
|
|
}
|
|
|
|
|
page := m.PageIndex - 1
|
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if m.PageSize == 0 {
|
|
|
|
|
m.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
qs := orm.Eloquent.Table("erp_purchase_order")
|
2024-03-06 02:07:55 +00:00
|
|
|
|
var stateList []int
|
2024-03-27 10:01:38 +00:00
|
|
|
|
if m.AuditFlag == "ON" { //2-待入库 4-已完成 5-已终止 6-入库中
|
|
|
|
|
stateList = []int{2, 4, 5, 6}
|
2024-03-06 02:07:55 +00:00
|
|
|
|
qs = qs.Where("state IN ?", stateList)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
qs = qs.Where("purchase_type=?", ErpProcureOrder)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
2024-02-20 09:59:43 +00:00
|
|
|
|
if m.SerialNumber != "" {
|
|
|
|
|
qs = qs.Where("serial_number=?", m.SerialNumber)
|
|
|
|
|
} else {
|
|
|
|
|
if m.PurchaseType != "" {
|
|
|
|
|
qs = qs.Where("purchase_type=?", m.PurchaseType)
|
|
|
|
|
}
|
|
|
|
|
if m.StoreId != 0 {
|
|
|
|
|
qs = qs.Where("store_id=?", m.StoreId)
|
|
|
|
|
}
|
|
|
|
|
if m.ErpSupplierId != 0 {
|
|
|
|
|
qs = qs.Where("erp_supplier_id=?", m.ErpSupplierId)
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
if len(m.State) > 0 {
|
|
|
|
|
qs = qs.Where("state IN (?)", m.State)
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
if m.AuditTimeStart != "" {
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, m.AuditTimeStart)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("erpPurchaseOrderList err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("audit_time > ?", parse)
|
|
|
|
|
}
|
|
|
|
|
if m.AuditTimeEnd != "" {
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, m.AuditTimeEnd)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("erpPurchaseOrderList err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-03-06 02:07:55 +00:00
|
|
|
|
//parse = parse.AddDate(0, 0, 1)
|
2024-02-20 09:59:43 +00:00
|
|
|
|
qs = qs.Where("audit_time < ?", parse)
|
|
|
|
|
}
|
2024-03-16 08:19:12 +00:00
|
|
|
|
if m.HandlerId != 0 {
|
|
|
|
|
qs = qs.Where("handler_id=?", m.HandlerId)
|
|
|
|
|
}
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
|
err := qs.Count(&count).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("count err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
resp.Total = int(count)
|
|
|
|
|
var orders []ErpPurchaseOrder
|
|
|
|
|
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&orders).Error
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
logger.Error("erp commodity list err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
// 校验时间,如果为01-01-01 08:05,则赋值为空
|
|
|
|
|
for i, v := range orders {
|
|
|
|
|
if v.MakerTime != nil && v.MakerTime.IsZero() {
|
|
|
|
|
orders[i].MakerTime = nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v.AuditTime != nil && v.AuditTime.IsZero() {
|
|
|
|
|
orders[i].AuditTime = nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 09:59:43 +00:00
|
|
|
|
resp.List = orders
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewErpPurchaseSn 生成采购订单号
|
|
|
|
|
func NewErpPurchaseSn() string {
|
|
|
|
|
nowTime := time.Now()
|
|
|
|
|
rand.Seed(nowTime.UnixNano())
|
|
|
|
|
max := 1
|
|
|
|
|
for {
|
|
|
|
|
if max > 5 {
|
|
|
|
|
logger.Error("create sn err")
|
|
|
|
|
return ""
|
|
|
|
|
}
|
2024-03-16 08:19:12 +00:00
|
|
|
|
random := rand.Intn(9000) + 1000
|
2024-02-20 09:59:43 +00:00
|
|
|
|
sn := fmt.Sprintf("%s%d", nowTime.Format("060102"), random)
|
|
|
|
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_purchase_order WHERE serial_number='%s'", sn))
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("exist sn err")
|
|
|
|
|
}
|
|
|
|
|
if !exist {
|
|
|
|
|
return sn
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
max++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
func ErpPurchaseCommodityListPerfectInfo(serialNumber string, purchaseCommodities []ErpPurchaseCommodity) error {
|
2024-02-20 09:59:43 +00:00
|
|
|
|
commodityIds := make([]uint32, 0, len(purchaseCommodities))
|
|
|
|
|
for i, _ := range purchaseCommodities {
|
|
|
|
|
commodityIds = append(commodityIds, purchaseCommodities[i].ID)
|
|
|
|
|
}
|
|
|
|
|
commodityMap, err := GetErpCommodityMap(commodityIds)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("purchase commodities err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i, _ := range purchaseCommodities {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
if serialNumber != "" { // 采购退货单才需判断
|
|
|
|
|
// 查询入库商品实际库存详情处剩余有效数,不包含已出库的数量
|
|
|
|
|
nCount, err := GetCommodityStockByPurchaseId(serialNumber, purchaseCommodities[i].ErpCommodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("ErpPurchaseCommodityListPerfectInfo GetCommodityStockByPurchaseId err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
// 如果库存数量不够则报错
|
|
|
|
|
if nCount < purchaseCommodities[i].RejectedCount {
|
|
|
|
|
return fmt.Errorf("商品[%s]采购退货数量超出实际库存数量,请先零售退货", purchaseCommodities[i].ErpCommodityName)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 09:59:43 +00:00
|
|
|
|
v, ok := commodityMap[purchaseCommodities[i].ErpCommodityId]
|
|
|
|
|
if ok {
|
|
|
|
|
purchaseCommodities[i].CommoditySerialNumber = v.SerialNumber
|
|
|
|
|
purchaseCommodities[i].IMEIType = v.IMEIType
|
|
|
|
|
//purchaseCommodities[i].IMEI = v.IMEI
|
|
|
|
|
purchaseCommodities[i].ErpCommodityName = v.Name
|
|
|
|
|
if purchaseCommodities[i].Count != 0 {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
purchaseCommodities[i].Amount = float64(purchaseCommodities[i].Count) * purchaseCommodities[i].Price
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
if purchaseCommodities[i].RejectedCount != 0 {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
purchaseCommodities[i].RejectedAmount = float64(purchaseCommodities[i].RejectedCount) * purchaseCommodities[i].RejectedPrice
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IdInit 添加商户和供应商信息
|
|
|
|
|
func (m *ErpPurchaseOrder) IdInit() error {
|
|
|
|
|
if m.StoreId != 0 {
|
|
|
|
|
store, err := GetStore(m.StoreId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("get store err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
m.StoreName = store.Name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if m.ErpSupplierId != 0 {
|
|
|
|
|
supplier, err := GetErpSupplier(m.ErpSupplierId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("get supplier err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
m.ErpSupplierName = supplier.Name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if m.ErpCashierId != 0 {
|
|
|
|
|
cashier, err := GetAccountDetail(int(m.ErpCashierId))
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("get cashier err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
m.ErpCashierName = cashier.Name
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPurchaseInventorySn 生成入库编号
|
|
|
|
|
func GetPurchaseInventorySn() string {
|
|
|
|
|
count := 0
|
|
|
|
|
for {
|
|
|
|
|
if count > 5 {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
nowTime := time.Now()
|
|
|
|
|
sn := nowTime.Format("060102")
|
|
|
|
|
sn += fmt.Sprintf("%d", nowTime.Unix()%100)
|
|
|
|
|
rand.Seed(nowTime.UnixNano())
|
|
|
|
|
sn += fmt.Sprintf("%d", rand.Int31n(100))
|
|
|
|
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_purchase_inventory WHERE serial_number='%s'", sn))
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("sn err:", logger.Field("err", err))
|
|
|
|
|
count++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if err == nil && !exist {
|
|
|
|
|
return sn
|
|
|
|
|
}
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-16 08:19:12 +00:00
|
|
|
|
// CheckCreateErpPurchaseOrderParam 新增采购订单-检查参数
|
|
|
|
|
func CheckCreateErpPurchaseOrderParam(req *ErpPurchaseCreateReq) error {
|
|
|
|
|
if req.PurchaseType == ErpProcureOrder { // 采购入库订单
|
|
|
|
|
if req.StoreId == 0 {
|
|
|
|
|
return errors.New("操作失败:门店id为空")
|
|
|
|
|
}
|
|
|
|
|
if req.DeliveryAddress == "" {
|
|
|
|
|
return errors.New("操作失败:交货地址为空")
|
|
|
|
|
}
|
|
|
|
|
if req.ErpSupplierId == 0 {
|
|
|
|
|
return errors.New("操作失败:供应商id为空")
|
|
|
|
|
}
|
|
|
|
|
if req.AccountHolder == "" {
|
|
|
|
|
return errors.New("操作失败:收款人为空")
|
|
|
|
|
}
|
|
|
|
|
if req.OpeningBank == "" {
|
|
|
|
|
return errors.New("操作失败:开户行为空")
|
|
|
|
|
}
|
|
|
|
|
if req.BankAccount == "" {
|
|
|
|
|
return errors.New("操作失败:银行卡号为空")
|
|
|
|
|
}
|
|
|
|
|
if req.DeliveryTime == "" {
|
|
|
|
|
return errors.New("操作失败:交货日期为空")
|
|
|
|
|
}
|
|
|
|
|
} else if req.PurchaseType == ErpRejectOrder { // 退货单
|
|
|
|
|
if req.PurchaseOrderSn == "" {
|
|
|
|
|
return errors.New("操作失败:采购退货单据编号为空")
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return errors.New("操作失败:采购类型有误")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CheckEditErpPurchaseOrderParam 编辑采购订单-检查参数
|
|
|
|
|
func CheckEditErpPurchaseOrderParam(req *ErpPurchaseEditReq) error {
|
|
|
|
|
if req.PurchaseType == ErpProcureOrder { // 采购入库订单
|
|
|
|
|
if req.StoreId == 0 {
|
|
|
|
|
return errors.New("操作失败:门店id为空")
|
|
|
|
|
}
|
|
|
|
|
if req.DeliveryAddress == "" {
|
|
|
|
|
return errors.New("操作失败:交货地址为空")
|
|
|
|
|
}
|
|
|
|
|
if req.ErpSupplierId == 0 {
|
|
|
|
|
return errors.New("操作失败:供应商id为空")
|
|
|
|
|
}
|
|
|
|
|
if req.AccountHolder == "" {
|
|
|
|
|
return errors.New("操作失败:收款人为空")
|
|
|
|
|
}
|
|
|
|
|
if req.OpeningBank == "" {
|
|
|
|
|
return errors.New("操作失败:开户行为空")
|
|
|
|
|
}
|
|
|
|
|
if req.BankAccount == "" {
|
|
|
|
|
return errors.New("操作失败:银行卡号为空")
|
|
|
|
|
}
|
|
|
|
|
if req.DeliveryTime == "" {
|
|
|
|
|
return errors.New("操作失败:交货日期为空")
|
|
|
|
|
}
|
|
|
|
|
} else if req.PurchaseType == ErpRejectOrder { // 退货单
|
|
|
|
|
if req.PurchaseOrderSn == "" {
|
|
|
|
|
return errors.New("操作失败:采购退货单据编号为空")
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return errors.New("操作失败:采购类型有误")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 09:59:43 +00:00
|
|
|
|
// CreateErpPurchaseOrder 新增采购订单
|
|
|
|
|
func CreateErpPurchaseOrder(req *ErpPurchaseCreateReq, sysUser *SysUser) (*ErpPurchaseOrder, error) {
|
|
|
|
|
var err error
|
|
|
|
|
nowTime := time.Now()
|
|
|
|
|
|
|
|
|
|
purchaseOrder := &ErpPurchaseOrder{}
|
|
|
|
|
if req.PurchaseType == ErpProcureOrder { // 采购入库订单
|
|
|
|
|
purchaseOrder = &ErpPurchaseOrder{
|
2024-02-26 10:18:23 +00:00
|
|
|
|
SerialNumber: "cgr" + NewErpPurchaseSn(),
|
|
|
|
|
PurchaseType: req.PurchaseType,
|
|
|
|
|
StoreId: req.StoreId,
|
|
|
|
|
ErpSupplierId: req.ErpSupplierId,
|
2024-03-18 11:53:42 +00:00
|
|
|
|
MakerTime: &nowTime,
|
2024-02-26 10:18:23 +00:00
|
|
|
|
HandlerId: req.HandlerId,
|
|
|
|
|
HandlerName: req.HandlerName,
|
|
|
|
|
MakerId: uint32(sysUser.UserId),
|
|
|
|
|
MakerName: sysUser.NickName,
|
|
|
|
|
State: ErpPurchaseOrderUnAudit, // 1-待审核
|
|
|
|
|
ErpCashierId: req.ErpCashierId,
|
|
|
|
|
AccountHolder: req.AccountHolder,
|
|
|
|
|
OpeningBank: req.OpeningBank,
|
|
|
|
|
BankAccount: req.BankAccount,
|
|
|
|
|
DeliveryTime: req.DeliveryTime,
|
|
|
|
|
DeliveryAddress: req.DeliveryAddress,
|
|
|
|
|
Remark: req.Remark,
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
err = purchaseOrder.IdInit()
|
|
|
|
|
} else if req.PurchaseType == ErpRejectOrder { // 采购退货订单
|
2024-02-23 10:06:21 +00:00
|
|
|
|
if req.PurchaseOrderSn == "" {
|
|
|
|
|
return nil, errors.New("新建失败:采购退货订单号为空")
|
|
|
|
|
}
|
2024-02-20 09:59:43 +00:00
|
|
|
|
var erpPurchaseOrder ErpPurchaseOrder
|
|
|
|
|
err = orm.Eloquent.Table("erp_purchase_order").Where("serial_number=?", req.PurchaseOrderSn).Find(&erpPurchaseOrder).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("purchase order err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
purchaseOrder = &ErpPurchaseOrder{
|
2024-03-18 11:53:42 +00:00
|
|
|
|
SerialNumber: "cgt" + NewErpPurchaseSn(),
|
|
|
|
|
PurchaseType: req.PurchaseType,
|
|
|
|
|
StoreId: erpPurchaseOrder.StoreId,
|
|
|
|
|
ErpSupplierId: erpPurchaseOrder.ErpSupplierId,
|
|
|
|
|
MakerTime: &nowTime,
|
|
|
|
|
HandlerId: req.HandlerId,
|
|
|
|
|
HandlerName: req.HandlerName,
|
|
|
|
|
MakerId: uint32(sysUser.UserId),
|
|
|
|
|
MakerName: sysUser.NickName,
|
|
|
|
|
State: ErpPurchaseOrderUnAudit, // 1-待审核
|
|
|
|
|
ErpCashierId: req.ErpCashierId,
|
|
|
|
|
Remark: req.Remark,
|
|
|
|
|
RejectedSerialNumber: req.PurchaseOrderSn,
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
err = purchaseOrder.IdInit()
|
|
|
|
|
} else {
|
|
|
|
|
logger.Errorf("purchase_type err:", req.PurchaseType)
|
|
|
|
|
return nil, errors.New("操作失败:采购类型有误")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("info err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
err = ErpPurchaseCommodityListPerfectInfo(req.PurchaseOrderSn, req.ErpPurchaseCommodities)
|
2024-02-20 09:59:43 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("info err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
begin := orm.Eloquent.Begin()
|
|
|
|
|
err = begin.Create(purchaseOrder).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("create purchase order err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i, _ := range req.ErpPurchaseCommodities {
|
|
|
|
|
req.ErpPurchaseCommodities[i].ErpPurchaseOrderId = purchaseOrder.ID
|
|
|
|
|
req.ErpPurchaseCommodities[i].InventoryCount = 0 // todo 数量待核实
|
|
|
|
|
err = begin.Create(&req.ErpPurchaseCommodities[i]).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("create purchase commodity err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
err = begin.Commit().Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("commit purchase commodity err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return purchaseOrder, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// EditErpPurchaseOrder 编辑采购订单
|
|
|
|
|
func EditErpPurchaseOrder(req *ErpPurchaseEditReq, sysUser *SysUser) (*ErpPurchaseOrder, error) {
|
|
|
|
|
// 查询订单信息
|
|
|
|
|
var purchaseOrder ErpPurchaseOrder
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_order").Where("id=?", req.ErpPurchaseOrderId).Find(&purchaseOrder).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("purchase order err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if purchaseOrder.State != ErpPurchaseOrderUnAudit { // 只有待审核的订单才能编辑
|
|
|
|
|
return nil, errors.New("订单不是待审核状态")
|
|
|
|
|
}
|
2024-03-16 08:19:12 +00:00
|
|
|
|
|
|
|
|
|
if req.StoreId == 0 && req.PurchaseType == ErpProcureOrder {
|
|
|
|
|
return nil, errors.New("操作失败:门店id为空")
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 09:59:43 +00:00
|
|
|
|
begin := orm.Eloquent.Begin()
|
|
|
|
|
// 1-更新采购订单信息
|
|
|
|
|
purchaseOrder.StoreId = req.StoreId
|
|
|
|
|
purchaseOrder.ErpSupplierId = req.ErpSupplierId
|
2024-02-23 10:06:21 +00:00
|
|
|
|
purchaseOrder.HandlerId = req.HandlerId
|
|
|
|
|
purchaseOrder.HandlerName = req.HandlerName
|
|
|
|
|
purchaseOrder.MakerId = uint32(sysUser.UserId)
|
|
|
|
|
purchaseOrder.MakerName = sysUser.NickName
|
2024-02-20 09:59:43 +00:00
|
|
|
|
purchaseOrder.ErpCashierId = req.ErpCashierId
|
|
|
|
|
purchaseOrder.AccountHolder = req.AccountHolder
|
|
|
|
|
purchaseOrder.OpeningBank = req.OpeningBank
|
|
|
|
|
purchaseOrder.BankAccount = req.BankAccount
|
|
|
|
|
purchaseOrder.DeliveryTime = req.DeliveryTime
|
2024-02-26 10:18:23 +00:00
|
|
|
|
purchaseOrder.DeliveryAddress = req.DeliveryAddress
|
|
|
|
|
purchaseOrder.Remark = req.Remark
|
2024-02-20 09:59:43 +00:00
|
|
|
|
err = purchaseOrder.IdInit()
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("purchase IdInit err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = begin.Model(&ErpPurchaseOrder{}).Where("id = ?", req.ErpPurchaseOrderId).Updates(purchaseOrder).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("update erp_order err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2-更新采购订单商品表
|
|
|
|
|
err = updatePurchaseCommodityData(begin, req.ErpPurchaseOrderId, req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("update erp_purchase_commodity err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = begin.Commit().Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("commit err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &purchaseOrder, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// updatePurchaseCommodityData 更新采购订单商品信息
|
|
|
|
|
func updatePurchaseCommodityData(gdb *gorm.DB, orderId uint32, req *ErpPurchaseEditReq) error {
|
|
|
|
|
// 查询现有的零售订单信息
|
|
|
|
|
var commodities []ErpPurchaseCommodity
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_commodity").Where("erp_purchase_order_id = ?", orderId).Find(&commodities).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("query erp_purchase_commodity err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var newCommodities []ErpPurchaseCommodity
|
|
|
|
|
var deletedCommodities []ErpPurchaseCommodity
|
|
|
|
|
var matchingCommodities []ErpPurchaseCommodity
|
|
|
|
|
// 找到新增的商品
|
|
|
|
|
for i, reqCommodity := range req.ErpPurchaseCommodities {
|
|
|
|
|
// 订单商品表信息添加零售订单id
|
|
|
|
|
req.ErpPurchaseCommodities[i].ErpPurchaseOrderId = orderId
|
|
|
|
|
|
|
|
|
|
var found bool
|
|
|
|
|
for _, dbCommodity := range commodities {
|
|
|
|
|
if reqCommodity.ErpCommodityId == dbCommodity.ErpCommodityId {
|
|
|
|
|
found = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found {
|
|
|
|
|
newCommodities = append(newCommodities, reqCommodity)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 找到删除的商品
|
|
|
|
|
for _, dbCommodity := range commodities {
|
|
|
|
|
var found bool
|
|
|
|
|
for _, reqCommodity := range req.ErpPurchaseCommodities {
|
|
|
|
|
if reqCommodity.ID == dbCommodity.ID {
|
|
|
|
|
found = true
|
|
|
|
|
// 找到匹配的商品,加入匹配列表
|
|
|
|
|
matchingCommodities = append(matchingCommodities, reqCommodity)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found {
|
|
|
|
|
deletedCommodities = append(deletedCommodities, dbCommodity)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2-更新商品订单信息-更新
|
|
|
|
|
for _, commodity := range matchingCommodities {
|
|
|
|
|
if err := gdb.Model(&ErpPurchaseCommodity{}).Where("id = ?", commodity.ID).Updates(commodity).Error; err != nil {
|
|
|
|
|
logger.Error("更新商品订单信息-更新 error")
|
|
|
|
|
return errors.New("操作失败:" + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2-更新商品订单信息-新增
|
|
|
|
|
if len(newCommodities) != 0 {
|
|
|
|
|
err = gdb.Create(&newCommodities).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("更新商品订单信息-新增 error")
|
|
|
|
|
return errors.New("操作失败:" + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//2-更新商品订单信息-删除
|
|
|
|
|
if len(deletedCommodities) != 0 {
|
|
|
|
|
err = gdb.Delete(&deletedCommodities).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("更新商品订单信息-删除 error")
|
|
|
|
|
return errors.New("操作失败:" + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// InventoryErpPurchase 采购订单入库
|
|
|
|
|
func InventoryErpPurchase(req *ErpPurchaseInventoryReq) error {
|
|
|
|
|
err := checkPurchaseInventory(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("checkPurchaseInventoryReq err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
begin := orm.Eloquent.Begin()
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var inventoryList []ErpPurchaseInventory
|
|
|
|
|
for i, v := range req.Inventories {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
v.SerialNumber = GetPurchaseInventorySn()
|
2024-03-27 10:01:38 +00:00
|
|
|
|
req.Inventories[i].SerialNumber = v.SerialNumber
|
2024-02-20 09:59:43 +00:00
|
|
|
|
// 更新采购商品表的执行数量
|
2024-02-23 10:06:21 +00:00
|
|
|
|
// todo 如果用户在同一个采购单中新建了同一个商品的2条采购信息,可能采购价不同,需要区分入库的是哪一条(已修改)
|
2024-02-20 09:59:43 +00:00
|
|
|
|
err = begin.Model(&ErpPurchaseCommodity{}).
|
2024-03-27 10:01:38 +00:00
|
|
|
|
Where("erp_purchase_order_id = ? and erp_commodity_id = ?", v.ErpPurchaseOrderId, v.ErpCommodityId).
|
2024-02-23 10:06:21 +00:00
|
|
|
|
UpdateColumn("inventory_count", gorm.Expr("inventory_count + ?", v.Count)).Error
|
2024-02-20 09:59:43 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("update inventory count err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-03-18 11:53:42 +00:00
|
|
|
|
v.PurchaseType = req.PurchaseType // 记录采购类型
|
|
|
|
|
v.InventoryId = req.InventoryId // 记录入库人id
|
|
|
|
|
v.InventoryName = req.InventoryName // 记录入库人姓名
|
2024-03-27 10:01:38 +00:00
|
|
|
|
|
|
|
|
|
nCount := v.Count
|
|
|
|
|
nAmount := v.Amount
|
|
|
|
|
for i := 0; i < int(nCount); i++ { // 采购入库记录表都是单笔数据
|
|
|
|
|
v.ID = 0
|
|
|
|
|
v.Count = 1
|
|
|
|
|
v.Amount = nAmount / float64(nCount) // 前端传的执行金额是总金额
|
|
|
|
|
// 新建采购入库记录
|
|
|
|
|
err = begin.Create(&v).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("create erp inventory commodity err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
inventoryList = append(inventoryList, v)
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
2024-02-23 10:06:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购订单信息
|
|
|
|
|
var purchaseOrder ErpPurchaseOrder
|
|
|
|
|
err = orm.Eloquent.Table("erp_purchase_order").Where("id=?", req.ErpPurchaseOrderId).Find(&purchaseOrder).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("purchase order err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新库存信息表
|
|
|
|
|
if purchaseOrder.PurchaseType == ErpProcureOrder { //采购入库订单
|
2024-03-27 10:01:38 +00:00
|
|
|
|
err = InventoryErpPurchaseUpdateStock(begin, inventoryList, purchaseOrder)
|
2024-02-23 10:06:21 +00:00
|
|
|
|
} else if purchaseOrder.PurchaseType == ErpRejectOrder { // 采购退货订单
|
2024-03-27 10:01:38 +00:00
|
|
|
|
err = InventoryErpPurchaseUpdateRejectStock(begin, inventoryList, purchaseOrder)
|
2024-02-23 10:06:21 +00:00
|
|
|
|
} else {
|
|
|
|
|
return errors.New("订单类型有误")
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("update stock err:", logger.Field("err", err))
|
|
|
|
|
return err
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = begin.Commit().Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("commit err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// 查询采购订单商品表入库或退库情况,如果都已经完成了,则更新采购订单的状态为:已完成
|
|
|
|
|
_ = CheckAndUpdatePurchaseOrderState(req.ErpPurchaseOrderId)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CheckAndUpdatePurchaseOrderState
|
|
|
|
|
// 查询采购订单商品表入库或退库情况,如果都已经完成了,则更新采购订单的状态为:已完成
|
|
|
|
|
func CheckAndUpdatePurchaseOrderState(orderId uint32) error {
|
|
|
|
|
var order ErpPurchaseOrder
|
|
|
|
|
if err := orm.Eloquent.Where("id = ?", orderId).First(&order).Error; err != nil {
|
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
|
return fmt.Errorf("purchase order with ID %d not found", orderId)
|
|
|
|
|
}
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if order.State == ErpPurchaseOrderFinished {
|
|
|
|
|
return nil // Order is already marked as completed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var commodities []ErpPurchaseCommodity
|
|
|
|
|
if err := orm.Eloquent.Where("erp_purchase_order_id = ?", orderId).Find(&commodities).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, commodity := range commodities {
|
|
|
|
|
if (order.PurchaseType == "procure" && commodity.Count != uint32(commodity.InventoryCount)) ||
|
|
|
|
|
(order.PurchaseType == "reject" && commodity.RejectedCount != uint32(commodity.InventoryCount)) {
|
|
|
|
|
return nil // Order not completed, exit early
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If all commodities are checked and everything is in order, update the state to completed
|
|
|
|
|
if err := orm.Eloquent.Model(&order).Update("state", ErpPurchaseOrderFinished).Update("audit_time", time.Now()).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 09:59:43 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
// GetInventoryIdAndName 获取采购单最近入库人信息
|
|
|
|
|
func GetInventoryIdAndName(orderId uint32) (uint32, string, error) {
|
|
|
|
|
var purchaseInventory ErpPurchaseInventory
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_inventory").Where("erp_purchase_order_id=?", orderId).
|
2024-03-27 10:01:38 +00:00
|
|
|
|
Order("created_at DESC").First(&purchaseInventory).Error
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("purchase order err:", logger.Field("err", err))
|
|
|
|
|
return 0, "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return purchaseInventory.InventoryId, purchaseInventory.InventoryName, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-23 10:06:21 +00:00
|
|
|
|
// InventoryErpPurchaseUpdateStock 采购订单入库更新库存信息
|
2024-03-27 10:01:38 +00:00
|
|
|
|
func InventoryErpPurchaseUpdateStock(gdb *gorm.DB, list []ErpPurchaseInventory, purchaseOrder ErpPurchaseOrder) error {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
// 遍历采购入库商品信息
|
|
|
|
|
var stockList []ErpStockCommodity
|
2024-03-27 10:01:38 +00:00
|
|
|
|
for _, v := range list {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
commodityInfo, err := GetCommodity(v.ErpCommodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("GetCommodity err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock WHERE store_id=%d AND erp_commodity_id=%d",
|
|
|
|
|
purchaseOrder.StoreId, v.ErpCommodityId))
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("exist err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if exist {
|
|
|
|
|
err = gdb.Exec(fmt.Sprintf(
|
2024-03-27 10:01:38 +00:00
|
|
|
|
"UPDATE erp_stock SET count=count+%d WHERE store_id=%d AND erp_commodity_id=%d",
|
2024-02-23 10:06:21 +00:00
|
|
|
|
v.Count, purchaseOrder.StoreId, v.ErpCommodityId)).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("update stock err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
stock := &ErpStock{
|
|
|
|
|
StoreId: purchaseOrder.StoreId,
|
|
|
|
|
StoreName: purchaseOrder.StoreName,
|
|
|
|
|
ErpCommodityId: v.ErpCommodityId,
|
|
|
|
|
ErpCommodityName: v.ErpCommodityName,
|
|
|
|
|
ErpCategoryId: commodityInfo.ErpCategoryId,
|
|
|
|
|
ErpCategoryName: commodityInfo.ErpCategoryName,
|
|
|
|
|
CommoditySerialNumber: v.CommoditySerialNumber,
|
|
|
|
|
IMEIType: v.IMEIType,
|
|
|
|
|
RetailPrice: commodityInfo.RetailPrice,
|
|
|
|
|
MinRetailPrice: commodityInfo.MinRetailPrice,
|
|
|
|
|
Count: v.Count,
|
|
|
|
|
DispatchCount: 0,
|
|
|
|
|
}
|
|
|
|
|
err = gdb.Create(stock).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("create stock err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nowTime := time.Now()
|
|
|
|
|
stockCommodity := ErpStockCommodity{
|
|
|
|
|
StoreId: purchaseOrder.StoreId,
|
|
|
|
|
StoreName: purchaseOrder.StoreName,
|
|
|
|
|
ErpCommodityId: v.ErpCommodityId,
|
|
|
|
|
ErpCommodityName: v.ErpCommodityName,
|
|
|
|
|
CommoditySerialNumber: v.CommoditySerialNumber,
|
|
|
|
|
ErpCategoryId: commodityInfo.ErpCategoryId,
|
|
|
|
|
ErpCategoryName: commodityInfo.ErpCategoryName,
|
|
|
|
|
ErpSupplierId: purchaseOrder.ErpSupplierId,
|
|
|
|
|
ErpSupplierName: purchaseOrder.ErpSupplierName,
|
|
|
|
|
StaffCostPrice: uint32(v.EmployeePrice - v.ImplementationPrice),
|
|
|
|
|
WholesalePrice: uint32(v.ImplementationPrice),
|
2024-03-16 08:19:12 +00:00
|
|
|
|
State: InStock,
|
|
|
|
|
StorageType: PurchaseInventory, // 采购入库
|
2024-02-23 10:06:21 +00:00
|
|
|
|
FirstStockTime: nowTime,
|
|
|
|
|
StockTime: nowTime,
|
|
|
|
|
Count: v.Count,
|
|
|
|
|
ErpBarcode: commodityInfo.ErpBarcode, // 240106新增商品条码
|
|
|
|
|
IMEIType: v.IMEIType,
|
|
|
|
|
IMEI: v.IMEI,
|
|
|
|
|
Remark: "",
|
|
|
|
|
MemberDiscount: commodityInfo.MemberDiscount,
|
|
|
|
|
MinRetailPrice: commodityInfo.MinRetailPrice,
|
|
|
|
|
RetailPrice: commodityInfo.RetailPrice,
|
2024-03-18 11:53:42 +00:00
|
|
|
|
OriginalSn: purchaseOrder.SerialNumber,
|
2024-03-27 10:01:38 +00:00
|
|
|
|
StockSn: v.SerialNumber,
|
2024-02-23 10:06:21 +00:00
|
|
|
|
}
|
|
|
|
|
stockList = append(stockList, stockCommodity)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := gdb.Debug().Create(&stockList).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("create stock commodity err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// InventoryErpPurchaseUpdateRejectStock 采购退货更新库存信息
|
2024-03-27 10:01:38 +00:00
|
|
|
|
func InventoryErpPurchaseUpdateRejectStock(gdb *gorm.DB, list []ErpPurchaseInventory, purchaseOrder ErpPurchaseOrder) error {
|
|
|
|
|
usedStockCommodityIdList := make(map[uint32]bool)
|
|
|
|
|
for i, _ := range list {
|
|
|
|
|
if list[i].IMEIType == 2 { // 串码商品
|
|
|
|
|
if list[i].IMEI == "" {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
return errors.New("串码为空")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 判断该串码商品是否已经销售
|
|
|
|
|
var stockCommodityInfo ErpStockCommodity
|
2024-03-27 10:01:38 +00:00
|
|
|
|
err := orm.Eloquent.Table("erp_stock_commodity").Where("imei = ?", list[i].IMEI).
|
2024-02-23 10:06:21 +00:00
|
|
|
|
Find(&stockCommodityInfo).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("Inventory RejectStock query commodities err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if stockCommodityInfo.State == SoldOut {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
return fmt.Errorf("商品[%s]已经销售,不能退货", stockCommodityInfo.ErpCommodityName)
|
2024-02-23 10:06:21 +00:00
|
|
|
|
} else if stockCommodityInfo.State == OnSale {
|
|
|
|
|
return fmt.Errorf("商品[%s]在销售锁定中,不能退货", stockCommodityInfo.ErpCommodityName)
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
err = gdb.Table("erp_stock_commodity").Where("imei = ?", list[i].IMEI).
|
|
|
|
|
Updates(&map[string]interface{}{
|
|
|
|
|
"state": PurchaseReturn,
|
|
|
|
|
"stock_sn": list[i].SerialNumber,
|
|
|
|
|
}).Error // 状态更新为采购退货
|
2024-02-23 10:06:21 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?",
|
2024-03-27 10:01:38 +00:00
|
|
|
|
purchaseOrder.StoreId, list[i].ErpCommodityId).
|
2024-02-23 10:06:21 +00:00
|
|
|
|
Updates(map[string]interface{}{"count": gorm.Expr("count - ?", 1)}).Error // 库存数量-1
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
} else {
|
|
|
|
|
// 查询入库商品实际库存详情处剩余有效数,不包含已出库的数量
|
|
|
|
|
nCount, err := GetCommodityStockByPurchaseId(purchaseOrder.RejectedSerialNumber, list[i].ErpCommodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("InventoryErpPurchaseUpdateRejectStock GetCommodityStockByPurchaseId err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
// 如果库存数量不够则报错
|
|
|
|
|
if nCount < list[i].Count {
|
|
|
|
|
return fmt.Errorf("商品[%s]采购退货数量超出实际库存数量,请先零售退货", list[i].ErpCommodityName)
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-23 10:06:21 +00:00
|
|
|
|
var stockCommodity []ErpStockCommodity
|
|
|
|
|
// 通过门店id,商品id,查找状态为1-在库的非串码商品
|
2024-03-27 10:01:38 +00:00
|
|
|
|
err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and store_id = ? "+
|
|
|
|
|
"and state = ? and imei_type = ?", list[i].ErpCommodityId, purchaseOrder.StoreId, InStock, 1).
|
2024-02-23 10:06:21 +00:00
|
|
|
|
Order("id DESC").Find(&stockCommodity).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if stockCommodity == nil {
|
|
|
|
|
return errors.New("RetailTypeRejected find no stock commodity")
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var currentID uint32
|
|
|
|
|
// 找一个可用的库存ID
|
|
|
|
|
for _, item := range stockCommodity {
|
|
|
|
|
_, ok := usedStockCommodityIdList[item.ID]
|
|
|
|
|
if !ok {
|
|
|
|
|
usedStockCommodityIdList[item.ID] = true
|
|
|
|
|
currentID = item.ID
|
|
|
|
|
break
|
|
|
|
|
} else {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if currentID == 0 {
|
|
|
|
|
return fmt.Errorf("商品[%s]采购退货数量超出实际库存数量,请先零售退货", list[i].ErpCommodityName)
|
|
|
|
|
}
|
|
|
|
|
err = gdb.Table("erp_stock_commodity").Where("id = ?", currentID).Updates(&map[string]interface{}{
|
|
|
|
|
"state": PurchaseReturn,
|
|
|
|
|
"stock_sn": list[i].SerialNumber,
|
|
|
|
|
}).Error // 状态更新为采购退货
|
2024-02-23 10:06:21 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?",
|
2024-03-27 10:01:38 +00:00
|
|
|
|
purchaseOrder.StoreId, list[i].ErpCommodityId).
|
2024-02-23 10:06:21 +00:00
|
|
|
|
Updates(map[string]interface{}{"count": gorm.Expr("count - ?", 1)}).Error // 库存数量-1
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 09:59:43 +00:00
|
|
|
|
// 校验入参数据,执行数量是否超过总数;串码商品的串码是否重复
|
|
|
|
|
func checkPurchaseInventory(req *ErpPurchaseInventoryReq) error {
|
|
|
|
|
// 查询现有的零售订单信息
|
|
|
|
|
var commodities []ErpPurchaseCommodity
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_commodity").Where("erp_purchase_order_id = ?", req.ErpPurchaseOrderId).Find(&commodities).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("query erp_purchase_commodity err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-23 10:06:21 +00:00
|
|
|
|
countMap := make(map[uint32]uint32)
|
2024-03-16 08:19:12 +00:00
|
|
|
|
for i, inventory := range req.Inventories {
|
|
|
|
|
if inventory.ErpCommodityId == 0 {
|
|
|
|
|
return fmt.Errorf("商品Id传参错误,不能为0")
|
|
|
|
|
}
|
2024-02-23 10:06:21 +00:00
|
|
|
|
countMap[inventory.ErpCommodityId] += inventory.Count
|
2024-02-20 09:59:43 +00:00
|
|
|
|
|
|
|
|
|
// 如果该商品是串码商品,判断其串码是否会重复
|
|
|
|
|
if inventory.IMEI != "" {
|
|
|
|
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock_commodity WHERE FIND_IN_SET(%s, imei) > 0", inventory.IMEI))
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("exist sn err")
|
|
|
|
|
}
|
|
|
|
|
if exist {
|
2024-03-16 08:19:12 +00:00
|
|
|
|
return fmt.Errorf("串码有重复项请修改[%s]", inventory.IMEI)
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-16 08:19:12 +00:00
|
|
|
|
|
|
|
|
|
// 备注:员工成本价在"库存管理-采购单入库"里面的入库操作前端是隐藏不可修改的,会默认传0
|
|
|
|
|
if inventory.EmployeePrice != 0 && inventory.EmployeePrice < inventory.ImplementationPrice {
|
|
|
|
|
return fmt.Errorf("数据错误,员工成本价不能低于采购执行单价")
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
erpCommodity, err := GetCommodity(inventory.ErpCommodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("checkPurchaseInventory GetCommodity err:", logger.Field("err", err))
|
|
|
|
|
return fmt.Errorf("查询员工成本价报错")
|
|
|
|
|
}
|
|
|
|
|
req.Inventories[i].ErpCategoryID = erpCommodity.ErpCategoryId // 分类id,入库的时候前端没传,后端补充
|
|
|
|
|
req.Inventories[i].ErpCategoryName = erpCommodity.ErpCategoryName // 分类名称,入库的时候前端没传,后端补充
|
2024-03-16 08:19:12 +00:00
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
if inventory.EmployeePrice == 0 { // 没有传入员工成本价,则默认按照商品资料设置的员工成本价加价金额
|
2024-03-16 08:19:12 +00:00
|
|
|
|
req.Inventories[i].EmployeePrice = inventory.ImplementationPrice + float64(erpCommodity.StaffCostPrice)
|
|
|
|
|
}
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 入库的商品信息有误,不在之前的商品列表中
|
|
|
|
|
for commodityID := range countMap {
|
|
|
|
|
found := false
|
|
|
|
|
for _, commodity := range commodities {
|
|
|
|
|
if commodity.ErpCommodityId == commodityID {
|
|
|
|
|
found = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found {
|
|
|
|
|
return fmt.Errorf("商品编号[%d]不属于该采购订单", commodityID)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 本次入库的数量超出该商品未入库数量
|
|
|
|
|
for _, commodity := range commodities {
|
|
|
|
|
if inventoryCount, ok := countMap[commodity.ErpCommodityId]; ok {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
if req.PurchaseType == ErpProcureOrder {
|
|
|
|
|
if commodity.Count-uint32(commodity.InventoryCount) < inventoryCount {
|
|
|
|
|
return fmt.Errorf("本次入库商品[%s]数量[%d]超出该商品未入库数量[%d]", commodity.ErpCommodityName,
|
|
|
|
|
inventoryCount, int32(commodity.Count)-commodity.InventoryCount)
|
|
|
|
|
}
|
|
|
|
|
} else if req.PurchaseType == ErpRejectOrder {
|
|
|
|
|
if commodity.RejectedCount-uint32(commodity.InventoryCount) < inventoryCount {
|
|
|
|
|
return fmt.Errorf("本次退货商品[%s]数量[%d]超出该商品未退货数量[%d]", commodity.ErpCommodityName,
|
|
|
|
|
inventoryCount, int32(commodity.Count)-commodity.InventoryCount)
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
|
|
|
|
|
// 查询入库商品实际库存详情处剩余有效数,不包含已出库的数量
|
|
|
|
|
var purchaseOrder ErpPurchaseOrder
|
|
|
|
|
err = orm.Eloquent.Table("erp_purchase_order").Where("id=?", req.ErpPurchaseOrderId).Find(&purchaseOrder).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("checkPurchaseInventory purchase order err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
nCount, err := GetCommodityStockByPurchaseId(purchaseOrder.RejectedSerialNumber, commodity.ErpCommodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("checkPurchaseInventory GetCommodityStockByPurchaseId err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
// 如果库存数量不够则报错
|
|
|
|
|
if nCount < commodity.RejectedCount {
|
|
|
|
|
return fmt.Errorf("商品[%s]采购退货数量超出实际库存数量,请先零售退货", commodity.ErpCommodityName)
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ExecuteErpPurchase 执行(入库/退货)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
func ExecuteErpPurchase(req *ErpPurchaseExecuteReq) (*ErpPurchaseExecuteResp, error) {
|
|
|
|
|
reqParam := &ErpPurchaseInventoryReq{
|
|
|
|
|
ErpPurchaseOrderId: req.ErpPurchaseOrderId,
|
|
|
|
|
PurchaseType: req.PurchaseType,
|
|
|
|
|
Inventories: req.Inventories,
|
|
|
|
|
}
|
|
|
|
|
err := checkPurchaseInventory(reqParam)
|
2024-02-20 09:59:43 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("checkPurchaseInventoryReq err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp := &ErpPurchaseExecuteResp{
|
|
|
|
|
List: make([]ExecuteData, 0),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, inventory := range req.Inventories {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// 获取商品信息
|
|
|
|
|
commodityInfo, err := GetCommodity(inventory.ErpCommodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if commodityInfo.IMEIType == 2 || commodityInfo.IMEIType == 3 {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
// 如果是串码商品,根据 Count 拆分成对应数量的数据
|
|
|
|
|
for i := 0; i < int(inventory.Count); i++ {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
imei := "" // 默认退货单执行时不需要串码
|
|
|
|
|
if inventory.PurchaseType == ErpProcureOrder && commodityInfo.IMEIType == 2 { // 采购单
|
2024-02-23 10:06:21 +00:00
|
|
|
|
// 调用函数B生成商品串码
|
|
|
|
|
imei, err = generateIMEI(inventory.ErpCommodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-02-20 09:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
// 将拆分后的商品信息添加到执行响应中
|
|
|
|
|
resp.List = append(resp.List, ExecuteData{
|
|
|
|
|
ErpPurchaseOrderId: inventory.ErpPurchaseOrderId,
|
|
|
|
|
ErpCommodityId: inventory.ErpCommodityId,
|
|
|
|
|
ErpCommodityName: inventory.ErpCommodityName,
|
|
|
|
|
CommoditySerialNumber: inventory.CommoditySerialNumber,
|
|
|
|
|
IMEIType: inventory.IMEIType,
|
|
|
|
|
IMEI: imei,
|
|
|
|
|
Count: 1,
|
|
|
|
|
ImplementationPrice: inventory.ImplementationPrice,
|
|
|
|
|
EmployeePrice: inventory.EmployeePrice,
|
|
|
|
|
})
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
} else if commodityInfo.IMEIType == 1 {
|
2024-02-20 09:59:43 +00:00
|
|
|
|
// 如果是非串码商品,只需拆分为1条数据
|
|
|
|
|
resp.List = append(resp.List, ExecuteData{
|
|
|
|
|
ErpPurchaseOrderId: inventory.ErpPurchaseOrderId,
|
|
|
|
|
ErpCommodityId: inventory.ErpCommodityId,
|
|
|
|
|
ErpCommodityName: inventory.ErpCommodityName,
|
|
|
|
|
CommoditySerialNumber: inventory.CommoditySerialNumber,
|
|
|
|
|
IMEIType: inventory.IMEIType,
|
|
|
|
|
IMEI: "",
|
|
|
|
|
Count: inventory.Count,
|
|
|
|
|
ImplementationPrice: inventory.ImplementationPrice,
|
|
|
|
|
EmployeePrice: inventory.EmployeePrice,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-23 10:06:21 +00:00
|
|
|
|
resp.Total = len(resp.List)
|
|
|
|
|
|
2024-02-20 09:59:43 +00:00
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-23 10:06:21 +00:00
|
|
|
|
// 生成串码
|
2024-02-20 09:59:43 +00:00
|
|
|
|
func generateIMEI(commodityId uint32) (string, error) {
|
|
|
|
|
commodity, err := GetCommodity(commodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return GenerateSerialCode(commodity.ErpCategoryId)
|
|
|
|
|
}
|
2024-02-23 10:06:21 +00:00
|
|
|
|
|
|
|
|
|
// CreateErpPurchaseDemand 创建采购需求单
|
|
|
|
|
func CreateErpPurchaseDemand(req *CreateErpPurchaseDemandReq, sysUser *SysUser) error {
|
|
|
|
|
var demandInfo ErpPurchaseDemand
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var demandRemark ErpPurchaseDemandRemark
|
2024-02-23 10:06:21 +00:00
|
|
|
|
var demandList []ErpPurchaseDemand
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// 采购需求信息
|
2024-02-23 10:06:21 +00:00
|
|
|
|
demandInfo.ErpCommodityId = req.ErpCommodityID
|
|
|
|
|
demandInfo.ErpCommoditySerialNumber = req.ErpCommoditySerialNumber
|
|
|
|
|
demandInfo.ErpCommodityName = req.ErpCommodityName
|
|
|
|
|
demandInfo.State = ErpDemandStateWait // 待采购
|
|
|
|
|
for _, v := range req.List {
|
|
|
|
|
demandInfo.StoreId = v.StoreID
|
|
|
|
|
demandInfo.StoreName = v.StoreName
|
|
|
|
|
demandInfo.Count = v.NeedCount
|
|
|
|
|
demandInfo.MakerId = uint32(sysUser.UserId)
|
|
|
|
|
demandList = append(demandList, demandInfo)
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// 采购需求备注信息
|
|
|
|
|
demandRemark.ErpCommodityId = req.ErpCommodityID
|
|
|
|
|
demandRemark.State = ErpDemandStateWait // 待采购
|
|
|
|
|
demandRemark.MakerId = uint32(sysUser.UserId)
|
|
|
|
|
demandRemark.Remark = req.Remark
|
|
|
|
|
|
2024-02-23 10:06:21 +00:00
|
|
|
|
begin := orm.Eloquent.Begin()
|
|
|
|
|
// 查询当前表格,有记录则更新,没有则插入新记录
|
|
|
|
|
for _, v := range demandList {
|
|
|
|
|
var demand ErpPurchaseDemand
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_demand").Where("erp_commodity_id = ? and store_id = ? and state = 1",
|
|
|
|
|
v.ErpCommodityId, v.StoreId).Find(&demand).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("query erp_purchase_demand err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if demand.StoreId != 0 { // 有记录
|
|
|
|
|
if demand.Count == v.Count { // 值没变则不更新
|
|
|
|
|
continue
|
|
|
|
|
} else {
|
|
|
|
|
err = begin.Model(&ErpPurchaseDemand{}).Where("erp_commodity_id = ? and store_id = ? and state = 1",
|
|
|
|
|
v.ErpCommodityId, v.StoreId).Updates(v).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("update erp_order err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else { // 无记录,新建
|
|
|
|
|
err = begin.Create(&v).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("query erp_purchase_demand err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// 更新备注,先查询有无记录,有则更新,没有则插入新记录
|
|
|
|
|
var demandRemarkInfo ErpPurchaseDemandRemark
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_demand_remark").Where("erp_commodity_id = ? and state = 1",
|
|
|
|
|
req.ErpCommodityID).Find(&demandRemarkInfo).Error
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if err != nil {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
logger.Error("query erp_purchase_demand_remark err:", logger.Field("err", err))
|
2024-03-18 11:53:42 +00:00
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
if demandRemarkInfo.ErpCommodityId != 0 { // 有记录
|
|
|
|
|
if demandRemarkInfo.Remark != req.Remark { // 备注有变化才更新
|
|
|
|
|
err := begin.Model(&ErpPurchaseDemandRemark{}).Where("erp_commodity_id = ? and state = 1",
|
|
|
|
|
req.ErpCommodityID).Updates(demandRemark).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("update erp_purchase_demand_remark err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else { // 无记录,新建
|
|
|
|
|
err = begin.Create(&demandRemark).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("create erp_purchase_demand_remark err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
err = begin.Commit().Error
|
2024-02-23 10:06:21 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("commit err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FinishErpPurchaseDemand 完成采购需求
|
|
|
|
|
func FinishErpPurchaseDemand(req *FinishErpPurchaseDemandReq, sysUser *SysUser) error {
|
|
|
|
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_purchase_demand WHERE erp_commodity_id='%d'",
|
|
|
|
|
req.ErpCommodityID))
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("exist sn err")
|
|
|
|
|
}
|
|
|
|
|
if !exist {
|
|
|
|
|
return fmt.Errorf("商品编号[%d]的商品不在采购需求单中", req.ErpCommodityID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 批量更新状态
|
2024-03-27 10:01:38 +00:00
|
|
|
|
err = orm.Eloquent.Table("erp_purchase_demand").Where("erp_commodity_id=? and state = 1", req.ErpCommodityID).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"state": ErpDemandStateFinish,
|
|
|
|
|
"finish_time": time.Now(),
|
|
|
|
|
"purchaser_id": sysUser.UserId,
|
|
|
|
|
}).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("update err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = orm.Eloquent.Table("erp_purchase_demand_remark").Where("erp_commodity_id=? and state = 1", req.ErpCommodityID).
|
2024-02-23 10:06:21 +00:00
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"state": ErpDemandStateFinish,
|
|
|
|
|
"finish_time": time.Now(),
|
|
|
|
|
"purchaser_id": sysUser.UserId,
|
|
|
|
|
}).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("update err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//// GetErpPurchaseDemand 获取采购需求
|
|
|
|
|
//func GetErpPurchaseDemand(req *GetErpPurchaseDemandReq) (*GetErpPurchaseDemandResp, error) {
|
|
|
|
|
// resp := &GetErpPurchaseDemandResp{
|
|
|
|
|
// PageIndex: req.PageIndex,
|
|
|
|
|
// PageSize: req.PageSize,
|
|
|
|
|
// }
|
|
|
|
|
// page := req.PageIndex - 1
|
|
|
|
|
// if page < 0 {
|
|
|
|
|
// page = 0
|
|
|
|
|
// }
|
|
|
|
|
// if req.PageSize == 0 {
|
|
|
|
|
// req.PageSize = 10
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// qs := orm.Eloquent.Debug().Table("erp_commodity")
|
|
|
|
|
// if req.ErpCategoryId != 0 {
|
|
|
|
|
// qs = qs.Where("erp_category_id=?", req.ErpCategoryId)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// var commodities []ErpCommodity
|
|
|
|
|
// err := qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&commodities).Error
|
|
|
|
|
// if err != nil && err != RecordNotFound {
|
|
|
|
|
// //logger.Error("erp commodity list err:", err)
|
|
|
|
|
// return resp, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 组合数据
|
|
|
|
|
// resp, err = convertToDemandResp(commodities)
|
|
|
|
|
//
|
|
|
|
|
// return resp, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func convertToDemandResp(commodities []ErpCommodity) (*GetErpPurchaseDemandResp, error) {
|
|
|
|
|
// resp := new(GetErpPurchaseDemandResp)
|
|
|
|
|
// var demandData DemandData
|
|
|
|
|
// var demandList []DemandData
|
|
|
|
|
//
|
|
|
|
|
// // 查询所有在线门店信息
|
|
|
|
|
// var stores []Store
|
|
|
|
|
// err := orm.Eloquent.Table("store").Where("is_online = ?", 1).Find(&stores).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("stores err:", logger.Field("err", err))
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// demandData.List = make([]struct {
|
|
|
|
|
// StoreID uint32 `json:"store_id"`
|
|
|
|
|
// StoreName string `json:"store_name"`
|
|
|
|
|
// LastMonthSales uint32 `json:"last_month_sales"`
|
|
|
|
|
// StockCount uint32 `json:"stock_count"`
|
|
|
|
|
// NeedCount uint32 `json:"need_count"`
|
|
|
|
|
// }, len(stores))
|
|
|
|
|
//
|
|
|
|
|
// var totalCount uint32 // 总需采购数量
|
|
|
|
|
//
|
|
|
|
|
// // 遍历所有商品
|
|
|
|
|
// for _, v := range commodities {
|
|
|
|
|
// // 初始化 NeedCount 为 0
|
|
|
|
|
// var totalNeedCount uint32
|
|
|
|
|
//
|
|
|
|
|
// for i, store := range stores {
|
|
|
|
|
// demandData.List[i].StoreID = store.ID
|
|
|
|
|
// demandData.List[i].StoreName = store.Name
|
|
|
|
|
//
|
|
|
|
|
// // 初始化 NeedCount 为 0
|
|
|
|
|
// demandData.List[i].NeedCount = 0
|
|
|
|
|
//
|
|
|
|
|
// // 设置商品相关信息
|
|
|
|
|
// demandData.ErpCommodityID = v.ID
|
|
|
|
|
// demandData.ErpCommoditySerialNumber = v.SerialNumber
|
|
|
|
|
// demandData.ErpCommodityName = v.Name
|
|
|
|
|
// demandData.ErpCategoryID = v.ErpCategoryId
|
|
|
|
|
// demandData.ErpCategoryName = v.ErpCategoryName
|
|
|
|
|
// demandData.RetailPrice = v.RetailPrice
|
|
|
|
|
// // 最近采购价
|
|
|
|
|
// demandData.LastWholesalePrice, _ = GetCommodityLastWholesalePrice(v.ID)
|
|
|
|
|
//
|
|
|
|
|
// // 查询采购需求单
|
|
|
|
|
// var demand []ErpPurchaseDemand
|
|
|
|
|
// err = orm.Eloquent.Table("erp_purchase_demand").Where("erp_commodity_id = ? AND state = 1 AND store_id = ?",
|
|
|
|
|
// v.ID, store.ID).Find(&demand).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("query erp_purchase_demand err:", logger.Field("err", err))
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if len(demand) > 0 {
|
|
|
|
|
// totalNeedCount += demand[0].Count
|
|
|
|
|
// demandData.List[i].NeedCount = demand[0].Count
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 查询某个门店某个商品的库存情况
|
|
|
|
|
// demandData.List[i].StockCount, _ = GetCommodityStockByStoreId(v.ID, store.ID)
|
|
|
|
|
// // 查询某个门店某件商品的上月销售数量
|
|
|
|
|
// demandData.List[i].LastMonthSales, _ = GetCommodityLastMonthSalesByStoreId(v.ID, store.ID)
|
|
|
|
|
// }
|
|
|
|
|
// totalCount += totalNeedCount
|
|
|
|
|
// demandData.TotalCount = totalCount
|
|
|
|
|
// demandData.TotalAmount = float64(totalCount) * demandData.LastWholesalePrice
|
|
|
|
|
// demandList = append(demandList, demandData)
|
|
|
|
|
// }
|
|
|
|
|
// resp.List = demandList
|
|
|
|
|
//
|
|
|
|
|
// return resp, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetCommodityStockByStoreId 查询某个门店某个商品的库存情况
|
|
|
|
|
//func GetCommodityStockByStoreId(commodityId, storeId uint32) (uint32, error) {
|
|
|
|
|
// var count int64
|
|
|
|
|
// err := orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and store_id = ? and state = 1",
|
|
|
|
|
// commodityId, storeId).Count(&count).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("GetCommodityStockByStoreId count err:", logger.Field("err", err))
|
|
|
|
|
// return 0, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return uint32(count), nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetCommodityLastMonthSalesByStoreId 查询某个门店某件商品的上月销售数量
|
|
|
|
|
//func GetCommodityLastMonthSalesByStoreId(commodityId, storeId uint32) (uint32, error) {
|
|
|
|
|
// var lastMonthSales uint32
|
|
|
|
|
//
|
|
|
|
|
// // 获取当前时间
|
|
|
|
|
// now := time.Now()
|
|
|
|
|
// year, month, _ := now.Date()
|
|
|
|
|
// firstDay := time.Date(year, month-1, 1, 0, 0, 0, 0, now.Location())
|
|
|
|
|
// lastDay := firstDay.AddDate(0, 1, -1)
|
|
|
|
|
//
|
|
|
|
|
// // 执行查询
|
|
|
|
|
// err := orm.Eloquent.Model(&ErpOrderCommodity{}).
|
|
|
|
|
// Joins("JOIN erp_order ON erp_order_commodity.erp_order_id = erp_order.id").
|
|
|
|
|
// Select("SUM(erp_order_commodity.count) AS last_month_sales").
|
|
|
|
|
// Where("erp_order.pay_status = ? AND erp_order_commodity.erp_commodity_id = ? AND erp_order.store_id = ? "+
|
|
|
|
|
// "AND erp_order_commodity.created_at BETWEEN ? AND ?",
|
|
|
|
|
// HavePaid, commodityId, storeId, firstDay, lastDay).
|
|
|
|
|
// Scan(&lastMonthSales).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("GetCommodityLastMonthSalesByStoreId err:", logger.Field("err", err))
|
|
|
|
|
// return 0, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return lastMonthSales, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetCommodityLastWholesalePrice 查询某个商品的最近采购价
|
|
|
|
|
//func GetCommodityLastWholesalePrice(commodityId uint32) (float64, error) {
|
|
|
|
|
// var implementationPrice float64
|
|
|
|
|
//
|
|
|
|
|
// // 执行查询
|
|
|
|
|
// err := orm.Eloquent.Table("erp_purchase_inventory").
|
|
|
|
|
// Select("implementation_price").
|
|
|
|
|
// Where("erp_commodity_id = ? AND purchase_type = ?", 167, "procure").
|
|
|
|
|
// Order("created_at DESC").
|
|
|
|
|
// Limit(1).
|
|
|
|
|
// Scan(&implementationPrice).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("GetCommodityLastMonthSalesByStoreId err:", logger.Field("err", err))
|
|
|
|
|
// return 0, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return implementationPrice, nil
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
// 222222222
|
|
|
|
|
//// GetErpPurchaseDemand 获取采购需求
|
|
|
|
|
//func GetErpPurchaseDemand(req *GetErpPurchaseDemandReq) (*GetErpPurchaseDemandResp, error) {
|
|
|
|
|
// resp := &GetErpPurchaseDemandResp{
|
|
|
|
|
// PageIndex: req.PageIndex,
|
|
|
|
|
// PageSize: req.PageSize,
|
|
|
|
|
// }
|
|
|
|
|
// page := req.PageIndex - 1
|
|
|
|
|
// if page < 0 {
|
|
|
|
|
// page = 0
|
|
|
|
|
// }
|
|
|
|
|
// if req.PageSize == 0 {
|
|
|
|
|
// req.PageSize = 10
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// qs := orm.Eloquent.Debug().Table("erp_commodity")
|
|
|
|
|
// if req.ErpCategoryId != 0 {
|
|
|
|
|
// qs = qs.Where("erp_category_id=?", req.ErpCategoryId)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// var commodities []ErpCommodity
|
|
|
|
|
// err := qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&commodities).Error
|
|
|
|
|
// if err != nil && err != RecordNotFound {
|
|
|
|
|
// return resp, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 批量查询门店信息
|
|
|
|
|
// stores, err := GetOnlineStores()
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 批量查询商品信息
|
|
|
|
|
// demandDataList := make([]DemandData, 0, len(commodities))
|
|
|
|
|
// for _, v := range commodities {
|
|
|
|
|
// demandData, err := convertToDemandData(v, stores)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
// demandDataList = append(demandDataList, demandData)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// resp.List = demandDataList
|
|
|
|
|
//
|
|
|
|
|
// return resp, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// convertToDemandData 将商品转换为采购需求数据
|
|
|
|
|
//func convertToDemandData(commodity ErpCommodity, stores []Store) (DemandData, error) {
|
|
|
|
|
// demandData := DemandData{
|
|
|
|
|
// ErpCommodityID: commodity.ID,
|
|
|
|
|
// ErpCommoditySerialNumber: commodity.SerialNumber,
|
|
|
|
|
// ErpCommodityName: commodity.Name,
|
|
|
|
|
// ErpCategoryID: commodity.ErpCategoryId,
|
|
|
|
|
// ErpCategoryName: commodity.ErpCategoryName,
|
|
|
|
|
// RetailPrice: commodity.RetailPrice,
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 批量查询最近采购价
|
|
|
|
|
// lastWholesalePrices, err := GetCommodityLastWholesalePrices(commodity.ID)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return DemandData{}, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// for i, store := range stores {
|
|
|
|
|
// demandData.List = append(demandData.List, struct {
|
|
|
|
|
// StoreID uint32 `json:"store_id"`
|
|
|
|
|
// StoreName string `json:"store_name"`
|
|
|
|
|
// LastMonthSales uint32 `json:"last_month_sales"`
|
|
|
|
|
// StockCount uint32 `json:"stock_count"`
|
|
|
|
|
// NeedCount uint32 `json:"need_count"`
|
|
|
|
|
// }{
|
|
|
|
|
// StoreID: store.ID,
|
|
|
|
|
// StoreName: store.Name,
|
|
|
|
|
// })
|
|
|
|
|
//
|
|
|
|
|
// // 批量查询库存情况
|
|
|
|
|
// stockCounts, err := GetCommodityStocksByStoreID(commodity.ID, store.ID)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return DemandData{}, err
|
|
|
|
|
// }
|
|
|
|
|
// demandData.List[i].StockCount = stockCounts[store.ID]
|
|
|
|
|
//
|
|
|
|
|
// // 批量查询上月销售数量
|
|
|
|
|
// lastMonthSales, err := GetCommodityLastMonthSales(commodity.ID, store.ID)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return DemandData{}, err
|
|
|
|
|
// }
|
|
|
|
|
// demandData.List[i].LastMonthSales = lastMonthSales
|
|
|
|
|
//
|
|
|
|
|
// // 设置最近采购价
|
|
|
|
|
// demandData.LastWholesalePrice = lastWholesalePrices[commodity.ID]
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return demandData, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetCommodityLastWholesalePrices 批量查询商品的最近采购价
|
|
|
|
|
//func GetCommodityLastWholesalePrices(commodityID uint32) (map[uint32]float64, error) {
|
|
|
|
|
// // 查询最近采购价
|
|
|
|
|
// var prices []struct {
|
|
|
|
|
// CommodityID uint32
|
|
|
|
|
// Price float64
|
|
|
|
|
// }
|
|
|
|
|
// err := orm.Eloquent.Table("erp_purchase_inventory").
|
|
|
|
|
// Select("erp_commodity_id, implementation_price AS price").
|
|
|
|
|
// Where("erp_commodity_id IN (?) AND purchase_type = ?", commodityID, "procure").
|
|
|
|
|
// Group("erp_commodity_id").
|
|
|
|
|
// Order("created_at DESC").
|
|
|
|
|
// Find(&prices).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 构建结果
|
|
|
|
|
// result := make(map[uint32]float64)
|
|
|
|
|
// for _, p := range prices {
|
|
|
|
|
// result[p.CommodityID] = p.Price
|
|
|
|
|
// }
|
|
|
|
|
// return result, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetCommodityStocksByStoreID 批量查询商品的库存情况
|
|
|
|
|
//func GetCommodityStocksByStoreID(commodityID, storeID uint32) (map[uint32]uint32, error) {
|
|
|
|
|
// // 查询库存情况
|
|
|
|
|
// var stocks []struct {
|
|
|
|
|
// StoreID uint32
|
|
|
|
|
// CommodityID uint32
|
|
|
|
|
// StockCount uint32
|
|
|
|
|
// }
|
|
|
|
|
// err := orm.Eloquent.Table("erp_stock_commodity").
|
|
|
|
|
// Select("store_id, erp_commodity_id, COUNT(*) AS stock_count").
|
|
|
|
|
// Where("erp_commodity_id IN (?) AND store_id = ? AND state = 1", commodityID, storeID).
|
|
|
|
|
// Group("store_id, erp_commodity_id").
|
|
|
|
|
// Find(&stocks).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 构建结果
|
|
|
|
|
// result := make(map[uint32]uint32)
|
|
|
|
|
// for _, s := range stocks {
|
|
|
|
|
// result[s.StoreID] = s.StockCount
|
|
|
|
|
// }
|
|
|
|
|
// return result, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetCommodityLastMonthSales 批量查询商品的上月销售数量
|
|
|
|
|
//func GetCommodityLastMonthSales(commodityID, storeID uint32) (uint32, error) {
|
|
|
|
|
// // 获取上个月的时间范围
|
|
|
|
|
// firstDay, lastDay := GetLastMonthRange()
|
|
|
|
|
//
|
|
|
|
|
// // 查询上月销售数量
|
|
|
|
|
// var lastMonthSales struct {
|
|
|
|
|
// Sales uint32
|
|
|
|
|
// }
|
|
|
|
|
// err := orm.Eloquent.Table("erp_order_commodity").
|
|
|
|
|
// Joins("JOIN erp_order ON erp_order_commodity.erp_order_id = erp_order.id").
|
|
|
|
|
// Where("erp_order.pay_status = ? AND erp_order_commodity.erp_commodity_id = ? AND erp_order.store_id = ? "+
|
|
|
|
|
// "AND erp_order_commodity.created_at BETWEEN ? AND ?",
|
|
|
|
|
// HavePaid, commodityID, storeID, firstDay, lastDay).
|
|
|
|
|
// Select("SUM(erp_order_commodity.count) AS sales").
|
|
|
|
|
// Scan(&lastMonthSales).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return 0, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return lastMonthSales.Sales, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetLastMonthRange 获取上个月的时间范围
|
|
|
|
|
//func GetLastMonthRange() (time.Time, time.Time) {
|
|
|
|
|
// now := time.Now()
|
|
|
|
|
// year, month, _ := now.Date()
|
|
|
|
|
// firstDay := time.Date(year, month-1, 1, 0, 0, 0, 0, now.Location())
|
|
|
|
|
// lastDay := firstDay.AddDate(0, 1, -1)
|
|
|
|
|
// return firstDay, lastDay
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetOnlineStores 查询所有在线门店信息
|
|
|
|
|
//func GetOnlineStores() ([]Store, error) {
|
|
|
|
|
// var stores []Store
|
|
|
|
|
// err := orm.Eloquent.Table("store").Where("is_online = ?", 1).Find(&stores).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
// return stores, nil
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
// 3333
|
|
|
|
|
//// GetErpPurchaseDemand 获取采购需求
|
|
|
|
|
//func GetErpPurchaseDemand(req *GetErpPurchaseDemandReq) (*GetErpPurchaseDemandResp, error) {
|
|
|
|
|
// resp := &GetErpPurchaseDemandResp{
|
|
|
|
|
// PageIndex: req.PageIndex,
|
|
|
|
|
// PageSize: req.PageSize,
|
|
|
|
|
// }
|
|
|
|
|
// page := req.PageIndex - 1
|
|
|
|
|
// if page < 0 {
|
|
|
|
|
// page = 0
|
|
|
|
|
// }
|
|
|
|
|
// if req.PageSize == 0 {
|
|
|
|
|
// req.PageSize = 10
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// qs := orm.Eloquent.Debug().Table("erp_commodity")
|
|
|
|
|
// if req.ErpCategoryId != 0 {
|
|
|
|
|
// qs = qs.Where("erp_category_id=?", req.ErpCategoryId)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// var commodities []ErpCommodity
|
|
|
|
|
// err := qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&commodities).Error
|
|
|
|
|
// if err != nil && err != RecordNotFound {
|
|
|
|
|
// return resp, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 批量查询门店信息
|
|
|
|
|
// stores, err := GetOnlineStores()
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 并行查询需求数据
|
|
|
|
|
// var wg sync.WaitGroup
|
|
|
|
|
// demandDataList := make([]DemandData, len(commodities))
|
|
|
|
|
//
|
|
|
|
|
// for i, v := range commodities {
|
|
|
|
|
// wg.Add(1)
|
|
|
|
|
// go func(index int, commodity ErpCommodity) {
|
|
|
|
|
// defer wg.Done()
|
|
|
|
|
// demandData, err := convertToDemandData(commodity, stores)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// // Handle error
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
// demandDataList[index] = demandData
|
|
|
|
|
// }(i, v)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// wg.Wait()
|
|
|
|
|
//
|
|
|
|
|
// resp.List = demandDataList
|
|
|
|
|
//
|
|
|
|
|
// return resp, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// convertToDemandData 将商品转换为采购需求数据
|
|
|
|
|
//func convertToDemandData(commodity ErpCommodity, stores []Store) (DemandData, error) {
|
|
|
|
|
// demandData := DemandData{
|
|
|
|
|
// ErpCommodityID: commodity.ID,
|
|
|
|
|
// ErpCommoditySerialNumber: commodity.SerialNumber,
|
|
|
|
|
// ErpCommodityName: commodity.Name,
|
|
|
|
|
// ErpCategoryID: commodity.ErpCategoryId,
|
|
|
|
|
// ErpCategoryName: commodity.ErpCategoryName,
|
|
|
|
|
// RetailPrice: commodity.RetailPrice,
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 并行查询最近采购价、库存情况、上月销售数量
|
|
|
|
|
// var wg sync.WaitGroup
|
|
|
|
|
// wg.Add(3)
|
|
|
|
|
//
|
|
|
|
|
// var lastWholesalePrices map[uint32]float64
|
|
|
|
|
// var stockCounts map[uint32]uint32
|
|
|
|
|
// var lastMonthSales uint32
|
|
|
|
|
// var err1, err2, err3 error
|
|
|
|
|
//
|
|
|
|
|
// go func() {
|
|
|
|
|
// defer wg.Done()
|
|
|
|
|
// lastWholesalePrices, err1 = GetCommodityLastWholesalePrices(commodity.ID)
|
|
|
|
|
// }()
|
|
|
|
|
//
|
|
|
|
|
// go func() {
|
|
|
|
|
// defer wg.Done()
|
|
|
|
|
// stockCounts, err2 = GetCommodityStocksByStoreID(commodity.ID, stores)
|
|
|
|
|
// }()
|
|
|
|
|
//
|
|
|
|
|
// go func() {
|
|
|
|
|
// defer wg.Done()
|
|
|
|
|
// lastMonthSales, err3 = GetCommodityLastMonthSales(commodity.ID, stores)
|
|
|
|
|
// }()
|
|
|
|
|
//
|
|
|
|
|
// wg.Wait()
|
|
|
|
|
//
|
|
|
|
|
// if err1 != nil || err2 != nil || err3 != nil {
|
|
|
|
|
// // Handle error
|
|
|
|
|
// return DemandData{}, err1
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 构建需求数据
|
|
|
|
|
// demandData.List = make([]struct {
|
|
|
|
|
// StoreID uint32 `json:"store_id"`
|
|
|
|
|
// StoreName string `json:"store_name"`
|
|
|
|
|
// LastMonthSales uint32 `json:"last_month_sales"`
|
|
|
|
|
// StockCount uint32 `json:"stock_count"`
|
|
|
|
|
// NeedCount uint32 `json:"need_count"`
|
|
|
|
|
// }, len(stores))
|
|
|
|
|
//
|
|
|
|
|
// for i, store := range stores {
|
|
|
|
|
// demandData.List[i].StoreID = store.ID
|
|
|
|
|
// demandData.List[i].StoreName = store.Name
|
|
|
|
|
//
|
|
|
|
|
// demandData.List[i].StockCount = stockCounts[store.ID]
|
|
|
|
|
// demandData.List[i].LastMonthSales = lastMonthSales
|
|
|
|
|
//
|
|
|
|
|
// // 设置最近采购价
|
|
|
|
|
// demandData.LastWholesalePrice = lastWholesalePrices[commodity.ID]
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return demandData, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetCommodityLastWholesalePrices 批量查询商品的最近采购价
|
|
|
|
|
//func GetCommodityLastWholesalePrices(commodityID uint32) (map[uint32]float64, error) {
|
|
|
|
|
// // 查询最近采购价
|
|
|
|
|
// var prices []struct {
|
|
|
|
|
// CommodityID uint32
|
|
|
|
|
// Price float64
|
|
|
|
|
// }
|
|
|
|
|
// err := orm.Eloquent.Table("erp_purchase_inventory").
|
|
|
|
|
// Select("erp_commodity_id, implementation_price AS price").
|
|
|
|
|
// Where("erp_commodity_id IN (?) AND purchase_type = ?", commodityID, "procure").
|
|
|
|
|
// Group("erp_commodity_id").
|
|
|
|
|
// Order("created_at DESC").
|
|
|
|
|
// Find(&prices).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 构建结果
|
|
|
|
|
// result := make(map[uint32]float64)
|
|
|
|
|
// for _, p := range prices {
|
|
|
|
|
// result[p.CommodityID] = p.Price
|
|
|
|
|
// }
|
|
|
|
|
// return result, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetCommodityStocksByStoreID 批量查询商品的库存情况
|
|
|
|
|
//func GetCommodityStocksByStoreID(commodityID uint32, stores []Store) (map[uint32]uint32, error) {
|
|
|
|
|
// // 并行查询库存情况
|
|
|
|
|
// var wg sync.WaitGroup
|
|
|
|
|
// wg.Add(len(stores))
|
|
|
|
|
//
|
|
|
|
|
// result := make(map[uint32]uint32)
|
|
|
|
|
//
|
|
|
|
|
// for _, store := range stores {
|
|
|
|
|
// go func(storeID uint32) {
|
|
|
|
|
// defer wg.Done()
|
|
|
|
|
// // 查询库存情况
|
|
|
|
|
// var stockCount int64
|
|
|
|
|
// err := orm.Eloquent.Table("erp_stock_commodity").
|
|
|
|
|
// Where("erp_commodity_id = ? AND store_id = ? AND state = 1", commodityID, storeID).
|
|
|
|
|
// Count(&stockCount).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// // Handle error
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
// result[storeID] = uint32(stockCount)
|
|
|
|
|
// }(store.ID)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// wg.Wait()
|
|
|
|
|
//
|
|
|
|
|
// return result, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetCommodityLastMonthSales 批量查询商品的上月销售数量
|
|
|
|
|
//func GetCommodityLastMonthSales(commodityID uint32, stores []Store) (uint32, error) {
|
|
|
|
|
// // 获取上个月的时间范围
|
|
|
|
|
// firstDay, lastDay := GetLastMonthRange()
|
|
|
|
|
//
|
|
|
|
|
// // 并行查询上月销售数量
|
|
|
|
|
// var wg sync.WaitGroup
|
|
|
|
|
// wg.Add(len(stores))
|
|
|
|
|
//
|
|
|
|
|
// var totalSales uint32
|
|
|
|
|
// var mu sync.Mutex // 用于保护 totalSales 的并发访问
|
|
|
|
|
//
|
|
|
|
|
// for _, store := range stores {
|
|
|
|
|
// go func(storeID uint32) {
|
|
|
|
|
// defer wg.Done()
|
|
|
|
|
// // 查询上月销售数量
|
|
|
|
|
// var sales uint32
|
|
|
|
|
// err := orm.Eloquent.Table("erp_order_commodity").
|
|
|
|
|
// Joins("JOIN erp_order ON erp_order_commodity.erp_order_id = erp_order.id").
|
|
|
|
|
// Where("erp_order.pay_status = ? AND erp_order_commodity.erp_commodity_id = ? AND erp_order.store_id = ? "+
|
|
|
|
|
// "AND erp_order_commodity.created_at BETWEEN ? AND ?",
|
|
|
|
|
// HavePaid, commodityID, storeID, firstDay, lastDay).
|
|
|
|
|
// Select("SUM(erp_order_commodity.count) AS sales").
|
|
|
|
|
// Scan(&sales).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// // Handle error
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 累加销售数量
|
|
|
|
|
// mu.Lock()
|
|
|
|
|
// totalSales += sales
|
|
|
|
|
// mu.Unlock()
|
|
|
|
|
// }(store.ID)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// wg.Wait()
|
|
|
|
|
//
|
|
|
|
|
// return totalSales, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetLastMonthRange 获取上个月的时间范围
|
|
|
|
|
//func GetLastMonthRange() (time.Time, time.Time) {
|
|
|
|
|
// now := time.Now()
|
|
|
|
|
// year, month, _ := now.Date()
|
|
|
|
|
// firstDay := time.Date(year, month-1, 1, 0, 0, 0, 0, now.Location())
|
|
|
|
|
// lastDay := firstDay.AddDate(0, 1, -1)
|
|
|
|
|
// return firstDay, lastDay
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// GetOnlineStores 查询所有在线门店信息
|
|
|
|
|
//func GetOnlineStores() ([]Store, error) {
|
|
|
|
|
// var stores []Store
|
|
|
|
|
// err := orm.Eloquent.Table("store").Where("is_online = ?", 1).Find(&stores).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
// return stores, nil
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
// GetErpPurchaseDemand 获取采购需求
|
|
|
|
|
func GetErpPurchaseDemand(req *GetErpPurchaseDemandReq) (*GetErpPurchaseDemandResp, error) {
|
2024-02-26 10:18:23 +00:00
|
|
|
|
var err error
|
|
|
|
|
resp := new(GetErpPurchaseDemandResp)
|
|
|
|
|
if req.HideFlag == "ON" { // 隐藏无采购需求的商品
|
|
|
|
|
resp, err = getErpPurchaseDemandHide(req)
|
|
|
|
|
} else { // 展示所有
|
|
|
|
|
resp, err = getErpPurchaseDemandAll(req)
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 展示所有采购需求
|
|
|
|
|
func getErpPurchaseDemandAll(req *GetErpPurchaseDemandReq) (*GetErpPurchaseDemandResp, error) {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
page := req.PageIndex - 1
|
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if req.PageSize == 0 {
|
|
|
|
|
req.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp := &GetErpPurchaseDemandResp{
|
|
|
|
|
PageIndex: page + 1,
|
|
|
|
|
PageSize: req.PageSize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qs := orm.Eloquent.Debug().Table("erp_commodity")
|
|
|
|
|
if req.ErpCategoryId != 0 {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
categoryInfo, err := GetErpCategory(req.ErpCategoryId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("serial_number like ?", categoryInfo.Number+"%")
|
2024-02-23 10:06:21 +00:00
|
|
|
|
}
|
2024-02-26 10:18:23 +00:00
|
|
|
|
if req.ErpCommoditySerialNumber != "" {
|
|
|
|
|
qs = qs.Where("serial_number=?", req.ErpCommoditySerialNumber)
|
|
|
|
|
}
|
|
|
|
|
if req.ErpCommodityName != "" {
|
|
|
|
|
qs = qs.Where("name=?", req.ErpCommodityName)
|
|
|
|
|
}
|
2024-02-23 10:06:21 +00:00
|
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
|
if err := qs.Count(&count).Error; err != nil {
|
|
|
|
|
logger.Error("count err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var commodities []ErpCommodity
|
2024-02-26 10:18:23 +00:00
|
|
|
|
if req.IsExport == 1 { // 导出excel
|
|
|
|
|
err := qs.Order("id DESC").Find(&commodities).Error
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
err := qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&commodities).Error
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
2024-02-23 10:06:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 批量查询门店信息
|
|
|
|
|
stores, err := GetOnlineStores()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 并行查询需求数据
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
demandDataList := make([]DemandData, len(commodities))
|
|
|
|
|
|
|
|
|
|
for i, v := range commodities {
|
|
|
|
|
wg.Add(1)
|
|
|
|
|
go func(index int, commodity ErpCommodity) {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
demandData, err := convertToDemandData(commodity, stores)
|
|
|
|
|
if err != nil {
|
|
|
|
|
// Handle error
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
demandDataList[index] = demandData
|
|
|
|
|
}(i, v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
2024-02-26 10:18:23 +00:00
|
|
|
|
if req.IsExport == 1 { // 导出excel
|
|
|
|
|
if len(demandDataList) == 0 {
|
|
|
|
|
return nil, errors.New("未查询到数据")
|
|
|
|
|
}
|
|
|
|
|
resp.ExportUrl, err = demandDataExport(demandDataList)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
resp.List = demandDataList
|
|
|
|
|
resp.Total = count
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 隐藏无采购需求的商品
|
|
|
|
|
func getErpPurchaseDemandHide(req *GetErpPurchaseDemandReq) (*GetErpPurchaseDemandResp, error) {
|
|
|
|
|
page := req.PageIndex - 1
|
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if req.PageSize == 0 {
|
|
|
|
|
req.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp := &GetErpPurchaseDemandResp{
|
|
|
|
|
PageIndex: page + 1,
|
|
|
|
|
PageSize: req.PageSize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购需求单信息,筛选出有采购需求的商品id
|
|
|
|
|
var demand []ErpPurchaseDemand
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_demand").
|
|
|
|
|
Where("state = 1").Find(&demand).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
// 用 map 存储已经出现过的 ErpCommodityId
|
|
|
|
|
commodityIds := make(map[uint32]bool)
|
|
|
|
|
var uniqueCommodityIds []uint32
|
|
|
|
|
|
|
|
|
|
for _, d := range demand {
|
|
|
|
|
if _, ok := commodityIds[d.ErpCommodityId]; !ok {
|
|
|
|
|
commodityIds[d.ErpCommodityId] = true
|
|
|
|
|
uniqueCommodityIds = append(uniqueCommodityIds, d.ErpCommodityId)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询商品信息
|
|
|
|
|
qs := orm.Eloquent.Debug().Table("erp_commodity")
|
|
|
|
|
if req.ErpCategoryId != 0 {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
//qs = qs.Where("erp_category_id=?", req.ErpCategoryId)
|
|
|
|
|
categoryInfo, err := GetErpCategory(req.ErpCategoryId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("serial_number like ?", categoryInfo.Number+"%")
|
2024-02-26 10:18:23 +00:00
|
|
|
|
}
|
|
|
|
|
if req.ErpCommoditySerialNumber != "" {
|
|
|
|
|
qs = qs.Where("serial_number=?", req.ErpCommoditySerialNumber)
|
|
|
|
|
}
|
|
|
|
|
if req.ErpCommodityName != "" {
|
|
|
|
|
qs = qs.Where("name=?", req.ErpCommodityName)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
|
if err := qs.Count(&count).Error; err != nil {
|
|
|
|
|
logger.Error("count err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var commodities []ErpCommodity
|
|
|
|
|
if req.IsExport == 1 { // 导出excel
|
|
|
|
|
err := qs.Order("id DESC").Find(&commodities).Error
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
err := qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&commodities).Error
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 匹配商品id,有则继续查询返回数据,没有则不返回
|
|
|
|
|
var matchedCommodities []ErpCommodity
|
|
|
|
|
for _, c := range commodities {
|
|
|
|
|
for _, uniqueID := range uniqueCommodityIds {
|
|
|
|
|
if c.ID == uniqueID {
|
|
|
|
|
matchedCommodities = append(matchedCommodities, c)
|
|
|
|
|
break // 找到匹配的商品后跳出内层循环,继续下一个商品
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(matchedCommodities) == 0 {
|
|
|
|
|
resp.List = nil
|
|
|
|
|
} else {
|
|
|
|
|
// 批量查询门店信息
|
|
|
|
|
stores, err := GetOnlineStores()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 并行查询需求数据
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
demandDataList := make([]DemandData, len(matchedCommodities))
|
|
|
|
|
|
|
|
|
|
for i, v := range matchedCommodities {
|
|
|
|
|
wg.Add(1)
|
|
|
|
|
go func(index int, commodity ErpCommodity) {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
demandData, err := convertToDemandData(commodity, stores)
|
|
|
|
|
if err != nil {
|
|
|
|
|
// Handle error
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
demandDataList[index] = demandData
|
|
|
|
|
}(i, v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
|
|
|
|
if req.IsExport == 1 { // 导出excel
|
|
|
|
|
if len(demandDataList) == 0 {
|
|
|
|
|
return nil, errors.New("未查询到数据")
|
|
|
|
|
}
|
|
|
|
|
resp.ExportUrl, err = demandDataExport(demandDataList)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
resp.List = demandDataList
|
|
|
|
|
resp.Total = int64(len(matchedCommodities))
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-23 10:06:21 +00:00
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// convertToDemandData 将商品转换为采购需求数据
|
|
|
|
|
func convertToDemandData(commodity ErpCommodity, stores []Store) (DemandData, error) {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// 查询采购商品的备注信息
|
|
|
|
|
var demandRemarkInfo ErpPurchaseDemandRemark
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_demand_remark").Where("erp_commodity_id = ? and state = 1",
|
|
|
|
|
commodity.ID).Find(&demandRemarkInfo).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("query erp_purchase_demand_remark err:", logger.Field("err", err))
|
|
|
|
|
return DemandData{}, err
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-23 10:06:21 +00:00
|
|
|
|
demandData := DemandData{
|
|
|
|
|
ErpCommodityID: commodity.ID,
|
|
|
|
|
ErpCommoditySerialNumber: commodity.SerialNumber,
|
|
|
|
|
ErpCommodityName: commodity.Name,
|
|
|
|
|
ErpCategoryID: commodity.ErpCategoryId,
|
|
|
|
|
ErpCategoryName: commodity.ErpCategoryName,
|
|
|
|
|
RetailPrice: commodity.RetailPrice,
|
2024-03-27 10:01:38 +00:00
|
|
|
|
Remark: demandRemarkInfo.Remark,
|
2024-02-23 10:06:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购需求单
|
|
|
|
|
demands, err := GetCommodityPurchaseDemands(commodity.ID, stores)
|
|
|
|
|
if err != nil {
|
|
|
|
|
// Handle error
|
|
|
|
|
return DemandData{}, err
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
//if len(demands) != 0 {
|
|
|
|
|
// demandData.Remark = demands[0].Remark
|
|
|
|
|
//}
|
2024-02-23 10:06:21 +00:00
|
|
|
|
|
|
|
|
|
// 使用 WaitGroup 进行并行查询
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
wg.Add(3)
|
|
|
|
|
|
|
|
|
|
var lastWholesalePrices map[uint32]float64
|
|
|
|
|
var stockCounts map[uint32]uint32
|
|
|
|
|
var lastMonthSales uint32
|
|
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
lastWholesalePrices, err = GetCommodityLastWholesalePrices(commodity.ID)
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
stockCounts, err = GetCommodityStocksByStoreID(commodity.ID, stores)
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
lastMonthSales, err = GetCommodityLastMonthSales(commodity.ID, stores)
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
if err != nil {
|
|
|
|
|
// Handle error
|
|
|
|
|
return DemandData{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var totalCount uint32 // 总需采购数量
|
|
|
|
|
// 构建需求数据
|
|
|
|
|
demandData.StoreList = make([]struct {
|
|
|
|
|
StoreID uint32 `json:"store_id"`
|
|
|
|
|
StoreName string `json:"store_name"`
|
|
|
|
|
LastMonthSales uint32 `json:"last_month_sales"`
|
|
|
|
|
StockCount uint32 `json:"stock_count"`
|
|
|
|
|
NeedCount uint32 `json:"need_count"`
|
|
|
|
|
}, len(stores))
|
|
|
|
|
|
|
|
|
|
for i, store := range stores {
|
|
|
|
|
demandData.StoreList[i].StoreID = store.ID
|
|
|
|
|
demandData.StoreList[i].StoreName = store.Name
|
|
|
|
|
|
|
|
|
|
demandData.StoreList[i].StockCount = stockCounts[store.ID]
|
|
|
|
|
demandData.StoreList[i].LastMonthSales = lastMonthSales
|
|
|
|
|
|
|
|
|
|
// 设置最近采购价
|
|
|
|
|
demandData.LastWholesalePrice = lastWholesalePrices[commodity.ID]
|
|
|
|
|
|
|
|
|
|
// 设置采购需求量
|
|
|
|
|
for _, demand := range demands {
|
|
|
|
|
if demand.StoreId == store.ID {
|
|
|
|
|
demandData.StoreList[i].NeedCount = demand.Count
|
|
|
|
|
totalCount += demand.Count
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
demandData.TotalCount = totalCount
|
|
|
|
|
demandData.TotalAmount = float64(totalCount) * demandData.LastWholesalePrice
|
|
|
|
|
|
|
|
|
|
return demandData, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetCommodityPurchaseDemands 查询商品的采购需求单
|
|
|
|
|
func GetCommodityPurchaseDemands(commodityID uint32, stores []Store) ([]ErpPurchaseDemand, error) {
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
var mu sync.Mutex
|
|
|
|
|
var demands []ErpPurchaseDemand
|
|
|
|
|
wg.Add(len(stores))
|
|
|
|
|
|
|
|
|
|
for _, store := range stores {
|
|
|
|
|
go func(storeID uint32) {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
var demand ErpPurchaseDemand
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_demand").
|
|
|
|
|
Where("erp_commodity_id = ? AND state = 1 AND store_id = ?", commodityID, storeID).
|
|
|
|
|
First(&demand).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
// Handle error
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mu.Lock()
|
|
|
|
|
defer mu.Unlock()
|
|
|
|
|
demands = append(demands, demand)
|
|
|
|
|
}(store.ID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
|
|
|
|
return demands, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetCommodityLastWholesalePrices 批量查询商品的最近采购价
|
|
|
|
|
func GetCommodityLastWholesalePrices(commodityID uint32) (map[uint32]float64, error) {
|
|
|
|
|
// 查询最近采购价
|
|
|
|
|
var prices []struct {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
ErpCommodityID uint32
|
|
|
|
|
Price float64
|
2024-02-23 10:06:21 +00:00
|
|
|
|
}
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_inventory").
|
|
|
|
|
Select("erp_commodity_id, implementation_price AS price").
|
|
|
|
|
Where("erp_commodity_id IN (?) AND purchase_type = ?", commodityID, "procure").
|
2024-03-27 10:01:38 +00:00
|
|
|
|
//Group("erp_commodity_id").
|
2024-02-23 10:06:21 +00:00
|
|
|
|
Order("created_at DESC").
|
2024-03-27 10:01:38 +00:00
|
|
|
|
First(&prices).Error
|
2024-02-23 10:06:21 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建结果
|
|
|
|
|
result := make(map[uint32]float64)
|
|
|
|
|
for _, p := range prices {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
result[p.ErpCommodityID] = p.Price
|
2024-02-23 10:06:21 +00:00
|
|
|
|
}
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetCommodityStocksByStoreID 批量查询商品的库存情况
|
|
|
|
|
func GetCommodityStocksByStoreID(commodityID uint32, stores []Store) (map[uint32]uint32, error) {
|
|
|
|
|
// 并行查询库存情况
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
wg.Add(len(stores))
|
|
|
|
|
|
|
|
|
|
result := make(map[uint32]uint32)
|
|
|
|
|
|
|
|
|
|
for _, store := range stores {
|
|
|
|
|
go func(storeID uint32) {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
// 查询库存情况
|
|
|
|
|
var stockCount int64
|
|
|
|
|
err := orm.Eloquent.Table("erp_stock_commodity").
|
|
|
|
|
Where("erp_commodity_id = ? AND store_id = ? AND state = 1", commodityID, storeID).
|
|
|
|
|
Count(&stockCount).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
// Handle error
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
result[storeID] = uint32(stockCount)
|
|
|
|
|
}(store.ID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// GetCommodityStockByPurchaseId 查询入库商品实际库存详情处剩余有效数,不包含已出库的数量
|
|
|
|
|
func GetCommodityStockByPurchaseId(serialNumber string, orderId uint32) (uint32, error) {
|
|
|
|
|
var count int64
|
|
|
|
|
err := orm.Eloquent.Table("erp_stock_commodity").Where("original_sn = ? and erp_commodity_id = ? and state = ?",
|
|
|
|
|
serialNumber, orderId, InStock).Count(&count).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return uint32(count), nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-23 10:06:21 +00:00
|
|
|
|
// GetCommodityLastMonthSales 批量查询商品的上月销售数量
|
|
|
|
|
func GetCommodityLastMonthSales(commodityID uint32, stores []Store) (uint32, error) {
|
|
|
|
|
// 获取上个月的时间范围
|
|
|
|
|
firstDay, lastDay := GetLastMonthRange()
|
|
|
|
|
|
|
|
|
|
// 并行查询上月销售数量
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
wg.Add(len(stores))
|
|
|
|
|
|
|
|
|
|
var totalSales uint32
|
|
|
|
|
var mu sync.Mutex // 用于保护 totalSales 的并发访问
|
|
|
|
|
|
|
|
|
|
for _, store := range stores {
|
|
|
|
|
go func(storeID uint32) {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
// 查询上月销售数量
|
|
|
|
|
var sales uint32
|
|
|
|
|
err := orm.Eloquent.Table("erp_order_commodity").
|
|
|
|
|
Joins("JOIN erp_order ON erp_order_commodity.erp_order_id = erp_order.id").
|
|
|
|
|
Where("erp_order.pay_status = ? AND erp_order_commodity.erp_commodity_id = ? AND erp_order.store_id = ? "+
|
|
|
|
|
"AND erp_order_commodity.created_at BETWEEN ? AND ?",
|
|
|
|
|
HavePaid, commodityID, storeID, firstDay, lastDay).
|
|
|
|
|
Select("SUM(erp_order_commodity.count) AS sales").
|
|
|
|
|
Scan(&sales).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
// Handle error
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保护 totalSales 的并发访问
|
|
|
|
|
mu.Lock()
|
|
|
|
|
defer mu.Unlock()
|
|
|
|
|
totalSales += sales
|
|
|
|
|
}(store.ID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
|
|
|
|
return totalSales, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetLastMonthRange 获取上个月的时间范围
|
|
|
|
|
func GetLastMonthRange() (time.Time, time.Time) {
|
|
|
|
|
now := time.Now()
|
|
|
|
|
year, month, _ := now.Date()
|
|
|
|
|
firstDay := time.Date(year, month-1, 1, 0, 0, 0, 0, now.Location())
|
|
|
|
|
lastDay := firstDay.AddDate(0, 1, -1)
|
|
|
|
|
return firstDay, lastDay
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetOnlineStores 查询所有在线门店信息
|
|
|
|
|
func GetOnlineStores() ([]Store, error) {
|
|
|
|
|
var stores []Store
|
|
|
|
|
err := orm.Eloquent.Table("store").Where("is_online = ?", 1).Find(&stores).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return stores, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Result struct {
|
|
|
|
|
TotalCount uint32 `gorm:"column:total_count"`
|
|
|
|
|
AvgImplementationPrice float64 `gorm:"column:avg_implementation_price"`
|
|
|
|
|
TotalAmount float64 `gorm:"column:total_amount"`
|
|
|
|
|
AvgEmployeePrice float64 `gorm:"column:avg_employee_price"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetTotalsAndAveragesByCommodityID 查询执行数量之和、平均执行单价、执行金额之和和平均员工成本价
|
2024-03-16 08:19:12 +00:00
|
|
|
|
func GetTotalsAndAveragesByCommodityID(commodityID, orderID uint32) (Result, error) {
|
2024-02-23 10:06:21 +00:00
|
|
|
|
var result Result
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_inventory").
|
|
|
|
|
Select("SUM(`count`) AS total_count, AVG(`implementation_price`) AS avg_implementation_price, "+
|
|
|
|
|
"SUM(`amount`) AS total_amount, AVG(`employee_price`) AS avg_employee_price").
|
2024-03-16 08:19:12 +00:00
|
|
|
|
Where("erp_commodity_id = ? and erp_purchase_order_id = ?", commodityID, orderID).
|
2024-02-23 10:06:21 +00:00
|
|
|
|
Scan(&result).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return Result{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|
2024-02-26 10:18:23 +00:00
|
|
|
|
|
|
|
|
|
// UpdateRetailPrice 更新指导零售价
|
|
|
|
|
func UpdateRetailPrice(begin *gorm.DB, commodityId, retailPrice uint32) error {
|
|
|
|
|
// 更新商品信息表
|
|
|
|
|
err := begin.Table("erp_commodity").Where("id=?", commodityId).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"retail_price": retailPrice,
|
|
|
|
|
}).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新库存表
|
|
|
|
|
err = begin.Table("erp_stock").Where("erp_commodity_id=?", commodityId).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"retail_price": retailPrice,
|
|
|
|
|
}).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新库存商品表
|
|
|
|
|
err = begin.Table("erp_stock_commodity").Where("erp_commodity_id=? and state not in (2,5)", commodityId).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"retail_price": retailPrice,
|
|
|
|
|
}).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 导出采购需求excel
|
|
|
|
|
func demandDataExport(list []DemandData) (string, error) {
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
fSheet := "Sheet1"
|
|
|
|
|
|
|
|
|
|
url := ExportUrl
|
|
|
|
|
fileName := time.Now().Format(TimeFormat) + "采购需求" + ".xlsx"
|
|
|
|
|
fmt.Println("url fileName:", url+fileName)
|
|
|
|
|
|
|
|
|
|
// 组合标题栏第一行数据
|
|
|
|
|
title1 := []interface{}{"商品编号", "商品名称", "商品分类", "指导零售价", "最近采购价"}
|
|
|
|
|
storeCount := len(list[0].StoreList)
|
|
|
|
|
var mergeCells []string // 存储需要合并的单元格范围
|
|
|
|
|
|
|
|
|
|
for _, v := range list[0].StoreList {
|
|
|
|
|
for i := 0; i < 3; i++ {
|
|
|
|
|
title1 = append(title1, v.StoreName)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i := 0; i < storeCount; i++ {
|
|
|
|
|
// 计算每个商户名称的起始和结束单元格
|
|
|
|
|
startCol, _ := excelize.ColumnNumberToName(6 + i*3) // 从第6列开始,每个商户占3列
|
|
|
|
|
endCol, _ := excelize.ColumnNumberToName(8 + i*3)
|
|
|
|
|
mergeCell := startCol + "1:" + endCol + "1"
|
|
|
|
|
mergeCells = append(mergeCells, mergeCell)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
title1 = append(title1, "需采购总数量")
|
|
|
|
|
title1 = append(title1, "需采购总金额")
|
|
|
|
|
title1 = append(title1, "备注")
|
|
|
|
|
|
|
|
|
|
// 合并单元格
|
|
|
|
|
for _, mergeCell := range mergeCells {
|
|
|
|
|
startCell, endCell := splitMergeCellCoordinates(mergeCell)
|
|
|
|
|
_ = file.MergeCell(fSheet, startCell, endCell)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 组合标题栏第二行数据
|
|
|
|
|
title2 := []interface{}{"商品编号", "商品名称", "商品分类", "指导零售价", "最近采购价"}
|
|
|
|
|
for _, _ = range list[0].StoreList {
|
|
|
|
|
title2 = append(title2, "上月销售数")
|
|
|
|
|
title2 = append(title2, "库存数量")
|
|
|
|
|
title2 = append(title2, "需采购数")
|
|
|
|
|
}
|
|
|
|
|
title2 = append(title2, "需采购总数量")
|
|
|
|
|
title2 = append(title2, "需采购总金额")
|
|
|
|
|
title2 = append(title2, "备注")
|
|
|
|
|
|
|
|
|
|
for i, _ := range title1 {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, 1)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, title1[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i, _ := range title2 {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, 2)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, title2[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var row []interface{}
|
|
|
|
|
nExcelStartRow := 0
|
|
|
|
|
for i := 0; i < len(list); i++ {
|
|
|
|
|
row = []interface{}{
|
|
|
|
|
list[i].ErpCommoditySerialNumber, // 商品编号
|
|
|
|
|
list[i].ErpCommodityName, // 商品名称
|
|
|
|
|
list[i].ErpCategoryName, // 商品分类名称
|
|
|
|
|
list[i].RetailPrice, // 指导零售价
|
|
|
|
|
list[i].LastWholesalePrice, // 最近采购价
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, v := range list[i].StoreList {
|
|
|
|
|
row = append(row, v.LastMonthSales) // 上月销售数
|
|
|
|
|
row = append(row, v.StockCount) // 库存数量
|
|
|
|
|
row = append(row, v.NeedCount) // 需采购数
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
row = append(row, list[i].TotalCount) // 需采购总数量
|
|
|
|
|
row = append(row, list[i].TotalAmount) // 需采购总金额
|
|
|
|
|
row = append(row, list[i].Remark) // 备注
|
|
|
|
|
|
|
|
|
|
for j, _ := range row {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+3)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, row[j])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nExcelStartRow++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 合并 "需采购总数量","需采购总金额" 和 "备注" 列的单元格
|
|
|
|
|
strTotalCountCol, strTotalAmountCol, strRemarkCol := computeExtraColumns("E", storeCount)
|
|
|
|
|
_ = file.MergeCell(fSheet, strTotalCountCol+"1", strTotalCountCol+"2")
|
|
|
|
|
_ = file.MergeCell(fSheet, strTotalAmountCol+"1", strTotalAmountCol+"2")
|
|
|
|
|
_ = file.MergeCell(fSheet, strRemarkCol+"1", strRemarkCol+"2")
|
|
|
|
|
|
|
|
|
|
// 设置所有单元格的样式: 居中、加边框
|
|
|
|
|
style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},
|
|
|
|
|
"border":[{"type":"left","color":"000000","style":1},
|
|
|
|
|
{"type":"top","color":"000000","style":1},
|
|
|
|
|
{"type":"right","color":"000000","style":1},
|
|
|
|
|
{"type":"bottom","color":"000000","style":1}]}`)
|
|
|
|
|
|
|
|
|
|
endRow := fmt.Sprintf(strRemarkCol+"%d", nExcelStartRow+2)
|
|
|
|
|
// 应用样式到整个表格
|
|
|
|
|
_ = file.SetCellStyle("Sheet1", "A1", endRow, style)
|
|
|
|
|
|
|
|
|
|
_ = file.MergeCell(fSheet, "A1", "A2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "B1", "B2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "C1", "C2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "D1", "D2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "E1", "E2")
|
|
|
|
|
|
|
|
|
|
fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
|
|
|
|
|
if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
return url + fileName, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据合并单元格的字符串获取左上角和右下角的坐标
|
|
|
|
|
func splitMergeCellCoordinates(cell string) (string, string) {
|
|
|
|
|
split := strings.Split(cell, ":")
|
|
|
|
|
if len(split) != 2 {
|
|
|
|
|
return "", ""
|
|
|
|
|
}
|
|
|
|
|
return split[0], split[1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算 "需采购总数量","需采购总金额" 和 "备注" 列的坐标字符串
|
|
|
|
|
func computeExtraColumns(startCol string, storeCount int) (string, string, string) {
|
|
|
|
|
// "需采购总数量" 列在商户列表结束后的下一列
|
|
|
|
|
totalCountCol := convertColumnToLetters(convertLettersToColumn(startCol) + storeCount*3 + 1)
|
|
|
|
|
|
|
|
|
|
// "需采购总金额" 列在 "需采购总数量" 列的下一列
|
|
|
|
|
totalAmountCol := convertColumnToLetters(convertLettersToColumn(totalCountCol) + 1)
|
|
|
|
|
|
|
|
|
|
// "备注" 列在 "需采购总金额" 列的下一列
|
|
|
|
|
remarkCol := convertColumnToLetters(convertLettersToColumn(totalAmountCol) + 1)
|
|
|
|
|
|
|
|
|
|
return totalCountCol, totalAmountCol, remarkCol
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将列号转换为字母
|
|
|
|
|
func convertColumnToLetters(column int) string {
|
|
|
|
|
var result string
|
|
|
|
|
for column > 0 {
|
|
|
|
|
column--
|
|
|
|
|
result = string('A'+column%26) + result
|
|
|
|
|
column /= 26
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将字母转换为列号
|
|
|
|
|
func convertLettersToColumn(letters string) int {
|
|
|
|
|
result := 0
|
|
|
|
|
for _, letter := range letters {
|
|
|
|
|
result *= 26
|
|
|
|
|
result += int(letter) - 'A' + 1
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|
2024-03-06 02:07:55 +00:00
|
|
|
|
|
|
|
|
|
// GetReportByOrder 查询采购报表(按单)
|
|
|
|
|
func GetReportByOrder(req *ErpPurchaseReportByOrderReq) (*ErpPurchaseReportByOrderResp, error) {
|
|
|
|
|
var err error
|
|
|
|
|
resp := new(ErpPurchaseReportByOrderResp)
|
|
|
|
|
if req.ErpCommodityName != "" || req.ErpCategoryID != 0 { // 商品名称、商品分类不为空
|
|
|
|
|
// 先筛选商品入库信息表,然后再补充采购订单信息
|
|
|
|
|
resp, err = getReportByOrderFromCommodityOrCategory(req)
|
|
|
|
|
} else {
|
|
|
|
|
// 先筛选采购订单表,再补充商品入库信息
|
|
|
|
|
resp, err = getReportByOrderFromCommon(req)
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购报表(按单):先筛选商品入库信息表,然后再补充采购订单信息
|
|
|
|
|
func getReportByOrderFromCommodityOrCategory(req *ErpPurchaseReportByOrderReq) (*ErpPurchaseReportByOrderResp, error) {
|
|
|
|
|
page := req.PageIndex - 1
|
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if req.PageSize == 0 {
|
|
|
|
|
req.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
resp := &ErpPurchaseReportByOrderResp{
|
2024-03-16 08:19:12 +00:00
|
|
|
|
PageIndex: page + 1,
|
2024-03-06 02:07:55 +00:00
|
|
|
|
PageSize: req.PageSize,
|
|
|
|
|
}
|
|
|
|
|
qs := orm.Eloquent.Table("erp_purchase_inventory")
|
|
|
|
|
if req.ErpCommodityName != "" {
|
|
|
|
|
qs = qs.Where("erp_commodity_name=?", req.ErpCommodityName)
|
|
|
|
|
}
|
|
|
|
|
if req.ErpCategoryID != 0 {
|
|
|
|
|
qs = qs.Where("erp_category_id=?", req.ErpCategoryID)
|
|
|
|
|
}
|
2024-03-18 11:53:42 +00:00
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
var inventoryList []ErpPurchaseInventory
|
|
|
|
|
var err error
|
|
|
|
|
if req.IsExport == 1 { // 导出excel
|
|
|
|
|
err = qs.Order("id DESC").Find(&inventoryList).Error
|
|
|
|
|
} else {
|
|
|
|
|
err = qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&inventoryList).Error
|
|
|
|
|
}
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
logger.Error("getReportByOrderFromCommodityOrCategory erp_purchase_inventory err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建一个 map,用于存储不同的 ErpCommodityId
|
|
|
|
|
commodityMap := make(map[uint32]uint32)
|
|
|
|
|
|
|
|
|
|
// 遍历 inventoryList,将不同的 ErpCommodityId 存入 map 中
|
|
|
|
|
for _, inventory := range inventoryList {
|
|
|
|
|
commodityMap[inventory.ErpCommodityId] = inventory.ErpPurchaseOrderId
|
|
|
|
|
}
|
|
|
|
|
// 计算不同的 ErpCommodityId 的数量
|
|
|
|
|
differentCommodityCount := len(commodityMap)
|
|
|
|
|
|
|
|
|
|
var reportOrderDataList []ReportByOrderData
|
|
|
|
|
var nTotalAmount float64
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var nTotalCount int32
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// 查询采购订单信息
|
|
|
|
|
for _, v := range commodityMap {
|
|
|
|
|
var purchaseOrder ErpPurchaseOrder
|
|
|
|
|
var commodityList []ErpPurchaseCommodityData
|
2024-03-18 11:53:42 +00:00
|
|
|
|
|
|
|
|
|
query := orm.Eloquent.Table("erp_purchase_order")
|
|
|
|
|
|
|
|
|
|
if len(req.ErpSupplierId) > 0 { // 供应商复选
|
2024-03-27 10:01:38 +00:00
|
|
|
|
query = query.Where("erp_purchase_order.erp_supplier_id IN (?)", req.ErpSupplierId)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
}
|
|
|
|
|
if len(req.StoreId) > 0 { // 门店复选
|
2024-03-27 10:01:38 +00:00
|
|
|
|
query = query.Where("erp_purchase_order.store_id IN (?)", req.StoreId)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = query.Where("id = ?", v).Find(&purchaseOrder).Error
|
2024-03-06 02:07:55 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
var reportByOrderData ReportByOrderData
|
2024-03-18 11:53:42 +00:00
|
|
|
|
reportByOrderData.ErpPurchaseOrderId = purchaseOrder.ID
|
2024-03-06 02:07:55 +00:00
|
|
|
|
reportByOrderData.SerialNumber = purchaseOrder.SerialNumber
|
|
|
|
|
reportByOrderData.PurchaseType = purchaseOrder.PurchaseType
|
|
|
|
|
reportByOrderData.StoreId = purchaseOrder.StoreId
|
|
|
|
|
reportByOrderData.StoreName = purchaseOrder.StoreName
|
|
|
|
|
reportByOrderData.ErpSupplierId = purchaseOrder.ErpSupplierId
|
|
|
|
|
reportByOrderData.ErpSupplierName = purchaseOrder.ErpSupplierName
|
|
|
|
|
reportByOrderData.HandlerId = purchaseOrder.HandlerId
|
|
|
|
|
reportByOrderData.HandlerName = purchaseOrder.HandlerName
|
|
|
|
|
reportByOrderData.MakerTime = purchaseOrder.MakerTime
|
|
|
|
|
reportByOrderData.MakerId = purchaseOrder.MakerId
|
|
|
|
|
reportByOrderData.MakerName = purchaseOrder.MakerName
|
|
|
|
|
reportByOrderData.AuditorId = purchaseOrder.AuditorId
|
|
|
|
|
reportByOrderData.AuditTime = purchaseOrder.AuditTime
|
|
|
|
|
reportByOrderData.AuditorName = purchaseOrder.AuditorName
|
|
|
|
|
reportByOrderData.State = purchaseOrder.State
|
|
|
|
|
reportByOrderData.Remark = purchaseOrder.Remark
|
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if purchaseOrder.MakerTime != nil && purchaseOrder.MakerTime.IsZero() {
|
|
|
|
|
reportByOrderData.MakerTime = nil
|
|
|
|
|
} else {
|
|
|
|
|
reportByOrderData.MakerTime = purchaseOrder.MakerTime
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if purchaseOrder.AuditTime != nil && purchaseOrder.AuditTime.IsZero() {
|
|
|
|
|
reportByOrderData.AuditTime = nil
|
|
|
|
|
} else {
|
|
|
|
|
reportByOrderData.AuditTime = purchaseOrder.AuditTime
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
var nAmount float64
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var nCount int32
|
|
|
|
|
// 使用 map 来组合相同 ErpCommodityId 的数据
|
|
|
|
|
commodityMapInfo := make(map[uint32]ErpPurchaseCommodityData)
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
for _, inventory := range inventoryList {
|
|
|
|
|
if inventory.ErpPurchaseOrderId == purchaseOrder.ID {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var vCount int32
|
|
|
|
|
var vAmount float64
|
|
|
|
|
if inventory.PurchaseType == ErpRejectOrder { // 退货单金额和数量取负值
|
|
|
|
|
vAmount = -inventory.Amount
|
|
|
|
|
vCount = -int32(inventory.Count)
|
|
|
|
|
} else {
|
|
|
|
|
vCount = int32(inventory.Count)
|
|
|
|
|
vAmount = inventory.Amount
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if existingData, ok := commodityMapInfo[inventory.ErpCommodityId]; ok {
|
|
|
|
|
// 如果已经存在相同 ErpCommodityId 的数据,则累加 Amount 和 Count
|
|
|
|
|
existingData.Amount += vAmount
|
|
|
|
|
existingData.Count += vCount
|
|
|
|
|
existingData.Price = existingData.Amount / float64(existingData.Count)
|
|
|
|
|
commodityMapInfo[inventory.ErpCommodityId] = existingData
|
|
|
|
|
} else {
|
|
|
|
|
// 否则,创建新的数据
|
|
|
|
|
commodityMapInfo[inventory.ErpCommodityId] = ErpPurchaseCommodityData{
|
|
|
|
|
CommodityData: CommodityData{
|
|
|
|
|
ErpCommodityId: inventory.ErpCommodityId,
|
|
|
|
|
ErpCommodityName: inventory.ErpCommodityName,
|
|
|
|
|
ErpCategoryID: inventory.ErpCategoryID,
|
|
|
|
|
ErpCategoryName: inventory.ErpCategoryName,
|
|
|
|
|
},
|
|
|
|
|
Amount: vAmount,
|
|
|
|
|
Price: inventory.ImplementationPrice,
|
|
|
|
|
Count: vCount,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 累加总金额和总数量
|
|
|
|
|
nAmount += vAmount
|
|
|
|
|
nCount += vCount
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
|
|
|
|
|
// 将 map 中的值转换为 slice
|
|
|
|
|
for _, data := range commodityMapInfo {
|
|
|
|
|
commodityList = append(commodityList, data)
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
reportByOrderData.CommodityData = commodityList
|
|
|
|
|
reportByOrderData.Amount = nAmount
|
|
|
|
|
reportByOrderData.Count = nCount
|
|
|
|
|
if nCount != 0 {
|
|
|
|
|
reportByOrderData.Price = nAmount / float64(nCount)
|
|
|
|
|
}
|
|
|
|
|
reportOrderDataList = append(reportOrderDataList, reportByOrderData)
|
|
|
|
|
|
|
|
|
|
nTotalAmount += nAmount
|
|
|
|
|
nTotalCount += nCount
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp.Total = differentCommodityCount
|
|
|
|
|
resp.List = reportOrderDataList
|
|
|
|
|
resp.Amount = nTotalAmount
|
|
|
|
|
resp.Count = nTotalCount
|
|
|
|
|
|
|
|
|
|
if req.IsExport == 1 {
|
|
|
|
|
filePath, err := reportByOrderExport(resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
resp = &ErpPurchaseReportByOrderResp{}
|
|
|
|
|
resp.ExportUrl = filePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购报表(按单): 先筛选采购订单表,再补充商品入库信息
|
|
|
|
|
func getReportByOrderFromCommon(req *ErpPurchaseReportByOrderReq) (*ErpPurchaseReportByOrderResp, error) {
|
|
|
|
|
page := req.PageIndex - 1
|
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if req.PageSize == 0 {
|
|
|
|
|
req.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
resp := &ErpPurchaseReportByOrderResp{
|
2024-03-16 08:19:12 +00:00
|
|
|
|
PageIndex: page + 1,
|
2024-03-06 02:07:55 +00:00
|
|
|
|
PageSize: req.PageSize,
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
qs := orm.Eloquent.Table("erp_purchase_order").Where("state != 1") // 未审核订单不展示
|
|
|
|
|
if req.SerialNumber != "" { // 单据编号
|
2024-03-06 02:07:55 +00:00
|
|
|
|
qs = qs.Where("serial_number=?", req.SerialNumber)
|
|
|
|
|
} else {
|
|
|
|
|
if req.PurchaseType != "" { // 采购类型
|
|
|
|
|
qs = qs.Where("purchase_type=?", req.PurchaseType)
|
|
|
|
|
}
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if len(req.ErpSupplierId) > 0 { // 供应商复选
|
|
|
|
|
var supplierIDs []uint32
|
|
|
|
|
for _, supplier := range req.ErpSupplierId {
|
|
|
|
|
supplierIDs = append(supplierIDs, supplier)
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("erp_supplier_id IN (?)", supplierIDs)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if len(req.StoreId) > 0 { // 门店复选
|
|
|
|
|
var storeIDs []uint32
|
|
|
|
|
for _, store := range req.StoreId {
|
|
|
|
|
storeIDs = append(storeIDs, store)
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("store_id IN (?)", storeIDs)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
if req.HandlerId != 0 { // 经手人id
|
|
|
|
|
qs = qs.Where("handler_id=?", req.HandlerId)
|
|
|
|
|
}
|
|
|
|
|
if req.State != 0 { // 订单状态
|
|
|
|
|
qs = qs.Where("state=?", req.State)
|
|
|
|
|
}
|
|
|
|
|
if req.AuditTimeStart != "" { // 审核开始时间
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, req.AuditTimeStart)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("erpPurchaseOrderList err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("audit_time > ?", parse)
|
|
|
|
|
}
|
|
|
|
|
if req.AuditTimeEnd != "" { // 审核结束时间
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, req.AuditTimeEnd)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("erpPurchaseOrderList err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
//parse = parse.AddDate(0, 0, 1)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
qs = qs.Where("audit_time < ?", parse)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
|
err := qs.Count(&count).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("getReportByOrderFromCommon count err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
resp.Total = int(count)
|
|
|
|
|
var orders []ErpPurchaseOrder
|
|
|
|
|
|
|
|
|
|
if req.IsExport == 1 { // 导出excel
|
|
|
|
|
err = qs.Order("id DESC").Find(&orders).Error
|
|
|
|
|
} else {
|
|
|
|
|
err = qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&orders).Error
|
|
|
|
|
}
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
logger.Error("getReportByOrderFromCommon erp_purchase_order err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var reportByOrderDataList []ReportByOrderData
|
|
|
|
|
var nTotalAmount float64
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var nTotalCount int32
|
2024-03-06 02:07:55 +00:00
|
|
|
|
for _, v := range orders {
|
|
|
|
|
var reportByOrderData ReportByOrderData
|
|
|
|
|
var nAmount float64
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var nCount int32
|
2024-03-18 11:53:42 +00:00
|
|
|
|
reportByOrderData.ErpPurchaseOrderId = v.ID
|
2024-03-06 02:07:55 +00:00
|
|
|
|
reportByOrderData.SerialNumber = v.SerialNumber
|
|
|
|
|
reportByOrderData.PurchaseType = v.PurchaseType
|
|
|
|
|
reportByOrderData.StoreId = v.StoreId
|
|
|
|
|
reportByOrderData.StoreName = v.StoreName
|
|
|
|
|
reportByOrderData.ErpSupplierId = v.ErpSupplierId
|
|
|
|
|
reportByOrderData.ErpSupplierName = v.ErpSupplierName
|
|
|
|
|
reportByOrderData.HandlerId = v.HandlerId
|
|
|
|
|
reportByOrderData.HandlerName = v.HandlerName
|
2024-03-18 11:53:42 +00:00
|
|
|
|
//reportByOrderData.MakerTime = v.MakerTime
|
2024-03-06 02:07:55 +00:00
|
|
|
|
reportByOrderData.MakerId = v.MakerId
|
|
|
|
|
reportByOrderData.MakerName = v.MakerName
|
|
|
|
|
reportByOrderData.AuditorId = v.AuditorId
|
2024-03-18 11:53:42 +00:00
|
|
|
|
//reportByOrderData.AuditTime = v.AuditTime
|
2024-03-06 02:07:55 +00:00
|
|
|
|
reportByOrderData.AuditorName = v.AuditorName
|
|
|
|
|
reportByOrderData.State = v.State
|
|
|
|
|
reportByOrderData.Remark = v.Remark
|
2024-03-18 11:53:42 +00:00
|
|
|
|
|
|
|
|
|
if v.MakerTime != nil && v.MakerTime.IsZero() {
|
|
|
|
|
reportByOrderData.MakerTime = nil
|
|
|
|
|
} else {
|
|
|
|
|
reportByOrderData.MakerTime = v.MakerTime
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v.AuditTime != nil && v.AuditTime.IsZero() {
|
|
|
|
|
reportByOrderData.AuditTime = nil
|
|
|
|
|
} else {
|
|
|
|
|
reportByOrderData.AuditTime = v.AuditTime
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
reportByOrderData.CommodityData, nAmount, nCount, err = getOrderInventoryInfo(v.ID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
reportByOrderData.Amount = nAmount
|
|
|
|
|
reportByOrderData.Count = nCount
|
|
|
|
|
if nCount != 0 {
|
|
|
|
|
reportByOrderData.Price = nAmount / float64(nCount)
|
|
|
|
|
}
|
|
|
|
|
reportByOrderDataList = append(reportByOrderDataList, reportByOrderData)
|
|
|
|
|
nTotalAmount += nAmount
|
|
|
|
|
nTotalCount += nCount
|
|
|
|
|
}
|
|
|
|
|
resp.List = reportByOrderDataList
|
|
|
|
|
resp.Amount = nTotalAmount
|
|
|
|
|
resp.Count = nTotalCount
|
|
|
|
|
resp.Total = int(count)
|
|
|
|
|
|
|
|
|
|
if req.IsExport == 1 {
|
|
|
|
|
filePath, err := reportByOrderExport(resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
resp = &ErpPurchaseReportByOrderResp{}
|
|
|
|
|
resp.ExportUrl = filePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购订单的入库信息
|
2024-03-27 10:01:38 +00:00
|
|
|
|
func getOrderInventoryInfo(erpPurchaseOrderId uint32) ([]ErpPurchaseCommodityData, float64, int32, error) {
|
2024-03-06 02:07:55 +00:00
|
|
|
|
var inventoryList []ErpPurchaseInventory
|
2024-03-27 10:01:38 +00:00
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_inventory").
|
|
|
|
|
Where("erp_purchase_order_id = ?", erpPurchaseOrderId).
|
2024-03-06 02:07:55 +00:00
|
|
|
|
Find(&inventoryList).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("getOrderInventoryInfo err:", logger.Field("err", err))
|
|
|
|
|
return nil, 0, 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(inventoryList) == 0 {
|
|
|
|
|
//return nil, 0, 0, errors.New("未查询到采购订单的入库信息")
|
|
|
|
|
return nil, 0, 0, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// 使用 map 来组合相同 ErpCommodityId 的数据
|
|
|
|
|
commodityMap := make(map[uint32]ErpPurchaseCommodityData)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
var nAmount float64
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var nCount int32
|
|
|
|
|
|
|
|
|
|
// 遍历库存列表,组合相同 ErpCommodityId 的数据
|
2024-03-06 02:07:55 +00:00
|
|
|
|
for _, v := range inventoryList {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var vCount int32
|
|
|
|
|
var vAmount float64
|
|
|
|
|
if v.PurchaseType == ErpRejectOrder { // 退货单金额和数量取负值
|
|
|
|
|
vAmount = -v.Amount
|
|
|
|
|
vCount = -int32(v.Count)
|
|
|
|
|
} else {
|
|
|
|
|
vCount = int32(v.Count)
|
|
|
|
|
vAmount = v.Amount
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if existingData, ok := commodityMap[v.ErpCommodityId]; ok {
|
|
|
|
|
// 如果已经存在相同 ErpCommodityId 的数据,则累加 Amount 和 Count
|
|
|
|
|
existingData.Amount += vAmount
|
|
|
|
|
existingData.Count += vCount
|
|
|
|
|
existingData.Price = existingData.Amount / float64(existingData.Count)
|
|
|
|
|
commodityMap[v.ErpCommodityId] = existingData
|
|
|
|
|
} else {
|
|
|
|
|
// 否则,创建新的数据
|
|
|
|
|
commodityMap[v.ErpCommodityId] = ErpPurchaseCommodityData{
|
|
|
|
|
CommodityData: CommodityData{
|
|
|
|
|
ErpCommodityId: v.ErpCommodityId,
|
|
|
|
|
ErpCommodityName: v.ErpCommodityName,
|
|
|
|
|
ErpCategoryID: v.ErpCategoryID,
|
|
|
|
|
ErpCategoryName: v.ErpCategoryName,
|
|
|
|
|
},
|
|
|
|
|
Amount: vAmount,
|
|
|
|
|
Price: v.ImplementationPrice,
|
|
|
|
|
Count: vCount,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 累加总金额和总数量
|
|
|
|
|
nAmount += vAmount
|
|
|
|
|
nCount += vCount
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将 map 中的值转换为 slice
|
|
|
|
|
var resp []ErpPurchaseCommodityData
|
|
|
|
|
for _, data := range commodityMap {
|
|
|
|
|
resp = append(resp, data)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nAmount, nCount, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 导出采购报表(按单)excel
|
|
|
|
|
func reportByOrderExport(req *ErpPurchaseReportByOrderResp) (string, error) {
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
fSheet := "Sheet1"
|
|
|
|
|
|
|
|
|
|
url := ExportUrl
|
|
|
|
|
fileName := time.Now().Format(TimeFormat) + "采购报表(按单)" + ".xlsx"
|
|
|
|
|
fmt.Println("url fileName:", url+fileName)
|
|
|
|
|
|
|
|
|
|
// 组合标题栏数据
|
|
|
|
|
title := []interface{}{"单据编号", "类型", "店铺名称", "备注", "供应商", "经手人", "制单人", "审核时间", "订单状态",
|
|
|
|
|
"商品名称", "商品分类", "已执行金额", "执行单价", "已执行数量"}
|
|
|
|
|
for i, _ := range title {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, 1)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, title[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var row1 []interface{}
|
|
|
|
|
var row2 []interface{}
|
|
|
|
|
nExcelStartRow := 0
|
|
|
|
|
for _, orderData := range req.List {
|
|
|
|
|
var orderType string
|
|
|
|
|
switch orderData.PurchaseType {
|
|
|
|
|
case "procure":
|
|
|
|
|
orderType = "采购入库"
|
|
|
|
|
case "reject":
|
|
|
|
|
orderType = "采购退货"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var orderStatus string
|
|
|
|
|
switch orderData.State { // 1-待审核 2-待入库 3-待退货 4-已完成 5-已终止
|
|
|
|
|
case ErpPurchaseOrderUnAudit:
|
|
|
|
|
orderStatus = "待审核"
|
|
|
|
|
case ErpPurchaseOrderWaitInventory:
|
|
|
|
|
orderStatus = "待入库"
|
|
|
|
|
case ErpPurchaseOrderWaitReject:
|
|
|
|
|
orderStatus = "待退货"
|
|
|
|
|
case ErpPurchaseOrderFinished:
|
|
|
|
|
orderStatus = "已完成"
|
|
|
|
|
case ErpPurchaseOrderEnd:
|
|
|
|
|
orderStatus = "已终止"
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var strTime string
|
|
|
|
|
if orderData.AuditTime != nil {
|
|
|
|
|
strTime = orderData.AuditTime.Format(TimeFormat)
|
|
|
|
|
} else {
|
|
|
|
|
strTime = "--"
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
row1 = []interface{}{
|
2024-03-27 10:01:38 +00:00
|
|
|
|
orderData.SerialNumber, // 单据编号
|
|
|
|
|
orderType, // 类型
|
|
|
|
|
orderData.StoreName, // 店铺名称
|
|
|
|
|
orderData.Remark, // 备注
|
|
|
|
|
orderData.ErpSupplierName, // 供应商
|
|
|
|
|
orderData.HandlerName, // 经手人
|
|
|
|
|
orderData.MakerName, // 制单人
|
|
|
|
|
strTime, // 审核时间
|
|
|
|
|
orderStatus, // 订单状态
|
|
|
|
|
"--", // 商品名称
|
|
|
|
|
"--", // 商品分类
|
|
|
|
|
orderData.Amount, // 已执行金额
|
|
|
|
|
orderData.Price, // 执行单价
|
|
|
|
|
orderData.Count, // 已执行数量
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for j, _ := range row1 {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, row1[j])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nExcelStartRow++
|
|
|
|
|
|
|
|
|
|
for _, commodity := range orderData.CommodityData {
|
|
|
|
|
row2 = []interface{}{
|
|
|
|
|
"", // 单据编号
|
|
|
|
|
"", // 类型
|
|
|
|
|
"", // 店铺名称
|
|
|
|
|
"", // 备注
|
|
|
|
|
"", // 供应商
|
|
|
|
|
"", // 经手人
|
|
|
|
|
"", // 制单人
|
|
|
|
|
"", // 审核时间
|
|
|
|
|
"", // 订单状态
|
|
|
|
|
commodity.ErpCommodityName, // 商品名称
|
|
|
|
|
commodity.ErpCategoryName, // 商品分类
|
|
|
|
|
commodity.Amount, // 已执行金额
|
|
|
|
|
commodity.Price, // 执行单价
|
|
|
|
|
commodity.Count, // 已执行数量
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for j, _ := range row2 {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, row2[j])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nExcelStartRow++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalData := "订单数:" + strconv.FormatInt(int64(req.Total), 10)
|
|
|
|
|
end := []interface{}{totalData, "", "", "", "", "", "", "", "", "", "", req.Amount, "--", req.Count}
|
|
|
|
|
for i, _ := range end {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, end[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置所有单元格的样式: 居中、加边框
|
|
|
|
|
style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},
|
|
|
|
|
"border":[{"type":"left","color":"000000","style":1},
|
|
|
|
|
{"type":"top","color":"000000","style":1},
|
|
|
|
|
{"type":"right","color":"000000","style":1},
|
|
|
|
|
{"type":"bottom","color":"000000","style":1}]}`)
|
|
|
|
|
|
|
|
|
|
//设置单元格高度
|
|
|
|
|
file.SetRowHeight("Sheet1", 1, 20)
|
|
|
|
|
|
|
|
|
|
// 设置单元格大小
|
|
|
|
|
file.SetColWidth("Sheet1", "A", "A", 13)
|
|
|
|
|
file.SetColWidth("Sheet1", "C", "C", 25)
|
|
|
|
|
file.SetColWidth("Sheet1", "H", "H", 20)
|
|
|
|
|
file.SetColWidth("Sheet1", "J", "J", 18)
|
|
|
|
|
|
|
|
|
|
endRow := fmt.Sprintf("N"+"%d", nExcelStartRow+2)
|
|
|
|
|
// 应用样式到整个表格
|
|
|
|
|
_ = file.SetCellStyle("Sheet1", "A1", endRow, style)
|
|
|
|
|
|
|
|
|
|
fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
|
|
|
|
|
if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
return url + fileName, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetReportByCommodity 查询采购报表(按商品)
|
|
|
|
|
func GetReportByCommodity(req *ErpPurchaseReportByCommodityReq) (*ErpPurchaseReportByCommodityResp, error) {
|
|
|
|
|
var err error
|
|
|
|
|
resp := new(ErpPurchaseReportByCommodityResp)
|
|
|
|
|
if req.ErpCommodityName != "" || req.ErpCategoryID != 0 { // 商品名称、商品分类不为空
|
|
|
|
|
// 先筛选商品入库信息表,然后再补充采购订单信息
|
|
|
|
|
resp, err = getReportByCommodityFromCommodityOrCategory(req)
|
|
|
|
|
} else {
|
|
|
|
|
// 先筛选采购订单表,再补充商品入库信息
|
|
|
|
|
resp, err = getReportByCommodityFromCommon(req)
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购报表(按商品):先筛选商品入库信息表,然后再补充采购订单信息
|
|
|
|
|
func getReportByCommodityFromCommodityOrCategory(req *ErpPurchaseReportByCommodityReq) (*ErpPurchaseReportByCommodityResp, error) {
|
|
|
|
|
page := req.PageIndex - 1
|
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if req.PageSize == 0 {
|
|
|
|
|
req.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
resp := &ErpPurchaseReportByCommodityResp{
|
2024-03-16 08:19:12 +00:00
|
|
|
|
PageIndex: page + 1,
|
2024-03-06 02:07:55 +00:00
|
|
|
|
PageSize: req.PageSize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qs := orm.Eloquent.Table("erp_purchase_inventory")
|
|
|
|
|
if req.ErpCommodityName != "" {
|
|
|
|
|
qs = qs.Where("erp_commodity_name=?", req.ErpCommodityName)
|
|
|
|
|
}
|
|
|
|
|
if req.ErpCategoryID != 0 {
|
|
|
|
|
qs = qs.Where("erp_category_id=?", req.ErpCategoryID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
|
err := qs.Count(&count).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("getReportByOrderFromCommodityOrCategory count err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var inventoryList []ErpPurchaseInventory
|
|
|
|
|
if req.IsExport == 1 { // 导出excel
|
|
|
|
|
err = qs.Order("id DESC").Find(&inventoryList).Error
|
|
|
|
|
} else {
|
|
|
|
|
err = qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&inventoryList).Error
|
|
|
|
|
}
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
logger.Error("getReportByOrderFromCommodityOrCategory erp_purchase_inventory err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
commodityIDMap := make(map[uint32]map[uint32]ErpPurchaseInventory)
|
|
|
|
|
// 遍历 inventoryList
|
|
|
|
|
for _, inventory := range inventoryList {
|
|
|
|
|
// 如果该商品id已经在map中,则将该订单id加入到对应的set中
|
|
|
|
|
if ids, ok := commodityIDMap[inventory.ErpCommodityId]; ok {
|
|
|
|
|
ids[inventory.ErpPurchaseOrderId] = inventory
|
|
|
|
|
} else {
|
|
|
|
|
// 如果该商品id不在map中,则创建一个新的map并加入订单id及其对应的 ErpPurchaseInventory
|
|
|
|
|
commodityIDMap[inventory.ErpCommodityId] = map[uint32]ErpPurchaseInventory{
|
|
|
|
|
inventory.ErpPurchaseOrderId: inventory,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
resp.Total = len(commodityIDMap)
|
|
|
|
|
|
|
|
|
|
var reportByCommodityDataList []ReportByCommodityData
|
|
|
|
|
var totalData PurchaseData
|
|
|
|
|
|
|
|
|
|
// 遍历 map 获取去重的 ErpPurchaseOrderId
|
|
|
|
|
for _, orderIdSet := range commodityIDMap {
|
|
|
|
|
var reportByCommodityData ReportByCommodityData
|
|
|
|
|
if len(orderIdSet) != 0 {
|
|
|
|
|
reportByCommodityData.ErpCommodityId = orderIdSet[0].ErpPurchaseCommodityId
|
|
|
|
|
reportByCommodityData.ErpCommodityName = orderIdSet[0].ErpCommodityName
|
|
|
|
|
reportByCommodityData.ErpCategoryID = orderIdSet[0].ErpCategoryID
|
|
|
|
|
reportByCommodityData.ErpCategoryName = orderIdSet[0].ErpCategoryName
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var totalPurchaseData PurchaseData
|
|
|
|
|
var purchaseOrderDataList []ErpCommodityPurchaseOrderData
|
|
|
|
|
for orderId := range orderIdSet {
|
2024-03-18 11:53:42 +00:00
|
|
|
|
purchaseOrderData, err := getPurchaseOrderData(orderId, req)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
purchaseOrderDataList = append(purchaseOrderDataList, purchaseOrderData)
|
|
|
|
|
|
|
|
|
|
totalPurchaseData.PlanCount += purchaseOrderData.PlanCount
|
|
|
|
|
totalPurchaseData.PlanPrice += purchaseOrderData.PlanPrice
|
|
|
|
|
totalPurchaseData.PlanAmount += purchaseOrderData.PlanAmount
|
|
|
|
|
totalPurchaseData.Amount += purchaseOrderData.Amount
|
|
|
|
|
totalPurchaseData.Price += purchaseOrderData.Price
|
|
|
|
|
totalPurchaseData.Count += purchaseOrderData.Count
|
|
|
|
|
totalPurchaseData.NonExecutionAmount += purchaseOrderData.NonExecutionAmount
|
|
|
|
|
totalPurchaseData.NonExecutionCount += purchaseOrderData.NonExecutionCount
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reportByCommodityData.PlanCount = totalPurchaseData.PlanCount
|
|
|
|
|
reportByCommodityData.PlanPrice = totalPurchaseData.PlanPrice
|
|
|
|
|
reportByCommodityData.PlanAmount = totalPurchaseData.PlanAmount
|
|
|
|
|
reportByCommodityData.Amount = totalPurchaseData.Amount
|
|
|
|
|
reportByCommodityData.Price = totalPurchaseData.Price
|
|
|
|
|
reportByCommodityData.Count = totalPurchaseData.Count
|
|
|
|
|
reportByCommodityData.NonExecutionAmount = totalPurchaseData.NonExecutionAmount
|
|
|
|
|
reportByCommodityData.NonExecutionCount = totalPurchaseData.NonExecutionCount
|
|
|
|
|
|
|
|
|
|
totalData.PlanCount += reportByCommodityData.PlanCount
|
|
|
|
|
totalData.PlanAmount += reportByCommodityData.PlanAmount
|
|
|
|
|
totalData.Amount += reportByCommodityData.Amount
|
|
|
|
|
totalData.Count += reportByCommodityData.Count
|
|
|
|
|
totalData.NonExecutionAmount += reportByCommodityData.NonExecutionAmount
|
|
|
|
|
totalData.NonExecutionCount += reportByCommodityData.NonExecutionCount
|
|
|
|
|
|
|
|
|
|
reportByCommodityData.OrderInfo = purchaseOrderDataList
|
|
|
|
|
reportByCommodityDataList = append(reportByCommodityDataList, reportByCommodityData)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp.List = reportByCommodityDataList
|
|
|
|
|
resp.PlanCount = totalData.PlanCount
|
|
|
|
|
resp.PlanAmount = totalData.PlanAmount
|
|
|
|
|
resp.Amount = totalData.Amount
|
|
|
|
|
resp.Count = totalData.Count
|
|
|
|
|
resp.NonExecutionAmount = totalData.NonExecutionAmount
|
|
|
|
|
resp.NonExecutionCount = totalData.NonExecutionCount
|
|
|
|
|
|
|
|
|
|
if req.IsExport == 1 {
|
|
|
|
|
filePath, err := reportByCommodityExport(resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
resp = &ErpPurchaseReportByCommodityResp{}
|
|
|
|
|
resp.ExportUrl = filePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购订单信息
|
2024-03-18 11:53:42 +00:00
|
|
|
|
func getPurchaseOrderData(orderID uint32, req *ErpPurchaseReportByCommodityReq) (ErpCommodityPurchaseOrderData, error) {
|
2024-03-06 02:07:55 +00:00
|
|
|
|
var purchaseOrderData ErpCommodityPurchaseOrderData
|
|
|
|
|
// 查询采购订单信息
|
|
|
|
|
var purchaseOrder ErpPurchaseOrder
|
2024-03-18 11:53:42 +00:00
|
|
|
|
qs := orm.Eloquent.Table("erp_purchase_order")
|
|
|
|
|
|
|
|
|
|
if len(req.ErpSupplierId) > 0 { // 供应商复选
|
2024-03-27 10:01:38 +00:00
|
|
|
|
qs = qs.Where("erp_supplier_id IN (?)", req.ErpSupplierId)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
}
|
|
|
|
|
if len(req.StoreId) > 0 { // 门店复选
|
2024-03-27 10:01:38 +00:00
|
|
|
|
qs = qs.Where("store_id IN (?)", req.StoreId)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
}
|
|
|
|
|
err := qs.Where("id = ?", orderID).Find(&purchaseOrder).Error
|
2024-03-06 02:07:55 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return purchaseOrderData, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购订单的计划和执行信息
|
|
|
|
|
purchaseData, err := getPurchaseData(purchaseOrder.ID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return purchaseOrderData, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 组合数据
|
2024-03-18 11:53:42 +00:00
|
|
|
|
purchaseOrderData.ErpPurchaseOrderId = purchaseOrder.ID
|
2024-03-06 02:07:55 +00:00
|
|
|
|
purchaseOrderData.SerialNumber = purchaseOrder.SerialNumber
|
|
|
|
|
purchaseOrderData.PurchaseType = purchaseOrder.PurchaseType
|
|
|
|
|
purchaseOrderData.StoreId = purchaseOrder.StoreId
|
|
|
|
|
purchaseOrderData.StoreName = purchaseOrder.StoreName
|
|
|
|
|
purchaseOrderData.ErpSupplierId = purchaseOrder.ErpSupplierId
|
|
|
|
|
purchaseOrderData.ErpSupplierName = purchaseOrder.ErpSupplierName
|
|
|
|
|
purchaseOrderData.HandlerId = purchaseOrder.HandlerId
|
|
|
|
|
purchaseOrderData.HandlerName = purchaseOrder.HandlerName
|
2024-03-18 11:53:42 +00:00
|
|
|
|
//purchaseOrderData.MakerTime = purchaseOrder.MakerTime
|
2024-03-06 02:07:55 +00:00
|
|
|
|
purchaseOrderData.MakerId = purchaseOrder.MakerId
|
|
|
|
|
purchaseOrderData.MakerName = purchaseOrder.MakerName
|
|
|
|
|
purchaseOrderData.AuditorId = purchaseOrder.AuditorId
|
2024-03-18 11:53:42 +00:00
|
|
|
|
//purchaseOrderData.AuditTime = purchaseOrder.AuditTime
|
2024-03-06 02:07:55 +00:00
|
|
|
|
purchaseOrderData.AuditorName = purchaseOrder.AuditorName
|
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if purchaseOrder.MakerTime != nil && purchaseOrder.MakerTime.IsZero() {
|
|
|
|
|
purchaseOrderData.MakerTime = nil
|
|
|
|
|
} else {
|
|
|
|
|
purchaseOrderData.MakerTime = purchaseOrder.MakerTime
|
|
|
|
|
}
|
|
|
|
|
if purchaseOrder.AuditTime != nil && purchaseOrder.AuditTime.IsZero() {
|
|
|
|
|
purchaseOrderData.AuditTime = nil
|
|
|
|
|
} else {
|
|
|
|
|
purchaseOrderData.AuditTime = purchaseOrder.AuditTime
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
purchaseOrderData.PlanCount = purchaseData.PlanCount
|
|
|
|
|
purchaseOrderData.PlanPrice = purchaseData.PlanPrice
|
|
|
|
|
purchaseOrderData.PlanAmount = purchaseData.PlanAmount
|
|
|
|
|
purchaseOrderData.Amount = purchaseData.Amount
|
|
|
|
|
purchaseOrderData.Price = purchaseData.Price
|
|
|
|
|
purchaseOrderData.Count = purchaseData.Count
|
|
|
|
|
purchaseOrderData.NonExecutionAmount = purchaseData.NonExecutionAmount
|
|
|
|
|
purchaseOrderData.NonExecutionCount = purchaseData.NonExecutionCount
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
if purchaseOrder.PurchaseType == ErpRejectOrder { // 退货单
|
|
|
|
|
purchaseOrderData.PlanCount = -purchaseOrderData.PlanCount
|
|
|
|
|
purchaseOrderData.PlanAmount = -purchaseOrderData.PlanAmount
|
|
|
|
|
purchaseOrderData.Amount = -purchaseOrderData.Amount
|
|
|
|
|
purchaseOrderData.Count = -purchaseOrderData.Count
|
|
|
|
|
purchaseOrderData.NonExecutionAmount = -purchaseOrderData.NonExecutionAmount
|
|
|
|
|
purchaseOrderData.NonExecutionCount = -purchaseOrderData.NonExecutionCount
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
return purchaseOrderData, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getPurchaseData 根据 ErpPurchaseCommodity 表查询采购数据
|
|
|
|
|
func getPurchaseData(erpPurchaseOrderId uint32) (PurchaseData, error) {
|
|
|
|
|
var purchaseData PurchaseData
|
|
|
|
|
|
|
|
|
|
err := orm.Eloquent.Raw(`
|
|
|
|
|
SELECT
|
|
|
|
|
SUM(pc.count) AS plan_count,
|
|
|
|
|
AVG(pc.price) AS plan_price,
|
|
|
|
|
SUM(pc.amount) AS plan_amount,
|
|
|
|
|
SUM(pi.count) AS count,
|
|
|
|
|
AVG(pi.implementation_price) AS price,
|
|
|
|
|
SUM(pi.amount) AS amount
|
|
|
|
|
FROM
|
|
|
|
|
erp_purchase_commodity pc
|
|
|
|
|
JOIN
|
|
|
|
|
erp_purchase_inventory pi ON pc.erp_purchase_order_id = pi.erp_purchase_order_id
|
|
|
|
|
WHERE
|
|
|
|
|
pc.erp_purchase_order_id = ?
|
|
|
|
|
GROUP BY
|
|
|
|
|
pc.erp_purchase_order_id
|
|
|
|
|
`, erpPurchaseOrderId).Scan(&purchaseData).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("getPurchaseData err:", logger.Field("err", err))
|
|
|
|
|
return purchaseData, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算未执行金额和未执行数量
|
|
|
|
|
purchaseData.NonExecutionAmount = purchaseData.PlanAmount - purchaseData.Amount
|
|
|
|
|
purchaseData.NonExecutionCount = purchaseData.PlanCount - purchaseData.Count
|
|
|
|
|
|
|
|
|
|
return purchaseData, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购报表(按商品):先筛选采购订单表,再补充商品入库信息
|
|
|
|
|
func getReportByCommodityFromCommon(req *ErpPurchaseReportByCommodityReq) (*ErpPurchaseReportByCommodityResp, error) {
|
|
|
|
|
page := req.PageIndex - 1
|
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if req.PageSize == 0 {
|
|
|
|
|
req.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
resp := &ErpPurchaseReportByCommodityResp{
|
|
|
|
|
PageIndex: page + 1,
|
|
|
|
|
PageSize: req.PageSize,
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
qs := orm.Eloquent.Table("erp_purchase_order").Where("state != 1")
|
2024-03-06 02:07:55 +00:00
|
|
|
|
if req.SerialNumber != "" { // 单据编号
|
|
|
|
|
qs = qs.Where("serial_number=?", req.SerialNumber)
|
|
|
|
|
} else {
|
|
|
|
|
if req.PurchaseType != "" { // 采购类型
|
|
|
|
|
qs = qs.Where("purchase_type=?", req.PurchaseType)
|
|
|
|
|
}
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if len(req.ErpSupplierId) > 0 { // 供应商复选
|
2024-03-27 10:01:38 +00:00
|
|
|
|
qs = qs.Where("erp_supplier_id IN (?)", req.ErpSupplierId)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if len(req.StoreId) > 0 { // 门店复选
|
2024-03-27 10:01:38 +00:00
|
|
|
|
qs = qs.Where("store_id IN (?)", req.StoreId)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
if req.HandlerId != 0 { // 经手人id
|
|
|
|
|
qs = qs.Where("handler_id=?", req.HandlerId)
|
|
|
|
|
}
|
|
|
|
|
if req.State != 0 { // 订单状态
|
|
|
|
|
qs = qs.Where("state=?", req.State)
|
|
|
|
|
}
|
|
|
|
|
if req.AuditTimeStart != "" { // 审核开始时间
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, req.AuditTimeStart)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("erpPurchaseOrderList err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("audit_time > ?", parse)
|
|
|
|
|
}
|
|
|
|
|
if req.AuditTimeEnd != "" { // 审核结束时间
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, req.AuditTimeEnd)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("erpPurchaseOrderList err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
//parse = parse.AddDate(0, 0, 1)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
qs = qs.Where("audit_time < ?", parse)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
|
err := qs.Count(&count).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("getReportByOrderFromCommon count err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var orders []ErpPurchaseOrder
|
|
|
|
|
err = qs.Order("id DESC").Find(&orders).Error
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
logger.Error("getReportByOrderFromCommon erp_purchase_order err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询所有商品id及其对应的orderId
|
|
|
|
|
commodityAndOrderIdMap, err := getAllOrderCommodity(page, req.PageSize, int(req.IsExport))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tempDataMap := make(map[uint32][]TempData)
|
|
|
|
|
|
|
|
|
|
//// 补充所有采购订单的商品信息和采购执行数量
|
|
|
|
|
//for _, v := range orders {
|
|
|
|
|
// commodityIds := findCommodityIDsByOrderID(v.ID, commodityAndOrderIdMap)
|
|
|
|
|
// // 获取每个采购订单的每个商品的采购和执行信息
|
|
|
|
|
// for _, commodityId := range commodityIds {
|
|
|
|
|
// purchaseOrderData, commodityData, err := getPurchaseOrderAndCommodityData(v.ID, commodityId)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// tempData := TempData{
|
|
|
|
|
// CommodityData: commodityData,
|
|
|
|
|
// ErpCommodityPurchaseOrderData: purchaseOrderData,
|
|
|
|
|
// }
|
|
|
|
|
// tempDataMap[commodityId] = append(tempDataMap[commodityId], tempData)
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
ch := make(chan TempData, len(orders)*len(commodityAndOrderIdMap))
|
|
|
|
|
|
|
|
|
|
// 并发查询每个采购订单的每个商品的采购和执行信息
|
|
|
|
|
for _, v := range orders {
|
|
|
|
|
commodityIds := findCommodityIDsByOrderID(v.ID, commodityAndOrderIdMap)
|
|
|
|
|
for _, commodityID := range commodityIds {
|
|
|
|
|
wg.Add(1)
|
|
|
|
|
go getPurchaseOrderAndCommodityDataAsync(v.ID, commodityID, ch, &wg)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
wg.Wait()
|
|
|
|
|
close(ch)
|
|
|
|
|
|
|
|
|
|
for data := range ch {
|
|
|
|
|
tempDataMap[data.ErpCommodityId] = append(tempDataMap[data.ErpCommodityId], data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var dataList []ReportByCommodityData
|
|
|
|
|
var totalData PurchaseData
|
|
|
|
|
// tempDataList,按照商品id进行归类
|
|
|
|
|
for _, tempDataList := range tempDataMap {
|
|
|
|
|
var reportData ReportByCommodityData
|
|
|
|
|
for _, v := range tempDataList {
|
|
|
|
|
reportData.ErpCategoryID = v.ErpCategoryID
|
|
|
|
|
reportData.ErpCategoryName = v.ErpCategoryName
|
|
|
|
|
reportData.ErpCommodityId = v.ErpCommodityId
|
|
|
|
|
reportData.ErpCommodityName = v.ErpCommodityName
|
|
|
|
|
|
|
|
|
|
reportData.PlanCount += v.PlanCount
|
|
|
|
|
reportData.PlanAmount += v.PlanAmount
|
|
|
|
|
reportData.Amount += v.Amount
|
|
|
|
|
reportData.Count += v.Count
|
|
|
|
|
reportData.NonExecutionAmount += v.NonExecutionAmount
|
|
|
|
|
reportData.NonExecutionCount += v.NonExecutionCount
|
2024-03-27 10:01:38 +00:00
|
|
|
|
if reportData.PlanCount != 0 {
|
|
|
|
|
reportData.PlanPrice = reportData.PlanAmount / float64(reportData.PlanCount)
|
|
|
|
|
reportData.PlanPrice = math.Round(reportData.PlanPrice*100) / 100
|
|
|
|
|
}
|
|
|
|
|
if reportData.Count != 0 {
|
|
|
|
|
reportData.Price = reportData.Amount / float64(reportData.Count)
|
|
|
|
|
reportData.Price = math.Round(reportData.Price*100) / 100
|
|
|
|
|
}
|
2024-03-06 02:07:55 +00:00
|
|
|
|
|
|
|
|
|
purchaseOrderData := ErpCommodityPurchaseOrderData{
|
|
|
|
|
CommonData{
|
2024-03-18 11:53:42 +00:00
|
|
|
|
ErpPurchaseOrderId: v.ErpPurchaseOrderId,
|
|
|
|
|
SerialNumber: v.SerialNumber,
|
|
|
|
|
PurchaseType: v.PurchaseType,
|
|
|
|
|
StoreId: v.StoreId,
|
|
|
|
|
StoreName: v.StoreName,
|
|
|
|
|
ErpSupplierId: v.ErpSupplierId,
|
|
|
|
|
ErpSupplierName: v.ErpSupplierName,
|
|
|
|
|
HandlerId: v.HandlerId,
|
|
|
|
|
HandlerName: v.HandlerName,
|
|
|
|
|
//MakerTime: v.MakerTime,
|
|
|
|
|
MakerId: v.MakerId,
|
|
|
|
|
MakerName: v.MakerName,
|
|
|
|
|
AuditorId: v.AuditorId,
|
|
|
|
|
//AuditTime: v.AuditTime,
|
|
|
|
|
AuditorName: v.AuditorName,
|
2024-03-06 02:07:55 +00:00
|
|
|
|
},
|
|
|
|
|
PurchaseData{
|
|
|
|
|
PlanCount: v.PlanCount,
|
|
|
|
|
PlanPrice: v.PlanPrice,
|
|
|
|
|
PlanAmount: v.PlanAmount,
|
|
|
|
|
Amount: v.Amount,
|
|
|
|
|
Price: v.Price,
|
|
|
|
|
Count: v.Count,
|
|
|
|
|
NonExecutionAmount: v.NonExecutionAmount,
|
|
|
|
|
NonExecutionCount: v.NonExecutionCount,
|
|
|
|
|
},
|
|
|
|
|
}
|
2024-03-18 11:53:42 +00:00
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
if v.PurchaseType == ErpRejectOrder { // 退货单
|
|
|
|
|
reportData.PlanCount = -reportData.PlanCount
|
|
|
|
|
reportData.PlanAmount = -reportData.PlanAmount
|
|
|
|
|
reportData.Amount = -reportData.Amount
|
|
|
|
|
reportData.Count = -reportData.Count
|
|
|
|
|
reportData.NonExecutionAmount = -reportData.NonExecutionAmount
|
|
|
|
|
reportData.NonExecutionCount = -reportData.NonExecutionCount
|
|
|
|
|
|
|
|
|
|
purchaseOrderData.PlanCount = -purchaseOrderData.PlanCount
|
|
|
|
|
purchaseOrderData.PlanAmount = -purchaseOrderData.PlanAmount
|
|
|
|
|
purchaseOrderData.Amount = -purchaseOrderData.Amount
|
|
|
|
|
purchaseOrderData.Count = -purchaseOrderData.Count
|
|
|
|
|
purchaseOrderData.NonExecutionAmount = -purchaseOrderData.NonExecutionAmount
|
|
|
|
|
purchaseOrderData.NonExecutionCount = -purchaseOrderData.NonExecutionCount
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if v.MakerTime != nil && v.MakerTime.IsZero() {
|
|
|
|
|
purchaseOrderData.MakerTime = nil
|
|
|
|
|
} else {
|
|
|
|
|
purchaseOrderData.MakerTime = v.MakerTime
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if v.AuditTime != nil && v.AuditTime.IsZero() {
|
|
|
|
|
purchaseOrderData.AuditTime = nil
|
|
|
|
|
} else {
|
|
|
|
|
purchaseOrderData.AuditTime = v.AuditTime
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
reportData.OrderInfo = append(reportData.OrderInfo, purchaseOrderData)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dataList = append(dataList, reportData)
|
|
|
|
|
|
|
|
|
|
totalData.PlanCount += reportData.PlanCount
|
|
|
|
|
totalData.PlanAmount += reportData.PlanAmount
|
|
|
|
|
totalData.Amount += reportData.Amount
|
|
|
|
|
totalData.Count += reportData.Count
|
|
|
|
|
totalData.NonExecutionAmount += reportData.NonExecutionAmount
|
|
|
|
|
totalData.NonExecutionCount += reportData.NonExecutionCount
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sortByCommodityIDDesc(dataList)
|
|
|
|
|
resp.Total = len(dataList)
|
|
|
|
|
resp.List = dataList
|
|
|
|
|
resp.PlanCount = totalData.PlanCount
|
|
|
|
|
resp.PlanAmount = totalData.PlanAmount
|
|
|
|
|
resp.Amount = totalData.Amount
|
|
|
|
|
resp.Count = totalData.Count
|
|
|
|
|
resp.NonExecutionAmount = totalData.NonExecutionAmount
|
|
|
|
|
resp.NonExecutionCount = totalData.NonExecutionCount
|
|
|
|
|
|
|
|
|
|
if req.IsExport == 1 {
|
|
|
|
|
filePath, err := reportByCommodityExport(resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
resp = &ErpPurchaseReportByCommodityResp{}
|
|
|
|
|
resp.ExportUrl = filePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getPurchaseOrderAndCommodityDataAsync(orderID, commodityID uint32, ch chan<- TempData, wg *sync.WaitGroup) {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
|
|
purchaseOrderData, commodityData, err := getPurchaseOrderAndCommodityData(orderID, commodityID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("getPurchaseOrderAndCommodityDataAsync err:", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tempData := TempData{
|
|
|
|
|
CommodityData: commodityData,
|
|
|
|
|
ErpCommodityPurchaseOrderData: purchaseOrderData,
|
|
|
|
|
}
|
|
|
|
|
ch <- tempData
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 按照商品ID进行倒序排序的 less 函数
|
|
|
|
|
func sortByCommodityIDDesc(dataList []ReportByCommodityData) {
|
|
|
|
|
sort.Slice(dataList, func(i, j int) bool {
|
|
|
|
|
return dataList[i].ErpCommodityId > dataList[j].ErpCommodityId
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购订单信息
|
|
|
|
|
func getPurchaseOrderAndCommodityData(orderID, commodityId uint32) (ErpCommodityPurchaseOrderData, CommodityData, error) {
|
|
|
|
|
var purchaseOrderData ErpCommodityPurchaseOrderData
|
|
|
|
|
// 查询采购订单信息
|
|
|
|
|
var purchaseOrder ErpPurchaseOrder
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_order").Where("id = ?", orderID).Find(&purchaseOrder).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return ErpCommodityPurchaseOrderData{}, CommodityData{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询采购订单的计划和执行信息
|
|
|
|
|
purchaseData, commodityData, err := getSignalPurchaseData(purchaseOrder.ID, commodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return ErpCommodityPurchaseOrderData{}, CommodityData{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 组合数据
|
2024-03-18 11:53:42 +00:00
|
|
|
|
purchaseOrderData.ErpPurchaseOrderId = purchaseOrder.ID
|
2024-03-06 02:07:55 +00:00
|
|
|
|
purchaseOrderData.SerialNumber = purchaseOrder.SerialNumber
|
|
|
|
|
purchaseOrderData.PurchaseType = purchaseOrder.PurchaseType
|
|
|
|
|
purchaseOrderData.StoreId = purchaseOrder.StoreId
|
|
|
|
|
purchaseOrderData.StoreName = purchaseOrder.StoreName
|
|
|
|
|
purchaseOrderData.ErpSupplierId = purchaseOrder.ErpSupplierId
|
|
|
|
|
purchaseOrderData.ErpSupplierName = purchaseOrder.ErpSupplierName
|
|
|
|
|
purchaseOrderData.HandlerId = purchaseOrder.HandlerId
|
|
|
|
|
purchaseOrderData.HandlerName = purchaseOrder.HandlerName
|
|
|
|
|
purchaseOrderData.MakerId = purchaseOrder.MakerId
|
|
|
|
|
purchaseOrderData.MakerName = purchaseOrder.MakerName
|
|
|
|
|
purchaseOrderData.AuditorId = purchaseOrder.AuditorId
|
|
|
|
|
purchaseOrderData.AuditTime = purchaseOrder.AuditTime
|
|
|
|
|
purchaseOrderData.AuditorName = purchaseOrder.AuditorName
|
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if purchaseOrder.MakerTime != nil && purchaseOrder.MakerTime.IsZero() {
|
|
|
|
|
purchaseOrderData.MakerTime = nil
|
|
|
|
|
} else {
|
|
|
|
|
purchaseOrderData.MakerTime = purchaseOrder.MakerTime
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if purchaseOrder.AuditTime != nil && purchaseOrder.AuditTime.IsZero() {
|
|
|
|
|
purchaseOrderData.AuditTime = nil
|
|
|
|
|
} else {
|
|
|
|
|
purchaseOrderData.AuditTime = purchaseOrder.AuditTime
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
purchaseOrderData.PlanCount = purchaseData.PlanCount
|
|
|
|
|
purchaseOrderData.PlanPrice = purchaseData.PlanPrice
|
|
|
|
|
purchaseOrderData.PlanAmount = purchaseData.PlanAmount
|
|
|
|
|
purchaseOrderData.Amount = purchaseData.Amount
|
|
|
|
|
purchaseOrderData.Price = purchaseData.Price
|
|
|
|
|
purchaseOrderData.Count = purchaseData.Count
|
|
|
|
|
purchaseOrderData.NonExecutionAmount = purchaseData.NonExecutionAmount
|
|
|
|
|
purchaseOrderData.NonExecutionCount = purchaseData.NonExecutionCount
|
|
|
|
|
|
|
|
|
|
return purchaseOrderData, commodityData, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getSignalPurchaseData 根据 ErpPurchaseCommodity 表查询采购数据
|
|
|
|
|
func getSignalPurchaseData(erpPurchaseOrderId, commodityId uint32) (PurchaseData, CommodityData, error) {
|
|
|
|
|
var purchaseData PurchaseData
|
|
|
|
|
var commodityData CommodityData
|
|
|
|
|
|
|
|
|
|
err := orm.Eloquent.Raw(`
|
|
|
|
|
SELECT
|
|
|
|
|
SUM(pc.count) AS plan_count,
|
|
|
|
|
AVG(pc.price) AS plan_price,
|
|
|
|
|
SUM(pc.amount) AS plan_amount,
|
|
|
|
|
SUM(pi.count) AS count,
|
|
|
|
|
AVG(pi.implementation_price) AS price,
|
|
|
|
|
SUM(pi.amount) AS amount
|
|
|
|
|
FROM
|
|
|
|
|
erp_purchase_commodity pc
|
|
|
|
|
JOIN
|
|
|
|
|
erp_purchase_inventory pi ON pc.erp_purchase_order_id = pi.erp_purchase_order_id
|
|
|
|
|
WHERE
|
|
|
|
|
pc.erp_purchase_order_id = ? and pc.erp_commodity_id = ?
|
|
|
|
|
GROUP BY
|
|
|
|
|
pc.erp_purchase_order_id
|
|
|
|
|
`, erpPurchaseOrderId, commodityId).Scan(&purchaseData).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("getPurchaseData err:", logger.Field("err", err))
|
|
|
|
|
return PurchaseData{}, CommodityData{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算未执行金额和未执行数量
|
|
|
|
|
purchaseData.NonExecutionAmount = purchaseData.PlanAmount - purchaseData.Amount
|
|
|
|
|
purchaseData.NonExecutionCount = purchaseData.PlanCount - purchaseData.Count
|
|
|
|
|
|
|
|
|
|
// 查询订单对应的商品信息
|
|
|
|
|
commodityInfo, err := GetCommodity(commodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return PurchaseData{}, CommodityData{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
commodityData.ErpCommodityId = commodityInfo.ID
|
|
|
|
|
commodityData.ErpCommodityName = commodityInfo.Name
|
|
|
|
|
commodityData.ErpCategoryID = commodityInfo.ErpCategoryId
|
|
|
|
|
commodityData.ErpCategoryName = commodityInfo.ErpCategoryName
|
|
|
|
|
|
|
|
|
|
return purchaseData, commodityData, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//// 查询所有商品信息
|
|
|
|
|
//func getAllOrderCommodity(pageIndex, pageSize int) (map[uint32][]uint32, error) {
|
|
|
|
|
// qs := orm.Eloquent.Table("erp_purchase_commodity")
|
|
|
|
|
//
|
|
|
|
|
// var count int64
|
|
|
|
|
// err := qs.Count(&count).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("getAllOrderCommodity count err:", logger.Field("err", err))
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// var commodityList []ErpPurchaseCommodity
|
|
|
|
|
// err = qs.Order("id DESC").Offset(pageIndex * pageSize).Limit(pageSize).Find(&commodityList).Error
|
|
|
|
|
// if err != nil && err != RecordNotFound {
|
|
|
|
|
// logger.Error("getAllOrderCommodity erp_purchase_commodity err:", logger.Field("err", err))
|
|
|
|
|
// return nil, err
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// commodityMap := make(map[uint32][]uint32)
|
|
|
|
|
// for _, v := range commodityList {
|
|
|
|
|
// if !contains(commodityMap[v.ErpCommodityId], v.ErpPurchaseOrderId) {
|
|
|
|
|
// commodityMap[v.ErpCommodityId] = append(commodityMap[v.ErpCommodityId], v.ErpPurchaseOrderId)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return commodityMap, nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func contains(slice []uint32, item uint32) bool {
|
|
|
|
|
// for _, value := range slice {
|
|
|
|
|
// if value == item {
|
|
|
|
|
// return true
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// return false
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
// 查询所有商品信息,每页展示不同商品ID及其对应的订单ID
|
|
|
|
|
func getAllOrderCommodity(pageIndex, pageSize, is_export int) (map[uint32][]uint32, error) {
|
|
|
|
|
var commodityMap = make(map[uint32][]uint32)
|
|
|
|
|
var query string
|
|
|
|
|
if is_export == 1 { //导出excel
|
|
|
|
|
// 执行原生 SQL 查询,联结表格,按照每个商品ID列出所有的订单ID
|
|
|
|
|
query = fmt.Sprintf(`
|
|
|
|
|
SELECT pc1.erp_commodity_id, GROUP_CONCAT(pc2.erp_purchase_order_id) AS order_ids
|
|
|
|
|
FROM erp_purchase_commodity pc1
|
|
|
|
|
JOIN erp_purchase_commodity pc2
|
|
|
|
|
ON pc1.erp_commodity_id = pc2.erp_commodity_id
|
|
|
|
|
GROUP BY pc1.erp_commodity_id`)
|
|
|
|
|
} else {
|
|
|
|
|
// 执行原生 SQL 查询,联结表格,按照每个商品ID列出所有的订单ID
|
|
|
|
|
query = fmt.Sprintf(`
|
|
|
|
|
SELECT pc1.erp_commodity_id, GROUP_CONCAT(pc2.erp_purchase_order_id) AS order_ids
|
|
|
|
|
FROM erp_purchase_commodity pc1
|
|
|
|
|
JOIN erp_purchase_commodity pc2
|
|
|
|
|
ON pc1.erp_commodity_id = pc2.erp_commodity_id
|
|
|
|
|
GROUP BY pc1.erp_commodity_id
|
|
|
|
|
LIMIT %d OFFSET %d
|
|
|
|
|
`, pageSize, pageIndex*pageSize)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rows, err := orm.Eloquent.Raw(query).Rows()
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("getAllOrderCommodity erp_purchase_commodity err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
|
var commodityID uint32
|
|
|
|
|
var orderIDs string
|
|
|
|
|
if err := rows.Scan(&commodityID, &orderIDs); err != nil {
|
|
|
|
|
logger.Error("getAllOrderCommodity rows scan err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将 orderIDs 字符串拆分为字符串数组
|
|
|
|
|
orderIDStrList := strings.Split(orderIDs, ",")
|
|
|
|
|
|
|
|
|
|
// 去重并转换为 uint32 数组
|
|
|
|
|
var orderIDList []uint32
|
|
|
|
|
seen := make(map[uint32]bool)
|
|
|
|
|
for _, idStr := range orderIDStrList {
|
|
|
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("getAllOrderCommodity parse orderID err:", logger.Field("err", err))
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果该订单ID未被添加过,则添加到列表中
|
|
|
|
|
if _, ok := seen[uint32(id)]; !ok {
|
|
|
|
|
orderIDList = append(orderIDList, uint32(id))
|
|
|
|
|
seen[uint32(id)] = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加到 map 中
|
|
|
|
|
commodityMap[commodityID] = orderIDList
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return commodityMap, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func findCommodityIDsByOrderID(orderID uint32, commodityMap map[uint32][]uint32) []uint32 {
|
|
|
|
|
var commodityIDs []uint32
|
|
|
|
|
|
|
|
|
|
for commodityID, orderIDs := range commodityMap {
|
|
|
|
|
for _, id := range orderIDs {
|
|
|
|
|
if id == orderID {
|
|
|
|
|
commodityIDs = append(commodityIDs, commodityID)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return commodityIDs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 导出采购报表(按商品)excel
|
|
|
|
|
func reportByCommodityExport(req *ErpPurchaseReportByCommodityResp) (string, error) {
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
fSheet := "Sheet1"
|
|
|
|
|
|
|
|
|
|
url := ExportUrl
|
|
|
|
|
fileName := time.Now().Format(TimeFormat) + "采购报表(按商品)" + ".xlsx"
|
|
|
|
|
fmt.Println("url fileName:", url+fileName)
|
|
|
|
|
|
|
|
|
|
// 组合标题栏数据
|
|
|
|
|
title1 := []interface{}{"商品名称", "商品分类", "单据编号", "类型", "店铺名称", "供应商", "经手人", "制单人", "审核时间",
|
|
|
|
|
"计划采购", "", "", "已执行", "", "", "未执行", ""}
|
|
|
|
|
title2 := []interface{}{"商品名称", "商品分类", "单据编号", "类型", "店铺名称", "供应商", "经手人", "制单人", "审核时间",
|
|
|
|
|
"采购金额", "采购单价", "采购数量", "已执行金额", "执行单价", "已执行数量", "未执行金额", "未执行数量"}
|
|
|
|
|
for i, _ := range title1 {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, 1)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, title1[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("file set value err:", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i, _ := range title2 {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, 2)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, title2[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("file set value err:", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var row1 []interface{}
|
|
|
|
|
var row2 []interface{}
|
|
|
|
|
nExcelStartRow := 0
|
|
|
|
|
for _, commodityData := range req.List {
|
|
|
|
|
row1 = []interface{}{
|
|
|
|
|
commodityData.ErpCommodityName, // 商品名称
|
|
|
|
|
commodityData.ErpCategoryName, // 商品分类
|
|
|
|
|
"", // 单据编号
|
|
|
|
|
"", // 类型
|
|
|
|
|
"", // 店铺名称
|
|
|
|
|
"", // 供应商
|
|
|
|
|
"", // 经手人
|
|
|
|
|
"", // 制单人
|
|
|
|
|
"", // 审核时间
|
|
|
|
|
commodityData.PlanAmount, // 计划采购金额
|
|
|
|
|
commodityData.PlanPrice, // 计划采购单价
|
|
|
|
|
commodityData.PlanCount, // 计划采购数量
|
|
|
|
|
commodityData.Amount, // 已执行金额
|
|
|
|
|
commodityData.Price, // 已执行单价
|
|
|
|
|
commodityData.Count, // 已执行数量
|
|
|
|
|
commodityData.NonExecutionAmount, // 未执行金额
|
|
|
|
|
commodityData.NonExecutionCount, // 未执行数量
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for j, _ := range row1 {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+3)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, row1[j])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nExcelStartRow++
|
|
|
|
|
|
|
|
|
|
for _, orderData := range commodityData.OrderInfo {
|
|
|
|
|
var orderType string
|
|
|
|
|
switch orderData.PurchaseType {
|
|
|
|
|
case "procure":
|
|
|
|
|
orderType = "采购入库"
|
|
|
|
|
case "reject":
|
|
|
|
|
orderType = "采购退货"
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var strTime string
|
|
|
|
|
if orderData.AuditTime != nil {
|
|
|
|
|
strTime = orderData.AuditTime.Format(TimeFormat)
|
|
|
|
|
} else {
|
|
|
|
|
strTime = "--"
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
row2 = []interface{}{
|
2024-03-27 10:01:38 +00:00
|
|
|
|
"", // 商品名称
|
|
|
|
|
"", // 商品分类
|
|
|
|
|
orderData.SerialNumber, // 单据编号
|
|
|
|
|
orderType, // 类型
|
|
|
|
|
orderData.StoreName, // 店铺名称
|
|
|
|
|
orderData.ErpSupplierName, // 供应商
|
|
|
|
|
orderData.HandlerName, // 经手人
|
|
|
|
|
orderData.MakerName, // 制单人
|
|
|
|
|
strTime, // 审核时间
|
|
|
|
|
orderData.PlanAmount, // 计划采购金额
|
|
|
|
|
orderData.PlanPrice, // 计划采购单价
|
|
|
|
|
orderData.PlanCount, // 计划采购数量
|
|
|
|
|
orderData.Amount, // 已执行金额
|
|
|
|
|
orderData.Price, // 已执行单价
|
|
|
|
|
orderData.Count, // 已执行数量
|
|
|
|
|
orderData.NonExecutionAmount, // 未执行金额
|
|
|
|
|
orderData.NonExecutionCount, // 未执行数量
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for j, _ := range row2 {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+3)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, row2[j])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nExcelStartRow++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalData := "订单数:" + strconv.FormatInt(int64(req.Total), 10)
|
|
|
|
|
end := []interface{}{totalData, "", "", "", "", "", "", "", "",
|
|
|
|
|
req.PlanAmount, // 计划采购金额
|
|
|
|
|
"--", // 计划采购单价
|
|
|
|
|
req.PlanCount, // 计划采购数量
|
|
|
|
|
req.Amount, // 已执行金额
|
|
|
|
|
"--", // 已执行单价
|
|
|
|
|
req.Count, // 已执行数量
|
|
|
|
|
req.NonExecutionAmount, // 未执行金额
|
|
|
|
|
req.NonExecutionCount, // 未执行数量
|
|
|
|
|
}
|
|
|
|
|
for i, _ := range end {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, end[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置所有单元格的样式: 居中、加边框
|
|
|
|
|
style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},
|
|
|
|
|
"border":[{"type":"left","color":"000000","style":1},
|
|
|
|
|
{"type":"top","color":"000000","style":1},
|
|
|
|
|
{"type":"right","color":"000000","style":1},
|
|
|
|
|
{"type":"bottom","color":"000000","style":1}]}`)
|
|
|
|
|
|
|
|
|
|
// 合并单元格
|
|
|
|
|
_ = file.MergeCell(fSheet, "A1", "A2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "B1", "B2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "C1", "C2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "D1", "D2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "E1", "E2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "F1", "F2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "G1", "G2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "H1", "H2")
|
|
|
|
|
_ = file.MergeCell(fSheet, "I1", "I2")
|
|
|
|
|
|
|
|
|
|
_ = file.MergeCell(fSheet, "J1", "L1")
|
|
|
|
|
_ = file.MergeCell(fSheet, "M1", "O1")
|
|
|
|
|
_ = file.MergeCell(fSheet, "P1", "Q1")
|
|
|
|
|
|
|
|
|
|
//设置单元格高度
|
|
|
|
|
file.SetRowHeight("Sheet1", 1, 20)
|
|
|
|
|
file.SetRowHeight("Sheet1", 2, 20)
|
|
|
|
|
|
|
|
|
|
// 设置单元格大小
|
|
|
|
|
file.SetColWidth("Sheet1", "A", "A", 15)
|
|
|
|
|
file.SetColWidth("Sheet1", "B", "B", 10)
|
|
|
|
|
file.SetColWidth("Sheet1", "C", "C", 13)
|
|
|
|
|
file.SetColWidth("Sheet1", "E", "E", 25)
|
|
|
|
|
|
|
|
|
|
endRow := fmt.Sprintf("Q"+"%d", nExcelStartRow+2)
|
|
|
|
|
// 应用样式到整个表格
|
|
|
|
|
_ = file.SetCellStyle("Sheet1", "A1", endRow, style)
|
|
|
|
|
|
|
|
|
|
fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
|
|
|
|
|
if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
return url + fileName, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetReportBySupplier 查询供应商采购汇总
|
|
|
|
|
func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq) (*ErpPurchaseReportBySupplierResp, error) {
|
|
|
|
|
page := req.PageIndex - 1
|
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if req.PageSize == 0 {
|
|
|
|
|
req.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
resp := &ErpPurchaseReportBySupplierResp{
|
|
|
|
|
PageIndex: page + 1,
|
|
|
|
|
PageSize: req.PageSize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建查询条件
|
|
|
|
|
query := orm.Eloquent.Model(&ErpPurchaseInventory{}).
|
|
|
|
|
Select("erp_purchase_inventory.erp_purchase_order_id, erp_purchase_inventory.purchase_type, " +
|
|
|
|
|
"erp_purchase_order.store_id, erp_purchase_order.store_name, erp_purchase_order.erp_supplier_id, " +
|
|
|
|
|
"erp_purchase_order.erp_supplier_name, " +
|
|
|
|
|
"erp_purchase_inventory.erp_commodity_id, erp_purchase_inventory.erp_commodity_name, " +
|
|
|
|
|
"erp_purchase_inventory.erp_category_id, erp_purchase_inventory.erp_category_name, " +
|
|
|
|
|
"SUM(erp_purchase_inventory.count) AS total_count, " +
|
|
|
|
|
"SUM(erp_purchase_inventory.amount) AS total_amount").
|
|
|
|
|
Joins("JOIN erp_purchase_order ON erp_purchase_order.id = erp_purchase_inventory.erp_purchase_order_id").
|
|
|
|
|
Group("erp_purchase_inventory.erp_purchase_order_id, erp_purchase_inventory.erp_commodity_id, " +
|
|
|
|
|
"erp_purchase_inventory.erp_commodity_name, erp_purchase_inventory.erp_category_id")
|
|
|
|
|
|
|
|
|
|
// 根据请求参数过滤数据
|
|
|
|
|
if req.PurchaseType != "" {
|
|
|
|
|
query = query.Where("erp_purchase_inventory.purchase_type = ?", req.PurchaseType)
|
|
|
|
|
}
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if len(req.ErpCommodityName) > 0 {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
query = query.Where("erp_purchase_inventory.erp_commodity_name IN (?)", req.ErpCommodityName)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
2024-03-16 08:19:12 +00:00
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if len(req.ErpCategoryID) > 0 {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
query = query.Where("erp_purchase_inventory.erp_category_id IN (?)", req.ErpCategoryID)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
2024-03-16 08:19:12 +00:00
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
if req.StartTime != "" { // 入/出库开始时间
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, req.StartTime)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("GetReportDetail err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
query = query.Where("erp_purchase_inventory.created_at >= ?", parse)
|
|
|
|
|
}
|
2024-03-16 08:19:12 +00:00
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
if req.EndTime != "" { // 入/出库结束时间
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, req.EndTime)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("GetReportDetail err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
query = query.Where("erp_purchase_inventory.created_at <= ?", parse)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(req.StoreList) > 0 {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
query = query.Where("erp_purchase_order.store_id IN (?)", req.StoreList)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取总数
|
|
|
|
|
var total int64
|
|
|
|
|
query.Count(&total)
|
|
|
|
|
resp.Total = int(total)
|
|
|
|
|
|
|
|
|
|
// 分页查询
|
2024-03-18 11:53:42 +00:00
|
|
|
|
var err error
|
2024-03-06 02:07:55 +00:00
|
|
|
|
if req.IsExport == 1 { // 导出excel
|
2024-03-18 11:53:42 +00:00
|
|
|
|
err = query.Find(&resp.List).Error
|
2024-03-06 02:07:55 +00:00
|
|
|
|
} else {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
//err = query.Offset((req.PageIndex - 1) * req.PageSize).Limit(req.PageSize).Find(&resp.List).Error
|
|
|
|
|
err = query.Find(&resp.List).Error
|
2024-03-18 11:53:42 +00:00
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var esData []PurchaseReportData
|
2024-03-06 02:07:55 +00:00
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
if len(req.ErpSupplierId) > 0 {
|
|
|
|
|
var purchaseOrder []ErpPurchaseOrder
|
|
|
|
|
err = orm.Eloquent.Where("erp_purchase_order.erp_supplier_id IN (?)", req.ErpSupplierId).Find(&purchaseOrder).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 循环遍历采购订单
|
|
|
|
|
for _, po := range purchaseOrder {
|
|
|
|
|
// 在resp.List中查找匹配的订单
|
|
|
|
|
for _, respItem := range resp.List {
|
|
|
|
|
if po.ID == respItem.ErpPurchaseOrderId {
|
|
|
|
|
// 如果找到匹配的订单,将其添加到esData中
|
|
|
|
|
data := PurchaseReportData{
|
|
|
|
|
ErpPurchaseOrderId: po.ID,
|
|
|
|
|
StoreId: po.StoreId,
|
|
|
|
|
StoreName: po.StoreName,
|
|
|
|
|
PurchaseType: respItem.PurchaseType,
|
|
|
|
|
ErpSupplierId: po.ErpSupplierId,
|
|
|
|
|
ErpSupplierName: po.ErpSupplierName,
|
|
|
|
|
ErpCommodityId: respItem.ErpCommodityId,
|
|
|
|
|
ErpCommodityName: respItem.ErpCommodityName,
|
|
|
|
|
ErpCategoryID: respItem.ErpCategoryID,
|
|
|
|
|
ErpCategoryName: respItem.ErpCategoryName,
|
|
|
|
|
Count: respItem.Count,
|
|
|
|
|
Amount: respItem.Amount,
|
|
|
|
|
RejectAmount: respItem.RejectAmount,
|
|
|
|
|
Difference: respItem.Difference,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if data.PurchaseType == "reject" {
|
|
|
|
|
data.Amount = -data.Amount
|
|
|
|
|
data.RejectAmount = -data.RejectAmount
|
|
|
|
|
data.Difference = data.Amount + data.RejectAmount
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esData = append(esData, data)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
resp.List = esData
|
|
|
|
|
} else {
|
|
|
|
|
// 补充关联的供应商和店铺信息
|
|
|
|
|
for i := range resp.List {
|
|
|
|
|
var purchaseOrderInfo ErpPurchaseOrder
|
|
|
|
|
orm.Eloquent.Where("id = ?", resp.List[i].ErpPurchaseOrderId).First(&purchaseOrderInfo)
|
|
|
|
|
|
|
|
|
|
resp.List[i].StoreId = purchaseOrderInfo.StoreId
|
|
|
|
|
resp.List[i].StoreName = purchaseOrderInfo.StoreName
|
|
|
|
|
resp.List[i].ErpSupplierId = purchaseOrderInfo.ErpSupplierId
|
|
|
|
|
resp.List[i].ErpSupplierName = purchaseOrderInfo.ErpSupplierName
|
|
|
|
|
|
|
|
|
|
if resp.List[i].PurchaseType == "reject" {
|
|
|
|
|
resp.List[i].Amount = -resp.List[i].Amount
|
|
|
|
|
resp.List[i].RejectAmount = -resp.List[i].RejectAmount
|
|
|
|
|
resp.List[i].Difference = resp.List[i].Amount + resp.List[i].RejectAmount
|
|
|
|
|
}
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
mergedData := mergeData(resp.List)
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// 统计总计数量和金额
|
|
|
|
|
var totalAmount float64
|
|
|
|
|
var totalCount uint32
|
2024-03-27 10:01:38 +00:00
|
|
|
|
var totalRejectAmount float64
|
|
|
|
|
var totalDifference float64
|
|
|
|
|
for _, item := range mergedData {
|
2024-03-06 02:07:55 +00:00
|
|
|
|
totalAmount += item.Amount
|
|
|
|
|
totalCount += item.Count
|
2024-03-27 10:01:38 +00:00
|
|
|
|
totalRejectAmount += item.RejectAmount
|
|
|
|
|
totalDifference += item.Difference
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp.Amount = totalAmount
|
|
|
|
|
resp.Count = totalCount
|
2024-03-27 10:01:38 +00:00
|
|
|
|
resp.RejectAmount = totalRejectAmount
|
|
|
|
|
resp.Difference = totalDifference
|
|
|
|
|
resp.Total = len(mergedData)
|
|
|
|
|
|
|
|
|
|
// 分页处理
|
|
|
|
|
startIdx := (resp.PageIndex - 1) * resp.PageSize
|
|
|
|
|
endIdx := resp.PageIndex * resp.PageSize
|
|
|
|
|
|
|
|
|
|
// 确保不超出索引范围
|
|
|
|
|
if startIdx >= len(mergedData) {
|
|
|
|
|
resp.List = []PurchaseReportData{}
|
|
|
|
|
} else if endIdx > len(mergedData) {
|
|
|
|
|
resp.List = mergedData[startIdx:]
|
|
|
|
|
} else {
|
|
|
|
|
resp.List = mergedData[startIdx:endIdx]
|
|
|
|
|
}
|
2024-03-06 02:07:55 +00:00
|
|
|
|
|
|
|
|
|
if req.IsExport == 1 {
|
|
|
|
|
filePath, err := reportBySupplierExport(resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
resp = &ErpPurchaseReportBySupplierResp{}
|
|
|
|
|
resp.ExportUrl = filePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
//func mergeData(esData []PurchaseReportData) []PurchaseReportData {
|
|
|
|
|
// mergedMap := make(map[string]*PurchaseReportData)
|
|
|
|
|
//
|
|
|
|
|
// // 遍历 esData 数据
|
|
|
|
|
// for _, data := range esData {
|
|
|
|
|
// key := fmt.Sprintf("%d_%d_%d_%s", data.StoreId, data.ErpSupplierId, data.ErpCommodityId, data.PurchaseType)
|
|
|
|
|
// if _, ok := mergedMap[key]; !ok {
|
|
|
|
|
// // 如果键不存在,创建新条目
|
|
|
|
|
// mergedMap[key] = &PurchaseReportData{
|
|
|
|
|
// StoreId: data.StoreId,
|
|
|
|
|
// ErpSupplierId: data.ErpSupplierId,
|
|
|
|
|
// ErpCommodityId: data.ErpCommodityId,
|
|
|
|
|
// StoreName: data.StoreName,
|
|
|
|
|
// PurchaseType: data.PurchaseType,
|
|
|
|
|
// ErpSupplierName: data.ErpSupplierName,
|
|
|
|
|
// ErpCommodityName: data.ErpCommodityName,
|
|
|
|
|
// ErpCategoryID: data.ErpCategoryID,
|
|
|
|
|
// ErpCategoryName: data.ErpCategoryName,
|
|
|
|
|
// Count: data.Count,
|
|
|
|
|
// Amount: data.Amount,
|
|
|
|
|
// RejectAmount: data.RejectAmount,
|
|
|
|
|
// Difference: data.Difference,
|
|
|
|
|
// }
|
|
|
|
|
// } else {
|
|
|
|
|
// // 如果键已存在,进行累加操作
|
|
|
|
|
// mergedMap[key].Count += data.Count
|
|
|
|
|
// mergedMap[key].Amount += data.Amount
|
|
|
|
|
// mergedMap[key].RejectAmount += data.RejectAmount
|
|
|
|
|
// mergedMap[key].Difference += data.Difference
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 将合并后的数据转换为数组返回
|
|
|
|
|
// var mergedData []PurchaseReportData
|
|
|
|
|
// for _, v := range mergedMap {
|
|
|
|
|
// mergedData = append(mergedData, *v)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return mergedData
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
func mergeData(esData []PurchaseReportData) []PurchaseReportData {
|
|
|
|
|
mergedMap := make(map[string]*PurchaseReportData)
|
|
|
|
|
var keys []string // 用于记录键的顺序
|
|
|
|
|
|
|
|
|
|
// 遍历 esData 数据
|
|
|
|
|
for _, data := range esData {
|
|
|
|
|
key := fmt.Sprintf("%d_%d_%d_%s", data.StoreId, data.ErpSupplierId, data.ErpCommodityId, data.PurchaseType)
|
|
|
|
|
if _, ok := mergedMap[key]; !ok {
|
|
|
|
|
// 如果键不存在,创建新条目
|
|
|
|
|
mergedMap[key] = &PurchaseReportData{
|
|
|
|
|
StoreId: data.StoreId,
|
|
|
|
|
ErpSupplierId: data.ErpSupplierId,
|
|
|
|
|
ErpCommodityId: data.ErpCommodityId,
|
|
|
|
|
StoreName: data.StoreName,
|
|
|
|
|
PurchaseType: data.PurchaseType,
|
|
|
|
|
ErpSupplierName: data.ErpSupplierName,
|
|
|
|
|
ErpCommodityName: data.ErpCommodityName,
|
|
|
|
|
ErpCategoryID: data.ErpCategoryID,
|
|
|
|
|
ErpCategoryName: data.ErpCategoryName,
|
|
|
|
|
Count: data.Count,
|
|
|
|
|
Amount: data.Amount,
|
|
|
|
|
RejectAmount: data.RejectAmount,
|
|
|
|
|
Difference: data.Difference,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if data.PurchaseType == ErpRejectOrder {
|
|
|
|
|
mergedMap[key].RejectAmount = mergedMap[key].Amount
|
|
|
|
|
mergedMap[key].Amount = 0
|
|
|
|
|
}
|
|
|
|
|
keys = append(keys, key) // 将键添加到有序的键列表中
|
|
|
|
|
} else {
|
|
|
|
|
// 如果键已存在,进行累加操作
|
|
|
|
|
mergedMap[key].Count += data.Count
|
|
|
|
|
mergedMap[key].Amount += data.Amount
|
|
|
|
|
mergedMap[key].RejectAmount += data.RejectAmount
|
|
|
|
|
mergedMap[key].Difference += data.Difference
|
|
|
|
|
|
|
|
|
|
if data.PurchaseType == ErpRejectOrder {
|
|
|
|
|
mergedMap[key].RejectAmount = mergedMap[key].Amount
|
|
|
|
|
mergedMap[key].Amount = 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据有序的键列表顺序构建返回的数组
|
|
|
|
|
var mergedData []PurchaseReportData
|
|
|
|
|
for _, key := range keys {
|
|
|
|
|
mergedData = append(mergedData, *mergedMap[key])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mergedData
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// 导出供应商采购汇总excel
|
|
|
|
|
func reportBySupplierExport(req *ErpPurchaseReportBySupplierResp) (string, error) {
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
fSheet := "Sheet1"
|
|
|
|
|
|
|
|
|
|
url := ExportUrl
|
|
|
|
|
fileName := time.Now().Format(TimeFormat) + "供应商采购汇总" + ".xlsx"
|
|
|
|
|
fmt.Println("url fileName:", url+fileName)
|
|
|
|
|
|
|
|
|
|
// 组合标题栏数据
|
|
|
|
|
title := []interface{}{"店铺名称", "采购类型", "供应商", "商品名称", "商品分类", "采购数量", "采购金额", "退货金额", "差额"}
|
|
|
|
|
for i, _ := range title {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, 1)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, title[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("file set value err:", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var row []interface{}
|
|
|
|
|
nExcelStartRow := 0
|
|
|
|
|
for _, supplierData := range req.List {
|
|
|
|
|
var orderType string
|
|
|
|
|
switch supplierData.PurchaseType {
|
|
|
|
|
case "procure":
|
|
|
|
|
orderType = "采购入库"
|
|
|
|
|
case "reject":
|
|
|
|
|
orderType = "采购退货"
|
|
|
|
|
}
|
|
|
|
|
row = []interface{}{
|
|
|
|
|
supplierData.StoreName, // 店铺名称
|
|
|
|
|
orderType, // 采购类型
|
|
|
|
|
supplierData.ErpSupplierName, // 供应商
|
|
|
|
|
supplierData.ErpCommodityName, // 商品名称
|
|
|
|
|
supplierData.ErpCategoryName, // 商品分类
|
|
|
|
|
supplierData.Count, // 采购数量
|
|
|
|
|
supplierData.Amount, // 采购金额
|
|
|
|
|
supplierData.RejectAmount, // 退货金额
|
|
|
|
|
supplierData.Difference, // 差额
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for j, _ := range row {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, row[j])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nExcelStartRow++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalData := "记录数:" + strconv.FormatInt(int64(req.Total), 10)
|
|
|
|
|
end := []interface{}{"汇总", totalData, "", "", "",
|
|
|
|
|
req.Count, // 采购数量
|
|
|
|
|
req.Amount, // 采购金额
|
|
|
|
|
req.RejectAmount, // 退货金额
|
|
|
|
|
req.Difference, // 差额
|
|
|
|
|
}
|
|
|
|
|
for i, _ := range end {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, end[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置所有单元格的样式: 居中、加边框
|
|
|
|
|
style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},
|
|
|
|
|
"border":[{"type":"left","color":"000000","style":1},
|
|
|
|
|
{"type":"top","color":"000000","style":1},
|
|
|
|
|
{"type":"right","color":"000000","style":1},
|
|
|
|
|
{"type":"bottom","color":"000000","style":1}]}`)
|
|
|
|
|
|
|
|
|
|
//设置单元格高度
|
|
|
|
|
file.SetRowHeight("Sheet1", 1, 20)
|
|
|
|
|
|
|
|
|
|
// 设置单元格大小
|
|
|
|
|
file.SetColWidth("Sheet1", "A", "A", 25)
|
|
|
|
|
file.SetColWidth("Sheet1", "D", "D", 15)
|
|
|
|
|
|
|
|
|
|
endRow := fmt.Sprintf("I"+"%d", nExcelStartRow+2)
|
|
|
|
|
// 应用样式到整个表格
|
|
|
|
|
_ = file.SetCellStyle("Sheet1", "A1", endRow, style)
|
|
|
|
|
|
|
|
|
|
fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
|
|
|
|
|
if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
return url + fileName, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetReportDetail 查询采购明细
|
|
|
|
|
func GetReportDetail(req *ErpPurchaseReportDetailReq) (*ErpPurchaseReportDetailResp, error) {
|
|
|
|
|
page := req.PageIndex - 1
|
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if req.PageSize == 0 {
|
|
|
|
|
req.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
resp := &ErpPurchaseReportDetailResp{
|
|
|
|
|
PageIndex: page + 1,
|
|
|
|
|
PageSize: req.PageSize,
|
|
|
|
|
List: make([]struct {
|
2024-03-18 11:53:42 +00:00
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id"` // 采购订单id
|
|
|
|
|
OrderSerialNumber string `json:"order_serial_number"`
|
2024-03-27 10:01:38 +00:00
|
|
|
|
SerialNumber string `json:"serial_number"`
|
2024-03-18 11:53:42 +00:00
|
|
|
|
PurchaseType string `json:"purchase_type"`
|
|
|
|
|
ExecuteTime *time.Time `json:"execute_time"`
|
|
|
|
|
StoreId uint32 `json:"store_id"`
|
|
|
|
|
StoreName string `json:"store_name"`
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id"`
|
|
|
|
|
ErpSupplierName string `json:"erp_supplier_name"`
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id"`
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"`
|
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id"`
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"`
|
|
|
|
|
IMEIType uint32 `json:"imei_type"`
|
|
|
|
|
IMEI string `json:"imei"`
|
|
|
|
|
Price float64 `json:"price"`
|
|
|
|
|
EmployeePrice float64 `json:"employee_price"`
|
|
|
|
|
RejectPrice float64 `json:"reject_price"`
|
|
|
|
|
DifferencePrice float64 `json:"difference_price"`
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}, 0),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qs := orm.Eloquent.Debug().Table("erp_purchase_order").
|
2024-03-18 11:53:42 +00:00
|
|
|
|
Select("erp_purchase_order.id as erp_purchase_order_id, "+
|
|
|
|
|
"erp_purchase_order.serial_number as order_serial_number, "+
|
2024-03-27 10:01:38 +00:00
|
|
|
|
"erp_purchase_inventory.serial_number, "+
|
2024-03-06 02:07:55 +00:00
|
|
|
|
"erp_purchase_order.purchase_type, "+
|
|
|
|
|
"erp_purchase_inventory.created_at as execute_time, "+
|
|
|
|
|
"erp_purchase_order.store_id, "+
|
|
|
|
|
"erp_purchase_order.store_name, "+
|
|
|
|
|
"erp_purchase_order.erp_supplier_id, "+
|
|
|
|
|
"erp_purchase_order.erp_supplier_name, "+
|
|
|
|
|
"erp_purchase_inventory.erp_commodity_id, "+
|
|
|
|
|
"erp_purchase_inventory.erp_commodity_name, "+
|
|
|
|
|
"erp_purchase_inventory.erp_category_id, "+
|
|
|
|
|
"erp_purchase_inventory.erp_category_name, "+
|
|
|
|
|
"erp_purchase_inventory.imei_type, "+
|
|
|
|
|
"erp_purchase_inventory.imei, "+
|
|
|
|
|
"CASE "+
|
|
|
|
|
"WHEN erp_purchase_order.purchase_type = 'procure' THEN erp_purchase_inventory.implementation_price "+
|
|
|
|
|
"WHEN erp_purchase_order.purchase_type = 'reject' THEN erp_purchase_inventory.implementation_price "+
|
|
|
|
|
"ELSE 0 END AS price, "+
|
|
|
|
|
"CASE "+
|
|
|
|
|
"WHEN erp_purchase_order.purchase_type = 'procure' THEN 0 "+
|
|
|
|
|
"WHEN erp_purchase_order.purchase_type = 'reject' THEN erp_purchase_inventory.implementation_price "+
|
|
|
|
|
"ELSE 0 END AS reject_price, "+
|
|
|
|
|
"erp_purchase_inventory.employee_price, "+
|
|
|
|
|
"(erp_purchase_inventory.implementation_price - erp_purchase_inventory.employee_price) as difference_price").
|
|
|
|
|
Joins("JOIN erp_purchase_inventory ON erp_purchase_order.id = erp_purchase_inventory.erp_purchase_order_id").
|
|
|
|
|
Where("erp_purchase_order.state <> ?", 5) // 排除已终止的订单
|
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
// 创建一个新的查询对象,用于 count 查询
|
|
|
|
|
countQuery := orm.Eloquent.Debug().Table("erp_purchase_order").
|
|
|
|
|
Joins("JOIN erp_purchase_inventory ON erp_purchase_order.id = erp_purchase_inventory.erp_purchase_order_id").
|
|
|
|
|
Where("erp_purchase_order.state <> ?", 5) // 排除已终止的订单
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
if req.SerialNumber != "" {
|
|
|
|
|
qs = qs.Where("erp_purchase_order.serial_number = ?", req.SerialNumber)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
countQuery = countQuery.Where("erp_purchase_order.serial_number = ?", req.SerialNumber)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
if req.PurchaseType != "" {
|
|
|
|
|
qs = qs.Where("erp_purchase_order.purchase_type = ?", req.PurchaseType)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
countQuery = countQuery.Where("erp_purchase_order.purchase_type = ?", req.PurchaseType)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
if req.ErpCommodityName != "" {
|
|
|
|
|
qs = qs.Where("erp_purchase_inventory.erp_commodity_name LIKE ?", "%"+req.ErpCommodityName+"%")
|
2024-03-18 11:53:42 +00:00
|
|
|
|
countQuery = countQuery.Where("erp_purchase_inventory.erp_commodity_name LIKE ?", "%"+req.ErpCommodityName+"%")
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
if req.ErpCategoryID != 0 {
|
|
|
|
|
qs = qs.Where("erp_purchase_inventory.erp_category_id = ?", req.ErpCategoryID)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
countQuery = countQuery.Where("erp_purchase_inventory.erp_category_id = ?", req.ErpCategoryID)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
if req.ErpSupplierId != 0 {
|
|
|
|
|
qs = qs.Where("erp_purchase_order.erp_supplier_id = ?", req.ErpSupplierId)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
countQuery = countQuery.Where("erp_purchase_order.erp_supplier_id = ?", req.ErpSupplierId)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
if req.StartTime != "" { // 入/出库开始时间
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, req.StartTime)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("GetReportDetail err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("erp_purchase_inventory.created_at >= ?", parse)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
countQuery = countQuery.Where("erp_purchase_inventory.created_at >= ?", parse)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
if req.EndTime != "" { // 入/出库结束时间
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, req.EndTime)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("GetReportDetail err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("erp_purchase_inventory.created_at <= ?", parse)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
countQuery = countQuery.Where("erp_purchase_inventory.created_at <= ?", parse)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-18 11:53:42 +00:00
|
|
|
|
if len(req.StoreId) > 0 {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
qs = qs.Where("erp_purchase_order.store_id IN (?)", req.StoreId)
|
|
|
|
|
countQuery = countQuery.Where("erp_purchase_order.store_id IN (?)", req.StoreId)
|
2024-03-18 11:53:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
|
err := countQuery.Count(&count).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("GetReportDetail count err:", err)
|
|
|
|
|
return nil, err
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
offset := (req.PageIndex - 1) * req.PageSize
|
2024-03-18 11:53:42 +00:00
|
|
|
|
err = qs.Order("erp_purchase_inventory.created_at desc").
|
2024-03-06 02:07:55 +00:00
|
|
|
|
Offset(offset).
|
|
|
|
|
Limit(req.PageSize).
|
|
|
|
|
Scan(&resp.List).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("GetReportDetail scan err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据订单类型调整价格的正负性
|
|
|
|
|
for i := range resp.List {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
resp.List[i].DifferencePrice = 0
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
if resp.List[i].PurchaseType == "reject" {
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// 采购退货单查询采购价:根据采购入库编号
|
|
|
|
|
price, err := getPrice(resp.List[i].SerialNumber)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp.List[i].Price = -float64(price)
|
2024-03-06 02:07:55 +00:00
|
|
|
|
resp.List[i].DifferencePrice = -resp.List[i].DifferencePrice
|
|
|
|
|
resp.List[i].RejectPrice = -resp.List[i].RejectPrice
|
2024-03-27 10:01:38 +00:00
|
|
|
|
|
|
|
|
|
resp.List[i].DifferencePrice = resp.List[i].Price - resp.List[i].RejectPrice
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp.Total = int(count)
|
|
|
|
|
resp.Price, resp.EmployeePrice, resp.RejectPrice, resp.DifferencePrice = calculatePrices(resp.List)
|
|
|
|
|
|
|
|
|
|
if req.IsExport == 1 {
|
|
|
|
|
filePath, err := reportDetailExport(resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
resp = &ErpPurchaseReportDetailResp{}
|
|
|
|
|
resp.ExportUrl = filePath
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-27 10:01:38 +00:00
|
|
|
|
// 根据采购单据号查询入库采购价
|
|
|
|
|
func getPrice(serialNumber string) (uint32, error) {
|
|
|
|
|
var stockCommodity ErpStockCommodity
|
|
|
|
|
err := orm.Eloquent.Table("erp_stock_commodity").Where("stock_sn = ?", serialNumber).
|
|
|
|
|
Find(&stockCommodity).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return stockCommodity.WholesalePrice, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 02:07:55 +00:00
|
|
|
|
// 计算价格信息
|
|
|
|
|
func calculatePrices(list []struct {
|
2024-03-18 11:53:42 +00:00
|
|
|
|
ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id"` // 采购订单id
|
|
|
|
|
OrderSerialNumber string `json:"order_serial_number"`
|
2024-03-27 10:01:38 +00:00
|
|
|
|
SerialNumber string `json:"serial_number"`
|
2024-03-18 11:53:42 +00:00
|
|
|
|
PurchaseType string `json:"purchase_type"`
|
|
|
|
|
ExecuteTime *time.Time `json:"execute_time"`
|
|
|
|
|
StoreId uint32 `json:"store_id"`
|
|
|
|
|
StoreName string `json:"store_name"`
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id"`
|
|
|
|
|
ErpSupplierName string `json:"erp_supplier_name"`
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id"`
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"`
|
|
|
|
|
ErpCategoryID uint32 `json:"erp_category_id"`
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"`
|
|
|
|
|
IMEIType uint32 `json:"imei_type"`
|
|
|
|
|
IMEI string `json:"imei"`
|
|
|
|
|
Price float64 `json:"price"`
|
|
|
|
|
EmployeePrice float64 `json:"employee_price"`
|
|
|
|
|
RejectPrice float64 `json:"reject_price"`
|
|
|
|
|
DifferencePrice float64 `json:"difference_price"`
|
2024-03-06 02:07:55 +00:00
|
|
|
|
}) (price, employeePrice, rejectPrice, differencePrice float64) {
|
|
|
|
|
for _, item := range list {
|
|
|
|
|
price += item.Price
|
|
|
|
|
employeePrice += item.EmployeePrice
|
|
|
|
|
rejectPrice += item.RejectPrice
|
|
|
|
|
differencePrice += item.DifferencePrice
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 导出采购明细excel
|
|
|
|
|
func reportDetailExport(req *ErpPurchaseReportDetailResp) (string, error) {
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
fSheet := "Sheet1"
|
|
|
|
|
|
|
|
|
|
url := ExportUrl
|
|
|
|
|
fileName := time.Now().Format(TimeFormat) + "采购明细" + ".xlsx"
|
|
|
|
|
fmt.Println("url fileName:", url+fileName)
|
|
|
|
|
|
|
|
|
|
// 组合标题栏数据
|
|
|
|
|
title := []interface{}{"单据编号", "单据类型", "出/入库时间", "店铺名称", "供应商", "商品名称", "商品分类", "是否串码", "串码",
|
|
|
|
|
"采购价", "员工成本价", "退货价", "差价"}
|
|
|
|
|
for i, _ := range title {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, 1)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, title[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("file set value err:", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var row []interface{}
|
|
|
|
|
nExcelStartRow := 0
|
|
|
|
|
for _, detailData := range req.List {
|
|
|
|
|
var orderType string
|
|
|
|
|
switch detailData.PurchaseType {
|
|
|
|
|
case "procure":
|
|
|
|
|
orderType = "采购入库"
|
|
|
|
|
case "reject":
|
|
|
|
|
orderType = "采购退货"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var IMEIType string
|
|
|
|
|
switch detailData.IMEIType {
|
|
|
|
|
case 1:
|
|
|
|
|
IMEIType = "非串码"
|
|
|
|
|
case 2, 3:
|
|
|
|
|
IMEIType = "串码类"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
row = []interface{}{
|
|
|
|
|
detailData.OrderSerialNumber, // 单据编号
|
|
|
|
|
orderType, // 单据类型
|
|
|
|
|
detailData.ExecuteTime.Format(TimeFormat), // 出/入库时间
|
|
|
|
|
detailData.StoreName, // 店铺名称
|
|
|
|
|
detailData.ErpSupplierName, // 供应商
|
|
|
|
|
detailData.ErpCommodityName, // 商品名称
|
|
|
|
|
detailData.ErpCategoryName, // 商品分类
|
|
|
|
|
IMEIType, // 是否串码
|
|
|
|
|
detailData.IMEI, // 串码
|
|
|
|
|
detailData.Price, // 采购价
|
|
|
|
|
detailData.EmployeePrice, // 员工成本价
|
|
|
|
|
detailData.RejectPrice, // 退货价
|
|
|
|
|
detailData.DifferencePrice, // 差价
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for j, _ := range row {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, row[j])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nExcelStartRow++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalData := "记录数:" + strconv.FormatInt(int64(req.Total), 10)
|
|
|
|
|
end := []interface{}{totalData, "", "", "", "", "", "", "", "",
|
|
|
|
|
req.Price, // 采购价
|
|
|
|
|
req.EmployeePrice, // 员工成本价
|
|
|
|
|
req.RejectPrice, // 退货价
|
|
|
|
|
req.DifferencePrice, // 差价
|
|
|
|
|
}
|
|
|
|
|
for i, _ := range end {
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2)
|
|
|
|
|
err := file.SetCellValue(fSheet, cell, end[i])
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("file set value err:", logger.Field("err", err))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置所有单元格的样式: 居中、加边框
|
|
|
|
|
style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},
|
|
|
|
|
"border":[{"type":"left","color":"000000","style":1},
|
|
|
|
|
{"type":"top","color":"000000","style":1},
|
|
|
|
|
{"type":"right","color":"000000","style":1},
|
|
|
|
|
{"type":"bottom","color":"000000","style":1}]}`)
|
|
|
|
|
|
|
|
|
|
//设置单元格高度
|
|
|
|
|
file.SetRowHeight("Sheet1", 1, 20)
|
|
|
|
|
|
|
|
|
|
// 设置单元格大小
|
|
|
|
|
file.SetColWidth("Sheet1", "A", "A", 15)
|
|
|
|
|
file.SetColWidth("Sheet1", "C", "C", 20)
|
|
|
|
|
file.SetColWidth("Sheet1", "D", "D", 26)
|
|
|
|
|
file.SetColWidth("Sheet1", "F", "F", 18)
|
|
|
|
|
file.SetColWidth("Sheet1", "I", "I", 18)
|
|
|
|
|
|
|
|
|
|
endRow := fmt.Sprintf("M"+"%d", nExcelStartRow+2)
|
|
|
|
|
// 应用样式到整个表格
|
|
|
|
|
_ = file.SetCellStyle("Sheet1", "A1", endRow, style)
|
|
|
|
|
|
|
|
|
|
fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
|
|
|
|
|
if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
return url + fileName, nil
|
|
|
|
|
}
|
2024-03-27 10:01:38 +00:00
|
|
|
|
|
|
|
|
|
// CancelAuditUpdateStock 反审核后更新库存信息
|
|
|
|
|
// 查询订单有无入库信息
|
|
|
|
|
// 采购单,有入库信息,则退库;如果有已审核的退货单则不能反审核,报错提示
|
|
|
|
|
// 退货单,有入库信息,则入库
|
|
|
|
|
func CancelAuditUpdateStock(begin *gorm.DB, req ErpPurchaseOrder) error {
|
|
|
|
|
var purchaseOrder ErpPurchaseOrder
|
|
|
|
|
err := orm.Eloquent.Table("erp_purchase_order").Where("id=?", req.ID).Find(&purchaseOrder).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("checkPurchaseInventory purchase order err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var inventoryList []ErpPurchaseInventory
|
|
|
|
|
err = orm.Eloquent.Table("erp_purchase_inventory").Where("erp_purchase_order_id=?", req.ID).
|
|
|
|
|
Find(&inventoryList).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("purchase commodities err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(inventoryList) == 0 { // 还没有入库记录,直接取消审核
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if req.PurchaseType == ErpProcureOrder { // 采购单反审核
|
|
|
|
|
// 查询有无退货订单
|
|
|
|
|
var count int64
|
|
|
|
|
stateList := []int{ErpPurchaseOrderUnAudit, ErpPurchaseOrderEnd}
|
|
|
|
|
err = orm.Eloquent.Table("erp_purchase_order").Where("rejected_serial_number = ? and state NOT IN (?)",
|
|
|
|
|
req.SerialNumber, stateList).Count(&count).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if count > 0 { // 有已审核的退货单
|
|
|
|
|
return errors.New("取消审核失败:已存在采购退库订单,请先将其取消")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//// 更新入库的商品为"采购退库"
|
|
|
|
|
//reqParam := &ErpPurchaseInventoryReq{
|
|
|
|
|
// ErpPurchaseOrderId: req.ID,
|
|
|
|
|
// PurchaseType: ErpRejectOrder,
|
|
|
|
|
// Inventories: inventoryList,
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
// 按照采购退货更新库存
|
|
|
|
|
err = InventoryErpPurchaseUpdateRejectStock(begin, inventoryList, purchaseOrder)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("取消审核失败:%s", err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新采购商品表的入库数量
|
|
|
|
|
for _, v := range inventoryList {
|
|
|
|
|
err = begin.Model(&ErpPurchaseCommodity{}).
|
|
|
|
|
Where("erp_purchase_order_id = ? and erp_commodity_id = ?", v.ErpPurchaseOrderId, v.ErpCommodityId).
|
|
|
|
|
UpdateColumn("inventory_count", gorm.Expr("inventory_count - ?", v.Count)).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("update inventory count err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if req.PurchaseType == ErpRejectOrder { // 退货单反审核
|
|
|
|
|
// 更新入库的商品为"采购退库"
|
|
|
|
|
reqParam := &ErpPurchaseInventoryReq{
|
|
|
|
|
ErpPurchaseOrderId: req.ID,
|
|
|
|
|
PurchaseType: ErpProcureOrder,
|
|
|
|
|
Inventories: inventoryList,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 采购退货单反审核更新库存
|
|
|
|
|
err = ErpRejectOrderCancelAuditUpdateStock(begin, reqParam, purchaseOrder)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("取消审核失败:%s", err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新采购商品表的入库数量
|
|
|
|
|
for _, v := range inventoryList {
|
|
|
|
|
err = begin.Model(&ErpPurchaseCommodity{}).
|
|
|
|
|
Where("erp_purchase_order_id = ? and erp_commodity_id = ?", v.ErpPurchaseOrderId, v.ErpCommodityId).
|
|
|
|
|
UpdateColumn("inventory_count", gorm.Expr("inventory_count + ?", v.Count)).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("update inventory count err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return errors.New("取消审核失败:采购类型有误")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除采购入库的记录
|
|
|
|
|
err = begin.Table("erp_purchase_inventory").Where("erp_purchase_order_id = ? and purchase_type = ?",
|
|
|
|
|
req.ID, req.PurchaseType).Delete(&ErpPurchaseInventory{}).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpRejectOrderCancelAuditUpdateStock 采购退货单反审核更新库存
|
|
|
|
|
func ErpRejectOrderCancelAuditUpdateStock(gdb *gorm.DB, req *ErpPurchaseInventoryReq, purchaseOrder ErpPurchaseOrder) error {
|
|
|
|
|
// 遍历采购入库商品信息
|
|
|
|
|
var stockList []ErpStockCommodity
|
|
|
|
|
for _, v := range req.Inventories {
|
|
|
|
|
commodityInfo, err := GetCommodity(v.ErpCommodityId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("GetCommodity err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock WHERE store_id=%d AND erp_commodity_id=%d",
|
|
|
|
|
purchaseOrder.StoreId, v.ErpCommodityId))
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("exist err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if exist {
|
|
|
|
|
err = gdb.Exec(fmt.Sprintf(
|
|
|
|
|
"UPDATE erp_stock SET count=count+%d WHERE store_id=%d AND erp_commodity_id=%d;",
|
|
|
|
|
v.Count, purchaseOrder.StoreId, v.ErpCommodityId)).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("update stock err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return errors.New("未查询到商品库存信息")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新商品库存信息
|
|
|
|
|
// 串码商品直接更新状态为:在库
|
|
|
|
|
if v.IMEIType == 2 || v.IMEIType == 3 { // 串码商品
|
|
|
|
|
if v.IMEI == "" {
|
|
|
|
|
return fmt.Errorf("商品[%s]串码为空", v.ErpCommodityName)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = gdb.Table("erp_stock_commodity").Where("imei = ?", v.IMEI).
|
|
|
|
|
Update("state", InStock).Error // 状态更新为采购退货
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 非串码商品则新建
|
|
|
|
|
nowTime := time.Now()
|
|
|
|
|
stockCommodity := ErpStockCommodity{
|
|
|
|
|
StoreId: purchaseOrder.StoreId,
|
|
|
|
|
StoreName: purchaseOrder.StoreName,
|
|
|
|
|
ErpCommodityId: v.ErpCommodityId,
|
|
|
|
|
ErpCommodityName: v.ErpCommodityName,
|
|
|
|
|
CommoditySerialNumber: v.CommoditySerialNumber,
|
|
|
|
|
ErpCategoryId: commodityInfo.ErpCategoryId,
|
|
|
|
|
ErpCategoryName: commodityInfo.ErpCategoryName,
|
|
|
|
|
ErpSupplierId: purchaseOrder.ErpSupplierId,
|
|
|
|
|
ErpSupplierName: purchaseOrder.ErpSupplierName,
|
|
|
|
|
StaffCostPrice: uint32(v.EmployeePrice - v.ImplementationPrice),
|
|
|
|
|
WholesalePrice: uint32(v.ImplementationPrice),
|
|
|
|
|
State: InStock,
|
|
|
|
|
StorageType: PurchaseInventory, // 采购入库
|
|
|
|
|
FirstStockTime: nowTime,
|
|
|
|
|
StockTime: nowTime,
|
|
|
|
|
Count: v.Count,
|
|
|
|
|
ErpBarcode: commodityInfo.ErpBarcode, // 240106新增商品条码
|
|
|
|
|
IMEIType: v.IMEIType,
|
|
|
|
|
IMEI: v.IMEI,
|
|
|
|
|
Remark: "",
|
|
|
|
|
MemberDiscount: commodityInfo.MemberDiscount,
|
|
|
|
|
MinRetailPrice: commodityInfo.MinRetailPrice,
|
|
|
|
|
RetailPrice: commodityInfo.RetailPrice,
|
|
|
|
|
OriginalSn: purchaseOrder.SerialNumber,
|
|
|
|
|
}
|
|
|
|
|
stockList = append(stockList, stockCommodity)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := gdb.Debug().Create(&stockList).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("create stock commodity err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|