Application Programming Interface forums

0 Abonnenten

3 Themen

4939 Gespräche

Area for questions and answers about SuperOffice API's.

push_pin lock

how to get value of user-defined list item per crm script

Hi,   in SO Windows with vbscripts by Trigger Sales beforeSave, I can get value of user-defined list item: division = objSO.GetListItem(currentSale.Udef.ByProgId("SuperOffice:1").ListTableId, division).Text   but in SO CLoud or SO Web with crm script, with this i get ID of List item back: devision = ed.getInputValue("SaleEntity.UserDefinedFields.SuperOffice:1"); Is there way to get its ListItem Value back, only with SearchEngine?   Thanks!
Jianchun You
2
8
11. März 2020 | 12:00 AM
Thema:
Online development and web service API's

Letzte Antworten

Answer to Ummairs question: https://community.superoffice.com/en/technical/forums/api-forums/service-crmscript/get-listitem-by-listid/
by Tony Yates
6 h, 39 m vor | 11:38 AM
push_pin lock

Get listitem by listId

Hello.  When it comes to defining udef in Sales with respect to lists there are 2 ways. 1. Creating a user defined field and assign a standard list to it.  2. Creating a user defined field and assign a user defined list to it.  I have problems with getting the item value from a standard list.  In the table UDefField the only reference to a standard list table is the field listTableId as far as I can see. If I have defined a userdefined field that points to one of the standard entities (ie, associate, sale stage, project status) and get a the item value id, how can I then fetch the item value if the only lookup field I have is the listTableId ? https://docs.superoffice.com/en/database/tables/udeffield.html I can see there are functions agent.GetListIdByListName("name") and NSMDOListItem item = agent.GetListItem("listname", itemId) but I cannot see a way to get listitem when I only have the listTableId
Ummair Tahir
2
1
18. Mai 2025 | 02:04 PM
Thema:
Service and CRMScript Discussion

Letzte Antworten

Hi Ummair, There are a couple variations, but generally use the MDOAgent to get all lists, and then from that get all list items or one particular list item. Something like this should get you started. NSMDOAgent mdoAgent; Integer listId = 2; Integer listItemId = 5; NSMDOListItem GetMDOListByListId(Integer listId) { NSMDOListItem[] lists = mdoAgent.GetList("lists", true, "", false); foreach(NSMDOListItem item in lists) { if(item.GetId() == listId) { return item; } } throw "List Not Found"; } NSMDOListItem[] GetMDOListItemsByListId(Integer listId) { NSMDOListItem list = GetMDOListByListId(listId); String listName = list.GetType(); return mdoAgent.GetList(listName, true, "", false); } NSMDOListItem GetMDOListItemById(Integer listId, Integer listItemId) { NSMDOListItem list = GetMDOListByListId(listId); String listName = list.GetType(); NSMDOListItem item = mdoAgent.GetListItem(listName, listItemId); return item; } NSMDOListItem list = GetMDOListByListId(listId); printLine("Found list: " + list.GetId().toString() + ": " + list.GetType()); //--------------------------------------------------------------------------------------------------------------- NSMDOListItem itemItem = GetMDOListItemById(list.GetId(), listItemId); printLine("Found item: " + itemItem.GetId().toString() + ": " + itemItem.GetName()); printLine("---------------------------"); NSMDOListItem[] listItems = GetMDOListItemsByListId(list.GetId()); foreach(NSMDOListItem item in listItems) printLine("Found list item: " + item.GetId().toString() + ": " + item.GetName()); printLine("done"); Hope this helps!
by Tony Yates
6 h, 41 m vor | 11:37 AM
push_pin lock

self-defined List Display

Hi, We have Service old Mode for several years and now want to update to new Mode to get AI-based Function, but we have Problems to re-define the Filter, Sort, More Fields to display a List in new Service Mode in Screen Designer. Case 1: We have filtered Project-List related to Tickets. To solve that, in "Screen" of old Service Mode we have defined the Filter for the Projects which Status is open. and display second udf to help User to select correct Project. Here is the filtered Project List, and this works fine: Case 2: We have 2nd List to Ticket based on our Custom Object "Cost Center" with ExtraTable, the "Cost Center" has boolean Field "disabled", the List should be displayed with all enabled Entries to Tickets. Both case we have good solved in old Mode but there is no alternative in new Service Mode. Due to this, we are now disadvantaged to update AI-Function for our Ticketsystem becase SuperOffice do no more Updates to Service old Mode.  
Jianchun You
1
4
16. Mai 2025 | 12:54 PM
Thema:
Service and CRMScript Discussion

Letzte Antworten

I Think SuperOffice has already good Solution in Screen in old Service Mode by self, this can be moved in new Service Mode to display a List in Screen Designer.
by Jianchun You
16. Mai 2025 | 01:31 PM
push_pin lock

CRMScript HTTP call to Azure Function returns empty response (works in Postman and C#)

Hi everyone, I'm currently trying to make a GET request from CRMScript to an Azure Function endpoint ( *.azurewebsites.net ). The call works perfectly when I test it using Postman and with a simple C# console app. However, when I try it using CRMScript , the response is empty . What I'm doing The function expects a requestid to be sent in the body. Headers include  Accept: application/json and a x-functions-key . I've tried both GET and POST methods in CRMScript. JSONBuilder payload; payload.pushObject(""); payload.addString("requestid", "example-request-id-1234"); //I get the requestid from the first function which also is a request to azurewebsites. payload.popLevel(); printLine(payload.getString()); HTTP httpClient; httpClient.addHeader("Accept", "application/json"); httpClient.addHeader("Content-Type", "application/json; charset=utf-8"); httpClient.addHeader("x-functions-key", "example-functions-key"); httpClient.setOption("parameters", "?" + payload.getString()); String response = String(httpClient.post("https://example-function.azurewebsites.net/api/MyFunctionEndpoint")); printLine("Response: " + response); But response is always empty. 🔹 How it works correctly in C# (for comparison) Here’s a minimal C# example that works correctly: static async Task Main(string[] args) { var client = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Get, "https://example-function.azurewebsites.net/api/MyFunctionEndpoint"); request.Headers.Add("Accept", "application/json"); request.Headers.Add("x-functions-key", "example-functions-key"); var content = new StringContent("{ \"requestid\": \"example-request-id-1234\" }", null, "application/json"); request.Content = content; var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); Console.WriteLine(await response.Content.ReadAsStringAsync()); }   What am I doing wrong here ? Just to add little preface. I'm trying first to trigger an azure job with crmscript, this works fine and then i use the request id from the response in trigging the azure job to check the status which for some odd reason does not work.
Ummair Tahir
6
12
29. Apr. 2025 | 02:22 PM
Thema:
Service and CRMScript Discussion

Letzte Antworten

The backend developer have already changed things on their end to make it to accept a POST :)
by Ummair Tahir
13. Mai 2025 | 01:16 PM
push_pin lock

Help with SuperOffice CRM Script: Finding Contacts by Category

I'm developing a CRMScript and need to search for contacts with category custom category. For testing I have just labeled it "C", but I'm getting the error "SearchEngine::useField() contact.category not found" when using either contact.category or contact.category_id in my SearchEngine criteria. What's the correct field name to use when searching for contacts by category in SuperOffice CRM, and should I be using the category name 'C' as a string or looking for an ID number instead? Any working code examples would be very helpful.

KH

Kamil Halden
3
2
12. Mai 2025 | 10:17 PM
Thema:
Service and CRMScript Discussion

Letzte Antworten

Hi Kamil In addition to what Frode said, you can find the field names you're looking for in the database reference: https://docs.superoffice.com/en/database/tables/contact.html
by Espen Steen
13. Mai 2025 | 06:39 AM
push_pin lock

How to get the columnname in UDF-tables by columnid

HOw do I find the actual database field name based on the response ?    {     "UDefFieldId": 715,     "ColumnId": 40509,     "FieldDefault": "",     "FieldHeight": 17,     "FieldLabel": "Postnummer",     "FieldLeft": 100,     "FieldTop": 0,     "FieldType": "ShortText",     "FieldWidth": 100,     "FormatMask": "",     "HideLabel": false,     "IsIndexed": true,     "LabelHeight": 17,     "LabelLeft": 0,     "LabelTop": 0,     "LabelWidth": 100,     "LastVersionId": 705,     "ListTableId": 0,     "IsMandatory": false,     "Type": "Sale",     "Page1LineNo": 1,     "ProgId": "zip",     "IsReadOnly": false,     "ShortLabel": "",     "TabOrder": 0,     "TextLength": 20,     "Tooltip": "",     "UdefIdentity": 1,     "UDListDefinitionId": 0,     "Justification": "Left",     "Version": 18,     "TemplateVariableName": "ss01",     "HasBeenPublished": true,     "MdoListName": null,     "TableRight": null   },

IT

Inge Simon Thorbjørnsen
2
2
8. Mai 2025 | 11:48 AM
Thema:
Online development and web service API's

Letzte Antworten

Thanks.

IT

by Inge Simon Thorbjørnsen
8. Mai 2025 | 02:41 PM
push_pin lock

Archiving outlook .msg files using PUT on document Content

Hi,   I'm wondering how to use the REST endpoint correctly https://docs.superoffice.com/en/api/reference/restful/rest/Document/v1DocumentEntity_SetDocumentStreamFromId.html This endpoint behaves correctly whenever I upload .pdf files using "Content-Type" and "application/octet-stream". But when uploading .msg files with the same content type "application/octet-stream". Everything works except that the content within the binary files has an added "prefix" instead of only the binary content. The consequence is failing to open the document inside Super Office online. I've also tried using content-type application/msword with same result. --eada92e1-9621-4759-b670-9d05f01d258d Content-Type: application/octet-stream Content-Disposition: form-data; name="=?utf-8?B?SHVzayDDpSBtZWxkZSBkZWcgcMOlIGZyb2tvc3RzZW1pbmFyIDIuIGFwcmlsISAoMSkubXNn?="; filename="=?utf-8?B?SHVzayDDpSBtZWxkZSBkZWcgcMOlIGZyb2tvc3RzZW1pbmFyIDIuIGFwcmlsISAoMSkubXNn?=" ÐÏࡱá                >  þ   I hope that you can help me with this or have any suggestion to get around this.   Sincere regards   Truong

TL

Truong Le
1
1
5. Mai 2025 | 08:27 AM
Thema:
Online development and web service API's

Letzte Antworten

This might be an encoding problems also. When I remove the "prefix" in notepad++, the file opens fine

TL

by Truong Le
5. Mai 2025 | 11:43 AM
push_pin lock

Trigger on Service: New message on request and messge.getAttachments() is empty

Hey, We're trying to get the attachements for a message on this trigger, but Message.getAttachments() is empty when called. If we manually set an old messageId, we do get the attachements. It's almost like the trigger fires before the attachments are stored. Any clever work arounds here? I tried to get the trigger script to sleep. Or do a while loop and wait until the Integer array is filled with something. But seems like it never does.  I hit execution timeout before the array has any entries. So maybe this is some job that is done after the trigger i run? Best Regards Bjørn

BK

Bjørn Karlsen
0
1
28. Apr. 2025 | 02:18 PM
Thema:
Service and CRMScript Discussion

Letzte Antworten

Hi Bjørn,  I agree with you, it seems like the trigger is fired after the message is created, but before the attachments rows are added to the ticket_attachment table. You should report it to bug@superoffice.com.
by Frode Lillerud
30. Apr. 2025 | 09:09 AM
push_pin lock

SuperOffice.SystemUser.Client v1.2 ignores proxy on authentication

Hi There seems to be a bug in the latest version of nuget SuperOffice.SystemUser.Client where the HttpClient provided is not used when authenticating. This results in not using proxy settings and therefore authentication fails when behind proxy. I'm guessing it is this change that causes it Snorre  

SG

Snorre Garmann
2
1
11. Apr. 2025 | 07:49 AM
Thema:
Client libraries and tools

Letzte Antworten

Hello Snorre,  Thank you for reporting this.  This issue belongs on github , so please create an issue there and I will look into it :) /Eivind
by Eivind Fasting
28. Apr. 2025 | 07:10 AM
push_pin lock

Best way to create a new address format in Online

Hi there, i have a customer who'd like a custom address format. In order to do this on-premise i would just copy a layout that already exists, and change the variables i need. Therefore i constructed the following CRM-Script that should copy the 4 other lines, and add them to the addressformat table, with my changed values:   #setLanguageLevel 4; SearchEngine se; se.addField('AddressFormat.addressformat_id'); se.addField('AddressFormat.name'); se.addField('AddressFormat.layout_id'); se.addField('AddressFormat.atype_idx'); se.addField('AddressFormat.address1_line'); se.addField('AddressFormat.address1_subpos'); se.addField('AddressFormat.address1_leadtext'); se.addField('AddressFormat.address1_zip'); se.addField('AddressFormat.address1_length'); se.addField('AddressFormat.address1_flags'); se.addField('AddressFormat.address1_mask'); se.addField('AddressFormat.address2_line'); se.addField('AddressFormat.address2_subpos'); se.addField('AddressFormat.address2_leadtext'); se.addField('AddressFormat.address2_zip'); se.addField('AddressFormat.address2_length'); se.addField('AddressFormat.address2_flags'); se.addField('AddressFormat.address2_mask'); se.addField('AddressFormat.address3_line'); se.addField('AddressFormat.address3_subpos'); se.addField('AddressFormat.address3_leadtext'); se.addField('AddressFormat.address3_zip'); se.addField('AddressFormat.address3_length'); se.addField('AddressFormat.address3_flags'); se.addField('AddressFormat.address3_mask'); se.addField('AddressFormat.city_line'); se.addField('AddressFormat.city_subpos'); se.addField('AddressFormat.city_leadtext'); se.addField('AddressFormat.city_zip'); se.addField('AddressFormat.city_length'); se.addField('AddressFormat.city_flags'); se.addField('AddressFormat.city_mask'); se.addField('AddressFormat.county_line'); se.addField('AddressFormat.county_subpos'); se.addField('AddressFormat.county_leadtext'); se.addField('AddressFormat.county_zip'); se.addField('AddressFormat.county_length'); se.addField('AddressFormat.county_flags'); se.addField('AddressFormat.county_mask'); se.addField('AddressFormat.state_line'); se.addField('AddressFormat.state_subpos'); se.addField('AddressFormat.state_leadtext'); se.addField('AddressFormat.state_zip'); se.addField('AddressFormat.state_length'); se.addField('AddressFormat.state_flags'); se.addField('AddressFormat.state_mask'); se.addField('AddressFormat.zip_line'); se.addField('AddressFormat.zip_subpos'); se.addField('AddressFormat.zip_leadtext'); se.addField('AddressFormat.zip_zip'); se.addField('AddressFormat.zip_length'); se.addField('AddressFormat.zip_flags'); se.addField('AddressFormat.zip_mask'); se.addField('AddressFormat.extraFlags'); se.addField('AddressFormat.labelLayout'); se.addField('AddressFormat.registered'); se.addField('AddressFormat.registered_associate_id'); se.addField('AddressFormat.updated'); se.addField('AddressFormat.updated_associate_id'); se.addField('AddressFormat.updatedCount'); se.addField('AddressFormat.labelLayout2'); se.addField('AddressFormat.isBuiltIn'); se.addCriteria('AddressFormat.addressformat_id', 'In', '211,212,213,214'); //print(se.executeHTMLTable()); SearchEngine sequence; sequence.addField('sequence.id'); sequence.addField('sequence.next_id'); sequence.addField('sequence.TableName'); sequence.addField('sequence.TableNumber'); sequence.addCriteria('sequence.id', 'In', '67'); sequence.execute(); Integer next = sequence.getField('sequence.next_id').toInteger(); //Copy the rows from the search engine to 4 new rows, named "Other - 2 address lines" for(se.execute(); !se.eof(); se.next()){ SearchEngine insert; insert.addData('AddressFormat.addressformat_id', next.toString()); insert.addData('AddressFormat.name', 'Other - 2 address lines'); insert.addData('AddressFormat.layout_id', se.getField('AddressFormat.layout_id')); insert.addData('AddressFormat.atype_idx', se.getField('AddressFormat.atype_idx')); insert.addData('AddressFormat.address1_line', se.getField('AddressFormat.address1_line')); insert.addData('AddressFormat.address1_subpos', se.getField('AddressFormat.address1_subpos')); insert.addData('AddressFormat.address1_leadtext', se.getField('AddressFormat.address1_leadtext')); insert.addData('AddressFormat.address1_zip', se.getField('AddressFormat.address1_zip')); insert.addData('AddressFormat.address1_length', se.getField('AddressFormat.address1_length')); insert.addData('AddressFormat.address1_flags', se.getField('AddressFormat.address1_flags')); insert.addData('AddressFormat.address1_mask', se.getField('AddressFormat.address1_mask')); insert.addData('AddressFormat.address2_line', se.getField('AddressFormat.address2_line')); insert.addData('AddressFormat.address2_subpos', se.getField('AddressFormat.address2_subpos')); insert.addData('AddressFormat.address2_leadtext', se.getField('AddressFormat.address2_leadtext')); insert.addData('AddressFormat.address2_zip', se.getField('AddressFormat.address2_zip')); insert.addData('AddressFormat.address2_length', se.getField('AddressFormat.address2_length')); insert.addData('AddressFormat.address2_flags', se.getField('AddressFormat.address2_flags')); insert.addData('AddressFormat.address2_mask', se.getField('AddressFormat.address2_mask')); insert.addData('AddressFormat.address3_line', '0'); insert.addData('AddressFormat.address3_subpos', '0'); insert.addData('AddressFormat.address3_leadtext', '0'); insert.addData('AddressFormat.address3_zip', se.getField('AddressFormat.address3_zip')); insert.addData('AddressFormat.address3_length', '0'); insert.addData('AddressFormat.address3_flags', se.getField('AddressFormat.address3_flags')); insert.addData('AddressFormat.address3_mask', se.getField('AddressFormat.address3_mask')); insert.addData('AddressFormat.city_line', '3'); insert.addData('AddressFormat.city_subpos', se.getField('AddressFormat.city_subpos')); insert.addData('AddressFormat.city_leadtext', se.getField('AddressFormat.city_leadtext')); insert.addData('AddressFormat.city_zip', se.getField('AddressFormat.city_zip')); insert.addData('AddressFormat.city_length', se.getField('AddressFormat.city_length')); insert.addData('AddressFormat.city_flags', se.getField('AddressFormat.city_flags')); insert.addData('AddressFormat.city_mask', se.getField('AddressFormat.city_mask')); insert.addData('AddressFormat.county_line', se.getField('AddressFormat.county_line')); insert.addData('AddressFormat.county_subpos', se.getField('AddressFormat.county_subpos')); insert.addData('AddressFormat.county_leadtext', se.getField('AddressFormat.county_leadtext')); insert.addData('AddressFormat.county_zip', se.getField('AddressFormat.county_zip')); insert.addData('AddressFormat.county_length', se.getField('AddressFormat.county_length')); insert.addData('AddressFormat.county_flags', se.getField('AddressFormat.county_flags')); insert.addData('AddressFormat.county_mask', se.getField('AddressFormat.county_mask')); insert.addData('AddressFormat.state_line', se.getField('AddressFormat.state_line')); insert.addData('AddressFormat.state_subpos', se.getField('AddressFormat.state_subpos')); insert.addData('AddressFormat.state_leadtext', se.getField('AddressFormat.state_leadtext')); insert.addData('AddressFormat.state_zip', se.getField('AddressFormat.state_zip')); insert.addData('AddressFormat.state_length', se.getField('AddressFormat.state_length')); insert.addData('AddressFormat.state_flags', se.getField('AddressFormat.state_flags')); insert.addData('AddressFormat.state_mask', se.getField('AddressFormat.state_mask')); insert.addData('AddressFormat.zip_line', '3'); insert.addData('AddressFormat.zip_subpos', se.getField('AddressFormat.zip_subpos')); insert.addData('AddressFormat.zip_leadtext', se.getField('AddressFormat.zip_leadtext')); insert.addData('AddressFormat.zip_zip', se.getField('AddressFormat.zip_zip')); insert.addData('AddressFormat.zip_length', se.getField('AddressFormat.zip_length')); insert.addData('AddressFormat.zip_flags', se.getField('AddressFormat.zip_flags')); insert.addData('AddressFormat.zip_mask', se.getField('AddressFormat.zip_mask')); insert.addData('AddressFormat.extraFlags', se.getField('AddressFormat.extraFlags')); insert.addData('AddressFormat.labelLayout', se.getField('AddressFormat.labelLayout')); insert.addData('AddressFormat.registered', se.getField('AddressFormat.registered')); insert.addData('AddressFormat.registered_associate_id', se.getField('AddressFormat.registered_associate_id')); insert.addData('AddressFormat.updated', se.getField('AddressFormat.updated')); insert.addData('AddressFormat.updated_associate_id', se.getField('AddressFormat.updated_associate_id')); insert.addData('AddressFormat.updatedCount', se.getField('AddressFormat.updatedCount')); insert.addData('AddressFormat.labelLayout2', se.getField('AddressFormat.labelLayout2')); insert.addData('AddressFormat.isBuiltIn', 'false'); insert.insert(); next = next + 1; } //Update sequence with the new next_id sequence.addData('sequence.next_id', next.toString()); sequence.addCriteria('sequence.id', 'In', '67'); sequence.update();   This Does not work however. I'm getting the following error, that does not really provide me with any help:   So do i really have to send a SQL command to support for them to execute, or what is best practise for me to create a custom address format with the tools available?   Thanks!  
Dennis Aagaard Mortensgaard
3
8
21. März 2025 | 12:29 PM
Thema:
Service and CRMScript Discussion

Letzte Antworten

Well if you update something using the SearchEngine you are bypassing all business logic, so it is not strange that the cache is not updated in that case. It should be updated when you do it through the API/List agent.  If you call DiagnosticsAgent.FlushCaches() after updating and before retrieving, do you the get the correct id's back? so: #setLanguageLevel 4; Integer countryId = 827; Integer customAddressFormatId = 17; NSListAgent listAgent; NSDiagnosticsAgent diagnosticsAgent; NSCountry customCountry = listAgent.GetCountry(countryId); customCountry.SetAddressLayoutId(customAddressFormatId ); customCountry.SetForeignAddressLayoutId(customAddressFormatId ); customCountry.SetDomesticAddressLayoutId(customAddressFormatId ); customCountry = listAgent.SaveCountry(customCountry); diagnosticsAgent.FlushCaches(); customCountry = listAgent.GetCountry(countryId); printLine(customCountry.GetAddressLayoutId().toString()); printLine(customCountry.GetForeignAddressLayoutId().toString()); printLine(customCountry.GetDomesticAddressLayoutId().toString());
by David Hollegien
16. Apr. 2025 | 12:04 PM