Показать сообщение отдельно
Старый 05.10.2011, 20:48   #13  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,867 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Есть еще одна неприятная бага. Не связанная напрямую с печатью, но влияющая на печать (причем ошибка похоже не только в локализации).

Попробую быть краток :
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-й версии.
За это сообщение автора поблагодарили: Pustik (2), gl00mie (7), someOne (2).