03.05.2012, 13:14 | #1 |
Участник
|
Обновление статуса производственного заказа программно
День добрый!
версия 2009 Есть желание создать небольшой job или даже целый класс, который проходился бы по всем заказам в ProdTable, и где статус выше "создано", но максимум "запланировано", сбрасывал его, затем сам же запускал планирование от сегодняшней даты. Как я понимаю, сбросом статуса занимается класс ProdUpdStatusDecrease, а обновлением статуса до "запланировано" класс ProdUpdScheduling. Но оба эти класса запускаются через формы и т.д. и требуют заполнения Query с нажатием кнопки ок. Вопрос, как это сделать программно? я думаю, задача не нова и кто-нибудь её уже решал. Если ошибся где-нибудь, поправьте. с уважением, Николай |
|
03.05.2012, 13:21 | #2 |
северный Будда
|
Так вы же сами и написали решение
Сэмулировать Query с формы несложно, а дальше запускаете указанные классы У меня аналогичная задача - удалённый запуск создания отгрузочной накладной - отняла совсем немного времени
__________________
С уважением, Вячеслав |
|
|
За это сообщение автора поблагодарили: RVS (1), niksen (1). |
03.05.2012, 13:24 | #3 |
Участник
|
ээээ, несложно, но что-то сколько не ищу, не могу найти, сколько не копаю...
или может быть воспользоваться prodtable.autoupdate() для обновления? но чем тогда сбрасывать? именно тем, что я написал? и вопрос, если честно, не в курсе, как сэмулировать, может быть есть другой способ? как это лучше реализовывать? через пакетное задание? |
|
03.05.2012, 13:32 | #4 |
Участник
|
Если цель перепланирования - сдвиг дат, то на сколько я понимаю статус можно не сбрасывать, а просто повторно перепланировать.
Вот нашёл у себя код: X++: ProdParmScheduling prodParmScheduling; ; prodParmScheduling.clear(); prodParmScheduling.ParmBuffer::initParmId(); prodParmScheduling.ProdId = _ProdId; // устанавливаем параметры перепланирования: // prodParmScheduling.SchedDirection = // prodParmScheduling.SchedMethod = // prodParmScheduling.SchedDate = // ... prodParmScheduling.insert(); ProdTable::find(_ProdId).status().runOperationScheduling(prodParmScheduling); На всякий случай код, сбрасывающий статус: X++: prodMultiStatusDecrease = new JmgProdMultiStatusDecrease();
parmBuffer = prodMultiStatusDecrease.defaultParmBuffer();
prodMultiStatusDecrease.initParmSFC();
prodMultiStatusDecrease.insert(prodTable,parmBuffer);
prodParmStatusDecrease = parmBuffer;
prodParmStatusDecrease.WantedStatus = ProdStatus::Created;
prodMultiStatusDecrease.run(); Последний раз редактировалось S.Kuskov; 03.05.2012 в 13:40. |
|
|
За это сообщение автора поблагодарили: niksen (1). |
03.05.2012, 13:33 | #5 |
северный Будда
|
Эм... давно я производством не занимался, конечно... но разве нельзя эту задачу решить инструментами сводного? вы же, по сути, пытаетесь делать динамическое перепланирование
__________________
С уважением, Вячеслав |
|
03.05.2012, 13:38 | #6 |
Участник
|
Сводное максимум что нагенерит фьючерсов и действий. Уже утверждённые ПЗ оно не изменит.
Последний раз редактировалось S.Kuskov; 03.05.2012 в 13:47. |
|
|
За это сообщение автора поблагодарили: pitersky (1). |
03.05.2012, 16:41 | #7 |
Участник
|
вот именно в этом всё и дело, в этом и состоит задача
т.к. удалять просто так производственные заказы никто не будет, они могут висеть запланированные, пока их никто не начал. А их нужно периодически перепланировать с учётом того, что сегодня уже другая дата. Перепланирование большого количества производственных заказов с утра перед началом работы может затянуть начало рабочего дня ближе к обеду а так вот ночью запускать это как пакетное задание и таким образом к началу рабочего дня уже всё есть |
|
04.05.2012, 10:33 | #8 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Если цель перепланирования - сдвиг дат, то на сколько я понимаю статус можно не сбрасывать, а просто повторно перепланировать.
Вот нашёл у себя код: X++: ProdParmScheduling prodParmScheduling; ; prodParmScheduling.clear(); prodParmScheduling.ParmBuffer::initParmId(); prodParmScheduling.ProdId = _ProdId; // устанавливаем параметры перепланирования: // prodParmScheduling.SchedDirection = // prodParmScheduling.SchedMethod = // prodParmScheduling.SchedDate = // ... prodParmScheduling.insert(); ProdTable::find(_ProdId).status().runOperationScheduling(prodParmScheduling); На всякий случай код, сбрасывающий статус: X++: prodMultiStatusDecrease = new JmgProdMultiStatusDecrease();
parmBuffer = prodMultiStatusDecrease.defaultParmBuffer();
prodMultiStatusDecrease.initParmSFC();
prodMultiStatusDecrease.insert(prodTable,parmBuffer);
prodParmStatusDecrease = parmBuffer;
prodParmStatusDecrease.WantedStatus = ProdStatus::Created;
prodMultiStatusDecrease.run(); |
|
04.05.2012, 10:37 | #9 |
Участник
|
|
|
04.05.2012, 11:56 | #10 |
Участник
|
вот такой код у меня получился. Гуру, подскажите другой вариант остановки цикла
смысл в том, что есть заказы, которые зависят друг от друга, поэтому вот именно таким образом поступил. Может быть есть ещё что-нибудь? У меня почему-то при первом прогоне статус становится "оценено", хотя требуемый "создано". X++: static void Job4(Args _args) { JmgProdMultiStatusDecrease _prodMultiStatusDecrease = new JmgProdMultiStatusDecrease(); ProdParmStatusDecrease parmBuffer, prodParmStatusDecrease; ProdTable ProdTable; prodId prodId; ; do { while select prodTable where (ProdTable.ProdStatus != ProdStatus::Created) { parmBuffer = null; _prodMultiStatusDecrease.reset(); prodParmStatusDecrease = null; parmBuffer = _prodMultiStatusDecrease.defaultParmBuffer(); _prodMultiStatusDecrease.initParmSFC(); _prodMultiStatusDecrease.insert(prodTable,parmBuffer); prodParmStatusDecrease = parmBuffer; prodParmStatusDecrease.WantedStatus = ProdStatus::Created; _prodMultiStatusDecrease.run(); } prodId = '1'; select firstonly prodTable where (ProdTable.ProdStatus != ProdStatus::Created); { prodId = prodTable.ProdId; } } while (prodId!=''); } |
|
04.05.2012, 12:02 | #11 |
Программатор
|
учите бест практис, без него никуда. Зачем do while? Еще, наверно, транзакцию влепить лучше.
Последний раз редактировалось Sada; 04.05.2012 в 12:14. |
|
05.05.2012, 08:03 | #12 |
Участник
|
do-while затем, что некоторые заказы не сбрасываются до желаемого статуса, а while select проходит по таблице prodTable только 1 раз и может выйти ситуация, когда остаются заказы с другими статусами. А как обойти это без ещё одного select с выборкой только по несброшенным - я пока не додумался.
Транзакцию конечно же влепить нужно это без вопросов и try-catch тоже |
|
05.05.2012, 10:52 | #13 |
Программатор
|
|
|
05.05.2012, 10:54 | #14 |
Участник
|
вот что получилось для перепланирования. Может кому понадобится.
Критикуйте X++: static void ProdStatusSched(Args _args) { ProdParmScheduling prodParmScheduling; ProdTable prodTable; ; ttsbegin; while select ProdTable where ProdTable.ProdStatus != ProdStatus::Scheduled { prodParmScheduling.clear(); prodParmScheduling.ParmBuffer::initParmId(); prodParmScheduling.ProdId = ProdTable.ProdId; // устанавливаем параметры перепланирования: prodParmScheduling.SchedDirection = ProdSchedDirection::ForwardFromToday; prodParmScheduling.SchedMethod = ProdSchedMethod::OperationScheduling; prodParmScheduling.SchedDate = str2date('24/05/2012',123); prodParmScheduling.SchedTime = str2time('15:55'); prodParmScheduling.CapLimited = NoYes::Yes; prodParmScheduling.MatLimited = NoYes::Yes; prodParmScheduling.SyncRef = NoYes::Yes; prodParmScheduling.SchedRef = NoYes::Yes; prodParmScheduling.CancelProcessTime = NoYes::No; prodParmScheduling.CancelSetupTime = NoYes::No; prodParmScheduling.CancelQueueTime = NoYes::No; prodParmScheduling.CancelTransportTime = NoYes::No; prodParmScheduling.CancelOverlap = NoYes::No; prodParmScheduling.JobStatus = ParmJobStatus::Executed; prodParmScheduling.AutoUpdate = NoYes::Yes; prodParmScheduling.insert(); ProdTable::find(ProdTable.ProdId).status().runJobScheduling(prodParmScheduling); } ttscommit; } |
|
05.05.2012, 10:58 | #15 |
Участник
|
|
|
05.05.2012, 11:05 | #16 |
Программатор
|
X++: static void ProdStatusSched(Args _args) { ProdParmScheduling prodParmScheduling; ProdTable prodTable; ; ttsbegin; while select prodTable where prodTable.ProdStatus != ProdStatus::Scheduled { prodParmScheduling.clear(); prodParmScheduling.ParmBuffer::initParmId(); prodParmScheduling.ProdId = ProdTable.ProdId; prodParmScheduling.SchedDirection = ProdSchedDirection::ForwardFromToday; prodParmScheduling.SchedMethod = ProdSchedMethod::OperationScheduling; prodParmScheduling.SchedDate = str2date('24/05/2012',123); prodParmScheduling.SchedTime = str2time('15:55'); prodParmScheduling.CapLimited = NoYes::Yes; prodParmScheduling.MatLimited = NoYes::Yes; prodParmScheduling.SyncRef = NoYes::Yes; prodParmScheduling.SchedRef = NoYes::Yes; prodParmScheduling.JobStatus = ParmJobStatus::Executed; prodParmScheduling.AutoUpdate = NoYes::Yes; prodParmScheduling.insert(); prodTable.status().runJobScheduling(prodParmScheduling); } ttscommit; } |
|
|
За это сообщение автора поблагодарили: niksen (1). |
10.05.2012, 15:54 | #17 |
Участник
|
Sada, и правда красивше и понятнее. Дело в другом, правильно ли я использую тот приём с выборкой, чтобы узнать, пустая ли она? Может его как-нибудь заменить, а то совсем уж некрасиво выглядит...
|
|
10.05.2012, 17:30 | #18 |
Программатор
|
Не понял...
|
|
10.05.2012, 17:51 | #19 |
Участник
|
X++: prodId = '1'; select firstonly prodTable where (ProdTable.ProdStatus != ProdStatus::Created); { prodId = prodTable.ProdId; } } while (prodId!=''); можно ли его как-нибудь заменить? |
|
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|