Есть еще одна неприятная бага. Не связанная напрямую с печатью, но влияющая на печать (причем ошибка похоже не только в локализации).
Попробую быть краток :
1. Связь между шапкой CustInvoiceJour и строками CustInvoiceTrans идет по странному Relation, в который входят поля :
SalesId
InvoiceId
InvoiceDate
numberSequenceGroup
но нет аналога поля VendInvoiceJour.InternalInvoiceId
из-за этого возможна ситуация, когда номера накладных, даты и номера заказов совпадают, что приводит к перепутыванию строчек разных накладных.
А это в свою очередь происходит из-за того, что :
2. Поле CustInvoiceJour.invoiceID является как составной частью первичного ключа таблички, так и номером документа, выводимым на печать.
На практике это крайне неудобно, так как нередко приходится исправлять ошибки в документах через кредит-ноту.
Например, выписали накладную по заказу. Заметили ошибку, сделали по заказу сторно через немедленное получение. Исправили документ, закатываем накладную по заказу заново. Клиент требует чтобы номер не менялся.
Что делать ?
Разрешаем дубликаты CustInvoiceJour.invoiceID и получаем все вышеописанные проблемы.
т.е. надо выделить поле - первичный ключ накладной, а-ля InventJournalTable.JournalId и использовать его для связки шапки и строк, но не для печати.
3. Поле CustInvoiceJour.invoiceID является составной частью первичного ключа, но не является уникальным и может повторяться. Более того в системе штатно предусмотрен режим проверки уникальности по этому полю, предполагающий, что Аксапта может работать в режиме, когда номера накладных повторяются. А в системе есть куча мест где CustInvoiceJour.invoiceID используется так, словно он и есть первичный ключ и однозначно идентифицирует шапку накладной.
Со всеми вытекающими проблемами...
Навскидку :
4. Метод \Classes\FactureTransCreateCust_RU\createTrans
расщепляет строки по ГТД.
Для расщепления используются запросы :
X++:
select sum(Qty) from inventTrans
where inventTrans.InvoiceId == custInvoiceTrans.InvoiceId &&
inventTrans.DateFinancial == custInvoiceTrans.InvoiceDate &&
inventTrans.InventTransId == custInvoiceTrans.InventTransId
join InventGtdId_RU from inventDim
group by InventGtdId_RU
where inventDim.InventDimId == inventTrans.InventDimId;
while (qtyToAllocate && inventTrans)
{
select sum(Qty) from factureTransSum
where factureTransSum.InventTransId == custInvoiceTrans.InventTransId &&
factureTransSum.InvoiceId == custInvoiceTrans.InvoiceId &&
factureTransSum.InvoiceDate == custInvoiceTrans.InvoiceDate &&
factureTransSum.InventGTDId == inventDim.InventGtdId_RU &&
factureTransSum.FactureLineType == FactureLineType_RU::InvoiceLine &&
factureTransSum.Module == FactureModule_RU::Cust;
т.е. в качестве первичного ключа идентифицирующего шапку накладной используется связка
InvoiceId
InvoiceDate
Легко видеть что если по лоту у нас отгружается 2 ГТД-ки по 5 штук, то после сторнирования и проведения фактуры заново может получиться 1 ГТД-ка на 10 штук. т.е. 5 штук будет взято из правильной накладной и 5 из исправленной, а 2-я ГТД-ка вообще в фактуру не попадет.
5. Код
\Data Dictionary\Tables\InventTrans\Methods\qtyInvoiceSold
также закладывается только на InvoiceId
что приходит в конечном итоге к проблемам при вызове с формы
\Forms\SalesCopying\Methods\canClose
(копирование строк, создание кредит-нот с неверными количествами salesLine.QtyOrdered и.т.п.)
6. Также есть ряд мест в расчете налогов, в книгах покупок и продаж, где ваучер не используется.
\Classes\BookTransCalc_Sales_RU\appendGtd
\Classes\SalesCalcTax_Invoice\initCursor
Правда в 3-ке таких мест было больше.
В одном месте я как то видел просто фильтр по InvoiceId и все.
Повеселило...
P.S.
Что с этим делать - фиг знает.
Самым безопасным, простым и дешевым способом на мой взгляд было бы сделать поле CustInvoiceJour.InvoiceId уникальным, а для печати использовать свое кастомизированное поле. Так безопаснее. По крайней мере большинство кода с вышеописанными косяками при этом условии выполняется правильно. Косяк не проявляется.
Можно еще добавить в строки CustInvoiceTrans, FactureTrans - ваучер и везде в запросах добавлять фильтры по нему. Работает корректно. Но поддерживать сложно, особенно с выходом сервис-паков. Хотя мы в итоге по этому пути и пошли. (Исторически так сложилось)
Надежды что это когда-нить исправят - уже нет, особенно с учетом того что в 2012-й все переколбасили, т.е. исправление будет актуально только для 2009-й версии.