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

10.10.13

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

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

Скачать исходный код

Наименование Файл Версия Размер
Демо конфигурация online резервирования (только для SQL)
.rar 450,00Kb
2
.rar 1.0 450,00Kb 2 Скачать

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

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

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

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

Что нужно сделать? Рассмотрим работу с форматом 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С 7.7

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

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

1 стартмани

04.02.2022    3235    1    igor7777    0    

3

Расчет страховых взносов в 1С 7.7 "Учет и отчетность предпринимателя, ред. 1.2" с апреля 2020

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

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

09.04.2020    20010    Юджин58    39    

5

Дистрибьюция 7.7. Часть 1. Жизненный цикл заявки покупателя. Одна заявка покупателя, много адресов доставки.

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

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

14.10.2019    6093    ksnik    14    

3

Как в торговле 7.7 печатать код ТНВЭД в счет-фактуре

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

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

15.11.2017    11870    AndKovalchuk    0    

1

Предельные базы взносов в ПФР, ФСС, ФФОМС 2015 в 1С: Бухгалтерия 7.7

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

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

1 стартмани

31.12.2014    23974    9    Sergey1CSpb    2    

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