Заказы клиентов в 1С УТ 11 — это документ «Заказ клиента» и цепочка вокруг него: резерв, график оплаты, отгрузка и закрытие. Ниже — как включить заказы и выбрать режим, что значат статусы и колонка «Действия», где смотреть исполнение, а затем код: запросы к регистрам заказов и расчётов, запрет отмены строк, дата отгрузки по правилу и автозакрытие.
Названия сверены по выгрузке 1С:Управление торговлей 11.4.14 и по КА 2.5, у которой общая с УТ 11.5 кодовая база; отличия 11.5 отмечены.
«НСИ и администрирование» → «Настройка НСИ и разделов» → «Продажи», группа «Оптовые продажи»: флажок «Заказы клиентов». Ниже, в блоке «Использование заказов» (в 11.5 — «Использование заказов клиентов»), выбирают режим. Менять режим на рабочей базе программа не советует.
| Режим | Что даёт | Функциональные опции |
|---|---|---|
| Заказ как счет | Заказ нужен для печати счёта: статусов нет, товар не резервируется, исполнение не контролируется | обе выключены |
| Заказ только со склада | Заказ на товар в наличии, статусы, планирование оплаты, контроль исполнения | ИспользоватьРасширенныеВозможностиЗаказаКлиента |
| Заказ со склада и под заказ | Можно заказать то, чего нет: действие задают в каждой строке, отгрузка по мере обеспечения | плюс ИспользоватьПострочнуюОтгрузкуВЗаказеКлиента |
Рядом — флажки «Контроль отгрузки при закрытии заказов и заявок», «Контроль оплаты при закрытии заказов и заявок», «Причины отмены заказов клиентов» и «Реализация по нескольким заказам». Список документов — «Продажи» → «Оптовые продажи» → «Заказы клиентов».
Статус ставит менеджер, а состояние программа пересчитывает при проведении заказа, оплат и отгрузок и хранит в регистре сведений «Состояния заказов клиентов».
КОбеспечению, подпись зависит от режима.«Закрыт» есть в списке статусов, только если включён один из флажков контроля при закрытии. Кнопка «Закрыть заказ» (в списке — «Закрыть заказы») открывает «Помощник закрытия заказов»: он отменяет неотгруженные строки и ставит статус «Закрыт».
Состояния: «Ожидается согласование», «Ожидается аванс (до обеспечения)», «Готов к обеспечению», «Ожидается предоплата (до отгрузки)», «Ожидается обеспечение», «Готов к отгрузке», «В процессе отгрузки», «Ожидается оплата (после отгрузки)», «Готов к закрытию», «Закрыт». В 11.5 подписи оплат другие: «Ожидается оплата до обеспечения», «Ожидается оплата до отгрузки», «Ожидается оплата». «Готов к закрытию» бывает только при включённом контроле закрытия, без него выполненный заказ сразу получает состояние «Закрыт».
Вид цен, склад и график оплаты заказ берёт из соглашения с клиентом, перезаполнить цены — команда «Цены по условиям продаж». Способ планирования оплаты задаёт блок «Условия и порядок оплаты» в тех же настройках: «Предоплата и/или кредит» (в 11.5 — «Оплата до отгрузки и/или после отгрузки»), «Произвольное количество этапов оплаты» или «Шаблоны графиков оплаты». В заказе этапы открываются ссылкой на вкладке «Основное», в коде это табличная часть ЭтапыГрафикаОплаты.
Значение ВариантОплаты | УТ 11.4 | УТ 11.5 |
|---|---|---|
АвансДоОбеспечения | Аванс (до обеспечения) | Оплата до обеспечения |
ПредоплатаДоОтгрузки | Предоплата (до отгрузки) | Оплата до отгрузки |
КредитПослеОтгрузки | Кредит (плановый) | Оплата независимо от отгрузки |
КредитСдвиг | Кредит (после отгрузки) | Оплата после отгрузки |
Перечисления разные: ВариантыОплатыКлиентом в 11.4 и ВариантыКонтроляОплатыКлиентом в 11.5. Пока аванс или предоплата не пришли, заказ ждёт в состоянии «Ожидается аванс» или «Ожидается предоплата». Контроль работает при детализации расчётов «По заказам» (в 11.5 и «Аванс по заказам, долг по накладным»). При «По накладным» (в 11.5 — «По расчетным документам») суммы аванса и предоплаты при записи заказа обнуляются.
В режиме «Заказ со склада и под заказ» судьбу строки задаёт колонка «Действия» на вкладке «Товары» (реквизит ВариантОбеспечения). В режиме «Заказ только со склада» действие подставляется само по статусу.
| Действие | Значение | Что происходит |
|---|---|---|
| Отгрузить | Отгрузить | Товар есть, строка готова к оформлению накладной |
| Резервировать на складе | СоСклада | Резерв из свободного остатка склада |
| Резервировать к дате (11.4), Резервировать по мере поступления (11.5) | ИзЗаказов, РезервироватьПоМереПоступления | Резерв из ожидаемых поступлений |
| К обеспечению | Требуется (11.4), КОбеспечению (11.5) | Потребность: товар надо закупить или переместить |
| Не обеспечивать | НеТребуется | Строка не резервируется и в потребность не попадает |
Обособленное обеспечение под конкретный заказ включают в «Склад и доставка» → «Обеспечение потребностей» → «Обособленное обеспечение заказов»: в 11.4 для него есть действия «Обеспечивать обособленно» и «Отгрузить обособленно», в 11.5 — флажок «Обособленно» в строке. Состояние строк показывает команда «Обеспечение» → «Состояние обеспечения...» над таблицей, в 11.5 — ссылка «Состояние обеспечения» на той же вкладке. Под строки «К обеспечению» на основании заказа создают «Заказ поставщику» или запускают «Формирование заказов по потребностям». Свободный остаток перед резервом смотрят по остаткам товаров на складах.
Код ниже — одно расширение с префиксом Расш_: общий модуль Расш_ЗаказыКлиентовСервер (флажок «Сервер»), заимствованный документ ЗаказКлиента и роль Расш_ОтменаСтрокЗаказовКлиентов без прав для профиля руководителей. Как заимствовать объекты — в статье о расширении конфигурации.
Те же данные, что в колонках списка, плюс отбор по менеджеру и просрочка. Текст запроса проверяется в бесплатной консоли запросов.
// Открытые заказы клиентов: текущее состояние, проценты оплаты и отгрузки, просрочка.
// Регистр сведений СостоянияЗаказовКлиентов одинаков в УТ 11.4 и 11.5,
// из него же берет колонки список «Заказы клиентов».
// Функция для серверного общего модуля; текст запроса работает и в консоли запросов.
//
// Параметры:
// Менеджер - СправочникСсылка.Пользователи, Неопределено - отбор по менеджеру заказа.
//
// Возвращаемое значение:
// ТаблицаЗначений - сначала заказы, у которых прошел срок текущего этапа.
//
Функция ОткрытыеЗаказыКлиентов(Менеджер = Неопределено) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Заказы.Ссылка КАК Заказ,
| Заказы.Партнер КАК Клиент,
| Заказы.Менеджер КАК Менеджер,
| Заказы.Статус КАК Статус,
| Заказы.СуммаДокумента КАК Сумма,
| Состояния.Состояние КАК Состояние,
| Состояния.ДатаСобытия КАК СрокЭтапа,
| Состояния.ПроцентОплаты КАК ПроцентОплаты,
| Состояния.ПроцентОтгрузки КАК ПроцентОтгрузки,
| ВЫБОР
| КОГДА Состояния.СуммаДолга > 0
| ТОГДА Состояния.СуммаДолга
| ИНАЧЕ 0
| КОНЕЦ КАК ДолгКлиента,
| ВЫБОР
| КОГДА Состояния.ДатаСобытия <> ДАТАВРЕМЯ(1, 1, 1)
| И Состояния.ДатаСобытия < &НачалоДня
| ТОГДА 1
| ИНАЧЕ 0
| КОНЕЦ КАК Просрочен
|ИЗ
| РегистрСведений.СостоянияЗаказовКлиентов КАК Состояния
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента КАК Заказы
| ПО Состояния.Заказ = Заказы.Ссылка
|ГДЕ
| Состояния.Состояние <> ЗНАЧЕНИЕ(Перечисление.СостоянияЗаказовКлиентов.Закрыт)
| И (&ВсеМенеджеры
| ИЛИ Заказы.Менеджер = &Менеджер)
|
|УПОРЯДОЧИТЬ ПО
| Просрочен УБЫВ,
| СрокЭтапа";
Запрос.УстановитьПараметр("НачалоДня", НачалоДня(ТекущаяДатаСеанса()));
Запрос.УстановитьПараметр("ВсеМенеджеры", Не ЗначениеЗаполнено(Менеджер));
Запрос.УстановитьПараметр("Менеджер", Менеджер);
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Регистры отличаются между релизами, поэтому имена таблиц функция берёт из метаданных.
// Неотгруженный остаток по строкам и неоплаченная сумма по заказам клиентов.
// Регистры зависят от релиза, поэтому имена берем из метаданных:
// - с УТ 11.5.18 оборотный РаспоряженияНаОтгрузку (измерение Распоряжение),
// раньше остаточный ЗаказыКлиентов (измерение ЗаказКлиента);
// - в РасчетыСКлиентами заказ лежит в измерении ЗаказКлиента (УТ 11.4)
// или в реквизите Объект справочника ОбъектыРасчетов (УТ 11.5).
//
// Параметры:
// Заказы - Массив из ДокументСсылка.ЗаказКлиента
//
// Возвращаемое значение:
// Структура:
// * Товары - ТаблицаЗначений - Заказ, Номенклатура, Характеристика, Склад, НеОтгружено, КОформлению.
// * Оплата - ТаблицаЗначений - Заказ, Валюта, ОсталосьОплатить.
//
Функция НеисполненноеПоЗаказам(Заказы) Экспорт
ТекстЗапроса =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Товары.#ПолеЗаказа КАК Заказ,
| Товары.Номенклатура КАК Номенклатура,
| Товары.Характеристика КАК Характеристика,
| Товары.Склад КАК Склад,
| Товары.Заказано#Итог КАК НеОтгружено,
| Товары.КОформлению#Итог КАК КОформлению
|ИЗ
| #ТаблицаТоваров КАК Товары
|ГДЕ
| (Товары.Заказано#Итог <> 0
| ИЛИ Товары.КОформлению#Итог <> 0)
|
|УПОРЯДОЧИТЬ ПО
| Заказ,
| Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Расчеты.#ЗаказВРасчетах КАК Заказ,
| Расчеты.Валюта КАК Валюта,
| Расчеты.КОплатеОстаток КАК ОсталосьОплатить
|ИЗ
| РегистрНакопления.РасчетыСКлиентами.Остатки(, #ЗаказВРасчетах В (&Заказы)) КАК Расчеты
|ГДЕ
| Расчеты.КОплатеОстаток > 0";
Если Метаданные.РегистрыНакопления.Найти("РаспоряженияНаОтгрузку") <> Неопределено Тогда
// Регистр оборотов: остаток распоряжения равен сумме всех его оборотов
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ТаблицаТоваров",
"РегистрНакопления.РаспоряженияНаОтгрузку.Обороты(, , , Распоряжение В (&Заказы))");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ПолеЗаказа", "Распоряжение");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#Итог", "Оборот");
Иначе
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ТаблицаТоваров",
"РегистрНакопления.ЗаказыКлиентов.Остатки(, ЗаказКлиента В (&Заказы))");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ПолеЗаказа", "ЗаказКлиента");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#Итог", "Остаток");
КонецЕсли;
Если Метаданные.РегистрыНакопления.РасчетыСКлиентами.Измерения.Найти("ОбъектРасчетов") <> Неопределено Тогда
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ЗаказВРасчетах", "ОбъектРасчетов.Объект");
Иначе
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ЗаказВРасчетах", "ЗаказКлиента");
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Заказы", Заказы);
Результаты = Запрос.ВыполнитьПакет();
Результат = Новый Структура;
Результат.Вставить("Товары", Результаты[0].Выгрузить());
Результат.Вставить("Оплата", Результаты[1].Выгрузить());
Возврат Результат;
КонецФункции
// Общий модуль расширения Расш_ЗаказыКлиентовСервер.
// Свойства: флажок «Сервер» установлен, остальные сняты.
#Область ПрограммныйИнтерфейс
// Запрещает отменять строки заказа без роли расширения Расш_ОтменаСтрокЗаказовКлиентов.
// «Закрыть заказ» отменяет неотгруженные строки, поэтому без роли
// не получится и закрыть заказ с недогрузом.
//
// Параметры:
// Заказ - ДокументОбъект.ЗаказКлиента - проверяемый заказ.
// Отказ - Булево - становится Истина, если строку отменили без права.
//
Процедура ПроверитьОтменуСтрок(Заказ, Отказ) Экспорт
// РольДоступна, а не Пользователи.РолиДоступны: функция БСП включает привилегированный режим
Если РольДоступна("ПолныеПрава") Или РольДоступна("Расш_ОтменаСтрокЗаказовКлиентов") Тогда
Возврат;
КонецЕсли;
// Строки, отмененные до этой записи, не проверяем: старый заказ можно перепровести
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.КодСтроки КАК КодСтроки
|ИЗ
| Документ.ЗаказКлиента.Товары КАК Товары
|ГДЕ
| Товары.Ссылка = &Ссылка
| И Товары.Отменено";
Запрос.УстановитьПараметр("Ссылка", Заказ.Ссылка);
ОтмененыРанее = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("КодСтроки");
Шаблон = НСтр("ru = 'Строка %1 (%2): отменять строки заказа может только руководитель продаж.'");
Для Каждого СтрокаТовары Из Заказ.Товары Цикл
Если Не СтрокаТовары.Отменено
Или ОтмененыРанее.Найти(СтрокаТовары.КодСтроки) <> Неопределено Тогда
Продолжить;
КонецЕсли;
ОбщегоНазначения.СообщитьПользователю(
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон,
СтрокаТовары.НомерСтроки, СтрокаТовары.Номенклатура),
Заказ,
ОбщегоНазначенияКлиентСервер.ПутьКТабличнойЧасти("Товары", СтрокаТовары.НомерСтроки, "Отменено"),
,
Отказ);
КонецЦикла;
КонецПроцедуры
// Дата отгрузки нового заказа: принятый до 15:00 отгружаем в тот же рабочий день,
// принятый позже или в выходной — в ближайший рабочий день по производственному календарю.
//
// Параметры:
// МоментПриема - Дата - когда принят заказ.
//
// Возвращаемое значение:
// Дата - начало дня отгрузки.
//
Функция ДатаОтгрузкиПоУмолчанию(МоментПриема) Экспорт
ЧасОкончанияПриема = 15; // при необходимости вынесите в константу расширения
ДатаОтсчета = НачалоДня(МоментПриема);
Если Час(МоментПриема) >= ЧасОкончанияПриема Тогда
ДатаОтсчета = ДатаОтсчета + 86400; // секунд в сутках
КонецЕсли;
Календарь = КалендарныеГрафики.ОсновнойПроизводственныйКалендарь();
Если Не ЗначениеЗаполнено(Календарь) Тогда
Возврат ДатаОтсчета;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Дни.Дата КАК Дата
|ИЗ
| РегистрСведений.ДанныеПроизводственногоКалендаря КАК Дни
|ГДЕ
| Дни.ПроизводственныйКалендарь = &Календарь
| И Дни.Дата >= &ДатаОтсчета
| И Дни.ВидДня В (ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий),
| ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный))
|
|УПОРЯДОЧИТЬ ПО
| Дни.Дата";
Запрос.УстановитьПараметр("Календарь", Календарь);
Запрос.УстановитьПараметр("ДатаОтсчета", ДатаОтсчета);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Дата;
КонецЕсли;
// Календарь на следующий год еще не загружен — оставляем календарную дату
Возврат ДатаОтсчета;
КонецФункции
// Закрывает заказы в состоянии «Готов к закрытию»: все отгружено и оплачено, осталось сменить статус.
// Такое состояние бывает, только если включен контроль отгрузки или оплаты при закрытии.
// Обработчик регламентного задания расширения (платформа 8.3.23 и новее)
// или процедура, которую вызывает дополнительная обработка по расписанию.
//
Процедура ЗакрытьВыполненныеЗаказы() Экспорт
ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Состояния.Заказ КАК Заказ
|ИЗ
| РегистрСведений.СостоянияЗаказовКлиентов КАК Состояния
|ГДЕ
| Состояния.Состояние = ЗНАЧЕНИЕ(Перечисление.СостоянияЗаказовКлиентов.ГотовКЗакрытию)
| И Состояния.Заказ ССЫЛКА Документ.ЗаказКлиента";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ЗакрытьЗаказ(Выборка.Заказ);
КонецЦикла;
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Процедура ЗакрытьЗаказ(Заказ)
НачатьТранзакцию();
Попытка
// Блокируем до чтения, чтобы заказ не изменили между ПолучитьОбъект и Записать
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Документ.ЗаказКлиента");
ЭлементБлокировки.УстановитьЗначение("Ссылка", Заказ);
Блокировка.Заблокировать();
ЗаказОбъект = Заказ.ПолучитьОбъект();
// Типовая экспортная функция модуля объекта: ставит статус и проверяет заполнение
Если ЗаказОбъект.УстановитьСтатус("Закрыт", Неопределено) Тогда
ЗаказОбъект.Записать(РежимЗаписиДокумента.Проведение);
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации(
НСтр("ru = 'Закрытие выполненных заказов'", ОбщегоНазначения.КодОсновногоЯзыка()),
УровеньЖурналаРегистрации.Ошибка,
Метаданные.Документы.ЗаказКлиента,
Заказ,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
#КонецОбласти
// Расширение, модуль объекта документа ЗаказКлиента.
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
&После("ОбработкаЗаполнения")
Процедура Расш_ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
Расш_ЗаполнитьДатуОтгрузки();
КонецПроцедуры
&После("ПриКопировании")
Процедура Расш_ПриКопировании(ОбъектКопирования)
// Копирование не вызывает ОбработкаЗаполнения, поэтому правило применяем и здесь
Расш_ЗаполнитьДатуОтгрузки();
КонецПроцедуры
&После("ОбработкаПроверкиЗаполнения")
Процедура Расш_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// Проведение из формы, «Закрыть заказ» и «Закрыть заказы» в списке
Расш_ЗаказыКлиентовСервер.ПроверитьОтменуСтрок(ЭтотОбъект, Отказ);
КонецПроцедуры
Процедура Расш_ЗаполнитьДатуОтгрузки()
// «Отгружать одной датой»: дату шапки типовой ПередЗаписью переносит в строки.
// Если флажок снят, даты ведут в строках, и правило не применяем.
Если Не НеОтгружатьЧастями Тогда
Возврат;
КонецЕсли;
ДатаПоПравилу = Расш_ЗаказыКлиентовСервер.ДатаОтгрузкиПоУмолчанию(ТекущаяДатаСеанса());
// Более позднюю дату, которую уже подставила типовая логика, оставляем
Если ДатаОтгрузки < ДатаПоПравилу Тогда
ДатаОтгрузки = ДатаПоПравилу;
КонецЕсли;
КонецПроцедуры
#КонецЕсли
ДатаСобытия — срок текущего этапа: согласования, оплаты или отгрузки. Список заказов считает просрочку так же, а записи в регистре есть только у проведённых заказов.РаспоряженияНаОтгрузку — регистр оборотов: остаток распоряжения равен сумме всех оборотов, поэтому Обороты без периода. Он заменил остаточный ЗаказыКлиентов в УТ 11.5.18, измерение ЗаказКлиента стало Распоряжение.Заказано — ещё не отгружено, КОформлению — строки «Отгрузить» без накладной, КОплатеОстаток — сколько осталось оплатить. При расчётах по договорам долг к заказу не привязан, и таблица «Оплата» пустая.ОбработкаПроверкиЗаполнения срабатывает при проведении из формы и в помощнике закрытия: при групповом закрытии он вызывает типовую УстановитьСтатус, а та — ПроверитьЗаполнение(). Задание «Корректировка строк заказов мерных товаров» проводит заказ программно, запрет его не трогает.КодСтроки с записанной версией ловит только новые отмены: старые не мешают перепровести заказ.ПриНачалеВыполненияРегламентногоЗадания включает привилегированный режим, поэтому у расширения с заданием снимите флажок «Безопасный режим».РаспоряженияНаОтгрузку или выбирайте таблицу по метаданным, как во втором листинге.Добавьте в график оплаты соглашения этап «Аванс (до обеспечения)», в 11.5 — «Оплата до обеспечения». Пока аванс не пришёл, заказ стоит в состоянии «Ожидается аванс (до обеспечения)» и в «Готов к обеспечению» не переходит.
При включённом контроле закрытия отгруженный и оплаченный заказ получает состояние «Готов к закрытию», а статус «Закрыт» ставят вручную, командой «Закрыть заказы» в списке или заданием вроде ЗакрытьВыполненныеЗаказы. Без контроля такой заказ сразу считается закрытым.
Да: включите «Реализация по нескольким заказам» в настройках раздела «Продажи», и заказ будет указан в каждой строке реализации.
По выгрузке КА 2.5: регистр РаспоряженияНаОтгрузку вместо ЗаказыКлиентов, расчёты через справочник «Объекты расчетов» (реквизит заказа ОбъектРасчетов), другой состав ВариантыОбеспечения, флажок Обособленно в строке, новый реквизит ЭтоЗаказКакСчет и нет ЖелаемаяДатаОтгрузки.
Смена режима заказов на рабочей базе, обособленное обеспечение, заказы с сайта или маркетплейсов с резервом и контролем оплаты — задачи, где ошибка сразу видна на складе и в долгах клиентов. Опишите задачу в разделе услуг по доработке 1С или разместите задачу: оценка бесплатная, ответ в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.