Search in sources :

Example 1 with PartyRoleType

use of org.estatio.module.party.dom.role.PartyRoleType in project estatio by estatio.

the class StateTransitionRepositoryGeneric method createTaskIfRequired.

protected <DO, ST extends StateTransitionAbstract<DO, ST, STT, S>, STT extends StateTransitionType<DO, ST, STT, S>, S extends State<S>> Task createTaskIfRequired(final IPartyRoleType iRoleAssignTo, final Person personToAssignToIfAny, final String taskDescription, final Class<ST> stateTransitionClass, final DO domainObject) {
    if (iRoleAssignTo == null) {
        return null;
    }
    final LocalDateTime createdOn = clockService.nowAsLocalDateTime();
    final String transitionObjectType = metaModelService3.toObjectType(stateTransitionClass);
    final Person assignToIfAny = personToAssignToIfAny != null ? personToAssignToIfAny : partyRoleTypeService.onlyMemberOfElseNone(iRoleAssignTo, domainObject);
    final PartyRoleType roleAssignTo = iRoleAssignTo.findOrCreateUsing(partyRoleTypeRepository);
    final Task task = new Task(roleAssignTo, assignToIfAny, taskDescription, createdOn, transitionObjectType);
    repositoryService.persist(task);
    return task;
}
Also used : LocalDateTime(org.joda.time.LocalDateTime) Task(org.estatio.module.capex.dom.task.Task) IPartyRoleType(org.estatio.module.party.dom.role.IPartyRoleType) PartyRoleType(org.estatio.module.party.dom.role.PartyRoleType) Person(org.estatio.module.party.dom.Person)

Example 2 with PartyRoleType

use of org.estatio.module.party.dom.role.PartyRoleType in project estatio by estatio.

the class TaskRepository method findIncompleteForMyRolesAndUnassigned.

/**
 * Those tasks which are assigned to no-one, but for which I have the (party) roles to perform.
 */
@Programmatic
public List<Task> findIncompleteForMyRolesAndUnassigned() {
    final Person meAsPerson = meAsPerson();
    if (meAsPerson == null) {
        return Lists.newArrayList();
    }
    final List<PartyRoleType> myRoleTypes = partyRoleTypesFor(meAsPerson);
    return findIncompleteByUnassignedForRoles(myRoleTypes);
}
Also used : PartyRoleType(org.estatio.module.party.dom.role.PartyRoleType) Person(org.estatio.module.party.dom.Person) Programmatic(org.apache.isis.applib.annotation.Programmatic)

Example 3 with PartyRoleType

use of org.estatio.module.party.dom.role.PartyRoleType in project estatio by estatio.

the class StateTransitionService method pendingTransitionIfPossible.

private <DO, ST extends StateTransition<DO, ST, STT, S>, STT extends StateTransitionType<DO, ST, STT, S>, S extends State<S>> ST pendingTransitionIfPossible(final DO domainObject, final Class<ST> stateTransitionClass, final STT requestedTransitionTypeIfAny, final Person personToAssignNextToIfAny, final String nextTaskDescriptionIfAny) {
    // check the override, if any
    if (requestedTransitionTypeIfAny != null) {
        boolean canTransition = requestedTransitionTypeIfAny.canTransitionFromCurrentStateAndIsMatch(domainObject, serviceRegistry2);
        if (!canTransition) {
            // what's been requested is a no-go.
            return null;
        }
    }
    // determine what previously was determined as the pending (if any)
    ST pendingTransitionIfAny = pendingTransitionOf(domainObject, stateTransitionClass);
    // what we now think as the pending (if any)
    STT nextTransitionType = null;
    // current state
    final ST mostRecentTransitionIfAny = mostRecentlyCompletedTransitionOf(domainObject, stateTransitionClass);
    final S currentStateIfAny = mostRecentTransitionIfAny != null ? mostRecentTransitionIfAny.getTransitionType().getToState() : null;
    if (requestedTransitionTypeIfAny != null) {
        nextTransitionType = requestedTransitionTypeIfAny;
    } else {
        if (mostRecentTransitionIfAny != null) {
            // use most recent transition to determine the next transition (since one hasn't been requested)
            final STT mostRecentTransitionType = mostRecentTransitionIfAny.getTransitionType();
            final NextTransitionSearchStrategy<DO, ST, STT, S> transitionStrategy = mostRecentTransitionType.getNextTransitionSearchStrategy();
            if (transitionStrategy != null) {
                nextTransitionType = transitionStrategy.nextTransitionType(domainObject, mostRecentTransitionType, serviceRegistry2);
            }
        } else {
            // can't proceed because unable to determine current state, and no transition specified
            return null;
        }
    }
    // if pending has changed, then reconcile
    STT pendingTransitionType = pendingTransitionIfAny != null ? pendingTransitionIfAny.getTransitionType() : null;
    if (pendingTransitionType != nextTransitionType) {
        if (pendingTransitionType != null) {
            if (nextTransitionType != null) {
                final Task taskIfAny = pendingTransitionIfAny.getTask();
                repositoryService.remove(pendingTransitionIfAny);
                if (taskIfAny != null) {
                    repositoryService.removeAndFlush(taskIfAny);
                }
                pendingTransitionType = nextTransitionType;
                pendingTransitionIfAny = createPendingTransition(domainObject, currentStateIfAny, nextTransitionType, personToAssignNextToIfAny, nextTaskDescriptionIfAny);
            } else {
                // in this branch the transition strategy for the most recently completed transition
                // must have returned null for nextTransitionType, and yet a pending transition does exist
                // (pendingTransitionType is not null).  This can only have come about if that pending
                // transition was created directly (using createPendingTransition(...)).
                // We don't want to discard this pending transition, so we use instead update nextTransitionType
                // to this existing pending value.
                nextTransitionType = pendingTransitionType;
            }
        } else {
            // pendingTransitionType == null, so nextTransitionType != null because of outer if
            pendingTransitionIfAny = createPendingTransition(domainObject, currentStateIfAny, nextTransitionType, personToAssignNextToIfAny, nextTaskDescriptionIfAny);
            pendingTransitionType = nextTransitionType;
        }
    }
    if (pendingTransitionType == null) {
        return null;
    }
    if (domainObject instanceof Stateful) {
        final Stateful stateful = (Stateful) domainObject;
        final S currentStateAccordingToDomainObject = stateful.getStateOf(stateTransitionClass);
        if (currentStateAccordingToDomainObject == null && mostRecentTransitionIfAny != null) {
            // self-healing
            stateful.setStateOf(stateTransitionClass, mostRecentTransitionIfAny.getToState());
        }
    }
    final Task taskIfAny = pendingTransitionIfAny.getTask();
    if (taskIfAny != null) {
        final PartyRoleType roleAssignedTo = taskIfAny.getAssignedTo();
        final IPartyRoleType iRoleShouldBeAssignedTo = pendingTransitionType.getTaskAssignmentStrategy().getAssignTo(domainObject, serviceRegistry2);
        // always overwrite the role
        final PartyRoleType roleShouldBeAssignedTo = partyRoleTypeRepository.findOrCreate(iRoleShouldBeAssignedTo);
        if (roleAssignedTo != roleShouldBeAssignedTo) {
            taskIfAny.setAssignedTo(roleShouldBeAssignedTo);
        }
        // only overwrite the person if not actually assigned
        final Person personAssignedToIfAny = taskIfAny.getPersonAssignedTo();
        if (personAssignedToIfAny == null) {
            if (iRoleShouldBeAssignedTo != null) {
                Person person = partyRoleTypeService.onlyMemberOfElseNone(iRoleShouldBeAssignedTo, domainObject);
                taskIfAny.setPersonAssignedTo(person);
            }
        }
    }
    if (!pendingTransitionType.isGuardSatisfied(domainObject, serviceRegistry2)) {
        // (there must be a guard prohibiting it for this particular domain object)
        return null;
    }
    // if requestedTransitionTypeIfAny != null, then this is an explicit action, so automatic doesn't apply...
    if (requestedTransitionTypeIfAny != null) {
        return pendingTransitionIfAny;
    }
    final AdvancePolicy advancePolicy = nextTransitionType.advancePolicyFor(domainObject, serviceRegistry2);
    if (advancePolicy.isAutomatic() && pendingTransitionType.isAutoGuardSatisfied(domainObject, serviceRegistry2)) {
        return pendingTransitionIfAny;
    }
    return null;
}
Also used : Task(org.estatio.module.capex.dom.task.Task) IPartyRoleType(org.estatio.module.party.dom.role.IPartyRoleType) IPartyRoleType(org.estatio.module.party.dom.role.IPartyRoleType) PartyRoleType(org.estatio.module.party.dom.role.PartyRoleType) Person(org.estatio.module.party.dom.Person)

Example 4 with PartyRoleType

use of org.estatio.module.party.dom.role.PartyRoleType in project estatio by estatio.

the class Party_Test method validate_delete_works.

@Test
public void validate_delete_works() throws Exception {
    // given
    PartyRoleType typeForTenant = new PartyRoleType();
    PartyRole roleForTenant = new PartyRole();
    roleForTenant.setRoleType(typeForTenant);
    Party partyToDelete = new PartyForTesting();
    // party to delete now has tenant role
    partyToDelete.getRoles().add(roleForTenant);
    partyToDelete.partyRoleTypeRepository = mockPartyRoleTypeRepository;
    PartyRoleType typeForSupplier = new PartyRoleType();
    PartyRole roleForSupplier = new PartyRole();
    roleForSupplier.setRoleType(typeForSupplier);
    Party replacementParty = new PartyForTesting();
    // replacement party now has supplier role but NOT tenant role
    replacementParty.getRoles().add(roleForSupplier);
    replacementParty.partyRoleTypeRepository = mockPartyRoleTypeRepository;
    // expect
    context.checking(new Expectations() {

        {
            oneOf(mockPartyRoleTypeRepository).findByKey("TENANT");
            will(returnValue(typeForTenant));
            oneOf(mockPartyRoleTypeRepository).findByKey("SUPPLIER");
            will(returnValue(typeForSupplier));
            oneOf(mockPartyRoleTypeRepository).findByKey("TENANT");
            will(returnValue(null));
        }
    });
    // when, then
    Assertions.assertThat(partyToDelete.validateDelete(replacementParty)).isEqualTo("A tenant should not be replaced by a supplier");
}
Also used : Expectations(org.jmock.Expectations) PartyRole(org.estatio.module.party.dom.role.PartyRole) PartyRoleType(org.estatio.module.party.dom.role.PartyRoleType) AbstractBeanPropertiesTest(org.incode.module.unittestsupport.dom.bean.AbstractBeanPropertiesTest) Test(org.junit.Test)

Example 5 with PartyRoleType

use of org.estatio.module.party.dom.role.PartyRoleType in project estatio by estatio.

the class IncomingInvoiceApprovalState_IntegTest method refund_by_supplier_skips_bank_account_verification_and_creates_check_task_for_treasury.

@Test
public void refund_by_supplier_skips_bank_account_verification_and_creates_check_task_for_treasury() {
    // given
    PartyRoleType typeForTreasurer = partyRoleTypeRepository.findByKey(PartyRoleTypeEnum.TREASURER.getKey());
    // workaround: clear MeService#me cache
    queryResultsCache.resetForNextTransaction();
    sudoService.sudo(Person_enum.JonathanPropertyManagerGb.getRef().toLowerCase(), (Runnable) () -> wrap(incomingInvoice).changePaymentMethod(PaymentMethod.REFUND_BY_SUPPLIER));
    sudoService.sudo(Person_enum.JonathanPropertyManagerGb.getRef().toLowerCase(), (Runnable) () -> wrap(mixin(IncomingInvoice_complete.class, incomingInvoice)).act("PROPERTY_MANAGER", null, null));
    // workaround: clear MeService#me cache
    queryResultsCache.resetForNextTransaction();
    sudoService.sudo(Person_enum.PeterPanProjectManagerGb.getRef().toLowerCase(), (Runnable) () -> wrap(mixin(IncomingInvoice_approve.class, incomingInvoice)).act("COUNTRY_DIRECTOR", null, null, false));
    List<Task> tasksForTreasury = taskRepository.findIncompleteByRole(typeForTreasurer);
    assertThat(tasksForTreasury).isEmpty();
    BankAccount bankAccount = incomingInvoice.getBankAccount();
    assertThat(bankAccount).isNotNull();
    BankAccountVerificationState state = stateTransitionService.currentStateOf(bankAccount, BankAccountVerificationStateTransition.class);
    assertThat(state).isEqualTo(BankAccountVerificationState.NOT_VERIFIED);
    // when
    // workaround: clear MeService#me cache
    queryResultsCache.resetForNextTransaction();
    sudoService.sudo(Person_enum.OscarCountryDirectorGb.getRef().toLowerCase(), (Runnable) () -> wrap(mixin(IncomingInvoice_approveAsCountryDirector.class, incomingInvoice)).act(null, false));
    // then
    assertThat(incomingInvoice.getApprovalState()).isEqualTo(IncomingInvoiceApprovalState.PAYABLE);
    List<IncomingInvoiceApprovalStateTransition> transitions = incomingInvoiceStateTransitionRepository.findByDomainObject(incomingInvoice);
    assertThat(transitions.size()).isEqualTo(7);
    assertThat(transitions.get(0).getTransitionType()).isEqualTo(IncomingInvoiceApprovalStateTransitionType.CHECK_PAYMENT);
    tasksForTreasury = taskRepository.findIncompleteByRole(typeForTreasurer);
    assertThat(tasksForTreasury.size()).isEqualTo(1);
    assertThat(tasksForTreasury.get(0).getDescription()).isEqualTo("Check Payment");
    // and still
    state = stateTransitionService.currentStateOf(bankAccount, BankAccountVerificationStateTransition.class);
    assertThat(state).isEqualTo(BankAccountVerificationState.NOT_VERIFIED);
    // and when
    // workaround: clear MeService#me cache
    queryResultsCache.resetForNextTransaction();
    sudoService.sudo(Person_enum.EmmaTreasurerGb.getRef().toLowerCase(), (Runnable) () -> wrap(mixin(IncomingInvoice_checkPayment.class, incomingInvoice)).act(null, false));
    // then
    assertThat(incomingInvoice.getApprovalState()).isEqualTo(IncomingInvoiceApprovalState.PAID);
}
Also used : Task(org.estatio.module.capex.dom.task.Task) BankAccountVerificationState(org.estatio.module.capex.dom.bankaccount.verification.BankAccountVerificationState) IncomingInvoiceApprovalStateTransition(org.estatio.module.capex.dom.invoice.approval.IncomingInvoiceApprovalStateTransition) PartyRoleType(org.estatio.module.party.dom.role.PartyRoleType) BankAccount(org.estatio.module.financial.dom.BankAccount) BankAccountVerificationStateTransition(org.estatio.module.capex.dom.bankaccount.verification.BankAccountVerificationStateTransition) Test(org.junit.Test)

Aggregations

PartyRoleType (org.estatio.module.party.dom.role.PartyRoleType)13 Person (org.estatio.module.party.dom.Person)9 Task (org.estatio.module.capex.dom.task.Task)6 Test (org.junit.Test)5 Programmatic (org.apache.isis.applib.annotation.Programmatic)4 BankAccountVerificationStateTransition (org.estatio.module.capex.dom.bankaccount.verification.BankAccountVerificationStateTransition)3 BankAccount (org.estatio.module.financial.dom.BankAccount)3 IPartyRoleType (org.estatio.module.party.dom.role.IPartyRoleType)3 PartyRole (org.estatio.module.party.dom.role.PartyRole)3 BankAccountVerificationState (org.estatio.module.capex.dom.bankaccount.verification.BankAccountVerificationState)2 IncomingInvoiceApprovalStateTransition (org.estatio.module.capex.dom.invoice.approval.IncomingInvoiceApprovalStateTransition)2 DisabledException (org.apache.isis.applib.services.wrapper.DisabledException)1 AbstractBeanPropertiesTest (org.incode.module.unittestsupport.dom.bean.AbstractBeanPropertiesTest)1 Expectations (org.jmock.Expectations)1 LocalDateTime (org.joda.time.LocalDateTime)1 Before (org.junit.Before)1