How to show customized error message in moqui? - moqui

When I create a new record in WorkEffort and when I provide the workEffortId that already exists, then an error message displayed is:
(Error in update for:INSERT INTO WORK_EFFORT (WORK_EFFORT_ID, WORK_EFFORT_TYPE_ENUM_ID, STATUS_ID, WORK_EFFORT_NAME, DESCRIPTION, LAST_UPDATED_STAMP) VALUES (?, ?, ?, ?, ?, ?))
Now I want to show a customized error message to user instead of the technical one above, like :
"This workEffortId already exists".
Thanks in advance :-)

Just write a bit of code to check for the error condition, and then add an error message to the MessageFacade error list. In Groovy code this would be something like ec.message.addError(...) or .addValidationError(...). In XML Actions you can use the message or return action elements to do this (a return with error="true" plus a message is the most common way to do this in a service, for example).
For more details see the MessageFacade API JavaDoc and the XML Actions schema documentation on moqui.org, or the relevant sections in the Making Apps with Moqui book.

Related

Is there an automated way in SQL Server to add delta records to a table weekly from a .CSV file and a FTP secure site?

I have a table with training records of students with a 9 digit primary key for each student. Every week I will receive a delta file (new courses the students finish) in a .csv file dropped on a secure FTP server.
Is there an automated way to update the table weekly with the new records? The table is in SQL Server 2014. Thank you in advance.
SELECT
STUDENT_KEY, (New record might be added)
FIRST_NAME, (New record might be added)
LAST_NAME, (New record might be added)
COURSE_NAME, (New record might be added)
COURSE_NUMBER, (New record might be added)
SCORE, (New record might be added)
SCORE_DATE, (New record might be added)
TRAINING_HOURS (New record might be added)
FROM
STUDENTS_REC
Despite it's relationship to healthcare, I use Mirth Connect (Now called NextGen Connect Integration Engine) for this sort of thing regardless of industry. Open source, fairly lightweight, and infinitely configurable it can pickup CSV and other text, XML, and EDI Documents from a variety of sources, transform them, then push them to SQL Server. Using an Interface Engine like Mirth Connect results in monitorability and a dashboard, with built in error logging, archiving, and other benefits.
The same is also easily accomplished if you want to go the other direction. For example, you could have a query which sends results back to a SFTP server.
For the use case you describe (CSV to SQL), the solution might look like:
Create a new channel in Mirth
On the "Summary" tab, set Data Type to "Delimited Text" on the source connector, and XML on all the other connectors. (XML is the "native" Mirth format - you will not actually work with the XML directly)
In the "Delimited Text" inbound properties, set the column delimiter to "," and set the "Column Names" to "STUDENT_KEY,FIRST_NAME,LAST_NAME,COURSE_NAME,COURSE_NUMBER,SCORE,SCORE_DATE,TRAINING_HOURS" or whatever the columns present in the CSV File are.
On the "Source" tab, set the connector type to "File Reader" and add set the FTP server information. Key parameters would be "Method" of "FTP" or "SFTP" depending, Server and Path, filename filter, username, and Password.
Decide how to handle "Completed" files - you can either delete them or move them with the "After Processing Action". Leaving it at "None" will result in reprocessing all messages indefinately.
I recommend enabling "Check file age" to avoid reading the files while they are still being written. 60 seconds is usually sufficient for all but the largest or slowest writers.
Set the encoding of the files to be read, usually utf8 (which is I believe the default)
On the destination tab, select Connector Type of "Javascript Writer"
Write your script, calling SQL Server as needed:
Example Javascript with E4X:
var dbConn;
var result;
try {
dbConn = DatabaseConnectionFactory.createDatabaseConnection('net.sourceforge.jtds.jdbc.Driver','jdbc:jtds:sqlserver://127.0.0.1:1433/DBName','username','password');
// insert header
var params = new java.util.ArrayList();
params.add($('originalFilename'));
result = dbConn.executeUpdateAndGetGeneratedKeys('INSERT INTO ImportFiles ([Filename], ImportDate) VALUES (?, GETDATE());', params);
result.next();
var headerId = result.getInt(1);
// save in the channel map (message data) for fun
channelMap.put('headerId', headerId);
// loop over rows and insert
var msg = new XML(connectorMessage.getEncodedData());
for each (row in msg.row) {
if (row.Location.toString() == "Current Location") {
// skip headers
continue;
}
params = new java.util.ArrayList();
params.add(headerId);
params.add(row.SpillmanPatientID.toString());
params.add(row.AdmitDate.toString());
params.add(row.Location.toString());
params.add(row.TransferDate.toString());
params.add(row.LastName.toString());
params.add(row.FirstName.toString());
params.add(row.MiddleName.toString());
params.add(row.SuffixName.toString());
params.add(row.Birthdate.toString());
params.add(row.Sex.toString());
params.add(row.SSN.toString());
dbConn.executeUpdate('INSERT INTO dbo.ImportData (ImportFileID, SpillmanPatientID, AdmitDate, Location, TransferDate, LastName, FirstName, MiddleName, SuffixName, Birthdate, Sex, SSN)'
+ ' SELECT ?, ?, ?, GETDATE(), ?, ?, ?, ?, ?, ?, ?, ?, ?', params);
}
// call sproc
params = new java.util.ArrayList();
params.add(headerId);
dbConn.executeUpdate('EXEC dbo.ProcessImportFile ?', params);
} finally {
if (dbConn) {
dbConn.close();
}
}
Note that the members of "row" are whatever you specified for column names in the source connector setup.
Click "Deploy Channel" on the left
Verify operation using the dashboard. You can double click a channel to see the messages that have been sent (with results and error logs), and can right click and hit "Resend Message" to try again (for example, if you make a change to the script).
After you get things set the way you want, I would recommend:
On the summary tab in the Channel Setup
Set "Message storage" to "Production" or "Raw" - you can always move back to Development and reprocess a message if you have a problem
Set "Metadata Pruning" to (for example) 7 days
Set "Custom Metadata" - Remove SOURCE and TYPE, add originalFilename and any data you added to the channel map in your javascript. In the example above, I create a "headerId" which could be used to correlate between SQL and Mirth.

How to internationalization errors returned by API?

I'm wondering how to manage error in an API with multiple language.
I know there are multiple way to do that. I found 3.
Send a statusCode to front (with optionnal some data to manage dynamics values like : "you can manage only X users")
Send errors for all language ex :
{
en:"error is....",
fr:"l'erreur est...",
...
}
send just one error in the correct language
{
en:"error is...."
}
All of this have pro and cons...
the first :
+ API just manage statusCode and front(s) can manage error how it want
- API must manage dynamics error and send extra data
- Front must reformat the error (error + extra data)
others ?
the second :
+ error message can just be displayed on front without update it (but need to get the good one for the language client)
- back must manage error message for all language (if there are 10-50 or more language it's a little bit annoying)
- back end must take care of displaying message interstanding for a user (I think it's not is role)
others ?
the third :
+ error message can just be displayed on front without update it
- back end must take care of displaying message interstanding for a user (I think it's not is role)
- front must send the user's language at the session's begining and update this information if user change it
others ?
I think the third is the better but I don't know.
someone could say me what is the best solution and why ?
Thanks in advance :)

How to add parameters to API calls?

I'm using CareerBuilder's API:
http://api.careerbuilder.com/Search/jobsearch/jobsearchinfo.aspx
In the description, the endpoint is:
http://api.careerbuilder.com/v1/jobsearch
As the developer key is necessary, I assume that the key should insert after v1 with a ?, as follows:
http://api.careerbuilder.com/v1?DeveloperKey=XXXXXXXXXXXXXXXX/jobsearch
Then, if I put this into a browser, it should return me the XML as the output.
When I have done this, the page gave me 404 errors.
How does this type of API works? I assume it works like Google APIs
I eventually solve this by adding parameters at the end of the endpoint URL...
http://api.careerbuilder.com/v1/jobsearch?DeveloperKey=XXXXXXXXXXXXXXXX&ID=YYYYY

I am trying to use Yodlee/executeUserSearchRequest as a RESTful request and need an answer on how to call

I am working with the Yodlee services in c# and using the RESTful api. So far I have successfully connected and logged in with my CobrandSession and UserSessionToken in the development environment. I used the sample apps provided in c# and with some advice from shreyans i got an app working. What I got working was
1) Get YodleeAuthentication
2) Get UserAuthentication
3) Get ItemSummaries
I am now trying to get the full transaction details for each of the Items (i.e. collections of accounts that are an Item)
reading the Docs here https://developer.yodlee.com/Indy_FinApp/Aggregation_Services_Guide/REST_API_Reference/executeUserSearchRequest it states that I need to call executeUserSearchRequest and then paginate through the results using the getUserTransactions. So I am stuck at this point. I dont really want a search which has parameters I just want ALL transactions for this account that I can see.
However, I am using the variables as defined in that page :-
var request = new RestRequest("/jsonsdk/TransactionSearchService/executeUserSearchRequest", Method.POST);
request.AddParameter("cobSessionToken", param.CobSessionToken);
request.AddParameter("userSessionToken", param.UserSessionToken);
request.AddParameter("transactionSearchRequest.containerType", param.ContainerType);
request.AddParameter("transactionSearchRequest.higherFetchLimit", param.HigherFetchLimit);
request.AddParameter("transactionSearchRequest.lowerFetchLimit", param.LowerFetchLimit);
request.AddParameter("transactionSearchRequest.resultRange.endNumber", param.EndNumber);
request.AddParameter("transactionSearchRequest.resultRange.startNumber", param.StartNumber);
request.AddParameter("transactionSearchRequest.searchFilter.currencyCode", param.CurrencyCode);
request.AddParameter("transactionSearchRequest.searchFilter.postDateRange.fromDate", param.FromDate);
request.AddParameter("transactionSearchRequest.searchFilter.postDateRange.toDate", param.ToDate);
request.AddParameter("transactionSearchRequest.searchFilter.transactionSplitType.splitType", param.SplitType);
request.AddParameter("transactionSearchRequest.ignoreUserInput", param.IgnoreUserInput);
request.AddParameter("transactionSearchRequest.searchFilter.itemAcctId", param.ItemAcctId);
var response = RestClientUtil.GetBase().Execute(request);
var content = response.Content;
return new YodleeServiceResultDto(content);
As per the response from shreyans in this posting Getting Error "Any one of [**] of transactionSearchFilter cannot be NULL OR Invalid Values I am not putting in the ClientId and the ClientName
The documentation doesn't specify the format of the dates but the example seems to tell me that its american date format. And specifies a parameter saying IgnoreUserinput, but doesnt have a parameter for user input so this is confusing
When I make a call using this format I get an error response
var getSearchResult = yodleeExecuteUserSearchRequest.Go(yodleeExecuteUserSearchRequestDto);
getSearchResult.Result="
{"errorOccured":"true","exceptionType":"Exception Occured","refrenceCode":"_60ecb1d7-a4c4-4914-b3cd-49182518ca5d"}"
But I get no error message in this and I have no idea what I have done wrong or where to look up this error, can somebody who has used Yodlee REST Api point me in the right direction as I need to get this researched quickly....
thanks your your help, advice, corrections and pointers....
Here is the list of parameters which you can try
1) For a specific ItemAccountId all transactions
transactionSearchRequest.containerType=all
transactionSearchRequest.higherFetchLimit=500
transactionSearchRequest.lowerFetchLimit=1
transactionSearchRequest.resultRange.startNumber=1
transactionSearchRequest.resultRange.endNumber=500
transactionSearchRequest.searchClients.clientId=1
transactionSearchRequest.searchClients.clientName=DataSearchService
transactionSearchRequest.searchFilter.currencyCode=USD
transactionSearchRequest.searchClients=DEFAULT_SERVICE_CLIENT
transactionSearchRequest.ignoreUserInput=true
transactionSearchRequest.ignoreManualTransactions=false
transactionSearchRequest.searchFilter.transactionSplitType=ALL_TRANSACTION
transactionSearchRequest.searchFilter.itemAccountId.identifier=10000353
2) For a Specific account (itemAccountId) with start and end dates
transactionSearchRequest.containerType=all
transactionSearchRequest.higherFetchLimit=500
transactionSearchRequest.lowerFetchLimit=1
transactionSearchRequest.resultRange.startNumber=1
transactionSearchRequest.resultRange.endNumber=500
transactionSearchRequest.searchClients.clientId=1
transactionSearchRequest.searchClients.clientName=DataSearchService
transactionSearchRequest.searchFilter.currencyCode=USD
transactionSearchRequest.searchClients=DEFAULT_SERVICE_CLIENT
transactionSearchRequest.ignoreUserInput=true
transactionSearchRequest.ignoreManualTransactions=false
transactionSearchRequest.searchFilter.transactionSplitType=ALL_TRANSACTION
transactionSearchRequest.searchFilter.itemAccountId.identifier=10000353
transactionSearchRequest.searchFilter.postDateRange.fromDate=08-01-2013
transactionSearchRequest.searchFilter.postDateRange.toDate=10-31-2013

SugarCRM: Getting "Invalid Session ID" error with REST calls

I'm using SugarCRM CE 6.0.3.
When I make REST API calls like get_entry_list(), I always get this error:
{'description': 'The session ID is invalid',
'name': 'Invalid Session ID',
'number': 11}
I am very sure that I am logged in and using the correct session ID. In fact, when I can successfully call get_user_id() and retrieve my own user ID.
Googling has not produced any helpful results, anyone else encountered this problem?
I have found the problem, it is really just a matter of bad documentation on SugarCRM's part. The parameter naming is all wrong in this document:
http://developers.sugarcrm.com/docs/OS/6.0/-docs-Developer_Guides-Sugar_Developer_Guide_6.0-Chapter%202%20Application%20Framework.html#9000259
Simple fix for this problem: Do not use named parameters when making REST calls in SugarCRM. i.e. Use positional parameters (JSON array) for 'rest_data' in API calls.
I encountered this issue with the set_entry api call. For me the issue is one of the values that I was submitting to the call contained special characters that the api couldn't handle. My solution was to urlencode the value, and Sugar decodes it on their end. See below:
$name = "abc's ; 10/10/2013";
$values = array(
"name"=>$name
);
$sugar->set_entry("Accounts", $values);
The above threw the Invalid session ID error. Below is the code that works:
$name = urlencode("abc's ; 10/10/2013");
$values = array(
"name"=>$name
);
$sugar->set_entry("Accounts", $values);