diff --git a/src/main/java/org/olat/core/commons/persistence/NativeQueryBuilder.java b/src/main/java/org/olat/core/commons/persistence/NativeQueryBuilder.java index ca8b70d48b8f520dd0a5f58b8547a3c6bbb1b606..7afc78d295aa7a254749b286d93970e3d0f134d6 100644 --- a/src/main/java/org/olat/core/commons/persistence/NativeQueryBuilder.java +++ b/src/main/java/org/olat/core/commons/persistence/NativeQueryBuilder.java @@ -127,6 +127,16 @@ public class NativeQueryBuilder { } return this; } + + public NativeQueryBuilder appendOrderBy(SortKey orderBy) { + sb.append(" order by ").append(orderBy.getKey()); + if(orderBy.isAsc()) { + sb.append(" asc"); + } else { + sb.append(" desc"); + } + return this; + } /** * @param i diff --git a/src/main/java/org/olat/resource/accesscontrol/ACService.java b/src/main/java/org/olat/resource/accesscontrol/ACService.java index c06b83bf2243bbb8c6dcdb4174abd7be5da2b0fa..919f464cd2ae0ce1c08b28e938b33f575e0269d2 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ACService.java +++ b/src/main/java/org/olat/resource/accesscontrol/ACService.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Set; import org.olat.basesecurity.IdentityRef; +import org.olat.core.commons.persistence.SortKey; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.group.BusinessGroup; @@ -34,6 +35,7 @@ import org.olat.resource.accesscontrol.model.ACResourceInfo; import org.olat.resource.accesscontrol.model.AccessMethod; import org.olat.resource.accesscontrol.model.OLATResourceAccess; import org.olat.resource.accesscontrol.ui.OrderTableItem; +import org.olat.user.propertyhandlers.UserPropertyHandler; /** * @@ -192,7 +194,11 @@ public interface ACService { public List<Order> findOrders(OLATResource resource, OrderStatus... status); + public int countOrderItems(OLATResource resource, IdentityRef delivery, Long orderNr, Date from, Date to, + OrderStatus[] statuss); + public List<OrderTableItem> findOrderItems(OLATResource resource, IdentityRef delivery, Long orderNr, Date from, Date to, - OrderStatus[] status, int firstResult, int maxResults); + OrderStatus[] status, int firstResult, int maxResults, + List<UserPropertyHandler> userPropertyHandlers, SortKey... orderBy); } diff --git a/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java b/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java index 8246df6e67c26985f5291a9ea1218734f3305745..f7a861d81937b3469f6c53b4d4652b15254a53b2 100644 --- a/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java +++ b/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java @@ -34,6 +34,7 @@ import java.util.Set; import org.olat.basesecurity.GroupRoles; import org.olat.basesecurity.IdentityRef; import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.persistence.SortKey; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.core.logging.OLog; @@ -72,6 +73,7 @@ import org.olat.resource.accesscontrol.model.PSPTransactionStatus; import org.olat.resource.accesscontrol.model.RawOrderItem; import org.olat.resource.accesscontrol.ui.OrderTableItem; import org.olat.resource.accesscontrol.ui.OrderTableItem.Status; +import org.olat.user.propertyhandlers.UserPropertyHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -620,16 +622,23 @@ public class ACFrontendManager implements ACService { return orderManager.findOrdersByResource(resource, status); } + @Override + public int countOrderItems(OLATResource resource, IdentityRef delivery, Long orderNr, Date from, Date to, OrderStatus[] status) { + return orderManager.countNativeOrderItems(resource, delivery, orderNr, from, to, status); + } + @Override public List<OrderTableItem> findOrderItems(OLATResource resource, IdentityRef delivery, Long orderNr, - Date from, Date to, OrderStatus[] status, int firstResult, int maxResults) { + Date from, Date to, OrderStatus[] status, int firstResult, int maxResults, + List<UserPropertyHandler> userPropertyHandlers, SortKey... orderBy) { List<AccessMethod> methods = methodManager.getAllMethods(); Map<String,AccessMethod> methodMap = new HashMap<>(); for(AccessMethod method:methods) { methodMap.put(method.getKey().toString(), method); } - List<RawOrderItem> rawOrders = orderManager.findNativeOrderItems(resource, delivery, orderNr, from, to, firstResult, maxResults, status); + List<RawOrderItem> rawOrders = orderManager.findNativeOrderItems(resource, delivery, orderNr, from, to, status, + firstResult, maxResults, userPropertyHandlers, orderBy); List<OrderTableItem> items = new ArrayList<>(rawOrders.size()); for(RawOrderItem rawOrder:rawOrders) { String orderStatusStr = rawOrder.getOrderStatus(); @@ -649,7 +658,7 @@ public class ACFrontendManager implements ACService { OrderTableItem item = new OrderTableItem(rawOrder.getOrderKey(), rawOrder.getOrderNr(), rawOrder.getTotal(), rawOrder.getCreationDate(), orderStatus, finalStatus, - rawOrder.getDeliveryKey(), orderMethods); + rawOrder.getDeliveryKey(), rawOrder.getUsername(), rawOrder.getUserProperties(), orderMethods); item.setResourceDisplayname(rawOrder.getResourceName()); items.add(item); diff --git a/src/main/java/org/olat/resource/accesscontrol/manager/ACOrderDAO.java b/src/main/java/org/olat/resource/accesscontrol/manager/ACOrderDAO.java index 6029e709f09f3a13a418df2a6a4dced1ec7a2b1e..318e6b310fcae843dfd308723a954155edd5d86c 100644 --- a/src/main/java/org/olat/resource/accesscontrol/manager/ACOrderDAO.java +++ b/src/main/java/org/olat/resource/accesscontrol/manager/ACOrderDAO.java @@ -34,6 +34,7 @@ import org.olat.basesecurity.IdentityRef; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.NativeQueryBuilder; import org.olat.core.commons.persistence.PersistenceHelper; +import org.olat.core.commons.persistence.SortKey; import org.olat.core.id.Identity; import org.olat.resource.OLATResource; import org.olat.resource.accesscontrol.Offer; @@ -46,6 +47,7 @@ import org.olat.resource.accesscontrol.model.OrderImpl; import org.olat.resource.accesscontrol.model.OrderLineImpl; import org.olat.resource.accesscontrol.model.OrderPartImpl; import org.olat.resource.accesscontrol.model.RawOrderItem; +import org.olat.user.propertyhandlers.UserPropertyHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -167,6 +169,90 @@ public class ACOrderDAO { return orders; } + + /** + * The method is optimized for our settings: 1 order -> 1 order part -> 1 order line + * + * @param resource + * @param delivery + * @return + */ + public int countNativeOrderItems(OLATResource resource, IdentityRef delivery, Long orderNr, + Date from, Date to, OrderStatus... status) { + + NativeQueryBuilder sb = new NativeQueryBuilder(1024, dbInstance); + sb.append("select count(o.order_id)") + .append(" from o_ac_order o") + .append(" inner join o_ac_order_part order_part on (o.order_id=order_part.fk_order_id and order_part.pos=0)") + .append(" inner join o_ac_order_line order_line on (order_part.order_part_id=order_line.fk_order_part_id and order_line.pos=0)") + .append(" inner join o_ac_offer offer on (order_line.fk_offer_id=offer.offer_id)"); + boolean where = false; + if(resource != null) { + where = PersistenceHelper.appendAnd(sb, where); + sb.append(" offer.fk_resource_id=:resourceKey "); + } + if(delivery != null) { + where = PersistenceHelper.appendAnd(sb, where); + sb.append(" o.fk_delivery_id=:deliveryKey "); + } + if(status != null && status.length > 0 && status[0] != null) { + where = PersistenceHelper.appendAnd(sb, where); + sb.append("o.order_status in (:status)"); + } + if(from != null) { + where = PersistenceHelper.appendAnd(sb, where); + sb.append("o.creationdate >=:from"); + } + if(to != null) { + where = PersistenceHelper.appendAnd(sb, where); + sb.append("o.creationdate <=:to"); + } + if(orderNr != null) { + where = PersistenceHelper.appendAnd(sb, where); + sb.append("o.order_id=:orderNr"); + } + + Query query = dbInstance.getCurrentEntityManager() + .createNativeQuery(sb.toString()); + if(resource != null) { + query.setParameter("resourceKey", resource.getKey()); + } + if(delivery != null) { + query.setParameter("deliveryKey", delivery.getKey()); + } + if(status != null && status.length > 0 && status[0] != null) { + List<String> statusStr = new ArrayList<String>(); + for(OrderStatus s:status) { + statusStr.add(s.name()); + } + query.setParameter("status", statusStr); + } + if(orderNr != null) { + query.setParameter("orderNr", orderNr); + } + if(from != null) { + Calendar cal = Calendar.getInstance(); + cal.setTime(from); + cal.set(Calendar.HOUR, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + query.setParameter("from", cal.getTime(), TemporalType.TIMESTAMP); + } + if(to != null) { + Calendar cal = Calendar.getInstance(); + cal.setTime(to); + cal.set(Calendar.HOUR, 23); + cal.set(Calendar.MINUTE, 59); + cal.set(Calendar.SECOND, 59); + cal.set(Calendar.MILLISECOND, 0); + query.setParameter("to", cal.getTime(), TemporalType.TIMESTAMP); + } + + Object rawOrders = query.getSingleResult(); + return rawOrders instanceof Number ? ((Number)rawOrders).intValue() : 0; + } + /** * The method is optimized for our settings: 1 order -> 1 order part -> 1 order line * @@ -175,7 +261,8 @@ public class ACOrderDAO { * @return */ public List<RawOrderItem> findNativeOrderItems(OLATResource resource, IdentityRef delivery, Long orderNr, - Date from, Date to, int firstResult, int maxResults, OrderStatus... status) { + Date from, Date to, OrderStatus[] status, int firstResult, int maxResults, + List<UserPropertyHandler> userPropertyHandlers, SortKey... orderBy) { NativeQueryBuilder sb = new NativeQueryBuilder(1024, dbInstance); sb.append("select") @@ -188,13 +275,29 @@ public class ACOrderDAO { .append(" ").appendToArray("offer.resourcedisplayname").append(" as resDisplaynames,") .append(" ").appendToArray("trx.trx_status").append(" as trxStatus,") .append(" ").appendToArray("trx.fk_method_id").append(" as trxMethodIds,") - .append(" ").appendToArray("pspTrx.trx_status").append(" as pspTrxStatus") - .append(" from o_ac_order o") - .append(" left join o_ac_transaction trx on (o.order_id = trx.fk_order_id)") - .append(" left join o_ac_paypal_transaction pspTrx on (o.order_id = pspTrx.order_id)") + .append(" ").appendToArray("pspTrx.trx_status").append(" as pspTrxStatus"); + if(delivery == null) { + sb.append(" ,delivery.id as delivery_ident_id") + .append(" ,delivery.name as delivery_ident_name") + .append(" ,delivery_user.user_id as delivery_user_id"); + if(userPropertyHandlers != null) { + for(UserPropertyHandler handler:userPropertyHandlers) { + sb.append(" ,delivery_user.").append(handler.getDatabaseColumnName()).append(" as ") + .append(handler.getName()); + } + } + } + sb.append(" from o_ac_order o") .append(" inner join o_ac_order_part order_part on (o.order_id=order_part.fk_order_id and order_part.pos=0)") .append(" inner join o_ac_order_line order_line on (order_part.order_part_id=order_line.fk_order_part_id and order_line.pos=0)") .append(" inner join o_ac_offer offer on (order_line.fk_offer_id=offer.offer_id)"); + if(delivery == null) { + sb.append(" inner join o_bs_identity delivery on (delivery.id=o.fk_delivery_id)") + .append(" inner join o_user delivery_user on (delivery_user.fk_identity=delivery.id)"); + } + sb.append(" left join o_ac_paypal_transaction pspTrx on (o.order_id = pspTrx.order_id)") + .append(" left join o_ac_transaction trx on (o.order_id = trx.fk_order_id)"); + boolean where = false; if(resource != null) { where = PersistenceHelper.appendAnd(sb, where); @@ -221,7 +324,25 @@ public class ACOrderDAO { sb.append("o.order_id=:orderNr"); } - sb.append(" group by o.order_id, o.total_currency_code, o.total_amount, o.creationdate, o.order_status, o.fk_delivery_id"); + sb.append(" group by o.order_id"); + if(dbInstance.isOracle()) { + sb.append(", o.total_currency_code, o.total_amount, o.creationdate, o.order_status, o.fk_delivery_id"); + } + if(delivery == null) { + sb.append(", delivery.id, delivery_user.user_id"); + if(dbInstance.isOracle()) { + sb.append(", delivery.name"); + if(userPropertyHandlers != null) { + for(UserPropertyHandler handler:userPropertyHandlers) { + sb.append(", delivery_user.").append(handler.getDatabaseColumnName()); + } + } + } + } + + if(orderBy != null && orderBy.length > 0 && orderBy[0] != null) { + sb.appendOrderBy(orderBy[0]); + } Query query = dbInstance.getCurrentEntityManager() .createNativeQuery(sb.toString()); @@ -263,25 +384,40 @@ public class ACOrderDAO { if(maxResults > 0) { query.setFirstResult(firstResult).setMaxResults(maxResults); } - + + int numOfProperties = userPropertyHandlers == null ? 0 : userPropertyHandlers.size(); List<?> rawOrders = query.getResultList(); List<RawOrderItem> items = new ArrayList<>(rawOrders.size()); for(Object rawOrder:rawOrders) { Object[] order = (Object[])rawOrder; - Long orderKey = ((Number)order[0]).longValue(); - String totalCurrencyCode = (String)order[1]; - BigDecimal totalAmount = (BigDecimal)order[2]; - Date creationDate = (Date)order[3]; - String orderStatus = (String)order[4]; - Long deliveryKey = ((Number)order[5]).longValue(); - String resourceName = (String)order[6]; - String trxStatus = (String)order[7]; - String trxMethodIds = (String)order[8]; - String pspTrxStatus = (String)order[8]; + int pos = 0; + + Long orderKey = ((Number)order[pos++]).longValue(); + String totalCurrencyCode = (String)order[pos++]; + BigDecimal totalAmount = (BigDecimal)order[pos++]; + Date creationDate = (Date)order[pos++]; + String orderStatus = (String)order[pos++]; + Long deliveryKey = ((Number)order[pos++]).longValue(); + String resourceName = (String)order[pos++]; + String trxStatus = (String)order[pos++]; + String trxMethodIds = (String)order[pos++]; + String pspTrxStatus = (String)order[pos++]; + + String username = null; + String[] userProperties = null; + if(numOfProperties > 0) { + pos++;//identityKey + username = (String)order[pos++]; + pos++;//userKey + userProperties = new String[numOfProperties]; + for(int i=0; i<numOfProperties; i++) { + userProperties[i] = (String)order[pos++]; + } + } RawOrderItem item = new RawOrderItem(orderKey, orderKey.toString(), totalCurrencyCode, totalAmount, creationDate, orderStatus, deliveryKey, resourceName, - trxStatus, trxMethodIds, pspTrxStatus); + trxStatus, trxMethodIds, pspTrxStatus, username, userProperties); items.add(item); } return items; diff --git a/src/main/java/org/olat/resource/accesscontrol/model/RawOrderItem.java b/src/main/java/org/olat/resource/accesscontrol/model/RawOrderItem.java index 0294e9f4b7900a0af7cc65c7ce49acaae61736d2..f31edfa7e5063f7247d06fe1d2b6964217131617 100644 --- a/src/main/java/org/olat/resource/accesscontrol/model/RawOrderItem.java +++ b/src/main/java/org/olat/resource/accesscontrol/model/RawOrderItem.java @@ -46,9 +46,13 @@ public class RawOrderItem { private final String trxMethodIds; private final String pspTrxStatus; + private final String username; + private final String[] userProperties; + public RawOrderItem(Long orderKey, String orderNr, String totalCurrencyCode, BigDecimal totalAmount, Date creationDate, String orderStatus, Long deliveryKey, String resourceName, - String trxStatus, String trxMethodIds, String pspTrxStatus) { + String trxStatus, String trxMethodIds, String pspTrxStatus, + String username, String[] userProperties) { this.orderKey = orderKey; this.orderNr = orderNr; this.total = new PriceImpl(totalAmount, totalCurrencyCode); @@ -59,6 +63,8 @@ public class RawOrderItem { this.trxStatus = trxStatus; this.trxMethodIds = trxMethodIds; this.pspTrxStatus = pspTrxStatus; + this.username = username; + this.userProperties = userProperties; } public Long getOrderKey() { @@ -100,4 +106,12 @@ public class RawOrderItem { public String getPspTrxStatus() { return pspTrxStatus; } + + public String getUsername() { + return username; + } + + public String[] getUserProperties() { + return userProperties; + } } diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/AccessMethodRenderer.java b/src/main/java/org/olat/resource/accesscontrol/ui/AccessMethodRenderer.java index be5b243c160e5b5ac95e6595bc10e761769778a9..372caee3f4ea29361a35be29ef6ed6b7f2080c3a 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/AccessMethodRenderer.java +++ b/src/main/java/org/olat/resource/accesscontrol/ui/AccessMethodRenderer.java @@ -24,9 +24,13 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; import org.olat.core.gui.components.table.CustomCellRenderer; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.URLBuilder; +import org.olat.core.gui.translator.Translator; import org.olat.resource.accesscontrol.AccessControlModule; import org.olat.resource.accesscontrol.AccessTransaction; import org.olat.resource.accesscontrol.method.AccessMethodHandler; @@ -41,7 +45,7 @@ import org.olat.resource.accesscontrol.model.AccessMethod; * Initial Date: 27 mai 2011 <br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class AccessMethodRenderer implements CustomCellRenderer { +public class AccessMethodRenderer implements CustomCellRenderer, FlexiCellRenderer { private final AccessControlModule acModule; @@ -49,6 +53,33 @@ public class AccessMethodRenderer implements CustomCellRenderer { this.acModule = acModule; } + + + @Override + public void render(Renderer renderer, StringOutput sb, Object val, int row, FlexiTableComponent source, + URLBuilder ubu, Translator translator) { + + if(val instanceof AccessTransaction) { + AccessTransaction transaction = (AccessTransaction)val; + Set<String> uniqueType = new HashSet<String>(3); + render(sb, transaction, uniqueType, translator.getLocale()); + } else if (val instanceof Collection) { + Collection<?> transactions = (Collection<?>)val; + Set<String> uniqueType = new HashSet<String>((transactions.size() * 2) + 1); + for(Object transaction : transactions) { + if(transaction instanceof AccessTransaction) { + render(sb, (AccessTransaction)transaction, uniqueType, translator.getLocale()); + } else if(transaction instanceof AccessMethod) { + render(sb, (AccessMethod)transaction, uniqueType, translator.getLocale()); + + } + + } + } + } + + + @Override public void render(StringOutput sb, Renderer renderer, Object val, Locale locale, int alignment, String action) { diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/OrderStatusRenderer.java b/src/main/java/org/olat/resource/accesscontrol/ui/OrderStatusRenderer.java index 46d581277daca689aa329bd5779057dd258c24fc..caaf92b264b93e1885d9841748572fdfb47b4c35 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/OrderStatusRenderer.java +++ b/src/main/java/org/olat/resource/accesscontrol/ui/OrderStatusRenderer.java @@ -19,11 +19,12 @@ */ package org.olat.resource.accesscontrol.ui; -import java.util.Locale; - -import org.olat.core.gui.components.table.CustomCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.URLBuilder; +import org.olat.core.gui.translator.Translator; import org.olat.resource.accesscontrol.OrderStatus; /** @@ -35,14 +36,11 @@ import org.olat.resource.accesscontrol.OrderStatus; * Initial Date: 27 mai 2011 <br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class OrderStatusRenderer implements CustomCellRenderer { +public class OrderStatusRenderer implements FlexiCellRenderer { - public OrderStatusRenderer() { - // - } - @Override - public void render(StringOutput sb, Renderer renderer, Object val, Locale locale, int alignment, String action) { + public void render(Renderer renderer, StringOutput sb, Object val, int row, FlexiTableComponent source, + URLBuilder ubu, Translator translator) { if(val instanceof OrderStatus) { OrderStatus status = (OrderStatus)val; String name = status.name().toLowerCase(); @@ -52,10 +50,10 @@ public class OrderStatusRenderer implements CustomCellRenderer { } else if (val instanceof OrderTableItem) { OrderTableItem item = (OrderTableItem)val; switch(item.getStatus()) { - case ERROR: sb.append("<i class='o_icon o_icon-fw o_ac_order_status_error_icon'></i>"); break; - case WARNING: sb.append("<i class='o_icon o_icon-fw o_ac_order_status_warning_icon'></i>"); break; - case CANCELED: sb.append("<i class='o_icon o_icon-fw o_ac_order_status_canceled_icon'></i>"); break; - default: sb.append("<i class='o_icon o_icon-fw o_ac_order_status_payed_icon'></i>"); + case ERROR: sb.append("<i class='o_icon o_icon-fw o_ac_order_status_error_icon'> </i>"); break; + case WARNING: sb.append("<i class='o_icon o_icon-fw o_ac_order_status_warning_icon'> </i>"); break; + case CANCELED: sb.append("<i class='o_icon o_icon-fw o_ac_order_status_canceled_icon'> </i>"); break; + default: sb.append("<i class='o_icon o_icon-fw o_ac_order_status_payed_icon'> </i>"); } } } diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/OrderTableItem.java b/src/main/java/org/olat/resource/accesscontrol/ui/OrderTableItem.java index 5104c7019fbbd244ca62ad577f2a4ba51434d60f..f2b77e96635473b5e0b847af5d93bf6539df87dc 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/OrderTableItem.java +++ b/src/main/java/org/olat/resource/accesscontrol/ui/OrderTableItem.java @@ -27,7 +27,6 @@ import java.util.HashSet; import java.util.List; import org.olat.resource.accesscontrol.AccessTransaction; -import org.olat.resource.accesscontrol.Order; import org.olat.resource.accesscontrol.OrderStatus; import org.olat.resource.accesscontrol.Price; import org.olat.resource.accesscontrol.model.AccessMethod; @@ -57,19 +56,15 @@ public class OrderTableItem { private String resourceDisplayname; private Long deliveryKey; + private String username; + private String[] userProperties; + private Status status; private List<AccessMethod> methods; - public OrderTableItem(Order order) { - orderKey = order.getKey(); - orderNr = order.getOrderNr(); - orderStatus = order.getOrderStatus(); - total = order.getTotal(); - creationDate = order.getCreationDate(); - } - public OrderTableItem(Long orderKey, String orderNr, Price total, Date creationDate, - OrderStatus orderStatus, Status status, Long deliveryKey, List<AccessMethod> methods) { + OrderStatus orderStatus, Status status, Long deliveryKey, + String username, String[] userProperties, List<AccessMethod> methods) { this.orderKey = orderKey; this.orderNr = orderNr; this.total = total; @@ -78,6 +73,8 @@ public class OrderTableItem { this.status = status; this.deliveryKey = deliveryKey; this.methods = methods; + this.username = username; + this.userProperties = userProperties; } public Long getOrderKey() { @@ -111,8 +108,14 @@ public class OrderTableItem { public void setResourceDisplayname(String resourceDisplayname) { this.resourceDisplayname = resourceDisplayname; } - - + + public String getUsername() { + return username; + } + + public String[] getUserProperties() { + return userProperties; + } public List<AccessMethod> getMethods() { return methods; diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersAdminController.java b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersAdminController.java index 4c169969bdc746aea319964256b2f3b76532add9..e7798ba50596bf220deb7c3e0307f7368170cdf1 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersAdminController.java +++ b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersAdminController.java @@ -20,29 +20,34 @@ package org.olat.resource.accesscontrol.ui; import java.util.ArrayList; -import java.util.Date; +import java.util.Calendar; import java.util.List; -import org.olat.core.gui.ShortName; +import org.olat.basesecurity.BaseSecurityModule; +import org.olat.commons.calendar.CalendarUtils; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent; import org.olat.core.gui.components.panel.StackedPanel; -import org.olat.core.gui.components.stack.TooledStackedPanel; -import org.olat.core.gui.components.table.ColumnDescriptor; -import org.olat.core.gui.components.table.CustomRenderColumnDescriptor; -import org.olat.core.gui.components.table.DefaultColumnDescriptor; -import org.olat.core.gui.components.table.StaticColumnDescriptor; -import org.olat.core.gui.components.table.Table; -import org.olat.core.gui.components.table.TableController; -import org.olat.core.gui.components.table.TableEvent; -import org.olat.core.gui.components.table.TableGuiConfiguration; +import org.olat.core.gui.components.stack.BreadcrumbPanel; +import org.olat.core.gui.components.stack.BreadcrumbPanelAware; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.Roles; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; import org.olat.core.util.resource.OresHelper; @@ -51,8 +56,9 @@ import org.olat.resource.accesscontrol.ACService; import org.olat.resource.accesscontrol.AccessControlModule; import org.olat.resource.accesscontrol.Order; import org.olat.resource.accesscontrol.OrderStatus; -import org.olat.resource.accesscontrol.ui.OrdersDataModel.Col; +import org.olat.resource.accesscontrol.ui.OrdersDataModel.OrderCol; import org.olat.user.UserManager; +import org.olat.user.propertyhandlers.UserPropertyHandler; import org.springframework.beans.factory.annotation.Autowired; /** @@ -64,25 +70,37 @@ import org.springframework.beans.factory.annotation.Autowired; * Initial Date: 30 mai 2011 <br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class OrdersAdminController extends BasicController implements Activateable2 { +public class OrdersAdminController extends FormBasicController implements Activateable2, BreadcrumbPanelAware { + + protected static final int USER_PROPS_OFFSET = 500; + protected static final String USER_PROPS_ID = OrdersAdminController.class.getCanonicalName(); private static final String CMD_SELECT = "sel"; - private final StackedPanel mainPanel; - private final VelocityContainer mainVC; - private final TableController tableCtr; + private StackedPanel mainPanel; + private VelocityContainer mainVC; + + private FlexiTableElement tableEl; + private OrdersDataSource dataSource; + private OrdersDataModel dataModel; + + private BreadcrumbPanel stackPanel; private OrdersSearchForm searchForm; - private final TooledStackedPanel stackPanel; private OrderDetailController detailController; private final OLATResource resource; - - @Autowired - private AccessControlModule acModule; + + private final boolean isAdministrativeUser; + private final List<UserPropertyHandler> userPropertyHandlers; + @Autowired private ACService acService; @Autowired private UserManager userManager; + @Autowired + private AccessControlModule acModule; + @Autowired + private BaseSecurityModule securityModule; /** * Constructor for the admin. extension @@ -94,110 +112,112 @@ public class OrdersAdminController extends BasicController implements Activateab this(ureq, wControl, null, null); } - public OrdersAdminController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, OLATResource resource) { - super(ureq, wControl); + public OrdersAdminController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel, OLATResource resource) { + super(ureq, wControl, "order_list"); this.resource = resource; this.stackPanel = stackPanel; - if(resource == null) { - searchForm = new OrdersSearchForm(ureq, wControl); - listenTo(searchForm); + Roles roles = ureq.getUserSession().getRoles(); + isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles); + userPropertyHandlers = userManager.getUserPropertyHandlersFor(USER_PROPS_ID, isAdministrativeUser); + setTranslator(userManager.getPropertyHandlerTranslator(getTranslator())); + + initForm(ureq); + } + + @Override + public void setBreadcrumbPanel(BreadcrumbPanel stackPanel) { + this.stackPanel = stackPanel; + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.status, new OrderStatusRenderer())); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.orderNr)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.creationDate)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.summary)); + + if(isAdministrativeUser) { + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.username)); } - TableGuiConfiguration tableConfig = new TableGuiConfiguration(); - tableConfig.setDownloadOffered(true); - //tableConfig.setPreferencesOffered(true, "Orders2"); - //tableConfig.setTableEmptyMessage(translate("table.order.empty")); - - List<ShortName> statusList = new ArrayList<ShortName>(); - OrderStatusContextShortName allStatus = new OrderStatusContextShortName("-", OrderStatus.values()); - OrderStatusContextShortName newStatus = new OrderStatusContextShortName(translate("order.status.new"), OrderStatus.NEW); - OrderStatusContextShortName preStatus = new OrderStatusContextShortName(translate("order.status.prepayment"), OrderStatus.PREPAYMENT); - OrderStatusContextShortName payedStatus = new OrderStatusContextShortName(translate("order.status.payed"), OrderStatus.PAYED); - OrderStatusContextShortName cancelStatus = new OrderStatusContextShortName(translate("order.status.canceled"), OrderStatus.CANCELED); - OrderStatusContextShortName errorStatus = new OrderStatusContextShortName(translate("order.status.error"), OrderStatus.ERROR); - statusList.add(allStatus); - statusList.add(newStatus); - statusList.add(preStatus); - statusList.add(payedStatus); - statusList.add(cancelStatus); - statusList.add(errorStatus); + int i=0; + for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) { + int colIndex = USER_PROPS_OFFSET + i++; + if (userPropertyHandler == null) continue; + + String propName = userPropertyHandler.getName(); + boolean visible = userManager.isMandatoryUserProperty(USER_PROPS_ID , userPropertyHandler); - tableCtr = new TableController(tableConfig, ureq, wControl, statusList, payedStatus, translate("order.status"), null, false, getTranslator()); - tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("order.status", Col.status.ordinal(), null, getLocale(), - ColumnDescriptor.ALIGNMENT_LEFT, new OrderStatusRenderer()) { - @Override - public int compareTo(int rowa, int rowb) { - OrderTableItem a = (OrderTableItem)table.getTableDataModel().getValueAt(rowa, dataColumn); - OrderTableItem b = (OrderTableItem)table.getTableDataModel().getValueAt(rowb, dataColumn); - return a.compareStatusTo(b); - } - }); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("order.nr", Col.orderNr.ordinal(), CMD_SELECT, getLocale())); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("order.creationDate", Col.creationDate.ordinal(), null, getLocale())); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("order.summary", Col.summary.ordinal(), null, getLocale())); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("order.delivery", Col.delivery.ordinal(), null, getLocale())); - tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("order.part.payment", Col.methods.ordinal(), null, getLocale(), - ColumnDescriptor.ALIGNMENT_LEFT, new AccessMethodRenderer(acModule))); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("order.total", Col.total.ordinal(), null, getLocale())); - tableCtr.addColumnDescriptor(new StaticColumnDescriptor(CMD_SELECT, "table.order.details", getTranslator().translate("select"))); + FlexiColumnModel col = new DefaultFlexiColumnModel(visible, userPropertyHandler.i18nColumnDescriptorLabelKey(), colIndex, true, propName); + columnsModel.addFlexiColumnModel(col); + } + + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.methods, new AccessMethodRenderer(acModule))); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.total)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.order.details", translate("select"), CMD_SELECT)); - listenTo(tableCtr); + dataSource = new OrdersDataSource(acService, resource, null, userPropertyHandlers); + if(resource == null) { + searchForm = new OrdersSearchForm(ureq, getWindowControl(), mainForm); + listenTo(searchForm); + formLayout.add("searchForm", searchForm.getInitialFormItem()); + + Calendar cal = CalendarUtils.getStartOfDayCalendar(getLocale()); + cal.add(Calendar.MONTH, -1); + searchForm.setFrom(cal.getTime()); + dataSource.setFrom(cal.getTime()); + } - loadModel(); + dataModel = new OrdersDataModel(dataSource, getLocale(), userManager, columnsModel); + tableEl = uifactory.addTableElement(getWindowControl(), "orderList", dataModel, 25, true, getTranslator(), formLayout); + tableEl.setExportEnabled(true); + + List<FlexiTableFilter> filters = new ArrayList<>(); + filters.add(new FlexiTableFilter(translate("order.status.new"), OrderStatus.NEW.name())); + filters.add(new FlexiTableFilter(translate("order.status.prepayment"), OrderStatus.PREPAYMENT.name())); + filters.add(new FlexiTableFilter(translate("order.status.payed"), OrderStatus.PAYED.name())); + filters.add(new FlexiTableFilter(translate("order.status.canceled"), OrderStatus.CANCELED.name())); + filters.add(new FlexiTableFilter(translate("order.status.error"), OrderStatus.ERROR.name())); + tableEl.setFilters("", filters, false); - mainVC = createVelocityContainer("orders"); - if(searchForm != null) { - mainVC.put("searchForm", searchForm.getInitialComponent()); + if(formLayout instanceof FormLayoutContainer) { + FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout; + layoutCont.contextPut("title", translate("orders.admin.my")); + layoutCont.contextPut("description", translate("orders.admin.my.desc")); } - mainVC.put("orderList", tableCtr.getInitialComponent()); - mainVC.contextPut("title", translate("orders.admin.my")); - mainVC.contextPut("description", translate("orders.admin.my.desc")); + } - mainPanel = putInitialPanel(mainVC); + @Override + protected void formOK(UserRequest ureq) { + // } - - private void loadModel() { - OrderStatusContextShortName filter = (OrderStatusContextShortName)tableCtr.getActiveFilter(); - Date from = null; - Date to = null; - Long orderNr = null; - if(searchForm != null) { - from = searchForm.getFrom(); - to = searchForm.getTo(); - orderNr = searchForm.getRefNo(); + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(source == tableEl) { + if(event instanceof SelectionEvent) { + SelectionEvent se = (SelectionEvent)event; + OrderTableItem row = dataModel.getObject(se.getIndex()); + if(CMD_SELECT.equals(se.getCommand())) { + doSelectOrder(ureq, row); + } + } } - List<OrderTableItem> items = acService.findOrderItems(resource, null, orderNr, from, to, filter.getStatus(), 0, -1); - tableCtr.setTableDataModel(new OrdersDataModel(items, getLocale(), userManager)); + super.formInnerEvent(ureq, source, event); } protected void doDispose() { // } - @Override - protected void event(UserRequest ureq, Component source, Event event) { - // - } @Override protected void event(UserRequest ureq, Controller source, Event event) { - if(source == tableCtr) { - if (event.getCommand().equals(Table.COMMANDLINK_ROWACTION_CLICKED)) { - TableEvent te = (TableEvent) event; - String actionid = te.getActionId(); - int rowid = te.getRowId(); - OrderTableItem order = (OrderTableItem)tableCtr.getTableDataModel().getObject(rowid); - if(CMD_SELECT.equals(actionid)) { - selectOrder(ureq, order); - } - } else if (TableController.EVENT_FILTER_SELECTED == event) { - loadModel(); - addToHistory(ureq, getWindowControl()); - } - } else if (source == searchForm) { + if (source == searchForm) { if(event == Event.DONE_EVENT) { - loadModel(); + doSearch(); addSearchToHistory(ureq); } } else if (source == detailController) { @@ -210,6 +230,14 @@ public class OrdersAdminController extends BasicController implements Activateab } } + private void doSearch() { + dataSource.setFrom(searchForm.getFrom()); + dataSource.setTo(searchForm.getTo()); + dataSource.setRefNo(searchForm.getRefNo()); + dataSource.reset(); + tableEl.reset(true, true, true); + } + protected void addSearchToHistory(UserRequest ureq) { StateEntry state = searchForm == null ? null : searchForm.getStateEntry(); ContextEntry currentEntry = getWindowControl().getBusinessControl().getCurrentContextEntry(); @@ -219,7 +247,7 @@ public class OrdersAdminController extends BasicController implements Activateab addToHistory(ureq, getWindowControl()); } - protected void selectOrder(UserRequest ureq, OrderTableItem order) { + protected void doSelectOrder(UserRequest ureq, OrderTableItem order) { removeAsListenerAndDispose(detailController); OLATResourceable ores = OresHelper.createOLATResourceableInstance(Order.class, order.getOrderKey()); @@ -237,6 +265,7 @@ public class OrdersAdminController extends BasicController implements Activateab @Override public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + /* if(state != null) { if(searchForm.setStateEntry(state)) { loadModel(); @@ -251,5 +280,6 @@ public class OrdersAdminController extends BasicController implements Activateab if(order != null) { selectOrder(ureq, order); } + */ } } \ No newline at end of file diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersController.java b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersController.java index d73ee3f6f1e1121eed5ba029a9efbc426ec4552a..b2e6a29cc34bb101b640021ddddf9950349c2fed 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersController.java +++ b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersController.java @@ -23,23 +23,23 @@ package org.olat.resource.accesscontrol.ui; import java.util.ArrayList; import java.util.List; -import org.olat.core.gui.ShortName; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.Component; -import org.olat.core.gui.components.panel.StackedPanel; -import org.olat.core.gui.components.table.ColumnDescriptor; -import org.olat.core.gui.components.table.CustomRenderColumnDescriptor; -import org.olat.core.gui.components.table.DefaultColumnDescriptor; -import org.olat.core.gui.components.table.StaticColumnDescriptor; -import org.olat.core.gui.components.table.Table; -import org.olat.core.gui.components.table.TableController; -import org.olat.core.gui.components.table.TableEvent; -import org.olat.core.gui.components.table.TableGuiConfiguration; -import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent; +import org.olat.core.gui.components.stack.BreadcrumbPanel; +import org.olat.core.gui.components.stack.BreadcrumbPanelAware; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.ContextEntry; @@ -49,7 +49,7 @@ import org.olat.resource.accesscontrol.ACService; import org.olat.resource.accesscontrol.AccessControlModule; import org.olat.resource.accesscontrol.Order; import org.olat.resource.accesscontrol.OrderStatus; -import org.olat.resource.accesscontrol.ui.OrdersDataModel.Col; +import org.olat.resource.accesscontrol.ui.OrdersDataModel.OrderCol; import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; @@ -62,100 +62,93 @@ import org.springframework.beans.factory.annotation.Autowired; * Initial Date: 20 avr. 2011 <br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class OrdersController extends BasicController implements Activateable2 { +public class OrdersController extends FormBasicController implements Activateable2, BreadcrumbPanelAware { private static final String CMD_SELECT = "sel"; + + + private FlexiTableElement tableEl; + private OrdersDataSource dataSource; + private OrdersDataModel dataModel; + private BreadcrumbPanel stackPanel; - private final StackedPanel mainPanel; - private final VelocityContainer mainVC; - private final TableController tableCtr; private OrderDetailController detailController; - @Autowired - private AccessControlModule acModule; @Autowired private ACService acService; @Autowired private UserManager userManager; + @Autowired + private AccessControlModule acModule; public OrdersController(UserRequest ureq, WindowControl wControl) { - super(ureq, wControl); + super(ureq, wControl, LAYOUT_BAREBONE); + initForm(ureq); + } - TableGuiConfiguration tableConfig = new TableGuiConfiguration(); - tableConfig.setDownloadOffered(true); - tableConfig.setPreferencesOffered(true, "Orders"); - tableConfig.setTableEmptyMessage(translate("table.order.empty")); - - List<ShortName> statusList = new ArrayList<ShortName>(); - OrderStatusContextShortName payedStatus = new OrderStatusContextShortName(translate("order.status.payed"), OrderStatus.PAYED); - OrderStatusContextShortName errorStatus = new OrderStatusContextShortName(translate("order.status.error"), OrderStatus.ERROR); - statusList.add(payedStatus); - statusList.add(errorStatus); + @Override + public void setBreadcrumbPanel(BreadcrumbPanel stackPanel) { + this.stackPanel = stackPanel; + } - tableCtr = new TableController(tableConfig, ureq, wControl, statusList, payedStatus, translate("order.status"), null, false, getTranslator()); - tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("order.status", Col.status.ordinal(), null, getLocale(), - ColumnDescriptor.ALIGNMENT_LEFT, new OrderStatusRenderer()) { - @Override - public int compareTo(int rowa, int rowb) { - OrderTableItem a = (OrderTableItem)table.getTableDataModel().getValueAt(rowa, dataColumn); - OrderTableItem b = (OrderTableItem)table.getTableDataModel().getValueAt(rowb, dataColumn); - return a.compareStatusTo(b); - } - }); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("order.nr", Col.orderNr.ordinal(), CMD_SELECT, getLocale())); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("order.creationDate", Col.creationDate.ordinal(), null, getLocale())); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("order.summary", Col.summary.ordinal(), null, getLocale())); - tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("order.part.payment", Col.methods.ordinal(), null, getLocale(), - ColumnDescriptor.ALIGNMENT_LEFT, new AccessMethodRenderer(acModule))); - - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("order.total", Col.total.ordinal(), null, getLocale())); - - tableCtr.addColumnDescriptor(new StaticColumnDescriptor(CMD_SELECT, "table.order.details", getTranslator().translate("order.details"))); - listenTo(tableCtr); - - loadModel(); + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.status, new OrderStatusRenderer())); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.orderNr)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.creationDate)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.summary)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.methods, new AccessMethodRenderer(acModule))); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.total)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.order.details", translate("select"), CMD_SELECT)); - mainVC = createVelocityContainer("orders"); - mainVC.put("orderList", tableCtr.getInitialComponent()); - mainVC.contextPut("title", translate("orders.my")); - mainVC.contextPut("description", translate("orders.my.desc")); + dataSource = new OrdersDataSource(acService, null, getIdentity(), null); + dataModel = new OrdersDataModel(dataSource, getLocale(), userManager, columnsModel); + tableEl = uifactory.addTableElement(getWindowControl(), "orderList", dataModel, 25, true, getTranslator(), formLayout); + tableEl.setExportEnabled(true); + tableEl.setEmtpyTableMessageKey("table.order.empty"); - mainPanel = putInitialPanel(mainVC); - } - - private void loadModel() { - OrderStatusContextShortName filter = (OrderStatusContextShortName)tableCtr.getActiveFilter(); - List<OrderTableItem> items = acService.findOrderItems(null, getIdentity(), null, null, null, filter.getStatus(), 0, -1); - tableCtr.setTableDataModel(new OrdersDataModel(items, getLocale(), userManager)); + List<FlexiTableFilter> filters = new ArrayList<>(); + filters.add(new FlexiTableFilter(translate("order.status.payed"), OrderStatus.PAYED.name())); + filters.add(new FlexiTableFilter(translate("order.status.error"), OrderStatus.ERROR.name())); + tableEl.setFilters("", filters, false); + + if(formLayout instanceof FormLayoutContainer) { + FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout; + layoutCont.contextPut("title", translate("orders.my")); + layoutCont.contextPut("description", translate("orders.my.desc")); + } } @Override protected void doDispose() { // } - + @Override - protected void event(UserRequest ureq, Component source, Event event) { + protected void formOK(UserRequest ureq) { // } - + @Override - protected void event(UserRequest ureq, Controller source, Event event) { - if(source == tableCtr) { - if (event.getCommand().equals(Table.COMMANDLINK_ROWACTION_CLICKED)) { - TableEvent te = (TableEvent) event; - String actionid = te.getActionId(); - int rowid = te.getRowId(); - OrderTableItem order = (OrderTableItem)tableCtr.getTableDataModel().getObject(rowid); - if(CMD_SELECT.equals(actionid)) { - selectOrder(ureq, order); + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(source == tableEl) { + if(event instanceof SelectionEvent) { + SelectionEvent se = (SelectionEvent)event; + OrderTableItem row = dataModel.getObject(se.getIndex()); + if(CMD_SELECT.equals(se.getCommand())) { + doSelectOrder(ureq, row); } - } else if (TableController.EVENT_FILTER_SELECTED == event) { - loadModel(); } - } else if (source == detailController) { + } + super.formInnerEvent(ureq, source, event); + } + + + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if (source == detailController) { if(event == Event.BACK_EVENT) { - mainPanel.setContent(mainVC); removeAsListenerAndDispose(detailController); detailController = null; } @@ -164,7 +157,7 @@ public class OrdersController extends BasicController implements Activateable2 { @Override public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { - if(entries == null || entries.isEmpty()) return; + /*if(entries == null || entries.isEmpty()) return; ContextEntry entry = entries.get(0); String type = entry.getOLATResourceable().getResourceableTypeName(); @@ -176,16 +169,17 @@ public class OrdersController extends BasicController implements Activateable2 { break; } } - } + }*/ } - protected void selectOrder(UserRequest ureq, OrderTableItem order) { + private void doSelectOrder(UserRequest ureq, OrderTableItem order) { removeAsListenerAndDispose(detailController); OLATResourceable ores = OresHelper.createOLATResourceableInstance(Order.class, order.getOrderKey()); WindowControl bwControl = addToHistory(ureq, ores, null); detailController = new OrderDetailController(ureq, bwControl, order.getOrderKey()); + detailController.hideBackLink(); listenTo(detailController); - mainPanel.setContent(detailController.getInitialComponent()); + stackPanel.pushController(order.getOrderNr(), detailController); } } \ No newline at end of file diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersDataModel.java b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersDataModel.java index 485ea1b63cb45dba631df74d80559131db18f321..5248a97c0fd5e13c09610c2b50336c2213099168 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersDataModel.java +++ b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersDataModel.java @@ -1,70 +1,42 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ - package org.olat.resource.accesscontrol.ui; import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Locale; -import org.olat.core.gui.components.table.TableDataModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataSourceModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataSourceDelegate; import org.olat.core.util.StringHelper; import org.olat.resource.accesscontrol.model.AccessMethod; import org.olat.user.UserManager; /** * - * Description:<br> - * A data model which hold the orders and their transactions - * - * <P> - * Initial Date: 20 avr. 2011 <br> + * Initial date: 5 janv. 2017<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * */ -public class OrdersDataModel implements TableDataModel<OrderTableItem> { +public class OrdersDataModel extends DefaultFlexiTableDataSourceModel<OrderTableItem> { private final Locale locale; - private List<OrderTableItem> orders; private final UserManager userManager; - public OrdersDataModel(List<OrderTableItem> orders, Locale locale, UserManager userManager) { - this.orders = orders; + public OrdersDataModel(FlexiTableDataSourceDelegate<OrderTableItem> dataSource, Locale locale, UserManager userManager, FlexiTableColumnModel columnModel) { + super(dataSource, columnModel); this.locale = locale; this.userManager = userManager; } - @Override - public int getColumnCount() { - return 1; - } - - @Override - public int getRowCount() { - return orders.size(); - } - @Override public Object getValueAt(int row, int col) { - OrderTableItem order = orders.get(row); - switch(Col.get(col)) { + OrderTableItem order = getObject(row); + if(col >= OrdersAdminController.USER_PROPS_OFFSET) { + int propIndex = col - OrdersAdminController.USER_PROPS_OFFSET; + return order.getUserProperties()[propIndex]; + } + + switch(OrderCol.values()[col]) { case status: { return order; } @@ -93,46 +65,47 @@ public class OrdersDataModel implements TableDataModel<OrderTableItem> { return "-"; } case summary: return order.getResourceDisplayname(); + case username: return order.getUsername(); default: return order; } } @Override - public OrderTableItem getObject(int row) { - return orders.get(row); + public OrdersDataModel createCopyWithEmptyList() { + return new OrdersDataModel(getSourceDelegate(), locale, userManager, getTableColumnModel()); } - public OrderTableItem getItem(Long key) { - if(orders == null) return null; - for(OrderTableItem item:orders) { - if(item.getOrderKey().equals(key)) { - return item; - } + public enum OrderCol implements FlexiSortableColumnDef { + orderNr("order.nr", "order_id"), + creationDate("order.creationDate", "creationdate"), + delivery("order.delivery", "delivery_id"), + methods("order.part.payment", "trxMethodIds"), + total("order.total", "total_amount"), + summary("order.summary", "resDisplaynames"), + status("order.status", "o_status"), + username("order.username", "delivery_ident_name"); + + private final String i18nKey; + private final String sortKey; + + private OrderCol(String i18nKey, String sortKey) { + this.i18nKey = i18nKey; + this.sortKey = sortKey; } - return null; - } - @Override - public void setObjects(List<OrderTableItem> objects) { - this.orders = objects; - } + @Override + public String i18nHeaderKey() { + return i18nKey; + } - @Override - public Object createCopyWithEmptyList() { - return new OrdersDataModel(Collections.<OrderTableItem>emptyList(), locale, userManager); - } - - public enum Col { - orderNr, - creationDate, - delivery, - methods, - total, - summary, - status; + @Override + public boolean sortable() { + return true; + } - public static Col get(int index) { - return values()[index]; + @Override + public String sortKey() { + return sortKey; } } } diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersDataSource.java b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersDataSource.java new file mode 100644 index 0000000000000000000000000000000000000000..17cb289fe8dc97fae593e2b856ec72253814fd73 --- /dev/null +++ b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersDataSource.java @@ -0,0 +1,98 @@ +package org.olat.resource.accesscontrol.ui; + +import java.util.Date; +import java.util.List; + +import org.olat.basesecurity.IdentityRef; +import org.olat.core.commons.persistence.DefaultResultInfos; +import org.olat.core.commons.persistence.ResultInfos; +import org.olat.core.commons.persistence.SortKey; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataSourceDelegate; +import org.olat.resource.OLATResource; +import org.olat.resource.accesscontrol.ACService; +import org.olat.resource.accesscontrol.OrderStatus; +import org.olat.user.propertyhandlers.UserPropertyHandler; + +/** + * + * Initial date: 5 janv. 2017<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class OrdersDataSource implements FlexiTableDataSourceDelegate<OrderTableItem> { + + private ACService acService; + + private Long refNo; + private Integer count; + private Date from, to; + private final OLATResource resource; + private final IdentityRef delivery; + private final List<UserPropertyHandler> userPropertyHandlers; + + public OrdersDataSource(ACService acService, OLATResource resource, IdentityRef delivery, + List<UserPropertyHandler> userPropertyHandlers) { + this.acService = acService; + this.resource = resource; + this.delivery = delivery; + this.userPropertyHandlers = userPropertyHandlers; + } + + public Long getRefNo() { + return refNo; + } + + public void setRefNo(Long refNo) { + this.refNo = refNo; + } + + public Date getFrom() { + return from; + } + + public void setFrom(Date from) { + this.from = from; + } + + public Date getTo() { + return to; + } + + public void setTo(Date to) { + this.to = to; + } + + public void reset() { + count = null; + } + + @Override + public int getRowCount() { + if(count == null) { + count = acService.countOrderItems(resource, delivery, refNo, from, to, null); + } + return count.intValue(); + } + + @Override + public List<OrderTableItem> reload(List<OrderTableItem> rows) { + return rows; + } + + @Override + public ResultInfos<OrderTableItem> getRows(String query, List<FlexiTableFilter> filters, List<String> condQueries, + int firstResult, int maxResults, SortKey... orderBy) { + + OrderStatus[] states = null; + if(filters != null && filters.size() > 0) { + String filter = filters.get(0).getFilter(); + states = new OrderStatus[] { OrderStatus.valueOf(filter) }; + } + + List<OrderTableItem> rows = acService.findOrderItems(resource, delivery, refNo, from, to, states, + firstResult, maxResults, userPropertyHandlers, orderBy); + ResultInfos<OrderTableItem> results = new DefaultResultInfos<>(firstResult + rows.size(), -1, rows); + return results; + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersSearchForm.java b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersSearchForm.java index ba8eced0db57758f24000f21fc5182da6d5a9115..6aa4a6b970550c1dddabc69e375371f7f7cb9a51 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersSearchForm.java +++ b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersSearchForm.java @@ -25,6 +25,7 @@ import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.DateChooser; import org.olat.core.gui.components.form.flexible.elements.TextElement; +import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.control.Controller; @@ -51,7 +52,11 @@ public class OrdersSearchForm extends FormBasicController { public OrdersSearchForm(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); - + initForm(ureq); + } + + public OrdersSearchForm(UserRequest ureq, WindowControl wControl, Form rootForm) { + super(ureq, wControl, LAYOUT_DEFAULT, null, rootForm); initForm(ureq); } @@ -65,7 +70,6 @@ public class OrdersSearchForm extends FormBasicController { buttonCont.setRootForm(mainForm); formLayout.add(buttonCont); uifactory.addFormSubmitButton("search", "search", buttonCont); - } @Override @@ -136,6 +140,10 @@ public class OrdersSearchForm extends FormBasicController { public Date getFrom() { return fromEl.getDate(); } + + public void setFrom(Date from) { + fromEl.setDate(from); + } @Override protected void formOK(UserRequest ureq) { diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/_content/order_list.html b/src/main/java/org/olat/resource/accesscontrol/ui/_content/order_list.html new file mode 100644 index 0000000000000000000000000000000000000000..f77d933b39a0f968b33df388afb830d129d04f22 --- /dev/null +++ b/src/main/java/org/olat/resource/accesscontrol/ui/_content/order_list.html @@ -0,0 +1,8 @@ +<div class="o_sel_order_list"> + <h4><i class="o_icon o_icon_booking"> </i> $title</h4> + <div class="o_info">$description</div> + #if($r.available("searchForm")) + $r.render("searchForm") + #end + $r.render("orderList") +</div> \ No newline at end of file diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties index 8be17c72b44bec50e5a925ecd00f6d10dfdc9b8d..dbb1d949e0a14678699af862ed5f63068158a69e 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties @@ -84,6 +84,7 @@ order.status.prepayment=In Zahlungsprozess order.summary=Inhalt order.to=An order.total=Total +order.username=Benutzername orders.admin.my=Buchungen dieser Ressource orders.admin.my.desc=Diese Ressource wurde von den folgenden Benutzern gebucht. W\u00E4hlen Sie eine Buchung, um weitere Detailinformationen anzuzeigen. orders.my=Meine Buchungen diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties index 8e82309da73676683408df1ff63a7a6f332438fe..9685a5e74c95dcbd50dbcb1237bc21cf661f1cbc 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties @@ -107,6 +107,7 @@ order.status.prepayment=In payment process order.summary=Content order.to=To order.total=Total +order.username=Username orders.admin.my=Bookings of this resource orders.admin.my.desc=This resource has been booked by the following people. Select a booking to see the booking details. orders.my=My bookings diff --git a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml index 6e9e93aa87194eda4666497accb8728e83113f10..0b8028b698b1fa65df9a7cbcaeb4539e75d8f9c3 100644 --- a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml +++ b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml @@ -317,6 +317,30 @@ </bean> </entry> + <entry key="org.olat.resource.accesscontrol.ui.OrdersAdminController"> + <bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext"> + <property name="description" value="Booking list" /> + <property name="propertyHandlers"> + <list> + <ref bean="userPropertyLastName" /> + <ref bean="userPropertyFirstName" /> + <ref bean="userPropertyInstitutionalUserIdentifier" /> + </list> + </property> + <property name="mandatoryProperties"> + <set> + <ref bean="userPropertyLastName" /> + <ref bean="userPropertyFirstName" /> + </set> + </property> + <property name="adminViewOnlyProperties"> + <set> + <ref bean="userPropertyInstitutionalUserIdentifier" /> + </set> + </property> + </bean> + </entry> + <entry key="org.olat.course.nodes.cl.ui.CheckListAssessmentController"> <bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext"> <property name="description" value="Table for check lists" /> diff --git a/src/test/java/org/olat/resource/accesscontrol/ACOrderManagerTest.java b/src/test/java/org/olat/resource/accesscontrol/ACOrderManagerTest.java index fcbf8f73fa7acd4d3f76872b6e35ce7851bfb2c6..c18bddb2c5a205ebf3115ef82296e2f174379fca 100644 --- a/src/test/java/org/olat/resource/accesscontrol/ACOrderManagerTest.java +++ b/src/test/java/org/olat/resource/accesscontrol/ACOrderManagerTest.java @@ -32,6 +32,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.persistence.SortKey; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.util.CodeHelper; @@ -48,6 +49,7 @@ import org.olat.resource.accesscontrol.model.FreeAccessMethod; import org.olat.resource.accesscontrol.model.PriceImpl; import org.olat.resource.accesscontrol.model.RawOrderItem; import org.olat.resource.accesscontrol.model.TokenAccessMethod; +import org.olat.resource.accesscontrol.ui.OrdersDataModel.OrderCol; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; import org.springframework.beans.factory.annotation.Autowired; @@ -194,9 +196,16 @@ public class ACOrderManagerTest extends OlatTestCase { acTransactionManager.update(accessTransaction2, AccessTransactionStatus.CANCELED); long start = System.nanoTime(); - List<RawOrderItem> items = acOrderManager.findNativeOrderItems(randomOres, null, null, null, null, 0, -1); + List<RawOrderItem> items = acOrderManager.findNativeOrderItems(randomOres, null, null, null, null, null, 0, -1, null); CodeHelper.printNanoTime(start, "Order itemized"); Assert.assertNotNull(items); + + //check the order by + for(OrderCol col:OrderCol.values()) { + List<RawOrderItem> rawItems = acOrderManager.findNativeOrderItems(randomOres, null, null, null, null, null, + 0, -1, null, new SortKey(col.sortKey(), false)); + Assert.assertNotNull(rawItems); + } } @Test @@ -222,7 +231,7 @@ public class ACOrderManagerTest extends OlatTestCase { dbInstance.commitAndCloseSession(); long start = System.nanoTime(); - List<RawOrderItem> items = acOrderManager.findNativeOrderItems(randomOres, null, null, null, null, 0, -1); + List<RawOrderItem> items = acOrderManager.findNativeOrderItems(randomOres, null, null, null, null, null, 0, -1, null); CodeHelper.printNanoTime(start, "Order itemized"); Assert.assertNotNull(items); } diff --git a/src/test/java/org/olat/selenium/page/core/BookingPage.java b/src/test/java/org/olat/selenium/page/core/BookingPage.java index 54fece431eabb288c84bfa35f3fa871769e1d85f..3ac9ae74baef1ebcd58b8f64e14135a84ba08a95 100644 --- a/src/test/java/org/olat/selenium/page/core/BookingPage.java +++ b/src/test/java/org/olat/selenium/page/core/BookingPage.java @@ -128,20 +128,9 @@ public class BookingPage { * @return */ public BookingPage assertFirstNameInListIsOk(UserVO user) { - By firstNameBy = By.xpath("//td[contains(text(),'" + user.getFirstName() + "')]"); - By okBy = By.className("o_ac_order_status_payed_icon"); - By rowBy = By.cssSelector(".o_sel_order_list table.o_table.table tr"); - boolean found = false; - List<WebElement> rows = browser.findElements(rowBy); - for(WebElement row:rows) { - List<WebElement> firstNameEl = row.findElements(firstNameBy); - List<WebElement> okEl = row.findElements(okBy); - if(firstNameEl.size() == 1 && okEl.size() == 1) { - found = true; - break; - } - } - Assert.assertTrue(found); + By rowsBy = By.xpath("//div[contains(@class,'o_sel_order_list')]//table//tr[td/i[contains(@class,'o_ac_order_status_payed_icon')]]/td/a[contains(text(),'" + user.getFirstName() + "')]"); + List<WebElement> rows = browser.findElements(rowsBy); + Assert.assertEquals(1, rows.size()); return this; } }