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;
}
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);
}
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;
}
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");
}
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);
}
Aggregations