Есть таблицы покупка, продажа (дата, количество, цена, id номенклатуры)
Как узнать остаток на дату?
Остаток в количественном виде считается просто купили - продали, и легко выводится в разрезе по номенклатуре.
Но вот остаток в денежной форме?
Количество товара в последних партиях * их цену, за исключением не полной партии, там считать пропорционально количеству.
Как это реализовать на SQL
Или хотя бы логику
Хотелось бы партионный учёт, но в голову приходит только вариант с мнооожеством sql запросами в цикле
Select nomenclarure_id по приходу
Далее в цикле по каждой номенклатуре находить количество расхода
далее делать запрос на выборку последних партий из прихода на остаток, складывать в цикле все партии кроме последней умножая количество на сумму,
Последнюю партию, т.к. она может быть не целой считать пропорционально остатку.
Получается количество SQL запросов минимум = количество номенклатуры * 2. Хотелось бы меньше...
У маленького магазинчика 100 товаров, это уже 200 запросов. Придется городить Ajax, чтобы не вылететь по таймауту
Гм.. а в чем непонятность?
Если речь о партионном учете - т.е. в каждой продаже фигурирет отсыл на конкретную партию покупки - то собственно вычитая из отбора покупок до нужной даты отбор продаж до этой же даты через связку партий - получим остатки по каждой конкретной партии. Сумма произведений остатков в каждой партии на цену покупки - и даст сумму остатков.
Если учет по среднему - то трактовок может быть несколько:
- глобальное среднее по всем партиям прихода до нужной даты умножаем на количественный остаток (это попроще)
- закладываемся на FIFO и тогда вначале исключаем обнулившиеся "партии" (по хронологии поступления) и потом для оставшегося считаем среднее
Хотелось бы партионный учёт, но в голову приходит только вариант с мнооожеством sql запросами в цикле
Select nomenclarure_id по приходу
Далее в цикле по каждой номенклатуре находить количество расхода
далее делать запрос на выборку последних партий из прихода на остаток, складывать в цикле все партии кроме последней умножая количество на сумму,
Последнюю партию, т.к. она может быть не целой считать пропорционально остатку.
Получается количество SQL запросов минимум = количество номенклатуры * 2. Хотелось бы меньше...
У маленького магазинчика 100 товаров, это уже 200 запросов. Придется городить Ajax, чтобы не вылететь по таймауту
Ну если партионный - то и надо партионный. Он очевиднее, понятнее и предсказуемее.
Всей разницы - таблица-связка списаний партий.
То бишь строка в расходе(продаже) - ссылается на строку в "партиях" (id_прихода, id_расхода, кол-во, дата, кто и т.п.) и уже через нее - в приходы
побочный эффект - продажа 2 булок может оказаться из двух строк (1 булка из одной партии, вторая - из другой). Впрочем если речь зайдет о ОСН и НДС и импортных товарах - то это итак будет нужно в плане учета ГТД)
Ну и в итоге простейший вариант (несколько упрощенный) даст приход, остаток, сумму остатка:
select
incomes.doc_id,
incomes.item_code,
rest_qnt = sum(incomes.qnt)-sum(outs.qnt),
rest_sum = (sum(incomes.qnt)-sum(outs.qnt))*incomes.price,
from incomes
inner join outs on outs.id_in=incomes_id
group by incomes.doc_id, incomes.item_code
where incomes.date<date_x and outs.date<date_x
дальше останется обернуть это в еще одну группировку только по товару и просуммировать кол-во и сумму
d-stream, как я понимаю запрос считает по некой incomes.price
Скорее всего это не цена только последних партий в количестве остатков, включая неполную пограничную партию.
Скорее всего это не цена только последних партий в количестве остатков, включая неполную пограничную партию.
это цена в каждой конкретной поставке. Вчера было по три, сегодня - по пять)
для понимания - пример:
поступления
партия1: 1 января куплено 20 булок по 3 р
партия2: 1 февраля куплено 15 булок по 2р
партия3: 1 марта куплено 30 булок по 4р
продажи:
продажа1 1 июля - 23 булки по 15р, а именно:
- 15 булок из партии1
- 6 булок из партии2
- 2 булки из партии3
в таком раскладе:
партия1: осталось 5 булок, купленных по 3р = 15р
партия2: осталось 9 булок, купленных по 2р = 18р
партия3: осталось 28 булок, купленных по 4р = 112р
итого на складе осталось 42 булки на сумму 145р (средняя себестоимость остатка 3.45р)
p/s/ можно вместо булок рассмотреть например водку/обувь/ювелирку/шины - там каждая бутылка прослеживаемая и имеет уникальный "серийный номер"
d-stream,
может мне сохраняя продажу нужно находить в некой буферной таблице(ах) партионного учёта последнюю партию закупки по каждой из номенклатур в текущей продаже и генерить новые строки с новыми объединениями в партии покупок, начиная с последней учтеной и текущей продажей?
А уже на странице генерации остатков обращаться только к одной\двум таблице партий и считать по ней\ним
Связка продажи с партией поступления (реальное списание) возникает в момент продажи - ничего искусственно создавать не надо. Кстати в тот же момент можно апдейтить строки поступления указывая хелпер остатка. Последнее конечно слегка отходит от идеологии целостности, но иногда может поспособствовать.