Monday, October 25, 2010

Line ###-Offset voucher does not exist in account ______.


If a vendor transaction is reversed but an AP check has been printed (and the payment journal not posted) you may get this error.  Essentially the record which was marked for settlement by the check has been deleted so it does not exist (VendTransOpen was deleted when the invoice was reversed).  If you go to the line in the accounts payable payment journal and click Inquiries > view marked transactions you will find it blank.  AX has lost the relationship of what invoices/credits were settled as part of the payment.  There are really two tables involved SpecTrans and VendTransOpen.

First thing we need to know is which transactions were settled by that payment.  The check will have the transactions shown in the Bank module.  Bank > Checks…select the check…Invoices button.  It lists all the transactions paid.  Go to the vendor transaction which was paid, click the Open button and remember the RecID of the VendTransOpen record for that transaction.

Find the reversal transaction and revoke the reversal (click the Reverse button when you have the reversal transaction selected).  The invoice should now have a balance like any other open invoice.
At this point if the SpecTrans record still exists you can fix it otherwise you must create it.  First open the SpecTrans table in the table browser and filter on SpecRecID = the journal line’s RecID.  If you find one then just fix the RefRecID to be the record ID of the VendTransOpen record.  Otherwise create the missing SpecTrans record by using a job.

static void Job1(Args _args)
{
    SpecTrans       specTrans;
    ;
    SpecTrans.clear();
    SpecTrans.initValue();
    SpecTrans.SpecTableId       = tablenum(LedgerJournalTrans);
    SpecTrans.SpecRecId         = 5638151884; // Record ID of the ledger journal line
    SpecTrans.LineNum           = 1.00;
    SpecTrans.Code              = "USD";
    SpecTrans.Balance01         = -78680.92; // Amount of the invoice which was paid
    SpecTrans.RefTableId        = tablenum(VendTransOpen);
    SpecTrans.RefRecId          = 5637622098; // Record ID of the open transaction
    SpecTrans.Payment           = NoYes::No;
    SpecTrans.PaymentStatus     = CustVendPaymStatus::Sent;
    SpecTrans.ErrorCodePayment  = "";
    SpecTrans.FullSettlement    = NoYes::No;
    SpecTrans.insert();
}

Saturday, October 9, 2010

Get the next unique file name

Sometimes you are saving a temporary file so you don't want to delete or overwrite anything that already exists in a directory...there is a nice function to find the next unique file name.

fileNameTemp = Global::fileNameNext(fileOriginalsPath + fileName);

Monday, October 4, 2010

Rename items quickly

Here is a little script to rename items quickly.  Just provide a CSV file with old and new item number.  I found that making the CSV file was faster than making a job to intelligently rename items because I could use Excel functions and review the new item numbers faster.

static void renameFromCSV(Args _args)
{
    #File
    CommaIO                 file;
    Container               values;
    Dialog                  dialog;
    DialogField             dfFileName;
    LineNum                 lineNum;
    ItemID                  itemIDfrom;
    ItemID                  itemIDto;
    InventTable             inventTable;
    ;
    setPrefix(funcName());
    dialog      = new Dialog("Rename items");
    dialog.filenameLookupFilter(["@SYS39829", #AllFilesName + #csv]);
    dfFileName  = dialog.addField(typeid(FileNameOpen));
    if (!dialog.run() || !dfFileName.value())
        return;

    if (!WinAPI::fileExists(dfFileName.value()))
        throw error(strfmt("@SYS18678", dfFileName.value()));

    file = new CommaIO(dfFileName.value(), #io_read);
    if (!file)
        throw error("@SYS74299");
    values = file.read();

    while (values != connull())
    {
        setPrefix(strfmt("Row %1 for %2", lineNum, conpeek(values, 1)));
        if (conlen(values) != 2)
            throw error('Bad row');

        itemIDfrom  = conpeek(values, 1);
        itemIDto    = conpeek(values, 2);

        if (InventTable::exist(itemIDfrom))
        {
            if (!InventTable::exist(itemIDto))
            {
                ttsbegin;
                inventTable = InventTable::find(itemIDfrom, true);
                inventTable.ItemId = itemIDto;
                inventTable.renamePrimaryKey();
                ttscommit;
                
                info(strfmt("%1 to %2", itemIDfrom, itemIDto));
            }
            else
                error(strfmt("@SYS93964", itemIDto));
        }
        else
            error(strfmt("@SYS94719", itemIDfrom));

        lineNum++;
        values = file.read();
    }
    info("@SYS78985");
}