Creating Purchase Invoice with API - Custom Fields

Using the documentations and researching through this forum I have managed to create invoices using the API from Power Automate. I am using the on premise server version internally so I am leveraging the O365 on premise gateway for connectivity which is working great.

This functionality is so that bills / vendor invoices can be scanned, uploaded to O365, analyzed by an AI model, and the extracted fields can be used in a POST request that creates the invoice in Manager. I found that adding attachments through the API is unsupported so my next best option was to have Power Automate pass the direct link to the scan document to a custom field I created. I have been unsuccessful to get this to work in any way.

Appreciate the help, if you need any other information from me let me know.

Here is an example of the body of my post request.
{
“IssueDate”: “2024-12-14”,
“Reference”: “INV-455”,
“description”: “Name of Company”,
“Supplier”: “980b0296-4f4c-4e70-98b2-5766a21160dd”,
“Lines”: [
{
“account”: “d9e9ae6b-56e2-4056-9499-321a4dc6813a”,
“Item”: “6fe116be-331e-4b1e-9436-aa584d9c5634”,
“Qty”: 1,
“PurchaseUnitPrice”: 589.88,
“Division”: “9f82cb63-ebbc-4d1f-b384-fc2d51eb15a8”
}
],
“CustomFields”: {
“b60442bb-870a-4a98-b2ba-1ea1a164426e”: “URLHERE”
},
“balanceDue”: {
“value”: 589.88,
“currency”: “USD”
},
“status”: “ComingDue”
}

Here’s an example of using CustomFields2 Dictionary in json.

{
  "IssueDate": "2024-12-14",
  "Reference": "0001-0001",
  "Customer": "4ca6b624-c371-4269-aa69-91010d9f4b06",
  "Lines": [
    {
      "Item": "a9c5d199-576c-48e9-b88e-adc8a6728ac2",
      "LineDescription": "Item with VAT 15% Rate",
      "CustomFields2": {
        "Strings": {
          "329de867-9cf1-4dfe-8b06-5084bce788c7": "00002222"
        }
      },
      "Qty": 1,
      "SalesUnitPrice": 100,
      "TaxCode": "d45ffe42-182a-4920-a5c6-dd2fd983794a"
    }
  ],
  "HasSalesInvoiceCustomTheme": true,
  "SalesInvoiceCustomTheme": "f43edcbb-2448-4890-bbd2-18f87fdbad13",
  "ShowTaxAmountColumn": true,
  "HasRelay": true,
  "Relay": "https://localhost:7235/relay",
  "CustomFields2": {
    "Strings": {
      "5b3ebf5f-ad4f-4ffc-84d1-abda67a7d294": "0 | Cash",
      "fc6f05f9-50c7-46c0-b9f5-7fe0ca83cf2a": "APPROVED",
      "39b3d219-a386-4d9f-b3a0-55968b4bc7b7": "2024-12-14 21:19:00",
      "75190339-992a-4fb0-bf79-f5f8226edb4b": "{\r\n  \"ApprovalStatus\": \"APPROVED\",\r\n  \"ReceiptHash\": \"ltDgwubEfbohivvdZxICPumYfSZv/lz0kwtwtSCAOdw=\",\r\n  \"ReceiptSignature\": \"KWWY+aQXFNAprUkGCNp4i41wDs7mFpC/wG+4I0OlF9tgDq56AlSpCPFZL6O5EuS6kOuRLzrt6tQNiIrbTk/7zxhoA3NuP1eVSp3mWWtQYakzVsg7AxTDs9PGTiDakch+V1aMVDm2pffn2jbIkH0So4KKfen0jD65PpE+QjBQPE0cBURyA9e9La1HmO9g9X4gRcwibOCy7ljqP5J39nVUw72Cujjoc2nvLFdcdQm5LL+zb3UKN6g5aIg60LRQ7EcNNVIE8C5yio9kJUtFmp7oyhZ3BqS4PxpG/K0eJXvtdIYXpr8aObsM8l5lHkTVoTy3qzKueAivbSgoa1WoF6BjKA==\",\r\n  \"SubmitReceiptResponse\": {\r\n    \"operationID\": \"0HN8SD02S538A:00000001\",\r\n    \"receiptID\": 5125452,\r\n    \"serverDate\": \"2024-12-14T21:19:19\",\r\n    \"receiptServerSignature\": {\r\n      \"hash\": \"4JzjTa3AQgL0rXtFer0u1j+pnsQdhuwJg6Dhsc3Gbg8=\",\r\n      \"signature\": \"OrIEzux+mKamTDJqaIich4WqEzTQc0MfxjGcRnH5qAB0KJ6whwn6KqDK7Ad/oP+dA445E/1ZKLud5O5tfJYoTSwi0Wi5lQjf/G5X5FYgdwobpHPipDunYEr4itjQqBUA11VyZhL5uX17owPl3dkkja3hQFRsZOfhDT4decTz6SNDYBKJFvI+ZXGrTFhEwz1bIeNKQliOGiaaUmFt8ya0tUHX4gSIlcGsuE5ISw8LOrI6yj8V0BYCsWpyYsiUhClYcFin/t+ykwI+BKPUcxUN5aRphVueYWiDWBO4M4lNu19CafeZvg82arX9mjR6gKO0XUFE5/TO5gv86Qw1gKJTLQ==\",\r\n      \"certificateThumbprint\": \"F9B295CA65BA22B94F6D4B27E48D08BF6CD7F7C8\"\r\n    },\r\n    \"validationErrors\": []\r\n  }\r\n}",
      "7eaadfa6-1fb9-4dce-9a1c-9d74beb1d0f7": "https://fdmstest.zimra.co.zw/0000020568141220240000000001777A40D032440E70",
      "a0454495-cae8-43ef-a418-4dad69427e78": "777A-40D0-3244-0E70",
      "a360538c-ebe9-49e9-8cf8-fccd51320380": "MGR-20241203"
    },
    "Decimals": {
      "e2ab11ef-73e2-4ea4-802f-55b8c834037d": 115,
      "d08c8744-486f-470d-82d1-29b1a1cb06ae": 20568,
      "c6e40e7a-974e-4ffc-9c76-1c1ecfd05693": 1,
      "4712e5df-c5e3-4b6e-9746-8ebb58a81dee": 1,
      "a9867045-740b-493f-8b67-43b6da07e41e": 1
    }
  }
}
2 Likes

You can do it on two stages, but you will have to know the URL of the invoice you just posted.

Unfortunately, this requires you to manually get the URL which defeats the entire purpose of your automation.

Alternatively, you can embed images files directly inside your object

2 Likes

Thanks for your response. So at this point there is no way to modify custom fields from the API for purchase invoices?
Can you provide any more detail on how to use the API to embed image files inside the object?

1 Like

My post was aimed at your first option which is to attach files.

As for custom field, there is a way as described by @Mabaega in the deleted post that I just restored.

First you will have to change CustomFields to CustomFields2, then you will have to specify the subtype (i.e. Strings, Decimals, etc)

@Mabaega I hope you’re OK with me restoring your post. :slight_smile:

2 Likes

This is fantastic, thank you very much. I figured there were a couple changes with API2 and custom fields, this explains it!

I am still a bit interested in the attaching images if you can provide any more details on how I could do that?

I am using desktop version of manager & having a powershell script to fetch inventory data which is working fine for standard fields. I also want to import custom fields data from the same script. Please check the script & suggest endpoints for custom fields.
Landed Cost (77e2d6f5-8526-4e57-b20a-cbf5be61af57)
MRP (2b48a958-a252-4d1c-87dc-31f1963bf0b3)

Script:

$headers = @{
“accept” = “application/json”
“X-API-KEY” = “Cg5BYmhpZG55YSBUb29scxISCfJHllTll3JJEZWiD8+f2SrRGhIJSkoZe8asdUIRpn4VDeto7yw=”
}

$endpoint = “http://localhost:51857/api2/inventory-items?pageSize=1000&fields=ItemName&fields=PurchasePrice&fields=SalePrice&fields=QtyOwned&fields=TotalCost&fields=UnitName

$response = Invoke-RestMethod -Uri $endpoint -Method Get -Headers $headers

$headerMapping = @{
“key” = “Item_ID”
“ItemName” = “Item name”
“QtyOwned” = “Qty owned”
“PurchasePrice.value” = “Purchase price”
“SalePrice.value” = “Sale price”
“TotalCost.value” = “Total cost”
“UnitName” = “UOM”

}

$desiredHeaders = @(“Key”, “ItemName”, “QtyOwned”, “PurchasePrice.value”, “SalePrice.value”, “TotalCost.value”, “UnitName” )

$filteredData = $response.inventoryItems | ForEach-Object {
$filteredObject = New-Object PSObject
foreach ($header in $desiredHeaders) {
if ($header -match ‘.’) {
# Handle nested properties
$headerParts = $header -split ‘.’
$value = $_
foreach ($part in $headerParts) {
if ($value -ne $null) {
$value = $value.$part
}
}
# Add the property to the new object with custom header name
$customHeaderName = $headerMapping[$header]
$filteredObject | Add-Member -MemberType NoteProperty -Name $customHeaderName -Value $value
} else {
# Direct properties
$value = $_.$header
$customHeaderName = $headerMapping[$header]
$filteredObject | Add-Member -MemberType NoteProperty -Name $customHeaderName -Value $value
}
}
$filteredObject
}

$filteredData | Export-Csv -Path “K:\My Drive\appsheet\Manager API\AT_Manager API\AT_inventory.csv” -NoTypeInformation -Encoding UTF8 -Force

@virtuos

Try this

$apiKey = "CgpNR1ItMjQxMjk5EhIJ2U2XgRWTtE8RhWaeptM81pAaEgm9hQ1AS7MDRxG1fD2pqyc7WQ=="
$baseUrl = "http://127.0.0.1:55667/api2"

# Get all inventory items
$inventoryResponse = Invoke-RestMethod -Uri "$baseUrl/inventory-items?fields=Image" -Method Get -Headers @{
    "X-API-KEY" = $apiKey
    "accept" = "application/json"
}


# Process each item
foreach ($item in $inventoryResponse.inventoryItems) {
    $itemKey = $item.key
    
    # Get detailed information for each item
    $itemDetail = Invoke-RestMethod -Uri "$baseUrl/inventory-item-form/$itemKey" -Method Get -Headers @{
        "X-API-KEY" = $apiKey
        "accept" = "*/*"
    }
    
    Write-Host "`nKey: $($itemDetail.Key)"
    Write-Host "Item Name: $($itemDetail.ItemName)"
    
    # Process custom fields if they exist
    if ($itemDetail.CustomFields2.Strings) {
        Write-Host "Custom Fields:"
        $itemDetail.CustomFields2.Strings.PSObject.Properties | ForEach-Object {
            Write-Host "  $($_.Name): $($_.Value)"
        }
    }
}

1 Like

@Mabaega Thanks a lot… it worked…