cancel
Showing results for 
Search instead for 
Did you mean: 

Make Invoice from draft

Former Member
0 Kudos

Hello,

We make draft invoices via an addon. The customer checks the invoices and correct them if needed.

Is there an easy way to make an invoice of these draft via the SDK ?

(Like in SBO, you open the concept and just save it)

Are do you have to recreate the invoice document.

You can't link the .baseentry to the draft document,

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi ,

You have to recreate the document and there is to my knowledge no easy way to create the invoice from the draft using the DI API. I have a similar process in an add-on and set every property of the invoice one by one from the draft.

Hope it helps,

Adele

Former Member
0 Kudos

Hi Adele, I also try to copy this 1 by 1 as the Xml route doesn't work for me (some document types have xml errors when I recreate).

However the copying way is also difficult because an exception is thrown if the field isn't populated, and I can't check to see if the field is null before I attempt the copy...

Do you have the code handy that you use?

Former Member
0 Kudos

Hi Daniel,

I only use specific fields and know that they are not null when I populate them. Sorry for not being a great help on this.

Adele

Former Member
0 Kudos

Thanks anyway Adele, I appreciate all your posts and quick responses!

Answers (8)

Answers (8)

Former Member
0 Kudos

It seems there is no easy way to copy a draft to a real doc.

And the DRQ have been rejected ...

Former Member
0 Kudos

Hi Francis,

before the last word is spoken, try the following code. I was able to turn a Draft into an Invoice via XML. The trick is to specify a document owner...



// Confirm all draft invoices...

private void ConfermaBozza()
        {

            int empID = 1;

            XmlDocument x = new XmlDocument();

            SAPbobsCOM.Recordset rs_emp = (SAPbobsCOM.Recordset) B1Company.GetBusinessObject(SAPbobsCOM.BoObjectTypes.BoRecordset);

            rs_emp.DoQuery("SELECT empID FROM OHEM");
            
            if (!rs_emp.EoF)
                empID = (int) rs_emp.Fields.Item("empID").Value;

            SAPbobsCOM.Recordset rs = (SAPbobsCOM.Recordset)B1Company.GetBusinessObject(SAPbobsCOM.BoObjectTypes.BoRecordset);

            rs.DoQuery("SELECT DocEntry FROM ODRF WHERE ObjType='13' AND DocStatus <> 'C'");

            SAPbouiCOM.ProgressBar pb = B1App.StatusBar.CreateProgressBar("Applicazione spese a tutti i documenti in bozza", rs.RecordCount, false);
            
            int i = 1;

            while (!rs.EoF)
            {

                pb.Value = i++;
                
                try
                {

                    SAPbobsCOM.Documents docs = (SAPbobsCOM.Documents)B1Company.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oDrafts);

                    if (docs.GetByKey((int)rs.Fields.Item(0).Value))
                    {
                    
                        string filename = "bozza.xml";

                        docs.SaveXML(ref filename);

                        // Trasformazione della bozza
                        x.Load(filename);

                        XmlNode n = x.DocumentElement;

                        n = n.FirstChild;
                        n = n.FirstChild;
                        n = n.FirstChild;

                        n.InnerText = "13";

                        
                        
                        x.InnerXml = x.InnerXml.Replace("DRF", "INV");
                        x.InnerXml = x.InnerXml.Replace("<OwnerCode>0</OwnerCode>", "");


                        x.Save(filename);

                        SAPbobsCOM.Documents fattura = (SAPbobsCOM.Documents)B1Company.GetBusinessObjectFromXML(filename, 0);

                        

                        fattura.DocumentsOwner = empID;
                                               
                        if (fattura.Add() != 0)
                        {
                            int err;
                            string msg;

                            B1Company.GetLastError(out err, out msg);
                            B1App.MessageBox(msg, 0, "OK", "", "");
                        }

                    }
                }
                catch (Exception e)
                {
                    B1App.MessageBox(e.Message, 0, "OK", "", "");
                    break;
                }

                rs.MoveNext();
            
            }


            pb.Stop();
            System.Runtime.InteropServices.Marshal.ReleaseComObject(pb);

        }

Hope this will help anybody stuck with this issue...

Former Member
0 Kudos

Hi Daniel,

- Using the xmlfile to copy draft to an invoice, isn't a good solution. If it works to copy the draft to the invoice, some field(s) will not be taken over correctly.

(f.e. Quantity)

Sometimes you get an error when you create the invoice via xml. A solution for this is to remove one (or more) items in the xml. (I made a small sample and had to remove the Linetotal before I could save the Invoice)

- Error empty field.

I also had a problem when copying usersfields from one to another object. This is when the field has validvalues. In the case your From-object UDF value is empty, you may not set the To-object with that value. You hav to skip it.

Message was edited by: Francis Ide

Former Member
0 Kudos

I allready did that because you mentioned it before.

Still thanks for the tip.

It saves a lot of programming work.

Former Member
0 Kudos

Trinidad,

It looked OK, but then again I checked the invoice again that were created from the draft.

The Quantity for every line is reset to 1, and a negative discount is added to become the correct invoice total.

Please help !

Former Member
0 Kudos

Trinidad,

Thanks for the quick reply.

I thought I had to change the Doctype

in the AdmInfo of the XML file.

I changed it from 112 to 13, then when I added the document, I still got an error invalid Column.

I removed the DocObjectCode element from the xml file

and know it seems to work.

Thanks

Trinidad
Product and Topic Expert
Product and Topic Expert
0 Kudos

Francis,

You must also remove the DocNum element to have the document number automatically asigned.

Regards

Trinidad.

Former Member
0 Kudos

Hi Trinidad,

I am trying to use the Xml copy way, but for some document types when I create the object I get an Xml error?

Do you have some code that you could post that shows how this is supposed to work: Currently this is what i use:


private void CopyDocByXml(SAPbobsCOM.Documents draft, SAPbobsCOM.Documents doc)
{
	/* format file names as "Date_Time_DraftDocEntry_ObjectCode.xml" */
	string fileName = this._xmlFilePath + DateTime.Now.ToString("yyyyMMdd_hhmmss_") + draft.DocEntry.ToString() + "_" + draft.DocObjectCodeEx + ".xml";
	draft.SaveXML(ref fileName);

	/* Open the xml and modify so that we can save as the proper document type */
	XmlDocument xml = new XmlDocument();
	xml.Load(fileName);

	/* put the <DocObjectCode> value into the <object> value in the xml */
	string objType = xml.SelectSingleNode("BOM/BO/Documents/row/DocObjectCode").InnerText;
	xml.SelectSingleNode("BOM/BO/AdmInfo/Object").InnerText = objType;

	/* remove the <DocObjectCode> element as the doc won't load as a valid doc with it */
	XmlNode node = xml.SelectSingleNode("BOM/BO/Documents/row/DocObjectCode");
	xml.SelectSingleNode("BOM/BO/Documents/row").RemoveChild(node);
			
	/* remove the <DocNum> value from the xml so a new one gets assigned when it is saved */
	xml.SelectSingleNode("BOM/BO/Documents/row/DocNum").InnerText = "";

	xml.Save(fileName);

	/* load the saved xml as a new doc for saving into SAP */
	doc = (SAPbobsCOM.Documents)SboCompany.GetBusinessObjectFromXML(fileName, 0);
}

Dan

Former Member
0 Kudos

Trinidad,

Have you already done this ?

I just get another draft document when I try it the xml way.

An abstract of my code :

Dim oDraft As SAPbobsCOM.Documents

Dim oNewdoc As SAPbobsCOM.Documents

oDraft = CType(SBO_Company.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oDrafts), SAPbobsCOM.Documents)

oDraft.GetByKey(1)

oDraft.SaveXML(strTempFile)

oNewdoc = CType(SBO_Company.GetBusinessObjectFromXML(strTempFile, 0), SAPbobsCOM.Documents)

oNewdoc.DocNum = 0

intRetVal = oNewdoc.Add

Any idea how I can resolve this ?

Trinidad
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Francis,

You need to modify the document after saving it as a Draft and change at least the type of the document in the xml file (to the real type of the document you want to create ).

If you only save it as xml and the reaload it without changing anything you are recreating the same draft document. It is normal.

Hope it helps

Trinidad.

Former Member
0 Kudos

Trinidad,

Thanks for the proposition, this might be a good solution for my problem.

This will also work correctly when new fields become available via a patch/new version.

Former Member
0 Kudos

You're right, It will probably flicker and it's not the best solution.

I made a message to SAP for a DRQ, and hope

that in version 2008 a method will added.

Trinidad
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Francis,

The best way to create an Invoice from a Draft is to use Xml. You can easily save your Draft as Xml and after that create with the same Xml file (you have to remove DocNum) you can create the Invoice document.

Hope it helps

Trinidad.

Former Member
0 Kudos

Thanks for the DRQ, I'm sure we'll all benefit from it

Former Member
0 Kudos

Thanks,

It was not what I wanted to hear, but I was afraid that this was going to be the answer.

I think I first will try to do it via the UI API.

Open the document, fill in the number, and generate a click event on the save button.

Former Member
0 Kudos

Hi Francis,

That can also work, but with my solution I create hundreds of these documents and using the UI API was not a solution as the user will see this flickering on the screen.

Hope you get it right!

Adele