【问题标题】:How to design a relational model for double-entry accounting with job costing如何使用工作成本计算设计复式记账的关系模型
【发布时间】:2020-01-21 18:41:06
【问题描述】:

我想向读者推荐here 和here 的答案,因为它们的深度和思想深入人心。我在寻找与我正在进行的项目无关的内容时偶然发现了它们,然后我从头到尾阅读了它们。

我正在尝试使用这些原则(即复式记账法)构建一个利基市场应用程序,并加入工作成本计算。上述答案对重塑我的会计和会计概念非常有帮助。数据库应该看起来和工作起来像。但是,我很难将等式的工作成本部分整合到提供的优秀图形示例中。

有几个使用众议院、账户持有人、费用等的交易示例。我还有一些其他具体的用例,我很想得到一些意见:

  1. 我没有客户。我买了一个房产(通常现金用完,负债(贷款)产生,资产(房产)产生),花了一大笔钱来修理它(要么在商店兑现,信用卡收费商店,或写给供应商的支票,借记财产资产并借记或贷记资金来源),然后将其出售(现金进来,贷款还清,希望剩下的现金比我花的钱多该项目)。这可能会创建比我上面列出的更多的分类帐条目,但我不是会计师。我想我明白我所有的成本都用于我在房产中的基础,如果我的净收益大于我的基础,那么我就赚钱了,如果没有,那么就没有。

  2. 所以我需要记录的是 a) 来自特定帐户(即公司支票帐户或所有者的百思买卡等)的费用,b) 通常与特定工作相关联(但并非总是 - 我确实有办公用品等偶尔的间接费用),以及 c) 始终与成本代码相关联(即“100.12 - 窗户材料”、“100.13 - 窗户人工”等)。

  3. 我经常收到来自供应商的账单,这些账单将在未来某个时间到期。我想跟踪给定工作已收到但尚未支付的账单(承诺成本)。我认为这笔交易看起来像这样,但我不太确定:

  4. 正如您可能从我上面关于“所有者的百思买卡”的俏皮话中推测的那样,我有时(比我应该更频繁地)将我的个人资金用于与公司和工作相关的开支。我认为(再次警告我是外行)所有这些支出都记入“所有者权益”,并根据需要借记/贷记其他帐户。

我一直在一个又大又丑的电子表格中跟踪所有这些,这就是为什么我试图构建一个应用来替换它 - 电子表格方法效果不佳,而且肯定不会规模。

【问题讨论】:

  • @PerformanceDBA Halfer 准确地反映了共识。

标签: relational-database accounting


【解决方案1】:

初步

对于那些阅读此答案的人,请注意上下文如下,增量:

如果你还没有利用这一点,这个答案可能没有意义。

我会按照规范化的顺序进行回复,这当然与您提出问题的方式不同。

原理与修正

在你所陈述的问题中存在一些你没有意识到的错误,所以第一步是意识;理解。一旦问题被正确和准确地声明,它就很容易解决。这些是开发人员经常犯的错误,因此需要在考虑应用程序之前就对其进行理解。

1 第一原则

我一直在一个又大又丑的电子表格中跟踪所有这些[电子表格方法效果不佳,而且肯定无法扩展],这就是我尝试构建的原因替换它的应用程序

  • 如果手动(或以前的计算机化)系统出现故障,并且您实施了基于该系统的新应用或替换应用,则可以保证将这种损坏带入应用中。

    • 更糟糕的是,如果不理解这一点,可以编写第三个应用程序,承诺修复第二个应用程序中的问题,但它也保证迁移第一个和第二个应用程序中未修复的问题。
  • 因此,您必须识别并纠正您要替换的系统中的每一个问题,包括测试,然后才能设计出成功的应用和数据库。

  • 扩展是我们最不担心的事情。任何特定事物如何与任何其他事物一起工作是问题所在。

  • 你有一个又大又丑的电子表格,这意味着你有一个整体的视角:人类可以做到这一点,我们可以安享晚年,但计算机不能,它们需要明确的指令。

2 第二原则

我一直在一个又大又丑的电子表格中跟踪所有这些 [...] - 电子表格方法不太好用

  • 为什么它不起作用[就目前而言]?
    原因 1 之 2。
    你犯了一个开发人员经常犯的错误:你检查和研究一个事物的点点滴滴,这是在物理领域,并试图弄清楚这个事物是如何工作的。保证失败,因为事情是如何运作的;其目的;等等,是在智力领域,而不是物理领域。

    • 这里就不详述了,但大问题一定要注意。此错误是较大错误的特定实例,并且非常常见,即:
      开发人员专注于 GUI 的功能,
      而不是
      正确定义数据及其关系的需求,GUI 的功能在生存上是依赖的。
  • 一个没有学习过内燃机的人,即使仔细布置了零件,也无法通过查看已拆开的发动机零件来弄清楚如何制造发动机。更不用说带有喷油器或涡轮增压器的了。内燃原理是逻辑的,零件是物理的。

  • 在这里,您查看了其他人用来进行会计的电子表格,并且可能复制了这些电子表格,但不了解他们在使用电子表格做什么。

  • 举个例子。
    您已经检查了 first 和 second 链接的答案,并且您认为您可以弄清楚如何将其应用于修复脏大电子表格问题的新应用。

    • 许多开发人员认为,如果他们弄清楚具体细节、复制粘贴和替换,应用程序就会以某种方式运行。请注意经过深思熟虑但仍不完整的图形,其中详细说明了感知的交易。

    • 他们错过了逻辑领域,并在没有要求了解他们在搞什么乱的情况下搞乱了物理领域。

    • 总之,忘掉你和我的交易的漂亮图形,并努力理解逻辑(这个原则)和会计准则 [3]。

  • “测试驱动开发”又名“代码最少”又名“试错”是一种完全破产的方法,它没有科学依据(营销,是的,但科学,不是),它保证失败。危险,因为成本是持续的,永远不会有限。

    • 如果您了解上述内容,继续失败。

    • 更准确地说,它是反科学的,因为它与构建应用程序和数据库的科学相矛盾。

  • 因此,第一步是将庞大的电子表格分解为有目的的逻辑单元。当然,将每个引用电子表格列链接到引用电子表格中的正确列......这样任何金额值都不会重复。

3 第三原则

我一直在一个又大又丑的电子表格中跟踪所有这些 [...] - 电子表格方法不太好用

  • 为什么它不起作用,无论是现在还是当电子表格被划分为逻辑单元时?
    原因 2 之 2。
    缺乏标准。
    由于主题是会计,我们必须使用会计准则。

  • 那个又大又丑的电子表格就是你没有使用会计师来设置它的现成证据。当然,如果不了解会计或使用合格的会计师,您就无法设置一组电子表格来进行会计。

  • 因此,第二步是要么成为一名会计师,要么对会计有很好的了解。再次注意,您经过深思熟虑的交易的现成证据:尽管您是一个非常有能力的人,但您无法弄清楚first 和second 链接中的会计逻辑答案,更不用说您的应用(或手动系统)所需的会计了。

  • 所以我能给你的最好建议是,如 Double-Entry Accounting Answer 中所述,在网络上找到一些好的教程,然后学习它们。

  • 如果您这样做了,或者聘请了一位会计师来设置您的账簿,那么您会将单个大型电子表格拆分为标准的会计电子表格:

    • 资产负债表:
      • 资产或负债
    • 损益:
      • 收入或费用
    • 还有一组(稍后)
  • 说明这一原则的另一种方式是这样。当一个人不知道标准的存在时,或者更糟的是,当一个人故意选择不遵守它时,一个人就会处于重新发明轮子的危险境地,从头开始。又名“测试驱动开发”,又名“尽可能少的编码”,又名“反复试验”。这意味着一个人将经历一系列的发展增量,这些增量可以通过遵守标准来消除。

问题与解决方案

现在我们了解了这些原则,我们可以继续确定具体问题及其解决方案。其中每一个都是第三原则的具体应用。

4 财产/抵押处理

我没有客户。我买了一个房产(通常是现金用完,产生了负债(贷款),产生了资产(房产)),花了一大笔钱来修理它(要么在商店兑现,信用卡收费商店,或写给供应商的支票,借记财产资产并借记或贷记资金来源),然后将其出售

  • 我并不是说你没有听从我在Double-Entry Answer 中给出的建议。我是说您没有意识到建议的严重性;它在会计上下文中的含义(在我们冒险进入数据库上下文之前)。

  • 金钱代表价值。钱;价值,不能被创造或毁灭。它只能移动。从一个桶到另一个桶。根据 [3],需求是正确定义和安排您的存储桶。

  • 该属性未创建,它已经存在。当您购买房产时,您的现金会转移到银行,而他们的财产也会转移给您。仅在幼稚的意义上,财产现在是“资产”,抵押现在是“负债”。稍后将在适当的会计桶中澄清这种天真。

  • 事实上,您是一家小型的单一分行银行;合作社;一个赌场。 Double-Entry Accounting Answer 的准确上下文。以下情况适用于
    一组更正的电子表格,
    或适用于遵循和实施Double-Entry Accounting Answer(如果您直接进入应用程序 . .. 无需测试对单个电子表格的更正)。

    • 了解这一点非常重要,因为它与您所在国家/地区的立法有关,而您没有提及。该法规将被您称为税收,或您的企业纳税申报表。即使您在任何时候只持有一处房产。

    • 您的“客户”是为每家物业服务的每家银行。为属性命名。

    • 每个抵押(财产)都应设置为外部帐户。这将允许您仅针对它进行与它实际相关的那些交易。贷款支付;银行收费;花费;等等。在房产出售之前,不会有任何收入。

    • 在任何情况下,外部账户都将与银行为您提供的抵押账户银行对账单相匹配(您没有提及,但这是会计的基本要求)。

    • 根据Double-Entry Accounting Answer 中的定义,ExternalAccount 上的每一笔交易都将在分类帐中具有一个复式分支。更多,稍后。

    • 无论是会计术语中的资产还是负债,都是分类帐条目的功能,而不是外部帐户的功能。 (无论如何,我们都知道它代表一种财产,从幼稚的角度来看,它是一种“资产”,直到它开始亏损,当它从幼稚的角度来看,它变成了一种“负债”。)

  • 定义这一点的另一种方式是,银行贷款代表一种合同,在该合同上货币(价值)“易手”(被转移)。您聘请的银行是“客户”,即外部账户。您必须将与合同相关的所有收入和费用与合同一起保存。

利基市场应用 ...
我还有一些其他特定用例 ...

  • 不,你没有。太阳底下没有新鲜事。如果您正确设置帐簿(使用会计准则的多个链接电子表格),这是一个普通的用例。希望我的解释已经证明了这一事实。

5 分类帐

以上几点与智力领域有关,对每个问题的理解以及其中的解决方案,在物理领域几乎没有工作,这点对智力有同样的要求,在物理层面。即击键次数;检查;变化;在正确设置之前检查...。

  • 虽然第一个链接的答案涉及:
    Derived vs Stored Account Balance(高效且可审核的处理重新月末),
    第二个链接的答案涉及:
    Double-Entry Accounting(在现有会计系统中实施总体会计准则,更高水平的审计能力),
    两者都没有详细解释分类帐。

  • 分类帐是任何会计系统的核心条目。

    • 复式系统不是独立的文章,而是该分类帐的进步。

    • data model 是特定的如何正确设置数据库以供应用程序和任何报告客户端软件使用,平安无事。

  • 您没有真正的分类帐。单个大电子表格不是分类帐。

  • 您必须根据 [3] 设置分类帐。充其量,该电子表格中的某些项目将成为分类帐中的条目,但请注意,由于 [1][2][3] 中提出的更正,您会对它们有完全不同的看法。

  • 请注意,当我们说“将其放入分类帐”或“不在分类帐中”时,为简单起见,我们的确切意思是对单个分类帐条目的引用,其中由分类帐中的特定帐号标识。

  • 同样,当我们说“帐户”时,我们指的是分类帐中的单个帐号。

    • 如果交易不在分类帐中(特定帐号,LedgerNo,DEA 贷记/借记的一个分支),则它不在“帐户”中,不会计入。
  • 您将在这里设置真正的资产和负债账户。这是出于内部目的,在分类帐中,如 data model 中 Internal 的边距中声明的那样。

  • 我能给你的最好建议是,在网上搜索会计教程;确定哪些是好的;仔细研究它们,以便为您的目的建立一个适当的分类帐。

  • 简单的答案是,分类帐是帐号的层次结构。

    • 其中叶级别是可以进行交易的实际AccountNo,
      并且非叶子级别的存在是为了聚合,不允许交易。

    • 每当报告分类帐(或分类帐的任何衍生产品,例如资产负债表或损益表)时:
      层次结构由缩进显示, 交易账户条目显示当月的当前余额
      并且聚合帐户条目显示它下面的树的聚合

[您的图形重新交易]

  • 首先,每笔交易都在账本中。这意味着复式记帐交易的一个分支在分类帐中。查看§ 5 in my Double-Entry Accounting Answer,注意每个业务事务至少有一个蓝色条目(不要担心其他细节)。

  • 其次,DEA 的另一条腿是:

    • 任一在分类帐中,这意味着资金在一个分类帐户 LedgerNo 和另一个分类帐户 LedgerNo 之间移动。注意两边都是蓝色的商业交易。

    • 或在外部账户中,表示资金在一个分类账户 LedgerNo 和一个外部账户 AccountNo 之间移动。请注意一侧为蓝色另一侧为绿色的业务交易。

  • 当您了解这一点并设置了您的 Ledger 时,就不会有“??”在您的图形中,将显示蓝色/绿色。 (不要重新做你的图形,我希望这个答案就足够了。)

    • 您的“asset/liab”指定不正确。更准确地说,在完全定义和安排分类帐之前做出该声明还为时过早。首先设置您的分类帐,并牢记每个条目的资产/负债。这样您就不必在每笔交易中声明“资产/liab”,因为这是账本帐号LedgerNo 的函数,而不是交易的函数。

a) 来自特定账户(即公司支票账户或所有者的 Best Buy 卡等)的费用,

分类帐-外部帐户
(分类帐中的一条 DEA 分支,外部帐户中的另一条分支)。注意上面的警告。另一个 DEA 分支将是其中之一(层次结构):

  • 费用/物业改善/结构/材料
  • 费用/物业改善/结构/劳动力
  • 费用/物业改善/配件/材料
  • 费用/物业改善/装修/人工
  • 费用/物业改善/家具

c) 的费用始终与成本代码相关联(即“100.12 - 窗户材料”、“100.13 - 窗户人工”等)。

您将不再有“成本代码”,它们都将是分类帐帐号LedgerNos,因为分类帐是您记录任何事情的地方。

分类帐中的一个 DEA 分支,特定财产的外部帐户中的另一分支。层次结构将与上一点相同。

b) 一般与特定工作相关的费用

分类帐-外部帐户
(账本中的一个 DEA 分支,外部帐户中的另一个分支)。

(但并非总是如此 - 我确实有偶尔像办公用品这样的间接费用)

账本-账本

  • 支出或负债 LedgerNo 分类帐中的一条 DEA 分支 ... 这笔钱已支付给

    • 费用/常规/办公用品
  • 收入或资产LedgerNo 的分类帐中的另一条腿...这笔钱是从

    支付的
  • 收入/每月应付

6 信用卡及其他信用卡处理

信用卡收费
百思买卡

您的每张卡都代表一个合同,一个需要进行交易的账户,必须与发卡机构提供的月度报表相平衡。

  • 将每一个都设置为外部帐户,这里一个 DEA 分支,另一个在分类帐中。

  • “业主的百思买卡”对我来说不清楚(谁是业主,你还是业主......如果是后者,那么到目前为止的假设,“你”买卖房产是不正确的。)

    • 无论如何,我相信我已经提供了足够的细节让你弄清楚。

    • 不要将业主的财产帐户和他们的 Best Buy 卡合并到一个外部帐户中:为每个帐户保留单独的外部帐户。

7 作业成本核算

请注意,我将在最后解决这个问题,因为一旦您解决了大问题,剩下的问题就会很小。您提出的大问题(工作成本计算;每项财产的损益)一旦为您的业务正确设置了分类帐,实际上就是小问题。

据我所知,作业成本核算是我尚未解决的唯一剩余问题。首先,这里要理解的问题是,Actuals 和 Estimates 之间的区别。到目前为止,我讨论的所有内容都是实际的。

  • 对于估计,标准程序是在分类帐中设置单独的帐户结构(层次结构中的树)。这些通常被称为悬念账户,如悬念持有的钱。

  • 如果处理得当,这些帐户将阻止您在所有估算值转移到实际值之前关闭或最终确定外部帐户(暂停为零)。

  • 业务交易与实际交易完全相同。

  • 这将提供对此类数字的精确跟踪,以及项目从 Estimate 移动到 Actual 时的差异。

8 数据模型• 作业成本核算

注意first 和second 链接答案中的数据模型是完整的,其中分类帐没有扩展:

  • 这个答案涉及分类帐的解释,这个数据模型给出了Ledger的完整定义

    • 由AccountType整理
    • 单父层次结构
      • 只能针对叶级 LedgerAccount 进行交易
      • 中间层LedgerIntermediate用于汇总它下面的树。
  • 我已经进一步规范化Transaction

  • 扩展外部 Account 以显示个人与组织

  • 所有的约束都是明确的。

对于内嵌图形来说显然太大了。这是一个分两页的PDF:

  • 单独的数据模型(如上)
  • 带有示例数据和注释的数据模型,它包括答案中涵盖的所有示例
  • 注意 Ledger 中的缩进,它表示 Account 层次结构

评论

如何插入第一个分类帐(例如 100 资产,没有父级)?

分类帐是一个树,一个单父层次结构(由于奇怪的原因又称为“单向”),根据帐户层次结构。 root 行是必需的。在数据库构建操作中(使用文件中的 DDL),我们通常会执行所有CREATE TABLEs,然后是所有ADD CONSTRAINT FKs。使用CREATE TABLE 插入 root 行。

  • 之后
    CREATE TABLE Ledger
    做
    INSERT Ledger VALUES ( 0, 0, "I", "AL", "Root", ... ).

  • 之后
    CREATE TABLE LedgerIntermediate
    做
    INSERT LedgerIntermediate VALUES ( 0 ).

鉴于Comprises 的反面是belongs to,所有一级分类帐例如。 Fees, House, Interbank 和您的 Asset 将 belong to 这个 root 行。

【讨论】:

  • 如何插入第一个账本(例如 100 资产,无父账本)?由于LedgerIntermediate-Ledger 是强制的一对多,所以LedgerNo_Parent 必须是NOT NULL。将LedgerNo_Parent 插入为NULL 是不可能的,并且插入一些值也是不可能的,因为LedgerIntermediate 中没有Ledger.LegerNo_Parent 可以引用的行。
  • @marcos 我在答案中添加了说明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
  • 2019-01-07
  • 1970-01-01
相关资源
最近更新 更多