All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nakedobjects.example.expenses.claims.Claim Maven / Gradle / Ivy

There is a newer version: 3.0.3
Show newest version
package org.nakedobjects.example.expenses.claims;

import org.nakedobjects.applib.annotation.Disabled;
import org.nakedobjects.applib.annotation.Hidden;
import org.nakedobjects.applib.annotation.MemberOrder;
import org.nakedobjects.applib.annotation.Named;
import org.nakedobjects.applib.annotation.Optional;
import org.nakedobjects.applib.value.Date;
import org.nakedobjects.applib.value.Money;
import org.nakedobjects.example.expenses.employee.Employee;
import org.nakedobjects.example.expenses.recordedAction.RecordActionService;
import org.nakedobjects.example.expenses.recordedAction.RecordedActionContext;
import org.nakedobjects.example.expenses.services.EmailSender;


public class Claim extends AbstractClaim implements RecordedActionContext {

    // {{ Injected Services

    // {{ Injected: RecordActionService
    private RecordActionService recordActionService;

    /**
     * This property is not persisted, nor displayed to the user.
     */
    protected RecordActionService getRecordActionService() {
        return this.recordActionService;
    }

    /**
     * Injected by the application container.
     */
    public void setRecordActionService(final RecordActionService recordActionService) {
        this.recordActionService = recordActionService;
    }

    // }}

    // {{ Injected: EmailSender
    private EmailSender emailSender;

    /**
     * This property is not persisted, nor displayed to the user.
     */
    protected EmailSender getEmailSender() {
        return this.emailSender;
    }

    /**
     * Injected by the application container.
     */
    public void setEmailSender(final EmailSender emailSender) {
        this.emailSender = emailSender;
    }

    // }}

    // }}

    // {{ Life Cycle methods
    public void created() {
        changeStatusToNew();
        dateCreated = new Date();
    }

    // }}

    // {{ DateCreated
    private Date dateCreated;

    @Disabled
    @MemberOrder(sequence = "2")
    public Date getDateCreated() {
        resolve(dateCreated);
        return this.dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
        objectChanged();
    }

    // }}

    // {{ Status field
    private void changeStatusTo(String title) {
        setStatus(getClaimRepository().findClaimStatus(title));
    }

    protected boolean isNew() {
        return getStatus().isNew();
    }

    protected void changeStatusToNew() {
        changeStatusTo(ClaimStatus.NEW);
    }

    protected boolean isSubmitted() {
        return getStatus().isSubmitted();
    }

    protected void changeStatusToSubmitted() {
        changeStatusTo(ClaimStatus.SUBMITTED);
    }

    protected boolean isReturned() {
        return getStatus().isReturned();
    }

    protected void changeStatusToReturned() {
        changeStatusTo(ClaimStatus.RETURNED);
    }

    protected boolean isToBePaid() {
        return getStatus().isPaid();
    }

    protected void changeStatusToToBePaid() {
        changeStatusTo(ClaimStatus.TO_BE_PAID);
    }

    protected boolean isPaid() {
        return getStatus().isPaid();
    }

    protected void changeStatusToPaid() {
        changeStatusTo(ClaimStatus.PAID);
    }

    private ClaimStatus status;

    @MemberOrder(sequence = "3")
    @Disabled
    public ClaimStatus getStatus() {
        resolve(status);
        return status;
    }

    public void setStatus(final ClaimStatus claimStatus) {
        this.status = claimStatus;
        objectChanged();
    }

    @Hidden
    public String modifiable() {
        if (isNew() || isReturned()) {
            return null;
        }
        return "Cannot modify claim";
    }

    // }}

    // {{ Calculating the Total of Expense Items

    // {{ Total Field
    private Money total;

    @MemberOrder(sequence = "7")
    @Disabled
    public Money getTotal() {
        resolve(total);
        return this.total;
    }

    public void setTotal(Money total) {
        this.total = total;
        objectChanged();
    }

    @Hidden
    public void initialiseTotal() {
        total = new Money(0, currencyCode());
    }

    @Hidden
    public void recalculateTotal() {
        Money runningTotal = new Money(0, currencyCode());
        for (final ExpenseItem item : getExpenseItems()) {
            final Money itemAmount = item.requestedOrApprovedAmount();
            if (itemAmount != null) {
                runningTotal = runningTotal.add(itemAmount);
            }
        }
        setTotal(runningTotal);
    }

    // }}

    public void addToExpenseItems(ExpenseItem collectionNameSingularForm) {
        super.addToExpenseItems(collectionNameSingularForm);
        recalculateTotal();
    }

    public void removeFromExpenseItems(final ExpenseItem item) {
        super.removeFromExpenseItems(item);
        recalculateTotal();
    }

    // }}

    // {{ Workflow (submit, return etc)

    // {{ Submit

    @MemberOrder(sequence = "4.1")
    public void submit(@Named("Approver")
    final Employee approver, @Named("Advise approver by email")
    final boolean sendEmail) {
        setApprover(approver);
        changeStatusToSubmitted();
        for (final ExpenseItem item : getExpenseItems()) {
            item.setLocked(true);
        }
        String message = getClaimant().getName() + CLAIM_AWAITING_YOUR_APPROVAL;
        sendEmailIfPossible(sendEmail, getApprover().getEmailAddress(), message);
        getRecordActionService().recordMenuAction(this, "Submit", "to " + approver.title());
    }

    private void sendEmailIfPossible(final boolean sendEmail, String emailAddress, final String message) {
        if (sendEmail & !emailAddress.equals("") && getEmailSender() != null) {
            try {
                getEmailSender().sendTextEmail(emailAddress, message);
            } catch (final Exception e) {
                warnUser(e.getMessage() == null ? "Unknown problem sending email" : e.getMessage());
            }
        }
    }

    public static final String CLAIM_AWAITING_YOUR_APPROVAL = " has submitted an expenses claim for your approval";

    public Object[] defaultSubmit() {
        return new Object[] { getApprover(), Boolean.TRUE };
    }

    public static final String HAS_INCOMPLETE_ITEMS = "Cannot submit claim with incomplete Items";

    public static final String CAN_ONLY_SUBMIT_NEW_OR_RETURNED_CLAIMS = "Can only submit a claim that is 'New' or 'Returned'";

    public static final String ONLY_CLAIMANT_MAY_SUBMIT = "Only the Claimant may submit a Claim";

    public String disableSubmit() {
        if (!allItemsComplete()) {
            return HAS_INCOMPLETE_ITEMS;
        }
        if (!isNew() && !isReturned()) {
            return CAN_ONLY_SUBMIT_NEW_OR_RETURNED_CLAIMS;
        }
        if (!userIsClaimant()) {
            return ONLY_CLAIMANT_MAY_SUBMIT;
        }
        return null;
    }

    // }}

    // {{ Return to Claimant
    public void returnToClaimant(@Optional
    @Named("Message to claimant")
    String message) {
        returnToClaimant(message, true);
    }

    @Hidden
    public void returnToClaimant(@Named("Message to claimant")
    final String message, final boolean sendEmail) {
        changeStatusToReturned();
        for (final ExpenseItem item : getExpenseItems()) {
            item.setLocked(false);
        }
        getRecordActionService().recordMenuAction(this, "Return To Claimant", message);
        final String fullMessage = ("Your Expenses Claim: " + title() + " has been returned to you with the message " + message);
        sendEmailIfPossible(sendEmail, getClaimant().getEmailAddress(), fullMessage);
    }

    public static final String RETURNED_CLAIM = "A previously-submitted expenses claim has been returned to you";

    public String disableReturnToClaimant(String message) {
        return isSubmitted() ? null : STATUS_NOT_SUBMITTED;
    }

    public static final String STATUS_NOT_SUBMITTED = "Status of claim is not 'Submitted'";

    // }}

    // }}

    // {{ Approving claims

    // {{ ApproveAllItems
    @MemberOrder(sequence = "5.1")
    public void approveItems(@Optional
    @Named("Approve New Items Only")
    boolean newOnly) {
        for (final ExpenseItem item : getExpenseItems()) {
            if (!newOnly || (newOnly && item.isNewComplete())) {
                item.approve();
            }
        }
    }

    public String disableApproveItems() {
        return disableApproverActionsOnAllItems();
    }

    // }}

    // {{ RejectAllItems
    @MemberOrder(sequence = "5.3")
    public void rejectItems(@Named("Reason For Rejection")
    final String reason, @Optional
    @Named("Reject New Items Only")
    boolean newOnly) {
        for (final ExpenseItem item : getExpenseItems()) {
            if (!newOnly || (newOnly && item.isNewComplete())) {
                item.reject(reason);
            }
        }

    }

    public String disableRejectItems() {
        return disableApproverActionsOnAllItems();
    }

    // }}

    // {{ QueryAllItems
    @MemberOrder(sequence = "5.2")
    public void queryItems(@Named("Reason For Query")
    final String reason, @Optional()
    @Named("Query New Items Only")
    boolean newOnly) {
        for (final ExpenseItem item : getExpenseItems()) {
            if (!newOnly || (newOnly && item.isNewComplete())) {
                item.query(reason);
            }
        }
    }

    public String disableQueryItems() {
        return disableApproverActionsOnAllItems();
    }

    // }}

    public String disableApproverActionsOnAllItems() {
        if (!isSubmitted()) {
            return APPROVER_ACTIONS_NOT_VALID_ON_NEW_CLAIM;
        }
        if (!userIsTheApproverForThisClaim()) {
            return USER_IS_NOT_THE_APPROVER;
        }
        return null;
    }

    public static final String APPROVER_ACTIONS_NOT_VALID_ON_NEW_CLAIM = "Approver actions only available when status is Submitted";

    public static final String USER_IS_NOT_THE_APPROVER = "User is not the specified approver for this claim";

    public String disableApprover() {
        if (isNew() || isReturned()) {
            return null;
        }
        return CANNOT_CHANGE_APPROVER_ON_SUBMITTED_CLAIM;
    }

    public static final String CANNOT_CHANGE_APPROVER_ON_SUBMITTED_CLAIM = "Cannot change the Approver on a claim that has been submitted";

    // }}

    // {{ Support for rules
    private boolean allItemsComplete() {
        if (getExpenseItems().size() == 0) {
            return false;
        }
        for (final ExpenseItem item : getExpenseItems()) {
            if (!item.isNewComplete()) {
                return false;
            }
        }
        return true;
    }

    @Hidden
    public boolean userIsTheApproverForThisClaim() {
        return getUserFinder().currentUserAsObject() == getApprover();
    }

    private boolean userIsClaimant() {
        return getUserFinder().currentUserAsObject() == getClaimant();
    }
    // }}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy