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.
Related
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
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'])
I am an inexperience technical developer working on my first SuiteScript using SuiteScript 1.0. I am getting an SSS_MISSING_REQD_ARGUMENT error, but I am sure there are many more in my code. The purpose of the script is to populate the department field on the expense record line item from a joined record. The end user will select a Project on the expense line, and the script should look up the department on the project record (a custom field) and add the value to the native department field. Code is copied below.
function ProjectSegment ()
{
var record = nlapiLoadRecord(nlapiGetRecordType(), nlapiGetRecordId());
var recordID = nlapiGetRecordId(record);
//internal ID of project record
var project = nlapiGetField ('custcol_nra_expense_project');
//load project record
var precord = nlapiLoadRecord('job', project);
//get department on project record (internal ID)
var pdepartment = precord.GetFieldValue('custentity_nra_dept_project');
//get project name from project record
var projectName = precord.GetFieldText('entityid');
//load existing search
var search = nlapiLoadSearch('job','customsearch161');
//add filter to include project name
search.addFilter(new nlobjSearchFilter('entityid',null,'is',projectName));
//run search
var resultSet = search.runSearch();
//get department line
var departmentResult = new nlobjSearchColumn('custentity_nra_dept_project');
//set value
nlapiSetFieldTexts('job','department',1,departmentResult)
//record.commitLineItem('department');
nlapiSubmitRecord(record, true);
}
//internal ID of project record
var project = nlapiGetFieldValue ('custcol_nra_expense_project');
Praveen Kumar's response is correct regarding the missing required argument, but there are many other issues with the script as you've surmised.
Side notes:
The getFieldValue and getFieldText methods of nlobjRecord are not capitalized.
For performance reasons, you could/should use a search to get the values you need from the job record. Loading a record just to get field values is wasteful unless you mean to change the record.
Your search filter should probably be based on the value (not text) of the entityid in the job record.
Your desired search column probably is invalid (I don't think a custentity field could be on a job record).
Getting the search result is incorrect.
You want something like this instead:
var result = resultSet.getResults(0, 1);
if (result) {
var department = result.getValue('custentity_nra_dept_project');
// etc.
}
All that said, though, from your description, I don't think you need the search anyway. Once you have pdepartment (again, using precord.getFieldValue), I think all you need is:
record.setFieldValue('department', pdepartment);
Or if you're setting the line-level department, it would be different.
What kind of script is this? I'd like to make more recommendations, but it depends on what's going on.
I am currently trying to append data through I pull from Firebase to a table in the order of newest to oldest posts. I currently have the following setup in my code base (simplified to address issue):
var theDataRef = new Firebase('https://my-app.firebaseio.com');
theDataRef.orderByChild("timestamp").limitToLast(25).on('child_added', function (snapshot) {
var message = snapshot.val();
displaytableRow(message.name, message.text);
}
function displaytableRow(name, message) {
$("#sch").find('tbody > tr:first')
.before($("<tr><td><div>" + name + ":" + message + "</div></td></tr>"))
};
I have tried to create a table that displays newest to oldest data by using both firebase and jquery techniques but every time my data is displayed in a random order. I have a working timestamp field on every record in my data as well but even ordering by that does not solve the problem. Has anybody had any experience building this successfully?
EDIT:
The timestamp is gotten with the following code:
var timestamp = Firebase.ServerValue.TIMESTAMP;
And the database architecture is structured like so:
If you want to order your posts from newest to oldest you can do the following:
1/ Store a field in your post that is the inverse of the TimeStamp as follows:
var tDate = new Date().getTime();
var postData = {
//.....
timestampInverted: (0 - tDate),
//.....
};
2/ Query your posts ordered by this field as follows:
theDataRef.orderByChild("timestampInverted").limitToLast(25).once('value', function(snapshot) {
snapshot.forEach(function(childSnapshot) {
displaytableRow(childSnapshot.val().name, childSnapshot.val().text);
});
});
It is important to note that theDataRef.orderByChild("timestampInverted").limitToLast(25) returns a Query, which returns a DataSnapshot : Therefore you need to use snapshot.forEach() (see doc here) to iterate over the different posts items.
Also note that "even when there is only a single match for the query, the snapshot is still a list; it just contains a single item. To access the item, you always need to loop over the snapshot".
I have 2 tables which are both in an Azure SQL Database which is connected to my Lightswitch Sharepoint app. I am doing some manipulation of the data in code, and it appears to be working, except that when I load the entities from one table, I am not able to see the related entities in the other.
Basically, I have a products table and an invoice lines table. Each invoice line record contains a product code, which relates to the products table PK. I have defined the relationship in Lightswitch, but when I load the invoice line record, I can't see the product information.
My code is as follows:
// Select invoice and get products
myapp.AddEditServiceRecord.InvoicesByCustomer_ItemTap_execute = function (screen) {
screen.ServiceRecord.InvoiceNumber = screen.InvoicesByCustomer.selectedItem.INVO_NO;
// Delete existing lines (if any)
screen.ServiceDetails.data.forEach(function (line) {
line.deleteEntity();
});
// Add products for selected invoice
screen.getInvoiceLinesByNumber().then(function (invLines) {
invLines.data.forEach(function (invLine) {
invLine.getProduct().then(function (invProduct) {
var newLine = new myapp.ServiceDetail();
newLine.ServiceRecord = screen.ServiceRecord;
newLine.ProductCode = invLine.ProductCode;
newLine.ProductDescription = invProduct.Description;
newLine.CasesOrdered = invLine.Cases;
});
});
});
};
The idea is that a list of invoices are on the screen 'InvoicesByCustomer', and the user clicks one to add the details of that invoice to the 'ServiceRecord' table. If I comment out the newLine.ProductDescription = invProduct.Description line it works perfectly in adding the correct product codes and cases values. I have also tried a few other combinations of the below code, but in each case the related product entity appears as undefined in the Javascript debugger.
EDIT: I also read this article on including related data (http://blogs.msdn.com/b/bethmassi/archive/2012/05/29/lightswitch-tips-amp-tricks-on-query-performance.aspx) and noticed the section on 'Static Spans'. I checked and this was set to 'Auto (Excluded)' so I changed it to 'Included', but unfortunately this made no difference. I'm still getting the invProduct is undefined message. I also tried simply invLine.Product.Description but it gives the same error.
The solution in this case was a simple one. My data was wrong, and therefore Lightswitch was doing it's job correctly!
In my Invoices table, the product code was something like 'A123' whereas in my Products table, the product code was 'A123 ' (padded with spaces on the right). When doing SQL queries against the data, it was able to match the records but Lightswitch (correctly) saw the 2 fields as different and so could not relate them.
I may have wasted several hours on this, but it's not wasted when something has been learnt...or so I'll tell myself!