Update a contact group by using a People API - google-apps-script

Hello I need to update a created contact and remove from all earlier groups assigned. In this example a contact is created and it is later moved to Carpenter and now the actial question begins
How do I move a created contact to a different group. That is I need the contact to be moved to BLACKSMITHS group if that doesnt exist create BLACKSMITHS and assign BLACKSMITHS and remove from earlier assigned CARPENTERS
function doGet(e) {
// 1. CREATE CONTACT:
var contactResource = {
"names": [{
"displayNameLastFirst": "Smith Jefferson Jones",
"familyName": "Jones",
}],
/* "phoneNumbers": [{
'value': "+12345679962"
}],
"emailAddresses": [{
'value': ' '
}]*/
}
var contactResourceName = People.People.createContact(contactResource)["resourceName"];
// 2. CHECK IF GROUP EXISTS:
var groupName = "CARPENTERS";
var groups = People.ContactGroups.list()["contactGroups"];
var group = groups.find(group => group["name"] === groupName);
// 3. CREATE GROUP IF DOESN'T EXIST:
if (!group) {
var groupResource = {
contactGroup: {
name: groupName
}
}
group = People.ContactGroups.create(groupResource);
}
var groupResourceName = group["resourceName"];
// 4. ADD CONTACT TO GROUP:
var membersResource = {
"resourceNamesToAdd": [
contactResourceName
]
}
//HOW DO I MODIFY A CONTACT so that its must be removed from "CARPENTERS" group and ADDED TO "BLACKSMITHS" group
//??????????????????
People.ContactGroups.Members.modify(membersResource, groupResourceName);
return ContentService.createTextOutput("Success");
}

You just need to:
Add the contact to the new group (BLACKSMITHS), the way you did it in the code you shared.
Remove the contact from the previous group (CARPENTERS), using resourceNamesToRemove at contactGroups.members.modify.
Check the example below.
Code snippet:
// 1. Create Blacksmiths group if doesn't exist, add contact to group:
var groupNameToAdd = "BLACKSMITHS";
var groupToAdd = groups.find(group => group["name"] === groupNameToAdd);
if (!groupToAdd) { // Create group if doesn't exist
var groupToAddResource = {
contactGroup: {
name: groupNameToAdd
}
}
groupToAdd = People.ContactGroups.create(groupToAddResource);
}
var groupToAddResourceName = groupToAdd["resourceName"];
var membersToAddResource = {
"resourceNamesToAdd": [
contactResourceName
]
}
People.ContactGroups.Members.modify(membersToAddResource, groupToAddResourceName);
// 2. Remove contact from Carpenters:
var groupNameToRemove = "CARPENTERS";
var groupToRemove = groups.find(group => group["name"] === groupNameToRemove);
if (groupToRemove) { // Check that group exists
var groupToRemoveResourceName = groupToRemove["resourceName"];
var membersToRemoveResource = {
"resourceNamesToRemove": [
contactResourceName
]
}
People.ContactGroups.Members.modify(membersToRemoveResource, groupToRemoveResourceName);
}

Related

JSON add nested sub objects dynamically using JS or JQuery

I am creating a services cart at client side
where services are grouped inside 3 level of groupings like
product[SECTION] [SERVICE] [ITEM]
product['carpet']['cleaning']['room'] = {'qty':2,'price':15};
product['carpet']['cleaning']['hall'] = {'qty':1,'price':10};
product['carpet']['protecting']['hall'] = {'qty':1,'price':10};
product['carpet']['deodorize']['hall'] = {'qty':1,'price':10};
product['leather']['cleaning']['sofa'] = {'qty':1,'price':10};
want to generate above structure of json.
my text boxes looks like below notice data-section data-service data-tem and data-price
<input type="text" class="form-control input-number"
data-price="15" data-section="carpet" data-item="room" data-service="protect" />
My JS code is as below, but it adds only current item while overwriting all other services and sections.
$(function(){
$('.input-number').change(function(){
var section = $(this).attr('data-section');
var item = $(this).attr('data-item');
var service = $(this).attr('data-service');
var qty = $(this).val();
var unitprice = $(this).attr('data-unitprice');
addProduct(section,item,service,qty,unitprice);
});
});
function addProduct(section,item,service,qty,unitprice){
let products = {};
if(localStorage.getItem('products')){
products = JSON.parse(localStorage.getItem('products'));
}
products['"'+section+'"'] =
{
['"'+service+'"'] : {
['"'+item+'"'] : {
'unitprice' : unitprice, 'qty': qty
}
}
};
localStorage.setItem('products', JSON.stringify(products));
}
How can I append only instead of overwriting nested items?
EDITED
I have edited my add product function as below but still not getting desired result
function addProduct(section,item,service,qty,unitprice){
let products = {};
if(localStorage.getItem('products')){
products = JSON.parse(localStorage.getItem('products'));
}
var v = {
[service] : {
[item] :{
"qty":qty,'unitprice':unitprice
}
}
};
products.push( section, v );
localStorage.setItem('products', JSON.stringify(products));
}
Object.prototype.push = function( key, value ){
if(typeof value === 'object'){
var k = Object.keys(value)[0];
value.push( k, value[k] );
}
this[ key ] = value;
return this;
}
First of all that is not a good way to store your data.
Here's a better way to store your data.
It's much more easy to understand if you see it like an object cause in javascript it's the same thing
//example this 2 data is store the same way in javascript
var product['carpet']['cleaning']['room'] = {'qty':2,'price':15};
var product = [{
carpet: {
cleaning: {
room: {'qty':2,'price':15}
}
}
}]
// my solution would be just save section, service and item in the object, example:
var product = [];
var v = {
section: 'carpet',
service: 'cleaning',
item: 'room'
qty:2,
price:15
}
product.push(v)

Delete token from SAPUI5 Multi Input Field with Data Binding

in my SAPUI5 app I am using a Multi Input Field with tokens which are bound to a JSON Model. Newly added entries are saved in the JSON Model. However, when deleting a token by pressing the "x" next to the token text, the token disappears from the multi input field. But when adding a new token the deleted one reappears.
How can I ensure that the deleted entry is also deleted from the JSON Model?
This is my current code for adding the token to the model:
multiInputField.addValidator(function(args){
MessageBox.confirm("Do you really want to add Token\"" + args.text + "\"?", {
onClose: function(oAction) {
if (oAction === MessageBox.Action.OK){
var oToken = new Token({key: args.text, text: args.text});
args.asyncCallback(oToken);
var aFields = sap.ui.getCore().getView().getModel("myModel").getProperty("/Tokens");
var oNewFields= {
Tokens: args.text
};
aFields .push(oNewFields);
sap.ui.getCore().getView().getModel("myModel").setProperty("/Tokens", aFields );
sap.ui.getCore().getView().getModel("myModel").refresh();
} else {
args.asyncCallback(null);
}
},
title: "Add Token"
});
return sap.m.MultiInput.WaitForAsyncValidation;
});
I guess we can use "tokenUpdate" event for this.
For example, given that I have this MultiInput in my view:
<MultiInput width="500px" id="multiInput" suggestionItems="{ path: 'dataModel>/data'}" showValueHelp="true" tokenUpdate="onTokenUpdate">
<core:Item key="{dataModel>key}" text="{dataModel>value}"/>
</MultiInput>
then in my controller I can handle this like :
onTokenUpdate: function(oEvent) {
var sType = oEvent.getParameter("type");
if (sType === "removed") {
var sKey = oEvent.getParameter("removedTokens")[0].getProperty("key");
var oModel = this.getView().getModel("dataModel");
var aData = this.getView().getModel("dataModel").getProperty("/data");
for (var i = 0, len = aData.length; i < len; i++) {
var idx;
console.log(sKey + "-" + aData[i].key);
if (aData[i].key === sKey) {
idx = i;
}
}
aData.splice(idx, 1);
oModel.setProperty("/data", aData);
console.log(oModel);
}
}
And this is my json:
{
"data": [
{
"key": "token1",
"value": "token1"
},
{
"key": "token2",
"value": "token2"
}
]
}

KendoGrid refresh

I'm using KendoGrid to display some data fetched from my service.
The user selects some parameters (company and date) and cliks on a load button.
The user selects a month on a datePicker and the server will return data from that date plus 11 months.
I only display the grid after the user click on the load button.
Load function:
function loadGrid(e) {
var companyIds = [1, 3, 7]; // user select it
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var rowHeaders = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"];
var _dataSource = function () {
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: URL,
dataType: "json",
data: {
companyIds: companyIds,
date: kendo.toString(picker.value(), "yyyy-MM-dd") // user select it
}
}
},
schema: {
data: function (data) {
// function to handle data returned from server
var dataArray = [];
var index = 0;
for (var key in data[0]) {
if (Object.prototype.hasOwnProperty.call(data[0], key)) {
var property = key;
if (property == "date") {
continue;
}
key = {};
key["X"] = rowHeaders[index];
index++;
for (var i = 0; i < data.length; i++) {
var date = data[i].date;
var dateSplit = date.split("-");
var year = dateSplit[0];
var month = months[dateSplit[1] - 1];
var header = month + "_" + year;
key[header] = data[i][property];
}
dataArray.push(key);
}
}
return dataArray;
}
}
});
return dataSource;
};
$("#grid").kendoGrid({
scrollable: false,
editable: false,
dataSource: _dataSource()
});
}
When I click on the load button for the first time, the datasource is loaded and the grid is displayed correctly.
But, for instance, if I change the date on the datePicker and click on the load button again, the datasource is loaded with the correct data (new records for other months), but the grid is not refreshed.
If the first time I select the month Jan/2015, it loads and displays from Jan/2015 until Dec/2015, which is correct.
But if than I select the month Feb/2015, the datasource loads from Feb/2015 until Jan/2016 (correct), but the grid display the columns from Jan/2015 until Dec/2015, which is wrong. In this case, the column Jan/2015 is shown empty and the column Jan/2016 is not displayed.
Can someone point me to the right direction?
Thanks!
You should use a function for your dataSource -> transport -> read -> data:
data: function() {
return {
companyIds: companyIds,
date: kendo.toString(picker.value(), "yyyy-MM-dd") // user select it
};
}
UPDATE:
Here is how I would do it:
function loadGrid(e) {
$("#grid").data("kendoGrid").dataSource.fetch();
}
function getData() {
var companyIds = ...
var picker = ...
return {
companyIds: companyIds,
date: kendo.toString(picker.value(), "yyyy-MM-dd") // user select it
};
}
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: URL,
dataType: "json",
data: getData
}
},
schema: {
data: function (data) {
// function to handle data returned from server
var dataArray = [];
var index = 0;
for (var key in data[0]) {
if (Object.prototype.hasOwnProperty.call(data[0], key)) {
var property = key;
if (property == "date") {
continue;
}
key = {};
key["X"] = rowHeaders[index];
index++;
for (var i = 0; i < data.length; i++) {
var date = data[i].date;
var dateSplit = date.split("-");
var year = dateSplit[0];
var month = months[dateSplit[1] - 1];
var header = month + "_" + year;
key[header] = data[i][property];
}
dataArray.push(key);
}
}
return dataArray;
}
}
});
$("#grid").kendoGrid({
scrollable: false,
editable: false,
dataSource: dataSource
});
I ended up destroying and recreating the grid when the user clicks on load button.
$("#loadButton").kendoButton({
click: loadGrid
});
var loaded = false;
function loadGrid(e) {
if (value) {
if (loaded) {
var grid = $("#grid").data("kendoGrid");
grid.wrapper.empty();
grid.destroy();
}
$("#grid").kendoGrid({
scrollable: false,
editable: false,
autoBind: false,
dataSource: _dataSource()
});
$("#grid").data("kendoGrid").dataSource.read();
loaded = true;
} else {
e.preventDefault();
alert("aaaa");
}
}

How to disable the Default sorting applied to groups in Kendo Grid

element.kendoGrid({
dataSource: {
data: scope.people,
group: {
field: "name"
}
},
groupable: true,
sortable: false,
pageable: {
refresh: true,
pageSizes: true
},
columns: scope.columns
});
Passed Data Source
$scope.people = [man1, man2, man3, man4];
var man1 = new Man('Test name2', 25);
var man2 = new Man('Test name1', 28);
var man3 = new Man('Test name1', 21);
var man4 = new Man('Test name3', 21);
Actual REsult :
Group are displaying in following order
First Name : Test name 1
First Name : Test name 2
First Name : Test name 3
Expected Result :
Group should display in following order
First Name : Test name 2
First Name : Test name 1
First Name : Test name 3
How do we achieve this?
By default groups are getting displayed in ascending order. But I want the order of group as it is there in the DataSource
If you can add your data through Ajax, then it's not too hard. I haven't found a way to do it without ajax though.
Your ajax would look like this:
$.ajax({
...[add your data call info here]...
}).done(function(result) {
var data = result.d.results; //this may be different for others
var sortNum = 1;
var lastVal;
for (var i = 0; i < data.length; i++) {
var val = data[i]["Firstname"];
if (!lastVal) {
lastVal = val;
}
if (val !== lastVal) {
sortNum++;
lastVal = val;
}
data[i]["SortOrder"] = sortNum;
}
});
This is if you just want to pass the data as is into your kendo grid.
Now that you have a sort column, tell kendo to group on that new column and replace the text with the original group column to display the names correctly.
//fetch FirstName value and return it to display instead of SortOrder value
function getHeader(val) {
var $data = $('.grid').data('kendoGrid').dataSource.data();
for (var i = 0; i < $data.length; i++) {
if ($data[i].SortOrder === val.value) {
return data[i].FirstName + '';
}
}
}
$('.grid').kendoGrid({
//... do all your normal kendo initialization, I'll just add the stuff you need to change
dataSource: {
schema: {
model: {
fields: { //add the new SortOrder column
SortOrder: {
type: 'number'
}
}
}
},
group: {
field: "SortOrder"
}
},
columns: [{ //add the new SortOrder column, but call the getHeader function to override the value displayed
field: "SortOrder",
hidden: true,
groupHeaderTemplate: getHeader
}]
});
That should be all you need to do. Hope this helps.

jQuery and Json push issue

I am okay with using push({}) to create my javascript array, however one of my fields has a list of its own. So I'm having trouble doing the push() on level down.
As follows, tradeDetails array is defined and the EXTENSIONS field has a collection of values. How do I handle this one below.
function TradeDetailsToJson(xml) {
var tradeDetails = [];
var tradeId = $(xml).find("tradeHeader tradeId").text();
var tradeDate = $(xml).find("tradeHeader tradeDate").text();
var tradeType = $(xml).find("tradeHeader tradeType").text();
var counterparty = $(xml).find("tradeHeader counterparty").text();
var internalUnit = $(xml).find("tradeHeader internalUnit").text();
var buySell = $(xml).find("tradeHeader buySell").text();
var status = $(xml).find("tradeHeader status").text();
tradeDetails.push({
"tradeId": tradeId,
"tradeDate": tradeDate,
"tradeType": tradeType,
"counterparty": counterparty,
"internalUnit": internalUnit,
"buySell": buySell,
"status": status,
"**extensions**":[]
});
// NOW I'D LIKE TO PUSH MY EXTENSIONS !!
var extName = ""
var extValue = "";
$(xml).find("extensions extension").each(function () {
extName = $(this).find("name").text();
extValue = $(this).find("value").text();
//tradeDetails[extensions].push({ "name": name, "value": value }); ??????
});
}
thank you in advanced.
Bob
Use push on the extensions property again?
tradeDetails.push({
"tradeId": tradeId,
"tradeDate": tradeDate,
"tradeType": tradeType,
"counterparty": counterparty,
"internalUnit": internalUnit,
"buySell": buySell,
"status": status,
"extensions":[]
});
tradeDetails.extensions.push({ "name": name, "value": value });
With what you have tried, you need to wrap extensions which is the key of the object tradeDetails, in quotes.
So change
tradeDetails[extensions].push({ "name": name, "value": value });
to
tradeDetails["extensions"].push({ "name": name, "value": value });