Показать сообщение отдельно
Старый 17.10.2012, 14:24   #43  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,895 / 5650 (194) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
В завершение темы про ошибки в средней себестоимости:
Вот как работает рассчет средней себестоимость в западном приложении:
1. Для каждого закрываемого периода система создает фиктивный перенос. (Все последующие рассуждения относятся к модели "Средняя за период". В модели "Средняя на дату" система фактически разбивает месяц по датам каждого прихода и периоды между приходами трактует как отдельный период в модели "Средняя за период").
2. Система суммирует все приходы открытые на начало прихода и все приходы за период и присваивает рассчитанную себестоимость и количество в проводки фиктивного переноса.
3. Все расходы периода сопоставляются с приходной проводкой по фиктивному переносу, все приходы периода (и незакрытые приходы на начало периода) сопоставляются с расходной проводкой по переносу.
4. Система имеет специальный режим восстановления после сбоев. Если при обработке периода был найден уже существующий фиктивный перенос с нужной датой, система просто повторно использует его, не меняя суммы и количества.
5. Если закрытие склада отменяется, система удаляет все фиктивные переносы периода и все связанные с ними складские сопоставления и корректировки стоимости.

Если приглядется на код локализованного метода InventCostClosingCancel_WorkInvent.deleteVirtualTransfers() (или InventCostClosingCancel_End.deleteVirtualTransfers() - в зависимости от версии rollup), то можно найти следующий замечательный код:
X++:
   while select forupdate inventTrans order by InventTransId
        where inventTrans.ValueOpen             == InventTransOpen::Yes
           && inventTrans.ValueOpenSecCur_RU    == InventTransOpen::Yes
           && inventTrans.Voucher               == cancelClosing.Voucher
           && inventTrans.TransType             == InventTransType::SummedUp
Если у вас разрешена российская функциональность, но запрещен двухвалютный склад (а учитывая его качество - он у 95% пользователей запрещен), то условие inventTrans.ValueOpenSecCur_RU == InventTransOpen::Yes вернет false и никакие записи не будут обработаны (и, соответственно, никакие фиктивные переносы не будут удалены). Дальше - интереснее. Если вы закрыли склад, потом отменили закрытие, запостили парочку новых приходов и расходов, то следующее закрытие, наткнувшись на болтающиеся старые фиктивные переносы, с радостью примет их за результаты сбойного закрытия и попытается повторно их использовать. Правда, поскольку закрытие ничего плохого не подозревает, оно не поменяет стоимость и количество в этих переносах. А потом не проверяя, сопоставит со всеми приходами и расходами. В результате у фиктивного переноса может получиться пересопоставление - типа в qty стоит 100 штук, а в qtySettled - 120. Ну и конечно вся себестоимость едет и накрывается медным тазом...

Рекомендую поменять указанный выше код на что-нибудь типа
X++:
   while select forupdate inventTrans order by InventTransId
        where inventTrans.ValueOpen             == InventTransOpen::Yes
           && (!isconfigurationKeyEnabled( configurationkeynum(InventClosingSecCur_RU)) || inventTrans.ValueOpenSecCur_RU    == InventTransOpen::Yes)
           && inventTrans.Voucher               == cancelClosing.Voucher
           && inventTrans.TransType             == InventTransType::SummedUp
Еще очень рекомендую сначала попробовать предложенные мною и участником Bega правки на тестовой базе и потом пару месяцев попробовать позакрывать склад и посмотреть за результатами. А то один мой польский клиент сначала исправил ошибку, а потом, когда новые закрытия стали налетать на изуродованные складские проводки старых закрытий, получил не мало проблем...