Онлайн резервирование товаров

10.10.13

Задачи пользователя - Адаптация типовых решений

Бывало ли у Вас такое: зарезервировали товар по телефону, собрались проводить документ, а товара уже нет в доступном остатке на складе? Пока Вы разговаривали, кто-то успел провести документ, который зарезервировал товар. Что делать? Есть одна идея.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование SM По подписке [?] Купить один файл
Демо конфигурация online резервирования (только для SQL)
.rar 450,00Kb
2
2
1 SM
Скачать Купить за 1 850 руб.

Бывало ли у Вас такое: зарезервировали товар по телефону, собрались проводить документ, а товара уже нет в доступном остатке на складе? Как же так? Что ж такое? Недавно был виден остаток в подборе. Приходится вычеркивать товар либо брать партию по другой цене или с неподходящими для покупателя параметрами. Приходится извиняться либо вообще перезванивать и согласовывать новые условия заказа. А дорога каждая минута.

Все очень просто. Пока Вы разговаривали, кто-то успел провести документ, который зарезервировал товар. Или отработал робот, который грузит заявки, поступившие с сайта.

Что делать? Есть одна идея. Резервировать товар в не проведенных документах во временных резервах. Более того резервировать товар в новых, еще незаписанных документах. И даже изменять резерв при редактировании количества в строке заявки, удалении строки, изменении склада и других действиях в записанных и новых документах. Резерв сразу увидят все пользователи.

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

Что нужно сделать? Рассмотрим работу с форматом SQL. Все это писалось в 2007 году, но до сих пор работает. 

Необходимо  создать свою таблицу SQL примерно такой структуры: Товар, Склад, Резерв, IDDOC. Если склад адресный - добавляется поле для ячейки.

Далее необходимо модифицировать получение свободных остатков там где это нужно с учетом временных резервов:

Функция глПолучитьСвободныйОстаток(ВыбТовар, ВыбСклад, ПоложительныеОстатки =0, ОстаткиВТЗ =0)Экспорт
    ТекстЗапроса = "
    |SELECT SUM(Запрос.Остаток - Запрос.Резерв) AS Количество
    |FROM
    |(
    |SELECT ОстаткиТМЦОстатки.КоличествоОстаток Остаток
    |    , 0 Резерв
    |FROM $РегистрОстатки.ОстаткиТМЦ(,,
    |        (Номенклатура = :ВыбТовар)
    |        AND (Склад = :ВыбСклад)
    |        ,,
    |        Количество) AS ОстаткиТМЦОстатки
    |
    |UNION ALL
    |
    |SELECT 0 Остаток
    |, РезервыТМЦОстатки.КоличествоОстаток Резерв
    |FROM $РегистрОстатки.РезервыТМЦ(,,
    |        (Номенклатура = :ВыбТовар)
    |        AND (Склад = :ВыбСклад)
    |        ,,
    |        Количество) AS РезервыТМЦОстатки
    |
    |UNION ALL
    |
    |SELECT 0 Остаток
    |, ВременныйРезерв.Res Резерв
    |FROM Tempost AS ВременныйРезерв (NOLOCK)
    |WHERE ВременныйРезерв.Tov = :ВыбТовар
    |      AND ВременныйРезерв.Skl = :ВыбСклад
    |) AS Запрос
    |";
        
    Если ПоложительныеОстатки = 1 Тогда //только остатки > 0
        ТекстЗапроса = ТекстЗапроса + "
        |HAVING SUM(Запрос.Остаток - Запрос.Резерв) > 0
        |";
    КонецЕсли;
    
    RecordSet.УстановитьТекстовыйПараметр("ВыбТовар",    ВыбТовар);
    RecordSet.УстановитьТекстовыйПараметр("ВыбСклад",    ВыбСклад);
        
    ТЗ = RecordSet.ВыполнитьИнструкцию(ТекстЗапроса);
    
    Если ОстаткиВТЗ = 0 Тогда
        Возврат ТЗ.ПолучитьЗначение(1,1);
    Иначе 
        Возврат ТЗ;
    КонецЕсли;    
КонецФункции

Предусматриваем отмену проведения документа и его удаление:

Процедура ПриОтменеПроведенияДокумента(Док)//Переводим на всякий случай во временный резерв//Нужно следить за тем чтобы непроведенные документы долго не болталисьЕсли Док.Вид()= "ЗаявкаПокупателя" Тогда ТекстЗапроса ="|INSERT INTO Tempost
        |SELECT $РезервыТМЦ.Номенклатура
        |, $РезервыТМЦ.Склад
        |, $РезервыТМЦ.Количество
        |, РезервыТМЦ.IDDOC
        |FROM $Регистр.РезервыТМЦ AS РезервыТМЦ
        |WHERE (РезервыТМЦ.IDDOC = :ТекДок)
        |"; RecordSet.УстановитьТекстовыйПараметр("ТекДок", Док.ТекущийДокумент()); RecordSet.ВыполнитьИнструкцию(ТекстЗапроса);КонецЕсли;КонецПроцедурыПроцедура ПриУдаленииДокумента(Док, Реж)//Удаляем временный резерв по документуЕсли Док.Вид()= "ЗаявкаПокупателя" Тогда ТекстЗапроса ="|DELETE
        |FROM Tempost (HOLDLOCK)
        |WHERE IDDOC = :ВыбДок
        |"; RecordSet.УстановитьТекстовыйПараметр("ВыбДок", Док); RecordSet.ВыполнитьИнструкцию(ТекстЗапроса);КонецЕсли;КонецПроцедуры

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

Если ПоДвижениямДокумента = 1 Тогда
    ТекстЗапроса = "
    |SELECT Sum(ISNULL($РезервыТМЦ.Количество,0) + ISNULL(ВременныйРезерв.Res,0)) Количество
    |FROM $Регистр.РезервыТМЦ AS РезервыТМЦ (NOLOCK)
    |LEFT JOIN Tempost AS ВременныйРезерв (NOLOCK) ON РезервыТМЦ.IDDOC = ВременныйРезерв.IDDOC
    |AND $РезервыТМЦ.Номенклатура    = ВременныйРезерв.Tov
    |AND $РезервыТМЦ.Склад           = ВременныйРезерв.Skl
    |WHERE (РезервыТМЦ.IDDOC            = :ТекДок)
    |    AND ($РезервыТМЦ.Номенклатура  = :Товар)
    |    AND ($РезервыТМЦ.Склад         = :Склад)
    |";

    RecordSet.УстановитьТекстовыйПараметр("ТекДок",   ТекДок);
    RecordSet.УстановитьТекстовыйПараметр("Товар",    Товар);
    RecordSet.УстановитьТекстовыйПараметр("Склад",    Склад);

    ТаблИтогов = RecordSet.ВыполнитьИнструкцию(ТекстЗапроса);
Иначе
    ВыдаватьСообщение = 0; //документ может быть старым и во временных резервах отсутствовать

    ТекстЗапроса = "
    |SELECT Sum(ВременныйРезерв.Res) Количество
    |FROM Tempost AS ВременныйРезерв
    |WHERE (ВременныйРезерв.IDDOC    = :ИДДок)
    |    AND (ВременныйРезерв.Tov    = :Товар)
    |    AND (ВременныйРезерв.Skl    = :Склад)
    |";

    RecordSet.УстановитьТекстовыйПараметр("ИДДок",    ИДДок);
    RecordSet.УстановитьТекстовыйПараметр("Товар",    Товар);
    RecordSet.УстановитьТекстовыйПараметр("Склад",    Склад);

    ТаблИтогов = RecordSet.ВыполнитьИнструкцию(ТекстЗапроса);
КонецЕсли;    

Далее модифицируем модуль формы документа "Заявка покупателя". В процедуру ПриОткрытии() добавляем код создания временной таблицы хранения резервов (для отката изменений):

Процедура ПриОткрытии() СтарыйСклад = Склад; ИДДок = Meta.ЗначениеВСтрокуБД(ТекущийДокумент()); ИДПольз = Meta.ЗначениеВСтрокуБД(глПользователь);Если Выбран()= 0 Тогда ВТ ="temp" + СокрЛП(ИДПольз);Иначе ВТ ="temp" + СокрЛП(ИДДок);КонецЕсли;//для отката изменений ТекстЗапроса ="|if exists (select name from dbo.sysobjects where name = '" + ВТ + "' and xtype = 'U ')
    |drop table " + ВТ + "
    |"; RecordSet.ВыполнитьИнструкцию(ТекстЗапроса); RecordSet.ВыполнитьИнструкцию("create table " + ВТ 
 +" (tov char(9), skl char(9), res numeric (15,3), iddoc char(9))"); RecordSet.УстановитьТекстовыйПараметр("ИДДок", ИДДок); RecordSet.ВыполнитьИнструкцию("insert into " + ВТ +" select * from tempost where iddoc = :ИДДок");КонецПроцедуры

При записи документа производим хитрые манипуляции с таблицей для отката изменений и изменяем Iddoc в таблице временных резервов:

Процедура ПриЗаписи()Если Выбран() =1 ТогдаВозврат;КонецЕсли; Записать(); СтарыйИДДок = Лев(Meta.ЗначениеВСтрокуБД(глПользователь),6) +"ZZZ"; ИДДок = Meta.ЗначениеВСтрокуБД(ТекущийДокумент());//назначаем постоянный иддок новому документу RecordSet.УстановитьТекстовыйПараметр("ИДДок", ИДДок); RecordSet.УстановитьТекстовыйПараметр("СтарыйИДДок", СтарыйИДДок); RecordSet.ВыполнитьИнструкцию("update tempost (HOLDLOCK) set iddoc = :ИДДок where iddoc = :СтарыйИДДок"); ИДДок = Meta.ЗначениеВСтрокуБД(ТекущийДокумент()); ИДПольз = Meta.ЗначениеВСтрокуБД(глПользователь);//таблицу для отката переименуем ВТ ="temp" + СокрЛП(ИДПольз); ВТНов ="temp" + СокрЛП(ИДДок); RecordSet.ВыполнитьИнструкцию("EXEC sp_rename '" + ВТ +"', '" + ВТНов +"'");//если документ записан - удалим его из таблицы открытых документов RecordSet.УстановитьТекстовыйПараметр("ИДДок", ИДДок); RecordSet.ВыполнитьИнструкцию("delete from openz with(HOLDLOCK) where iddoc = :ИДДок");КонецПроцедуры

Процедура ПриЗакрытии() не менее хитрая, нам нужно откатить изменения:

Процедура ПриЗакрытии()
    Если Выбран() = 1 Тогда
        //если документ не записывается но изменялся - возвращаем назад состояние таблицы
        ИДДок = Meta.ЗначениеВСтрокуБД(ТекущийДокумент());
        ВТ = "temp" + СокрЛП(ИДДок);
        
        Если Модифицированность() = 1 Тогда
            RecordSet.УстановитьТекстовыйПараметр("ИДДок", ИДДок);
            RecordSet.ВыполнитьИнструкцию("delete from tempost with(HOLDLOCK) where iddoc = :ИДДок");
            
            RecordSet.ВыполнитьИнструкцию("insert into tempost with(HOLDLOCK) select * from " + ВТ);
            
            //если документ не изменялся сознательно - удалим его из таблицы открытых документов
            RecordSet.УстановитьТекстовыйПараметр("ИДДок", ИДДок);
            RecordSet.ВыполнитьИнструкцию("delete from openz with(HOLDLOCK) where iddoc = :ИДДок");
        КонецЕсли;
        
        RecordSet.ВыполнитьИнструкцию("drop table " + ВТ);
        Возврат;
    КонецЕсли;
    
    //если новый документ не записывается - очищаем таблицу
    ИДДок = Лев(Meta.ЗначениеВСтрокуБД(глПользователь), 6) + "ZZZ";
    
    ИДПольз = Meta.ЗначениеВСтрокуБД(глПользователь);
    ВТ = "temp" + СокрЛП(ИДПольз);
    
    RecordSet.УстановитьТекстовыйПараметр("ИДДок", ИДДок);
    RecordSet.ВыполнитьИнструкцию("delete from tempost with(HOLDLOCK) where iddoc = :ИДДок");
    
    RecordSet.ВыполнитьИнструкцию("drop table " + ВТ);
КонецПроцедуры 

Самое сложное позади. Осталось предусмотреть редактирование данных документа. Приведу коды некоторых процедур:

Процедура ПриУдаленииСтроки() глИзменитьРезерв(ТекущийДокумент(), Номенклатура, Склад,0, -Количество);КонецПроцедурыПроцедура ПриНачалеРедактированияСтроки() СтароеКоличество = Количество;КонецПроцедурыПроцедура ПриОкончанииРедактированияСтроки() МаксКолво =0;Если глИзменитьРезерв(ТекущийДокумент(), Номенклатура, Склад, Количество, Количество - СтароеКоличество, МаксКолво) =0 Тогда Количество = МаксКолво;КонецЕсли;КонецПроцедуры

При такой доработке конфигурации получаем три очевидных плюса при достаточно глубоком изменении кода:

  • Товар, который подбирается в заявку, будет в свободном остатке и заявка однозначно будет проведена (не придется звонить и извиняться перед заказчиком)
  • Ускорение проведения документов
  • Ускорение вывода доступных остатков в форме подбора, отчетах, формах документов

Можете скачать простую демо конфигурацию для SQL. Создавайте приходный документ и далее балуйтесь с заявкой.

Вот вкратце и все. Если тема показалась интересной - пишите, будем внедрять. 

Онлайн резервирование товаров торговля

См. также

Печатные формы Адаптация типовых решений Программист Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Приятное улучшение обработки "Внешние печатные формы" для типовых конфигураций на базе 1С 7.7 для более комфортной работы с "любимой семерочкой".

1 стартмани

04.02.2022    3277    1    igor7777    0    

3

Адаптация типовых решений Программист Платформа 1С v7.7 Конфигурации 1cv7 Россия Бухгалтерский учет ФОМС, ЕФС Бесплатно (free)

В этой статье описано, какие небольшие изменения можно внести в модуль документа Начисление налогов с ФОТ, чтобы правильно рассчитывались страховые взносы с 1 апреля 2020 г.

09.04.2020    20285    Юджин58    39    

5

Адаптация типовых решений Программист Платформа 1С v7.7 1С:Комплексная 7.7 1С:Торговля и склад 7.7 Управленческий учет Бесплатно (free)

Описан способ работы с учетом расписания с приоритетными покупателями - торговыми сетями (основными покупателями) в торговой или комплексной учетной системе на 1С 7.7. Множественная заявка покупателя на несколько торговых точек.

14.10.2019    6174    ksnik    14    

3

Операции по ВЭД Адаптация типовых решений Программист Оперативный учет 7.7 1С:Торговля и склад 7.7 Россия Бухгалтерский учет НДС Бесплатно (free)

В данной статье хотел поделиться опытом, как в Торговле 7.7 ( релиз 994) сделать возможность выводить код ТНВЭД в печатную форму счета-фактуры. Сразу скажу, что нужно это только тем, кто осуществляет экспорт в страны таможенного союза. Остальные могут не волноваться.

15.11.2017    11924    AndKovalchuk    0    

1

Зарплата Адаптация типовых решений Программист Бухгалтерский учет 7.7 1С:Бухгалтерия 7.7 Россия Бухгалтерский учет Абонемент ($m)

Реализация Постановления Правительства РФ 1316 от 04.12.14 для типовой конфигурации "Бухгалтерский учет 7.7" рел. 7.70.590

1 стартмани

31.12.2014    23996    9    Sergey1CSpb    2    

0
Оставьте свое сообщение