How to get the Designation of the User from AdminDirectory - javascript

I was able to get the user name from the below code, is there a way to get the user's designation (or mobile number or work location?)
function getUser() {
var user = Session.getActiveUser().getEmail();
var employee = AdminDirectory.Users.get(user).name.fullName;
Logger.log('User data:\n%s', JSON.stringify(employee, null, 2));
console.log(employee);
}

Answer:
Using the same AdminDirectory.Users.get() method you can obtain phone numbers and work locations by specifying the fields you want on the return.
Example:
The method has a large response body which can be seen in the documentation.
You can see in this resource the two pieces of data you are looking for:
phones[]: list
A list of the user's phone numbers. The maximum allowed data size for this field is 1Kb.
locations[]: list
The user's locations. The maximum allowed data size for this field is 10Kb.
You can then filter out the data you desire with sub categories, for example phones[].type or locations[].area.
In order to retrieve, for example, phone numbers, you can filter the requeest in the same way:
var employee = AdminDirectory.Users.get(user);
var phones = employee.phones
var loc = employee.locations
Logger.log('User data:');
Logger.log(phones);
Logger.log(loc);
Will yield a log with the following format:
[20-11-02 12:12:28:243 CET] User data:
[20-11-02 12:12:28:247 CET] [{type=home, value=123456789}, {value=987654321, type=mobile}]
[20-11-02 12:12:28:250 CET] [{floorSection=Upper, floorName=Floor 12, type=desk, buildingId=5, area=cityView}]
References:
Users | Directory API | Google Developers

Related

Programmatically add products to a cart – Odoo 13

I have a custom module that creates a form. Based on the answers inside this form I’m generating order line. After user sends this form I’m creating sale order with all products from the generated order line.
So from JavaScript I’m sending an JSON with products to buy:
order_data = [{product_id: 1, amount: 10, …},{product_id: 2, …}, …];
note = '';
this._rpc({
route: '/api/create_order',
params: { order_products: order_data, note: note }
}).then((data) => {
window.location = '/contactus-thank-you';
}).catch((error) => {
console.error(error);
});
And then inside Python I’m creating sale order based on the JSON:
#http.route('/api/create_order', type='json', auth='user', website=True)
def create_order(self, **kw):
uid = http.request.env.context.get('uid')
partner_id = http.request.env['res.users'].search([('id','=',uid)]).partner_id.id
order_products = kw.get('order_products', [])
note = kw.get('note', '')
order_line = []
for product in order_products:
amount = 0
if 'custom_amount' in product:
amount = product['custom_amount']
else:
amount = product['amount']
if amount > 0:
order_line.append(
(0, 0, {
'product_id': product['product_id'],
'product_uom_qty': amount,
}))
order_data = {
'name': http.request.env['ir.sequence'].with_user(SUPERUSER_ID).next_by_code('sale.order') or _('New'),
'partner_id': partner_id,
'order_line': order_line,
'note': note,
}
result_insert_record = http.request.env['sale.order'].with_user(SUPERUSER_ID).create(order_data)
return result_insert_record.id
But instead of generating sale order directly I need to use workflow from Odoo’s eCommerce addon. That way user can for example edit delivery address, choose payment etc. So I think I just need to programmatically put all the product inside a cart and then rest will be taken care of by Odoo built-in functionality.
But how? I’ve tried to find something inside Odoo source code but it is quite hard to grasp anything.
Odoo uses a typical Sale Order for handling products inside a cart. But the process isn't as simple as just creating Sale Order with some products. Odoo needs to know which order is linked with which cart etc.
Luckily Odoo has a method for dealing with it. There is a sale_get_order() method that lets you get an order that is currently linked with a cart or create new one if there isn't any.
I'm not sure if it is documented anywhere outside the source code so here is a slice from the code (/addons/website_sale/models/website.py):
def sale_get_order(self, force_create=False, code=None, update_pricelist=False, force_pricelist=False):
""" Return the current sales order after mofications specified by params.
:param bool force_create: Create sales order if not already existing
:param str code: Code to force a pricelist (promo code)
If empty, it's a special case to reset the pricelist with the first available else the default.
:param bool update_pricelist: Force to recompute all the lines from sales order to adapt the price with the current pricelist.
:param int force_pricelist: pricelist_id - if set, we change the pricelist with this one
:returns: browse record for the current sales order
"""
# ...
I'm using it alongside another method _cart_update() that lets me easily update products inside this order. There is also sale_reset() and I'm using it just to be sure that current session will be updated with particular sale order every time.
sale_order = request.website.sale_get_order(force_create=True)
request.website.sale_reset()
sale_order.write({'order_line':[(5, 0, 0)]})
for product in order_products:
sale_order._cart_update(product_id=product['product_id'], line_id=None, add_qty=None, set_qty=product['amount'])

How to get list of contacts and meetings from Exchange Web Services using nodejs?

I searched google about this problem and I got some results:
How to get contact list from Exchange Server?
https://msdn.microsoft.com/en-us/library/office/jj220498(v=exchg.80).aspx
// Get the number of items in the Contacts folder.
ContactsFolder contactsfolder = ContactsFolder.Bind(service, WellKnownFolderName.Contacts);
// Set the number of items to the number of items in the Contacts folder or 50, whichever is smaller.
int numItems = contactsfolder.TotalCount < 50 ? contactsfolder.TotalCount : 50;
// Instantiate the item view with the number of items to retrieve from the Contacts folder.
ItemView view = new ItemView(numItems);
// To keep the request smaller, request only the display name property.
view.PropertySet = new PropertySet(BasePropertySet.IdOnly, ContactSchema.DisplayName);
// Retrieve the items in the Contacts folder that have the properties that you selected.
FindItemsResults<Item> contactItems = service.FindItems(WellKnownFolderName.Contacts, view);
// Display the list of contacts.
foreach (Item item in contactItems)
{
if (item is Contact)
{
Contact contact = item as Contact;
Console.WriteLine(contact.DisplayName);
}
}
But it seems to be a black box that only open for C# developers.
I can't see any URL or how to add WSDL file here (so I can do the same in Nodejs)
So how can I use Nodejs to get this information?
Thanks
There is no NodeJS specific API.
There is a javascript version of the EWS Managed API. You may be able to get this to work in NodeJS.

Get all user properties from Microsoft graph

We have an application which has used a local AD to fetch user info. Some customers want to move to the cloud and are using Azure AD. We extended the app to sign users in via owin and now we're fetching users via Microsoft Graph.
However from Microsoft Graph we do not get full user profiles. We want to fetch all properties on users, not just the basic ones.
var client = new RestClient(string.Format("https://graph.microsoft.com/v1.0/users/{0}", userEmail));
request = new RestRequest();
request.Method = Method.GET;
request.AddHeader("Authorization", _token.Token);
var reponse = client.Execute(request);
This only gives me some information though, for example I don't get 'Department' from this.
Is it possible to configure in azure what should be returned here, if so then where? Or do I need something other than /users/?
Different customers might have different special properties that need to be fetched. So the best solution would be to have an endpoint to call and get everything, including special properties not standard in azure ad. After that I can parse it on my side. Is this possible?
The app has permission to read both basic and full profiles. Do I need something more?
That's the normal behaviour of Graph API, see documentation here and this extract:
By default, only a limited set of properties are returned (
businessPhones, displayName, givenName, id, jobTitle, mail,
mobilePhone, officeLocation, preferredLanguage, surname,
userPrincipalName).
To return an alternative property set, you must specify the desired
set of user properties using the OData $select query parameter. For
example, to return displayName, givenName, and postalCode, you would
use the add the following to your query
$select=displayName,givenName,postalCode
You have to specify all fields in the select, as $select=* will only output the key fields in Graph API implementation.
So you will not be able to get what you ask (variable custom fields).
More info on the fields of User can be found here
User user = await graphServiceClient
.Users[emailId]
.Request()
.Select(aadUser => new
{
aadUser.Id,
aadUser.UserPrincipalName,
aadUser.DisplayName,
aadUser.GivenName,
aadUser.Surname,
aadUser.City,
aadUser.MailNickname,
aadUser.UserType
})
.GetAsync()
.ConfigureAwait(false);
As already stated by NicolasR, you must list all the fields you want to retrieve by using the "$select" parameter; if you want, instead, to retrieve the custom fields, you can either add them to the previous parameter (if you know their names) or you can use "$expand=extensions"
function getGraphDataAdvanced($authToken, $urlGraph){
$url = $urlGraph + '&$count=true'
$data = (Invoke-RestMethod -Headers #{
Authorization = "Bearer $($authToken)"
ConsistencyLevel = "eventual"
} -Uri $url -Method Get)
$dataList = #()
$dataList += $data.value
$url = $data.'#Odata.NextLink'
while ($null -ne $url){
Write-Warning 'Retreiving Next Page'
$data = (Invoke-RestMethod -Headers #{
Authorization = "Bearer $($authToken)"
ConsistencyLevel = "eventual"
} -Uri $url -Method Get)
$dataList += $data.value
$url = $data.'#Odata.NextLink'
}
return $dataList
}
getGraphDataAdvanced $authToken 'https://graph.microsoft.com/beta/users? $expand=extensions'
Using the Microsoft Graph Explorer, I've been able to find all available properties for a user:
Go to "Groups"
Select "list all groups in my organization"
Change the query to filter by a group you know and expand members: https://graph.microsoft.com/v1.0/groups?$filter=mail eq 'aGroup#company.com'&$expand=members
Now you'll see all the available properties for the users.
I've been trying to find a way to get all Azure AD properties of objects via Powershell MSGraph cmdlets without it truncating at the right edge of the console.
I've discovered that Format-Custom triggers vomiting of (apparently) all properties of an object in a huge, alphabetical, indented, and bracketed list.
Get-MgUser -filter "startswith(userprincipalname, 'username')" | format-custom
The formatted properties of a newly created and unused user account in Azure AD is 13217 lines long.

Suitescript Scheduled Script ERROR: SSS_MISSING_REQD_ARGUMENT Details: id

I am trying to write a simple scheduled script to copy the total YTD Sales of a Sales Rep onto the Employee record daily. I was able to pull this information using a summary search, however, I am unable to Store the Value due to limitaions in the system. So I cannot query against that total with future searches/workflows. As a work around the only way I found possible to accomplish this is a daily scheduled script that will run the summary search and then copy the result for each Sales Rep into a custom field on the employee record. However when running it fails and I get the following error:
SSS_MISSING_REQD_ARGUMENT Details: id
The summary search is a transaction search grouping all transactions with a filter of Sales Rep:InternalId
Here is the code I am using. Thank you for your help.
function copyValues(){
var saleSearch = nlapiLoadSearch('transaction', 'customsearch_abi_totalsalesbyrep');
var resultSet = saleSearch.runSearch();
resultSet.forEachResult(function(searchResult){
var employeeId = searchResult.getValue('salesrep.internalid');
var employeeRec = nlapiLoadRecord('employee', employeeId);
employeeRec.setFieldValue('custentity_abi_ytdsalesstatic', employeeRec.getFieldValue('custentityabi_totalsalebyrep')); // Copy Total YTD Sales
nlapiSubmitRecord(employeeRec);
return true;
});
}
Have you checked if the variable employeeId is populated?
var employeeId = searchResult.getValue('salesrep.internalid');
For getting values from search results, I use this format
searchResult.getValue(<field id>,<join id>)
So in this case it would be
searchResult.getValue('internalid','salesrep')
Sublists are mandatory even if empty.

Thunderbird Addon - Filter by Sender

I have a list of email ids.i want to filter inbox messages and display only emails from those users in thunderbird. Please help me doing this.
This is what i tried so far and it's not working.But im getting completely irrelevant error message "We are unable to print or preview this page".
var gLocalIncomingServer = MailServices.accounts.localFoldersServer;
var gLocalMsgAccount = MailServices.accounts.FindAccountForServer(
gLocalIncomingServer);
var gLocalRootFolder = gLocalIncomingServer.rootMsgFolder
.QueryInterface(Ci.nsIMsgLocalMailFolder);
const kInboxFlag = Components.interfaces.nsMsgFolderFlags.Inbox;
var gLocalInboxFolder = gLocalRootFolder.getFolderWithFlags(kInboxFlag);
gLocalRootFolder.findSubFolder(gLocalInboxFolder.URI);
gLocalInboxFolder.setFlag(Ci.nsMsgFolderFlags.Mail);
// Force an initialization of the Inbox folder database.
var folderName = gLocalInboxFolder.prettiestName;
var aValue = "example#domain.com";
var aAttrib = Ci.nsMsgSearchAttrib.Sender;
var aop = nsMsgSearchOp.Contains;;
var hitCount = 1;
var searchListener =
{
onSearchHit: function(dbHdr, folder) { hitCount++; },
onSearchDone: function(status)
{
print("Finished search does " + aHitCount + " equal " + hitCount + "?");
searchSession = null;
do_check_eq(aHitCount, hitCount);
if (onDone)
onDone();
},
onNewSearch: function() {hitCount = 0;}
};
// define and initiate the search session
var hitCount;
var searchSession = Cc["#mozilla.org/messenger/searchSession;1"]
.createInstance(Ci.nsIMsgSearchSession);
searchSession.addScopeTerm(Ci.nsMsgSearchScope.offlineMail, gLocalInboxFolder);
var searchTerm = searchSession.createTerm();
searchTerm.attrib = aAttrib;
var value = searchTerm.value;
// This is tricky - value.attrib must be set before actual values
value.attrib = aAttrib;
value.str = aValue;
searchTerm.value = value;
if (aAttrib > nsMsgSearchAttrib.OtherHeader)
searchTerm.arbitraryHeader = gArrayHdrs[aAttrib - 1 - nsMsgSearchAttrib.OtherHeader];
searchTerm.op = aOp;
searchTerm.booleanAnd = false;
searchSession.appendTerm(searchTerm);
searchSession.registerListener(searchListener);
searchSession.search(null);
alert("search is done:");
Have you seen this Mozilla page? How do I search for a particular contact property (name, email)?
You don't really need to write any JS code to accomplish this. Thunderbird's search mechanism can be used in two UI-accessible ways:
Define a "saved search" folder. This filters one or more folders with a set of criteria and presents the results in a single folder. See and be aware you probably want an offline search since it will be faster than asking the IMAP server: http://kb.mozillazine.org/Saved_Search
Define a "mail view" that can be applied to any folder. Customize the mail toolbar by right clicking on it, choosing "customize..." and dragging the combo-box labeled "Mail Views" to the toolbar. Close the customize dialog by hitting "Done". Click on the combo-box on the toolbar, choose "customize...", hit "new..." to define and name your filter criteria. You can then apply the mail view by clicking on the combo box and locating it under the "Custom Views" header.
For your filter criteria, you can either type in all the names as separate predicates where "any" rule matches, or you might want to use the "is in my address book" predicate and just put all of those people in a special address book. For example, such a rule would look like: "From" "is in my address book" "cool people". You can create a new address book via "File... New... Address Book" from the Address Book window.
If you prefer to do things programatically and you want to be able to have the list of people vary at runtime, you will want to check out my blog post on creating quick filter bar extensions, as that's the easiest way to hook custom filtering logic into the Thunderbird UI that won't break:
http://www.visophyte.org/blog/2010/05/02/thunderbird-quick-filter-bar-extensions-theyre-a-thing/
Code for that example currently lives here on github:
github.com/asutherland/qfb-pivot
If your list of e-mails isn't going to change a lot, you can also create the "saved search folders" (virtual folders, internally), you should check out mxr.mozilla.org/comm-central/source/mailnews/base/src/virtualFolderWrapper.js and its createNewVirtualFolder method.
Apologies for de-hyperlinking two of the URLs, but the anti-spam mechanism won't let me have more than 2 links in the post...

Categories

Resources