26 Nisan 2019 Cuma

AX 2012 - View'a computed column eklemek

AX 2012 View'a computed column eklerken yaptığımız aslında create view cümlesine ekleme yapmak ve SQL Server tarafında hatasız oluşmasını sağlamak.

Öncelikle view tablo metodlarına eklemek istediğimiz kolon için bir metod ekliyoruz:

public static server str SNBisBuggedReverse()
{
return strFmt("select top 1 sign(sum(accountingcurrencyamount)) from GENERALJOURNALACCOUNTENTRY g "+
"where isnull(%1,'') <> '' and exists (select * from TRANSACTIONREVERSALTRANS t where t.TRACENUM = %1 and t.REFRECID = g.RECID and t.REFTABLEID = %2) "+
"group by g.LEDGERACCOUNT "+
"order by 1 desc",SysComputedColumn::comparisonField(identifierstr(PAXMizanView), identifierstr(TransactionReversalTrans), identifierstr(TraceNum)),
 tableNum(GeneralJournalAccountEntry));
}

Yukarıda görüldüğü gibi AX sorgusu değil de SQL Server sorgusu kullandım metodu eklerken. Metodumuz aşağıdaki gibi bir string değer döndürecek:

select top 1 sign(sum(accountingcurrencyamount)) from GENERALJOURNALACCOUNTENTRY g where isnull(T4.TRACENUM,'') <> '' and exists (select * from TRANSACTIONREVERSALTRANS t where t.TRACENUM = T4.TRACENUM and t.REFRECID = g.RECID and t.REFTABLEID = 3119) group by g.LEDGERACCOUNT order by 1 desc

View'a eklediğimiz kolonun NoYes cinsinde Enum olmasını istiyoruz. O zaman:




Ardından Eklediğimiz View metodu ViewMethod property alanından seçiyoruz.




Eklediğim yeni kolon maalesef view hızını çok yavaşlatan bir kolondu, mümkün oldukça daha basit birşeyler seçmek view hızı açısından önemli.

17 Nisan 2019 Çarşamba

AX 2012 - Source Document Framework hataları

AX 2012 ile bazen sebebini bilmediğim bir şekilde Source Document Framework ile ilgili hatalar alıyoruz. Bu hataların çözümü için full CIL önerenler olmuş, öksüz kayıtları temizleyen bir job önerilmiş (1), Source Document kayıtlarını düzelten başka bir job (2) önerilmiş.


Benim son aldığım hata aşağıdaki gibi:







Debug yaptığımda VendInvoiceInfoLine.SourceDocumentLine alanıyla ilişkili SourceDocumentLine tablosunda bir kayıt varken PurchLine.SourceDocumentLine alanıyla ilişkili kaydın silinmiş olduğunu gördüm. Yukarıda bahsedilen kod parçaları benim durumumda işe yaramadı. İrsaliyesi olan başka bir PurchLine satırına bağlı Source Document kaydını inceledim ve aşağıdaki jobu yazdım. Jobu çalıştırdıktan sonra hatasız bir şekilde deftere nakip yapabildim.


 PurchLine            purchLine;
    SourceDocumentLine   line;
    SourceDocumentHeader header;


    select firstonly forUpdate purchLine
        where purchLine.RecId == 5637329927;

    ttsBegin;
    header.AccountingStatus = SourceDocumentAccountingStatus::InProcess;
    header.SourceRelationType = 345;
    header.TypeEnumName = "SourceDocument_ProductOrder";
    header.TypeEnumValue = 1;
    header.insert();

    Line.SourceDocumentHeader = header.RecId;
    line.AccountingStatus = SourceDocumentLineAccountingStatus::Completed;
    Line.SourceRelationType = 340;
    Line.TypeEnumName = "SourceDocumentLine_ProductOrder";
    Line.TermQuantity = 0;
    Line.TypeEnumValue = 1;
    Line.insert();
    purchLine.SourceDocumentLine = Line.RecId;
    purchLine.doUpdate();
    ttsCommit;

TypeEnumName, SourceRelationType gibi fieldların değerleri ilişkili oldukları evrağa göre değişiyor. Siz de kendi durumunuza göre aynen benim yaptığım gibi sağlam bir kaydı inceleyerek kodu adapte edebilirsiniz. Tabii kodu öncelikle test ortamında denemelisiniz ve canlıda oluşturduğunuz kayıtların  RecId değerlerini saklamalısınız.

(1) Öksüz kayıtları temizlemek için tavsiye edilen job:

  SourceDocumentLine sline;
    SysDictTable table;
    PurchTable header;
    PurchLine purchline;
    PurchId purchId = "SA025965";
    boolean fix;
    Common rec;
    int fieldId, found, notfound;


    if (purchId)
    {
        while select purchLine where purchLine.PurchId == purchId
        {
            while select forUpdate sline where sline.ParentSourceDocumentLine == purchLine.SourceDocumentLine
            {
                table = new SysDictTable(sline.SourceRelationType);
                rec = table.makeRecord();
                fieldId = fieldName2id(sline.SourceRelationType, "SourceDocumentLine");
                select rec where rec.(fieldId) == sline.RecId;

                if (rec.RecId)
                {
                    info(strFmt("Record Match Found %1 %2 %3", table.name(),rec.caption(),sline.RecId));
                    found++;
                }
                else
                {
                    ttsBegin;
                    sline.doDelete();
                    ttsCommit;
                    info(strFmt("Orphan Found %1", table.name()));
                    notfound++;

                }

            }
            info(strFmt("Found %1", found));
            info(strFmt("Orphans found and deleted %1",notfound));
            found = 0;
            notfound = 0;
        }
    }

(2) Forumlarda bulduğumuz Source Document kayıtlarını düzeltmek için tavsiye edilen diğer job, benim kaydımda işe yaramadı:

   RecID VendInvoiceRecID =  5637357894;

    VendInvoiceInfoTable    vendInvoiceInfoTable;
    VendInvoiceInfoLine     vendInvoiceInfoLine;

    SourceDocumentLine SourceDocumentLine;
    SourceDocumentHeader SourceDocumentHeader;

    PurchParmUpdate   PurchParmUpdate;
    RandomGenerate          rg = RandomGenerate::construct();


    vendInvoiceInfoTable = VendInvoiceInfoTable::findRecId(VendInvoiceRecID,true);
    if(vendInvoiceInfoTable)
    {
        ttsBegin;


        while select forupdate SourceDocumentHeader
             where SourceDocumentHeader.SourceRelationType == 1425
                && SourceDocumentHeader.RecId == vendInvoiceInfoTable.SourceDocumentHeader
        {
            SourceDocumentHeader.delete();
        }

        while select forupdate VendInvoiceInfoLine
             where VendInvoiceInfoLine.TableRefId  == vendInvoiceInfoTable.TableRefId
               && VendInvoiceInfoLine.ParmId       == vendInvoiceInfoTable.ParmId
        {
           delete_from SourceDocumentLine
             where SourceDocumentLine.SourceRelationType == 1430
               && SourceDocumentLine.RecId == VendInvoiceInfoLine.SourceDocumentLine  ;

//            VendInvoiceInfoLine.SourceDocumentLine = 0;
                        VendInvoiceInfoLine.SourceDocumentLine = rg.randomInt(1000,10000000);
            VendInvoiceInfoLine.doUpdate();
        }

        vendInvoiceInfoTable.selectForUpdate(true);
        vendInvoiceInfoTable.SourceDocumentHeader = 0;
        vendInvoiceInfoTable.SourceDocumentLine = 0;
        vendInvoiceInfoTable.doUpdate();
        ttsCommit;
        ttsBegin;
SourceDocumentProcessorFacade::submitSourceDocumentImplementation(vendInvoiceInfoTable,1);
        SourceDocumentProcessorFacade::submitSourceDocumentLineImplementation(vendInvoiceInfoTable,1);
        while select forupdate VendInvoiceInfoLine
             where VendInvoiceInfoLine.TableRefId  == vendInvoiceInfoTable.TableRefId
               && VendInvoiceInfoLine.ParmId  == vendInvoiceInfoTable.ParmId
        {
SourceDocumentProcessorFacade::submitSourceDocumentLineImplementation(VendInvoiceInfoLine,1);
        }
        ttsCommit;
        info("ok");
    }