Skip to content

Commit

Permalink
FMD-53 generate qr codes in coceso, update to knockout 3.5.1
Browse files Browse the repository at this point in the history
  • Loading branch information
robo-w committed May 9, 2020
1 parent 1a7d5f8 commit 7ed3c4b
Show file tree
Hide file tree
Showing 25 changed files with 1,317 additions and 161 deletions.
17 changes: 16 additions & 1 deletion main/entity/src/main/java/at/wrk/coceso/entity/Container.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,28 @@
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapKeyJoinColumn;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import javax.persistence.*;

@Entity
@Table(name = "container")
Expand Down
2 changes: 2 additions & 0 deletions main/resources/ReleaseNotes/2.7.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
* FMD-27 Auto-complete for street intersections
* FMD-194 Provide one-time-actions of type "nextState" on geobroker API
* FMD-23 Refactor links of PDF reports: use dropdown instead of separate buttons
* FMD-53 Generate QR code in CoCeSo
* FMD-53 Upgrade to knockout 3.5.1
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
package at.wrk.coceso.service.impl;

import at.wrk.coceso.entity.Concern;
import at.wrk.coceso.entity.Unit;
import at.wrk.coceso.entity.Container;
import at.wrk.coceso.entity.Unit;
import at.wrk.coceso.entity.enums.Errors;
import at.wrk.coceso.exceptions.ErrorsException;
import at.wrk.coceso.repository.ContainerRepository;
import at.wrk.coceso.repository.UnitRepository;
import at.wrk.coceso.service.ConcernService;
import at.wrk.coceso.service.ContainerService;
import at.wrk.coceso.utils.Initializer;
import com.google.common.collect.ImmutableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
class ContainerServiceImpl implements ContainerService {
private static final Logger LOG = LoggerFactory.getLogger(ContainerServiceImpl.class);

@Autowired
private ContainerRepository containerRepository;
Expand All @@ -31,6 +36,21 @@ class ContainerServiceImpl implements ContainerService {
@Autowired
private ConcernService concernService;

@Override
public List<Container> getAll(final int concernId) {
Concern concern = concernService.getById(concernId);

List<Container> containers;
if (concern != null) {
containers = getAll(concern);
} else {
LOG.info("Failed to read concern for concernId '{}'.", concernId);
containers = ImmutableList.of();
}

return containers;
}

@Override
public List<Container> getAll(Concern concern) {
List<Container> container = containerRepository.findByConcern(concern);
Expand All @@ -54,7 +74,10 @@ public Container getRoot(Concern concern) {

@Override
public Set<Integer> getSpare(Concern concern) {
return unitRepository.findSpare(concern).stream().map(Unit::getId).collect(Collectors.toSet());
return unitRepository.findSpare(concern)
.stream()
.map(Unit::getId)
.collect(Collectors.toSet());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

import at.wrk.coceso.entity.Concern;
import at.wrk.coceso.entity.Container;
import java.util.List;
import java.util.Set;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

@Service
@Transactional
public interface ContainerService {

List<Container> getAll(int concernId);

List<Container> getAll(Concern concern);

Container getRoot(Concern concern);
Expand All @@ -25,7 +28,7 @@ public interface ContainerService {

Container doRemoveUnit(int unitId);

static class ContainerPair {
class ContainerPair {

public boolean notifyRoot = false;
public Container previous = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,35 @@
public class DeploymentStatusProvider {
private static final Logger LOG = LoggerFactory.getLogger(DeploymentStatusProvider.class);

private static final String ALARM_TEXT_CLASS = "at.wrk.coceso.alarm.text.controller.AlarmTextController";
private static final String GEOBROKER_CONTROLLER_CLASS = "at.wrk.coceso.plugin.geobroker.controller.GeobrokerUnitController";

private final boolean alarmTextModuleDeployed;
private final boolean geoBrokerModuleDeployed;

public DeploymentStatusProvider() {
this.alarmTextModuleDeployed = checkIfClassIsPresent(ALARM_TEXT_CLASS);
this.geoBrokerModuleDeployed = checkIfClassIsPresent(GEOBROKER_CONTROLLER_CLASS);
}

public boolean isAlarmTextModuleDeployed() {
return alarmTextModuleDeployed;
}

public boolean isGeoBrokerModuleDeployed() {
return geoBrokerModuleDeployed;
}

private boolean checkIfClassIsPresent(final String className) {
boolean alarmTextClassPresent;
try {
Class.forName("at.wrk.coceso.alarm.text.controller.AlarmTextController");
LOG.debug("Alarm Text Module is present in classpath.");
Class.forName(className);
LOG.info("Class was found during deployment status check: '{}'. Associated feature is ENABLED.", className);
alarmTextClassPresent = true;
} catch (ClassNotFoundException e) {
LOG.info("Class was not found during deployment status check: '{}'. Associated feature is DISABLED. Message: {}", className, e.getMessage());
alarmTextClassPresent = false;
}

this.alarmTextModuleDeployed = alarmTextClassPresent;
}

public boolean isAlarmTextModuleDeployed() {
return alarmTextModuleDeployed;
return alarmTextClassPresent;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@
import at.wrk.coceso.service.ContainerService;
import at.wrk.coceso.service.ContainerWriteService;
import at.wrk.coceso.utils.ActiveConcern;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@PreAuthorize("@auth.hasAccessLevel('Edit')")
Expand All @@ -29,36 +34,43 @@ public class ContainerController {
private final EntityEventHandler<Container> entityEventHandler;

@Autowired
public ContainerController(EntityEventFactory eehf) {
this.entityEventHandler = eehf.getEntityEventHandler(Container.class);
public ContainerController(final EntityEventFactory entityEventFactory) {
this.entityEventHandler = entityEventFactory.getEntityEventHandler(Container.class);
}

@RequestMapping(value = "getAll", produces = "application/json", method = RequestMethod.GET)
public SequencedResponse<List<Container>> getAll(@ActiveConcern Concern concern) {
public SequencedResponse<List<Container>> getAll(@ActiveConcern final Concern concern) {
return new SequencedResponse<>(entityEventHandler.getHver(), entityEventHandler.getSeq(concern.getId()), containerService.getAll(concern));
}

@RequestMapping(value = "getAllForConcern", produces = "application/json", method = RequestMethod.GET)
public RestResponse getAll(@RequestParam(value = "concernId") final int concernId) {
return new RestResponse(true, new RestProperty("container", containerService.getAll(concernId)));
}

@RequestMapping(value = "updateContainer", produces = "application/json", method = RequestMethod.POST)
public RestResponse updateContainer(@RequestBody Container container, @ActiveConcern Concern concern) {
container = containerWriteService.update(container, concern);
return new RestResponse(true, new RestProperty("id", container.getId()));
public RestResponse updateContainer(@RequestBody final Container container, @ActiveConcern final Concern concern) {
Container updatedContainer = containerWriteService.update(container, concern);
return new RestResponse(true, new RestProperty("id", updatedContainer.getId()));
}

@RequestMapping(value = "removeContainer", produces = "application/json", method = RequestMethod.POST)
public RestResponse removeContainer(@RequestParam("container_id") int containerId) {
public RestResponse removeContainer(@RequestParam("container_id") final int containerId) {
containerWriteService.remove(containerId);
return new RestResponse(true);
}

@RequestMapping(value = "updateUnit", produces = "application/json", method = RequestMethod.POST)
public RestResponse updateUnit(@RequestParam("container_id") int containerId,
@RequestParam("unit_id") int unitId, @RequestParam("ordering") double ordering) {
public RestResponse updateUnit(
@RequestParam("container_id") final int containerId,
@RequestParam("unit_id") final int unitId,
@RequestParam("ordering") final double ordering) {
containerWriteService.updateUnit(containerId, unitId, ordering);
return new RestResponse(true);
}

@RequestMapping(value = "removeUnit", produces = "application/json", method = RequestMethod.POST)
public RestResponse removeUnit(@RequestParam("unit_id") int unitId) {
public RestResponse removeUnit(@RequestParam("unit_id") final int unitId) {
containerWriteService.removeUnit(unitId);
return new RestResponse(true);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.wrk.coceso.controller.view;

import at.wrk.coceso.controller.config.DeploymentStatusProvider;
import at.wrk.coceso.data.AuthenticatedUser;
import at.wrk.coceso.entity.Concern;
import at.wrk.coceso.entity.User;
Expand All @@ -9,6 +10,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.web.WebAttributes;
Expand All @@ -27,13 +29,23 @@

@Controller
public class WelcomeController {
private final static Logger LOG = LoggerFactory.getLogger(WelcomeController.class);

private static final Set<Integer> ALLOWED_ERRORS = ImmutableSet.of(1);

private final static Logger LOG = LoggerFactory.getLogger(WelcomeController.class);
private final UserService userService;
private final DeploymentStatusProvider deploymentStatusProvider;
private final String publicGeoBrokerUrl;

@Autowired
private UserService userService;
public WelcomeController(
final UserService userService,
final DeploymentStatusProvider deploymentStatusProvider,
final @Value("${geobroker.public.url:configuration-missing}") String publicGeoBrokerUrl) {
this.userService = userService;
this.deploymentStatusProvider = deploymentStatusProvider;
this.publicGeoBrokerUrl = publicGeoBrokerUrl.endsWith("/") ? publicGeoBrokerUrl : publicGeoBrokerUrl + "/";
}

@PreAuthorize("permitAll")
@RequestMapping(value = "/", method = RequestMethod.GET)
Expand Down Expand Up @@ -73,17 +85,26 @@ public String showHome(
response.addCookie(new Cookie("concern", active.getId() + ""));
} else {
// Delete Cookie and active concern reference
LOG.info("{}: Active concern is already closed, clean up", authenticationUser);
LOG.info("{}: Active concern is already closed, cleaning up cookie", authenticationUser);
response.addCookie(new Cookie("concern", null));
userService.setActiveConcern(authenticationUser, null);
}

// Add Userdetails to Model
map.addAttribute("user", Initializer.init(user, User::getInternalAuthorities));
map.addAttribute("authenticatedUser", authenticationUser);
map.put("isGeoBrokerFeatureAvailable", deploymentStatusProvider.isGeoBrokerModuleDeployed());

LOG.debug("{}: Started Home Screen", user);
LOG.debug("{}: Started Home Screen with model map: {}", user, map);

return "home";
}

@PreAuthorize("@auth.hasAccessLevel('Edit')")
@RequestMapping(value = "/geo/qr-codes", method = RequestMethod.GET)
public String showQrCodePage(final ModelMap map, @RequestParam(value = "concernId") final int concernId) {
map.put("concernId", concernId);
map.put("publicGeobrokerUrl", publicGeoBrokerUrl);
return "qr_codes";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ concern.locked=<strong>Die aktuelle Ambulanz ist in einem anderen Fenster ge\u00
Falls das nicht funktioniert k\u00f6nnen Sie eine Aufhebung der Sperre erzwingen.
concern.unlock=Sperre aufheben
concern.addsection=Abschnitt hinzuf\u00fcgen
concern.qr.codes=QR Codes

# Unit - Properties
unit=Einheit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ concern.locked=<strong>Some page seems to lock the concern.</strong><br/> \
You can also force unlocking.
concern.unlock=Force unlocking
concern.addsection=Create section
concern.qr.codes=QR Codes

# Unit - Properties
unit=Unit
Expand Down
15 changes: 11 additions & 4 deletions main/view/src/main/webapp/WEB-INF/pages/home.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@
<button type="button" class="btn btn-sm btn-danger" data-bind="click: close"><spring:message code="concern.close"/></button>
</sec:authorize>
<sec:authorize access="@auth.hasAccessLevel('Report')">
<div class="btn-group" role="group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<spring:message code="pdf.report.create"/> <span class="caret"></span>
</button>
<ul class="dropdown-menu">
Expand All @@ -126,6 +126,13 @@
</ul>
</div>
</sec:authorize>
<sec:authorize access="@auth.hasAccessLevel('Edit')">
<c:if test="${isGeoBrokerFeatureAvailable}">
<a target="_blank" data-bind="attr: {href: '<c:url value="/geo/qr-codes?concernId="/>' + id}" class="btn btn-sm btn-default">
<spring:message code="concern.qr.codes"/>
</a>
</c:if>
</sec:authorize>
</td>
</tr>
</tbody>
Expand Down Expand Up @@ -163,8 +170,8 @@
<button type="button" class="btn btn-sm btn-danger" data-bind="click: reopen"><spring:message code="concern.reopen"/></button>
</sec:authorize>
<sec:authorize access="@auth.hasAccessLevel('Report')">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<spring:message code="pdf.report.create"/> <span class="caret"></span>
</button>
<ul class="dropdown-menu">
Expand Down
Loading

0 comments on commit 7ed3c4b

Please sign in to comment.