Вход | Регистрация
    1  2  3  4  5  6   

Конкретные вопросы по lsFusion. Часть 2.

Конкретные вопросы по lsFusion. Часть 2.
Я
   CrushBy
 
14.10.19 - 21:08
В этой ветке только вопросы по lsFusion, без оценок и срача, что в сторону lsFusion, что в сторону 1С.

Для сравнения и троллинга есть отдельная ветка : OFF: lsFusion vs 1C. Раунд 3
 
 
   _DAle_
 
401 - 25.10.19 - 11:09
(398) Извиняюсь, нет времени сейчас разобраться полностью в вопросе (да и, возможно, я не смогу на него полностью ответить). Главное - любые изменения в lsfusion делаются в некоторой сессии изменений (можно, наверное, провести аналогию с транзакцией). То есть пользователь в своей сессии изменений что-то меняет, и пока он не сохранит эти изменения (обычно это осуществляется нажатием кнопки "Сохранить"), ничего в базу не попадает, и другие пользователи этих изменений не видят.
Сессии изменений: https://documentation.lsfusion.org/pages/viewpage.action?pageId=2719863
действие APPLY: https://documentation.lsfusion.org/pages/viewpage.action?pageId=5832735
   Злопчинский
 
402 - 25.10.19 - 13:51
(400) тут ценность не в том что написано, а какие подходы сделаны. а почти каждая ВМС на рынке - это свой вариант реализации. Простые вмс системы это одно. а есть вмс, где можно сконструировать практически без кода очень сложные бизнес-процессы обработки товаропотока на складе. и это - не на уровне галочек делается. даже формы для ТСД и то могут генериться системой на ходу автоматически. это вам блин не столбец просуммировать...
   НиколаевГ
 
403 - 25.10.19 - 13:55
(402) Вот поэтому нет и не будет WMS на фузине...
   Злопчинский
 
404 - 25.10.19 - 14:07
(403) с учетом того, что фузиновцы пилят решения частные "по месту" - то вполне можно.
   Злопчинский
 
405 - 25.10.19 - 14:12
(403) вмску под конкретный склад написать можно достаточно быстро. реально достаточно быстро. только проблема в подстройке под новые хотелки. все превратится в постонное допрограммирование.
   НиколаевГ
 
406 - 25.10.19 - 14:14
(404) Тогда почему нет до сих пор? А, да, клиенты же не попросили :))
   Ещё1
 
407 - 25.10.19 - 14:19
Пишу действие по кнопке на форме редактирования заказа. Чем отличается
NEWSESSION {
  status(order) <- Status.Sent;
  APPLY;
}
от
NEWSESSION {
  status(order) <- Status.Sent;
}
В обоих случаях создаваемая здесь сессия будет завершена при выходе с обработчика действия кнопки.
   Злопчинский
 
408 - 25.10.19 - 14:35
Чем на форме (со списком документов, например) кнопка "ок" отличается от кнопки "закрыть"..? - вы как-то если подвязались на вопросы отвечать - не динамьте, а то ломает повторно спрашивать
   _DAle_
 
409 - 25.10.19 - 14:36
(407) Сессия будет завершена в обоих, а изменения сохранятся в базу только в первом варианте.
   _DAle_
 
410 - 25.10.19 - 14:38
(408) Эмм, "ок" - это сохранить и закрыть, "закрыть" - это просто закрыть.
   Злопчинский
 
411 - 25.10.19 - 14:41
(410) список документов поступления. что "сохранить"..?
сохранить - это как бы применяется к содержательным данным.
в форме списка документов - что сохранить?
   НиколаевГ
 
412 - 25.10.19 - 14:42
(409) А... зачем так может быть нужно?
   _DAle_
 
413 - 25.10.19 - 14:44
(411) Изменения в текущей сессии изменений.
   Злопчинский
 
414 - 25.10.19 - 15:04
Как наложить блокировку на чтение данных для всех пользователей по определенным таблицам БД (регистры остатков) по определенной номенклатуре на период пока какойто пользователь инициировава интерактивно действие не пройдет всю цепочку вычислений "чтение данных(здесь блокируем, если уже заблокировано - отлуп)-на основании прочитанных данных перехрендрячиваем кучу инфы из базы, в т.ч. чтение доп.данных(их тоже никто не может читать кроме меня)- пишем кучу инфы в базу - отпускаем блокировку (могут такой же процесс делать ктото другой).
?
   _DAle_
 
415 - 25.10.19 - 15:06
(412) Хороший вопрос, сам его пару раз задавал. Я на lsfusion не пишу, а те, кто пишут, говорят, что для них такой явный APPLY лучше. Насколько я понимаю, один из основных аргументов в том, что далеко не всегда мы хотим применить изменения, которые сделали. Например, есть необходимость в конце выполнения некоторого действия спросить пользователя, нужно ли сохранять измененное или нет. В такой ситуации нужен дополнительно некий способ закрыть сессию уже без сохранения изменений. Говорят, что такие случаи в реальном коде довольно распространены, поэтому они за явный APPLY.
   Ещё1
 
416 - 25.10.19 - 15:50
(409) Т.е. во 2-м случае (без APPLY) несохранённое изменение свойства как бы передастся в вышестоящую сессию, открытую при открытии формы редактирования заказа. Правильно?
   НиколаевГ
 
417 - 25.10.19 - 15:53
(415) Примерчик бы... Как-то странно всё это.
   Ещё1
 
418 - 25.10.19 - 15:59
(416) Если убрать APPLY, новое значение свойства вообще не сохраняется. Получается, выходит из сессии без сохранения...
   НиколаевГ
 
419 - 25.10.19 - 16:01
(418) Вот я и говорю, странно это как-то, хочется понять логику.
   Ещё1
 
420 - 25.10.19 - 16:10
(419) Тут логика в том, что все действия пользователя с объектами как бы накапливаются в текущей сессии, не переносятся в базу сразу. И применяются к основной базе только по нажатию OK, или программно при вызове APPLY. А также пользователь может отказаться ("Закрыть"), либо программно CANCEL. Там есть ещё нюансы и разные параметры этих команд, я пока не разбирался детально.

При применении изменений платформа проверит все установленные ограничения (CONSTRAINTS), и если где-то что-то пользователь накосячил или удалил лишнее - не даст ему испортить базу, позволит исправить, либо отказаться от сохранения.
   НиколаевГ
 
421 - 25.10.19 - 16:12
(420) Так ограничения же только после APPLY сработают, или как?
   Ещё1
 
422 - 25.10.19 - 16:17
(421) Верно, во время APPLY (применения изменений). Если сработают ограничения - APPLY не состоится. Я в (407) во 2-м примере создал новую сессию, что-то там изменил, и закрыл. А надо было сохранить изменения (APPLY).
   Bro
 
423 - 25.10.19 - 16:18
(421) все события (в частности и ограничения) именно при apply и срабатывают, в этом смысл apply. И newsession не делает apply потому что это строго говоря перпендикулярные понятия. Newsession создаёт новую сессию, apply применяет изменения в текущей.
   НиколаевГ
 
424 - 25.10.19 - 16:22
(423) Не понял, APPLY в новой сессии применит изменения в родительской сессии? Когда нажимаем ОК на форме, что происходит?
   _DAle_
 
425 - 25.10.19 - 16:56
(424) APPLY применит изменения текущей сессии.

>Newsession создаёт новую сессию, apply применяет изменения в текущей.

Здесь два независимых утверждения:
NEWSESSION создает новую сессию
APPLY применяет изменения в текущей
   Bro
 
426 - 25.10.19 - 17:02
(424) применяются изменения в текущей сессии.
   Ещё1
 
427 - 25.10.19 - 17:35
А скажите есть ли в платформе диалог выбора папки на сервере? Хочу для админа приложения сделать выбор папки для обмена с 1С. Не то чтобы это обязательно, но может такая функция уже реализована?
   НиколаевГ
 
428 - 25.10.19 - 18:19
(425) Тогда непонятен смысл NEWSESSION без APPLY. И что, всё-таки, происходит при нажатии кнопки ОК? Новая сессия открывается или изменения в текущей применяются?
   _DAle_
 
429 - 25.10.19 - 18:47
(428) >Тогда непонятен смысл NEWSESSION без APPLY

Я выше писал: не всегда нужно применять изменения, которые произошли в сессии. Например, пользователь не захотел этого делать.

>И что, всё-таки, происходит при нажатии кнопки ОК

Сохраняются изменения текущей сессии, форма закрывается.
   НиколаевГ
 
430 - 25.10.19 - 19:11
(429) То есть, то, что Ещё1 делает в (407) так делать не надо?
 
 Рекламное место пустует
   Ещё1
 
431 - 25.10.19 - 19:26
(430) Да, 2-й вариант обычно* не имеет смысла. Если начата сессия, её нужно закончить либо APPLY, либо CANCEL.

*Если в течении сессии какие-то файлы на диск записывались, или удалялись, или информация отсылалась куда-то, то естественно это назад не вернёшь. APPLY и CANCEL действует только на БД приложения.
   НиколаевГ
 
432 - 25.10.19 - 20:11
(431) А зачем вообще новую сессию открывать было в этом примере?
   Ещё1
 
433 - 25.10.19 - 20:25
(432) Новая сессия гарантирует что все изменения, которые будут в ней произведены с БД, будут либо записаны целым блоком, либо отменены целым блоком. А без сессии может получиться так, что часть свойств были изменены, потом произошла какая-то ошибка и дальше выполнение не пошло.

Короче, ещё 1 контроль целостности базы.
   Ещё1
 
434 - 25.10.19 - 20:30
Если на примере:
NEWSESSION {
  fileSaved() <- TRUE;
  //... тут пишем файл на диск
}
Если Exception случится в момент записи файла на диск, то флажок fileSaved() к этому моменту будет уже установлен, что нарушит логику программы.
(И не говорите мне, что устанавливать флажок надо в конце блока, это просто иллюстрация.)
   НиколаевГ
 
435 - 25.10.19 - 20:36
(433) Типа аналог НачатьТранзакцию в 1С? Оригинально...
   Ещё1
 
436 - 25.10.19 - 20:48
(435) Получается да, но тут гораздо продвинутее. Можно например создавать вложенные сессии, тогда локальные свойства материнской сессии будут видны у потомка.

Кстати, в примерах у них нашёл создание сессии с временным объектом, которая не заканчивается ни APPLY, ни CANCEL:

NEWSESSION {
    NEW s = Sku {
            id(s) <- 1234;
            name(s) <- 'New Sku';
            SHOW sku OBJECTS s = s;
    }
}
   НиколаевГ
 
437 - 25.10.19 - 20:57
(436) Что-то слишком заумно. Провоцирует писать совершенно неочевидный и несопровождаемый код.
   Ещё1
 
438 - 25.10.19 - 21:09
(437) Как посмотреть. Я сейчас пробую писать свою приблуду, но не использую и половины возможностей языка. С другой стороны, приятно сознавать, что там есть такие мощные вещи.
   Злопчинский
 
439 - 25.10.19 - 21:10
(438) Покажи потом что написал...
   Злопчинский
 
440 - 25.10.19 - 21:11
Про сессии - нихрена не понял.
открывается например визуальная форма для редактирования документа. Нахера там ньюсессион открывать? система сама не может это проинтуичить?
   НиколаевГ
 
441 - 25.10.19 - 21:14
(438) Ну, я не уверен, что эти вещи именно так стоит реализовывать. Не хватает, конечно, стандартов разработки и внятной и непротиворечивой документации.
   НиколаевГ
 
442 - 25.10.19 - 21:16
(440) Я то-же не понимаю, поэтому есть сомнения, что именно так и надо делать. Подождем настоящих сварщиков :))
   Ещё1
 
443 - 25.10.19 - 21:31
(439) Можно. Но пока и половины не сделал. Планирую что-то вроде (очень упрощённой) системы заказов для разъездных продавцов и авторизованных клиентов. С импортом-экспортом в 1С УТ.
(440) Не надо. При открытии окна сессия автоматом создаётся. Новую сессию можно например для своих обработок по нажатию кнопки. Чтобы в случае чего не испортить то, что пользователь навводил в форме.
   Bro
 
444 - 26.10.19 - 05:30
(428) там в другом дело, вы если show формы например сделаете эта форма схватит сессию в новом потоке и будет там с ней работать. А newsession завершится. С сессиями же по сути сборка мусора работает, ссылок не осталось сессия закрывается.
   Bro
 
445 - 26.10.19 - 05:38
(435) (433) нет это не начатьтранзакцию, сессия это место куда записываются изменения свойств и добавление удаление объектов (пока они не сохранились в базу). За транзакцию отвечает apply. Хотя apply применяет именно накопленные в сессии изменения (так что связь есть)
   Bro
 
446 - 26.10.19 - 05:40
(441) как раз документация (та что парадигма) писалась достаточно сухим языком и ее цель была полнота, структурированность и непротиворечивость. Так что если где то нашли противоречие сразу пишите.
   Михаил Иванович
 
447 - 26.10.19 - 07:27
Так смешно смотреть, как фузиновцы сами с собой разговаривают. )))
   НиколаевГ
 
448 - 26.10.19 - 08:26
(445) А как тогда явно "обернуть" часть кода в транзакцию?
   CrushBy
 
449 - 26.10.19 - 08:37
(448) Покажу на примере.
Можно написать двумя способами :
NEWSESSION {
f(a) <- g(a);
APPLY;
}
и второй способ (именно обернуть код в транзакцию) :
APPLY {
f(a) <- g(a);
}

В первом случае f(a) <- g(a) ничего в базу писать не будет, а запишет изменения во временную таблицу. При APPLY пойдет UPDATE в базу исходя из данных временной таблицы.

Во втором случае, начнется транзакция, а затем сразу пойдет UPDATE f ...

NEWSESSION нужен в основном для взаимодействия с пользователем (вы же не можете начать транзакцию и дать пользователю что-то выбрать - это убийство базы).

На самом деле, открытие любой формы из меню равносильно :
NEWSESSION {
    SHOW form DOCKED;
}
Внутри любой формы есть кнопки Сохранить и ОК (сохранить и закрыть). Они по сути и сделают APPLY, если пользователь это нажмет.
   НиколаевГ
 
450 - 26.10.19 - 09:41
(449) И в каких случаях какой способ применять?
   CrushBy
 
451 - 26.10.19 - 10:09
(450) Если нужно с пользователем в действии взаимодействовать, то первый. Иначе второй.
   CrushBy
 
452 - 26.10.19 - 10:11
(451) Плюс первый предпочтительнее, если не хотите растягивать транзакцию, когда в действии есть сложные вычисления, которые можно сделать вне транзакции.
   Bro
 
453 - 26.10.19 - 11:09
Про сессии этот раздел:
https://habr.com/ru/company/lsfusion/blog/458376/#session

Тут все зависит на самом деле хотите чтобы верхняя и открываемая форма вместе свои изменения применяли (отменяли) или по отдельности.
   Ещё1
 
454 - 26.10.19 - 12:42
А, ну да, в Фузине транзакция кратковременная, происходит внутри блока в команде APPLY. Чтобы базу не блокировать надолго. Иначе не работало бы одновременное редактирование одного документа разными пользователями. Хотя стоило бы всё же предупреждать пользователя при открытии документа, что его уже редактирует Марьванна с бухгалтерии.
   Bro
 
455 - 26.10.19 - 13:04
(454) Вообще я писал, что лучше не так. Лучше как в гуглдокс, показывать, какие пользователи редактируют, рамочкой показывать, где сейчас фокус у этих пользователей и что недавно изменилось. Но это уже лучшее враг хорошего. Принципиальный момент, что платформа принципиально устойчива к одновременному редактированию.
   НиколаевГ
 
456 - 26.10.19 - 14:04
(455) И в 1С моно сделать так-же, если что.
   Bro
 
457 - 26.10.19 - 15:45
(456) Понятно что и на ассемблере можно так же сделать. Вопрос в том, что в lsFusion для этого делать ничего не надо, там одновременное редактирование "в крови" (по умолчанию).
   Bro
 
458 - 26.10.19 - 15:47
(454) Транзакция в принципе должна быть короткой. По сотне причин. Строго говоря если в транзакции есть любой интерактив или ожидание чего либо еще это уже неправильно.
   Ещё1
 
459 - 26.10.19 - 22:13
Вопрос по настройке планировщика программно. При запуске сервера приложений выполняется такой код (упрощённо):

onStarted() + {
  NEWSESSION {
        NEW task = UserScheduledTask {
          name(task) <- 'Импорт из 1С';
          //...
          NEW td = UserScheduledTaskDetail {
            active(td) <- TRUE;
            //...
            order(td) <- 1;
            NEW action = Action {
              caption(action) <- 'importFiles';
              canonicalName(action) <- 'import.importFiles[]';
              action(td) <- action;
            }
            scheduledTask(td) <- task;
          }
      APPLY;
    }
}

Я вижу, что код точно выполняется, ошибок никаких не выдаёт. Однако задание в планировщике не появляется. В чём здесь проблема?
   Bro
 
460 - 26.10.19 - 22:27
(459)
Странно выполняю в lsfusion.org/try у меня появляется задание:

REQUIRE Scheduler;

showHelloWorld 'Показать сообщение' () {
    MESSAGE 'Hello world!';
}

FORM formHelloWorld 'Форма'
    PROPERTIES 'Сообщение' = 'Hello world!';
;

NAVIGATOR {
    NEW showHelloWorld;
    NEW formHelloWorld;
}

onStarted() + {
   NEW d=UserScheduledTask {
       name(d) <- 'Импорт из 1С';
   }
}

И с NEWSESSION APPLY тоже.

А попробуйте просто в интерпретаторе показать форму
OBJECTS d=UserScheduledTask
PROPERTIES (d) VALUE,name
посмотреть создались или нет. То есть без фильтров и всего остального.
   Ещё1
 
461 - 26.10.19 - 22:59
Вы по-другому всё-таки делаете.
Если я отключаю создание NEW action то задание нормально создаётся, и в нём появляется 1 строка задания, но с пустым действием. И это понятно, т.к. action я не заполняю.
Я уже пробовал так:
action(td) <- actionCanonicalName('import.importFiles[]');
и так:
action(td) <- propertyCanonicalName('import.importFiles[]');
и даже так:
action(td) <- GROUP AGGR ActionOrProperty a WHERE a IS ActionOrProperty BY canonicalName(a);
Последнее не скомпилировалось.

Когда вручную выбираю это действие из списка, то в столбце "Класс действия" появляется ListAction. Но я не смог найти этот класс в LSF-файлах платформы, чтобы создавать экземпляр именно этого класса.
   Ещё1
 
462 - 26.10.19 - 23:08
В метаданных - Действие нужное мне действие есть в группе root - private:
https://paste.pics/a5adf06571625ca30c289eb7bfec901e
Но как его выцепить?
   Ещё1
 
463 - 27.10.19 - 01:44
OK добавил задание в планировщик пока вручную. Вроде всё прописалось, сохранилось. Планировщик запущен. Но задание не запускается. На закладке "Лог" - пустой. Вручную кнопкой с навигатора задание запускается и отрабатывает. Непонятно...
https://paste.pics/761e772096273f4cad5b97b6a878f672
   Ещё1
 
464 - 27.10.19 - 01:47
Нажимаю "Выполнить задание" в строке задания справа - всё срабатывает отлично.
   Злопчинский
 
465 - 27.10.19 - 02:56
(449) так как в итоге блокировку поставить для других пользователей как в (414) описано - по второму варианту из (449)?
   Злопчинский
 
466 - 27.10.19 - 02:57
а главное меню - верхняя часть - поддается настройке в пользовательском режиме (показать толькт значки, только тест, текст-значки)..? или зашито жестко ? или опять надо "написать одну строку?"
 
 Рекламное место пустует
   Bro
 
467 - 27.10.19 - 08:32
(462) У вас Import с маленькой буквы. Язык case sensitive, canonical name'ы тоже. По идее это правильно:

action(td) <- actionCanonicalName('Import.importFiles[]');

С NEW правда непонятно почему не сработало, я проверю чуть позже
   Bro
 
468 - 27.10.19 - 08:34
(463) А попробуйте Выполнять при старте, или дату начала проставить. Если это поможет то конечно криво, пофиксим.
   Bro
 
469 - 27.10.19 - 08:37
(465) В модуле Authentication есть уже готовые действия lock, unlock (можете кстати глянуть как они реализованы, если что можно просто их скопировать и сделать более хитрую логику)

lock(object);
TRY {
    IF lockResult() THEN {
       ...
    } ELSE
      MESSAGE 'Locked by user : ' + locked(object);
} FINALLY {
   unlock(object);
}
   Bro
 
470 - 27.10.19 - 08:47
(466) Смотрите есть вещи которые делает разработчик, есть которые пользователь. Общая идеология - пользователь делает совсем базовые вещи, связанные в основном с особенностями его компьютера (иногда бизнес-процесса, но все равно базовые). То есть акцент на бизнес-приложения, а не "телеграмы и вконтакте". Возможно пользовательскую настройку будем расширять, но не хочется дублировать механизмы. Все же возможности пользователя ограничены его желанием / способностями, а размазывать логику приложения - это создавать проблемы с поддержкой и доработкой. Пока основной фокус lsFusion это не массовые коробки (где можно все решить деньгами), а нишевые коробки и проекты с высокой степенью кастомизации.
   Bro
 
471 - 27.10.19 - 10:08
(461) GROUP AGGR не сработал потому как он неявно создает ограничение, и просто где попало его использовать нельзя, только при объявлении свойства вроде как, так же как и DATA. В таких случаях обычно GROUP MAX, или GROUP NAGGR (без создания ограничения, но что запись одна на совести разработчика)
   Ещё1
 
472 - 27.10.19 - 11:59
(467) Точно, не доглядел. Поменял букву, теперь нормально записывается простой командой:
action(td) <- actionCanonicalName('Import.importFiles[]');
(468) Да, установка запуска при старте помогла.
(471) Я потом был переписал эту строку так:
action(td) <- [GROUP AGGR Action a WHERE a IS Action BY canonicalName(a)]('import.importFiles[]');
Но естественно она тоже не работала, потому что 'import' с маленькой буквы.

OK на данный момент настройка шедулера в приложении работает как планировалось.
   Ещё1
 
473 - 27.10.19 - 12:03
Можно ли настроить уровень логирования в планировщике, напр. только ошибки?
Или полностью отключить лог, когда всё отлажено и работает.
   Bro
 
474 - 27.10.19 - 12:17
(473) EXTEND FORM scheduler FILTERS error(o), ну или точно не помню что просто наведите на колонке там в tooltip показывается свойство. Ну или FILTERGROUP можете добавить с DEFAULT, чтобы по умолчанию включены только ошибки, в при выключении все.

А что значит полностью отключить лог? Ну пишется и пишется, или что вы имеете ввиду?
   Ещё1
 
475 - 27.10.19 - 12:20
(474) Фильтр там уже реализован, под логом птичка "Ошибки или сообщения". Я думал, вообще можно отключить логирование, если оно не нужно. Но на закладке "Настройки планировщика" есть только "Количество потоков".
   Bro
 
476 - 27.10.19 - 12:29
(475) Туда все сообщения из задания пишутся, но непонятно зачем его вообще отключать
   Ещё1
 
477 - 27.10.19 - 13:27
В форме заказа, хочу сделать чтобы при добавлении новой строки OrderDetail по кнопке ( PROPERTIES(od) NEW ) или по клавише Insert, сразу же появлялось окошко выбора номенклатуры ( FORM skusForm ) для этой строки. Возможно ли?

Сейчас при нажатии Insert внизу в списке появляется новая пустая строка, надо щёлкнуть по ячейке Код товара или Товар, чтобы открылся список номенклатуры для подбора.
   Ещё1
 
478 - 27.10.19 - 13:38
Можно ли открыть форму заказа в режиме "Только чтение" при указанных условиях (напр., статус заказа - отправлен). Я могу это сделать, добавив на все свойства READONLYIF, а на конпки NEW и DELETE - условие SHOWIF. Но может есть простой способ, который сразу накладывает на все свойства объекта условие READONLY.
   Bro
 
479 - 27.10.19 - 13:47
(477) Action сделайте и повесьте на форму (но да CHANGEKEY и картинку придется прописать)
addDetail(Order o) {
   DIALOG LIST Sku INPUT s DO NEW od = OrderDetail {
        sku(od) <- s;
        order(od) <- o;
   }
}
// или (s-имя объекта на skusForm)
//   DIALOG skusForm OBJECTS s INPUT DO...
   Bro
 
480 - 27.10.19 - 13:48
(478) При SHOW / DIALOG есть опция READONLY, можно при показе проверить и показать либо с этой опцией либо без. Ну а так да, READONLYIF
   Михаил Иванович
 
481 - 27.10.19 - 14:05
разговоры сами с собой ведете?
(479) врешь!
   Михаил Иванович
 
482 - 27.10.19 - 14:05
(480) Опять врешь!
   Ещё1
 
483 - 27.10.19 - 14:31
(480) Это работает, но требуется небольшая доработка. При открытии формы в режиме READONLY надо дополнительно убирать кнопки NEW, DELETE.
   Bro
 
484 - 27.10.19 - 14:37
(483) А они разве не убираются? Может там они в NEWSESSION?
   Ещё1
 
485 - 27.10.19 - 14:47
(484) Нет, не убираются, и не NEWSESSION. Сейчас я добавил вручную SHOWIF, чтобы убирать кнопки когда не нужны:
  PROPERTIES(od) SHOWIF NOT readOnly(o) NEW, DELETE
   Bro
 
486 - 27.10.19 - 14:54
(485) не, в понедельник глянем пофиксим. но очень странно так как на тот же механизм политика безопасности read only завязана, и если бы появились эти кнопки нам бы давно сказали.
   Ещё1
 
487 - 27.10.19 - 14:56
(479) Не хотелось бы лезть в макет формы, чтобы поднастроить поведение стандартных действий. А что если как-то так сделать:

WHEN LOCAL SET(OrderDetail od) AND NOT sku(od) DO {
  DIALOG LIST SKU INPUT s DO {
    sku(od) <- s;
  }
}

Но в этом коде что-то не то с синтаксисом, пишет "Data:158:32 single parameter could not be a parameter of a session operator"
   Ещё1
 
488 - 27.10.19 - 15:07
(487) Переделал так, компилируется:

WHEN LOCAL SET(od IS OrderDetail) AND NOT sku(od) DO {  
  DIALOG LIST SKU INPUT s DO {
    sku(od) <- s;
  }
}

Но окно выбора не появляется, и на сервере вызывает StackOverflowError.
   Bro
 
489 - 27.10.19 - 15:15
(488) вообще локальные события предметной области асинхронные, и в них интерактивные блокирующие вызовы мы никогда не вызывали. Хотя теоретически не вижу почему они не должны работать, а можете стэк в слэк скинуть?
   Ещё1
 
490 - 27.10.19 - 15:22
(489) Я попробовал пошагово оттрассировать обработку этого события. Тут получается зацикливание, т.е. последовательно исполняется DIALOG LIST SKU, затем вызывается WHEN LOCAL SET, потом снова DIALOG LIST SKU и т.д.
Может как-то нужно подправить условие в WHEN, чтобы избежать этого?
   Bro
 
491 - 27.10.19 - 15:27
(490) Ну в общем да логично, она при открытии формы в той же сессии опять вызывает обработку локальных событий. Можно теоретически NEWSESSION сделать, но тогда придется sku через NESTED возвращать (так как в новой сессии не будет виден sku, можно конечно еще NESTEDSESSION попробовать, но это уже совсем жестко):
selectedSku = DATA LOCAL NESTED Sku ();
WHEN LOCAL SET(od IS OrderDetail) AND NOT sku(od) DO {  
  NEWSESSION
     DIALOG LIST SKU INPUT s DO
        selectedSku() <- s;

  sku(od) <- s;
}

Ну и не уверен, что это заработает. Хотя если нет, то интересно почему.

Но я бы все же вернулся к более кошерному варианту с явным действием Action.
   Bro
 
492 - 27.10.19 - 15:27
(491) * не видно свойство sku в смысле и даже новая строка не будет видна.
   Ещё1
 
493 - 27.10.19 - 15:35
Я решил эту проблему через добавление локального флажка, отслеживающего повторный заход в событие.

inDialog = DATA LOCAL BOOLEAN ();

WHEN LOCAL SET(od IS OrderDetail) AND NOT sku(od) AND NOT inDialog() DO {
  inDialog() <- TRUE;  
  DIALOG LIST SKU INPUT s DO {
    sku(od) <- s;
  }
  inDialog() <- NULL;
}

Костыльно, но работает.
   Bro
 
494 - 27.10.19 - 15:46
(493) Ниразу так не делали. Хотя с другой стороны, ситуации когда диалог вызывается в асинхронных операциях в платформе бывают, так что не вижу почему не должно работать. Тут бы конечно "связь" бы затормозить и потыкать на добавить очень быстро.

А с NEWSESSION заработает?
   Ещё1
 
495 - 27.10.19 - 16:13
(494) С новой сессией получилось так:

WHEN LOCAL SET(od IS OrderDetail) AND NOT sku(od) DO {
  LOCAL newSKU = SKU();
  NEWSESSION NESTED LOCAL {
    DIALOG LIST SKU INPUT s DO {
      newSKU() <- s;
    }
  }
  sku(od) <- newSKU();
}

Выглядит уже покрасивше. Пришлось использовать LOCAL newSKU для промежуточного хранения, потому что если сразу писать в sku(od) <- s; то присвоенное значение не сохраняется.
   Bro
 
496 - 27.10.19 - 18:48
(495) да я это и писал выше. Что надо через NESTED LOCAL делать.

Кстати в таких случаях в самом LOCAL лучше указывать NESTED. Он тогда автоматически передастся в NEWSESSION. Ну или в nested указать конкретно к свойство.

В любом случае мы так никогда не делали, даже интересно какие подводные камни при этом могут быть.
   Ещё1
 
497 - 27.10.19 - 19:03
(496) OK переделал на LOCAL NESTED newSKU = SKU();
Так тоже работает, минус 1 служебное слово.
OK
   CrushBy
 
498 - 27.10.19 - 20:55
(495) Есть только один момент. В том же ERP мы ни разу так не делали (в локальном событии вызов диалоговой формы). Так что точной корректности гарантировать не могу.
   Ещё1
 
499 - 28.10.19 - 23:34
(354) > VALUE(o) - описывается здесь https://documentation.lsfusion.org/pages/viewpage.action?pageId=1573071

А при обратном импорте из JSON в базу, я могу прочитать ранее записанный идентификатор объекта как число LONG, а как по нему получить сам объект известного класса (скажем Order)?
   Ещё1
 
500 - 28.10.19 - 23:46
Допустим:
impID = DATA LOCAL LONG (); // Сюда импортируется ID объекта из JSON
LOCAL order = Order (); // Сюда хочу поместить ссылку на сам объект с ID = impID()
Пробую разные варианты:
order() <- Order(impID()); // Приведение типа не работает
VALUE(order()) <- impID(); // Тоже не работает
order() <- [GROUP AGGR Order o WHERE o IS Order BY VALUE(o)](impID());
// тоже не берёт
  1  2  3  4  5  6   

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.