Campaign Forms
CampaignForms
This block of classes handles the display and processing of the form used to create/edit a Campaign entity via the UI.
It follows the standard architecture used in timveroOS: Form → FormService → Entity, with full versioning support through HistoryEntityFormService.
✅ CampaignForm
CampaignForm is a DTO class representing the fields of the campaign creation/edit form.
Validation annotations provide basic input checks.
Example fields:
public class CampaignForm {
@NotEmpty
private String name;
@NotNull
private CampaignExecutionType executionType;
private boolean restartable;
private Integer restartableUnit;
private RestartableUnitType restartableUnitType;
@Valid
private ExpressionForm expression;
@NotEmpty
private Set<@NotNull String> creditProductCodes;
private LocalDateTime dateTimeExecution;
// getters and setters
}🔁 CampaignFormMapper
The CampaignFormMapper interface is used to convert between Campaign and CampaignForm using the MapStruct library.
It extends EntityToFormMapper<Campaign, CampaignForm>.
Example:
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, uses = ReferenceMapper.class)
public interface CampaignFormMapper extends EntityToFormMapper<Campaign, CampaignForm> {
}MapStruct automatically generates the conversion based on matching fields.
Additional logic can be added using @AfterMapping if needed.
⚙️ CampaignFormService — Extends HistoryEntityFormService
HistoryEntityFormServiceCampaignFormService implements the core business logic for editing campaigns via the UI.
It extends HistoryEntityFormService<Campaign, CampaignForm, Long>, which means:
Versioning is handled automatically — saving a campaign creates a new version
Previous versions are marked as inactive
The version lineage is tracked via
lineageId
Example:
@Service
public class CampaignFormService extends
HistoryEntityFormService<Campaign, CampaignForm, Long> {
@Autowired
private CreditProductRepository productRepository;
@Autowired
private ScriptManager scriptManager;
@Override
protected void assembleEditModel(Long aLong, CampaignForm form, Map<String, Object> model) {
model.put("campaign", form);
model.put("executionTypes", CampaignExecutionType.values());
model.put("creditProductCodes", productRepository.getCreditProductCodes());
model.put("restartableUnitTypes", RestartableUnitType.values());
model.put("engineNames", scriptManager.getEngineNames());
}
@Override
protected void assembleViewModel(Long id, Campaign entity, Map<String, Object> model) {
// Implementation as needed
}
@Override
public List<Campaign> findAllVersions(UUID versionId) {
return super.findAllVersions(versionId);
}
}Key Method:
@Override
protected void assembleEditModel(Long aLong, CampaignForm form, Map<String, Object> model) {
model.put("campaign", form);
model.put("executionTypes", CampaignExecutionType.values());
model.put("creditProductCodes", productRepository.getCreditProductCodes());
model.put("restartableUnitTypes", RestartableUnitType.values());
model.put("engineNames", scriptManager.getEngineNames());
}Version History Support:
@Override
public List<Campaign> findAllVersions(UUID versionId) {
return super.findAllVersions(versionId);
}Dependencies Used:
CreditProductRepository— for retrieving available credit productsScriptManager— for showing available scripting engines
🧩 HTML Templates Related to Campaign
✅ /campaign/list.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<th:block>
<table class="table">
<thead>
<tr role="row">
<th data-sortField="id" th:text="#{symbol.id}"></th>
<th data-sortField="name" th:text="#{campaign.name}"></th>
<th th:text="#{campaign.active}"></th>
<th th:text="#{campaign.executionType}"></th>
<th th:text="#{campaign.lastStartDate}"></th>
</tr>
</thead>
<tbody th:attr="data-page=${page.page},data-total=${page.total}">
<th:block
th:each="entity : ${page.rows}"
th:object="${entity}">
<tr role="row"
class="clickable"
th:href="@{'/campaign/'+ ${entity.id}}">
<td th:text="*{id}"></td>
<td th:text="*{name}"></td>
<td th:text="*{active} ? #{common.yes} : #{common.no} "></td>
<td th:text="*{#enums.name(executionType)}"></td>
<td th:text="${latestExecution} ? ${#ldates.format(latestExecution.createdAt)} : #{campaign.noneStartDate}"></td>
</tr>
</th:block>
</tbody>
</table>
</th:block>
</html>Purpose: Displays a table with the list of all campaigns. It serves as the main campaign overview page.
Key Features:
Sortable by
id,name, andexecutionTypeDisplays active/inactive status
Shows the last execution date (if available)
Last updated
Was this helpful?