class DemandResponseEventService {

	@Transactional(readOnly = false)
	public DemandResponseEvent create(DemandResponseEventCreateDto dto) {
		DemandResponseEvent event = dtoMapper.map(dto, DemandResponseEvent.class);
		event.setCreatedTimestamp(System.currentTimeMillis());
		event.setLastUpdateTimestamp(System.currentTimeMillis());
		if (dto.isPublished()) {
			event.getDescriptor().setModificationNumber(0);
		} else {
			event.getDescriptor().setModificationNumber(-1);
		}

		Date dateStart = new Date();
		dateStart.setTime(event.getActivePeriod().getStart());

		// compute end from start and duration
		Duration duration = datatypeFactory.newDuration(event.getActivePeriod().getDuration());
		long durationInMillis = duration.getTimeInMillis(dateStart);
		event.getActivePeriod().setEnd(dateStart.getTime() + durationInMillis);

		// compute startNotification from start and notificationDuration
		Duration notificationDuration = datatypeFactory.newDuration(event.getActivePeriod().getNotificationDuration());
		long notificationDurationInMillis = notificationDuration.getTimeInMillis(dateStart);
		event.getActivePeriod().setStartNotification(dateStart.getTime() - notificationDurationInMillis);

		// save event
		DemandResponseEvent save = demandResponseEventDao.save(event);

		// link targets
		List<Ven> findByUsernameIn = findVenForTarget(event, dto.getTargets());

		List<VenDemandResponseEvent> list = new ArrayList<>();
		for (Ven ven : findByUsernameIn) {
			list.add(new VenDemandResponseEvent(event, ven));
		}
		venDemandResponseEventDao.saveAll(list);

		// link signals
		event.getSignals().forEach(sig -> {
			sig.setEvent(save);
		});
		demandResponseEventSignalDao.saveAll(event.getSignals());

		for (Ven ven : findByUsernameIn) {
			if (demandResponseEventPublisher != null && event.isPublished()) {
				pushAsync(ven, event.getDescriptor().getOadrProfile());
			}
		}

		return save;
	}

}