PDF
Download PDF
Download page Use Case and Sample Code for Ad Hoc Approval Runtime Process APIs.
Use Case and Sample Code for Ad Hoc Approval Runtime Process APIs
The Ad Hoc Approval feature allows an approver to add a new approval step in an active approval process. For example, if, while approving a request, the Deal Desk concludes that a quote will require additional approvals from Legal and the CFO, creates those approval steps for a quote, decides the sequence for approval, and creates a new approval step. You can create and modify an ad hoc approval process in runtime.
API flow for an ad hoc approval runtime process:
- Create a runtime ad hoc approval process
- Add comments
- Add attachments
- Update the process
- Retrieve the ad hoc process
- Delete attachments from an existing ad hoc process
This sample code shows how you can use the following 7 APIs to create, read, update, and retrieve ad hoc approval runtime process info and be able to add comments and attachments to it.
/**
* Apttus Approvals Management
* ApprovalsWebServiceTestSample
*
* @2019 Apttus Inc. All rights reserved.
*/
public with sharing class AdhocApprovalsWebServiceTestSample {
/**
* Class Constructor
*/
public AdhocApprovalsWebServiceTestSample() {
}
// test webservice API calls by running as anonymous apex from developer console
//AdhocApprovalsWebServiceTestSample.TestCreateRuntimeAdhocApprovalProcess('Apttus__APTS_Agreement__c','a07q000000EZfki');
//AdhocApprovalsWebServiceTestSample.TestUpdateRuntimeAdhocApprovalProcess('Apttus__APTS_Agreement__c','a07q000000EZfki');
//AdhocApprovalsWebServiceTestSample.TestGetRuntimeAdhocApprovalProcess('Apttus__APTS_Agreement__c','a07q000000EZfki');
//AdhocApprovalsWebServiceTestSample.TestAddCommentToRuntimeAdhocApprovalProcess('Apttus__APTS_Agreement__c','a07q000000EZfki');
//AdhocApprovalsWebServiceTestSample.TestAddAttachmentsToRuntimeAdhocApprovalProcess('Apttus__APTS_Agreement__c','a07q000000EZfki');
//AdhocApprovalsWebServiceTestSample.TestDeleteAttachmentsFromRuntimeAdhocApprovalProcess('Apttus__APTS_Agreement__c','a07q000000EZfki');
//AdhocApprovalsWebServiceTestSample.TestDeleteRuntimeAdhocApprovalProcess('Apttus__APTS_Agreement__c','a07q000000EZfki');
/**
* Create a runtime ad hoc approval process
* @param sObjectType the approval context sobject type
* @param sObjectId the approval context sobject identifier
* @return the runtime adhoc approval process structure for the created process
*/
public static void TestCreateRuntimeAdhocApprovalProcess(String sObjectType, ID sObjectId) {
// create insert structure
Apttus_Approval.AdhocApprovalProcessDTO adhocProcessDTO = new Apttus_Approval.AdhocApprovalProcessDTO();
// get users to add as approvers
List<User> users = [SELECT Id,Name
FROM User
WHERE UserType != 'AutomatedProcess'
LIMIT 2];
User userSO1 = users[0];
User userSO2 = users[1];
// add process
Apttus_Approval__AdhocApprovalProcess__c adhocProcessSO = new Apttus_Approval__AdhocApprovalProcess__c(
Id = null,
Apttus_Approval__AttachmentIds__c = null,
Apttus_Approval__BusinessObjectId__c = sObjectId,
Apttus_Approval__BusinessObjectType__c = sObjectType,
Apttus_Approval__DisplayFields__c = null,
Apttus_Approval__DisplayHeaderFields__c = null,
Apttus_Approval__ProcessComments__c = null
);
adhocProcessDTO.setAdhocApprovalProcessSO(adhocProcessSO);
// create group 1
Apttus_Approval__AdhocApprovalGroup__c adhocGroupSO1 = new Apttus_Approval__AdhocApprovalGroup__c(
Apttus_Approval__AdhocApprovalProcessId__c = null,
Apttus_Approval__DependsOn__c = null,
Apttus_Approval__GroupName__c = 'Group 1',
Apttus_Approval__GroupSequence__c = 1
);
// add group 1 to process
Apttus_Approval.AdhocApprovalProcessDTO.AdhocApprovalGroupDTO adhocGroupDTO1 = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApprovalGroupDTO(adhocGroupSO1);
adhocProcessDTO.addAdhocApprovalGroup(adhocGroupDTO1);
// create group 1 approver 1
Apttus_Approval__AdhocApprover__c adhocApproverSO1 = new Apttus_Approval__AdhocApprover__c(
Apttus_Approval__AdhocApprovalGroupId__c = null,
Apttus_Approval__ApproverSequence__c = 1,
Apttus_Approval__DependsOn__c = null,
Apttus_Approval__AssigneeId__c = userSO1.Id,
Apttus_Approval__AssigneeType__c = 'User',
Apttus_Approval__AssigneeValue__c = userSO1.Name,
Apttus_Approval__AutoReapprovalEnabled__c = true,
Apttus_Approval__IsReviewer__c = false
);
// add group 1 approver 1
Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO adhocApproverDTO1 = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO(adhocApproverSO1);
adhocGroupDTO1.addAdhocApprover(adhocApproverDTO1);
// create group 1 approver 2
Apttus_Approval__AdhocApprover__c adhocApproverSO2 = new Apttus_Approval__AdhocApprover__c(
Apttus_Approval__AdhocApprovalGroupId__c = null,
Apttus_Approval__ApproverSequence__c = 2,
Apttus_Approval__DependsOn__c = null,
Apttus_Approval__AssigneeId__c = userSO2.Id,
Apttus_Approval__AssigneeType__c = 'User',
Apttus_Approval__AssigneeValue__c = userSO2.Name,
Apttus_Approval__AutoReapprovalEnabled__c = true,
Apttus_Approval__IsReviewer__c = false
);
// add group 1 approver 2
Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO adhocApproverDTO2 = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO(adhocApproverSO2);
adhocGroupDTO1.addAdhocApprover(adhocApproverDTO2);
// create group 2
Apttus_Approval__AdhocApprovalGroup__c adhocGroupSO2 = new Apttus_Approval__AdhocApprovalGroup__c(
Apttus_Approval__AdhocApprovalProcessId__c = null,
Apttus_Approval__DependsOn__c = null,
Apttus_Approval__GroupName__c = 'Group 2',
Apttus_Approval__GroupSequence__c = 2
);
// add group 2 to process
Apttus_Approval.AdhocApprovalProcessDTO.AdhocApprovalGroupDTO adhocGroupDTO2 = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApprovalGroupDTO(adhocGroupSO2);
adhocProcessDTO.addAdhocApprovalGroup(adhocGroupDTO2);
// create group 2 approver 1
adhocApproverSO1 = new Apttus_Approval__AdhocApprover__c(
Apttus_Approval__AdhocApprovalGroupId__c = null,
Apttus_Approval__ApproverSequence__c = 1,
Apttus_Approval__DependsOn__c = null,
Apttus_Approval__AssigneeId__c = userSO1.Id,
Apttus_Approval__AssigneeType__c = 'User',
Apttus_Approval__AssigneeValue__c = userSO1.Name,
Apttus_Approval__AutoReapprovalEnabled__c = true,
Apttus_Approval__IsReviewer__c = false
);
// add group 2 approver 1
adhocApproverDTO1 = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO(adhocApproverSO1);
adhocGroupDTO2.addAdhocApprover(adhocApproverDTO1);
// create group 2 approver 2
adhocApproverSO2 = new Apttus_Approval__AdhocApprover__c(
Apttus_Approval__AdhocApprovalGroupId__c = null,
Apttus_Approval__ApproverSequence__c = 2,
Apttus_Approval__DependsOn__c = null,
Apttus_Approval__AssigneeId__c = userSO2.Id,
Apttus_Approval__AssigneeType__c = 'User',
Apttus_Approval__AssigneeValue__c = userSO2.Name,
Apttus_Approval__AutoReapprovalEnabled__c = true,
Apttus_Approval__IsReviewer__c = false
);
// add group 2 approver 2
adhocApproverDTO2 = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO(adhocApproverSO2);
adhocGroupDTO2.addAdhocApprover(adhocApproverDTO2);
// call API to create process
Apttus_Approval.AdhocApprovalProcessDTO adhocProcessDTOResult = Apttus_Approval.ApprovalsWebService.CreateRuntimeAdhocApprovalProcess(adhocProcessDTO);
system.debug('adhocProcessDTOResult='+adhocProcessDTOResult);
}
/**
* Update a runtime adhoc approval process
* @param sObjectType the approval context sobject type
* @param sObjectId the approval context sobject identifier
* @return the runtime adhoc approval process structure for the edited process
*/
public static void TestUpdateRuntimeAdhocApprovalProcess(String sObjectType, ID sObjectId) {
// create update structures
Apttus_Approval.AdhocApprovalProcessDTO adhocProcessDTO = new Apttus_Approval.AdhocApprovalProcessDTO();
Apttus_Approval.AdhocApprovalProcessDTO.AdhocApprovalGroupDTO adhocGroupDTO = null;
Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO adhocApproverDTO = null;
// get users to add as approvers
List<User> users = [SELECT Id,Name
FROM User
WHERE UserType != 'AutomatedProcess'
LIMIT 5];
User userSO1 = users[0];
User userSO2 = users[1];
User userSO3 = users[2];
User userSO4 = users[3];
User userSO5 = users[4];
// get process
Apttus_Approval__AdhocApprovalProcess__c processSO = [SELECT Id,Name,
Apttus_Approval__BusinessObjectType__c,
Apttus_Approval__BusinessObjectId__c
FROM Apttus_Approval__AdhocApprovalProcess__c
WHERE Apttus_Approval__BusinessObjectType__c = :sObjectType AND
Apttus_Approval__BusinessObjectId__c = :sObjectId
LIMIT 1];
system.assert(processSO != null);
// update process
Apttus_Approval__AdhocApprovalProcess__c adhocProcessSO = new Apttus_Approval__AdhocApprovalProcess__c(
Id = processSO.Id,
Apttus_Approval__AttachmentIds__c = null,
Apttus_Approval__BusinessObjectId__c = processSO.Apttus_Approval__BusinessObjectId__c,
Apttus_Approval__BusinessObjectType__c = processSO.Apttus_Approval__BusinessObjectType__c,
Apttus_Approval__DisplayFields__c = null,
Apttus_Approval__DisplayHeaderFields__c = 'Apttus__Total_Contract_Value__c',
Apttus_Approval__ProcessComments__c = 'new comment added'
);
adhocProcessDTO.setAdhocApprovalProcessSO(adhocProcessSO);
// get groups and approvers
List<Apttus_Approval__AdhocApprovalGroup__c> groups = [SELECT Id,
Name,
Apttus_Approval__AdhocApprovalProcessId__c,
Apttus_Approval__AdhocApprovalProcessId__r.Apttus_Approval__BusinessObjectId__c,
Apttus_Approval__GroupName__c,
Apttus_Approval__GroupSequence__c,
Apttus_Approval__DependsOn__c,
(SELECT Id,
Name,
Apttus_Approval__AdhocApprovalGroupId__c,
Apttus_Approval__ApproverSequence__c,
Apttus_Approval__DependsOn__c,
Apttus_Approval__AssigneeId__c,
Apttus_Approval__AssigneeType__c,
Apttus_Approval__AssigneeValue__c,
Apttus_Approval__AutoReapprovalEnabled__c,
Apttus_Approval__IsReviewer__c,
Apttus_Approval__SendEmail__c
FROM Apttus_Approval__AdhocApprovers__r
ORDER BY Apttus_Approval__ApproverSequence__c)
FROM Apttus_Approval__AdhocApprovalGroup__c
WHERE Apttus_Approval__AdhocApprovalProcessId__c = :processSO.Id
ORDER BY Apttus_Approval__GroupSequence__c
LIMIT 100];
// iterate over groups to update
for (Apttus_Approval__AdhocApprovalGroup__c groupSO : groups) {
Apttus_Approval__AdhocApprovalGroup__c adhocGroupSO = null;
if (groupSO.Apttus_Approval__GroupSequence__c == 1) {
// create group 1
adhocGroupSO = new Apttus_Approval__AdhocApprovalGroup__c(
Id = groupSO.Id,
Apttus_Approval__AdhocApprovalProcessId__c = processSO.Id,
Apttus_Approval__DependsOn__c = null,
Apttus_Approval__GroupName__c = 'Group 1 - Edited',
Apttus_Approval__GroupSequence__c = 1
);
// update group 1
adhocGroupDTO = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApprovalGroupDTO(adhocGroupSO);
adhocProcessDTO.addAdhocApprovalGroup(adhocGroupDTO);
// iterate over approvers to update
for (Apttus_Approval__AdhocApprover__c approverSO : groupSO.Apttus_Approval__AdhocApprovers__r) {
Apttus_Approval__AdhocApprover__c adhocApproverSO = null;
if (approverSO.Apttus_Approval__ApproverSequence__c == 1) {
// create group 1 approver 1
adhocApproverSO = new Apttus_Approval__AdhocApprover__c(
Id = approverSO.Id,
Apttus_Approval__AdhocApprovalGroupId__c = groupSO.Id,
Apttus_Approval__ApproverSequence__c = 1,
Apttus_Approval__DependsOn__c = null,
Apttus_Approval__AssigneeId__c = userSO1.Id,
Apttus_Approval__AssigneeType__c = 'User',
Apttus_Approval__AssigneeValue__c = userSO1.Name,
Apttus_Approval__AutoReapprovalEnabled__c = true,
Apttus_Approval__IsReviewer__c = false
);
} else if (approverSO.Apttus_Approval__ApproverSequence__c == 2) {
// create group 1 approver 2
adhocApproverSO = new Apttus_Approval__AdhocApprover__c(
Id = approverSO.Id,
Apttus_Approval__AdhocApprovalGroupId__c = groupSO.Id,
Apttus_Approval__ApproverSequence__c = 2,
Apttus_Approval__DependsOn__c = '1',
Apttus_Approval__AssigneeId__c = userSO2.Id,
Apttus_Approval__AssigneeType__c = 'User',
Apttus_Approval__AssigneeValue__c = userSO2.Name,
Apttus_Approval__AutoReapprovalEnabled__c = true,
Apttus_Approval__IsReviewer__c = false
);
}
// update approver
adhocApproverDTO = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO(adhocApproverSO);
adhocGroupDTO.addAdhocApprover(adhocApproverDTO);
}
} else if (groupSO.Apttus_Approval__GroupSequence__c == 2) {
// create group 2
adhocGroupSO = new Apttus_Approval__AdhocApprovalGroup__c(
Id = groupSO.Id,
Apttus_Approval__AdhocApprovalProcessId__c = processSO.Id,
Apttus_Approval__DependsOn__c = null,
Apttus_Approval__GroupName__c = 'Group 2 - Edited',
Apttus_Approval__GroupSequence__c = 2
);
// update group 2
adhocGroupDTO = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApprovalGroupDTO(adhocGroupSO);
adhocProcessDTO.addAdhocApprovalGroup(adhocGroupDTO);
// iterate over approvers to update
for (Apttus_Approval__AdhocApprover__c approverSO : groupSO.Apttus_Approval__AdhocApprovers__r) {
Apttus_Approval__AdhocApprover__c adhocApproverSO = null;
if (approverSO.Apttus_Approval__ApproverSequence__c == 1) {
// create group 2 approver 1
adhocApproverSO = new Apttus_Approval__AdhocApprover__c(
Id = approverSO.Id,
Apttus_Approval__AdhocApprovalGroupId__c = groupSO.Id,
Apttus_Approval__ApproverSequence__c = 1,
Apttus_Approval__DependsOn__c = null,
Apttus_Approval__AssigneeId__c = userSO3.Id,
Apttus_Approval__AssigneeType__c = 'User',
Apttus_Approval__AssigneeValue__c = userSO3.Name,
Apttus_Approval__AutoReapprovalEnabled__c = true,
Apttus_Approval__IsReviewer__c = false
);
} else if (approverSO.Apttus_Approval__ApproverSequence__c == 2) {
// create group 2 approver 2
adhocApproverSO = new Apttus_Approval__AdhocApprover__c(
Id = approverSO.Id,
Apttus_Approval__AdhocApprovalGroupId__c = groupSO.Id,
Apttus_Approval__ApproverSequence__c = 2,
Apttus_Approval__DependsOn__c = '1',
Apttus_Approval__AssigneeId__c = userSO4.Id,
Apttus_Approval__AssigneeType__c = 'User',
Apttus_Approval__AssigneeValue__c = userSO4.Name,
Apttus_Approval__AutoReapprovalEnabled__c = true,
Apttus_Approval__IsReviewer__c = false
);
}
// update approver
adhocApproverDTO = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO(adhocApproverSO);
adhocGroupDTO.addAdhocApprover(adhocApproverDTO);
}
// create group 2 approver 3
Apttus_Approval__AdhocApprover__c adhocApproverSO = new Apttus_Approval__AdhocApprover__c(
Id = null,
Apttus_Approval__AdhocApprovalGroupId__c = groupSO.Id,
Apttus_Approval__ApproverSequence__c = 3,
Apttus_Approval__DependsOn__c = '2',
Apttus_Approval__AssigneeId__c = userSO5.Id,
Apttus_Approval__AssigneeType__c = 'User',
Apttus_Approval__AssigneeValue__c = userSO5.Name,
Apttus_Approval__AutoReapprovalEnabled__c = true,
Apttus_Approval__IsReviewer__c = false
);
// update group 2 approver 3
adhocApproverDTO = new Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO(adhocApproverSO);
adhocGroupDTO.addAdhocApprover(adhocApproverDTO);
}
}
// print input structure
PrintAdhocApprovalProcess(adhocProcessDTO);
// call API to update process
Apttus_Approval.AdhocApprovalProcessDTO adhocProcessDTOResult = Apttus_Approval.ApprovalsWebService.UpdateRuntimeAdhocApprovalProcess(adhocProcessDTO);
// print output structure
PrintAdhocApprovalProcess(adhocProcessDTOResult);
}
/**
* Retrieve a runtime adhoc approval process
* @param sObjectType the approval context sobject type
* @param sObjectId the approval context sobject identifier
* @return the runtime adhoc approval process structure
*/
public static void TestGetRuntimeAdhocApprovalProcess(String sObjectType, ID sObjectId) {
// call API to get process
Apttus_Approval.AdhocApprovalProcessDTO adhocProcessDTOResult = Apttus_Approval.ApprovalsWebService.GetRuntimeAdhocApprovalProcess(sObjectType, sObjectId);
// print output structure
PrintAdhocApprovalProcess(adhocProcessDTOResult);
}
/**
* Delete a runtime adhoc approval process
* @param sObjectType the approval context sobject type
* @param sObjectId the approval context sobject identifier
* @return <code>true</code> if the process is deleted, <code>false</code> otherwise
*/
public static void TestDeleteRuntimeAdhocApprovalProcess(String sObjectType, ID sObjectId) {
// call API to delete process
Boolean ok = Apttus_Approval.ApprovalsWebService.DeleteRuntimeAdhocApprovalProcess(sObjectType, sObjectId);
system.assertEquals(ok, true);
}
/**
* Add comment to a runtime adhoc approval process
* @param sObjectType the approval context sobject type
* @param sObjectId the approval context sobject identifier
* @return <code>true</code> if the comment was added, <code>false</code> otherwise
*/
public static void TestAddCommentToRuntimeAdhocApprovalProcess(String sObjectType, ID sObjectId) {
// call API to add comment
Boolean ok = Apttus_Approval.ApprovalsWebService.AddCommentToRuntimeAdhocApprovalProcess(sObjectType, sObjectId, 'MY NEW comment');
system.assertEquals(ok, true);
// call API to get process
Apttus_Approval.AdhocApprovalProcessDTO adhocProcessDTOResult = Apttus_Approval.ApprovalsWebService.GetRuntimeAdhocApprovalProcess(sObjectType, sObjectId);
// get comment from process
Apttus_Approval__AdhocApprovalProcess__c adhocProcessSO = adhocProcessDTOResult.getAdhocApprovalProcessSO();
String comment = adhocProcessSO.Apttus_Approval__ProcessComments__c;
system.assertEquals(comment, 'MY NEW comment');
}
/**
* Add attachments to a runtime adhoc approval process
* @param sObjectType the approval context sobject type
* @param sObjectId the approval context sobject identifier
* @return <code>true</code> if the attachments were added, <code>false</code> otherwise
*/
public static void TestAddAttachmentsToRuntimeAdhocApprovalProcess(String sObjectType, ID sObjectId) {
// create list of attachments to add
List<ID> attachmentIds = new List<ID>{sObjectId, sObjectId};
// call API to add attachments
Boolean ok = Apttus_Approval.ApprovalsWebService.AddAttachmentsToRuntimeAdhocApprovalProcess(sObjectType, sObjectId, attachmentIds);
system.assertEquals(ok, true);
// call API to get process
Apttus_Approval.AdhocApprovalProcessDTO adhocProcessDTOResult = Apttus_Approval.ApprovalsWebService.GetRuntimeAdhocApprovalProcess(sObjectType, sObjectId);
// get attachments from process
Apttus_Approval__AdhocApprovalProcess__c adhocProcessSO = adhocProcessDTOResult.getAdhocApprovalProcessSO();
String attachmentIdsStr = adhocProcessSO.Apttus_Approval__AttachmentIds__c;
String attachmentIdsStrExpected = sObjectId + ',' + sObjectId;
system.assertEquals(attachmentIdsStr, attachmentIdsStrExpected);
}
/**
* Delete attachments from a runtime adhoc approval process
* @param sObjectType the approval context sobject type
* @param sObjectId the approval context sobject identifier
* @return <code>true</code> if the attachments were removed, <code>false</code> otherwise
*/
public static void TestDeleteAttachmentsFromRuntimeAdhocApprovalProcess(String sObjectType, ID sObjectId) {
// create list of attachments to delete
List<ID> attachmentIds = new List<ID>{sObjectId};
// call API to delete attachments
Boolean ok = Apttus_Approval.ApprovalsWebService.DeleteAttachmentsFromRuntimeAdhocApprovalProcess(sObjectType, sObjectId, attachmentIds);
system.assertEquals(ok, true);
// call API to get process
Apttus_Approval.AdhocApprovalProcessDTO adhocProcessDTOResult = Apttus_Approval.ApprovalsWebService.GetRuntimeAdhocApprovalProcess(sObjectType, sObjectId);
// get attachments from process
Apttus_Approval__AdhocApprovalProcess__c adhocProcessSO = adhocProcessDTOResult.getAdhocApprovalProcessSO();
String attachmentIdsStr = adhocProcessSO.Apttus_Approval__AttachmentIds__c;
system.assertEquals(attachmentIdsStr, sObjectId);
}
/**
* Prints an adhoc process definition
* @param approvalProcessDTO the adhoc approval process definition
*/
public static void PrintAdhocApprovalProcess(Apttus_Approval.AdhocApprovalProcessDTO approvalProcessDTO) {
// print process info
Apttus_Approval__AdhocApprovalProcess__c processSO = approvalProcessDTO.getAdhocApprovalProcessSO();
system.debug('processSO='+processSO);
// print approval groups and approvers
for (Apttus_Approval.AdhocApprovalProcessDTO.AdhocApprovalGroupDTO groupDTO : approvalProcessDTO.getAdhocApprovalGroups()) {
Apttus_Approval__AdhocApprovalGroup__c groupSO = groupDTO.getAdhocApprovalGroupSO();
system.debug('groupSO='+groupSO);
// get approvers
for (Apttus_Approval.AdhocApprovalProcessDTO.AdhocApproverDTO approverDTO : groupDTO.getAdhocApprovers()) {
Apttus_Approval__AdhocApprover__c approverSO = approverDTO.getAdhocApproverSO();
system.debug('approverSO='+approverSO);
}
}
}
}
CODE