Mastering Data Modeling with Liferay Objects

Course Overview

Extending Clarity's Distributor Management App with Client Extensions

To complete the onboarding flow, Clarity wants to enable managers to create business accounts for approved applications easily. Each account should be named after the application’s businessName and the applicant should be assigned automatically to the account with the Account Administrator role. You can achieve this using an object action client extension.

Exercise: Setting Up the Client Extension

When you deployed the liferay-course-etc-spring-boot project for your workflow, you also deployed a custom object action.

Before proceeding, ensure the Spring Boot application is running. If it isn’t, navigate to the liferay-course-etc-spring-boot project folder and run this command:

blade gw bootRun

Then go to http://localhost:58081/ready to confirm the application started successfully.

Examining the Client Extension Code

This client extension defines a REST controller (ObjectActionAccountRestController) that handles business account creation for approved distributors. It performs three primary operations:

  1. Create a business account using the businessName from the approved application.

  2. Associate the applicant with the account using the applicantEmailAddress field.

  3. Assign the applicant the Account Administrator role.

@RequestMapping("/object/action/account")
@RestController
public class ObjectActionAccountRestController extends BaseRestController {
	@PostMapping
	public ResponseEntity post(
			@AuthenticationPrincipal Jwt jwt, @RequestBody String json)
		throws Exception {
		log(jwt, _log, json);
		JSONObject jsonObject = new JSONObject(json);
		JSONObject objectEntryDTODistributorApplicationJSONObject =
			jsonObject.getJSONObject("objectEntryDTODistributorApplication");
		JSONObject propertiesJSONObject =
			objectEntryDTODistributorApplicationJSONObject.getJSONObject(
				"properties");
		String accountEmailAddress = propertiesJSONObject.getString(
			"applicantEmailAddress");
		String accountName = propertiesJSONObject.getString("businessName");
		String accountExternalReferenceCode = "ACCOUNT_".concat(
			accountName.toUpperCase(
			).replace(
				' ', '_'
			));
		WebClient.Builder builder = WebClient.builder();
		WebClient webClient = builder.baseUrl(
			lxcDXPServerProtocol + "://" + lxcDXPMainDomain
		).defaultHeader(
			HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE
		).defaultHeader(
			HttpHeaders.AUTHORIZATION, "Bearer " + jwt.getTokenValue()
		).defaultHeader(
			HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE
		).build();
		webClient.post(
		).uri(
			"o/headless-admin-user/v1.0/accounts"
		).bodyValue(
			StringBundler.concat(
				"{\"externalReferenceCode\": \"", accountExternalReferenceCode,
				"\", \"name\": \"", accountName, "\", \"type\": \"business\"}")
		).retrieve(
		).toEntity(
			String.class
		).flatMap(
			responseEntity -> _transform(responseEntity)
		).doOnSuccess(
			responseEntity -> _log(
				"Created account: " + responseEntity.getBody())
		).then(
			webClient.post(
			).uri(
				StringBundler.concat(
					"o/headless-admin-user/v1.0/accounts",
					"/by-external-reference-code/",
					accountExternalReferenceCode,
					"/user-accounts/by-email-address/", accountEmailAddress)
			).retrieve(
			).toEntity(
				String.class
			).flatMap(
				responseEntity -> _transform(responseEntity)
			)
		).doOnSuccess(
			responseEntity -> _log("Assigned user: " + responseEntity.getBody())
		).then(
			webClient.get(
			).uri(
				uriBuilder -> uriBuilder.path(
					StringBundler.concat(
						"o/headless-admin-user/v1.0/accounts",
						"/by-external-reference-code/",
						accountExternalReferenceCode, "/account-roles")
				).queryParam(
					"filter", "name eq 'Account Administrator'"
				).build()
			).retrieve(
			).bodyToMono(
				String.class
			).map(
				pageJSON -> new JSONObject(
					pageJSON
				).getJSONArray(
					"items"
				).getJSONObject(
					0
				).getInt(
					"id"
				)
			)
		).flatMap(
			accountRoleId -> webClient.post(
			).uri(
				StringBundler.concat(
					"o/headless-admin-user/v1.0/accounts",
					"/by-external-reference-code/",
					accountExternalReferenceCode, "/account-roles/",
					accountRoleId, "/user-accounts/by-email-address/",
					accountEmailAddress)
			).retrieve(
			).toEntity(
				String.class
			).flatMap(
				responseEntity -> _transform(responseEntity)
			).doOnSuccess(
				responseEntity -> _log(
					"Assigned role: " + responseEntity.getBody())
			)
		).subscribe();
		return new ResponseEntity<>(json, HttpStatus.OK);
	}
	private void _log(String message) {
		if (_log.isInfoEnabled()) {
			_log.info(message);
		}
	}
	private Mono> _transform(
		ResponseEntity responseEntity) {
		HttpStatus httpStatus = responseEntity.getStatusCode();
		if (httpStatus.is2xxSuccessful()) {
			return Mono.just(responseEntity);
		}
		return Mono.error(new RuntimeException(httpStatus.getReasonPhrase()));
	}
	private static final Log _log = LogFactory.getLog(
		ObjectActionAccountRestController.class);
}

This Java class automates user account management using Liferay’s headless APIs. These APIs provide programmatic access to Liferay's functionalities, enabling seamless integration and automation. Here are the specific calls this class makes:

  • Account Creation: A POST request to /o/headless-admin-user/v1.0/accounts creates the business account.

  • User Assignment: A POST request to /o/headless-admin-user/v1.0/accounts/by-external-reference-code/{accountExternalReferenceCode}/user-accounts/by-email-address/{accountEmailAddress} associates the user with the account.

  • Role Retrieval: A GET request to /o/headless-admin-user/v1.0/accounts/by-external-reference-code/{accountExternalReferenceCode}/account-roles retrieves the ID of the "Account Administrator" role.

  • Role Assignment: A POST request to /o/headless-admin-user/v1.0/accounts/by-external-reference-code/{accountExternalReferenceCode}/account-roles/{accountRoleId}/user-accounts/by-email-address/{accountEmailAddress} assigns the role to the user.

By integrating this client extension with the Distributor Application object, Clarity can automatically create and configure user accounts for approved applicants, eliminating manual steps and ensuring consistency.

Exercise: Adding the Account Setup Action

Clarity has collected valuable information throughout the application process, and they want to leverage that data to streamline the creation of business accounts for approved distributors. Here you’ll add an object action that uses the account setup client extension.

  1. Open the Global Menu (Applications Menu icon.), go to the Control Panel tab, and click Objects.

  2. Go to the Distributor Management folder and begin editing the Distributor Application object.

  3. Go to the Actions tab and click Add (Add icon.).

  4. Enter these values in the Basic Info tab:

    Field Value
    Action Label Set Up Account
    Action Name setUpAccount
    Description Create a business account for an approved application.
    Active Yes
  5. Go to the Action Builder tab and set these values:

    Field Value
    Trigger Standalone
    Action object-action-executor[function#liferay-clarity-etc-spring-boot-object-action-account]
    Description Failed to set up the business account.
  6. Click Save.

Once saved, Liferay adds the action as an option in the object’s overview page. This way so you can trigger it manually in the Liferay UI.

Liferay adds the action as an option in the object’s overview page.

Liferay also generates two headless APIs for triggering the standalone action programmatically.

Liferay also generates two headless APIs for triggering the standalone action programmatically.

Furthermore, when you use fragments to embed the Distributor Application object in site pages, you can map this action to a button fragment. You’ll learn more about this option in the next module.

With the action defined, you can now assign action permissions to the appropriate user roles. This ensures that only authorized individuals can create business accounts for distributor applications.

Exercise: Assigning the Account Setup Permission

When you define standalone actions, Liferay generates permissions for managing which roles can execute it. Here you’ll assign the account setup permission to the Business Development Manager role.

  1. Open the Global Menu (Applications Menu icon.), go to the Control Panel tab, and click Roles.

  2. Being editing the Business Development Manager role.

  3. Go to the Define Permissions tab.

  4. In the left menu, go to Applications MenuContentDistributor Applications.
    Enter “Distributor Applications” into the search bar to quickly locate this section.
  5. Add this permission:

    Section Permissions
    Resource Permissions Distributor Application > action.setUpAccount
  6. Click Save.

With this permissions defined, now all business development managers can trigger the account setup action for approved applications.

Exercise: Triggering the Account Setup Action

Here you’ll trigger the account setup for an approved distributor application.

  1. Go to the Distributor Applications page.

  2. Click Actions (Actions icon.) for an entry and select Set Up Account.

  3. Open the Accounts application and verify the account was created.

  4. Go to the Users tab and verify the applicant was associated with the account and assigned the Account Administrator role.

Conclusion

Congratulations! You’ve successfully added the business logic necessary for the Distributor Application object. Next, you’ll review what you’ve learned before moving on to the next module.

  • Exercise: Setting Up the Client Extension

  • Exercise: Adding the Account Setup Action

  • Exercise: Assigning the Account Setup Permission

  • Exercise: Triggering the Account Setup Action

  • Conclusion

Loading Knowledge

Capabilities

Product

Education

Contact Us

Connect

Powered by Liferay
© 2024 Liferay Inc. All Rights Reserved • Privacy Policy