Link to home
Start Free TrialLog in
Avatar of Murray Brown
Murray BrownFlag for United Kingdom of Great Britain and Northern Ireland

asked on

VB.net Xero - Creating Invoice with one code patch vs another

Hi
I manged to get a test invoice created in Xero with the first patch of code below
I now want to change the second patch of code to be one loop just like the first so that it is easier to understand

    Protected Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        Dim myxeroapi As XeroCoreApi
        myxeroapi = TryCast(Session("myxeroapi"), XeroCoreApi)
        oCreateInvoice2(myxeroapi)
    End Sub


    Sub oCreateInvoice2(ByVal myxeroapi As XeroCoreApi)

        Dim oEx As String

        'Dim ITracking As ItemTracking

        Try
            '======== Reader Code ==========

            'Invoice header
            Dim oInvoiceNumber As String
            Dim oContactName As String
            Dim oPayableReceivable As String
            Dim oInvoiceDate, oDueDate As String
            Dim oTaxInclusiveExclusive As String
            Dim oReference As String

            'Line items
            Dim oItemCode, oDescription, oQuantity As String
            Dim oUnitAmount, oTaxType, oDiscountRate As String
            Dim oAccountCode, oTrackingCategoryName, oTrackingCategoryOption As String

            'Create the invoice
            Dim invoice As New Invoice

            Dim pContact As New Xero.Api.Core.Model.Contact
            pContact.Name = "Test Company"

            'Create the list of lineitems to add to the invoice
            Dim LineItems As New List(Of LineItem)

            Try

                '// open the connection
                'cn.Open()

                '// execute the sql statement
                'Using reader As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)

                'While reader.Read()

                'Header...

                oContactName = "Test Company"
                oPayableReceivable = ""
                oInvoiceDate = "25 July 2019"
                oDueDate = "25 Aug 2019"
                oTaxInclusiveExclusive = ""
                oReference = "Test Ref"

                'Lines...
                oItemCode = "656"
                oDescription = "Test Desc"
                oQuantity = 5
                oUnitAmount = 25
                oTaxType = ""
                oDiscountRate = ""
                oAccountCode = "201"
                oTrackingCategoryName = "Shaft"
                oTrackingCategoryOption = "joel air"

                'Only gather invoice header data if there is an invoice number there
                oInvoiceNumber = 1 'Just beause we need a number
                If Len(oInvoiceNumber) > 0 Then

                    '...and fill in it's properties
                    With invoice

                        'Might want to leave out invoice number so it autogenerates
                        '.Number = oInvoiceNumber

                        .Contact = pContact
                        .Status = Xero.Api.Core.Model.Status.InvoiceStatus.Draft '**IMPORTANT

                        If oPayableReceivable = "Payable" Then
                            .Type = Types.InvoiceType.AccountsPayable
                        Else
                            .Type = Types.InvoiceType.AccountsReceivable
                        End If

                        If IsDate(oInvoiceDate) = True Then
                            .Date = oInvoiceDate
                        Else
                            .Date = Now
                        End If

                        If IsDate(oDueDate) = True Then
                            .DueDate = oDueDate
                        Else
                            If IsDate(oInvoiceDate) = True Then
                                .DueDate = CDate(oInvoiceDate).AddMonths(1)
                            Else
                                .DueDate = Now.AddMonths(1)
                            End If
                        End If


                        'Following is tax inclusive https://developer.xero.com/documentation/api-guides/tax-in-xero
                        '(1) Inclusive, (2) Exclusive, (3) NoTax
                        '** Invoices will be TaxExclusive by default if LineAmountTypes isn’t specified
                        'IN SA CASE THE AMOUNTS ARE TAX INCLUSIVE
                        If oTaxInclusiveExclusive = "Exclusive" Then
                            .LineAmountTypes = Xero.Api.Core.Model.Types.LineAmountType.Exclusive
                        ElseIf oTaxInclusiveExclusive = "No Tax" Then
                            .LineAmountTypes = Xero.Api.Core.Model.Types.LineAmountType.NoTax
                        Else
                            .LineAmountTypes = Xero.Api.Core.Model.Types.LineAmountType.Inclusive
                        End If

                        If Len(oReference) > 0 Then
                            .Reference = oReference
                        End If

                        .Reference = "Test Ref"
                        '*** ----- Optional -------
                        '.ExpectedPaymentDate = Now.AddDays(90) 'Optional
                        '.CurrencyCode = "USD"
                        '.BrandingThemeId = New Guid("4c82c365-35cb-467f-bb11-dce1f2f2f67c")
                        '.TotalTax = "10.89"
                        '.SubTotal = "87.11"
                        '.Total = "98.0"

                    End With

                End If


                'This section should be repeated for multiple items...
                'in this example we just add another lineitem for simplicity
                Dim pLineItem As New LineItem
                With pLineItem
                    .ItemCode = oItemCode 'eg "0026" 'Must be a valid code
                    .Description = oDescription 'eg "AX DRILLING 2 - 100 METERS"
                    .Quantity = oQuantity 'eg 20
                    .UnitAmount = oUnitAmount 'eg "1234.56"
                    If oTaxType = "" Then 'Won't specify most of the time
                        'If TaxType Then isn't specified then Xero will use the default
                        'tax Rate on the Chart of Accounts account that the line item Is coded to 
                        '(All other defaults such as from Contacts or Inventory Items are disregarded.)
                        'https://developer.xero.com/documentation/api-guides/tax-in-xero
                    Else
                        .TaxType = oTaxType 'eg "OUTPUT2"
                    End If
                    If IsNumeric(oDiscountRate) = True Then
                        .DiscountRate = oDiscountRate 'eg "16"
                    End If

                    .AccountCode = oAccountCode 'eg "201"
                    Dim itc As New ItemTrackingCategory
                    '** Note do not need the item tracking category id
                    'itc.Id = New Guid("7a434b76-7927-4c56-b0ca-ee1afe6d4c84")
                    itc.Name = oTrackingCategoryName 'eg "Shaft"
                    itc.Option = oTrackingCategoryOption
                    .Tracking = New ItemTracking
                    .Tracking.Add(itc)
                End With

                LineItems.Add(pLineItem)

                invoice.LineItems = LineItems

                'End While

                ' End Using


            Catch ex As Exception

                Response.Write(ex.Message & " x44")

            Finally

            End Try

            'and submit it to the Xero API
            myxeroapi.Create(invoice)

            Dim oMsg As String = "Invoice created successfully"
            ClientScript.RegisterClientScriptBlock([GetType](), "alert", "alert('" & oMsg & "');", True)

        Catch ex As Exception
            oEx = ex.Message
            Response.Write("Error. Invoice not created " & oEx)
        End Try

    End Sub

Open in new window


   
 Private Async Sub BtnCreateInvoice_Click(sender As Object, e As RibbonControlEventArgs) Handles btnCreateInvoice.Click

        Dim helper = ExcelHelper.GetInstance
        Dim data = ExcelHelper.GetData(Of ExcelInvoice)
        Dim result = Await ExcelHelper.CreateInvoices(data, _tracking1, _tracking2)
        Dim xeroResult = Await _xero.SetInvoice(cbCompanies.SelectedItem.Tag, result)
 End Sub

Imports System.ComponentModel.DataAnnotations
Imports System.Threading.Tasks
Imports Microsoft.Office.Interop.Excel
Imports Xero.NetStandard.OAuth2.Model.Accounting

Public Class ExcelHelper
    Private Shared _excelHelper As ExcelHelper

    Public Shared Function GetInstance() As ExcelHelper

        If _excelHelper Is Nothing Then
            _excelHelper = New ExcelHelper()
        End If
        Return _excelHelper
    End Function

    Public Shared Sub PopulateSheet(ByRef data As IEnumerable(Of IValidatableObject))
        Dim ws As Worksheet = Globals.ThisAddIn.Application.ActiveSheet
        Dim col = 1
        Dim row = 1
        Dim properties = data.GetType.GetGenericArguments()(0).GetProperties.ToList
        properties.ForEach(Sub(prop)
                               ws.Cells(row, col) = prop.Name
                               col += 1
                           End Sub)
        row += 1
        col = 1
        data.ToList.ForEach(Sub(account)
                                properties.ForEach(Sub(prop)
                                                       Dim value = prop.GetValue(account)
                                                       If value IsNot Nothing Then
                                                           ws.Cells(row, col) = value.ToString
                                                       End If
                                                       col += 1
                                                   End Sub)
                                row += 1
                                col = 1
                            End Sub)
    End Sub

    Public Shared Function GetData(Of T As New)() As IEnumerable(Of T)
        Dim range As Range = Globals.ThisAddIn.Application.Selection
        Dim rows = range.Rows.Count
        Dim cols = range.Columns.Count
        Dim data = New List(Of T)
        For rowIndex = 2 To rows
            Dim item = New T
            For colIndex = 1 To cols
                Dim cellValue = range(rowIndex, colIndex).Value
                Dim colName = range(1, colIndex).Value
                Dim prop = item.GetType.GetProperty(colName.ToString)
                If (cellValue IsNot Nothing) Then
                    Select Case prop.PropertyType
                        Case GetType(String)
                            prop.SetValue(item, cellValue.ToString)
                        Case GetType(Int32)
                            prop.SetValue(item, Int32.Parse(cellValue))
                        Case GetType(Decimal)
                            prop.SetValue(item, Decimal.Parse(cellValue))
                    End Select
                End If
            Next
            data.Add(item)
        Next
        Return data
    End Function

    Public Shared Function CreateInvoices(invoices As List(Of ExcelInvoice), tracking1 As String, tracking2 As String) _
        As Task(Of Invoices)
        Dim xeroInvoices = New Invoices With {._Invoices = New List(Of Invoice)}
        Dim xeroInvoice As Invoice
        invoices.OrderBy(Function(invoice)
                             Return invoice.Number
                         End Function).ToList.ForEach(Sub(einv)
                                                          If xeroInvoice Is Nothing Then
                                                              xeroInvoice = New Invoice _
                                                                                      With {.InvoiceNumber = einv.Number, .[Date] = DateTime.UtcNow,
                                                                                      .DueDate = DateTime.UtcNow,
                                                                                      .Reference = einv.Reference,
                                                                                      .LineAmountTypes = IIf(einv.TaxCode.Equals("NONE"), LineAmountTypes.NoTax, LineAmountTypes.Inclusive),
                                                                                      .Contact =
                                                                                      New Contact() With {.Name = einv.Contact, .AccountNumber = einv.Contact},
                                                                                      .Type = Invoice.TypeEnum.ACCREC,
                                                                                      .Status = Invoice.StatusEnum.DRAFT,
                                                                                      .LineItems = New List(Of LineItem)}

                                                          ElseIf Not xeroInvoice.InvoiceNumber.Equals(einv.Number) Then
                                                              xeroInvoices._Invoices.Add(xeroInvoice)
                                                              xeroInvoice = New Invoice _
                                                         With {.InvoiceNumber = einv.Number, .[Date] = DateTime.UtcNow,
                                                         .DueDate = DateTime.UtcNow,
                                                         .Reference = einv.Reference,
                                                         .Status = Invoice.StatusEnum.DRAFT,
                                                         .Type = Invoice.TypeEnum.ACCREC,
                                                         .LineAmountTypes = IIf(einv.TaxCode.Equals("NONE"), LineAmountTypes.NoTax, LineAmountTypes.Inclusive),
                                                         .Contact =
                                                         New Contact() With {.Name = einv.Contact, .AccountNumber = einv.Contact},
                                                         .LineItems = New List(Of LineItem)}
                                                          End If
                                                          Dim item = New LineItem() With {.Description = einv.LineDescription, .LineAmount = einv.LineAmount,
                                     .Quantity = einv.LineQuantity, .TaxType = einv.TaxCode, .Tracking = New List(Of LineItemTracking)}
                                                          item.Tracking.Add(New LineItemTracking() With {.Name = tracking1, .[Option] = einv.Tracking1})
                                                          item.Tracking.Add(New LineItemTracking() With {.Name = tracking2, .[Option] = einv.Tracking2})
                                                          xeroInvoice.LineItems.Add(item)
                                                      End Sub)
        If (xeroInvoice IsNot Nothing) Then
            xeroInvoices._Invoices.Add(xeroInvoice)
        End If
        Return Task.FromResult(xeroInvoices)
    End Function
End Class





Open in new window

ASKER CERTIFIED SOLUTION
Avatar of ste5an
ste5an
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Murray Brown

ASKER

Maybe I should rephrase part of this. I don't understand the first piece of code. Is there a way to simplify it so that it is a little easier to read

I realised that I had missed quite a bit out so am going to change the code in the original question


Thanks I saw that I can only accept one answer. Thanks for the input Rob