Skip to content
Snippets Groups Projects
Commit a678fa5c authored by uhensler's avatar uhensler
Browse files

OO-4688: Option to allow the same course ID for several auto bookings

parent 83f98055
No related branches found
No related tags found
No related merge requests found
...@@ -35,6 +35,8 @@ import org.olat.resource.accesscontrol.manager.ACMethodDAO; ...@@ -35,6 +35,8 @@ import org.olat.resource.accesscontrol.manager.ACMethodDAO;
import org.olat.resource.accesscontrol.method.AccessMethodHandler; import org.olat.resource.accesscontrol.method.AccessMethodHandler;
import org.olat.resource.accesscontrol.model.FreeAccessMethod; import org.olat.resource.accesscontrol.model.FreeAccessMethod;
import org.olat.resource.accesscontrol.model.TokenAccessMethod; import org.olat.resource.accesscontrol.model.TokenAccessMethod;
import org.olat.resource.accesscontrol.provider.auto.AdvanceOrder;
import org.olat.resource.accesscontrol.provider.auto.manager.AdvanceOrderDAO;
import org.olat.resource.accesscontrol.provider.paypal.model.PaypalAccessMethod; import org.olat.resource.accesscontrol.provider.paypal.model.PaypalAccessMethod;
import org.olat.resource.accesscontrol.provider.paypalcheckout.model.PaypalCheckoutAccessMethod; import org.olat.resource.accesscontrol.provider.paypalcheckout.model.PaypalCheckoutAccessMethod;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -67,6 +69,8 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO ...@@ -67,6 +69,8 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO
private static final String PAYPAL_CHECKOUT_ENABLED = "method.paypal.checkout.enabled"; private static final String PAYPAL_CHECKOUT_ENABLED = "method.paypal.checkout.enabled";
private static final String AUTO_ENABLED = "method.auto.enabled"; private static final String AUTO_ENABLED = "method.auto.enabled";
private static final String AUTO_EXTERNAL_REF_DELIMITER = "method.auto.external.ref.delimiter"; private static final String AUTO_EXTERNAL_REF_DELIMITER = "method.auto.external.ref.delimiter";
private static final String AUTO_MULTI_BOOKING = "method.auto.multi.booking";
private static final String AUTO_RESET_TO_PENDING = "method.auto.reset.to.pending";
@Value("${resource.accesscontrol.enabled:true}") @Value("${resource.accesscontrol.enabled:true}")
private boolean enabled; private boolean enabled;
...@@ -78,6 +82,10 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO ...@@ -78,6 +82,10 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO
private boolean autoEnabled; private boolean autoEnabled;
@Value("${method.auto.externalRef.delimiter}") @Value("${method.auto.externalRef.delimiter}")
private String autoExternalRefDelimiter; private String autoExternalRefDelimiter;
@Value("${method.auto.multi.booking}")
private boolean autoMultiBooking;
@Value("${method.auto.reset.to.pending}")
private boolean autoResetToPending;
@Value("${method.token.enabled:true}") @Value("${method.token.enabled:true}")
private boolean tokenEnabled; private boolean tokenEnabled;
@Value("${method.paypal.enabled:false}") @Value("${method.paypal.enabled:false}")
...@@ -95,6 +103,8 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO ...@@ -95,6 +103,8 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO
private DB dbInstance; private DB dbInstance;
private final ACMethodDAO acMethodManager; private final ACMethodDAO acMethodManager;
@Autowired @Autowired
private AdvanceOrderDAO advanceOrderDao;
@Autowired
private List<AccessMethodHandler> methodHandlers; private List<AccessMethodHandler> methodHandlers;
@Autowired @Autowired
...@@ -108,6 +118,7 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO ...@@ -108,6 +118,7 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO
//module enabled/disabled //module enabled/disabled
updateProperties(); updateProperties();
updateAccessMethods(); updateAccessMethods();
resetResetAutoStatusToPending();
log.info("Access control module is enabled: " + Boolean.toString(enabled)); log.info("Access control module is enabled: " + Boolean.toString(enabled));
} }
...@@ -152,6 +163,16 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO ...@@ -152,6 +163,16 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO
autoExternalRefDelimiter = autoExternalRefDelimiterObj; autoExternalRefDelimiter = autoExternalRefDelimiterObj;
} }
String autoMultiBookingObj = getStringPropertyValue(AUTO_MULTI_BOOKING, true);
if(StringHelper.containsNonWhitespace(autoMultiBookingObj)) {
autoMultiBooking = "true".equals(autoMultiBookingObj);
}
String autoResetToPendingObj = getStringPropertyValue(AUTO_RESET_TO_PENDING, true);
if(StringHelper.containsNonWhitespace(autoResetToPendingObj)) {
autoResetToPending = "true".equals(autoResetToPendingObj);
}
String homeEnabledObj = getStringPropertyValue(AC_HOME_ENABLED, true); String homeEnabledObj = getStringPropertyValue(AC_HOME_ENABLED, true);
if(StringHelper.containsNonWhitespace(homeEnabledObj)) { if(StringHelper.containsNonWhitespace(homeEnabledObj)) {
homeOverviewEnabled = "true".equals(homeEnabledObj); homeOverviewEnabled = "true".equals(homeEnabledObj);
...@@ -186,6 +207,13 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO ...@@ -186,6 +207,13 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO
dbInstance.commitAndCloseSession(); dbInstance.commitAndCloseSession();
} }
private void resetResetAutoStatusToPending() {
if (autoResetToPending) {
advanceOrderDao.updateAllStatus(AdvanceOrder.Status.PENDING);
dbInstance.commitAndCloseSession();
}
}
@Override @Override
public boolean isEnabled() { public boolean isEnabled() {
return enabled; return enabled;
...@@ -237,6 +265,15 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO ...@@ -237,6 +265,15 @@ public class AccessControlModule extends AbstractSpringModule implements ConfigO
setStringProperty(AUTO_EXTERNAL_REF_DELIMITER, autoExternalRefDelimiter, true); setStringProperty(AUTO_EXTERNAL_REF_DELIMITER, autoExternalRefDelimiter, true);
} }
public boolean isAutoMultiBooking() {
return autoMultiBooking;
}
public void setAutoMultiBooking(boolean autoMultiBooking) {
this.autoMultiBooking = autoMultiBooking;
setStringProperty(AUTO_MULTI_BOOKING, Boolean.toString(autoMultiBooking), true);
}
public boolean isPaypalEnabled() { public boolean isPaypalEnabled() {
return paypalEnabled; return paypalEnabled;
} }
......
...@@ -28,6 +28,7 @@ import java.util.stream.Collectors; ...@@ -28,6 +28,7 @@ import java.util.stream.Collectors;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DB;
import org.olat.core.commons.persistence.QueryBuilder;
import org.olat.core.id.Identity; import org.olat.core.id.Identity;
import org.olat.core.util.StringHelper; import org.olat.core.util.StringHelper;
import org.olat.resource.accesscontrol.model.AccessMethod; import org.olat.resource.accesscontrol.model.AccessMethod;
...@@ -45,7 +46,7 @@ import org.springframework.stereotype.Service; ...@@ -45,7 +46,7 @@ import org.springframework.stereotype.Service;
* *
*/ */
@Service @Service
class AdvanceOrderDAO { public class AdvanceOrderDAO {
@Autowired @Autowired
private DB dbInstance; private DB dbInstance;
...@@ -151,15 +152,32 @@ class AdvanceOrderDAO { ...@@ -151,15 +152,32 @@ class AdvanceOrderDAO {
return advanceOrder; return advanceOrder;
} }
AdvanceOrder accomplishAndSave(AdvanceOrder advanceOrder) { AdvanceOrder accomplishAndSave(AdvanceOrder advanceOrder, boolean multiOrder) {
if (advanceOrder == null) return advanceOrder; if (advanceOrder == null) return advanceOrder;
advanceOrder.setStatus(Status.DONE); if (!multiOrder) {
advanceOrder.setStatus(Status.DONE);
}
advanceOrder.setStatusModified(new Date()); advanceOrder.setStatusModified(new Date());
advanceOrder = save(advanceOrder); advanceOrder = save(advanceOrder);
return advanceOrder; return advanceOrder;
} }
public void updateAllStatus(Status status) {
QueryBuilder sb = new QueryBuilder();
sb.append("update advanceOrder advanceOrder");
sb.append(" set advanceOrder.status = :status");
sb.append(" , advanceOrder.lastModified = :lastModified");
sb.and().append(" advanceOrder.status <> :status");
dbInstance.getCurrentEntityManager()
.createQuery(sb.toString())
.setParameter("status", status)
.setParameter("lastModified", new Date())
.executeUpdate();
}
static final class IdentifierKeyValue { static final class IdentifierKeyValue {
......
...@@ -166,7 +166,7 @@ public class AutoAccessManagerImpl implements AutoAccessManager, UserDataDeletab ...@@ -166,7 +166,7 @@ public class AutoAccessManagerImpl implements AutoAccessManager, UserDataDeletab
for (RepositoryEntry entry: entries) { for (RepositoryEntry entry: entries) {
grantAccessIfHasNoAccess(advanceOrder, entry); grantAccessIfHasNoAccess(advanceOrder, entry);
} }
advanceOrderDAO.accomplishAndSave(advanceOrder); advanceOrderDAO.accomplishAndSave(advanceOrder, acModule.isAutoMultiBooking());
} }
} }
......
...@@ -1359,9 +1359,16 @@ method.auto.shib.shib= ...@@ -1359,9 +1359,16 @@ method.auto.shib.shib=
method.auto.shib.splitter.values=Semicolon method.auto.shib.splitter.values=Semicolon
method.auto.shib.splitter= method.auto.shib.splitter=
# External eeference may have many values separated by this delimiter. # External reference may have many values separated by this delimiter.
# If the value is not defined, no splitting is executed. # If the value is not defined, no splitting is executed.
method.auto.externalRef.delimiter= method.auto.externalRef.delimiter=
# If multi booking is disabled (false), a auto booking is done once and never again.
# If multi booking is enabled (true), a auto booking is done multiple times per identifier
# value and user. If two courses have the same id, the user is booked to both.
method.auto.multi.booking=false
# If enabled (true), the status of all existing advance orders is reset to pending (on startup).
# That is, all advance orders are ready again to create a new booking.
method.auto.reset.to.pending=false
######################################## ########################################
# Paypal Checkout # Paypal Checkout
......
...@@ -27,6 +27,7 @@ import java.util.HashSet; ...@@ -27,6 +27,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.assertj.core.api.SoftAssertions;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DB;
...@@ -132,7 +133,7 @@ public class AdvanceOrderDAOTest extends OlatTestCase { ...@@ -132,7 +133,7 @@ public class AdvanceOrderDAOTest extends OlatTestCase {
AdvanceOrder advanceOrderWithOtherIdentity = sut.create(otherIdentity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod); AdvanceOrder advanceOrderWithOtherIdentity = sut.create(otherIdentity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod);
sut.save(advanceOrderWithOtherIdentity); sut.save(advanceOrderWithOtherIdentity);
AdvanceOrder doneAdvanceOrder = sut.create(identity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod); AdvanceOrder doneAdvanceOrder = sut.create(identity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod);
sut.accomplishAndSave(doneAdvanceOrder); sut.accomplishAndSave(doneAdvanceOrder, false);
dbInstance.commitAndCloseSession(); dbInstance.commitAndCloseSession();
Collection<AdvanceOrder> pendingAdvanceOrders = sut.loadPendingAdvanceOrders(identity); Collection<AdvanceOrder> pendingAdvanceOrders = sut.loadPendingAdvanceOrders(identity);
...@@ -204,7 +205,7 @@ public class AdvanceOrderDAOTest extends OlatTestCase { ...@@ -204,7 +205,7 @@ public class AdvanceOrderDAOTest extends OlatTestCase {
sut.save(aoPending); sut.save(aoPending);
AdvanceOrder aoDone = sut.create(identity, IdentifierKey.externalId, IDENTIFIER_VALUE, freeMethod); AdvanceOrder aoDone = sut.create(identity, IdentifierKey.externalId, IDENTIFIER_VALUE, freeMethod);
sut.save(aoDone); sut.save(aoDone);
sut.accomplishAndSave(aoDone); sut.accomplishAndSave(aoDone, false);
Identity otherIdentity = JunitTestHelper.createAndPersistIdentityAsRndUser("otheruser"); Identity otherIdentity = JunitTestHelper.createAndPersistIdentityAsRndUser("otheruser");
AdvanceOrder aoOtherIdentity = sut.create(otherIdentity, IdentifierKey.internalId, "not matching", freeMethod); AdvanceOrder aoOtherIdentity = sut.create(otherIdentity, IdentifierKey.internalId, "not matching", freeMethod);
sut.save(aoOtherIdentity); sut.save(aoOtherIdentity);
...@@ -234,21 +235,31 @@ public class AdvanceOrderDAOTest extends OlatTestCase { ...@@ -234,21 +235,31 @@ public class AdvanceOrderDAOTest extends OlatTestCase {
} }
@Test @Test
public void shouldMarkAsDoneWhenAccomplished() { public void shouldMarkAsDoneWhenAccomplishedAndSingleOrder() {
AdvanceOrder advanceOrder = sut.create(identity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod); AdvanceOrder advanceOrder = sut.create(identity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod);
advanceOrder = sut.save(advanceOrder); advanceOrder = sut.save(advanceOrder);
AdvanceOrder accomplishedAdvanceOrder = sut.accomplishAndSave(advanceOrder); AdvanceOrder accomplishedAdvanceOrder = sut.accomplishAndSave(advanceOrder, false);
assertThat(accomplishedAdvanceOrder.getStatus()).isEqualTo(Status.DONE); assertThat(accomplishedAdvanceOrder.getStatus()).isEqualTo(Status.DONE);
} }
@Test
public void shouldMarkAsDoneWhenAccomplishedAndMultoOrder() {
AdvanceOrder advanceOrder = sut.create(identity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod);
advanceOrder = sut.save(advanceOrder);
AdvanceOrder accomplishedAdvanceOrder = sut.accomplishAndSave(advanceOrder, true);
assertThat(accomplishedAdvanceOrder.getStatus()).isEqualTo(Status.PENDING);
}
@Test @Test
public void shouldNotMarkedAsDoneIfNoOffer() { public void shouldNotMarkedAsDoneIfNoOffer() {
AdvanceOrder advanceOrder = sut.create(identity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod); AdvanceOrder advanceOrder = sut.create(identity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod);
advanceOrder = sut.save(advanceOrder); advanceOrder = sut.save(advanceOrder);
AdvanceOrder accomplishedAdvanceOrder = sut.accomplishAndSave(advanceOrder); AdvanceOrder accomplishedAdvanceOrder = sut.accomplishAndSave(advanceOrder, false);
assertThat(accomplishedAdvanceOrder.getStatus()).isEqualTo(advanceOrder.getStatus()); assertThat(accomplishedAdvanceOrder.getStatus()).isEqualTo(advanceOrder.getStatus());
} }
...@@ -309,4 +320,27 @@ public class AdvanceOrderDAOTest extends OlatTestCase { ...@@ -309,4 +320,27 @@ public class AdvanceOrderDAOTest extends OlatTestCase {
assertThat(exists).isFalse(); assertThat(exists).isFalse();
} }
@Test
public void shouldUpdateAllStatus() {
AdvanceOrder advanceOrder = sut.create(identity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod);
advanceOrder.setStatus(AdvanceOrder.Status.DONE);
sut.save(advanceOrder);
AdvanceOrder advanceOrder2 = sut.create(identity, IDENTIFIER_KEY, IDENTIFIER_VALUE, freeMethod);
advanceOrder2.setStatus(AdvanceOrder.Status.DONE);
sut.save(advanceOrder2);
dbInstance.commitAndCloseSession();
Collection<AdvanceOrder> pending = sut.loadPendingAdvanceOrders(identity);
SoftAssertions softly = new SoftAssertions();
softly.assertThat(pending).hasSize(0);
sut.updateAllStatus(AdvanceOrder.Status.PENDING);
dbInstance.commitAndCloseSession();
pending = sut.loadPendingAdvanceOrders(identity);
softly.assertThat(pending).hasSize(2);
softly.assertAll();
}
} }
...@@ -270,7 +270,7 @@ public class AutoAccessManagerImplTest { ...@@ -270,7 +270,7 @@ public class AutoAccessManagerImplTest {
sut.grantAccess(getPendingAdvanceOrders()); sut.grantAccess(getPendingAdvanceOrders());
verify(advanceOrderDaoMock, times(2)).accomplishAndSave(any(AdvanceOrder.class)); verify(advanceOrderDaoMock, times(2)).accomplishAndSave(any(AdvanceOrder.class), false);
} }
@Test @Test
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment