28.02.2013, 08:12 | #1 |
Участник
|
Критическая ошибка в функции LedgerBondServer_RU.addBondProrateAmountMSTSecond. (Проводки по операции ПЕР034122 не балансируют согласно 14.06.2012. (Валюта компании: 0,00 - вторичная валюта: 0,00)
Добрый день!
AX 2009 Kernel 5.0.1500.3761 Appl 5.0.1500.2985 Solution RU HRP5 5.0.1500.2116.1 При разноске журнала переноса возникает ошибка Критическая ошибка в функции LedgerBondServer_RU.addBondProrateAmountMSTSecond. (Проводки по операции ПЕР034122 не балансируют согласно 14.06.2012. (Валюта компании: 0,00 - вторичная валюта: 0,00) Изучал вопрос, просмотрел весь форум, читал/баловался настройками округления, ничего не помогает. Трейсил какое-то время, но понял немного... И нет, честно говоря времени, чтобы его тратить на детальный анализ и демоделирование классов LedgerBond... Сам код генерирующий ошибку. X++: if (! _amountMSTSecond || ! bondTransDebit.ledgerTransObject().parmAmountMSTSecondary() || ! bondTransCredit.ledgerTransObject().parmAmountMSTSecondary()) { fatalError = ! checkFailed(strfmt("@SYS19378", funcname())); return; } Пожалуйста, подскажите, где-что посмотреть. Как я понимаю, это не алгоритмическая ошибка, а наша ошибка в данных, но что сделать/посмотреть, чтобы ее исправить (кроме настроек округления в ГК)? Большое спасибо, буду очень благодарен. (Грустно и обреченно доделываю FormRunListener...) |
|
28.02.2013, 08:58 | #2 |
Программатор
|
Курить код вверх по стеку почему во вторичной валюте нули
|
|
28.02.2013, 09:49 | #3 |
Участник
|
Это и поглотило меня, не вырваться боле на волю....
|
|
28.02.2013, 10:17 | #4 |
Участник
|
Подобная ошибка возникала у нас в журналах ГК, когда профиль разноски был некорректно настроен...
|
|
28.02.2013, 11:11 | #5 |
Участник
|
Как разберётесь в чём проблема - отпишитесь, пожалуйста, интересно, в чём суть.
|
|
28.02.2013, 11:17 | #6 |
Участник
|
|
|
28.02.2013, 11:44 | #7 |
Участник
|
Профиль разноски в строке журнала ГК.
Навскидку, причин может быть много, это и курс валюты (а может, и самой валюты нет, но тогда ошибка должна быть другой), при разноске между двумя компаниями это могут быть ошибки в профилях по умолчанию (в одной профиль есть, в другой нету) и т.п. Проверяйте не саму ошибку, а строку журнала. Просто "тупо" пройтись по финансовым полям. Проводка в пределах одной компании или разных? Валюта отличается от основной? Курсы валюты проставлены? Профили указаны и настроены? |
|
|
За это сообщение автора поблагодарили: Romb (1). |
28.02.2013, 11:51 | #8 |
Участник
|
сначала надо понять, почему оно пытается сопоставить остатки именно во вторичной валюте. Если оно решило что все остальные остатки к сопоставлению нулевые, то по идее оно должно исключить из рассмотрения эту проводку ранее как полностью сопоставленную.
Какой колстек у этого места? Это корреспонденция чего и по какому алгоритму? |
|
28.02.2013, 11:52 | #9 |
Участник
|
И при чем тут FormRunListener
|
|
28.02.2013, 12:26 | #10 |
Программатор
|
Когда слышу про сопоставление и профили всегда думаю про это
CustVendSettle просмотр кода у вас в системе исправлено? |
|
28.02.2013, 18:21 | #11 |
Участник
|
Иногда такая ошибка выскакивает когда просо забыли указать код счета или коррсчета.
Еще такое бывало если умудрялись дробные суммы вводить. нов случае переноса у вас это наверно не сделать. Если только какая модификация. |
|
28.02.2013, 18:23 | #12 |
Участник
|
Можно еще вот здесь
\Classes\LedgerVoucherTransObject\newCreateTrans поставить вывод в инфолог приходящих сумма и счетов. Зачастую даёт подсказку где бага в настройках или в использовании. |
|
01.03.2013, 09:01 | #13 |
Участник
|
Добрый день, спасибо за советы.
С профилями, округлениями и др. все нормально. Вторичную валюту не используем. Перенос в основной валюте. Внутри одной компании. В данных проблемных строк в журнале переноса и в InventTrans ничего подозрительного не увидел. Разве, что журнал сторно. Дошел до следующего. Дошел до ошибки в коде в методе LedgerBondClient_RU.bondVRef2VRef() Для всех "нормальных" строк он отрабатывает по одной ветке, для "ненормальных" (на которых ошибка возникает) по другой. Вот код. X++: public void bondVRef2VRef(LedgerBondVrefId_RU _vRefId1, LedgerBondVrefId_RU _vRefId2, Amount _amount = 0.0, LedgerBondAmountType_RU _amountType = LedgerBondAmountType_RU::Currency, LedgerBondOrder_RU _bondOrder = LedgerBondOrder_RU::Auto, boolean _roundToCredit = false) { LedgerBondVrefId_RU vRefIdDebit; LedgerBondVrefId_RU vRefIdCredit; LedgerBondTransObject_RU bondTransObject2, bondTransObject1 = this.bondTransObject(_vRefId1); Amount amount1 = _amount, amount2; LedgerBondAmountType_RU amountType = _amountType; ; if (ledgerBondServer.fatalErrorState()) return; if (! amount1) { // здесь все отрабатывает для "нормальных" строк // без ошибок, т.е. amount2 и amount1 получают // ненулевые значения amount1 = bondTransObject1.remainAmountCur(); bondTransObject2 = this.bondTransObject(_vRefId2); if (ledgerBondServer.fatalErrorState()) return; // для нормальных строк в bondTransObject2.remainAmountCur() есть значение // для "ненормальных" возращается 0 amount2 = bondTransObject2.remainAmountCur(); if (! amount1 || ! amount2) { amount1 = bondTransObject1.remainAmountMST(); amount2 = bondTransObject2.remainAmountMST(); amountType = LedgerBondAmountType_RU::MST; } if (! amount1 || ! amount2) { // в случае, когда amount2 == 0 алгоритм приземляется здесь amount1 = bondTransObject1.remainAmountMSTSecond(); amount2 = bondTransObject2.remainAmountMSTSecond(); amountType = LedgerBondAmountType_RU::MSTSecondary; } amount1 = min(abs(amount1), abs(amount2)); } ......... ......... // ну и далее при amount1 == 0, возникает ошибка в во второй ветке LedgerBondAmountType_RU::MSTSecondary // ledgerBondServer.addBondProrateAmountMSTSecond() // т.к. как там внутри соответствующая проверка // в нормальном же случае все идет по последней ветке // amount1 ненулевой, ошибки внутрях не возникает switch (amountType) { case LedgerBondAmountType_RU::MST : ledgerBondServer.addBondProrateAmountMST(vRefIdDebit, vRefIdCredit, amount1, _roundToCredit); break; case LedgerBondAmountType_RU::MSTSecondary : ledgerBondServer.addBondProrateAmountMSTSecond(vRefIdDebit, vRefIdCredit, amount1, _roundToCredit); break; case LedgerBondAmountType_RU::Currency : ledgerBondServer.addBondProrateAmountCur(vRefIdDebit, vRefIdCredit, amount1, _roundToCredit); break; } Последний раз редактировалось Romb; 01.03.2013 в 09:17. |
|
01.03.2013, 09:07 | #14 |
Участник
|
Теперь осталось посмотреть, как получается так, что оно полностью корреспондирует в первичной валюте, но есть остаток во вторичной
|
|
01.03.2013, 10:33 | #15 |
Участник
|
|
|
04.03.2013, 08:40 | #16 |
Участник
|
Хм...
В общем, оказалось как всегда. Пока писал текст под чертой, параллельно проблему и решил.
Суть в том, что у нас был пересчет склада, в InventTrans записалась себестоимость. Уж что, да как , да почему копейка в ней возникает - расследовать поздно. Но оперативное решение - поправить InventTrans.CostAmountAdjustment у промаркированных проводок в InventTrans на одну копейку. (которые в синем квадрате) Тогда все ошибки уходят. Большое спасибо за участие. Надо было сразу лезть в InventTrans конечно Снизу, что сначала хотел написать, но уже неактуально. ---------------------------------------------------------------------------------------------------- Вторичная валюта у нас отключена. Проблема частично "решилась", но не до конца. После безумной трассировки, решили выделить проблемные номенклатуры в другой журнал. Включил дебаг (#if.never) отловил номенклатуры, строки с ними вынесли в отдельный журнал переноса. В итоге исходный журнал без проблемных строк разнесся уже без ошибок. А второй журнал с проблемными строками разнесся, но только с ошибкой "Критическая ошибка в функции LedgerBondServer_RU.addBondProrateAmountMSTSecond.". Эту ошибку изучал, есть подозрение, что при корреспонденции "наш" метод InventTran. findBondInventTrans() отрабатывает некорректно (в случае, когда количество по складским проводкам "сопоставляется" по InventTrans.InventRefTransId не один в один, а разбивается. В нашем случае в журнале переноса в строке количество -24 , в InventTrans по InventTransId -16 и -8 (выделено на скрине снизу), а по InventRefTransId 3, 16 и 5. (выделено на скрине сверху). Вот тут то он с ума и сходит. На очередном журнале, при повторении такого разбиения, ошибка "Не балансирует" осталась. И в логе видна эта копейка. Но теперь уже легче X++: public InventTrans findBondInventTrans(InventTransId _inventTransId = this.InventTransId) { InventTrans bondInventTrans; InventDim bondInventDim; InventDim thisInventDim = this.inventDim(); container dimFields = InventDimSearch::activeFields(this.inventTable().DimGroupId); int len, i; fieldId fieldId; boolean pastFieldId(fieldId _fieldId) { return (_fieldId == fieldnum(InventDim, InventLocationId) || _fieldId == fieldnum(InventDim, wMSLocationId) || _fieldId == fieldnum(InventDim, InventProfileId_RU) || _fieldId == fieldnum(InventDim, InventRespPers) || _fieldId == fieldnum(InventDim, InventSiteId)); } void findInventTrans(StatusReceipt _StatusReceipt, StatusIssue _StatusIssue) { select firstonly bondInventTrans index hint TransIdIdx order by RecId desc where bondInventTrans.InventTransId == _inventTransId && bondInventTrans.TransType == this.TransType && bondInventTrans.StatusReceipt == _StatusReceipt && bondInventTrans.StatusIssue == _StatusIssue join bondInventDim where bondInventDim.inventDimId == bondInventTrans.inventDimId && #InventDimMacros(thisInventDim, bondInventDim); } ; len = conlen(dimFields); for (i = 1; i <= len; i++) { fieldId = conpeek(dimFields, i); if(pastFieldId(fieldId)) { thisInventDim.(fieldId) = null; } } switch (this.Direction) { case InventDirection::Issue: findInventTrans(StatusReceipt::Purchased, StatusIssue::None); break; case InventDirection::Receipt: findInventTrans(StatusReceipt::None, StatusIssue::Sold); break; } return bondInventTrans; } Последний раз редактировалось Romb; 04.03.2013 в 10:08. |
|
19.04.2013, 03:41 | #17 |
Участник
|
В данном посте ошибку решил несистемно, "как получилось".
Тут правильное решение и объяснение Странная ошибка при разноске |
|
Теги |
ledgerbondserver_ru, не балансируют |
|
|