如何实现计费系统

时间:2013-03-06 16:10:39

标签: database-design business-logic billing application-design web-application-design

我在数据库income_fundsexpenditure_funds中有两个集合:

income_funds
    timestamp
    amount
    status (not confirmed, confirmed, refunded)

expenditure_funds
    timestamp
    amount

我需要获得当前帐户余额并获取有关使用的报告。如何更好地使用此集合实现计费逻辑?

最简单的方式(没有其他数据):

  1. 获取帐户余额sum(confirmed income_funds) - sum(expenditure_funds)
  2. 获取报告按期间获得收入和支出资金
  3. 但我不喜欢我必须一直计算帐户余额。

    添加帐户集:

    我将添加account集合:

    account
        balance
    
    1. 获取帐户余额只需获取account.balance
    2. 以上一个方法获取报告
    3. 但我不喜欢在任何资金发生变化(增加或改变状态)时,我必须随时改变平衡。要验证帐户余额,我必须按照第一种方法计算所有资金。如果我弄错了,我将不知道它是如何以及何时发生的。

      添加期间集合:

      我将添加period集合:

      period
          is_closed (yes, no)
          start_timestamp
          end_timestamp
          start_balance
          end_balance
      
      1. 获取帐户余额最后返回period.end_balance
      2. 以上一种方式获取报告,但很容易按期间获取时间戳
      3. 任何资金在期间发生变化时,我必须随时更改end_balance。但是我可以按期间验证平衡,如果有错误,我会知道它发生在这个时期。


        最后一种方法最喜欢我,但也许有人可以在我的结论中给我建议或者知道其他解决方案。

2 个答案:

答案 0 :(得分:2)

我认为你的设计有些问题。我会建议一些不同的东西(这里非常简化,注意我专业地建立会计软件):

account (id, account_number, description, account_type)
journal (id, name, description)
journal_entry (id, journal_id, reference, description, transaction_date, memo)
journal_line (journal_entry_id, account_id, amount)
invoice (id, journal_entry_id, customer_vendor_id, duedate, terms)
invoice_line (id, invoice_id, goods_service_id, qty, sellprice, discount)
account_checkpoint (id, account_id, debits, credits, balance, end_date)

然后你所做的就是在journal_entry上有一个触发器,这样任何在这里transaction_date早于max(account_checkpoint.end_date)的条目都被拒绝。通过这种方式,您可以从上一个关闭期间和开放期间前滚。这使报告变得更加容易,并最大限度地减少了您实际需要聚合的内容。

其他检查点表也可以添加期间,因此如果企业愿意,您可以比AP更频繁地关闭AR,反之亦然。通过这种方式,检查点既可以作为结束点,也可以作为可以前滚生成报告的点。

答案 1 :(得分:1)

我想我已经在我的项目中使用了所有3个选项。您可以根据项目的范围和可能性决定走哪条路。

如果您的数据库支持触发器,那么您可以使用单独的Balance表,并在* _funds表中具有更新/插入/删除触发器,以更新Balance表中的数据。这可确保无论数据如何变化,您的平衡始终是正确的。我建议使用这个选项。

如果您没有大量数据并且您不需要经常计算余额,那么您可以重新计算总和。恕我直言,它会使得将传入和传出资金存储在一个表中更容易一些。添加指示事务方向的额外字段(事务)(1表示传入,-1表示费用)。然后你可以通过

来获得平衡
SELECT SUM(amount*transaction) from funds

第三,当我将数据存储在月度文件中时,我已经使用该选项在过去有定期余额。每当创建新文件时,第一条记录就是开始余额,从上个月的数据当场计算。我还提供了在上个月数据发生变化的极少数情况下重新计算余额的可能性。当用户非常清楚自己在做什么时,这可以正常工作 - 例如在会计系统中,会计师知道他需要重新计算余额。

相关问题