今天有一个客户提出一个需求:在销售开单的时候,要自动带出销售价格。
先看一下金蝶KIS专业版系统本身的功能:销售价格政策可以做到周期定价,按客户类别+物料
或者客户+物料
这2种维度,按订货量的阶梯进行报价。
但是客户的要求是:按照不同的客户类别,在最近采购价格的基础上进行上浮n个百分点(下称客户毛利
)。
举个例子:1级客户利润率为5%,2级客户利润率为7%。最近采购订货价格为50,那么给1级客户进行销售开单时,销售价格应等于:50(1+0.05);给2级客户进行销售开单时,销售价格应等于:50(1+0.07)。
下面看一下如何实现?
思路
第一步、设置客户类别和客户毛利的对应关系表
第二步、新建客户类别+物料
的销售价格政策,作为客户最新销售价格的载体,每次新增物料时自动把物料同步到价格政策里面
第三步、当采购订单审核时,将采购单价*客户毛利
更新至销售价格政策表里面
第一步 客户分类和客户毛利对应表
在金蝶KIS专业版里面,客户分类是作为辅助资料存在的,其属性无法新增自定义的字段值。
那如何给客户类别指定具体的毛利值呢?
最初想着是在数据库的辅助资料表(t_SubMessage)中新增一个字段,提前在数据库中更新好。但是如果客户想自己维护修改这个值,或者有新增加的客户类别,就很不方便。
于是想了个办法:
我们知道,在金蝶KIS专业版的核算项目资料中,可以新增自定义核算项目,并且可以对新增的自定义核算项目添加属性字段。所以,可以在核算项目里面做一下文章。
所以,利用自定义核算项目就可以实现客户分类和客户毛利的对应表。
为了让客户感觉更人性化,这里做了一个同步的功能:当辅助资料中新建了客户类别之后,系统会自动将代码和名称同步到核算项目里面。
实现思路
当辅助资料表中插入客户类别后,在核算项目表中的客户毛利中插入同样的数据
相关表
客户类别:select * from t_SubMessage where FTypeID = 501
自定义核算项目-客户毛利:select * from t_Item where FItemClassID = 3001
自定义属性-毛利:select * from t_Item_3001
主要关联关系:将客户类别内码传递到了客户毛利的编码中
代码
create trigger tr_SubMessage_MaoliEntry
on t_SubMessage
for insert
as
begin
declare @FItemClassID int = 3001 -- 自定义核算项目“客户毛利”的分类内码
declare @FNumber int -- 辅助资料中“客户类别”的内码
declare @FName nvarchar(255) -- 辅助资料中“客户类别”的名称
if exists (select * from inserted where FTypeID = 501)
select @FNumber = FInterID,@FName = FName from inserted
insert into t_item(fitemclassid,fnumber,fparentid,flevel,fdetail,fname,ffullnumber,fshortnumber)
values (@FItemClassID,@FNumber,0,1,1,@FName,@FNumber,@FNumber)
-- 生成下游数据后,关联标志置1
update t_submessage set FMaoliEntry = 1 where FInterID = @FNumber
end
第二步 新增物料自动插入到价格方案中
先按照客户类别
+物料
建立一个价格政策方案:
为了方便客户使用,想实现每次新增物料时,自动将物料同步到价格方案中。
这里遇到了一些困难。
物料表是t_icitem,当我在create trigger on t_icitem for insert
的时候,发现报错了:
消息 8197,级别 16,状态 6,过程 t_fj,第 1 行
对象 't_icitem' 不存在,或对此操作无效。
原来t_icitem是视图
,所以需要用create trigger on t_icitem instead of insert
,之前的教程里面有说过触发器分2种,for/after
是不能用于视图的。所以用instead of
,然而:
消息 2111,级别 16,状态 1,过程 t_fj,第 6 行
无法对 视图 't_icitem' 创建 触发器 't_fj',因为此对象已有 INSTEAD OF INSERT 触发器。
系统已经在t_icitem
表上创建了instead of
触发器,而且一个表只能存在一个instead of
触发器。只能在原来的基础上去新增insert
语句了。
找到原始代码
在触发器上点击鼠标右键,打开修改
添加代码
IF not EXISTS (SELECT 1 FROM deleted)
begin
insert into ICPrcPlyEntry(FInterID,FItemID,FRelatedID,FModel,FAuxPropID,FUnitID,FBegQty,FEndQty,FCuryID,FPriceType,FPrice,FBegDate,FEndDate,FLeadTime,FNote,FChecked,FIndex,FTime,FID,FBase,FBase1,FBegQty_Base,FEndQty_Base,FInteger,FClassTypeID,FBCust,FB2CustCls,FB2Emp,FB2EmpCls,FB2VipGrp,FB2Cust,FB2ItemID,FB2Item,FFlagSave)
select
3 as "FInterID", -- 价格政策方案的内码
t1.fitemid as "FItemID", --物料id
t2.FInterID as "FRelatedID",
0 as "FModel",
0 as "FAuxPropID",
t1.FSaleUnitID as "FUnitID",
0 as "FBegQty",
999999 as "FEndQty",
1 as "FCuryID",
0 as "FPriceType",
1 as "FPrice",
'2020-01-01 00:00:00.000' as "FBegDate",
'2090-01-01 00:00:00.000' as "FEndDate",
0 as "FLeadTime",
'新增物料自动生成' as "FNote", --FNote
0 as "FChecked", --FChecked
1 as "FIndex",
null as "FTime",
0 as "FID",0 AS "FBase",0 as "FBase1",0 as "FBegQty_Base",0 as "FEndQty_Base",0 as "FInteger",0 as "FCLassTypeID",0 as "FBCust",0 as "FB2CustCls",0 as "FB2Emp",0 as "FB2EmpCls",0 as "FB2VipGrp",0 as "FB2Cust",0 as "FB2ItemID",0 as "FB2Item",'' as "FFLagSave"
from inserted t1 left join t_submessage t2 on 1=1 where t2.ftypeid = 501
end
这里值得注意的是:在同一个Trigger里同时包含Insert,Update,Delete。需要对执行过程进行一下判断。
开始没有判断的时候,总是插入重复的记录,每次修改物料名称或代码也会重复插入重复的记录。
参考:https://www.bbsmax.com/A/qVdeg47pJP/。
create trigger 触发名 on 表名
instead of insert,update,delete
as
--insert插入
if not exists(select 1 from deleted)
begin
打印插入
end
--update更新
if exists(select 1 from inserted) and exists(select 1 from deleted)
begin
打印修改
end
--delete删除
if not exists(select 1 from inserted)
begin
打印删除
end
go
只判断更改了某列
if update(colname)
第三步 更新价格方案
当采购订单审核之后,将采购价格*毛利 更新至价格方案的报价中。并且审核报价。
思路
采购订单按照基本计量单位的含税单价进行计算,价格政策中的计量单位要考虑换算率的问题。
难点
难点一、多计量单位的情况下,怎么计算价格
难点二、关联的表比较多,有采购订单表头、表体、价格政策表、辅助资料表、计量单位表、自定义核算项目表。
代码
alter trigger tr_POOrder_UICPrc
on POOrder
for update
as
begin
declare @FInterID int
declare @FCheckerID int
if update(FCheckerID) begin
select @FInterID = FInterID,@FCheckerID = FCheckerID from deleted
if @FCheckerID is null begin
if OBJECT_ID('tempdb..#prc') is not null
drop table #prc
create table #prc(FEntryID int , FPrice decimal(23,10))
insert into #prc(FEntryID,FPrice)
select v1.t2PrcFentryID,v1.FSprc from (
select t1.FItemID as "t1POFItemID",t1.FQty,t1.FPrice,t1.FPriceDiscount,
t2.FEntryID as "t2PrcFentryID",t2.FInterID as "t2PrcFinterID",t2.FItemID,t2.FUnitID,
t3.FName,t3.FInterID,t3.FTypeID,t6.F_102,
t4.FCoefficient,
t1.FPriceDiscount * t4.FCoefficient * (1+t6.F_102/100) as "FSprc"
from POOrderEntry t1 left join ICPrcPlyEntry t2 on t1.FItemID = t2.FItemID
left join t_SubMessage t3 on t3.FInterID = t2.FRelatedID
left join t_MeasureUnit t4 on t4.FMeasureUnitID = t2.FUnitID
left join t_item t5 on t5.fnumber = cast(t3.finterid as varchar)
left join t_item_3001 t6 on t6.fitemid = t5.fitemid
where t3.FTypeID = 501 and t2.FInterID = 3 and t1.FInterid = @FInterID) v1
select * from #prc
update t1 set t1.FPrice = t2.FPrice,t1.FChecked = 1 from ICPrcPlyEntry t1,#prc t2 where t1.FEntryID = t2.FEntryID
end
end
end
用到的相关表
价格政策表头:select * from ICPrcPly
价格政策表体:select * from ICPrcPlyEntry
物料视图:select * from t_icitem
核算项目:select * from t_item
计量单位:select * from t_MeasureUnit
辅助资料:select * from t_SubMessage where FTypeID = 501 --增加关联标志列FMaoliEntry
核算项目:select * from t_item where fitemclassid = 3001 --增加核算项目类别-客户毛利后生成
核算项目属性:select * from t_item_3001
采购订单表体:select * from POOrderEntry
客户:select * from t_Organization