Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
22 ноя 2024, 17:04

Вопрос по блокировке данных.

Автор DirecTwiX, 05 мая 2012, 02:35

0 Пользователей и 1 гость просматривают эту тему.

DirecTwiX

Есть задача:
ЦитироватьКомпания занимается оптовой торговлей. Принята следующая схема работы: поступление товаров отражается документом «Приходная накладная». По предварительной договоренности с покупателем менеджер может оформить резерв (документ «Резервирование товара»), причем наличие товара в этот момент не важно, товар может отсутствовать. Непосредственно отгрузка товара покупателю отражается документом «Расходная накладная», при этом происходит снятие резерва.
Учет товаров ведется в разрезе складов. В документах «Приходная накладная» и Расходная накладная» склад только один (склад -- реквизит шапки).
При проведении расходной накладной необходимо проверить наличие товара на складе и «свободного» (будет описано далее) товара. В том случае, когда товара недостаточно, документ не проводится и выводится соответствующее сообщение об ошибке.
У каждого менеджера есть приоритет, чем больше приоритет, тем более ответственный менеджер и тем важнее его продажи. Таким образом, если два менеджера одновременно зарезервировали один и тот же товара, то менеджер с большим приоритетом может продать товар, зарезервированный менеджером с меньшим приоритетом. Менеджер с низким приоритетом продать чужой резерв не имеет права. Таким образом, «свободный» товар менеджера определяется как товар на всех складах минус резерв всех остальных менеджеров с приоритетом большим либо таким же, как и у текущего менеджера.
Приоритет устанавливается для каждого менеджера индивидуально и может меняться не чаще чем 1 раз в месяц. При продаже необходимо использовать приоритет менеджера, актуальный на дату продажи.
Себестоимость товара рассчитывается как средняя по складу.
Регистр ОстаткиНоменклатуры устроен так:
Измерения:
  Номенклатура
  Менеджер
  Склад
Ресурсы:
  Количество
  Сумма

При резервировании товаров склад пуст, а в менеджере - сотрудник. При проводке - менеджер пуст, а в склад пишу склад.
При проведении расходной блокирую склад и список номенклатуры из документа. Вопрос в том, стоит ли мне блокировать определённых сотрудников? Насколько я понимаю - нет - они и так все заблокируютс.

Если интересно, то вот обработка проведения. Был бы рад любой критике)
ЦитироватьПроцедура ОбработкаПроведения(Отказ, РежимПроведения)
   Движения.ОстаткиНоменклатуры.Записывать = Истина;
   
   Блокировка = Новый БлокировкаДанных;
   ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");
   ЭлементБлокировки.УстановитьЗначение("Склад", Склад);
   ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
   
   ЭлементБлокировки.ИсточникДанных = Товары;
   ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
   Блокировка.Заблокировать();

   Запрос = Новый Запрос;
   Запрос.Текст = "ВЫБРАТЬ
                  |   ПриоритетыМенеджеровСрезПоследних.Менеджер,
                  |   ПриоритетыМенеджеровСрезПоследних.Приоритет
                  |ПОМЕСТИТЬ Приоритеты
                  |ИЗ
                  |   РегистрСведений.ПриоритетыМенеджеров.СрезПоследних(&Дата, ) КАК ПриоритетыМенеджеровСрезПоследних
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |   ОстаткиНоменклатурыОстатки.Номенклатура,
                  |   ОстаткиНоменклатурыОстатки.КоличествоОстаток,
                  |   ОстаткиНоменклатурыОстатки.СуммаОстаток,
                  |   ОстаткиНоменклатурыОстатки.Менеджер,
                  |   Приоритеты.Приоритет
                  |ПОМЕСТИТЬ ВсеОстатки
                  |ИЗ
                  |   РегистрНакопления.ОстаткиНоменклатуры.Остатки(
                  |         &Дата,
                  |         Склад = &Склад
                  |            ИЛИ Склад = ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка)) КАК ОстаткиНоменклатурыОстатки
                  |      ЛЕВОЕ СОЕДИНЕНИЕ Приоритеты КАК Приоритеты
                  |      ПО ОстаткиНоменклатурыОстатки.Менеджер = Приоритеты.Менеджер
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |   ВсеОстатки.Номенклатура,
                  |   ВсеОстатки.КоличествоОстаток,
                  |   ВсеОстатки.СуммаОстаток
                  |ПОМЕСТИТЬ Остатки
                  |ИЗ
                  |   ВсеОстатки КАК ВсеОстатки
                  |ГДЕ
                  |   ВсеОстатки.Менеджер = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |   ВсеОстатки.Номенклатура,
                  |   СУММА(ВсеОстатки.КоличествоОстаток) КАК КоличествоОстаток
                  |ПОМЕСТИТЬ Резервы
                  |ИЗ
                  |   ВсеОстатки КАК ВсеОстатки
                  |ГДЕ
                  |   ВсеОстатки.Менеджер <> &Менеджер
                  |   И ВсеОстатки.Приоритет >= &Приоритет
                  |
                  |СГРУППИРОВАТЬ ПО
                  |   ВсеОстатки.Номенклатура
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |   ВсеОстатки.Номенклатура,
                  |   ВсеОстатки.КоличествоОстаток
                  |ПОМЕСТИТЬ МоиРезервы
                  |ИЗ
                  |   ВсеОстатки КАК ВсеОстатки
                  |ГДЕ
                  |   ВсеОстатки.Менеджер = &Менеджер
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |   РасходнаяНакладнаяТовары.Номенклатура,
                  |   СУММА(РасходнаяНакладнаяТовары.Количество) КАК Количество,
                  |   СУММА(РасходнаяНакладнаяТовары.Сумма) КАК Сумма
                  |ПОМЕСТИТЬ Товары
                  |ИЗ
                  |   Документ.РасходнаяНакладная.Товары КАК РасходнаяНакладнаяТовары
                  |ГДЕ
                  |   РасходнаяНакладнаяТовары.Ссылка = &Ссылка
                  |
                  |СГРУППИРОВАТЬ ПО
                  |   РасходнаяНакладнаяТовары.Номенклатура
                  |;
                  |
                  |////////////////////////////////////////////////////////////////////////////////
                  |ВЫБРАТЬ
                  |   Товары.Номенклатура,
                  |   Товары.Количество,
                  |   Товары.Сумма,
                  |   ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
                  |   ЕСТЬNULL(Остатки.СуммаОстаток, 0) КАК СуммаОстаток,
                  |   ЕСТЬNULL(Резервы.КоличествоОстаток, 0) КАК Зарезервировано,
                  |   ЕСТЬNULL(МоиРезервы.КоличествоОстаток, 0) КАК МноюЗарезервировано
                  |ИЗ
                  |   Товары КАК Товары
                  |      ЛЕВОЕ СОЕДИНЕНИЕ Остатки КАК Остатки
                  |      ПО Товары.Номенклатура = Остатки.Номенклатура
                  |      ЛЕВОЕ СОЕДИНЕНИЕ МоиРезервы КАК МоиРезервы
                  |      ПО Товары.Номенклатура = МоиРезервы.Номенклатура
                  |      ЛЕВОЕ СОЕДИНЕНИЕ Резервы КАК Резервы
                  |      ПО Товары.Номенклатура = Резервы.Номенклатура";
   Запрос.УстановитьПараметр("Ссылка", Ссылка);
   Запрос.УстановитьПараметр("Склад", Склад);
   Запрос.УстановитьПараметр("Менеджер", Менеджер);
   Запрос.УстановитьПараметр("Дата", Дата);
   Отбор = Новый Структура;
   Отбор.Вставить("Менеджер", Менеджер);
   Запрос.УстановитьПараметр("Приоритет", РегистрыСведений.ПриоритетыМенеджеров.ПолучитьПоследнее(Дата, Отбор).Приоритет);
   Результат = Запрос.Выполнить();
   
   Выборка = Результат.Выбрать();
   Пока Выборка.Следующий() Цикл
      Если Выборка.Количество > Выборка.КоличествоОстаток - Выборка.Зарезервировано Тогда
         Сообщить("Не хватает " + (Выборка.Количество-(Выборка.КоличествоОстаток - Выборка.Зарезервировано)) + "шт. <" + Выборка.Номенклатура + ">");   
         Отказ = Истина;   
      КонецЕсли;       
      
      Если Отказ Тогда
         Продолжить;   
      КонецЕсли;
      
      Д = Движения.ОстаткиНоменклатуры.Добавить();
      Д.ВидДвижения = ВидДвиженияНакопления.Расход;
      Д.Количество = Выборка.Количество;
      Д.Склад = Склад;
      Д.Номенклатура = Выборка.Номенклатура ;
      Д.Период = Дата;
      Д.Сумма = Выборка.СуммаОстаток * Выборка.Количество / Выборка.КоличествоОстаток;
      
      Д = Движения.ОстаткиНоменклатуры.Добавить();
      Д.ВидДвижения = ВидДвиженияНакопления.Расход;
      Д.Количество = Мин(Выборка.МноюЗарезервировано, Выборка.Количество);
      Д.Менеджер = Менеджер;
      Д.Номенклатура = Выборка.Номенклатура ;
      Д.Период = Дата;
   КонецЦикла;
   
КонецПроцедуры

cska-fanat-kz

Лучше разделить на 2 регистра - Остатки и Резервы.
Именно потому, что у вас происходят движения с разным набором измерений (в одном случае со складом, в другом - с менеджером), что плохо и считается одной из грубых ошибок, потому что в этом случае вы никогда не выйдете в ноль и ваши итоговые таблицы регистра будут неоправданно "распухать"...
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

DirecTwiX

Почему в ноль не выйдут? Я ж резервы списываю и остатки. Вроде разбухнуть не получиться...

cska-fanat-kz

в любом случае лучше не смешивать...

к тому же вы не учитываете момент когда более старший менеджер "отбирает" резерв более младшего...
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

DirecTwiX

Вот же:
Цитировать|ВЫБРАТЬ
                  |   ВсеОстатки.Номенклатура,
                  |   СУММА(ВсеОстатки.КоличествоОстаток) КАК КоличествоОстаток
                  |ПОМЕСТИТЬ Резервы
                  |ИЗ
                  |   ВсеОстатки КАК ВсеОстатки
                  |ГДЕ
                  |   ВсеОстатки.Менеджер <> &Менеджер
                  |   И ВсеОстатки.Приоритет >= &Приоритет
                  |
                  |СГРУППИРОВАТЬ ПО
                  |   ВсеОстатки.Номенклатура
                  |;
Но за внимание спасибо)

cska-fanat-kz

конечно не претендует на истину, но примерно следующим образом (см. приложение).
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск