Автор |
Сообщение |
Long
SubAdmin Теоретик
|
|
сразу оговорюсь, задача в принципе уже решена, но хочется знать как решают другие. да и до клиента пока решение не дошло, поэтому есть еще возможность поправить. итак, задача - реализовать учет товара методом fifo (lifo - не принципиально). все вроде просто. усложняем задачу - проведеный товар может быть возвращен. хочется возвращения не в конец очереди, а на "свое место" (ситуация описывающая данное требование - заказ был отпущен по базе, но необходимо поправить, например, курс, ну не важно что, заказ надо вернуть). интересна структура данных, которая сможет обеспечить данное решение.
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
@TSV
постоянный участник
|
|
Long, ты только не смейся особо громко, но - массив (таблица с произвольным доступом). 
|
|
 |
|
 |
oLL
постоянный участник
|
|
Может я не о том, но нельзя в базе делать пометку об "условном" отспуске товара, которая по дефолту через определенное время "проводится" окончателььно или наоборот - метка снимается и все остается как было.
|
|
 |
|
 |
@TSV
постоянный участник
|
|
oLL, о том.  Так оно и делается. 
|
|
 |
|
 |
Long
SubAdmin Теоретик
|
|
@TSV, я не про то, где хранить, а про саму структуру - я же написал. временный флаг - не решение, а если через месяц заметят ошибку (например когда баланс будут сводить - его же не каждый день сводят)?
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
@TSV
постоянный участник
|
|
Long, дык проводки по-любому в отдельной таблице хранятся.  Причем это необходимо И для того, чтобы отслеживать такие текущие вещи, как остаток на складе, И для таких глобальных вещей, как баланс сводить. 
|
|
 |
|
 |
oLL
постоянный участник
|
|
@TSV, Цитата: | oLL, о том. Так оно и делается. |
Надо же Long, Цитата: | задача в принципе уже решена |
И как, если не секрет?
|
|
 |
|
 |
Long
SubAdmin Теоретик
|
|
@TSV, проводки понятно. ситуация - пришел товара А в количестве 2 по цене 1, потом пришел этот же товара А, но в количестве 3 и по цене 2. проводим заказ на 3 единицы товара. а потом делаем возврат етого заказа. опонятно, что простые флаги тут не спасут.
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
Long
SubAdmin Теоретик
|
|
oLL, пока секрет.  я же говорю - хочу узнать как решались подобные задачи  иначе будет обсуждение предложенного решения, как у нас водится 
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
@TSV
постоянный участник
|
|
Long, дык а таблица проводок ведь - спасёт.
1. Таблица товаров, запись - товар А, 17 единиц
2. Проводка: пришел товар А, в количестве 2 по цене 1
3. Проводка: пришел товар А, в количестве 3 по цене 2
4. Проводка: заказ на товар А, в количестве 3, по цене 1.5
5. Проводка: возврат проводки 4.
Баланс сводим по проводкам (и только по ним, товарный остаток считаем только интегрально), для текущих целей товарный остаток считаем по товарам + проводки. Изменения таблицы товаров делаем только в случае полностью завершенной транзакции: заказ - резервирование - выплата - отгрузка, запись в таблице товаров меняем, проводки "схлопываем", т.е. помечаем как завершенные, удаляем из таблицы проводок, заносим в таблицу архивов проводок. Последнее важно и полезно для производительности системы. Также подобная схема позволяет базе данных работать распределенно. Стандартная схема.

|
|
 |
|
 |
Crazy
Модератор
|
|
Long, аналогичная задача была у меня лет пять назад.
1. Вводим понятие "партия товара". Партия имеет сквозной порядковый номер. Она ассоциирована с конкретным типом товара и имеет ряд атрибутов, таких как дата приемки, исходное и остаточное количество, поставщик и курс бакса на момент поставки. В моем случае с партией ассоциировался и набор параметров, перекрывающих некоторые характеристики в карточке товара, но это скорее специфическое изощрение конкретной задачи.
2. Когда формируется карточка счета, то в нее записываются ссылки на типы товаров с указанием количества, различных условий и т.п.
3. Когда производится отгрузка товара, то устанавливается связь каждой строки счета с одной или несколькими партиями. Каждый раз мы при этом ищем партию с наименьшим номером, в которой есть ненулевой остаток. Эта связь атрибутируется количеством товара, взятого из данной партии. Соответственно уменьшается количество остатка по партии.
4. При выполнении возврата мы находит счет и для каждой его строки разрываем связь с партией, соответственно увеличивая количество остатка по этой партии. В принципе, имеет смысл протоколировать удаление связей, но я этого не делал.
_________________ We've got the big memory and the small memory. The small memory's to remember the small things and the big memory's to forget the big ones.
|
|
 |
|
 |
Long
SubAdmin Теоретик
|
|
@TSV, подожди, какой же это фифо??? это усредненное значение. так дело не пойдет... да и Цитата: | товарный остаток считаем по товарам + проводки |
боюсь, что это будет тормозить систему уже после нескольких месяцев интенсивной работы.
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
@TSV
постоянный участник
|
|
Crazy, а как разрешалась следующая ситуация:
1. Поступление партии, 2 единицы, товара А по цене 2
2. Поступление партии, 5 единиц, товара А по цене 3
3. Продажа товара А, 2 единицы, по цене 4.
Разве правильно в данном случае привязываться к конкретной партии товара?
Не проще и не правильнее ли разделить данные о товарном остатке и финансовые потоки?
|
|
 |
|
 |
Long
SubAdmin Теоретик
|
|
Crazy, во! вот я так и сделал. теперь ломаю голову - может есть "стандартные" решения. ведь задача довольно типичная.
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
@TSV
постоянный участник
|
|
Long, а я просто, наверное, не догнал, почему именно fifo/lifo.
То, что динамический расчет текущего товарного остатка дает большую нагрузку, я понимаю. Но ведь было специально оговорено, что таблицы: (1)"Проводки" и (2)"Архив проводок" - отдельные, записи из первой переносятся во вторую при первой же возможности, для текущей работы используется первая. В такой ситуации производительность системы зависит не от времени, а от того, насколько интенсивно ведутся текущие проводки, и насколько правильно и своевременно мы эти проводки архивируем. 
|
|
 |
|
 |
Long
SubAdmin Теоретик
|
|
@TSV, но в любом случае, чтобы подсчитать количество товара на складе в текущий момент нужно будет просмотреть все проводки (которые не в архиве?) а если строится состояние всего склада, а товаров там значительное количество, то для каждого товара надо просчитать его количество. имхо, лучше хранить текущее состояние склада. Это конечно потребует точности при реализации, но зато существенно снизит объем вычислений. конечно, в таком случае таблицы будут не нормализованы, но как показывает практика нормализация зачастую приносит вред.
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
@TSV
постоянный участник
|
|
Long, ИМХО это уже такие тонкости, что для принятия правильного решения нужно обязательно рассматривать конкретную задачу и конкретную нагрузку на базу данных. 
|
|
 |
|
 |
Crazy
Модератор
|
|
@TSV писал(а): | Crazy, а как разрешалась следующая ситуация |
В этой ситуации я не вижу ни одной конфликтной ситуации, которые нужно разрешать. Цитата: | Разве правильно в данном случае привязываться к конкретной партии товара? |
Из моего описания видно, что счет в определенный момент связывается с конкретными партиями товара. Цитата: | Не проще и не правильнее ли разделить данные о товарном остатке и финансовые потоки? |
При припомню, чтобы я что-то говорил о финансовых потоках. Ты уверен, что читаешь именно мои сообщения? 
|
|
 |
|
 |
@TSV
постоянный участник
|
|
Crazy, уверен.
- ну не видишь конфликтной ситуации, и ладно. Значит, не такая уж она и конфликтная.
- зато не видно, правильно или нет привязываться к партии, и нельзя ли поискать другое решение
- финансовые потоки все равно есть, иначе нету никакого смысла делить на партии.
- будет отпущен первым - при этом способе реализации структуры данных, а в общем случае это все равно структура произвольного доступа. 
|
|
 |
|
 |
jettero
новый человек
|
|
Лично я поступаю с этим так:
1. Набор реляционных таблиц описывающих состояние системы в настоящий момент.
2. Набор таблиц описывающих интересующие изменения системы во времени.
применительно к данному обсуждению, в простейшем случае это будет так:
состояние в наст. времени:
Код: таблица Item (наименования товара), поля: id, name, price(продажная цена) - содержит ассортимент товара таблица Store (склад), поля: item_id, quantity, cost(закупка) - товар на складе, ключ таблицы составной по полям item_id и cost изменения в прошлом: Код: таблица Item_moving (приход/расход на складе) поля: id, date, item_id, quantity, cost таблица Sell (продажа/возврат) поля: id, date, item_id, quantity, cost, return (флаг возврата)
логика FIFO/LIFO - такая логика актуальна, только если состояние товара зависит от времени хранения его на складе, в противном случае все единицы товара идентичны, и речь может идти только о том продавать ли товар сначала с низкой закупкой или с высокой.
|
|
 |
|
 |
Long
SubAdmin Теоретик
|
|
Цитата: | такая логика актуальна, только если состояние товара зависит от времени хранения его на складе |
ничего подобного. для бухгалтерского учета важно именно какой товар (по какой закупочной цене) был отпущен сначала.
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
jettero
новый человек
|
|
Long, ну я это и имел в виду - если товар отличается только закупкой, а его свойства от хранения не меняются, то не нужно делать фифо (если под фифо ты понимаешь, что более раннии партии реализуются в первую очередь) - достаточно чтобы был атрибут "закупка" в таблице склада и тогда при продаже можно выдавать нужную закупку. В том варианте структуры данных, что я написал выше, логика фифо/лифо не реализована, но товар с разной закупкой хранится в таблице раздельно и при продаже фиксируется какая была закупка проданного товара.
У меня по такой системе работают 3 интранет системы в разных фирмах.
|
|
 |
|
 |
Long
SubAdmin Теоретик
|
|
jettero, тут два варианта, либо ты для оценки себестоимости отпущенного заказа используешь фифо/лифо, либо некую усредненную цену товара. других вариантов нет.
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
jettero
новый человек
|
|
Long, почему нет?
пример: склад магазина, были приняты 3 партии носок одного артикула, 10 пар по закупке 10 руб., 15 пар по закупке 11 руб. и 20 пар по закупке 8 руб.
Итого на складе имеются 3 варианта носок одного артикула (с разными закупками). Внешне они ничем не отличаются и физически хранятся вместе. Но в программе работы со складом у меня три записи на этот артикул - по одной на каждую закупку. Соотвественно при продаже продавец выберет нужный артикул/закупку. Выбор может быть как случайным, так и по какой-то системе, зависит от политики фирмы, например правило может быть таким: продавать сначала товар по самой низкой закупке. Как видишь ни лифо/фифо, ни усредненной цены тут нету.
|
|
 |
|
 |
Crazy
Модератор
|
|
jettero, бухгалтерия требует, чтобы продавали в зависимости от порядка закупки, а не в засисимости от цены или погоды в Парагвае. Поэтому -- FIFO.
Когда бухгалтерия такого не требует, то и проблема вообще не возникает.
_________________ We've got the big memory and the small memory. The small memory's to remember the small things and the big memory's to forget the big ones.
|
|
 |
|
 |
@TSV
постоянный участник
|
|
Crazy, не "в зависимости от порядка закупки", а "нужно знать, по какой цене товар был закуплен". Доступ все равно произвольный.
|
|
 |
|
 |
Crazy
Модератор
|
|
Я где-то сказал "доступ"?
_________________ We've got the big memory and the small memory. The small memory's to remember the small things and the big memory's to forget the big ones.
|
|
 |
|
 |
@TSV
постоянный участник
|
|
Crazy, ты сказал - FIFO. А там не FIFO. И не LIFO. А произвольный доступ. И вообще, порядок продажи определяет НЕ бухгалтерия, а отдел продаж.
|
|
 |
|
 |
Crazy
Модератор
|
|
FIFO как структура данных определяет соотношение между последовательностью поступления и последовательностью обработки данных. Насколько я понимаю, БОЛЬШЕГО Long не вкладывал в трактовку термина.
_________________ We've got the big memory and the small memory. The small memory's to remember the small things and the big memory's to forget the big ones.
|
|
 |
|
 |
Long
SubAdmin Теоретик
|
|
Цитата: | правило может быть таким: продавать сначала товар по самой низкой закупке |
Цитата: | Внешне они ничем не отличаются и физически хранятся вместе |
а теперь скажи, как ты будешь выделять партию из самых дешевых носок?  но это все лирика.
в любой фирме есть учет (если его нет - скорее всего фирма либо в ближайшее время будет его внедрять, либо закроется). утет подразумевает некий алгоритм, по которому организуется учет и определение складского остатка (как в единичном выражении - количество конкретного товара на складе, так и финансовом - стоимость склада). алгоритм, теоретически, может быть любым - можно сначала "отпускать" товар с наименьшей закупочной ценой. можно организовывать учтет по случайной схеме - вибирается случайный приход. но ни один бухгалтер (а именно он на вирме отвечает за учет (потому что в конечном итоге он отвечает за отчетность фирмы, а соответственно ему нужно знать по какой цене ушла партия из 22 носок, чтобы посчитать прибыль или убыток от этой операции, даже для черной бухгалтерии), ни один бухгалтер в сдравом уме не будет вести учет предложенным "произвольным" образом. для него есть фифо, есть лифо, особо "продвинутый" может вычислять усредненую стоимость закупки. да, чисто теоретически у фирмы могут быть основания производить учет товара не стандартным методом, но это именно теоретичекая возможность. и, как я писал еще в самом первом посте, метод учета не принципиален, потому что это самое конечное действие в алгоритме учета, для меня важно было именно узнать как решается другими задача учтета товара когда партии товара различаются своей ценой и более ничем и есть определенный порядок выбора партии, и есть условия возврата партии или ее части обратно на свое место. понятно, что если реализованна такая задача, то учет любым способом (будь то фифо, лифо, усредненная стоимость или клинический случай - произвольная выборка партии) - сводится к уже решенной задаче, меняется только условие отбора.
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
Long
SubAdmin Теоретик
|
|
COLT, общая идея правильная, но не учтено, что это не просто товар, а партия товара. т.е надо хранить еще и остаток. это раз. а первая цитата не применима потому как задействован параметр время, что не есть хорошо, поскольку он не является константой в общем случае. поэтому это не одно и тоже.
_________________ Мудрость не всегда приходит с возрастом. Бывает, что возраст приходит один.
|
|
 |
|
 |
jettero
новый человек
|
|
Всего пару дней не заходил, а сколько постов
Long, пока проблем с бухгалтерами не возникало,  ; @TSV прав, им надо знать закупку проданного товара, а не то, что товар был отпущен в строгой очередности поступления.
А что до правила по отпуску - я встречался с желанием заказчика, чтобы закупочная стоимость склада (то есть сумма
закупок всех партий) была минимальной, подозреваю, что это желание было продиктовано той же бухгалтерией, а скорее уплатой налогов и это желание можно было реализовать только применяя правило по первоочередному отпуску товара с наибольшей закупочной стоимостью.
PS Цитата: | а теперь скажи, как ты будешь выделять партию из самых дешевых носок? |
разумеется никак, на самом деле клиника, это когда на складе хранят каждую партию абсолютно одинакового товара отдельно... я допускаю, что могут возникнуть причины для этого, но обычно это не требуется.
|
|
 |
|
 |
jettero
новый человек
|
|
Crazy писал(а): | FIFO как структура данных определяет соотношение между последовательностью поступления и последовательностью обработки данных. Насколько я понимаю, БОЛЬШЕГО Long не вкладывал в трактовку термина. |
его посты говорят об обратном 
|
|
 |
|
 |
Уровень доступа: Вы не можете начинать темы. Вы не можете отвечать на сообщения. Вы не можете редактировать свои сообщения. Вы не можете удалять свои сообщения. Вы не можете добавлять вложения.
|
|