Двойная запись бухгалтерского учета нумерации страниц

Существует действительно серьезная проблема в системах двойного учета с нумерацией страниц, я думаю, что это распространено, но я до сих пор не нашел решения для своей проблемы.

Вы можете использовать эту ссылку, чтобы прочитать о простых системах двойного учета, которые я сделал с 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', '<', $fromDate)
        ->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 транзакций на страницу, система будет работать, как и ожидалось, для первой страницы, так как мы уже можем рассчитать $balanceYesterday и зависит от него, чтобы рассчитать новый баланс после каждой транзакции до конца 100 транзакций на первой странице.

На следующей странице будет проблема в том, что она не знает, каким был последний баланс в предыдущей транзакции на первой странице, поэтому она начнется снова с $balanceYesterday, заставляя всю таблицу иметь неправильные вычисления.

То, что я сделал первым, чтобы исправить, была передача последней транзакции amount (в начале) на следующую страницу в качестве параметра и использовать его в качестве начальной суммы для повторного расчета, и это было лучшее решение, которое у меня было, поскольку я использовал только кнопки << PREV и NEXT >>, так что это было очень легко это исправить.

Но в последнее время я обнаружил, что этот обходной путь не будет работать, если у меня есть нумерация страниц с номерами страниц, так как пользователь хотел бы просматривать страницы для просмотра журнала, теперь невозможно узнать последний баланс на конкретной странице и Система покажет неверные расчеты.

То, что я пытаюсь сделать, - это найти способ рассчитать остаток по конкретной транзакции, если это был кредит или дебет, я ищу способ узнать, сколько было баланса после выполнения конкретной транзакции в конкретной На сегодняшний день Я НЕ ХОЧУ ДОБАВИТЬ НОВУЮ КОЛОННУ БАЛАНСА И СОХРАНИТЬ БАЛАНС ВНУТРИ ЭТОГО, ПОЛЬЗОВАТЕЛЬ ДЕЛАЕТ МНОГО ИЗМЕНЕНИЙ И РЕДАКТИРОВАТЬ СДЕЛКИ ИЗ ВРЕМЕНИ ВРЕМЯ, ЧТО ВСЕ МОЖЕТ ПОЛНОСТЬЮ ИЗМЕНИТЬ ВСЕ, КАК МАЛЕНЬКАЯ СУММА ИЗМЕНЕНИЯ ПОСЛЕ ЭТОГО БАЛАНСА, Я НЕ МОГУ зависеть от идентификаторов транзакций в любом методе, потому что транзакции могут иметь разные случайные даты, поэтому не будет упорядочения по идентификатору, но может быть упорядочение по другим полям, таким как дата или владелец счета или тип или что-то еще.,

Я ломал голову над этим около 4 месяцев, я искал в Интернете и не нашел решений, надеюсь, после этого длинного объяснения, что моя проблема ясна, и я надеюсь, что кто-нибудь может помочь мне с решением, пожалуйста..

Спасибо.

2 ответа

Решение

Я считаю, что единственное, что вам действительно нужно на данный момент, - это рассчитать сумму всех транзакций от начала разбитого на страницы набора данных (всех записей, а не только текущей страницы) до одной перед первой записью, отображаемой на текущей странице.

Вы можете получить это, найдя количество транзакций, произошедших между началом всего набора данных и транзакциями текущей страницы, получив их через LIMIT и добавив их.

Первое, что вам нужно, это точные ограничения вашего запроса на нумерацию страниц. Поскольку мы хотим получить другое подмножество записей, разбитых на страницы, помимо текущей страницы, вы хотите быть уверены, что результаты обоих запросов находятся в одинаковом порядке. Повторное использование объекта построителя запросов может помочь (настроить в соответствии с вашим фактическим запросом на нумерацию страниц):

$baseQuery = DB::table('journal')
    ->join('transactions', 'transactions.journal_id', 'journal.id')
    ->where('date', '>', $fromDate)
    ->where('date', '<', $toDate)
    ->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');

Добавив выделение здесь, чтобы объяснить, что использование вашей базы данных для выполнения SUM вычисления будут большим выигрышем в производительности, а не в цикле в PHP. Используйте БД так часто, как только сможете!

Добавьте этот баланс к исходному балансу "вчера", и у вас должен быть точный начальный баланс для разбитых на страницы транзакций.

Примечание: все, что псевдокодировано из теории, может нуждаться в корректировке. Рад пересмотреть, если есть вопросы или проблемы.

Вы должны быть в состоянии сформулировать утверждение истинности для баланса для каждой записи, при условии, что вы можете сказать, каков порядок вычисления суммы для баланса в каждой точке этого упорядоченного списка.

Конечно, это связано с большими накладными расходами, так как вам нужно запрашивать всю таблицу для каждой отображаемой записи, но, прежде всего, нужно уметь это делать. Как вы показали в примере, вы до тех пор, пока не разбиты на страницы.

Что можно сделать для разбивки на страницы, так это предварительно рассчитать баланс для каждой записи и сохранить его относительно исходной записи. Это бы нормализовало ваши данные, но с преимуществом создания нумерации страниц достаточно просто.

Другие вопросы по тегам