UML软件工程组织

帐务模式在代理结算系统中的应用
选自:www.analysispattern.com/patterns/agent.htm

 

代理是一种销售方式,代理商通过出售源厂商的产品或推广服务商提供的服务获得利润,不管是产品还是服务,代理商和产品/服务商之间的利润计算都是基于更优惠的代理价格(对产品代理而言,代理价格可能跟历史代理销售收入有关,如果上年度或上季度的代理销售收入较高,可能代理价格就更优惠),或者基于代理销售收入本身(对服务代理而言,更有可能是这种形式,代理销售收入越高,代理佣金也就越高),或者可能的其他方式;因为基于代理价格的结算相对而言较为简单,结算通过代理商对购买的产品付费已经完成,所以,我们在这里要应用到帐务模型进行处理的,不是基于代理价格的结算,而是基于代理销售收入的结算。

假设有这样一种代理商,代理推销汽车美容服务,代理商会跟服务商签订合同,规定代理条款,付费方式,各自的责任权利,等等。当代理商发展的顾客来消费的时候,顾客的汽车美容活动是顾客的事件,会产生顾客维护账单(帐务条目),然后,这个账单将成为代理商的原始事件,根据合同规定的规则(Posting Rule)产生代理商的帐务条目。

代理结算还有一个特点,就是一般按某个时间单位结算,例如一个月,一个季度,一年之类的,然后代理商的结构可能还会包括代理商下面的客户,客户下面还会有用户(象前面的例子,可能代理商发展了一个公司作为客户,然后公司里头的员工可以作为独立消费的用户),根据用户和客户的消费额不同,合同规则可能会不同,例如,月消费1万元以上的可能成为VIP客户,代理商可以提成10%,而对普通的客户代理商只能提成8%

用户消费产生的费用应该跟用户相关,而这些费用一般会分为很多种类,例如洗车,油漆,打腊,个性内装,防紫外线处理,发动机清洁护理等,因为每个种类的成本和效益不同,所以它们的提成比例也可能不同。

好的,假设代理商和服务商签订了如下合同:

代理商帮助服务商发展客户和用户,推广各项汽车美容服务,对所有客户高中低档(参见项目档次规定说明)美容服务每月累计实收费用进行提成,提成比例分别为高档20万元及以下8%20万元以上10%;中档6%;低档3%;其中,实收月消费超过10000元人民币的客户成为VIP客户,提成比例按实际消费额增加2%,代理费用按月结算,每月5日之前服务商将上月的结算款付给代理商。欠款部分等归还以后再按同样规则计提成。

(注:以上数据仅作讲解示范用。)

根据这样一些特点和相似性,以及上一节提到过的帐务模式,我们发现,帐务模式可以应用到这个问题上,尤其是Posting Rule,可以解决结算规则的灵活设置。

首先我们来看代理商的层次结构,它可能包含客户,也可能客户还包含用户,也可能代理商不包含客户,只包含用户(象推广连锁店服务),要解决这样灵活的层次结构,在这样可以用到Party模式中的层次组织结构模式,并稍作一些调整:

Party模式中的层次结构模型支持多种灵活的层次结构,但这里我们只要关心上下级的包含关系就可以了,参加结算的称为结算实体BalanceEntity,不可再拆分的称为LeafEntity,可以包含下级结算实体的称为CompositeEntity,因此在这里还可以支持一些象客户群,用户群这样的概念(一般没有那么复杂)。

从前面可以看到,代理商签有合同Agreement(如有多个代理商,合同内容可能相同也可能不同),在合同里面规定了不同的业务Business(汽车美容服务推广),每种业务的结算规则(BusinessRule,对应帐务模式中的PostingRule)各不相同,而结算规则作用在不同的服务项目(ServiceItem)上,因此,我们需要抽象出合同,业务,业务结算规则,服务项目,组成主要的模型结构。

为了从系统外部配置规则,我们同样还需要抽象出项目类别,规则类别和它们之间的关系(需要注意的是,项目从用户向客户汇总属于业务结算规则的一部分,还有最后的结算账目总额,也是规则的一部分,需要纳入配置)。同时,根据“范围”模式一文中的比例模型,这里有些规则需要用到比例,因此,它也需要加入模型。

具体的模型如下图所示:

如上图所示,虚线上面是基本的模型结构,下面是用来进行配置的类型和关系,其中的费用项目类别ItemType作为规则类别RuleType的参数和结果;而RuleType跟比例类别相关联,BusinessRule的计算方法也在RuleType中指定。

在前面的例子中,系统初始化的时候,建立代理商,客户,用户(作为叶子实体)的结算实体结构,建立它们之间的关联关系,根据费用项目类型,初始化费用项目(包括所有的具体费用项目,高中低三档的费用累计项目,和所有费用累计项目,普通佣金项目,和VIP佣金项目,佣金总和项目),费用项目容器,然后针对费用项目建立处理规则,和需要的比例(包括3个固定比例:中档佣金比例,低档佣金比例,VIP额外佣金比例和1个范围比例:高档佣金比例)。

而佣金计算的过程可用下面的序列图来表示:

费用数据集合的处理序列图如下:

模型的扩展

上面的模型基本可以解决代理商和服务提供商之间的结算合同,如果过了一段时间,代理商又和服务商签订了下面的合同条款:

代理商帮助服务商推广连锁店服务,对每家由代理商发展的连锁店,按参加金额5万,20万,100万及以上分别提成2%5%10%;以后的每月,根据它们的利润,按1万,5万,10万及以上分别提成1%2%3%

现在,又怎样面对这个问题呢?

首先来看结算实体结构,代理商,连锁店,好像还比较幸运,结算实体模型可以适用,然后,合同,嘿,合同,业务Business(新的业务是连锁店推广)都还在,新的服务项目有首月连锁参加金额,该金额累计,该金额对应佣金,连锁店经营利润,利润累计,利润对应的佣金,计算规则和比例同样可以制订,需要对系统增加新的BusinessRule子类和实现,如果用表达式解析等方法对规则的计算进行配置,那么不必对BusinessRule进行继承或更改实现。

好像问题解决了,不是吗?用原来的模型,需要的东西都可以从中找到,但是,服务提供商说,等等,我们要这个代理商的佣金结算金额,分别给出来,但是,不要分成两次计算,希望应用一次运行就能出所有的结果。 (注:该需求仅用于举例说明。)

这样好像有点问题,从上面可以看到,我们是分两个合同,两次运行才能得到服务推广佣金和连锁代理佣金,怎么办呢?

回到上面的模型,我们可以看到,代理商和合同之间的关系是1对多,可以支持多个合同,但是,两个合同规定中的结算实体完全不同,如果放在一起结算,结果不会出错,但是会导致许多无用的ServiceItems,和多余的计算过程,想想,同时对服务推广合同下的客户和用户计算连锁佣金和利润提成,以及还要对连锁用户计算服务推广佣金(它们根本就不存在),这是非常不合理的。

可以这样,将代理商与合同的关联上移到基类,从而可以让代理商关联到两个合同,而代理商下属的结算实体关联具体的合同,并由具体的合同和具体的下属结算实体一起进行计算。这样,模型进行小小的改变,支持了应用的完整性。以后增加新的代理商,新的合同条款,多个合同,一样可以适用。

如图所示:

该模型适合中小型代理结算系统,以及适用于其他行业代理结算业务。

 

版权所有:UML软件工程组织