Skip to content

Commit 9e4cc64

Browse files
committed
feat: added datamode to csv, fixed versioning for csv templates
1 parent 71758dc commit 9e4cc64

File tree

13 files changed

+70
-95
lines changed

13 files changed

+70
-95
lines changed
Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
Name,ReportType,Field Name,Parent,Mapped Types,Accumulated,Accumulated Yearly,Accumulated Previous Year,Negated
2-
Income Statement Example,INCOME_STATEMENT,Revenues,,,false,true,false,true
3-
Income Statement Example,INCOME_STATEMENT,Other Income,Revenues,,false,true,false,true
4-
Income Statement Example,INCOME_STATEMENT,Building of long term provisions,Revenues,Revenues_Build of long term provision,false,true,false,true
5-
Income Statement Example,INCOME_STATEMENT,Cost of goods and services,,,false,true,false,true
6-
Income Statement Example,INCOME_STATEMENT,External Services,Cost of goods and services,COGS_External services,false,true,false,true
7-
Income Statement Example,INCOME_STATEMENT,Operating Expenses,,,false,true,false,true
8-
Income Statement Example,INCOME_STATEMENT,Personnel Expenses,Operating Expenses,Expenses_Personnel expenses,false,true,false,true
9-
Income Statement Example,INCOME_STATEMENT,General administrative expenses,Operating Expenses,Expenses_General and Administrative expenses,false,true,false,true
10-
Income Statement Example,INCOME_STATEMENT,Depreciation and impairment losses on tangible Assets,Operating Expenses,Expenses_Depreciation and impairment losses on movable tangible assets,false,true,false,true
11-
Income Statement Example,INCOME_STATEMENT,Amortization on intangible assets,Operating Expenses,Expenses_Amortization on intangible assets,false,true,false,true
12-
Income Statement Example,INCOME_STATEMENT,Rent Expenses,Operating Expenses,Expenses_Rent expenses,false,true,false,true
13-
Income Statement Example,INCOME_STATEMENT,Financial Income,,,false,true,false,true
14-
Income Statement Example,INCOME_STATEMENT,Financial Revenues,Financial Income,Expenses_Financial income,false,true,false,true
15-
Income Statement Example,INCOME_STATEMENT,Financial Expenses,Financial Income,Expenses_Financial expenses,false,true,false,true
16-
Income Statement Example,INCOME_STATEMENT,Realised Gains on Sale of Cryptocurrencies,Financial Income,Expenses_Realised gains on sale of crypto currencies,false,true,false,true
17-
Income Statement Example,INCOME_STATEMENT,Staking Rewards income,Financial Income,Expenses_Staking rewards income,false,true,false,true
18-
Income Statement Example,INCOME_STATEMENT,Net Income options sale,Financial Income,Expenses_Net income option sales,false,true,false,true
19-
Income Statement Example,INCOME_STATEMENT,Extraordinary income,,,false,true,false,true
20-
Income Statement Example,INCOME_STATEMENT,Extraordinary Expenses,Extraordinary income,"Expenses_Extraordinary, non-recurring or prior period expenses",false,true,false,true
21-
Income Statement Example,INCOME_STATEMENT,Tax Expense,,,false,true,false,true
22-
Income Statement Example,INCOME_STATEMENT,Direct Taxes,Tax Expense,Expenses_Direct taxes,false,true,false,true
23-
Income Statement Example,INCOME_STATEMENT,Profit for the year,,Expenses_Net income option sales,false,true,false,true
1+
Name,ReportType,DataMode,Field Name,Parent,Mapped Types,Accumulated,Accumulated Yearly,Accumulated Previous Year,Negated
2+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Revenues,,,false,true,false,true
3+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Other Income,Revenues,,false,true,false,true
4+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Building of long term provisions,Revenues,Revenues_Build of long term provision,false,true,false,true
5+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Cost of goods and services,,,false,true,false,true
6+
Income Statement Example,INCOME_STATEMENT,SYSTEM,External Services,Cost of goods and services,COGS_External services,false,true,false,true
7+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Operating Expenses,,,false,true,false,true
8+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Personnel Expenses,Operating Expenses,Expenses_Personnel expenses,false,true,false,true
9+
Income Statement Example,INCOME_STATEMENT,SYSTEM,General administrative expenses,Operating Expenses,Expenses_General and Administrative expenses,false,true,false,true
10+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Depreciation and impairment losses on tangible Assets,Operating Expenses,Expenses_Depreciation and impairment losses on movable tangible assets,false,true,false,true
11+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Amortization on intangible assets,Operating Expenses,Expenses_Amortization on intangible assets,false,true,false,true
12+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Rent Expenses,Operating Expenses,Expenses_Rent expenses,false,true,false,true
13+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Financial Income,,,false,true,false,true
14+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Financial Revenues,Financial Income,Expenses_Financial income,false,true,false,true
15+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Financial Expenses,Financial Income,Expenses_Financial expenses,false,true,false,true
16+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Realised Gains on Sale of Cryptocurrencies,Financial Income,Expenses_Realised gains on sale of crypto currencies,false,true,false,true
17+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Staking Rewards income,Financial Income,Expenses_Staking rewards income,false,true,false,true
18+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Net Income options sale,Financial Income,Expenses_Net income option sales,false,true,false,true
19+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Extraordinary income,,,false,true,false,true
20+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Extraordinary Expenses,Extraordinary income,"Expenses_Extraordinary, non-recurring or prior period expenses",false,true,false,true
21+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Tax Expense,,,false,true,false,true
22+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Direct Taxes,Tax Expense,Expenses_Direct taxes,false,true,false,true
23+
Income Statement Example,INCOME_STATEMENT,SYSTEM,Profit for the year,,Expenses_Net income option sales,false,true,false,true
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
Template name,Name,Interval type,Period,Year,Data mode,Field name,Amount
2-
Income Statement Example,TestReport,QUARTER,1,2025,SYSTEM,,
2+
Income Statement Example,TestReport,QUARTER,1,2025,USER,Revenue,10
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Name,ReportType,Field Name,Parent,Mapped Types,Accumulated,Accumulated Yearly,Accumulated Previous Year,Negated
2-
Income Statement Example,INCOME_STATEMENT,Revenue,,,true,false,false,false
1+
Name,ReportType,DataMode,Field Name,Parent,Mapped Types,Accumulated,Accumulated Yearly,Accumulated Previous Year,Negated
2+
Income Statement Example,INCOME_STATEMENT,USER,Revenue,,,true,false,false,false

reporting/src/main/java/org/cardanofoundation/lob/app/reporting/dto/ReportTemplateFieldDto.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
@Schema(description = "Report template field definition")
2121
public class ReportTemplateFieldDto {
2222

23-
@Schema(description = "Field ID", example = "101", nullable = true)
24-
private Long id;
25-
2623
@Schema(description = "Field name", example = "Total Revenue")
2724
@NotNull(message = "Field name must not be null")
2825
private String fieldName;

reporting/src/main/java/org/cardanofoundation/lob/app/reporting/dto/TemplateCsvLine.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ public class TemplateCsvLine {
2121
@CsvBindByName(column = "ReportType")
2222
@NotNull(message = "ReportType is required")
2323
private String reportType;
24+
@CsvBindByName(column = "DataMode")
25+
@NotNull(message = "DataMode is required. Options are: SYSTEM or USER")
26+
private String dataMode;
2427
@CsvBindByName(column = "Field Name")
2528
@NotNull(message = "Field Name is required")
2629
private String fieldName;

reporting/src/main/java/org/cardanofoundation/lob/app/reporting/dto/ValidationRuleDto.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818
@Schema(description = "Validation rule for report template fields")
1919
public class ValidationRuleDto {
2020

21-
@Schema(description = "Rule ID", example = "123", nullable = true)
22-
private Long id;
23-
2421
@Schema(description = "Rule name", example = "Assets Balance Check")
2522
@NotNull(message = "Rule name must not be null")
2623
private String name;

reporting/src/main/java/org/cardanofoundation/lob/app/reporting/mapper/ReportTemplateMapper.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ private ReportTemplateFieldDto toColumnDto(ReportTemplateFieldEntity entity) {
162162
: Collections.emptyList();
163163

164164
return ReportTemplateFieldDto.builder()
165-
.id(entity.getId())
166165
.fieldName(entity.getName())
167166
.accumulated(entity.isAccumulated())
168167
.accumulatedYearly(entity.isAccumulatedYearly())
@@ -277,7 +276,6 @@ private ValidationRuleDto toValidationRuleDto(ReportTemplateValidationRuleEntity
277276
: Collections.emptyList();
278277

279278
return ValidationRuleDto.builder()
280-
.id(entity.getId())
281279
.name(entity.getName())
282280
.operator(entity.getOperator().name())
283281
.active(entity.isActive())

reporting/src/main/java/org/cardanofoundation/lob/app/reporting/service/CsvReportService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public Either<Problem, List<ReportResponseDto>> createCsvReports(@Valid CreateCs
8080
)
8181
.toList();
8282
reportLines.removeAll(sameReportLines);
83-
Optional<ReportTemplateEntity> templateEntityO = reportTemplateRepository.findByOrganisationIdAndName(csvTemplateRequest.getOrganisationId(), line.getTemplateName());
83+
Optional<ReportTemplateEntity> templateEntityO = reportTemplateRepository.findLatestByOrganisationIdAndName(csvTemplateRequest.getOrganisationId(), line.getTemplateName());
8484
if(templateEntityO.isEmpty()) {
8585
createdReports.add(ReportResponseDto.builder()
8686
.error(Optional.of(Problem.builder()

reporting/src/main/java/org/cardanofoundation/lob/app/reporting/service/CsvReportTemplateService.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,12 @@
3636
import org.cardanofoundation.lob.app.reporting.dto.ReportTemplateResponseDto;
3737
import org.cardanofoundation.lob.app.reporting.dto.TemplateCsvLine;
3838
import org.cardanofoundation.lob.app.reporting.mapper.ReportTemplateMapper;
39+
import org.cardanofoundation.lob.app.reporting.model.entity.ReportEntity;
3940
import org.cardanofoundation.lob.app.reporting.model.entity.ReportTemplateEntity;
41+
import org.cardanofoundation.lob.app.reporting.model.enums.DataMode;
4042
import org.cardanofoundation.lob.app.reporting.model.enums.ReportTemplateType;
4143
import org.cardanofoundation.lob.app.reporting.repository.ReportTemplateRepository;
44+
import org.cardanofoundation.lob.app.reporting.repository.ReportingRepository;
4245

4346
@Service
4447
@RequiredArgsConstructor
@@ -49,6 +52,7 @@ public class CsvReportTemplateService {
4952
private final OrganisationPublicApiIF organisationPublicApiIF;
5053
private final CsvParser<TemplateCsvLine> csvParser;
5154
private final ReportTemplateRepository reportTemplateRepository;
55+
private final ReportingRepository reportingRepository;
5256
private final ReportTemplateMapper reportTemplateMapper;
5357
private final ChartOfAccountTypeRepository chartOfAccountTypeRepository;
5458
private final Validator validator;
@@ -93,14 +97,23 @@ public Either<Problem, List<ReportTemplateResponseDto>> createCsvTemplates(@Vali
9397
results.add(Either.left(problem));
9498
continue;
9599
}
100+
try {
101+
DataMode.valueOf(firstLine.getDataMode());
102+
} catch (IllegalArgumentException e) {
103+
Problem problem = Problem.builder()
104+
.withTitle(Constants.CSV_PARSING_ERROR)
105+
.withDetail("Invalid data mode: " + firstLine.getDataMode() + ". Options are: SYSTEM, USER")
106+
.withStatus(Status.BAD_REQUEST)
107+
.build();
108+
results.add(Either.left(problem));
109+
continue;
110+
}
96111
ReportTemplateDto reportTemplateDto = new ReportTemplateDto();
97112
reportTemplateDto.setOrganisationId(csvTemplateRequest.getOrganisationId());
98113
reportTemplateDto.setName(firstLine.getName());
99114
reportTemplateDto.setReportTemplateType(reportTemplateType.name());
115+
reportTemplateDto.setDataMode(firstLine.getDataMode());
100116
reportTemplateDto.setVer(1L);
101-
reportTemplateRepository.findByOrgnisationIdAndNameAndReportTemplateTypeLatestVersion(reportTemplateDto.getOrganisationId(),
102-
reportTemplateDto.getName(), reportTemplateType)
103-
.ifPresent(existingTemplate -> reportTemplateDto.setVer(existingTemplate.getVer() + 1));
104117
List<ReportTemplateFieldDto> fieldDtos = new ArrayList<>();
105118
for (TemplateCsvLine templateCsvLine : filteredLines) {
106119
Either<Problem, ReportTemplateFieldDto> fieldEntityResult = csvLineToTemplateField(csvTemplateRequest.getOrganisationId(), templateCsvLine);
@@ -147,11 +160,20 @@ public Either<Problem, List<ReportTemplateResponseDto>> createCsvTemplates(@Vali
147160
return Either.right(results.stream().map(e -> e.fold(
148161
left -> ReportTemplateResponseDto.builder().error(Optional.of(left)).build(),
149162
dto -> {
150-
ReportTemplateEntity existingTemplate = reportTemplateRepository
151-
.findByOrgnisationIdAndNameAndReportTemplateTypeLatestVersion(dto.getOrganisationId(), dto.getName(), ReportTemplateType.valueOf(dto.getReportTemplateType()))
152-
.orElse(null);
153-
ReportTemplateEntity entity = reportTemplateMapper.toEntity(dto, existingTemplate);
154-
entity = reportTemplateRepository.save(entity);
163+
Optional<ReportTemplateEntity> existingTemplateO = reportTemplateRepository
164+
.findByOrgnisationIdAndNameAndReportTemplateTypeLatestVersion(dto.getOrganisationId(), dto.getName(), ReportTemplateType.valueOf(dto.getReportTemplateType()));
165+
ReportTemplateEntity entity = existingTemplateO.map(existingTemplate -> {
166+
List<ReportEntity> byReportTemplateId = reportingRepository.findByReportTemplateId(existingTemplate.getId());
167+
ReportTemplateEntity newEntity;
168+
if(byReportTemplateId.isEmpty()) {
169+
newEntity = reportTemplateMapper.toEntity(dto, existingTemplate);
170+
} else {
171+
newEntity = reportTemplateMapper.toEntity(dto, ReportTemplateEntity.builder().ver(existingTemplate.getVer() + 1).build());
172+
}
173+
return newEntity;
174+
})
175+
.orElseGet(() -> reportTemplateMapper.toEntity(dto, null));
176+
entity = reportTemplateRepository.saveAndFlush(entity);
155177
return reportTemplateMapper.toResponseDto(entity);
156178
}
157179
)).toList());

reporting/src/main/java/org/cardanofoundation/lob/app/reporting/service/ReportTemplateService.java

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -317,43 +317,6 @@ private Either<Problem, Void> validateNoDuplicateFields(List<ReportTemplateField
317317
if (duplicateFieldsNamesRecursive.isLeft()) {
318318
return duplicateFieldsNamesRecursive;
319319
}
320-
HashSet<Long> existingIds = new HashSet<>();
321-
Either<Problem, Void> duplicateIdsRecursive = validateNoDuplicateFieldIdsRecursive(fields, existingIds);
322-
if (duplicateIdsRecursive.isLeft()) {
323-
return duplicateIdsRecursive;
324-
}
325-
return Either.right(null);
326-
}
327-
328-
private Either<Problem, Void> validateNoDuplicateFieldIdsRecursive(List<ReportTemplateFieldDto> fields, Set<Long> existingIds) {
329-
if (fields == null || fields.isEmpty()) {
330-
return Either.right(null);
331-
}
332-
333-
for (ReportTemplateFieldDto field : fields) {
334-
if (field.getId() != null) {
335-
if (existingIds.contains(field.getId())) {
336-
return Either.left(Problem.builder()
337-
.withTitle("DUPLICATE_FIELD_ID")
338-
.withDetail("Duplicate field ID '" + field.getId() + "'. Field IDs must be unique within the template.")
339-
.withStatus(Status.BAD_REQUEST)
340-
.build());
341-
}
342-
existingIds.add(field.getId());
343-
}
344-
345-
// Recursively validate child fields
346-
if (field.getChildFields() != null && !field.getChildFields().isEmpty()) {
347-
Either<Problem, Void> childValidation = validateNoDuplicateFieldIdsRecursive(
348-
field.getChildFields(),
349-
existingIds
350-
);
351-
if (childValidation.isLeft()) {
352-
return childValidation;
353-
}
354-
}
355-
}
356-
357320
return Either.right(null);
358321
}
359322

0 commit comments

Comments
 (0)