Срок поставки

1. extrim-style 7 06.09.18 11:20 Сейчас в теме
Доброго дня!
Кто-нибудь реализовывал "срок поставки по периоду времени"? Как это лучше сделать?
Согласно ст. 190 ГК РФ "Период времени определяется годами, месяцами, неделями, днями или часами".
Существует ли типовой функционал? Как лучше хранить: в строке с разделителями, или в структуре (завернутой в хранилище)?
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Boneman 298 06.09.18 11:24 Сейчас в теме
(1)
Как лучше хранить: в строке с разделителями, или в структуре (завернутой в хранилище)?

Как по мне, так это классическое перечисление
3. extrim-style 7 06.09.18 11:41 Сейчас в теме
Перечисление - это в рамках определения вариантов, но в плане интерфейсной реализации с возможностью указания, к примеру "1 год 3 месяца 10 дней" всё несколько иначе.
4. Boneman 298 06.09.18 12:02 Сейчас в теме
(3) ах вон о чем речь идет.
Что то похожее я решал, только о сроке годности продукции речь шла.
Так вот, в базе я хранил просто количество дней. А внешне на форме, это количество преобразовывалось именно в Год, месяц, дней.. и обратное преобразование также было,
пользователь выбирает 1 - год, 3 месяца - 5 дней, а при записи оно высчитывало обратно, точное количество и записывало в реквизит число дней, от даты производства.
Но были сложности, с таким алгоритмом. Во первых число дней в месяцах разное, поэтому надо не константные значения, а именно отталкиваться от даты отсчета отталкиваться и по периодам по уменьшению. Во вторых, при открытии - форма должна число дней обратно разбить в год, месяц, день ..а не просто 0 лет, 0-месяцев, и 576 дней. Поэтому пришлось повозится. Зато потом с числом работать проще, и в обработках и в отчетах и во всяких процедурах..нежели я бы хранил именно структуру, как это вводит пользователь
9. extrim-style 7 06.09.18 13:26 Сейчас в теме
1 месяц - это сколько дней? 30 или 31? А может 28 или 29? Как из количества дней восстановить срок "1 месяц"?
10. Boneman 298 06.09.18 13:48 Сейчас в теме
(9)
1 месяц - это сколько дней? 30 или 31? А может 28 или 29? Как из количества дней восстановить срок "1 месяц"?

есть такая функция, добавить месяц.
По ней мы получаем точную очередную дату, ровного месяца от отчетной даты.
А значим легко можем получить количество дней между этими датами. Далее цикл, и вычисления - пока дни не закончатся.

Щас поищу у себя в архивах, может найду готовые функции
11. Boneman 298 06.09.18 13:58 Сейчас в теме
(9) ну я делал примерно так...в первую функцию загоняем Дата1 = ДатаНачала и Дней =количество дней - получим строкой сколько там дней, лет, месяцев
Функция ДнейВСтроку(ЗНАЧ Дней,ЗНАЧ Дата1=неопределено,Дата2=неопределено) Экспорт
	Если Дата1=неопределено тогда   //считает от нулевого года
		Дата1 = Дата(1,1,1,0,0,0);
	КонецЕсли;
	Если Дата2=неопределено тогда   //Вычсисляем по дням
		Дата2 = Дата1+Дней*24*60*60;
	КонецЕсли;
	Лет = 0; Месяцев = 0; Дней = 0;
	РазобратьРазностьДат(Дата2,Дата1,Лет,Месяцев,Дней);
	Возврат СрокПрописью(Лет,Месяцев,Дней);
КонецФункции

//Возвращает прописью Чис1-год, Чис2-мес, Чис3-лет
Функция СрокПрописью(Чис1,Чис2,Чис3) Экспорт
	Если Чис1=0 и Чис2=0 и Чис3=0 тогда
		Возврат "не ограничен";
	КонецЕсли;
    Возврат "" 
    + ?(Чис1>0,(Строка(Чис1) + " " + СтрЗаменить(ЧислоПрописью(Чис1,,"год,года,лет,м,,,,,0"),ЧислоПрописью(Чис1,,",,,,,,,,0"),"")+" "),"") 
    + ?(Чис2>0,(Строка(Чис2) + " " + СтрЗаменить(ЧислоПрописью(Чис2,,"месяц,месяца,месяцев,м,,,,,0"),ЧислоПрописью(Чис2,,",,,,,,,,0"),"")+" "),"") 
    + ?(Чис3>0,(Строка(Чис3) + " " + СтрЗаменить(ЧислоПрописью(Чис3,,"день, дня, дней,м,,,,,0"),ЧислоПрописью(Чис3,,",,,,,,,,0"),"")+" "),"");
КонецФункции

Процедура РазобратьРазностьДат(Дата1, Дата2, Лет = 0, Месяцев = 0, Дней = 0) Экспорт
    
    Лет        = 0;
    Месяцев    = 0;
    Дней    = 0;
    Если Дата1 > Дата2 Тогда
        
        ВременнаяДата = Дата1;
        Если День(ВременнаяДата) < День(Дата2) Тогда
            Дней = (ВременнаяДата - ДобавитьМесяц(ВременнаяДата,-1))/86400;
            ВременнаяДата = ДобавитьМесяц(ВременнаяДата,-1);
        КонецЕсли;
        Если Месяц(ВременнаяДата) < Месяц(Дата2) Тогда
            ВременнаяДата = ДобавитьМесяц(ВременнаяДата,-12);
            Месяцев = 12;
        КонецЕсли;
        Лет        = Макс(             Год(ВременнаяДата)        - Год(Дата2),    0);
        Месяцев    = Макс(Месяцев    + Месяц(ВременнаяДата)    - Месяц(Дата2),    0);
        Дней    = Макс(Дней        + День(ВременнаяДата)    - День(Дата2),    0);
        
       // скорректируем отображаемое значение, если "вмешалось" разное количество дней в месяцах
 
        Если Дата2 <> (ДобавитьМесяц(Дата1,-Лет*12-Месяцев)-Дней*86400) Тогда
            Дней = Дней + ((ДобавитьМесяц(Дата1,-Лет*12-Месяцев)-Дней*86400) - Дата2)/86400;
           //(День(КонецМесяца(Дата2)) - День(НачалоМесяца(Дата2))) - (День(КонецМесяца(ДобавитьМесяц(Дата1,-1))) - День(НачалоМесяца(ДобавитьМесяц(Дата1,-1))));
 
        КонецЕсли;
        
    КонецЕсли;

КонецПроцедуры   // РазобратьРазностьДат
Показать
12. extrim-style 7 06.09.18 14:25 Сейчас в теме
(11) Спасибо, но видимо у нас разные задачи. Я уже писал в (5), что у меня "плавающая дата начала". Пользователи хотят хранить срок поставки в карточке договора, которая - на период времени. Если срок, вводимый пользователем в момент создания карточки договора, будет конвертироваться в количество дней, то в момент формирования заказа сохраненное в реквизите количество дней никак не скажет о том, какой на самом деле срок поставки имел ввиду пользователь - "1 месяц" или "30 дней". А это - не одно и то же.
13. Octopus 337 06.09.18 14:29 Сейчас в теме
(12) Храните набор пар: число и единицу измерения. 30 "Дни" и 2 "Месяцы", к примеру. Закодировать просто - длинным числом. Последние два разряда - дни, следующие два - месяцы, и т.д. В запросе разбиваете делением, ненулевые куски плюсуете к нужной дате через ДОБАВИТЬКДАТЕ. Надеюсь, понятно объяснил...
14. extrim-style 7 06.09.18 14:38 Сейчас в теме
(13) Проще в таком случае строкой с разделителями.
16. Octopus 337 06.09.18 14:47 Сейчас в теме
(14) В запросе ее обрабатывать тяжело, не умеет 1Ска запросом строки в числа переводить
15. Boneman 298 06.09.18 14:40 Сейчас в теме
(12)
Спасибо, но видимо у нас разные задачи. Я уже писал в (5), что у меня "плавающая дата начала". Пользователи хотят хранить срок поставки в карточке договора, которая - на период времени. Если срок, вводимый пользователем в момент создания карточки договора, будет конвертироваться в количество дней, то в момент формирования заказа сохраненное в реквизите количество дней никак не скажет о том, какой на самом деле срок поставки имел ввиду пользователь - "1 месяц" или "30 дней". А это - не одно и то же.

Что же все такие трудные то.
В чем проблема пересчитывать туда- обратно ? Я привел уже готовую, разжеванную функцию по реализации именно такой задачи. Естественно это не готовое решение, а кусок решения.
У меня дата также не фиксированная, а плавающая была. И вызывалась и преобразовывалась, в нужных местах.
Могу даже вкратце поведать о чем речь. Это был паспорт качества товара, у которого задавался эталонный срок годности. При поступлении товара, естественно с разными датами и поступления и производства, должен отображаться всегда одно и тоже количество дней, лет и месяцев.

Не знаю, кому-как, но по мне, так это почти одинаковая задача с вашей, только у вас срок поставки, а у меня срок годности. У вас только еще часы надо вычислять.

А для реализации всего этого, нужна лишь эталонная дата начала, от которой считать эталонное количество лет. Если присмотреться в мою функцию, то там первый параметр если не задавать, то считается от Дата(1,1,1) - это и есть наш эталон.

З.Ы.
Собственно, чего это я тут... как говорится мое дело предложить. Нет так нет. Городите свои хранилища и структуры )))
17. extrim-style 7 06.09.18 15:39 Сейчас в теме
(15) Насколько я понял, в случае попытки хранения срока от нулевой даты могут возникнуть сложности при желании сохранения сроков 29-30 дней, к примеру "1 месяц 30 дней". В таком случае нужно, чтобы маска срока укладывалась в календарь. А если не укладывается, то нужно искать точку отчета такую, в которую эта маска уляжется. А это в свою очередь добавляет необходимость хранения ещё одной даты...
18. Boneman 298 06.09.18 15:50 Сейчас в теме
(17)
л, в случае попытки хранения срока от нулевой даты могут возникнуть сложности при желании сохранения сроков 29-30 дней, к примеру "1 месяц 30 дней

ну так эта проблема остается при любой алгоритмизации.
Даже если в буквальном виде хранить данные. То при фактическом расчете все равно придется что-то делать с вычислениями. От 1 января - у нас получится например сразу март. Хотя тут уже более логично задавать 2 месяца. Все равно что-то с этим делать придется.
Кстати, да, я помню - что у себя там я делал ограничение выбора пользователем количества дней 28, по минимуму февраля. И 1 месяц и 30 дней в принципе было невозможно задать.

Еще округлять можно, если количество дней превышает количество дней в расчетном месяце, то брать тупо последнее число, без перехода на следующий месяц.
19. extrim-style 7 06.09.18 17:16 Сейчас в теме
(18) Не вижу никаких проблем добавления конкретного срока, скажем "1 год 5 месяцев 20 дней", к конкретной дате. Получится то, что и должно получится...
20. RocKeR_13 1326 06.09.18 17:24 Сейчас в теме
(19) тогда как вариант - сделать строковый реквизит, бросить на форму и настроить ввод по маске, а-ля "99/99/99". Дальше при преобразовании использовать функцию СтрРазделить, указав в качестве разделителя "/" и использовать на выходе массив с количеством дней, месяцев и лет. В отчетах, если нужно, использовать функцию ПОДСТРОКА() ну или в крайнем случае вызывать экспортную процедуру из общего модуля для необходимых манипуляций
22. extrim-style 7 07.09.18 09:25 Сейчас в теме
(20) про строку с разделителями я уже упоминал в (0)
24. RocKeR_13 1326 07.09.18 09:39 Сейчас в теме
(22) да уж, вчера был сложный день, просмотрел) На мой взгляд вполне неплохой вариант.
21. Boneman 298 06.09.18 17:25 Сейчас в теме
(19)
олучится то, что и должно получится...

Всегда есть проблема в точности. 1 год 2 месяца и 3 дня может быть равен 1 году и 2 месяцам - если считать в днях.

Вопрос лишь в том, в какой момент мы эту погрешность игнорируем. В момент планирования или в момент вывода.
23. extrim-style 7 07.09.18 09:28 Сейчас в теме
(21) Есть договор, согласно которому оговаривается срок. Какой срок оговорили - такой и получили. Учетная система всего лишь должна правильно предоставить эту возможность. В противном случае, если проблема на стороне учетной системы, то это камень в ваш огород и минус вашего подхода.
25. Boneman 298 07.09.18 09:52 Сейчас в теме
(23)
Учетная система всего лишь должна правильно предоставить эту возможность. В противном случае, если проблема на стороне учетной системы, то это камень в ваш огород и минус вашего подхода.

мой подход - это всего лишь вариант реализации, идея. В мой огород вообще никаких камней быть не может. Это ВЫ у нас спрашиваете, как лучше сделать, а не мы с вами советуемся.

Я вообще тогда не понимаю сути вопроса. Как хранить константные условия договора ? Для этого и предназначены реквизиты объекта. Добавляете 3 реквизита тип Число, и хранятся они в базе у вас ровно в том виде как изначально в условиях прописано, и ничего придумывать тут вообще не нужно. И в отчетах выгребаться будут, и в расчетах без проблем обращаться можно.
26. extrim-style 7 07.09.18 11:54 Сейчас в теме
(25) Без каких-либо претензий. Наоборот, благодарю за участие в теме, направление решения и предоставленный код. Насчет "камня в огород" просто в том смысле, что вторая часть вашего ответа - снова к вам же.
5. extrim-style 7 06.09.18 12:21 Сейчас в теме
Как раз по причине разного количества дней и плавающей даты начала в периоде договора хранить в днях не получится.
6. Boneman 298 06.09.18 12:29 Сейчас в теме
(5)
Как раз по причине разного количества дней и плавающей даты начала в периоде договора хранить в днях не получится.

ну у меня же получилось ))
только их актуализировать надо каждый раз, при смене даты начала периода договора.
Ну или храни структуру, - только структуру реквизитом не сделаешь, и в отчетах не выведешь - и придется изобретать какую то универсальную функцию для вытаскивания этого.
Что так, что этак геморой.
7. RocKeR_13 1326 06.09.18 13:00 Сейчас в теме
(5) хранить в единицах самого малого периода, то бишь в часах?
8. Octopus 337 06.09.18 13:08 Сейчас в теме
(7) Ну так в (4) это и предлагают. Просто в том примере минимальным периодом был день.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот