[BP-843] feat: add cyclic reports controller

* added cyclic reports controller
* added report generation config dto
* added dozer mapping entry to map between ReportGenerationConfig
  and ReportGenerationConfigDto
* added testcases for ReportGenerationConfigDto

Signed-off-by: Tobias Stummer <stummer@develop-group.de>
diff --git a/oKBereitschaftsplanungBackend/src/main/java/org/eclipse/openk/sp/controller/CyclicReportsController.java b/oKBereitschaftsplanungBackend/src/main/java/org/eclipse/openk/sp/controller/CyclicReportsController.java
new file mode 100644
index 0000000..a2550df
--- /dev/null
+++ b/oKBereitschaftsplanungBackend/src/main/java/org/eclipse/openk/sp/controller/CyclicReportsController.java
@@ -0,0 +1,286 @@
+/* *******************************************************************************
+ * Copyright (c) 2020 Basys GmbH
+ * 
+ * See the NOTICE file(s) distributed with this work for additional 
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * *******************************************************************************/
+package org.eclipse.openk.sp.controller;
+
+import java.io.File;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+
+import javax.annotation.PostConstruct;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import javax.ws.rs.core.Response;
+
+import org.apache.log4j.Logger;
+import org.eclipse.openk.sp.controller.reports.ReportController;
+import org.eclipse.openk.sp.db.converter.EntityConverter;
+import org.eclipse.openk.sp.db.dao.CyclicReportGenerationConfigRepository;
+import org.eclipse.openk.sp.db.model.ReportGenerationConfig;
+import org.eclipse.openk.sp.dto.ReportGenerationConfigDto;
+import org.eclipse.openk.sp.dto.report.ReportDto;
+import org.eclipse.openk.sp.exceptions.SpErrorEntry;
+import org.eclipse.openk.sp.exceptions.SpException;
+import org.eclipse.openk.sp.exceptions.SpExceptionEnum;
+import org.eclipse.openk.sp.util.ArchiveHelper;
+import org.eclipse.openk.sp.util.MailHelper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@EnableScheduling
+@Transactional(rollbackFor = Exception.class)
+/** Class to handle automatic report generation and configuration. */
+public class CyclicReportsController extends AbstractController {
+
+	protected static final Logger LOGGER = Logger.getLogger(CyclicReportsController.class);
+
+	@Autowired
+	private CyclicReportGenerationConfigRepository automaticReportGenerationConfigRepository;
+
+	@Autowired
+	private MailHelper mailHelper;
+
+	@Autowired
+	private ArchiveHelper archiveHelper;
+
+	@Autowired
+	private EntityConverter entityConverter;
+
+	@Autowired
+	private ReportController reportController;
+
+	@Value("${report.cyclic.datePattern:yyyy-MM-dd}")
+	private String datePattern;
+
+	@Value("${report.cyclic.timePattern:HH-mm}")
+	private String timePattern;
+
+	@Value("${report.cyclic.weekPattern:'KW'ww}")
+	private String weekPattern;
+
+	@Value("${report.cyclic.archivePath:/opt/openk/reports/}")
+	private String archivePath;
+
+	@Value("${report.cyclic.slotDeltaMin:5}")
+	private int slotDeltaMin;
+
+	@Value("${report.cyclic.zoneName:Europe/Berlin}")
+	private String zoneName;
+
+	@Value("${report.cyclic.locale:de}")
+	private String locale;
+
+	@Value("${report.cyclic.sendReportMail:true}")
+	private boolean sendReportMail;
+
+	@Value("${report.cyclic.archiveReport:true}")
+	private boolean archiveReport;
+
+	private DateTimeFormatter datePatternFormatter;
+
+	private DateTimeFormatter timePatternFormatter;
+
+	private DateTimeFormatter weekPatternFormatter;
+
+	private ZoneId zoneId;
+	
+	private ZoneId zoneIdUTC;
+
+
+	@PostConstruct
+	private void init() {
+		Locale l = new Locale(locale);
+		datePatternFormatter = DateTimeFormatter.ofPattern(datePattern).withLocale(l);
+		timePatternFormatter = DateTimeFormatter.ofPattern(timePattern).withLocale(l);
+		weekPatternFormatter = DateTimeFormatter.ofPattern(weekPattern).withLocale(l);
+		zoneId = ZoneId.of(zoneName);
+		zoneIdUTC = ZoneId.of("UTC");
+
+	}
+
+	public List<ReportGenerationConfigDto> getAllReportGenerationConfig() throws SpException {
+		List<ReportGenerationConfigDto> configs = new ArrayList<>();
+		for (ReportGenerationConfig cfg : automaticReportGenerationConfigRepository.findAll()) {
+			configs.add((ReportGenerationConfigDto) entityConverter.convertEntityToDto(cfg,
+					new ReportGenerationConfigDto()));
+		}
+		return configs;
+	}
+
+	public Response deleteReportGenerationConfig(Long configId) throws SpException {
+		Optional<ReportGenerationConfig> oConfig = automaticReportGenerationConfigRepository.findById(configId);
+		if (oConfig.isPresent()) {
+			automaticReportGenerationConfigRepository.delete(configId);
+			return Response.noContent().build();
+		}
+		SpErrorEntry ee = SpExceptionEnum.HTTP_NOT_FOUND_EXCEPTION.getEntry();
+		String msgParam = "Not Found. Report generation config with id: " + configId;
+		SpException spE = new SpException(ee.getCode(), null, ee.getMessage(), msgParam);
+		LOGGER.error(spE, spE);
+		throw spE;
+	}
+
+	public ReportGenerationConfigDto editReportGenerationConfig(Long configId,
+			ReportGenerationConfigDto reportGenerationConfig) throws SpException {
+		Optional<ReportGenerationConfig> oConfig = automaticReportGenerationConfigRepository.findById(configId);
+		if (oConfig.isPresent()) {
+			ReportGenerationConfig cfg = (ReportGenerationConfig) entityConverter
+					.convertDtoToEntity(reportGenerationConfig, new ReportGenerationConfig());
+			cfg.setId(configId);
+			automaticReportGenerationConfigRepository.save(cfg);
+			reportGenerationConfig.setId(configId);
+			return reportGenerationConfig;
+		}
+		SpErrorEntry ee = SpExceptionEnum.HTTP_NOT_FOUND_EXCEPTION.getEntry();
+		String msgParam = "Not Found. Report generation config with id: " + configId;
+		SpException spE = new SpException(ee.getCode(), null, ee.getMessage(), msgParam);
+		LOGGER.error(spE, spE);
+		throw spE;
+	}
+
+	public ReportGenerationConfigDto addReportGenerationConfig(ReportGenerationConfigDto reportGenerationConfig)
+			throws SpException {
+		ReportGenerationConfig newCfg = (ReportGenerationConfig) entityConverter
+				.convertDtoToEntity(reportGenerationConfig, new ReportGenerationConfig());
+		newCfg.setId(null);
+		ReportGenerationConfig savedCfg = automaticReportGenerationConfigRepository.save(newCfg);
+		return (ReportGenerationConfigDto) entityConverter.convertEntityToDto(savedCfg,
+				new ReportGenerationConfigDto());
+	}
+
+	protected File generateReport(ReportGenerationConfig reportCfg, LocalDateTime triggerDate) throws SpException {
+		ReportDto reportDto = new ReportDto();
+		reportDto.setReportName(reportCfg.getReportName());
+		reportDto.setPrintFormat(reportCfg.getPrintFormat().toLowerCase());
+		reportDto.setStatusId(reportCfg.getStatusId());
+
+		// calculate from and to date
+		LocalDateTime fromLocalDateTime = triggerDate.plusDays(reportCfg.getValidFromDayOffset())
+				.withHour(reportCfg.getValidFromHour()).withMinute(reportCfg.getValidFromMinute());
+		LocalDateTime toLocalDateTime = triggerDate.plusDays(reportCfg.getValidToDayOffset())
+				.withHour(reportCfg.getValidToHour()).withMinute(reportCfg.getValidToMinute());
+		Date fromDate = Date.from(fromLocalDateTime.atZone(zoneIdUTC).toInstant());
+		Date toDate = Date.from(toLocalDateTime.atZone(zoneIdUTC).toInstant());
+
+		reportDto.setValidFromDate(fromDate);
+		reportDto.setValidToDate(toDate);
+		reportDto.setStandByListId(reportCfg.getStandByListId());
+		return reportController.generateReport(reportDto);
+	}
+
+
+	protected void generateAndDistributeReports(LocalDateTime triggerTimeGreaterEqual,
+			LocalDateTime triggerTimeLowerEqual) {
+		List<ReportGenerationConfig> currentConfigs = getReportGenerationConfigs(triggerTimeGreaterEqual,
+				triggerTimeLowerEqual);
+		for (ReportGenerationConfig cfg : currentConfigs) {
+			LOGGER.info("Matching report generationg config: " + cfg.getName());
+			try {
+				LocalDateTime triggerDateTime = triggerTimeGreaterEqual.withHour(cfg.getTriggerHour())
+						.withMinute(cfg.getTriggerMinute());
+				File reportFile = generateReport(cfg, triggerDateTime);
+				String fileName = fileNameOfCfg(triggerDateTime, cfg);
+				storeReport(reportFile, fileName);
+				sendReport(reportFile, fileName, cfg, triggerDateTime);
+			} catch (Exception e) {
+				LOGGER.warn("Could not autogenerate and send report configuration with name: " + cfg.getName(), e);
+			}
+		}
+	}
+
+	protected void sendReport(File reportFile, String fileName, ReportGenerationConfig cfg, LocalDateTime triggerDateTime) {
+		if (!sendReportMail || cfg.getTo() == null || cfg.getTo().isEmpty()) {
+			return;
+		}
+		try {
+			MimeMessage mail = mailHelper.newMultipartMail();
+			String subject = placeholderReplacement(triggerDateTime, cfg.getSubject());
+			MailHelper.setSubject(mail, subject);
+			MailHelper.setToRecipients(mail, cfg.getTo());
+			String text = placeholderReplacement(triggerDateTime, cfg.getEmailText());
+			MailHelper.addText(mail, text);
+			MailHelper.addAttachment(mail, reportFile, fileName);
+			mailHelper.send(mail);
+		} catch (IOException | MessagingException e) {
+			LOGGER.warn("Could not send report mail with name: " + cfg.getName() + " - " + e.getMessage(), e);
+		}
+	}
+
+	private void storeReport(File reportFile, String fileName) {
+		if (!archiveReport) {
+			return;
+		}
+		String absPath = archivePath + File.separator + fileName;
+		try {
+			archiveHelper.copyFile(reportFile.getAbsolutePath(), absPath);
+		} catch (IOException e) {
+			LOGGER.warn("Could not store report file with name: " + fileName + " - " + e.getMessage(), e);
+		}
+	}
+
+	protected String fileNameOfCfg(LocalDateTime triggerDateTime, ReportGenerationConfig cfg) {
+		String fileName = cfg.getFileNamePattern() + "." + cfg.getPrintFormat().toLowerCase();
+		fileName = placeholderReplacement(triggerDateTime, fileName);
+		return fileName;
+	}
+
+	private String placeholderReplacement(LocalDateTime triggerDateTime, String orig) {
+		String triggerDateString = datePatternFormatter.format(triggerDateTime);
+		String triggerTimeString = timePatternFormatter.format(triggerDateTime);
+		String triggerWeekString = weekPatternFormatter.format(triggerDateTime);
+		String newString = orig.replace("{Date}", triggerDateString);
+		newString = newString.replace("{Time}", triggerTimeString);
+		newString = newString.replace("{Week}", triggerWeekString);
+		return newString;
+	}
+	
+
+	protected List<ReportGenerationConfig> getReportGenerationConfigs(LocalDateTime triggerTimeGreaterEqual,
+			LocalDateTime triggerTimeLower) {
+		int weekDay = triggerTimeGreaterEqual.getDayOfWeek().getValue();
+		int hour = triggerTimeGreaterEqual.getHour();
+		int minuteGE = triggerTimeGreaterEqual.getMinute();
+		int minuteLE = triggerTimeLower.getMinute();
+		LOGGER.info("Search for report generation configs: " + weekDay + ", " + hour + ", " + minuteGE + ", " + minuteLE);
+		return automaticReportGenerationConfigRepository.findConfigs(weekDay, hour, minuteGE, minuteLE);
+	}
+
+	/**
+	 * Checks cyclic report generation configuration for matching trigger time.
+	 */
+	@Scheduled(cron = "${report.cyclic.checkCron:0 0/5 * * * ?}")
+	public void checkCyclicGenerationSlot() {
+		LOGGER.info("Check for automatic report generation");
+		LocalDateTime now = LocalDateTime.now(zoneId);
+		int slotNumber = now.getMinute() / slotDeltaMin;
+		LocalDateTime triggerTimeGreaterEqual = now.withMinute(slotNumber * slotDeltaMin);
+		LocalDateTime triggerTimeLowerEqual = triggerTimeGreaterEqual.plusMinutes(slotDeltaMin - 1L);
+		LOGGER.info("Check for automatic report generation - " + triggerTimeGreaterEqual);
+		generateAndDistributeReports(triggerTimeGreaterEqual, triggerTimeLowerEqual);
+		
+		
+		
+	}
+
+}
diff --git a/oKBereitschaftsplanungBackend/src/main/java/org/eclipse/openk/sp/dto/ReportGenerationConfigDto.java b/oKBereitschaftsplanungBackend/src/main/java/org/eclipse/openk/sp/dto/ReportGenerationConfigDto.java
new file mode 100644
index 0000000..77aedca
--- /dev/null
+++ b/oKBereitschaftsplanungBackend/src/main/java/org/eclipse/openk/sp/dto/ReportGenerationConfigDto.java
@@ -0,0 +1,268 @@
+/* *******************************************************************************
+ * Copyright (c) 2020 Basys GmbH
+ * 
+ * See the NOTICE file(s) distributed with this work for additional 
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * *******************************************************************************/
+package org.eclipse.openk.sp.dto;
+
+import java.util.Set;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.eclipse.openk.sp.abstracts.AbstractDto;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+
+/**
+ * The "ReportGenerationConfig" Data Transfer Object (DTO)
+ */
+@XmlRootElement(name = "ReportGenerationConfigDto")
+@JsonInclude(Include.NON_NULL)
+public class ReportGenerationConfigDto extends AbstractDto {
+
+	/**
+	 * default serial id.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	private Long id;
+
+	@NotNull(message = "Name is not set")
+	@Size(max = 256, message = "Name with max. 256 characters")
+	private String name;
+
+	@NotNull(message = "FileNamePattern is not set")
+	@Size(max = 128, message = "FileNamePattern with max. 128 characters")
+	private String fileNamePattern;
+
+	@NotNull(message = "Subject is not set")
+	@Size(max = 128, message = "Subject with max. 128 characters")
+	private String subject;
+
+	@NotNull(message = "To is not set")
+	private Set<String> to;
+
+	@NotNull(message = "PrintFormat is not set")
+	private String printFormat;
+
+	@NotNull(message = "ReportName is not set")
+	@Size(max = 256, message = "ReportName with max. 256 characters")
+	private String reportName;
+
+	@NotNull(message = "StandByListId is not set")
+	private Long standByListId;
+
+	@NotNull(message = "StatusId is not set")
+	@Min(0)
+	private Long statusId;
+
+	@Min(1)
+	@Max(7)
+	@NotNull(message = "TriggerWeekDay is not set")
+	private Integer triggerWeekDay;
+
+	@Min(0)
+	@Max(23)
+	@NotNull(message = "TriggerHour is not set")
+	private Integer triggerHour;
+
+	@Min(0)
+	@Max(59)
+	@NotNull(message = "TriggerMinute is not set")
+	private Integer triggerMinute;
+
+	@NotNull(message = "ValidFromDayOffset is not set")
+	private Integer validFromDayOffset;
+
+	@Min(0)
+	@Max(23)
+	@NotNull(message = "ValidFromHour is not set")
+	private Integer validFromHour;
+
+	@Min(0)
+	@Max(59)
+	@NotNull(message = "ValidFromMinute is not set")
+	private Integer validFromMinute;
+
+	@NotNull(message = "ValidToDayOffset is not set")
+	private Integer validToDayOffset;
+
+	@Min(0)
+	@Max(23)
+	@NotNull(message = "ValidToHour not set")
+	private Integer validToHour;
+
+	@Min(0)
+	@Max(59)
+	@NotNull(message = "ValidToMinute is not set")
+	private Integer validToMinute;
+	
+
+	@NotNull(message = "EmailText is not set")
+	private String emailText;
+
+	public void setId(final Long id) {
+		this.id = id;
+	}
+
+	public Long getId() {
+		return this.id;
+	}
+
+	public void setName(final String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public String getFileNamePattern() {
+		return fileNamePattern;
+	}
+
+	public void setFileNamePattern(String fileNamePattern) {
+		this.fileNamePattern = fileNamePattern;
+	}
+
+	public String getSubject() {
+		return subject;
+	}
+
+	public void setSubject(String subject) {
+		this.subject = subject;
+	}
+
+	public Set<String> getTo() {
+		return to;
+	}
+
+	public void setTo(Set<String> to) {
+		this.to = to;
+	}
+
+	public String getPrintFormat() {
+		return printFormat;
+	}
+
+	public void setPrintFormat(String printFormat) {
+		this.printFormat = printFormat;
+	}
+
+	public String getReportName() {
+		return reportName;
+	}
+
+	public void setReportName(String reportName) {
+		this.reportName = reportName;
+	}
+
+	public Long getStandByListId() {
+		return standByListId;
+	}
+
+	public void setStandByListId(Long standByListId) {
+		this.standByListId = standByListId;
+	}
+
+	public Long getStatusId() {
+		return statusId;
+	}
+
+	public void setStatusId(Long statusId) {
+		this.statusId = statusId;
+	}
+
+	public Integer getTriggerWeekDay() {
+		return triggerWeekDay;
+	}
+
+	public void setTriggerWeekDay(Integer triggerWeekDay) {
+		this.triggerWeekDay = triggerWeekDay;
+	}
+
+	public Integer getTriggerHour() {
+		return triggerHour;
+	}
+
+	public void setTriggerHour(Integer triggerHour) {
+		this.triggerHour = triggerHour;
+	}
+
+	public Integer getTriggerMinute() {
+		return triggerMinute;
+	}
+
+	public void setTriggerMinute(Integer triggerMinute) {
+		this.triggerMinute = triggerMinute;
+	}
+
+	public Integer getValidFromDayOffset() {
+		return validFromDayOffset;
+	}
+
+	public void setValidFromDayOffset(Integer validFromDayOffset) {
+		this.validFromDayOffset = validFromDayOffset;
+	}
+
+	public Integer getValidFromHour() {
+		return validFromHour;
+	}
+
+	public void setValidFromHour(Integer validFromHour) {
+		this.validFromHour = validFromHour;
+	}
+
+	public Integer getValidFromMinute() {
+		return validFromMinute;
+	}
+
+	public void setValidFromMinute(Integer validFromMinute) {
+		this.validFromMinute = validFromMinute;
+	}
+
+	public Integer getValidToDayOffset() {
+		return validToDayOffset;
+	}
+
+	public void setValidToDayOffset(Integer validToDayOffset) {
+		this.validToDayOffset = validToDayOffset;
+	}
+
+	public Integer getValidToHour() {
+		return validToHour;
+	}
+
+	public void setValidToHour(Integer validToHour) {
+		this.validToHour = validToHour;
+	}
+
+	public Integer getValidToMinute() {
+		return validToMinute;
+	}
+
+	public void setValidToMinute(Integer validToMinute) {
+		this.validToMinute = validToMinute;
+	}
+	
+	public String getEmailText() {
+		return emailText;
+	}
+	
+	public void setEmailText(String emailText) {
+		this.emailText = emailText;
+	}
+
+}
diff --git a/oKBereitschaftsplanungBackend/src/main/resources/dozer-mapping.xml b/oKBereitschaftsplanungBackend/src/main/resources/dozer-mapping.xml
index 8b924d3..0829b15 100644
--- a/oKBereitschaftsplanungBackend/src/main/resources/dozer-mapping.xml
+++ b/oKBereitschaftsplanungBackend/src/main/resources/dozer-mapping.xml
@@ -412,5 +412,10 @@
 			<b>locationId</b>
 		</field>
 	</mapping>
+	
+	<mapping>
+		<class-a>org.eclipse.openk.sp.db.model.ReportGenerationConfig</class-a>
+		<class-b>org.eclipse.openk.sp.dto.ReportGenerationConfigDto</class-b>
+	</mapping>
 
 </mappings>  
\ No newline at end of file
diff --git a/oKBereitschaftsplanungBackend/src/test/java/org/eclipse/openk/sp/dto/ReportGenerationConfigDtoTest.java b/oKBereitschaftsplanungBackend/src/test/java/org/eclipse/openk/sp/dto/ReportGenerationConfigDtoTest.java
new file mode 100644
index 0000000..ebfdd8b
--- /dev/null
+++ b/oKBereitschaftsplanungBackend/src/test/java/org/eclipse/openk/sp/dto/ReportGenerationConfigDtoTest.java
@@ -0,0 +1,88 @@
+package org.eclipse.openk.sp.dto;
+
+import static org.junit.Assert.*;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Test;
+
+public class ReportGenerationConfigDtoTest {
+
+	@Test
+	public void testGetterAndSetter() {
+
+		ReportGenerationConfigDto config = new ReportGenerationConfigDto();
+		
+		Integer triggerHour = 1;
+		Integer triggerMinute = 1;
+		Integer triggerWeekDay = 1;
+		Integer validFromDayOffset = -1;
+		Integer validFromHour = 2;
+		Integer validFromMinute = 30;
+		Integer validToDayOffset = 1;
+		Integer validToHour = 3;
+		Integer validToMinute = 35;
+		Long standByListId = 23L;
+		Long statusId = 4L;
+		String fileNamePattern = "pattern";
+		String name = "name";
+		String printFormat = "pdf";
+		String reportName = "REPORT_NAME";
+		String subject = "subject";
+		Set<String> to  = new HashSet<>();
+		
+		
+		config.setFileNamePattern(fileNamePattern);
+		assertEquals(fileNamePattern, config.getFileNamePattern());
+		
+		config.setName(name);
+		assertEquals(name, config.getName());
+		
+		config.setPrintFormat(printFormat);
+		assertEquals(printFormat, config.getPrintFormat());
+		
+		config.setReportName(reportName);
+		assertEquals(reportName, config.getReportName());
+		
+		config.setStandByListId(standByListId);
+		assertEquals(standByListId, config.getStandByListId());
+
+		config.setStatusId(statusId);
+		assertEquals(statusId, config.getStatusId());
+		
+		config.setSubject(subject);
+		assertEquals(subject, config.getSubject());
+		
+		config.setTo(to);
+		assertEquals(to, config.getTo());
+
+		config.setTriggerHour(triggerHour);
+		assertEquals(triggerHour, config.getTriggerHour());
+		
+		config.setTriggerMinute(triggerMinute);
+		assertEquals(triggerMinute, config.getTriggerMinute());
+
+		config.setTriggerWeekDay(triggerWeekDay);
+		assertEquals(triggerWeekDay, config.getTriggerWeekDay());
+
+		config.setValidFromDayOffset(validFromDayOffset);
+		assertEquals(validFromDayOffset, config.getValidFromDayOffset());
+		
+		config.setValidFromHour(validFromHour);
+		assertEquals(validFromHour, config.getValidFromHour());
+		
+		config.setValidFromMinute(validFromMinute);
+		assertEquals(validFromMinute, config.getValidFromMinute());
+		
+		config.setValidToDayOffset(validToDayOffset);
+		assertEquals(validToDayOffset, config.getValidToDayOffset());
+		
+		config.setValidToHour(validToHour);
+		assertEquals(validToHour, config.getValidToHour());
+		
+		config.setValidToMinute(validToMinute);
+		assertEquals(validToMinute, config.getValidToMinute());
+	}
+
+}