cancel
Showing results for 
Search instead for 
Did you mean: 

Using B1DE to create StockTransfers from POs?

Former Member
0 Kudos

Hi,

I am trying to create an addon that allows users to click a button from a PO and issue Stock Transfers from the line items in the PO.

There are two issues I am hoping you can please help with:

1) The code I've written reads the data from the Matrix on the PO. This seems to take a long time, and I am pretty sure it is happening in the way I am trying to read the Matrix, because I don't yet know how to do it better.

2) When trying to create a oStockTransfer document, the app crashes with this error:

{System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type 'SAPbobsCOM.Documents'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{A6DA575B-E105-4585-9F4B-50CC4044EEDD}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

at JFDC_AddOn.EventsHandler.OnAfterClick(ItemEvent pVal) in C:\Mike\Source\JFDC_AddOn\JFDC_AddOn\EventsHandler.cs:line 179}

Here is the code I am using:


    public class EventsHandler : B1Event
    {
        public EventsHandler()
        {
        }


        // Variables for GenTransfer
        SAPbobsCOM.Documents oStockTransferThroughWhs;
        SAPbobsCOM.Documents oStockTransferDestinationWhs;
        SAPbouiCOM.Button oButton;
        SAPbouiCOM.Item oItem;
        SAPbouiCOM.EditText oEdit;
        SAPbouiCOM.Matrix oMatrix;
        SAPbouiCOM.Columns oColumns;
        SAPbouiCOM.Column oColumn;
        string POtransferButtonName = "btnTrnsPO";

        public class PORow
        {
            private string _itemCode = "";
            private string _dscription = "";
            private string _project = "";
            private string _quantity = "";
            private string _whsCode = "";

            public string ItemCode
            {
                get
                { return _itemCode; }

                set
                { _itemCode = value; }
            }

            public string Dscription
            {
                get
                { return _dscription; }

                set
                { _dscription = value; }
            }

            public string Project
            {
                get
                { return _project; }

                set
                { _project = value; }
            }

            public string Quantity
            {
                get
                { return _quantity; }

                set
                { _quantity = value; }
            }

            public string WhsCode
            {
                get
                { return _whsCode; }

                set
                { _whsCode = value; }
            }

        }


        [B1Listener(BoEventTypes.et_GOT_FOCUS, false, new string[] {
                "142"})]
        public virtual void OnGotFocus(ItemEvent pVal)
        {
            PlaceTransferButton(pVal);
        }

        [B1Listener(BoEventTypes.et_FORM_ACTIVATE, false, new string[] {
                "142"})]
        public virtual void OnAfterFormActivate(ItemEvent pVal)
        {
            PlaceTransferButton(pVal);
        }

        [B1Listener(BoEventTypes.et_CLICK, false)]
        public virtual void OnAfterClick(ItemEvent pVal)
        {
            bool ActionSuccess = pVal.ActionSuccess;
            Form form = B1Connections.theAppl.Forms.Item(pVal.FormUID);

            if ((pVal.FormType == 142) && (pVal.ItemUID == POtransferButtonName) && (pVal.Before_Action == false))
            {
                try
                {
                    SAPbouiCOM.DBDataSource dSource = form.DataSources.DBDataSources.Item("OPOR");

                    string transferFrom = dSource.GetValue("U_WhsFrom", dSource.Offset);
                    string transferTo = dSource.GetValue("U_ToWH", dSource.Offset);
                    string transferWarehouse = dSource.GetValue("U_TransfWh", dSource.Offset);

                    oMatrix = (SAPbouiCOM.Matrix)form.Items.Item("38").Specific;
                    oColumns = oMatrix.Columns;


                    // Reading from the Matrix
                    // 1: Get the index of the columns we're looking for
                    // 2: Get the value of those columns


                    int ItemCodeIndex = -1;
                    int ProjectIndex = -1;
                    int WhsCodeIndex = -1;
                    int DscriptionIndex = -1;
                    int QuantityIndex = -1;

                    for (int i = 0; i < oColumns.Count; i++)
                    {
                        try
                        {
                            if (oColumns.Item(i).DataBind.Alias.ToString() == "ItemCode")
                            { ItemCodeIndex = i; }

                            if (oColumns.Item(i).DataBind.Alias.ToString() == "Project")
                            { ProjectIndex = i; }

                            if (oColumns.Item(i).DataBind.Alias.ToString() == "WhsCode")
                            { WhsCodeIndex = i; }

                            if (oColumns.Item(i).DataBind.Alias.ToString() == "Dscription")
                            { DscriptionIndex = i; }

                            if (oColumns.Item(i).DataBind.Alias.ToString() == "Quantity")
                            { QuantityIndex = i; }
                        }
                        catch (Exception ex)
                        {
                        }
                    }

                    ArrayList PORows = new ArrayList();

                    for (int i = 1; i <= oMatrix.RowCount; i++)
                    {
                        PORow poRow = new PORow();

                        poRow.ItemCode = ((SAPbouiCOM.EditText)oMatrix.Columns.Item(ItemCodeIndex).Cells.Item(i).Specific).Value;
                        poRow.Dscription = ((SAPbouiCOM.EditText)oMatrix.Columns.Item(DscriptionIndex).Cells.Item(i).Specific).Value;
                        poRow.Project = ((SAPbouiCOM.EditText)oMatrix.Columns.Item(ProjectIndex).Cells.Item(i).Specific).Value;
                        poRow.Quantity = ((SAPbouiCOM.EditText)oMatrix.Columns.Item(QuantityIndex).Cells.Item(i).Specific).Value;
                        poRow.WhsCode = ((SAPbouiCOM.EditText)oMatrix.Columns.Item(WhsCodeIndex).Cells.Item(i).Specific).Value;

                        PORows.Add(poRow);
                    }

                    oStockTransferThroughWhs = ((SAPbobsCOM.Documents)(B1Connections.diCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oStockTransfer)));
                    oStockTransferDestinationWhs = ((SAPbobsCOM.Documents)(B1Connections.diCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oStockTransfer)));
                    
                    foreach (PORow poRow in PORows)
                    {
                        oStockTransferThroughWhs.Lines.ItemCode = poRow.ItemCode;
                        oStockTransferThroughWhs.Lines.ProjectCode = poRow.Project;
                        oStockTransferThroughWhs.Lines.Quantity = Convert.ToDouble(poRow.Quantity);
                        oStockTransferThroughWhs.Lines.WarehouseCode = transferWarehouse;

                        oStockTransferThroughWhs.Lines.Add();


                        oStockTransferDestinationWhs.Lines.ItemCode = poRow.ItemCode;
                        oStockTransferDestinationWhs.Lines.ProjectCode = poRow.Project;
                        oStockTransferDestinationWhs.Lines.Quantity = Convert.ToDouble(poRow.Quantity);
                        oStockTransferDestinationWhs.Lines.WarehouseCode = transferTo;

                        oStockTransferDestinationWhs.Lines.Add();
                    }

                    oStockTransferDestinationWhs.Add();
                    oStockTransferThroughWhs.Add();

                    B1Connections.theAppl.MessageBox("Created transfer documents", 1, "Ok", "", "");

                }
                catch (Exception ex)
                {

                }
            }
        }

        private void PlaceTransferButton(ItemEvent pVal)
        {
            Form form = B1Connections.theAppl.Forms.Item(pVal.FormUID);

            if (form.Mode == BoFormMode.fm_OK_MODE)
            {
                try
                {
                    form.Items.Add(POtransferButtonName, BoFormItemTypes.it_BUTTON);
                    oItem = form.Items.Item(POtransferButtonName);

                    oItem.LinkTo = "2";
                    oItem.Left = form.Items.Item("2").Left + 168;
                    oItem.Top = form.Items.Item("2").Top;
                    oItem.Width = form.Items.Item("2").Width + 20;
                    oItem.Height = form.Items.Item("2").Height;

                    form.DefButton = POtransferButtonName;

                    oButton = (SAPbouiCOM.Button)form.Items.Item(POtransferButtonName).Specific;
                    oButton.Caption = "Transfer PO";

                    oItem.Enabled = true;
                    oItem.Visible = true;
                }
                catch (Exception ex)
                {
                    oItem = form.Items.Item(POtransferButtonName);

                    oItem.Enabled = true;
                    oItem.Visible = true;
                }
            }
            else
            {
                try
                {
                    oItem = form.Items.Item(POtransferButtonName);
                    oItem.Enabled = false;
                    oItem.Visible = false;
                }
                catch (Exception ex)
                {

                }
            }
        }
    }

If you can please help and share insight, I would sure appreciate it.

Thank you,

Mike

Accepted Solutions (0)

Answers (2)

Answers (2)

Former Member
0 Kudos

Hi,

For some reason the code is not showing up well in the original message. I've pasted the code here, please have a look:

Link: http://pastebin.com/7NfcxG96

Thank you,

Mike

Former Member
0 Kudos

Hi Arun,

Thank you, that made the code not crash and it appears to run, though when I look at the "Inventory Transfer" in the GUI, I do not see the new StockTransfer documents that have been created.

Do you happen to know what might be wrong? Could it be that I have to do something with the batches?

And, any chance you know how I might be able to speed up the Matrix reading?

Many thanks,

Mike

former_member689126
Active Contributor
0 Kudos

Hi

i think you are not setting the stock transfer header fields properly , try this code

SAPbobsCOM.StockTransfer oStockTransfer = null;
int RetVal = 0;
long ErrCode = 0;
string ErrMsg = string.Empty;
try {
	oStockTransfer = B1Connections.diCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oStockTransfer);
	//Set the document header fields properties

                oStockTransfer.CardCode = "bp code";
                oStockTransfer.CardName = "bp name";
                oStockTransfer.DocDate = "Date"
                oStockTransfer.FromWarehouse = "From whs";
	
		//Set the document rows field properties
        //first line
		oStockTransfer.Lines.ItemCode ="Item code";
		oStockTransfer.Lines.Quantity = "Quantity";
		oStockTransfer.Lines.WarehouseCode = "To Whs";

        //second line
        oStockTransfer.Lines.Add();
	    oStockTransfer.Lines.ItemCode ="Item code";
		oStockTransfer.Lines.Quantity = "Quantity";
		oStockTransfer.Lines.WarehouseCode = "To Whs";

	}
	RetVal = oStockTransfer.Add();
	if (RetVal != 0) {
		B1Connections.diCompany.GetLastError(ErrCode, ErrMsg);
		B1Connections.theAppl.StatusBar.SetText( ErrCode.ToString() + ErrMsg);
		return false;
	}
	return true;
} catch (Exception ex) {
	throw ex;
}

and for getting the cell value try this

oEditText = oMatrix.GetCellSpecific("column", iRow)
 sValue=oEditText .value;

(where iRow is the required row) instead of oMatrix.Columns.Item(ItemCodeIndex).Cells.Item(i).Specific).Value;

Hope this helps

Regards

Arun

Former Member
0 Kudos

Hi Arun,

Thank you very much for sharing thse great examples!

I tried the code to write the stock transfer, and am getting an error that says:

"No release warehouse defined". I have a feeling it has something to do with the business logic and will look deeper into it.

The requirements have changed for the application somewhat, now instead of writing the stock transfer in an automated way, we would like to show the Stock Transfer form, which I am doing with this:

B1Connections.theAppl.ActivateMenuItem("3080");

And then we would like to populate some of the UDFs with data from the PO Form.

Do you happen to know how I can access the UDFs on the Stock Transfer? Some of the UDFs are just text fields, while others are drop downs.

Many thanks for your kind and professional help,

Mike

former_member689126
Active Contributor
0 Kudos

Hi Mike

If you are using SAP B1 8.81 you can get the UDFs like this, make sure that user defined form must be enabled (Click on the menu: "View" > "User-Defined Fields" or press "CTRL + SHIFT + U")

Dim oForm As SAPbouiCOM.Form = B1Connections.theAppl.Forms.Item(form.UDFFormUID)
 Dim oEditText As SAPbouiCOM.EditText = oForm.Items.Item("U_CardCode").Specific
 oEditText.String = "value"

also see this thread

Regards

Arun

john_obrien7
Participant
0 Kudos

Hi Mike,

Did you ever resolve the release warehouse error issue?

I am getting same issue now v9.91 pl 7.

Creating stock transfers via DI.  Some lines based on stock transfer request, some not.

Mixture of warehouses at line level.

The from and to whs is being set at line level on all lines.

Only thing I can think of is that I'm not setting the header level whs details.

When I split the data up and post the not based lines and then the based lines, all works OK.

Any help appreciated.

Thanks,

John

former_member689126
Active Contributor
0 Kudos

Hi

for your second question stock transfer declaration is not correct chnage it like this.

SAPbobsCOM.StockTransfer oStockTransferThroughWhs;

SAPbobsCOM.StockTransfer oStockTransferDestinationWhs;

Regards

Arun