Perform workflow transition programmatically in liferay? - content-management-system

I have two transition named "approved" and "reject" at the lastest step of my workflow, but i want to controll the workflow action from my portlet.
Anybody know How to Perform workflow transition programmatically in liferay ?

my current code
JournalArticle journalArticle = JournalArticleLocalServiceUtil.getArticle(id);
getPermissionChecker().init(u.getUser(), true);
WorkflowInstanceLink wil= WorkflowInstanceLinkLocalServiceUtil.getWorkflowInstanceLink(companyId, journalArticle.getGroupId(), JournalArticle.class.getName(), journalArticle.getId());
WorkflowInstance workflowInstance = WorkflowInstanceManagerUtil.getWorkflowInstance(companyId, wil.getWorkflowInstanceId());
Map<String, Serializable> workflowContext = workflowInstance.getWorkflowContext();
List<Integer> logTypes_assign = new ArrayList<Integer>();
logTypes_assign.add(WorkflowLog.TASK_ASSIGN);
List<WorkflowLog> workflowLogs_assign = WorkflowLogManagerUtil.getWorkflowLogsByWorkflowInstance(companyId, wil.getWorkflowInstanceId(), logTypes_assign, QueryUtil.ALL_POS, QueryUtil.ALL_POS, WorkflowComparatorFactoryUtil.getLogCreateDateComparator(true));
//WorkflowPermissionUtil.hasPermission(permissionChecker, groupId, className, classPK, actionId);
if(workflowLogs_assign.size() > 0){
long taskId = workflowLogs_assign.get(workflowLogs_assign.size()-1).getWorkflowTaskId();
WorkflowTask task = WorkflowTaskManagerUtil.getWorkflowTask(companyId, taskId);
_log.info("task : "+task.getName());
WorkflowTask nextTask = WorkflowTaskManagerUtil.assignWorkflowTaskToUser(companyId, userId, task.getWorkflowTaskId(), userId, "auto assign", task.getDueDate(), workflowContext);
WorkflowTaskManagerUtil.completeWorkflowTask(companyId, userId, nextTask.getWorkflowTaskId(), "next task transition name", "next task name", workflowContext);
}

workflowInstance1 = WorkflowInstanceManagerUtil.signalWorkflowInstance(service.getCompanyId(), user.getUserId(),
workflowInstanceId, transitionNAME, workflowInstance.getWorkflowContext());

Related

How to launch contact detail activity of directory contact in android

I am Trying to launch the detail page of directory contacts(Some organigation contacts) with contact id. for local contacts it is working fine but not working for organigation contacts.
Here is my code. (name is contact name ,idstr is directory id )
lookupByName = ContactsContract.Contacts.CONTENT_FILTER_URI.buildUpon().appendEncodedPath(name)
.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, idStr).build();
mCursor = mContext.getContentResolver().query(lookupByName, new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup._ID}, null, null, null);
if (mCursor.moveToFirst()) {
idPhone =
Long.valueOf(mCursor.getString(
mCursor.getColumnIndex(ContactsContract.PhoneLookup._ID)));
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(ContentUris.
withAppendedId(ContactsContract.Contacts.CONTENT_URI, idPhone ));
startActivity(intent);
Please help me.
Thanks in advance.
This is tricky, but managed to get it working
You need to get the contact's LOOKUP_KEY, build a LookupUri from it, append the DIRECTORY_PARAM_KEY to the LookupUri, and put that in the intent's setData.
String name = "hello";
String directoryId = "5"
Uri uri = Contacts.CONTENT_FILTER_URI.buildUpon().appendPath(name).appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, directoryId).build();
String[] projection = new String[]{Contacts._ID, Contacts.DISPLAY_NAME, Contacts.LOOKUP_KEY};
Cursor cur = getContentResolver().query(uri, projection, null, null, null);
DatabaseUtils.dumpCursor(cur); // debug
// add some safety checks first obviously...
cur.moveToFirst();
String lookup = cur.getString(2);
Uri lookupUri = Contacts.getLookupUri(cur.getLong(0), lookup).buildUpon().appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, directoryId).build();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(lookupUri);
startActivity(intent);

Test Class in apex

So i am new to salesforce and i finished my training and now im working on a project. But on my project i have stumbled on a test class that i am not finding a way to write it, so i would appreciate if anyone can help me figure out a way to write it. Here is the code:
public class AP01_Opportunity
{
//Method to create a new service contract when opportunity = Gagné
public static void CreateContract(List<Opportunity> listOpp, Map<Id, Opportunity> oldMap)
{
//Variable Declaration
ServiceContract sc;
List<ServiceContract> listSCToAdd = new List<ServiceContract>();
List<ContractLineItem> listContractItems = new List<ContractLineItem>();
List<Opportunity> listOppGagne = new list<Opportunity>();
//Loop in list of opportunities
for(Opportunity opp : listOpp)
{
if(opp.StageName == Label.ClotureGagne && !oldMap.get(opp.Id).isWon)
{
listOppGagne.add(opp);
}
}
//check if list has opportunity becoming won
if(listOppGagne.size() > 0){
Map<Id, Opportunity> mapOppGagne = new Map<Id, Opportunity> ([SELECT Id,
Name,
StageName,
Pricebook2Id,
Account.Name,
(SELECT Id,
PricebookEntryId,
PricebookEntry.Name,
Quantity,
UnitPrice
FROM OpportunityLineItems)
FROM Opportunity
WHERE Id in :listOppGagne]);
for( Opportunity opp : listOppGagne )
{
//Create new service contract
sc = new ServiceContract();
sc.Name = opp.Name;
sc.ApprovalStatus = Label.Activated;
sc.OpportunityId__c = Id.valueOf(opp.Id);
sc.Pricebook2Id = opp.Pricebook2Id;
sc.StartDate = Date.today();
listSCToAdd.add(sc);
}
if(listSCToAdd.size() > 0){
insert listSCToAdd;
Opportunity currentOpp;
ContractLineItem cli;
Id oppId;
for(ServiceContract servcont : listSCToAdd)
{
oppId = servcont.OpportunityId__c;
if(mapOppGagne.containsKey(oppId))
{
currentOpp = mapOppGagne.get(oppId);
//copy the oppLineItems per opportunity to the respective Service Contract
for(OpportunityLineItem items : currentOpp.OpportunityLineItems)
{
cli = new ContractLineItem();
cli.PricebookEntryId = items.PricebookEntryId;
cli.Quantity = items.Quantity;
cli.UnitPrice = items.UnitPrice;
cli.ServiceContractId = servcont.Id;
listContractItems.add(cli);
}
}
}
if(listContractItems.size() > 0)
{
insert listContractItems;
}
}
}
}
}
this code is a trigger that creates a new service contract record with contract line items copied from the opportunity line items, when the opportunity stage changes to "Cloturé Gagné" which means closed won in french.
Thank you in advance.
In order to write a simple test class I would recommend you to use the following guide: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_qs_test.htm
The idea is simple: Lets say you create an Opportunity in your Test class and make an insert or update in your case - your trigger class will automatically fire and run the code from your AP01_Opportunity class. You can put some
System.debug('some message');
to check if your logic works as expected and also which code blocks are executed

Apex class is called in a trigger based on some conditions.Test class passes the test but code coverage is stil 0%

When work order updates to Completed then a new water meter reading record needs to created with two field values from work order and two from another object att. Both work order and water meter reading have a look up(workorder) and master detail relation(water meter reading) with att.Sorry for so much code,but I am really stuck and need help.
trigger CreateWaterMeterReading on sm1e__smWork_Order__c (after update)
{
if (Trigger.new.size() == 1)
{
sm1e__smWork_Order__c wo = Trigger.new[0];
if(wo.sm1e__WO_Type__c == 'Meter Read Move In/Out ' && wo.sm1e__Status__c == 'Completed')
reateNewWaterMeterRead.createWMRforMoveInOrOut(wo.Id);
}
}
--Apex class
public class CreateNewWaterMeterRead {
public static void createWMRforMoveInOrOut(string workorderId)
{
Work_Order__c wo = [Select Equipment__r.Name,Completion_Date__c,Meter_Reading__c from Work_Order__c where Id = : workorderId ];
Equipment__c att = [Select Id,Last_Water_Meter_Reading_Date__c,Last_Water_Meter_Reading__c from Equipment__c where Name = : wo.Equipment__r.Name ];
List<Water_Meter_Readings__c> newwmr = new List<Water_Meter_Readings__c>();
Water_Meter_Readings__c wmr = new Water_Meter_Readings__c();
wmr.Meter__c = att.Id;
wmr.Current_Meter_Reading__c = wo.Meter_Reading__c;
wmr.Current_Read_Date__c = wo.sm1e__Completion_Date__c;
wmr.Prior_Meter_Reading__c = att.Last_Water_Meter_Reading__c;
wmr.Prior_Read_Date__c = att.Last_Water_Meter_Reading_Date__c;
wmr.Source__c = 'Manual Read';
newwmr.add(wmr);
if(newwmr.size() >0)
insert newwmr;
}
--Test Class
isTest(SeeAllData = true)
public class CreateNewWaterMeterReadTest
{
static testmethod void createWMRforMoveInOrOut()
{
Work_Order__c wo = [Select Id,Equipment__r.Name,Completion_Date__c,Meter_Reading__c from Work_Order__c where sm1e__Status__c != 'Completed' AND sm1e__WO_Type__c = 'Meter Read Move In/Out' LIMIT 1];
Equipment__c att = [Select Id,Last_Water_Meter_Reading_Date__c,Last_Water_Meter_Reading__c from Equipment__c where Name = : wo.Equipment__r.Name ];
test.startTest();
wo.Meter_Reading__c = 1317;
wo.sm1e__Status__c = 'Completed';
update wo;
test.stopTest();
System.debug('updated wo');
Water_Meter_Readings__c wmr = new Water_Meter_Readings__c();
System.debug('wmr for test');
wmr.Meter__c= att.Id;
wmr.Current_Meter_Reading__c = wo.Meter_Reading__c;
wmr.Current_Read_Date__c = wo.Completion_Date__c;
System.debug('in between wmr');
wmr.Prior_Meter_Reading__c = att.Last_Water_Meter_Reading__c;
wmr.Prior_Read_Date__c = att.Last_Water_Meter_Reading_Date__c;
wmr.Source__c = 'Manual';
insert wmr;
You've written trigger on after update. But in your test class you're inserting a record and not updating it. That is why your code coverage is 0%. Refer to this link
For executing trigger you must do dml operation for which you've written a trigger. Also you can invoke your class method from test class by creating its instance. Refer above link for the same.

Trigger Help: Capture user from custom object (ticket) and assign task to user (task object)

I am very new to apex coding. Please see trigger below which creates a task when a ticket is raised with priority high. The trigger works except for this line : // t.Owner = Tickets__c.Assigned_To__c;
I am trying to pick up the the user to whom the ticket is assigned via field Assigned_To__c in the custom ticket object and then create a task where the owner of the task is the same user as the 'Assigned to' field captures in the ticket object.
What do I need to do to pick up the user captured in a field (Assigned to) in a custom object (ticket) and then assign the same user as owner of a task?
Trigger compiles except for the commented line:
trigger AssignTicket on Tickets__c (after insert,after update) {
for(Tickets__c tkt : trigger.new){
if(tkt.Priority__c == 'High'){
task t = new task();
t.Subject = 'Ticket has been assigned to you!';
t.Status = 'Not Started';
t.Priority = 'Normal';
//t.Owner = Tickets__c.Assigned_To__c.; **[Need help with this line]**
t.WhatId = tkt.id;
insert t;
}
}
Take the insert out of the loop and set OwnerID, not Owner.
List<Task> lInsert = new List<Task>();
for(Tickets__c tkt : trigger.new){
if(tkt.Priority__c == 'High'){
task t = new task();
t.Subject = 'Ticket has been assigned to you!';
t.Status = 'Not Started';
t.Priority = 'Normal';
t.OwnerID = Tickets__c.Assigned_To__c.; **[Need help with this line]**
t.WhatId = tkt.id;
lInsert.Add(t);
}
}
insert lInsert;

How do I test a trigger with an approval process?

I have a trigger which initiates an approval process when certain criteria are met:
trigger AddendumAfterIHMS on Addendum__c (after update) {
for (integer i = 0; i<Trigger.new.size(); i++){
if(Trigger.new[i].RecordTypeId != '012V0000000CkQA'){
if(Trigger.new[i].From_IHMS__c != null && Trigger.old[i].From_IHMS__c == null){
ID addendumId = Trigger.new[i].Id;
// Start next approval process
Approval.ProcessSubmitRequest request = new Approval.ProcessSubmitRequest();
request.setObjectId(addendumId);
Approval.ProcessResult requestResult = Approval.process(request);
}
}
}
}
It works perfectly, but now i need to create a test class for it. I have created a class which brings the code up to 75% coverage, which is the minimum, but I'm picky and like to have 100% coverage on my code. The test class I have now gets stuck on the line request.setObjectId(addendumId); and doesn't move past it. The error I receive is:
System.DmlException: Update failed. First exception on row 0 with id a0CV0000000B8cgMAC; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AddendumAfterIHMS: execution of AfterUpdate
Here is the test class that I have written so far, most of the class actually tests some other triggers, but the important line which is throwing the error is the very last line update addendumTierFeature;
#isTest
private class AddendumTest {
static testMethod void myUnitTest() {
// Query Testing Account, will need ID changed before testing to place into production
Account existingAccount = [SELECT Id FROM Account LIMIT 1];
Model__c existingModel = [SELECT Id FROM Model__c WHERE Active__c = TRUE LIMIT 1];
Pricebook2 existingPricebook = [SELECT Id,Name FROM Pricebook2 WHERE IsActive = TRUE LIMIT 1];
List<Contact> existingContacts = [SELECT Id,Name FROM Contact LIMIT 2];
Contact existingContactPrimary = existingContacts[0];
Contact existingContactSecondary = existingContacts[1];
Opportunity newOpportunity = new Opportunity(
Name = 'New Opportunity',
Account = existingAccount,
CloseDate = Date.today(),
Order_Proposed__c = Date.today(),
StageName = 'Branch Visit - Not Responding',
Opportunity_Follow_Up__c = 'Every 120 Days',
LeadSource = 'Farm Lists',
Source_Detail__c = 'FSBO',
Model_Name__c = existingModel.Id,
Processing_Fee__c = 100.50,
Site_State__c = 'OR',
base_Build_Zone__c = 'OR',
Pricebook_from_Lead__c = existingPricebook.Name
);
insert newOpportunity;
//system.assert(newOpportunity.Id != null);
ID newOppId = newOpportunity.Id;
OpportunityContactRole contactPrimary = new OpportunityContactRole(
Role = 'Primary',
IsPrimary = true,
OpportunityId = newOppId,
ContactId = existingContactPrimary.Id
);
OpportunityContactRole contactSecondary = new OpportunityContactRole(
Role = 'Primary',
IsPrimary = false,
OpportunityId = newOppId,
ContactId = existingContactPrimary.Id
);
insert contactPrimary;
insert contactSecondary;
newOpportunity.Name = 'Different - Updating';
newOpportunity.Order_Accepted__c = Datetime.now();
update newOpportunity;
Addendum__c addendumCustomOption = new Addendum__c(
RecordTypeId = '012V0000000CkQA', //Pre Priced Custom Option
Opportunity__c = newOppId,
Item_Pre_Priced_Description__c = 'a1eV00000004DNu',
Reason__c = 'This is a reason',
Item__c = 'This is an Item',
Quantity__c = 1
);
Addendum__c addendumTierFeature = new Addendum__c(
RecordTypeId = '012V0000000Cjks', //Tier Feature
Opportunity__c = newOppId,
Category__c = 'Countertops',
Reason__c = 'This is a reason',
Item__c = 'This is an Item',
Quantity__c = 1
);
insert addendumCustomOption;
insert addendumTierFeature;
addendumCustomOption.Quantity__c = 2;
addendumTierFeature.Quantity__c = 2;
update addendumCustomOption;
update addendumTierFeature;
update newOpportunity;
addendumTierFeature.To_IHMS__c = system.now();
update addendumTierFeature;
addendumTierFeature.From_IHMS__c = system.now();
update addendumTierFeature;
}
}
Any help on this matter would be greatly appreciated. I believe the problem is in the way I am testing the approval process start. Is there by chance a special testing function for this?
After fiddling around for a little while I discovered that the error was actually tied into my approval process. I kept digging into the error logs until I got to the error: caused by: System.DmlException: Process failed. First exception on row 0; first error: MANAGER_NOT_DEFINED, Manager undefined.: []. This phrase indicates that there is no one defined for the next step in my approval process.
When I created the opportunity, I did not set the owner and somehow this created an opportunity which had an owner without a manager. The addendum was also created without an owner/manager. So when I tried to launch the next approval process, there was no manager to send the approval to and an error was thrown.