class GrantOfferLetterServiceImpl extends BaseTransactionalService implements GrantOfferLetterService {

    @Override
    @Transactional
    public ServiceResult<Void> sendGrantOfferLetter(Long projectId) {

        return getProject(projectId).andOnSuccess(project -> {
            if (project.getGrantOfferLetter() == null) {
                return serviceFailure(CommonFailureKeys.GRANT_OFFER_LETTER_MUST_BE_AVAILABLE_BEFORE_SEND);
            }

            User projectManager = getExistingProjectManager(project).get().getUser();

            if (project.isUseDocusignForGrantOfferLetter()) {
                return sendGrantOfferLetterSuccess(project).andOnSuccess(() ->
                     docusignService.send(docusignRequest(projectManager, project))
                    .andOnSuccessReturnVoid((project::setSignedGolDocusignDocument)));
            } else {
                NotificationTarget pmTarget = createProjectManagerNotificationTarget(projectManager);

                Map<String, Object> notificationArguments = new HashMap<>();
                notificationArguments.put("dashboardUrl", webBaseUrl);
                notificationArguments.put("applicationId", project.getApplication().getId());
                String title = project.getApplication().getCompetition().isProcurement() ? "contract" : "grant offer letter";
                String shortTitle = project.getApplication().getCompetition().isProcurement() ? "contract" : "letter";
                notificationArguments.put("title", title);
                notificationArguments.put("shortTitle", shortTitle);

                return sendGrantOfferLetterSuccess(project).andOnSuccess(() -> {
                    Notification notification = new Notification(systemNotificationSource,
                            singletonList(pmTarget),
                            NotificationsGol.GRANT_OFFER_LETTER_PROJECT_MANAGER,
                            notificationArguments);

                    return notificationService.sendNotificationWithFlush(notification, EMAIL);
                });
            }
        });
    }

}