使用各种条款计算经常性付款的未来收入预测

时间:2011-05-04 21:25:51

标签: recurring revenue

我有各种套餐的服务,可以每月,每季度,每半年和每年购买。

每个包都有一个due_on日期,当有人续订时,我会递增。

通过查看本月谁有到期日,可以很容易地计算出我本月可以大致预期的收入。

我遇到麻烦的地方是计算明年每个月的收入。我不能将它建立在due_on之上,因为有些人将在明年支付12次,有些人将支付6次等等。

最好的方法是什么? 注意:为此我无视磨损。 我在PHP和MySQL工作,但我要求理论,所以这不应该太重要。

1 个答案:

答案 0 :(得分:1)

让我们来看看未来12个月的月收入情况。

我可以看到两种基本方法:

  1. 为接下来的12个月中的每一个创建一个桶的数组(或哈希)。然后,遍历每个活动订阅,并为每个订阅将该预期收入添加到每个适当的存储桶。例如,如果条款是每月,请将该付款添加到每个存储桶;如果该期限为季度,则将该付款添加到当前due_date月份的桶中,并在此之后的3个月,6个月和9个月添加桶;这对代码来说相当简单,但有足够的客户生成报告可能需要一些时间。

  2. 在mysql数据库中创建一个临时表,其中包含(monthamount)列,并用一系列插入语句填充它(有一堆;我会得到他们在一分钟内,然后在那张桌子上做报告。

    这有点不寻常,所以我将更详细地拼出来。我正在对你的SQL表结构做一些假设,但我试图让它尽可能保持通用。

    首先,您需要临时表,我们最初会根据当前due_on日期填写每月收入:

    CREATE TEMPORARY TABLE FutureRevenueReport
    SELECT
      CONCAT(YEAR(s.due_on), '-', MONTH(s.due_on)) as revenue_month,
      s.due_amount as revenue_amount
    FROM subscriptions s WHERE s.active = 'True';
    

    现在在同一个mysql会话中,执行这一系列的insert语句以填补未来的收入:

    INSERT INTO FutureRevenueReport(revenue_month, revenue_amount)
    SELECT CONCAT(YEAR(s.due_on + INTERVAL 1 MONTH), '-', 
                  MONTH(s.due_on + INTERVAL 1 MONTH)), s.due_amount
    FROM subscriptions s WHERE s.active = 'True' AND s.term = 'MONTHLY';
    
    INSERT INTO FutureRevenueReport(revenue_month, revenue_amount)
    SELECT CONCAT(YEAR(s.due_on + INTERVAL 2 MONTH), '-', 
                  MONTH(s.due_on + INTERVAL 2 MONTH)), s.due_amount
    FROM subscriptions s WHERE s.active = 'True' AND s.term = 'MONTHLY';
    
    INSERT INTO FutureRevenueReport(revenue_month, revenue_amount)
    SELECT CONCAT(YEAR(s.due_on + INTERVAL 3 MONTH), '-', 
                  MONTH(s.due_on + INTERVAL 3 MONTH)), s.due_amount
    FROM subscriptions s WHERE s.active = 'True' AND s.term = 'MONTHLY';
    -- etc, up to + INTERVAL 11 MONTH
    
    -- Now the quarterly:
    INSERT INTO FutureRevenueReport(revenue_month, revenue_amount)
    SELECT CONCAT(YEAR(s.due_on + INTERVAL 3 MONTH), '-', 
                  MONTH(s.due_on + INTERVAL 3 MONTH)), s.due_amount
    FROM subscriptions s WHERE s.active = 'True' AND s.term = 'QUARTERLY';
    
    INSERT INTO FutureRevenueReport(revenue_month, revenue_amount)
    SELECT CONCAT(YEAR(s.due_on + INTERVAL 6 MONTH), '-', 
                  MONTH(s.due_on + INTERVAL 6 MONTH)), s.due_amount
    FROM subscriptions s WHERE s.active = 'True' AND s.term = 'QUARTERLY';
    -- And the same for 9 months
    -- Then do the same thing for SEMI-ANNUALLY and + INTERVAL 6 MONTH
    
    -- And now the report:
    SELECT revenue_month, sum(revenue_amount) as revenue from FutureRevenueReport
    GROUP BY revenue_month;