Международные предоплаты и российские авансы (часть 1)

Как известно в Dynamics NAV 5.0 была добавлена новая функциональность - Предоплаты.
Также известно, что в Dynamics NAV 4SP3 (и ранее) существовала локальная функциональность по учету Авансов (суть заключалась в учете полученных авансов на отдельном счете, а также обработке НДС, связанным с получением авансов).

Но, к сожалению, оба функционала вместе работать отказываются, тому есть ряд причин. Одна из них объективная – это действительно сложно.

В данной статье будут приведен перечень изменений, которые требуется выполнить, чтобы заставить работать оба функционала. Сразу отмечу, что они будут работать независимо друг от друга, т.е. для одного заказа можно будет использовать либо международные предоплаты, либо местные авансы.

Форма статьи – протокол изменений.

Отдельное спасибо DA_NEAL, который нашел и устранил баг, который в принципе не давал учесть документ после выставления счета на предоплату.

Таблица 379 Detailed Cust. Ledg. Entry
Переименовать поле 12401 Prepayment -> PrepaymentRU

Таблица 380 Detailed Vendor Ledg. Entry
Переименовать поле 12401 Prepayment -> PrepaymentRU

Таблица 383 Detailed CV Ledg. Entry Buffer
Переименовать поле 12401 Prepayment -> PrepaymentRU

Таблица 81 Gen. Journal Line
1. Добавить поле 50401 PrepaymentRU boolean

Перенести код из триггера поля Prepayment в PrepaymentRU

IF Prepayment THEN BEGIN      
 
В  IF NOT ("Document Type" IN ["Document Type"::Payment,"Document Type"::Refund]) THEN      
 
В    FIELDERROR("Document Type");      
 
В  CLEAR("Applies-to Doc. Type");      
 
В  CLEAR("Applies-to Doc. No.");      
 
END;

В будущем этот триггер придется изменить.

2. В триггере Document Type - OnValidate()
РљРѕРґ

IF NOT ("Document Type" IN ["Document Type"::Payment,"Document Type"::Refund]) THEN      
 
В  Prepayment := FALSE;

Заменить кодом

IF NOT ("Document Type" IN ["Document Type"::Payment,"Document Type"::Refund]) THEN      
 
В  PrepaymentRU := FALSE;

3. В триггере Applies-to Doc. Type - OnValidate()
РљРѕРґ

IF "Applies-to Doc. Type" <> "Applies-to Doc. Type"::" " THEN      
 
В  TESTFIELD(Prepayment,FALSE);

Заменить кодом

IF "Applies-to Doc. Type" <> "Applies-to Doc. Type"::" " THEN      
 
В  TESTFIELD(PrepaymentRU,FALSE);

4. В триггере Applies-to Doc. No. - OnValidate()
РљРѕРґ

IF "Applies-to Doc. No." <> '' THEN      
 
В  TESTFIELD(Prepayment,FALSE);

Заменить кодом

IF "Applies-to Doc. No." <> '' THEN      
 
В  TESTFIELD(PrepaymentRU,FALSE);

5. В триггере Applies-to Doc. No. - OnLookup()
РљРѕРґ

IF Prepayment THEN      
 
В  EXIT;

Заменить кодом

IF PrepaymentRU THEN      
 
В  EXIT;

Таблица 382 CV Ledger Entry Buffer
Добавить поле 50401 PrepaymentRU bollean

Таблица 21 Cust. Ledger Entry
Добавить поле 50401 PrepaymentRU bollean

Таблица 25 Vendor Ledger Entry
1. Добавить поле 50401 PrepaymentRU bollean

2. Код из триггера OnValidate поля Prepayment перенести в триггер onValidate поля PrepaymentRU и закомментировать. С ним мы разберемся позже.

Поля Prepayment международного функционала используются в таблицах 81,21, 382
Поля PrepaymentRU используются в таблицах 81, 21, 382, 383, 379
Переименовать поля локальной функциональности нужно, т.к. в одной таблице не может быть два поля с одинаковыми наименованиями.

Формы 12422 Bank Payment Order, 12423 Ingoing Cash Order CO-1, 12446 Vendor Entries Analysis
1. В функциях CalcPayment изменить строки

IF Prepayment THEN BEGIN

РќР°

IF PrepaymentRU THEN BEGIN

(по две строки в каждой форме, всего шесть замен)

2. Р?зменить SourceExpr выключателя Аванс СЃ Prepayment РЅР° PrepaymentRU

Формы 39 General Journal, 253 Sales Journal, 255 Cash Receipt Journal, 256 Payment Journal, 12424 Payment Order List
Р?зменить значение свойства SourceExpr РІ соотвествующем поле СЃ Prepayment РЅР° PrepaymentRU

Отчеты 12402 Cash Outgoing Order CO-2, 12403 Cash Ingoing Order CO-1
В триггере onAfterGetRecord строки

IF Prepayment THEN

РќР°

IF PrepaymentRU THEN

(по две строки в каждой форме, всего четыре замены)

Отчет 595 Adjust Exchange Rates
Все Prepayment, заменить на PrepaymentRU (замен много).

Программный модуль 11 Gen. Jnl.-Check Line
В функции RunCheck
РљРѕРґ

В          IF ("Document Type" = "Document Type"::Payment) AND Prepayment THEN BEGIN      
 
В            TESTFIELD("Applies-to Doc. Type",0);      
 
В            TESTFIELD("Applies-to Doc. No.",'');      
 
В          END;

Заменить кодом

В          IF ("Document Type" = "Document Type"::Payment) AND PrepaymentRU THEN BEGIN      
 
В            TESTFIELD("Applies-to Doc. Type",0);      
 
В            TESTFIELD("Applies-to Doc. No.",'');      
 
В          END;

Программный модуль 226 CustEntry-Apply Posted Entries
В триггере onRun
РљРѕРґ

GenJnlLine.Prepayment := Prepayment

Заменить кодом

GenJnlLine.PrepaymentRU := PrepaymentRU

Программный модуль 227 VendEntry-Apply Posted Entries
В триггере onRun
РљРѕРґ

GenJnlLine.Prepayment := Prepayment

Заменить кодом

GenJnlLine.PrepaymentRU := PrepaymentRU

Программные модули 442 Sales-Post Prepayments и 444 Purchase-Post Prepayments
Ничего не трогаем

Отчет 12453 Post Customer Prepayment
В триггере onAfterGetReccord
РљРѕРґ

IF SourceCustLedgEntry.Prepayment THEN BEGIN

Заменить кодом

IF SourceCustLedgEntry.PrepaymentRU THEN BEGIN

Программный модуль 12410 Customer Prepayment-Post
1. В триггере onRun
РљРѕРґ

TESTFIELD(Prepayment,PostingType = PostingType::Reset)

Заменить кодом

TESTFIELD(PrepaymentRU,PostingType = PostingType::Reset)

2. В функции PostPrepayment
РљРѕРґ

В  GenJnlLine.Prepayment := TRUE

Заменить кодом

В  GenJnlLine.PrepaymentRU := TRUE

Указанный код встречается дважды

Программный модуль 12 Gen. Jnl.-Post Line
1. Функция InsertVAT
РљРѕРґ

В  VATEntry.Prepayment := Prepayment

Заменить кодом

В  VATEntry.Prepayment := PrepaymentRU

2. Функция InsertVAT
РљРѕРґ

В  IF GLSetup."Prepayment Unrealized VAT" AND NOT GLSetup."Unrealized VAT" AND      
 
В    (VATPostingSetup."Unrealized VAT Type" > 0)      
 
В  THEN      
 
В    UnrealizedVAT := GenJnlLine.Prepayment;  UnrealizedVAT := UnrealizedVAT OR      
 
В    (VATPostingSetup."Unrealized VAT Type" > 0) AND Prepayment AND      
 
В    ("Document Type" = "Document Type"::Payment);

Заменить кодом

В  IF GLSetup."Prepayment Unrealized VAT" AND NOT GLSetup."Unrealized VAT" AND      
 
В    (VATPostingSetup."Unrealized VAT Type" > 0)      
 
В  THEN      
 
В    UnrealizedVAT := GenJnlLine.PrepaymentRU;  UnrealizedVAT := UnrealizedVAT OR      
 
В    (VATPostingSetup."Unrealized VAT Type" > 0) AND PrepaymentRU AND      
 
В    ("Document Type" = "Document Type"::Payment);

Очень подозрительный кусок. Требуется проверка.

3. Функция PostCust
РљРѕРґ

В  CustLedgEntry."IC Partner Code" := "IC Partner Code";      
 
В  CustLedgEntry.Prepayment := Prepayment;      
 
В  CustLedgEntry."Prepayment Document No." := "Prepayment Document No.";

Заменить кодом

В  CustLedgEntry."IC Partner Code" := "IC Partner Code";      
 
В  CustLedgEntry.Prepayment := Prepayment;      
 
В  CustLedgEntry.PrepaymentRU := PrepaymentRU;      
 
В  CustLedgEntry."Prepayment Document No." := "Prepayment Document No.";

4. Функция PostVend
РљРѕРґ

В  VendLedgEntry."IC Partner Code" := "IC Partner Code";      
 
В  VendLedgEntry.Prepayment := Prepayment;      
 
В  VendLedgEntry."Vendor VAT Invoice No." := "Vendor VAT Invoice No.";

Заменить кодом

В  VendLedgEntry."IC Partner Code" := "IC Partner Code";      
 
В  VendLedgEntry.Prepayment := Prepayment;      
 
В  VendLedgEntry.PrepaymentRU := PrepaymentRU;      
 
В  VendLedgEntry."Vendor VAT Invoice No." := "Vendor VAT Invoice No.";

5. Функция ApplyCustLedgEntry
РљРѕРґ

В  IF NewCVLedgEntryBuf.Prepayment AND GenJnlLine.Correction THEN      
 
В    ERROR(Text12450);      
 
В  TempOldCustLedgEntry.SETRANGE(Positive,NewCVLedgEntryBuf."Remaining Amount" > 0);

Заменить кодом

В  IF NewCVLedgEntryBuf.PrepaymentRU AND GenJnlLine.Correction THEN      
 
В    ERROR(Text12450);      
 
В  TempOldCustLedgEntry.SETRANGE(Positive,NewCVLedgEntryBuf."Remaining Amount" > 0);

6. Функция ApplyCustLedgEntry
РљРѕРґ

В    IF (NewCVLedgEntryBuf."Currency Code" <> OldCustLedgEntry."Currency Code") THEN      
 
В      IF (NewCVLedgEntryBuf."Amt. Diff. Appln. Entry No." = 0) AND (OldCustLedgEntry."Amt. Diff. Appln. Entry No." = 0) THEN      
 
В        IF (NewCVLedgEntryBuf."Document Type" IN [2,3]) AND (OldCustLedgEntry."Document Type" IN [2,3]) OR      
 
В         (NewCVLedgEntryBuf."Document Type" IN [1,6]) AND (OldCustLedgEntry."Document Type" IN [1,6])      
 
В        THEN      
 
В          ERROR(Text12412,NewCVLedgEntryBuf."Document Type",NewCVLedgEntryBuf."Currency Code",      
 
В            OldCustLedgEntry."Document Type",OldCustLedgEntry."Currency Code");      
 
В    AmtDiffDocToPrepayment := (NewCVLedgEntryBuf."Amt. Diff. Appln. Entry No." <> 0) AND OldCustLedgEntry.Prepayment;

Заменить кодом

В    IF (NewCVLedgEntryBuf."Currency Code" <> OldCustLedgEntry."Currency Code") THEN      
 
В      IF (NewCVLedgEntryBuf."Amt. Diff. Appln. Entry No." = 0) AND (OldCustLedgEntry."Amt. Diff. Appln. Entry No." = 0) THEN      
 
В        IF (NewCVLedgEntryBuf."Document Type" IN [2,3]) AND (OldCustLedgEntry."Document Type" IN [2,3]) OR      
 
В         (NewCVLedgEntryBuf."Document Type" IN [1,6]) AND (OldCustLedgEntry."Document Type" IN [1,6])      
 
В        THEN      
 
В          ERROR(Text12412,NewCVLedgEntryBuf."Document Type",NewCVLedgEntryBuf."Currency Code",      
 
В            OldCustLedgEntry."Document Type",OldCustLedgEntry."Currency Code");      
 
В    AmtDiffDocToPrepayment := (NewCVLedgEntryBuf."Amt. Diff. Appln. Entry No." <> 0) AND OldCustLedgEntry.PrepaymentRU;

7. Функция ApplyCustLedgEntry
РљРѕРґ

В      IF (OldCustLedgEntry."Document Type" IN      
 
В         [OldCustLedgEntry."Document Type"::" ",OldCustLedgEntry."Document Type"::Payment,      
 
В          OldCustLedgEntry."Document Type"::Refund]) AND      
 
В          NOT OldCustLedgEntry.Prepayment      
 
В      THEN      
 
В        ERROR(Text12411);

Заменить кодом

В      IF (OldCustLedgEntry."Document Type" IN      
 
В         [OldCustLedgEntry."Document Type"::" ",OldCustLedgEntry."Document Type"::Payment,      
 
В          OldCustLedgEntry."Document Type"::Refund]) AND      
 
В          NOT OldCustLedgEntry.PrepaymentRU      
 
В      THEN      
 
В        ERROR(Text12411);

8. Функция ApplyCustLedgEntry
РљРѕРґ

В  IF NOT AmtDiffDocToPrepayment THEN      
 
В  IF GLSetup."Unrealized VAT" OR      
 
В    (GLSetup."Prepayment Unrealized VAT" AND TempOldCustLedgEntry.Prepayment)      
 
В  THEN BEGIN // TODO

Заменить кодом

В  IF NOT AmtDiffDocToPrepayment THEN      
 
В  IF GLSetup."Unrealized VAT" OR      
 
В    (GLSetup."Prepayment Unrealized VAT" AND TempOldCustLedgEntry.PrepaymentRU)      
 
В  THEN BEGIN // TODO

Хотя с этим фрагментом нужно будет разбираться отдельно. Уж очень он подозрителен.

9. Функция ApplyCustLedgEntry
РљРѕРґ

IF NOT AmtDiffDocToPrepayment THEN      
 
IF GLSetup."Unrealized VAT" OR      
 
В  (GLSetup."Prepayment Unrealized VAT" AND NewCustLedgEntry.Prepayment)      
 
THEN BEGIN // TODO

Заменить кодом

IF NOT AmtDiffDocToPrepayment THEN      
 
IF GLSetup."Unrealized VAT" OR      
 
В  (GLSetup."Prepayment Unrealized VAT" AND NewCustLedgEntry.PrepaymentRU)      
 
THEN BEGIN // TODO

Р? СЃ этим тоже нужно будет разбираться отдельно.

10. Фунция CalcAmtLCYAdjustment
РљРѕРґ

IF GLSetup."Cancel Curr. Prepmt. Adjmt." AND CVLedgEntryBuf.Prepayment THEN      
 
В  EXIT;

Заменить кодом

IF GLSetup."Cancel Curr. Prepmt. Adjmt." AND CVLedgEntryBuf.PrepaymentRU THEN      
 
В  EXIT;

11. Функция InsertDtldCVLedgEntry
РљРѕРґ

NewDtldCVLedgEntryBuf := DtldCVLedgEntryBuf;      
 
NewDtldCVLedgEntryBuf.PrepaymentRU := CVLedgEntryBuf.Prepayment;      
 
NewDtldCVLedgEntryBuf."Amount Difference" :=

Заменить кодом

NewDtldCVLedgEntryBuf := DtldCVLedgEntryBuf;      
 
NewDtldCVLedgEntryBuf.PrepaymentRU := CVLedgEntryBuf.PrepaymentRU;      
 
NewDtldCVLedgEntryBuf."Amount Difference" :=

В строке NewDtldCVLedgEntryBuf.PrepaymentRU уже отображается PrepaymentRU, т.к. ранее мы выполнили переименование поля в таблице.

12. Р?Р· функции TransferCustLedgEntr удалить строки

В  CVLedgEntryBuf.Prepayment := CustLedgEntry.Prepayment;

Р?

В  CustLedgEntry.Prepayment := CVLedgEntryBuf.Prepayment;

Оба значения хорошо перенесутся функцией Transfield т.к. у Prepayment в обеих таблицах ID 90, а у PrepaymentRU - 50401.

13. В функции ApplyVendLedgEntry
РљРѕРґ

В  IF GLSetup."Unrealized VAT" OR      
 
В    (GLSetup."Prepayment Unrealized VAT" AND OldVendLedgEntry.Prepayment)      
 
В  THEN BEGIN // TODO

Заменить кодом

В  IF GLSetup."Unrealized VAT" OR      
 
В    (GLSetup."Prepayment Unrealized VAT" AND OldVendLedgEntry.PrepaymentRU)      
 
В  THEN BEGIN // TODO

Хотя с этим фрагментом нужно будет разбираться отдельно. Уж очень он подозрителен.

14. В функции ApplyVendLedgEntry
РљРѕРґ

IF GLSetup."Unrealized VAT" OR      
 
В  (GLSetup."Prepayment Unrealized VAT" AND NewVendLedgEntry.Prepayment)      
 
THEN BEGIN // TODO

Заменить кодом

IF GLSetup."Unrealized VAT" OR      
 
В  (GLSetup."Prepayment Unrealized VAT" AND NewVendLedgEntry.PrepaymentRU)      
 
THEN BEGIN // TODO

Хотя с этим фрагментом нужно будет разбираться отдельно. Уж очень он подозрителен.

15. В функции TransferVendLedgEntr
РљРѕРґ

В  CVLedgEntryBuf.Prepayment := VendLedgEntry.Prepayment

Заменить кодом

В  CVLedgEntryBuf.Prepayment := VendLedgEntry.Prepayment      
 
В  CVLedgEntryBuf.PrepaymentRU := VendLedgEntry.PrepaymentRU

16. В функции TransferVendLedgEntr
РљРѕРґ

В  VendLedgEntry.Prepayment := CVLedgEntryBuf.Prepayment

Заменить кодом

В  VendLedgEntry.Prepayment := CVLedgEntryBuf.Prepayment      
 
В  VendLedgEntry.PrepaymentRU := CVLedgEntryBuf.PrepaymentRU

17. В функции PostCustPrepayment
РљРѕРґ

В    TempGenJnlLine."Document No." := "Document No.";      
 
В    TempGenJnlLine.Prepayment := Prepayment;      
 
В    TempGenJnlLine.VALIDATE("Account No.",GLEntry."G/L Account No.");

Заменить кодом

В    TempGenJnlLine."Document No." := "Document No.";      
 
В    TempGenJnlLine.Prepayment := Prepayment;      
 
В    TempGenJnlLine.PrepaymentRU := PrepaymentRU;      
 
В    TempGenJnlLine.VALIDATE("Account No.",GLEntry."G/L Account No.");

18. В функции RUFindAmtForAppln
РљРѕРґ

В  IF GLSetup."Cancel Curr. Prepmt. Adjmt." AND PayEntryBuf.Prepayment THEN      
 
В    AppliedAmountLCY := ROUND(OldAppliedAmount / PayEntryBuf."Original Currency Factor");

Заменить кодом

В  IF GLSetup."Cancel Curr. Prepmt. Adjmt." AND PayEntryBuf.PrepaymentRU THEN      
 
В    AppliedAmountLCY := ROUND(OldAppliedAmount / PayEntryBuf."Original Currency Factor");

19. В функции CalcTaxAccRealizedGainLossAmt
РљРѕРґ

IF NOT CVLedgEntryBuf.Prepayment THEN      
 
В  EXIT;

Заменить кодом

IF NOT CVLedgEntryBuf.PrepaymentRU THEN      
 
В  EXIT;

Форма 302 Customer Entry Statistics

Prepayment заменить на PrepaymentRU (4 вхождения)

Форма 302 Vendor Entry Statistics

Prepayment заменить на PrepaymentRU (4 вхождения)

Форма 402 Sales Order Statistics

РљРѕРґ

END      
 
TempSalesLine.DELETEALL

Заменить кодом

END;      
 
TempSalesLine.RESET;      
 
TempSalesLine.DELETEALL;

Программный модуль 80 Sales-Post
1. В функцию IncrAmount
РљРѕРґ

В  Increment(TotalSalesLine."Inv. Disc. Amount to Invoice","Inv. Disc. Amount to Invoice");      
 
END;

Заменить кодом

В  Increment(TotalSalesLine."Inv. Disc. Amount to Invoice","Inv. Disc. Amount to Invoice");      
 
В  Increment(TotalSalesLine."Prepmt. Amt. Inv.","Prepmt. Amt. Inv.");      
 
В  Increment(TotalSalesLine."Prepmt Amt to Deduct","Prepmt Amt to Deduct");      
 
В  Increment(TotalSalesLine."Prepmt Amt Deducted","Prepmt Amt Deducted");      
 
END;

2.В триггере onRun
РљРѕРґ

В  TempVATAmountLineRemainder.DELETEALL;      
 
В  SalesLine.CalcVATAmountLines(1,SalesHeader,SalesLine,TempVATAmountLine);

Заменить

В  TempVATAmountLineRemainder.DELETEALL;      
 
В  SalesLine.CalcVATAmountLines(1,SalesHeader,CombinedSalesLineTemp,TempVATAmountLine);

Стоит отдельно отметить, что некоторые изменения требуют дополнительного тестирования и осмысливания, что планируется выполнить при написании продолжения. Кроме того есть желание написать методологические рекомендации по работе с международным функционалом предоплат.

Замечания и советы, можно оставлять в комментариях, а если новая защита от спам-ботов окажется непроходимой – то пишите прямо мне на почту apanko@nav4u.ru.

PS. Со времени написания статьи до ее опубликования поставщик выпустил обновления касающиеся НДС с авансов. Следует это учитывать при использовании информации из данной статьи.

Метки:



Оставьте свой отзыв!