I currently have two lists, one is from an external api (splynx), which returns a list of all customers, and another list which returns a list of all Account names from the contacts module in Zoho crm, at the moment, I just want write a code that confirms if the two lists contain matching entries (like one entry in the splynx list matches another entry in the crm list).
What I actually want to achieve is for each matching entry, I want to update crm records with the Customer ID field from Splynx, with a custom field called Splynx ID in the accounts module in CRM (because this ID is auto generated so as to maintain consistency across both apps). I want to know if this even achievable.
This is the code I have written so far
headersmap = Map();
headersmap.put("Authorization","Basic xxxxxxx);
response = invokeurl
[
url :"https://selfcare.dotmac.ng/api/2.0/admin/customers/customer?"
type :GET
headers:headersmap
];
AccountlistSplynx = List();
li1 = List();
li2 = List();
li3 = List();
rows = response.toJSONList();
rows1 = response.toJSONList();
rows2 = response.toJSONList();
for each row in rows
{
Name = row.getjson("name");
AccountlistSplynx.add(Name);
}
for each row in rows1
{
Address = row.getjson("street_1");
li1.add(Address);
}
for each row in rows2
{
CustomerID = row.getjson("id");
li2.add(CustomerID);
}
Accountlistzoho = List();
mp = Map();
contacts = zoho.crm.getRecords("Contacts");
for each contact in contacts
{
account = ifnull(contact.getJSON("Account_Name"),Map());
if(account.size() > 0)
{
accountname = account.getJSON("name");
Accountlistzoho.add(accountname);
}
}
if ( Accountlistzoho == AccountlistSplynx )
{
info "Matching records!";
}
else
{
info "No matching records!";
}
I also want to know if this is the best route to follow in trying to achieve this because I had already imported these contacts from Splynx to CRM before I realized that I did not create the custom field for Accounts
Take a look at the intersect list function:
<variable> = <listVariableOne>.intersect( <listVariableTwo> );
Note!:
<listVariableOne>.intersect( <listVariableTwo> );
and
<listVariableTwo>.intersect( <listVariableOne> );
should return the same intersection set but sometimes one of these calls returns a smaller set. To work around this, call intersect() both ways and if they differ use the one that gives the expected set.
For this task intersect() would be used something like this:
headersmap = Map();
headersmap.put("Authorization","Basic xxxxxxx);
response = invokeurl
[
url:"https://selfcare.dotmac.ng/api/2.0/admin/customers/customer?"
type :GET
headers:headersmap
];
// Note: Using a Map to associate Splynx names and ids.
SplynxMap = Map();
rows = response.toJSONList();
for each row in rows
{
SplynxMap.put(row.getjson("name"), row.getjson("id");
}
// Here make a list of Splynx names based on the map keys.
AccountlistSplynx = List();
AccountlistSplynx = SplynxMap.keys();
// Intersect() function
ItemsToProcess = Accountlistzoho.intersect(AccountlistSplynx);
// Get Zoho record and update with Splynx Customer ID
// Here is one way to do this, but probably not the best or
// most efficient. There is should be a way in CRM to request
// a specific record based on the "name" field and avoid
// looping through contacts for each item to process.
for each item in itemsToProcess
{
for each contact in contacts
{
account = ifnull(contact.getJSON("Account_Name"),Map());
if(account.size() > 0)
{
if ( item == account.getJSON("name"))
{
account.Splynx_ID = SplynxMap.get(item);
}
}
}
}
Regarding your needs, do you want to update Zoho CRM records if they are matched in Splynx records?
Step 1:
Store all Splynx records into the List data type variable in the deluge.
Store all Zoho records into the List data type variable in the deluge.
Step 2:
Assume that API field Names of both Lists are not equally matched.
Step 3:
This is how to determine matched records in Zoho records if we assume that Account Name is the criteria to be said it is matched. Please note that api_field_name or keys will be different from your actual data.
SplynxData = {{"s_account_name":"Account A","ID":"s_ID_1"},{"s_account_name":"Account B","ID":"s_ID_2"},{"s_account_name":"Account C","ID":"s_ID_3"},{"s_account_name":"Account D","ID":"s_ID_4"}};
ZohoData = {{"z_account_name":"Account A","ID":"z_ID_1"},{"z_account_name":"Account B"},{"z_account_name":"Account C"}};
ZohoData_group_Name = Map();
for each ZohoData_item in ZohoData{
item_map = Map();
ZohoData_group_Name.put(ZohoData_item.get('z_account_name'),ZohoData_item);
}
for each SplynxData_item in SplynxData{
matched_zoho_item = ZohoData_group_Name.get(SplynxData_item.get('s_account_name')) ;
if (matched_zoho_item != null){
info matched_zoho_item;
//Do zoho.crm.updateRecords methods
}
}
You can try this deluge script in https://deluge.zoho.com/tryout.
Please refer to this link on how to update Zoho Records https://www.zoho.com/deluge/help/crm/update-record.html
Related
For each client we have, we associate their name with an ID number in a database. However, we sign people in by name. I am trying to convert the names into their ID number in a spreadsheet.
I have a list of all the names and corresponding IDs. I realize that I could hard code it so that it would look something like:
for (i=0; i < 31; i++) {
if name = 'john doe'
id = 256589
elseif name = 'jane doe'
id = 248352...}
and repeat that for each client. I've tested with a couple names and this solution does work. Since we don't have that many individuals come in it wouldn't be impossible to just repeat it. However, I would like to know if there are any shortcuts available.
It depends where you're doing this lookup.
This looks like script so you could use an object with the names as keys:
function getIdFromName(name) {
// list of all employees and ids
let employees = {
"john doe": 256589,
"jane doe": 248352
}
if (employees[name]) {
return employees[name]
} else {
// this covers the case if name not found
return false
}
}
// in rest of your code
var id = getIdFromName(name)
If you want to do the lookup in the sheet, you can use a lookup table containing names and ids then use VLOOKUP/INDEX(MATCH()) to find the corresponding ID
function updateFirebase(){
const fb=firebase.database().ref()
//get field values
author = document.getElementById('uname').value
user_email = document.getElementById('umail').value
data = {author, user_email}
//update database
fb.child('Article/').update(data);
}
</script>
I have problem with my code. I want to update the data inside a table named "Article". Article has generated items with a unique key/id and each key has its own content. Lets say I want to be able to edit the "author" or change the "title", the problem is they each have a randomly generated key/id that I cant access. for example that "-LS39kReBHrKGqNj7h_". I can only save the data inside the "Article" tree but I cant change the "author" or the "title". How do i get a workaround this so I can change those properties?
Here is how my firebase looks like
It depends whether you have the record reference on the frontend before update or not (whether you have fetched it before you are trying to update it).
But generally, you have two options
You can store the key reference as an "id" field on the object.
To achieve that, you need two step process when creating the record at the first place
// Creates a new record in DB and returns it to you. Now you can get the "key"
const newRecord = firebase.database().ref('TABLE_NAME_REF').push();
newRecord.set({
id: newRecord.key
...
});
This is great if you fetch the list of records on the frontend and then you want to update one of them. Then you can just build the ref path like this
fb.child('Article/' + record.id ).update(data); // where record is the prefetched thing
You need to find the element based on its fields first. And once you have it, you can update it right away.
To achieve this, you can simply do something like:
firebase.database()
.ref('TABLE_NAME_REF') // let's say 'Article'
.orderByChild('RECORD_KEY') // Let's say 'author'
.equalTo('KEY_VALUE') // let's say 'zoranm'
.limitToFirst(1)
.once("value")
.then(res => {
// You need to loop, it always returns an array
res.forEach(record => {
console.log(record.key); // Here you get access to the "key"
fb.child('Article/' + record.key ).update(data); // This is your code pasted here
})
})
In API reference described methods to select/isolate objects (in condition that only one model is loaded in viewer):
- select(dbids,selectionType)
- isolate(node)/isolateById(dbids) // that is the difference?
I know select analog for multimodel:
viewer.impl.selector.setSelection([objectIds], model);
Questions are:
Is isolate analog for multimodel mode exists?
How can I select/isolate two objects from diffrenent models at once?
In the recent version of the API the viewer.impl.visibilityManager is returning a MultiModelVisibilityManager, so you can pass a model as second argument:
MultiModelVisibilityManager.prototype.isolate = function (node, model)
Take a look in viewer3D.js (L#17825) to see available methods on that object.
As far as I know there is no way to select two objects from different models in a single call, you would just issue one select call for each model passing respective ids. I don't see a problem with that.
Hope that helps.
For the isolate, you can do something like this(borrowed from the Viewer3D.js):
// Get selected elements from each loaded models
var selection = this.viewer.getAggregateSelection();
var allModels = this.viewer.impl.modelQueue().getModels().concat(); // shallow copy
// Isolate selected nodes.
selection.forEach(function(singleRes){
singleRes.model.visibilityManager.isolate(singleRes.selection);
var indx = allModels.indexOf(singleRes.model);
if (indx >= 0) {
allModels.splice(indx, 1);
}
});
// Hide nodes from all other models
while (allModels.length) {
allModels.pop().visibilityManager.setAllVisibility(false);
}
this.viewer.clearSelection();
For the select, you need to pass corresponding model and dbIds to the viewer.impl.selector.setSelection([dbIds], model); and call setSelection for each set, such as below. It cannot be archived at once.
var selSet = [
{
selection: [1234, 5621],
model: model1
},
{
selection: [12, 758],
model: model2
},
];
selSet.forEach(funciton(sel) {
viewer.impl.selector.setSelection(sel.selection, sel.model);
});
Assuming I have the following MySQL tables to represent pricebooks, items and the relationship between them:
item - item_id|name|...etc
pricebook - pricebook_id|name|...etc
and the following pivot table
pricebook_item - pricebook_id|item_id|price|...etc
I have the correlating Eloquent models: Pricebook, Item and a repository named PricebookData to retrieve the necessary information.
Within the PricebookData repository, I need to get the pricebook data grouped by pricebook id and then keyed by item_id for easy access on client side.
If I do:
Pricebook::all()->groupBy('pricebook_id');
I get the information grouped by the pricebook_id but inside each pricebook the keys are simple numeric index (it arrives as js array) and not the actual product_id. So when returning to client side Javascript, the result arrives as the following:
pricebookData: {1: [{}, {}, {}...], 2: [{}, {}, {}...]}
The problem with the prices arriving as array, is that I can not access it easily without iterating the array. Ideally I would be able to receive it as:
pricebookData: {1: {1001:{}, 1002: {}, 1003: {}}, 2: {1001:{}, 1002: {}, 1003: {}}}
//where 1001, 1002, 1003 are actual item ids
//with this result format, I could simply do var price = pricebookData[1][1001]
I've also tried the following but without success:
Pricebook::all()->keyBy('item_id')->groupBy('pricebook_id');
The equivalent of what I am trying to avoid is:
$prices = Pricebook::all();
$priceData = [];
foreach ($prices as $price)
{
if (!isset($priceData[$price->pricebook_id]))
{
$priceData[$price->pricebook_id] = [];
}
$priceData[$price->pricebook_id][$price->item_id] = $price;
}
return $priceData;
I am trying to find a pure elegant Eloquent/Query Builder solution.
I think what you want is
Pricebook::all()
->groupBy('pricebook_id')
->map(function ($pb) { return $pb->keyBy('item_id'); });
You first group by Pricebook, then each Pricebook subset is keyed by item_id. You were on the right track with
Pricebook::all()->keyBy('item_id')->groupBy('pricebook_id');
unfortunately, as it is implemented, the groupBy resets previous keys.
Update:
Pricebook::all()->keyBy('item_id')->groupBy('pricebook_id', true);
(groupBy second parameter $preserveKeys)
I've created a blog on Sharepoint 2010 and want to query the list via REST for reporting. I want to order the list by the default field Category (internal name PostCategory). Unfortunately, this is a multiselect field, therefore a simple "?$orderby=Category" doesn't work. I've also tried to expand the Category, but that doesn't work either.
Is there a chance, that I can order the list using rest? What about more then one selected Category? Can it be ordered by the first category, then the second, etc.?
If it's not possible using REST, what about ordering within JSON? I use a small javascript, that puts the list in a reporting format. Can I order within the JSON result?
Here is an example:
// Create REST-API URL
var strURL = "<REST-URL>";
// Get information from REST-API and create html output
$.getJSON(strURL, function(data) {
<Create output>
};
// Append to webpart
$('#<WebPartTitle>').append($(html));
EDIT: I've posted the question also here, since it's happening all in sharepoint
Category field (PostCategory internal name) is a multiple choice field, in SharePoint REST it is not supported to apply $orderby query option to this type of field.
But you could sort returned items using JavaScript.
The following example demonstrates how to order Posts by Category field.
There is one important note here:
Since Category field is a multiple choice field value, it is
assumed that only one category could be specified per post.
For that purpose FirstCategoryTitle property is introduced which
represent the title of first category in post item. This property is used > for sorting items
Example
var endpointUrl = 'http://contoso.intranet.com/blog/_vti_bin/listdata.svc/Posts?$expand=Category';
$.getJSON(endpointUrl, function(data) {
var items = data.d.results.map(function(item){
item.FirstCategoryTitle = (item.Category.results.length > 0 ? item.Category.results[0].Title : ''); //get first category
return item;
});
items.sort(postComparer); //sort by category
items.forEach(function(item){
console.log(item.Title);
});
});
function postComparer(x,y) {
return x.FirstCategoryTitle > y.FirstCategoryTitle;
}