Create a new item in a SharePoint list - sharepoint

I try to create a new list item, in general work fine, buy I have trouble with Person field.
On my list, I have two columns:
Employee -> Person type - it's for employee
EmployeeId -> Text field - it's like Employee ID from ex. AAD
EmployeeSuperior -> Person type - it's for employee superior
I need to create new item with filled only the Employee I got errors.
If request body is like:
{
"fields": {
"EmployeeLookupId": "6"
}
}
A new item is created by field EmployeeId is filled, but Employee is empty.
If request body is like:
{
"fields": {
"EmployeeLookupId": 6
}
}
I get error:
"message": "General exception while processing",
If request body is like:
{
"fields": {
"EmployeeSuperiorLookupId": "6"
}
}
A new item is created by field EmployeeSuperior correctly.
I think the EmployeeId field is confusing for MS Graph. But I cannot remove it, but I want to use MS Graph for adding new items.
Has anyone how write good request body?
I tried a few combinations of request body, on new list with the same fields but with new names. For my tests I'm usingĀ  Graph Explorer, no test in other ways.

Related

Netsuite email template - how to get child values from custentity field?

guys!
I'm writing an email template for the invoices. On the invoice form I have a "Project" (internalId: Job) field -> on the "Project" form I have a "custom entity" field with employee-type. I can get an employee's name with ${transaction.job.custentity5}. But I can't get access to related fields such as email, phone number and etc. The code ${transaction.job.custentity5.email} gives me nothing. The code ${transaction.job.custentity5.mobilephone} gives me a strange error like "field job.mobilephone not found" (netsuite hides custentity5 in this objects chain), but I see this field in employee's profile.
How do i get child values from custentity field?
Unfortunately, you can't go into such a deep level with the standard data provided.
You can however fetch the data with a search.lookupFields during a beforeLoad and set it as default value on a custom field of the form.
/**
* #NApiVersion 2.x
* #NScriptType UserEventScript
*/
define(['N/ui/serverWidget', 'N/search'], function(serverWidget, search) {
function beforeLoad(context) {
var invoice = context.newRecord;
var form = context.form;
var type = context.type;
var UserEventType = context.UserEventType;
// only execute during printing...
if (type != UserEventType.PRINT) return
var jobID = invoice.getValue({fieldId: 'job'});
// return when no job/project is set on the invoice...
if (!jobID) return
var job = search.lookupFields({
type: search.Type.JOB,
id: jobID,
columns: ["custentity5"]
})
// return when no employee is set on the project...
if (!(job.custentity5 && job.custentity5[0] && job.custentity5[0].value)) return
var employee = search.lookupFields({
type: search.Type.JOB,
id: job.custentity5[0].value,
columns: ["email", "phone"]
})
var field = form.addField({
id : 'custpage_custom_data_employee',
label: 'Employee',
type : serverWidget.FieldType.LONGTEXT
});
field.defaultValue = JSON.stringify(employee);
}
return {
beforeLoad: beforeLoad
};
})
You can access the data within the template through:
<#if record.custpage_custom_data_employee?has_content>
<#assign employee = record.custpage_custom_data_employee?eval />
</#if>
Netsuite doesn't drill down that far for you. Generally you get one step away from the primary record so you see a name using ${transaction.job.custentity5} because you'd see a name if you opened the associated job record.
How you can show the details from custentity5 depends on a bunch of factors like who is sending this email? Is is special enough to have its own button? Is the email being sent batch etc.
Options:
A before load user event script can check whether the record is being printed or emailed the standard way. That script can load and populate custom fields on the main record so you may be able to reference ${transaction.custpage_ent5.mobilephone} where you'd added the job's custom entity to the transaction
fully script your email using n/Render. You'll likely need to script everything but you can look up and add arbitrary records and datastructures to your renderer. This would be triggered by a custom button or batched script.

Issue creating or retrieving Customer Payment Method with Acumatica Rest API

Update:--- Code provided which fixes an issue on the graph which was preventing the API from allowing me to create.
public class CustomerPaymentMethodMaint_Extension:PXGraphExtension<CustomerPaymentMethodMaint>
{
#region Event Handlers
protected virtual void CustomerPaymentMethodDetail_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected del)
{
if (del != null)
{
del(cache, e);
}
if (Base.IsContractBasedAPI)
{
CustomerPaymentMethodDetail row = (CustomerPaymentMethodDetail)e.Row;
PXDefaultAttribute.SetPersistingCheck<CustomerPaymentMethodDetail.value>(cache, row, PXPersistingCheck.Nothing);
}
}
#endregion
}
For the life of me, I cannot figure out what Acumatica is expecting me to send to it to either retrieve or create a customer payment method using the Rest API. It would be greatly appreciated if you could point me in the right direction. The examples we are given are very basic and don't seem to cover any scenarios such as this.
I would assume it would be retrieved using the standard "Retrieval of a Record by Key Fields" as described in the help section.
I have tried using all of the below url structures and it either gives me an "Operation is not valud due to the current state of the object" error, or "More than one entity satisfies the condition".
/entity/Default/6.00.001/CustomerPaymentMethod/{BAccountID}/{PMInstanceID}
/entity/Default/6.00.001/CustomerPaymentMethod/{AcctCD}/{PMInstanceID}
/entity/Default/6.00.001/CustomerPaymentMethod/{BAccountID}
/entity/Default/6.00.001/CustomerPaymentMethod/{PMInstanceID}
/entity/Default/6.00.001/CustomerPaymentMethod/{AcctCD}
While trying to create a payment method I tried using a "PUT" to the CustomerPaymentMethod endpoint with the following json Body (I also tried using the soap friendly names of these fields instead of the label thats in the UI "CCDNUM","CVV","EXPDATE","NAMEONCC"). The error I get returned to me is that "Value" cannot be empty.
{
"CustomerID" : { value: "0000467" },
"PaymentMethod" : { value: "CC" },
"CustomerPaymentMethodDetail" : [
{
"Description" : { value : "Card Number" },
"Value" : { value : "4111111111111111" },
},
{
"Description" : { value : "Expiration Date" },
"Value" : { value : "102020" },
},
{
"Description" : { value : "Name on the Card" },
"Value" : { value : "Test API" },
}
]
}
The following works for me on a project where I'm using APS (American Payment Solutions) as the Processing Center.
Use GET to retreive a collection of Customer Payment Methods for a specific customer:
/entity/Default/6.00.001/CustomerPaymentMethod/?$filter=CustomerID+eq+'000000'
Use GET to return a single Customer Payment Method by ID: (You can find the ID from a record returned by the call above.)
/entity/Default/6.00.001/CustomerPaymentMethod/guid-from-record?$expand=Details
I don't think it's possible to create a Customer Payment Method using a brand new card with the Acumatica API. I think you'll first have to create the payment record using your processing center's API. (APS in my case, but I assume Authorize.net works in a similar fashion.) Then, once the payment record exists at the processor, you can add the Customer Payment Record in Acumatica using a PUT to populate the Payment Profile ID, which is a reference to the tokenized card. From there, you can use the GET calls above to return what you need in order to auth/capture a Sales Order.
I'm working through this now and I'll update my comment once I've learned more.
For me the following worked
/entity/Default/{version}/CustomerPaymentMethod/{customerID}/{customerPaymentMethodId}
Now to get the customerPaymentMethodId this can be done via the customer endpoint when expanding PaymentInstructions.
However unfortunately PaymentInstructions only returns the default payment method for the customer.

MongoDB find documents based on array of values

I have one collection, called "games" whose documents store the ids of the owners of games.
{
"owner" : "88878b6c25c167d"
}
{
"owner" : "88878b6c25c167d"
}
{
"owner" : "af565f77f73469b"
}
Then I have another collection called "users".
{
"id" : "af565f77f73469b"
}
{
"id" : "a881335e1d4cf17"
}
{
"id" : "aa3ce3f7767c46b"
}
{
"id" : "d19e52c0bd78bcb"
}
{
"id" : "88878b6c25c167d"
}
So the first query I do retrieves the owners of all the games and stores those values in an array.['88878b6c25c167d', '88878b6c25c167d', 'af565f77f73469b']
The second query I want to perform should retrieve the documents of the users with the corresponding IDs. Previously I had used this query:
db.users.find({'id':
{'$in': [
'88878b6c25c167d',
'88878b6c25c167d',
'af565f77f73469b'
]}})
Here's the problem with this: It does not return duplicate documents if a user is listed twice, as above. Instead I just get one. This breaks my application. How can I make sure that each owner returns a document?
MongoDB works perfectly fine --- it finds all user, whose id-s are contained in the array.
Do not know the broader context of your needs (maybe tell us what you want to achieve -- not what is wrong?), but if you want to have an association between games and users something like that may be suitable:
after retrieving collection of games; just create an auxiliary hash map (normal JS object) that for given owner id will return the array of its games.
retrieve info about users who are owners.
if you want to know, which games belong to particular user just pass her id to data structure from 1. and get the arrays with games.
Is it what you were looking for? Do you need help with 1.?

Saving a Person or Group field using REST

Does anyone know how to save a Person field using REST?
I have tried the following and it works:
{
"__metadata": { "type": "SP.Data.SomeListListItem" } ,
"MyPersonFieldId" : 1
}
But this only works if you know the ID. I don't have that! How can I get it? I have the key which is i.0#w|domain\userName.
I tried the following and it doesnt work either:
{
"__metadata": { "type": "SP.Data.SomeListListItem" } ,
"MyPersonField" : { "__metadata": { "type": "SP.Data.UserInfoItem" }, "Name": "i.0#w|domain\userName" }
}
Any ideas?? Thanks!
I haven't done this with a Person field, but I did do something similar with a managed metadata field. I basically had to pass in additional information as an object to create the value in the field.
See if passing in the ID of the user along with the name works. I'm about to try this myself as I have the same need.
{
"MyPersonField": { "Name": "i.0#w|domain\userName", "ID": 1 }
}
EDIT: Ok, updating this field is easier than I thought. I was able to perform the update by simply passing in the ID of the user to the Id field:
{
"MyPersonFieldId": 1
}
This means the user should already be in the site collection, so if the user doesn't exist the request will fail.
Use the below code to get Current User ID to save user under People and group column. People column name is Requestor. But to save user we have to specify column name as RequestorId
var userid = _spPageContextInfo.userId; // To get current user ID
var itemProperties={'Title':vTitle,'RequestorId':userid};
The thing is that User information is a lookup field thereby MyPersonField does not exist on your SharePoint list if you use an OData endpoint, I really don't know how to save data but same problem happened to me when I tried to read a user.
for example {server}/{api}/list/getbytitle('mylist')/items does not return MyPersonField instead return MyPersonFieldId.
But if we use:
{server}/{api}/list/getbytitle('mylist')/items/?$select=*,MyPersonField/Name&$expand=MyPersonField
We are able to work with MyPersonField lookup values.

Automatic document updates in couchdb

I have 10,000+ couchdb documents, each having (simplified) format like -
{
"First Name" : "John",
"Last Name" : "Doe"
}
I want to add another field to this document, which is e-mail, so that document now looks like -
{
"First Name" : "John",
"Last Name" : "Doe",
"e-mail" : ""
}
I understand that I can easily update this document by inserting a new JSON, in new format.
But my question is how can I add new field automatically to "all 10,000+" docs that I have existing in the DB? Do I need to write my own script to read each doc and update each one of them individually? Or is there a simpler way?
If you use views to access your data, you can modify the view without having to modify the documents. Just emit an email value with a default of "".
Assuming the above is no good, use a view to show you which documents need upgrading.
function(doc) {
// views.email_upgrade.map
if(! ('e-mail' in doc)) {
var key = [doc["Last Name"], doc["First Name"]];
emit(key, {_id:doc._id, _rev:doc._rev});
}
Query /db/_design/foo/_view/email_upgrade?include_docs=true. You can add a &limit=N property to help. Query. The doc value in each row is a document that needs to upgrade. You can send them back with POST /db/_bulk_docs. Loop until you have 0 rows. Once you have 0 rows, add a check to your validate_doc_update function.

Resources