Wednesday, November 5, 2014

Create APP Developer Site


Get-SPServiceInstance | where{$_.GetType().Name -eq "AppManagementServiceInstance" -or $_.GetType().Name -eq "SPSubscriptionSettingsServiceInstance"}


  $account = Get-SPManagedAccount "Eli\spsvc"


  $appPoolSubSvc = New-SPServiceApplicationPool -Name SettingsServiceAppPool -Account $account
  $appPoolAppSvc = New-SPServiceApplicationPool -Name AppServiceAppPool -Account $account


  $appSubSvc = New-SPSubscriptionSettingsServiceApplication –ApplicationPool $appPoolSubSvc –Name SettingsServiceApp –DatabaseName SettingsServiceDB
  $proxySubSvc = New-SPSubscriptionSettingsServiceApplicationProxy –ServiceApplication $appSubSvc

  $appAppSvc = New-SPAppManagementServiceApplication –ApplicationPool $appPoolAppSvc –Name AppServiceApp –DatabaseName AppServiceDB
  $proxyAppSvc = New-SPAppManagementServiceApplicationProxy –ServiceApplication $appAppSvc



Set-SPAppSiteSubscriptionName -Name "app" -Confirm:$false

Monday, October 27, 2014

Add New User

Find SID from regedit, under HKEY_USERS. Copy the SID as your own machine's SID.

Update userinfo table as the following:
update userinfo set SID='', Networkdomain = '<Network_domain_name>', networkalias = '<Network_alias>' where id = 'admin'


Excerpt from other blog:
Prepare the Database-Create a new database in SQL and restore the backup from the customer into it.
-In SQL in the newly restored database go to Security > Users.  Right-click on Users and choose new user.  Add the user account that runs the AOS service.  For me, this is my domain account. 
-In the middle of this user form, under Owned Schemas mark db_owner.
-Still in the same form where you added the user, under Database role membership mark db_datareader, db_datawriter, and db_owner.
-In SQL in the newly restored database go to Programmability > Stored Procedures and right-click on CreateServerSessions and choose Properties.
-Click Permissions and click the Search button.  Find the account you just added to the database as a user, for me this is my domain account.
-In the bottom of this form under the Grant column mark all of the choices.
-In SQL in the newly restored database go to Programmability > Stored Procedures and right-click on CreateUserSessions and choose Properties.
-Click Permissions and click the Search button.  Find the account you just added to the database as a user, for me this is my domain account.
-In the bottom of this form under the Grant column mark all of the choices.
-In SQL click the New Query button.
-Choose your EXISTING AX database - so not the customer's database you just restored but the AX database you have with demo data in it, run the following query:
 select SID, NETWORKDOMAIN, NETWORKALIAS, * from UserInfo where Id = 'Admin'
-Click the New Query button and choose the CUSTOMER's database.  Leave your existing query against your own database open.  We are going to use the results in our next query.
-In the New Query against the customer's database run the following:
update USERINFO set SID = 'SID field from previous query', NETWORKDOMAIN = 'NETWORKDOMAIN field from previous query', NETWORKALIAS = 'NETWORKALIAS field from previous query'
 where ID = 'Admin' --The idea here is you want to grab the SID, NETWORKDOMAIN and NETWORKALIAS values from your own UserInfo table and update the customer's UserInfo table with your user information so you can log into their database.

Saturday, October 25, 2014

Restore DB


1.Shutdown the AOS in services
2.Open SQL Management Studio
3.Connect to the SQL Database
4.Right Click MicrosoftDynamicsAx => Tasks => Restore => Database
5.Select From Device and then find the downloaded .bak File.
6.On the top left click on "Options" and check the first box: Overwrite the existing database (With REPLACE)
7.Click OK and repeat for the other DB.
Repeat same for the Model database.

Tuesday, October 14, 2014

UserSessionService

Steps to remove fix it
1. Go to directory: C:\Program Files\Microsoft Dynamics AX\60\Server\OE_US_AX_TST\bin
2. Stop AX Service
3. Make a copy of XPPIL folder
4. Delete XPPIL folder
5. Start AX Service
6. Generate Full CIL

Monday, October 6, 2014

Mailer Program

    SysMailer                           mailer;  
    SysEmailParameters                  params;
   
    ;
   
    // Set up the email header
    mailer = new SysMailer();
    mailer.subject("TEST EQ");
    mailer.fromAddress("abc@abc.com");
   
    params = SysEmailParameters::find();
    mailer.SMTPRelayServer(params.SMTPRelayServerName,
                           params.SMTPPortNumber,
                           params.SMTPUserName,
                           sysEmailParameters::password());

    mailer.tos().appendAddress("abc@abc.com");
    mailer.body("Some body message");
   
    // Send the email
    startlengthyoperation();

    mailer.sendMail();

    endlengthyoperation();

Wednesday, August 20, 2014

Compare Datetime

    mbsWMSPODDeliveryTable mbsWMSPODDeliveryTable;
    utcdatetime xppDttm;
    System.DateTime    nppDttm;
    TransDate   d;
    ;
    xppDttm = 2013-10-05T23:22:21; // ISO standard format.
    nppDttm =  Global::utcDateTime2SystemDateTime( xppDttm);
    while select crosscompany SignatureName
        from mbsWMSPODDeliveryTable
            where mbsWMSPODDeliveryTable.DeliveryDateTime > xppDttm
               
    {
    if(strScan(mbsWMSPODDeliveryTable.SignatureName, "Laing", 1, strLen(mbsWMSPODDeliveryTable.SignatureName)))
        info(mbsWMSPODDeliveryTable.SignatureName);
    }

Tuesday, August 19, 2014

CommaIo object not initialized

"CommaIo object not initialized" was indeed file-related but in a more broad
sense.

The code was correct. The file path and name were correct. Backslashes were
escaped. The calls, the setup, everything was correct, except...

When a new Class is created the RunOn property is set to "Called from" by
default. Changing that to "Client" fixes the problem.

Thursday, August 7, 2014

Check Orphan SalesLine

static void checkSalesLineSalesTable(Args _args)
{
    #AviFiles
    SysOperationProgress    p;
    int64                   numRecs;
    SalesLine               salesLine;
    Counter                 totalLines;
    Counter                 totalGood;
    Counter                 totalBad;
    boolean                 goodFound;
    ;
    select count(RecId) from salesLine
         group by SalesId;
    numRecs = salesLine.RecId;
    if (numRecs)
    {
        p = SysOperationProgress::NewGeneral(#AviUpdate, "Check sales line sales qty", numRecs);
        while select * from salesLine
            group by SalesId
        {
            totalLines++;
            p.setText(strFmt('Record %1 : %2; Bad: %3', totalLines, numRecs, totalBad));
            p.incCount();
            if (!SalesTable::exist(salesLine.SalesId))
            {
                totalBad++;
                info(strfmt('Order %1 Type: %2 Status: %3 Item: %4 Qty: %5 Created by: %6, Created on: %7',
                            salesLine.SalesId,
                            salesLine.SalesType,
                            salesLine.SalesStatus,
                            salesLine.ItemId,
                            salesLine.SalesQty,
                            salesLine.createdBy,
                            salesLine.createdDateTime));
            }
            else
            {
                totalGood++;
            }
        }
    }
    info('Total lines: '+int2str(totalLines));
    info('Total good: '+int2str(totalGood));
    info('Total bad: '+int2str(totalBad));
}

Tuesday, August 5, 2014

Menu to Call Report

               salesInvoiceMenu = new MenuFunction(menuItemName, MenuItemType::Output);   
                if (mbsReprint && mbsConfigSetting::string("BD-191"))
                {
                    salesInvoiceMenu.objectType(UtilElementType::Report);
                    salesInvoiceMenu.object(mbsConfigSetting::string("BD-191"));
                }
                else
                {
                    if (reportContainer)
                    {
                        reportName             = conpeek(reportContainer,1);
                        reportCopies           = conpeek(reportContainer,2);

                        if (webInvoice)
                        {
                            reportName = strFmt("%1_web", reportName);
                        }

                        salesInvoiceMenu.enumTypeParameter(PrintCopyOriginal);
                        salesInvoiceMenu.enumParameter(args.parmEnum());
                        salesInvoiceMenu.objectType(UtilElementType::Report);
                        salesInvoiceMenu.object(reportName);
                    }
                    else
                    {
                        salesInvoiceMenu.objectType(UtilElementType::Report);
                        salesInvoiceMenu.object(menuItemOutputStr(SalesInvoice));
                    }
                }

Sunday, August 3, 2014

Backup and Restore AX 2009

Pre-requisites
In my existing environment I have a running instance of AX 2009 that is on sp1.  If the customer is on AX 2009 I assume the customer is on sp1 since most are.  The AOS, SQL server and AX client are all on the same machine.  The AOS service under Start > Control Panel > Administrative Tools > Services is started and runs under my domain account.  In the AX application my domain account is the Admin account under Administration > Users.
Prepare the Database
-Create a new database in SQL and restore the backup from the customer into it.
-In SQL in the newly restored database go to Security > Users.  Right-click on Users and choose new user.  Add the user account that runs the AOS service.  For me, this is my domain account. 
-In the middle of this user form, under Owned Schemas mark db_owner.
-Still in the same form where you added the user, under Database role membership mark db_datareader, db_datawriter, and db_owner.
-In SQL in the newly restored database go to Programmability > Stored Procedures and right-click on CreateServerSessions and choose Properties.
-Click Permissions and click the Search button.  Find the account you just added to the database as a user, for me this is my domain account.
-In the bottom of this form under the Grant column mark all of the choices.
-In SQL in the newly restored database go to Programmability > Stored Procedures and right-click on CreateUserSessions and choose Properties.
-Click Permissions and click the Search button.  Find the account you just added to the database as a user, for me this is my domain account.
-In the bottom of this form under the Grant column mark all of the choices.
-In SQL click the New Query button.
-Choose your EXISTING AX database - so not the customer's database you just restored but the AX database you have with demo data in it, run the following query:
 select SID, NETWORKDOMAIN, NETWORKALIAS, * from UserInfo where Id = 'Admin'
-Click the New Query button and choose the CUSTOMER's database.  Leave your existing query against your own database open.  We are going to use the results in our next query.
-In the New Query against the customer's database run the following:
update USERINFO set SID = 'SID field from previous query', NETWORKDOMAIN = 'NETWORKDOMAIN field from previous query', NETWORKALIAS = 'NETWORKALIAS field from previous query'
 where ID = 'Admin' --The idea here is you want to grab the SID, NETWORKDOMAIN and NETWORKALIAS values from your own UserInfo table and update the customer's UserInfo table with your user information so you can log into their database.
Prepare the Application Files
-When you install if you choose the default paths the Application files are stored at this location "C:\Program Files\Microsoft Dynamics AX\50\Application\Appl".  Take the copy of the customer's application folder and copy it to this location.   When it finishes copying you should have your existing application folder and the customer's application folder sitting side-by-side inside the Appl directory.
-Go into the copied application folder and find the file named axapd.aoi and rename it.
Create a New Server Configuration
-Go to Start > Control Panel > Administrative Tools > Microsoft Dynamics AX 2009 Server Configuration and open the server configuration utility.
-In this utility click Manage > Create configuration and give the new configuration a name.
-In the new configuration under the Application Object Server tab find the Application instance dropdown and click it.  If the customer's application files are restored correctly you should see the customer's folder in this list, pick it.
-Under the Database Connection tab click the Database name dropdown.  If the customer's database has been restored you should see the name of that database in the list, pick it.
-Click OK and it should prompt you to restart the AOS, choose Yes.  This will restart the AOS with your AX install pointing to the customer's database and application files.  Since we renamed the axapd.aoi file the AOS service will take a while to start.  You can go into Control Panel > Administrative Tools > Services and find the Dynamics AX AOS service.  It will likely be in a Starting state as it rebuilds the axapd.aoi file.  Wait for it to change to a Started state.
Test the Environment
-Launch AX to verify you can get in.  Be aware of the company you are logged into when trying to recreate an issue as customer's tend to have a lot more companies than the demo data.

Friday, July 25, 2014

Runtime FormLookup

Query query = new Query();
    QueryBuildDataSource queryBuildDataSource;
    QueryBuildRange queryBuildRange;
    SysTableLookup sysTableLookup = SysTableLookup::newParameters(tableNum(TableTaskCreationRules), this);
    TableId tableId;
    FieldId fieldId;
    ;
    tableId = tablename2id("TableTaskCreationRules");
    fieldId = fieldname2id(tableId, "CreationRule");
    sysTableLookup.addLookupfield(fieldId, true);
    fieldId = fieldname2id(tableId, "CreationDesc");
    sysTableLookup.addLookupfield(fieldId);
    fieldId = fieldname2id(tableId, "CreationMode");
    sysTableLookup.addLookupfield(fieldId);
    queryBuildDataSource = query.addDataSource(tableId);
    queryBuildRange      = queryBuildDataSource.addRange(fieldNum(TableTaskCreationRules, TaskType));
    queryBuildRange.value(enum2str(TaskType::Picking));
    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();

Monday, July 14, 2014

Create Run-Time Lookup Forms

public void lookup()
{
   
    Query                   query          = new Query();
    QueryBuildDataSource    queryBuildDataSource;
    QueryBuildRange         queryBuildRange;

    // Create an instance of SysTableLookup where 'this'
    // is the current form control.
    SysTableLookup sysTableLookup =
        SysTableLookup::newParameters(tableNum(custTable), this);
    ;

    // Add fields to be shown in the lookup form.
    sysTableLookup.addLookupField(fieldNum(CustTable, AccountNum));
    sysTableLookup.addLookupField(fieldNum(CustTable, Name));

    // Limit and arrange the data selection.
    queryBuildDataSource = query.addDataSource(tableNum(CustTable));
    queryBuildRange = queryBuildDataSource.addRange(
        fieldNum(CustTable, AccountNum));
    queryBuildRange.value('100..2000');
    sysTableLookup.parmQuery(query);

    // Perform the lookup.
    sysTableLookup.performFormLookup();

    //Don't call super() (commented out in the code).
    //   super()
}

Wednesday, July 2, 2014

ReadXML

static void RealXML(Args _args)
{
    XMLDocument     retXmlDoc;
    XMLElement      xmlOutput;
    XMLElement      creditCardNode, invoiceSumNode, invoiceDtlNode;
    boolean         requestPayment = true;
    str             requestContactId, requestCCSubId, requestRecId, requestPayMode, requestLast4;
    str             requestCCnum, requestNameOnCard, requestCCExpMonth, requestCCExpYear, requestCCType;
    str             requestNumInv, requestTtlAmt, retMessageCode, retMessageText;
    str             invoiceId, xRefRecId, openAmount;
    ;
    retXmlDoc = new XMLDocument();
    xmlOutput = retXmlDoc.createElement("ProcessInvoiceCCPayment");
    xmlOutput.setAttribute("processingFullPayment", strfmt("%1", requestPayment));
    xmlOutput.setAttribute("contactId", strfmt("%1", requestContactId));
    creditCardNode = retXmlDoc.createElement("CreditCard");
    xmlOutput.appendChild(CreditCardNode);
    creditCardNode.setAttribute("CCSubscriptionId", strfmt("%1", requestCCSubId));
    creditCardNode.setAttribute("CCRecID", strfmt("%1", requestRecId));
    creditCardNode.setAttribute("payMode", strfmt("%1", requestPayMode));
    creditCardNode.setAttribute("CCLast4Digits", strfmt("%1", requestLast4));
    creditCardNode.setAttribute("mbsCCNumber", strfmt("%1", requestCCnum));
    creditCardNode.setAttribute("nameOnCard", strfmt("%1", requestNameOnCard));
    creditCardNode.setAttribute("CCExpMonth", strfmt("%1", requestCCExpMonth));
    creditCardNode.setAttribute("CCExpYear", strfmt("%1", requestCCExpYear));
    creditCardNode.setAttribute("CCType", strfmt("%1", requestCCType));
    invoiceSumNode = retXmlDoc.createElement("InvoiceSummary");
    xmlOutput.appendChild(invoiceSumNode);
    invoiceSumNode.setAttribute("totalNumberOfInvoices", strfmt("%1", requestNumInv));
    invoiceSumNode.setAttribute("totalOpenAmount", strfmt("%1", requestTtlAmt));
    invoiceSumNode.setAttribute("messageCode", strfmt("%1", retMessageCode));
    invoiceSumNode.setAttribute("messageText", strfmt("%1", retMessageText));
    invoiceDtlNode = retXmlDoc.createElement("InvoiceDetail");
    invoiceSumNode.appendChild(invoiceDtlNode);
    invoiceDtlNode.setAttribute("InvoiceId", strfmt("%1", invoiceId));
    invoiceDtlNode.setAttribute("RefRecId", strfmt("%1", xRefRecId));
    invoiceDtlNode.setAttribute("OpenAmount", strfmt("%1", openAmount));
    info(xmlOutput.xml());

    /*
    <ProcessInvoiceCCPayment processingFullPayment="true" contactId="">
        <CreditCard CCSubscriptionId="" CCRecID="" payMode="" CCLast4Digits="" mbsCCNumber="" nameOnCard="" CCExpMonth="" CCExpYear="" CCType="" />
        <InvoiceSummary totalNumberOfInvoices="" totalOpenAmount="" messageCode="" messageText="">
            <InvoiceDetail InvoiceId="" RefRecId="" OpenAmount="" />
        </InvoiceSummary>
    </ProcessInvoiceCCPayment>
    */
}

Tuesday, June 10, 2014

FormRun 3

    salesTable              salesTable = SalesTable::find("S104872");
    FormRun                 formRun;
    Args                    args;
    str                     parmGuid;
    ;
    args = new Args(MenuItemDisplayStr(BDCCOneTime));
    args.record(salesTable);
    formRun = New Menufunction(MenuItemDisplayStr(BDCCOneTime), MenuItemType::Display).create(args);
    if (formRun)
    {
        formRun.run();
    }

FormRun 2


    salesTable              salesTable = SalesTable::find("S104872");
    FormRun                 fr;
    Args                    args;
    str                     parmGuid;
    ;
    args = new Args("BDCCOneTime");
    args.record(salesTable);
    fr = new FormRun(args);
    if (fr)
    {
        fr.init();
        fr.run();
        fr.wait();
    }

Where BDCCOneTime is a form. The short program passes a record into the Form.

FormRun

Form                    form;
    FormRun                 formRun;
    Args                    args;
    FormBuildDesign         formBuildDesign;
    FormBuildControl        formBuildControl;
    FormBuildTabControl     formBuildTabControl;
    FormBuildTabPageControl formBuildTabPageControl;
    FormBuildGridControl    formBuildGridControl;
    FormBuildDatasource     formBuildDatasource;
    FormBuildStringControl  formString;
    ;
    form = new Form();
    formBuildDatasource = form.addDataSource(tableStr(PurchTable));
    formBuildDesign = form.addDesign('design');
    formBuildTabControl = formBuildDesign.addControl(FormControlType::Tab, 'Tab');
    formBuildTabPageControl = formBuildTabControl.addControl(FormControlType::TabPage, 'TabPage');
    formBuildGridControl = formBuildTabPageControl.addControl(FormControlType::Grid, 'Grid');
    formString = formBuildGridControl.addDataField(formBuildDatasource.id(), fieldNum(PurchTable, PurchId));
    formString.label("PurchId");
    args    = new Args();
    args.object(form);
    formRun = classFactory.formRunClass(args);
    formRun.init();
    formRun.run();
    formRun.wait();

Monday, June 9, 2014

Clean Cart

Delete Table instance is different from select table instance. When do a loop find or assign to a new object, best practice is to use that object's find method.
static void clearDeliveryItems(cusWBWebCartId _cartId)
{
    cusWebCartLine  cusWebCartLine;
    InventTable     inventTable;
    cusWebCartLine  deletecusWebCartLine;
    str             test;
    ;
      _cartId = 'CART_ID_019937';
       while
        select * from cusWebCartLine where cusWebCartLine.cartId == _cartId
        {//test="reset";
            inventTable=inventTable::find(cusWebCartLine.ItemId,false);
                if (inventTable.cusbdDeliveryOption == NoYes::Yes)
                    {
                    ttsbegin;
                    deletecusWebCartLine = cusWebCartLine::findRecId(cusWebCartLine.RecId, true);
                    if (deletecusWebCartLine)
                    {
                        deletecusWebCartLine.delete();
                    }
                    ttscommit;
                   // test="deleted";
                    }
                // else test="safe";
        }
}
 

Friday, May 30, 2014

CreateClass

    int                         id;
    boolean                     ret;
    Array                       errArray = new Array(Types::String);
    str                         className;
    className   = "mbsEBErrChk" + enum2str(mDocType);
    id          = dict.className2Id(className);
    obj         = classFactory.createClass(id);
    if (obj)
    {
        obj.setmDocDir(mDocDir);
        obj.setmDocType(mDocType);
        obj.setTPId(TPId);
        obj.setUpdate(updateRec);
        if (partner)
        {
            obj.SetPartner(partner);
        }
        if (partnerType)
        {
            obj.SetPartnerType(partnerType);
        }
       numErrors   = obj.checkError(mDoc, writeErrRec, _showTiming);
    }

Monday, May 26, 2014

Lookup and Query Range

public void lookupHCMtable(FormStringControl _ctrl)
{
    SysTableLookup              sysTableLookup = SysTableLookup::newParameters(tablenum(hcmtable), _ctrl);
    Query                       query = new Query();
    QueryBuildDataSource        queryBuildDataSource;
    QueryBuildRange             queryBuildRange;
    ;
    sysTableLookup.addLookupfield(fieldnum(hcmtable, EmpId));
    sysTableLookup.addLookupfield(fieldnum(hcmtable, EmpName));
    queryBuildDataSource = query.addDataSource(tablenum(hcmtable));
    queryBuildRange = queryBuildDataSource.addRange(fieldnum(hcmtable, Lastdateworked));
    queryBuildRange.value(strFmt('(Lastdateworked > %1)', today()));
    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}
 

Wednesday, April 16, 2014

Run Query -- Pass in Param

    query = new Query();
    queryRun = new QueryRun(queryStr(mbs3PHPShipTo));
    qbds = queryRun.query().dataSourceTable(tableNum(CustTable));
    qbr = qbds.addRange(fieldNum(CustTable, AccountNum));
    qbr.value(SysQuery::value(custAccount));
    while(queryRun.next())
    {
        custTable = queryRun.get(tableNum(CustTable));
        address = queryRun.get(tableNum(Address));
        customerElemShipTo = this.addElement("ShipToValue", customerShipToNode);
        customerElemSUD = this.addElement("DisplayName", customerElemShipTo);
        customerElemSUD.text(address.Name);
   }