package models import "time" // ERP 进销存交易层模型,对应 docs/sql/erp_inventory_schema.sql。 // // 核心约定: // - 库存结存 yz_backend_erp_stock 只允许由库存流水(yz_backend_erp_stock_ledger) // 驱动变更,任何业务代码不得直接改 quantity/cost_price; // - 十类业务单据统一存 yz_backend_erp_document(+_item),用 doc_type 区分; // - tenant_id 为字符串(与 ERP/CRM 家族表一致),便于与客户/供应商表 JOIN。 // 单据类型 const ( ErpDocPurchaseOrder = "purchase_order" // 采购订单 ErpDocPurchaseIn = "purchase_in" // 采购入库 ErpDocPurchaseReturn = "purchase_return" // 采购退货 ErpDocSalesOrder = "sales_order" // 销售订单 ErpDocSalesOut = "sales_out" // 销售出库 ErpDocSalesReturn = "sales_return" // 销售退货 ErpDocOtherIn = "other_in" // 其他入库 ErpDocOtherOut = "other_out" // 其他出库 ErpDocTransfer = "transfer" // 库存调拨 ErpDocStockTake = "stock_take" // 库存盘点 ) // 单据状态 const ( ErpDocStatusDraft int8 = 0 // 草稿 ErpDocStatusPending int8 = 1 // 审批中 ErpDocStatusApproved int8 = 2 // 已生效 ErpDocStatusRejected int8 = 3 // 已驳回 ErpDocStatusCancelled int8 = 4 // 已作废 ) // 往来账类型 const ( ErpBillReceivable int8 = 1 // 应收 ErpBillPayable int8 = 2 // 应付 ) // 收付款类型 const ( ErpFundReceive int8 = 1 // 收款 ErpFundPay int8 = 2 // 付款 ErpFundOtherIn int8 = 3 // 其他收入 ErpFundExpense int8 = 4 // 费用支出 ) // 流水方向 const ( ErpStockIn int8 = 1 ErpStockOut int8 = -1 ) // ErpProductCategory 商品分类: yz_backend_erp_product_category type ErpProductCategory struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"` CategoryName string `orm:"column(category_name);size(100)" json:"category_name"` ParentID uint64 `orm:"column(parent_id);default(0)" json:"parent_id"` SortOrder int `orm:"column(sort_order);default(0)" json:"sort_order"` Status int8 `orm:"column(status);default(1)" json:"status"` Remark string `orm:"column(remark);size(500)" json:"remark"` CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"` UpdateTime time.Time `orm:"column(update_time);type(datetime);null;auto_now" json:"update_time"` DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"` } func (m *ErpProductCategory) TableName() string { return "yz_backend_erp_product_category" } // ErpProduct 商品档案: yz_backend_erp_product type ErpProduct struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"` ProductCode string `orm:"column(product_code);size(64)" json:"product_code"` ProductName string `orm:"column(product_name);size(200)" json:"product_name"` CategoryID uint64 `orm:"column(category_id);default(0)" json:"category_id"` Brand string `orm:"column(brand);size(100)" json:"brand"` Spec string `orm:"column(spec);size(200)" json:"spec"` Model string `orm:"column(model);size(100)" json:"model"` BaseUnit string `orm:"column(base_unit);size(32)" json:"base_unit"` AuxUnit string `orm:"column(aux_unit);size(32)" json:"aux_unit"` AuxRatio float64 `orm:"column(aux_ratio);type(decimal);digits(18);decimals(4);default(1)" json:"aux_ratio"` Barcode string `orm:"column(barcode);size(64)" json:"barcode"` ExtraBarcodes string `orm:"column(extra_barcodes);size(500)" json:"extra_barcodes"` PurchasePrice float64 `orm:"column(purchase_price);type(decimal);digits(18);decimals(4)" json:"purchase_price"` SalePrice float64 `orm:"column(sale_price);type(decimal);digits(18);decimals(4)" json:"sale_price"` WholesalePrice float64 `orm:"column(wholesale_price);type(decimal);digits(18);decimals(4)" json:"wholesale_price"` MemberPrice float64 `orm:"column(member_price);type(decimal);digits(18);decimals(4)" json:"member_price"` MinPrice float64 `orm:"column(min_price);type(decimal);digits(18);decimals(4)" json:"min_price"` TaxRate float64 `orm:"column(tax_rate);type(decimal);digits(9);decimals(4)" json:"tax_rate"` SafetyQty float64 `orm:"column(safety_qty);type(decimal);digits(18);decimals(4)" json:"safety_qty"` MaxQty float64 `orm:"column(max_qty);type(decimal);digits(18);decimals(4)" json:"max_qty"` ShelfLifeDays int `orm:"column(shelf_life_days);default(0)" json:"shelf_life_days"` EnableBatch int8 `orm:"column(enable_batch);default(0)" json:"enable_batch"` ImageURL string `orm:"column(image_url);size(500)" json:"image_url"` Status int8 `orm:"column(status);default(1)" json:"status"` IsDraft int8 `orm:"column(is_draft);default(0)" json:"is_draft"` Remark string `orm:"column(remark);type(text);null" json:"remark"` CreateUserID string `orm:"column(create_user_id);size(64)" json:"create_user_id"` CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"` UpdateTime time.Time `orm:"column(update_time);type(datetime);null;auto_now" json:"update_time"` DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"` // 联查展示字段(非表列) CategoryName string `orm:"-" json:"category_name"` TotalStock float64 `orm:"-" json:"total_stock"` SafetyState string `orm:"-" json:"safety_state"` Stocks []map[string]interface{} `orm:"-" json:"stocks"` } func (m *ErpProduct) TableName() string { return "yz_backend_erp_product" } // ErpWarehouse 仓库: yz_backend_erp_warehouse type ErpWarehouse struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"` WarehouseCode string `orm:"column(warehouse_code);size(64)" json:"warehouse_code"` WarehouseName string `orm:"column(warehouse_name);size(100)" json:"warehouse_name"` Address string `orm:"column(address);size(255)" json:"address"` Manager string `orm:"column(manager);size(50)" json:"manager"` Phone string `orm:"column(phone);size(20)" json:"phone"` IsDefault int8 `orm:"column(is_default);default(0)" json:"is_default"` Status int8 `orm:"column(status);default(1)" json:"status"` Remark string `orm:"column(remark);size(500)" json:"remark"` CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"` UpdateTime time.Time `orm:"column(update_time);type(datetime);null;auto_now" json:"update_time"` DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"` } func (m *ErpWarehouse) TableName() string { return "yz_backend_erp_warehouse" } // ErpStock 库存结存: yz_backend_erp_stock。唯一键 (tenant, product, warehouse, batch)。 type ErpStock struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"` ProductID uint64 `orm:"column(product_id)" json:"product_id"` WarehouseID uint64 `orm:"column(warehouse_id)" json:"warehouse_id"` BatchNo string `orm:"column(batch_no);size(64)" json:"batch_no"` Quantity float64 `orm:"column(quantity);type(decimal);digits(18);decimals(4)" json:"quantity"` CostPrice float64 `orm:"column(cost_price);type(decimal);digits(18);decimals(6)" json:"cost_price"` UpdateTime time.Time `orm:"column(update_time);type(datetime);null;auto_now" json:"update_time"` // 联查展示字段(非表列) ProductName string `orm:"-" json:"product_name"` ProductCode string `orm:"-" json:"product_code"` Spec string `orm:"-" json:"spec"` BaseUnit string `orm:"-" json:"base_unit"` WarehouseName string `orm:"-" json:"warehouse_name"` SafetyQty float64 `orm:"-" json:"safety_qty"` MaxQty float64 `orm:"-" json:"max_qty"` PurchasePrice float64 `orm:"-" json:"purchase_price"` } func (m *ErpStock) TableName() string { return "yz_backend_erp_stock" } // ErpStockLedger 库存流水(只增不改不删): yz_backend_erp_stock_ledger type ErpStockLedger struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"` ProductID uint64 `orm:"column(product_id)" json:"product_id"` WarehouseID uint64 `orm:"column(warehouse_id)" json:"warehouse_id"` BatchNo string `orm:"column(batch_no);size(64)" json:"batch_no"` Direction int8 `orm:"column(direction);default(1)" json:"direction"` Quantity float64 `orm:"column(quantity);type(decimal);digits(18);decimals(4)" json:"quantity"` BeforeQty float64 `orm:"column(before_qty);type(decimal);digits(18);decimals(4)" json:"before_qty"` AfterQty float64 `orm:"column(after_qty);type(decimal);digits(18);decimals(4)" json:"after_qty"` UnitCost float64 `orm:"column(unit_cost);type(decimal);digits(18);decimals(6)" json:"unit_cost"` TotalCost float64 `orm:"column(total_cost);type(decimal);digits(18);decimals(2)" json:"total_cost"` DocType string `orm:"column(doc_type);size(30)" json:"doc_type"` DocID uint64 `orm:"column(doc_id)" json:"doc_id"` DocNo string `orm:"column(doc_no);size(64)" json:"doc_no"` DocItemID uint64 `orm:"column(doc_item_id)" json:"doc_item_id"` ProductionDate *time.Time `orm:"column(production_date);type(date);null" json:"production_date"` ExpireDate *time.Time `orm:"column(expire_date);type(date);null" json:"expire_date"` OperatorID string `orm:"column(operator_id);size(64)" json:"operator_id"` OperatorName string `orm:"column(operator_name);size(64)" json:"operator_name"` Remark string `orm:"column(remark);size(500)" json:"remark"` CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"` ProductName string `orm:"-" json:"product_name"` ProductCode string `orm:"-" json:"product_code"` Spec string `orm:"-" json:"spec"` BaseUnit string `orm:"-" json:"base_unit"` WarehouseName string `orm:"-" json:"warehouse_name"` } func (m *ErpStockLedger) TableName() string { return "yz_backend_erp_stock_ledger" } // ErpDocument 业务单据主表: yz_backend_erp_document type ErpDocument struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"` DocNo string `orm:"column(doc_no);size(64)" json:"doc_no"` DocType string `orm:"column(doc_type);size(30)" json:"doc_type"` BizDate time.Time `orm:"column(biz_date);type(date)" json:"biz_date"` WarehouseID uint64 `orm:"column(warehouse_id);default(0)" json:"warehouse_id"` ToWarehouseID uint64 `orm:"column(to_warehouse_id);default(0)" json:"to_warehouse_id"` PartnerType string `orm:"column(partner_type);size(20)" json:"partner_type"` PartnerID uint64 `orm:"column(partner_id);default(0)" json:"partner_id"` PartnerName string `orm:"column(partner_name);size(200)" json:"partner_name"` SourceDocID uint64 `orm:"column(source_doc_id);default(0)" json:"source_doc_id"` TotalQty float64 `orm:"column(total_qty);type(decimal);digits(18);decimals(4)" json:"total_qty"` TotalAmount float64 `orm:"column(total_amount);type(decimal);digits(18);decimals(2)" json:"total_amount"` DiscountAmount float64 `orm:"column(discount_amount);type(decimal);digits(18);decimals(2)" json:"discount_amount"` ActualAmount float64 `orm:"column(actual_amount);type(decimal);digits(18);decimals(2)" json:"actual_amount"` Status int8 `orm:"column(status);default(0)" json:"status"` InstanceID uint64 `orm:"column(instance_id);default(0)" json:"instance_id"` AuditorID string `orm:"column(auditor_id);size(64)" json:"auditor_id"` AuditorName string `orm:"column(auditor_name);size(64)" json:"auditor_name"` AuditTime *time.Time `orm:"column(audit_time);type(datetime);null" json:"audit_time"` Remark string `orm:"column(remark);type(text);null" json:"remark"` CreateUserID string `orm:"column(create_user_id);size(64)" json:"create_user_id"` CreateUserName string `orm:"column(create_user_name);size(64)" json:"create_user_name"` CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"` UpdateTime time.Time `orm:"column(update_time);type(datetime);null;auto_now" json:"update_time"` DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"` Items []ErpDocumentItem `orm:"-" json:"items,omitempty"` WarehouseName string `orm:"-" json:"warehouse_name"` ToWarehouseName string `orm:"-" json:"to_warehouse_name"` SourceDocNo string `orm:"-" json:"source_doc_no"` DocTypeLabel string `orm:"-" json:"doc_type_label"` StatusLabel string `orm:"-" json:"status_label"` Instance map[string]interface{} `orm:"-" json:"instance,omitempty"` } func (m *ErpDocument) TableName() string { return "yz_backend_erp_document" } // ErpDocumentItem 业务单据明细: yz_backend_erp_document_item type ErpDocumentItem struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` DocID uint64 `orm:"column(doc_id)" json:"doc_id"` TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"` ProductID uint64 `orm:"column(product_id)" json:"product_id"` ProductName string `orm:"column(product_name);size(200)" json:"product_name"` Spec string `orm:"column(spec);size(200)" json:"spec"` Unit string `orm:"column(unit);size(32)" json:"unit"` WarehouseID uint64 `orm:"column(warehouse_id);default(0)" json:"warehouse_id"` BatchNo string `orm:"column(batch_no);size(64)" json:"batch_no"` Quantity float64 `orm:"column(quantity);type(decimal);digits(18);decimals(4)" json:"quantity"` BookQty float64 `orm:"column(book_qty);type(decimal);digits(18);decimals(4)" json:"book_qty"` ExecutedQty float64 `orm:"column(executed_qty);type(decimal);digits(18);decimals(4)" json:"executed_qty"` RefItemID uint64 `orm:"column(ref_item_id);default(0)" json:"ref_item_id"` UnitPrice float64 `orm:"column(unit_price);type(decimal);digits(18);decimals(6)" json:"unit_price"` Amount float64 `orm:"column(amount);type(decimal);digits(18);decimals(2)" json:"amount"` ProductionDate *time.Time `orm:"column(production_date);type(date);null" json:"production_date"` ExpireDate *time.Time `orm:"column(expire_date);type(date);null" json:"expire_date"` Remark string `orm:"column(remark);size(500)" json:"remark"` SortOrder int `orm:"column(sort_order);default(0)" json:"sort_order"` ProductCode string `orm:"-" json:"product_code"` BaseUnit string `orm:"-" json:"base_unit"` StockQty float64 `orm:"-" json:"stock_qty"` // 当前可用库存(开单时展示) } func (m *ErpDocumentItem) TableName() string { return "yz_backend_erp_document_item" } // ErpPartnerBill 往来账(应收/应付): yz_backend_erp_partner_bill type ErpPartnerBill struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"` BillType int8 `orm:"column(bill_type);default(1)" json:"bill_type"` PartnerType string `orm:"column(partner_type);size(20)" json:"partner_type"` PartnerID uint64 `orm:"column(partner_id)" json:"partner_id"` PartnerName string `orm:"column(partner_name);size(200)" json:"partner_name"` SourceDocID uint64 `orm:"column(source_doc_id)" json:"source_doc_id"` SourceDocNo string `orm:"column(source_doc_no);size(64)" json:"source_doc_no"` BillDate time.Time `orm:"column(bill_date);type(date)" json:"bill_date"` DueDate *time.Time `orm:"column(due_date);type(date);null" json:"due_date"` Amount float64 `orm:"column(amount);type(decimal);digits(18);decimals(2)" json:"amount"` SettledAmount float64 `orm:"column(settled_amount);type(decimal);digits(18);decimals(2)" json:"settled_amount"` Status int8 `orm:"column(status);default(0)" json:"status"` Remark string `orm:"column(remark);size(500)" json:"remark"` CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"` UpdateTime time.Time `orm:"column(update_time);type(datetime);null;auto_now" json:"update_time"` } func (m *ErpPartnerBill) TableName() string { return "yz_backend_erp_partner_bill" } // ErpFundBill 收付款单: yz_backend_erp_fund_bill type ErpFundBill struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"` FundNo string `orm:"column(fund_no);size(64)" json:"fund_no"` FundType int8 `orm:"column(fund_type);default(1)" json:"fund_type"` PartnerType string `orm:"column(partner_type);size(20)" json:"partner_type"` PartnerID uint64 `orm:"column(partner_id);default(0)" json:"partner_id"` PartnerName string `orm:"column(partner_name);size(200)" json:"partner_name"` Amount float64 `orm:"column(amount);type(decimal);digits(18);decimals(2)" json:"amount"` SettledAmount float64 `orm:"column(settled_amount);type(decimal);digits(18);decimals(2)" json:"settled_amount"` PayMethod string `orm:"column(pay_method);size(30);default(cash)" json:"pay_method"` PayAccount string `orm:"column(pay_account);size(100)" json:"pay_account"` BizDate time.Time `orm:"column(biz_date);type(date)" json:"biz_date"` Status int8 `orm:"column(status);default(0)" json:"status"` Remark string `orm:"column(remark);size(500)" json:"remark"` CreateUserID string `orm:"column(create_user_id);size(64)" json:"create_user_id"` CreateUserName string `orm:"column(create_user_name);size(64)" json:"create_user_name"` CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"` UpdateTime time.Time `orm:"column(update_time);type(datetime);null;auto_now" json:"update_time"` DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"` Settles []ErpFundSettle `orm:"-" json:"settles,omitempty"` } func (m *ErpFundBill) TableName() string { return "yz_backend_erp_fund_bill" } // ErpFundSettle 收付款核销明细: yz_backend_erp_fund_settle type ErpFundSettle struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"` FundBillID uint64 `orm:"column(fund_bill_id)" json:"fund_bill_id"` PartnerBillID uint64 `orm:"column(partner_bill_id)" json:"partner_bill_id"` PartnerBillNo string `orm:"column(partner_bill_no);size(64)" json:"partner_bill_no"` Amount float64 `orm:"column(amount);type(decimal);digits(18);decimals(2)" json:"amount"` CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"` } func (m *ErpFundSettle) TableName() string { return "yz_backend_erp_fund_settle" } // ErpDocTypeLabel 单据类型中文名(后端返回给两端的统一口径) var ErpDocTypeLabel = map[string]string{ ErpDocPurchaseOrder: "采购订单", ErpDocPurchaseIn: "采购入库", ErpDocPurchaseReturn: "采购退货", ErpDocSalesOrder: "销售订单", ErpDocSalesOut: "销售出库", ErpDocSalesReturn: "销售退货", ErpDocOtherIn: "其他入库", ErpDocOtherOut: "其他出库", ErpDocTransfer: "库存调拨", ErpDocStockTake: "库存盘点", } // ErpDocAffectsStock 单据生效是否产生库存流水 func ErpDocAffectsStock(docType string) bool { switch docType { case ErpDocPurchaseOrder, ErpDocSalesOrder: return false default: return true } } // ErpDocStatusLabel 单据状态中文名 func ErpDocStatusLabel(status int8) string { switch status { case ErpDocStatusPending: return "审批中" case ErpDocStatusApproved: return "已生效" case ErpDocStatusRejected: return "已驳回" case ErpDocStatusCancelled: return "已作废" default: return "草稿" } } // ErpDocBizTypePrefix 单据类型对应审批流 biz_type(与 approval.go 常量一致) func ErpDocApprovalBizType(docType string) string { return "erp_" + docType }