关于带有分页的Double Entry Accounting系统存在一个非常严重的问题,我认为这很普遍,但是我仍然没有找到解决我问题的方法。

您可以使用此链接来阅读简单的Double Entry Accounting系统,就像我用Laravel和AngularJS制作的系统一样。

在此系统中,预期结果(例如)如下所示:

ID      In       Out    Balance

1      100.00    0.00   100.00

2       10.00    0.00   110.00

3        0.00   70.00    40.00

4        5.00    0.00    45.00

5        0.00   60.00   -15.00

6       20.00    0.00     5.00

如果将所有交易显示在一页中,则很容易在累积函数中跟踪余额,最后一笔交易的余额是一天结束时的当前余额。

例如,对于特定日期范围$fromDate-> $toDate,我们喜欢:

$balanceYesterday = DB::table('journal')->where('date', '

->join('transactions','transactions.journal_id','journal.id')->where('transactions.type',"=", 0) /* 0 means the account of the company */

->select(DB::raw('SUM(amount) as total_balance'))

->first()->total_balance;

现在我们有了昨天的余额,我们依靠它来计算累积循环中直到此过程结束为止的余额,直到$toDate;

$currentBalance = $currentBalance + $currentTransaction->amount;

$currentTransactionBalance = $currentBalance;

现在,当您有大量交易时,真正的问题就开始了,您需要将它们分页$journal = $journal->paginate(100);,假设每页100个交易,系统将按预期工作在第一页,因为我们已经可以计算并依靠它来计算每次交易后到首页中100笔交易结束时的新余额。

下一页将出现一个问题,即它不知道第一页中上一个事务的最后余额是多少,因此它将再次从$balanceYesterday开始,从而使整个表的计算错误。

我首先要解决的问题是,将最后一个事务amount(在前端)作为参数传输到下一页,并将其用作重新计算的起始金额,这是我拥有的最佳解决方案仅使用<< PREV和NEXT >>按钮,因此很容易修复它。

但是我最近发现,如果我对页码进行分页,则此解决方法将不起作用,因为用户希望浏览各个页面以浏览日记,因此现在无法知道特定页面的最后余额,并且系统将显示错误的计算。

我想做的是找到一种方法来计算特定交易的余额,不管是贷方还是借方,我正在寻找一种方法来知道在特定交易中完成特定交易后的余额是多少到目前为止,我不想添加新的余额列,也不想在其中保存余额,用户不时对交易进行了大量修改和修改,而所有小额修改都会对所有交易造成破坏平衡之后,我不能以任何方式依赖交易ID,因为交易可能具有不同的随机日期,因此将不会按ID进行排序,但可能会按日期,帐户所有者或类型等其他字段进行排序。 。

我一直在这个问题上摸爬滚打大约4个月,我在网上搜索并没有找到解决方案,我希望在经过这么长时间的解释后,我的问题已经很清楚了,希望有人可以为我提供解决方案。

谢谢。

您永远不应该依赖ID值的顺序,这些ID值仅用于标识单个记录,而不用于排序等。在这种情况下,排序顺序是按日期排序,但是我不知道您对相同日期的条目会做什么因为他们的顺序是不确定的。

我从不依赖它们,我先按日期排序,然后再按ID排序以保存同一天进行的交易的正确顺序,感谢上帝,我们不使用小时或分钟,仅使用日期:|

但是,当您按日期排序时,所有具有相同日期的条目都是未定义的,因此您不能按日期排序。并写道:您不能依赖ID的订单,它是未定义的顺序。

我不明白为什么我不能按日期排序,请查看此屏幕快照以了解情况,我们不在乎特定日期的交易时间,同一天进行的交易均以其默认顺序排序。 image.ibb.co/kW90U7/Screen_Shot_2018_04_15_at_02_09_59.png

数据库的结果集仅具有未定义的顺序作为默认顺序。因此,如果按日期排序,则具有相同日期的所有记录都是未定义的顺序。无论如何,这可能有点太理论化了,在您的情况下,请先按日期排序,然后再按ID排序,因为没有重复的ID,所以实际上应该这样做。

我相信,此时您真正需要的唯一一件事就是计算从分页数据集(所有记录,而不仅仅是当前页面的记录)开始到当前页面上显示的第一条记录之前的所有事务的总和。

通过查找整个数据集的开始与当前页面的事务之间发生的事务数,然后通过LIMIT检索它们并将它们加起来,可以得到此结果。

您首先要拥有的是分页查询的确切约束。由于我们要获取除当前页面以外的其他分页记录子集,因此您需要确保两个查询的结果都在相同的顺序中。重用查询构建器对象可以有所帮助(调整以匹配您的实际分页查询):

$baseQuery = DB::table('journal')

->join('transactions', 'transactions.journal_id', 'journal.id')

->where('date', '>', $fromDate)

->where('date', '

->where('transactions.type',"=", 0)

->orderBy('date', 'asc');

// Note that we aren't fetching anything here yet.

然后,获取分页的结果集。这将执行两个查询:一个查询记录总数,第二个查询特定页面的事务。

$paginatedTransactions = $baseQuery->paginate(100);

从这里,我们可以确定检索先前余额所需的记录。返回的分页对象是LengthAwarePaginator的实例,该实例知道总共有多少条记录,页数,其上当前页等。

使用这些信息,我们可以做一些数学运算来获取所需的记录数:

total records needed = (current page - 1) * records per page

假设用户在第5页上,他们将看到记录401-500,因此我们需要检索以前的400条记录。

// If we're on Page 1, or there are not enough records to

// paginate, we don't need to calculate anything.

if ($paginatedTransactions->onFirstPage() || ! $paginatedTransactions->hasPages()) {

// Don't need to calculate a previous balance. Exit early here!

}

// Use helper methods from the Paginator to calculate

// the number of previous transactions.

$limit = ($paginatedTransactions->currentPage() - 1) * $paginatedTransactions->perPage();

现在我们有了在数据集中但在当前页面之前发生的事务数,我们可以再次使用基本查询来检索和计算总和:

$previousBalance = $baseQuery->limit($limit)->sum('amount');

Adding a highlight here to explain that using your database to perform the SUM calculations will be a big performance benefit, rather than doing it in a loop in PHP. Take advantage of the DB as often as you can!

将此余额添加到原始的"昨天"余额中,对于分页交易,您应该有一个准确的期初余额。

注意:理论上所有伪编码的内容都可能需要调整。如有疑问或问题,很高兴进行修改。

谢谢,我忍不住要哭,因为这几乎是一个完美的解决方案,但是从理论上讲,因为当您调用$previousBalance = $baseQuery->limit($limit)->sum(amount);时它正在计算当前页面中的项目数量,就像您调用->paginate时那样publicating?值,即使将$paginatedTransactions保存为临时值并调用分页方法,它也会以某种方式影响$ baseQuery结果!

伙计,我爱你,非常感谢您提供的出色解决方案,我通过使用Request()->get(page)和自定义$perPage值计算$limit解决了该问题,并且在计算$previousBalance之后运行了分页功能,因此它不会影响结果,谢谢:(

查看Builder::paginate(),看起来确实可以进一步修改构建器。您也可以使用clone关键字来复制基本查询构建器,以防止出现这种情况。很高兴我能帮上忙!

你真的做到了,你很棒,谢谢。

您应该能够为每个记录的余额制定一个真值陈述,只要您可以知道在该有序列表中的每个点上计算余额总和的顺序是什么。

确保这样做会带来巨大的开销,因为您需要查询整个表以显示每条记录,但是首先必须能够做到这一点。如示例所示,只要不分页就可以。

对于分页,您可以做的是预先计算每条记录的余额并将其相对于原始记录进行存储。这样可以对数据进行非规范化,但是这样做的好处是创建分页非常简单。

谢谢,我只是在发布时编辑我的问题,我是说我不想将余额保存在新列中,我之前尝试了一段时间,结果非常糟糕,用户正在更改交易金额不时出现,也就是修改后的总余额。.我一直在寻找一种动态的方法。

他们为每条记录制定真理声明,并为每条记录运行。对于额外的列:重新计算在更改或添加记录集时需要重新计算的那些,请参见数据库触发器。然后,您的数据库将解决此问题。

我已经尝试过了,在更改或插入上一个版本后,我使用了编辑和插入触发器来修改余额。迄今为止,对于5万种日记(= 10万笔交易),性能结果不佳。.该系统还在存储前几年的数据。我对此很困惑。

不要感到困惑。由于存在大量数据,因此需要花费一些时间来处理它。就是这样。您无法免费获得所有这些操作。但是,在簿记中不允许用户编辑现有记录或为已关闭的时间段添加或删除记录是没有意义的。因此,从理论上讲,您永远都不要修改已关闭年份的余额-这就是过去。因此,您可以一次计算整个过去无问题的余额。如果事情成为过去,那么您也可以计算该跨度。那应该减少caclulcations的数量。

当然!这是关于此系统的主要思想,在所有类似的系统中,都不应修改,就好像您犯了一个错误一样,您应该添加一个COUNTER事务来解决该错误。即使我们关闭了过去的工作并且仅在当年工作,我们也必须允许用户根据其业务类型对我们进行强制性的修改,并且在一年中只有很多要计算的内容,并且用户需要他所说的活动的GOD模式可随时修改任何内容。

海豚php分页问题,关于php:Double Entry Accounting分页问题相关推荐

  1. ASP.NET中利用DataGrid的自定义分页功能和存储过程结合实现高效分页

    关键字:DataGrid.存储过程.分页 出自: http://blog.csdn.net/yzx110/archive/2004/08/18/78525.aspx 摘要:在最进的一个项目中因为一个管 ...

  2. 计算机桌面分页,电脑word文档怎么快速分页?

    电脑word文档怎么快速分页? word是我们经常使用的办公软件之一.今天小编给大家介绍的就是word实现文档快速分页的方法. 具体如下: 1. 首先我们打开一篇word文档.文档最好有多个段落. 2 ...

  3. 分页技巧_实现第一个分页功能(回复列表中的分页)

    分页技巧_实现第一个分页功能(回复列表中的分页) ======================================== 假设共25条数据,每页显示10条,则共3页 first  max - ...

  4. 使用amaze ui的分页样式封装一个通用的JS分页控件

    作为一名码农,天天百度.偶尔谷歌,所有代码全靠copy,用第三方插件,偶尔也想着造造轮子,毕竟自己的骨肉总归比较亲. 今天有点空闲时间,想起我们公司之前套的页面的分页插件上还有bug,而写那个分页插件 ...

  5. 内核知识第九讲,32位下的分页管理,36位下的分页管理.以及64位下的分页管理

    内核知识第九讲,32位下的分页管理,36位下的分页管理.以及64位下的分页管理 一丶熟悉WinDbg的常见命令. dd 虚拟地址      显示内存. !dd 加上!,        ! dd 物理地 ...

  6. mysql分页案例_MySQL优化案例系列-mysql分页优化

    通常,我们会采用ORDER BY LIMIT start, offset 的方式来进行分页查询.例如下面这个SQL: SELECT * FROM `t1` WHERE ftype=1 ORDER BY ...

  7. php tp框架分页源代码,ThinkPHP3.2框架自带分页功能实现方法示例

    本文实例讲述了ThinkPHP3.2框架自带分页功能实现方法.分享给大家供大家参考,具体如下: 1.前端-分页代码: {$page} 2.创建分页样式:如page.css 并将以下代码复制到该文件中 ...

  8. mysql bean分页查询_javabean 来实现 MySQL 的分页

    javabean 来实现 MySQL 的分页.今天写了个 mysql 分页的 javabean,是用 mysql 里的 limit 来实现的. sql = "select * from te ...

  9. jspdf-html2canvas 自动分页 网页导出pdf 自动根据dom子节点的高度进行分页,避免dom的内容在分页的时候被截断

    jspdf-html2canvas 网页导出pdf 自动根据dom子节点的高度进行分页,避免dom的内容在分页的时候被截断 说明 直接上代码 说明 要导出的内容用 .pdf 包裹 ,默认会以.pdf的 ...

最新文章

  1. 一维数组对象转成二维数组
  2. linux免安装nginx,Nginx免安装包制作工具:Nginx-portable
  3. HTTP协议(5)HTTP请求和响应
  4. 20170822L08-04老男孩linux实战运维培训-Lamp系列之-Apache服务生产实战应用指南01
  5. 牛客网 【每日一题】5月28日题目精讲 Protecting the Flowers
  6. “约见”面试官系列之常见面试题第五篇说说vuex登录信息(建议收藏)
  7. 简单的php文件_简单的php文件上传(实例)
  8. [存档]xx-09210xxx-2010-ACM-ICPC竞赛总结
  9. PHP面试注意事项与问题
  10. FreeRTOS学习笔记(11)——CPU使用率统计
  11. 算符优先系列之(二)算符优先关系表
  12. 《Hello!树先生》简介
  13. linux运行o文件是什么,Linux的.a、.so和.o文件
  14. nginx启动,重启,关闭命令
  15. 白嫖正版《极客时间》课程的正确姿势
  16. Android和win10的融合,微软Windows10更新版亮相 更好融合iOS、Android系统
  17. 哪个邮箱群发效果好?邮件可以群发吗?群发邮件技巧教程来了
  18. iir滤波器的基本网络结构_IIR数字滤波器的基本结构详解.ppt
  19. SparkOnHive
  20. 校园网络的规划与实施(思科)

热门文章

  1. mysql btree索引原理_Postgres BTREE索引原理简单介绍
  2. html盒子背景图片路径,CSS3-背景
  3. 公众号家电维修小程序开发
  4. MySQL持续霸榜,《高性能MySQL》第4版追新巨献!
  5. MySQL存储引擎(InnoDB引擎)
  6. iOS游戏开发没有你想的那么难--Hardest
  7. 我的世界中国版配置java_我的世界中国版Java 不删档测试问题指引
  8. 【编程基础】如何自学计算机/编程 | 从零开始的代码之路
  9. prim算法(普里姆算法)详解
  10. spring boot + maven + opencv 车牌识别系统,包含车牌检测、车牌号识别训练