Passed
Push — master ( d0b20c...e90402 )
by Valentyn
07:56
created

AdminProgramService(ProgramRepository,ParseExerciseRepository,ParseGoalRepository,ParseUserGroupRepository,ParseRoundRepository,ParsePartRepository,Pa   A

Complexity

Conditions 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 20
rs 9.4
cc 1
1
package com.osomapps.pt.admin.program;
2
3
import com.osomapps.pt.ResourceNotFoundException;
4
import com.osomapps.pt.programs.ParseExercise;
5
import com.osomapps.pt.programs.ParseExerciseRepository;
6
import com.osomapps.pt.programs.ParseGoal;
7
import com.osomapps.pt.programs.ParseUserGroup;
8
import com.osomapps.pt.programs.ParseProgram;
9
import com.osomapps.pt.programs.ProgramRepository;
10
import com.osomapps.pt.xlsx.Workout;
11
import java.io.ByteArrayInputStream;
12
import java.time.LocalDateTime;
13
import java.util.Base64;
14
import java.util.List;
15
import java.util.stream.Collectors;
16
import org.springframework.data.domain.Sort;
17
import org.springframework.stereotype.Service;
18
import com.osomapps.pt.programs.ParseWarmupWorkoutItem;
19
import com.osomapps.pt.programs.ParseWorkout;
20
import com.osomapps.pt.programs.ParseWorkoutItem;
21
import com.osomapps.pt.programs.ParseWorkoutItemRepository;
22
import com.osomapps.pt.programs.ParseWorkoutRepository;
23
import com.osomapps.pt.xlsx.XlsxProgramParser;
24
import java.io.OutputStream;
25
import java.util.Arrays;
26
import java.util.Collections;
27
import com.osomapps.pt.programs.ParseGoalRepository;
28
import com.osomapps.pt.programs.ParsePart;
29
import com.osomapps.pt.programs.ParsePartRepository;
30
import com.osomapps.pt.programs.ParseRound;
31
import com.osomapps.pt.programs.ParseRoundRepository;
32
import com.osomapps.pt.programs.ParseSheets;
33
import com.osomapps.pt.programs.ParseUserGroupRepository;
34
import com.osomapps.pt.programs.ParseWarmupWorkoutItemRepository;
35
import com.osomapps.pt.programs.ParseWorkoutItemSet;
36
import com.osomapps.pt.programs.ParseWorkoutItemSetRepository;
37
import com.osomapps.pt.xlsx.ExcelSheets;
38
import java.io.IOException;
39
import org.apache.commons.lang3.BooleanUtils;
40
import org.apache.commons.lang3.StringUtils;
41
42
@Service
43
class AdminProgramService {
44
45
    private static final String BASE64_PREFIX = ";base64,";
46
    private static final int BASE64_PREFIX_LENGTH = 8;
47
    private final ProgramRepository programRepository;
48
    private final ParseExerciseRepository parseExerciseRepository;
49
    private final ParseGoalRepository parseGoalRepository;
50
    private final ParseUserGroupRepository parseUserGroupRepository;
51
    private final ParseRoundRepository parseRoundRepository;
52
    private final ParsePartRepository parsePartRepository;
53
    private final ParseWorkoutRepository parseWorkoutRepository;
54
    private final ParseWarmupWorkoutItemRepository parseWarmupWorkoutItemRepository;
55
    private final ParseWorkoutItemRepository parseWorkoutItemRepository;
56
    private final ParseWorkoutItemSetRepository parseWorkoutItemSetRepository;
57
58
    AdminProgramService(ProgramRepository programRepository,
0 ignored issues
show
Comprehensibility introduced by
Constructor has 10 parameters, which is greater than 7 authorized.
Loading history...
59
            ParseExerciseRepository parseExerciseRepository,
60
            ParseGoalRepository parseGoalRepository,
61
            ParseUserGroupRepository parseUserGroupRepository,
62
            ParseRoundRepository parseRoundRepository,
63
            ParsePartRepository parsePartRepository,
64
            ParseWorkoutRepository parseWorkoutRepository,
65
            ParseWarmupWorkoutItemRepository parseWarmupWorkoutItemRepository,
66
            ParseWorkoutItemRepository parseWorkoutItemRepository,
67
            ParseWorkoutItemSetRepository parseWorkoutItemSetRepository) {
68
        this.programRepository = programRepository;
69
        this.parseExerciseRepository = parseExerciseRepository;
70
        this.parseGoalRepository = parseGoalRepository;
71
        this.parseUserGroupRepository = parseUserGroupRepository;
72
        this.parseRoundRepository = parseRoundRepository;
73
        this.parsePartRepository = parsePartRepository;
74
        this.parseWorkoutRepository = parseWorkoutRepository;
75
        this.parseWarmupWorkoutItemRepository = parseWarmupWorkoutItemRepository;
76
        this.parseWorkoutItemRepository = parseWorkoutItemRepository;
77
        this.parseWorkoutItemSetRepository = parseWorkoutItemSetRepository;
78
    }
79
80
    List<ProgramResponseDTO> findAll() {
81
        return programRepository.findAll(sortByIdAsc()).stream().map(program -> programToDto(program))
82
        .collect(Collectors.toList());
83
    }
84
85
    private Sort sortByIdAsc() {
86
        return Sort.by(Sort.Direction.ASC, "id");
87
    }
88
89
    private ProgramResponseDTO programToDto(ParseProgram program) {
90
        return ProgramResponseDTO.builder()
91
                .id(program.getId())
92
                .name(program.getName())
93
                .fileName(program.getFile_name())
94
                .fileSize(program.getFile_size())
95
                .fileType(program.getFile_type())
96
                .dataUrl(program.getData_url())
97
                .updated(program.getUpdated())
98
                .parseExercises(program.getParseExercises().stream().map(exercise -> ParseExerciseDTO.builder()
99
                        .exercise_id(exercise.getExercise_id())
100
                        .exercise_name(exercise.getExercise_name())
101
                        .user_group_1_percent(exercise.getUser_group_1_percent())
102
                        .user_group_2_percent(exercise.getUser_group_2_percent())
103
                        .user_group_3_percent(exercise.getUser_group_3_percent())
104
                        .user_group_4_percent(exercise.getUser_group_4_percent())
105
                        .basis_for_calculations(exercise.getBasis_for_calculations())
106
                        .build()
107
                ).collect(Collectors.toList()))
108
                .parseGoals(program.getParseGoals().stream().map(result -> ParseGoalDTO.builder()
109
                    .id(result.getId())
110
                    .name(result.getName())
111
                    .loops(result.getLoops())
112
                    .errors(result.getErrors())
113
                    .userGroups(result.getParseUserGroups().stream().map(userGroup -> ParseUserGroupDTO.builder()
114
                        .id(userGroup.getId())
115
                        .name(userGroup.getName())
116
                        .rounds(userGroup.getParseRounds() == null ? null : userGroup.getParseRounds().stream().map(round -> ParseRoundDTO.builder()
117
                                .id(round.getId())
118
                                .name(round.getName())
119
                                .parts(round.getParseParts().stream().map(part -> ParsePartDTO.builder()
120
                                        .id(part.getId())
121
                                        .name(part.getName())
122
                                        .workouts(part.getParseWorkouts().stream().map(workout ->
123
                                                createParseWorkoutDTO(workout)).collect(Collectors.toList()))
124
                                        .build()).collect(Collectors.toList()))
125
                                .build()).collect(Collectors.toList()))
126
                            .build()).collect(Collectors.toList()))
127
                        .build()).collect(Collectors.toList()))
128
                .build();
129
    }
130
131
    private ParseWorkoutDTO createParseWorkoutDTO(ParseWorkout workout) {
132
        return ParseWorkoutDTO.builder()
133
                .id(workout.getId())
134
                .name(workout.getName())
135
                .warmupWorkoutItem(workout.getParseWarmupWorkoutItems() == null ? null
136
                        : ParseWarmupWorkoutItemDTO.builder()
137
                                .id(workout.getParseWarmupWorkoutItems().get(0).getId())
138
                                .name(workout.getParseWarmupWorkoutItems().get(0).getName())
139
                                .speed(workout.getParseWarmupWorkoutItems().get(0).getSpeed())
140
                                .incline(workout.getParseWarmupWorkoutItems().get(0).getIncline())
141
                                .time_in_min(workout.getParseWarmupWorkoutItems().get(0).getTime_in_min())
142
                                .build())
143
                .workoutItems(workout.getParseWorkoutItems() == null ? null : workout.getParseWorkoutItems().stream().map(workoutItem ->
144
                        ParseWorkoutItemDTO.builder()
145
                                .id(workoutItem.getId())
146
                                .name(workoutItem.getName())
147
                                .sets(workoutItem.getParseWorkoutItemSets().stream().map(set ->
148
                                    new ParseWorkoutItemSetDTO()
149
                                        .setRepetitions(set.getRepetitions())
150
                                        .setRepetitions_to_failure(set.getRepetitions_to_failure())
151
                                        .setWeight(set.getWeight())
152
                                        .setBodyweight(set.getBodyweight())
153
                                        .setTime_in_min(set.getTime_in_min())
154
                                        .setSpeed(set.getSpeed())
155
                                        .setIncline(set.getIncline())
156
                                        .setResistance(set.getResistance())
157
                                ).collect(Collectors.toList()))
158
                                .build()).collect(Collectors.toList()))
159
                .build();
160
    }
161
162
    ProgramResponseDTO findOne(Long id) {
163
        final ParseProgram program = programRepository.findById(id).orElse(null);
164
        if (program == null) {
165
            throw new ResourceNotFoundException("Program with id " + id + " not found");
166
        }
167
        return programToDto(program);
168
    }
169
170
    ProgramResponseDTO create(ProgramRequestDTO programRequestDTO) {
171
        final ParseProgram program = new ParseProgram();
172
        program.setName(programRequestDTO.getName());
173
        program.setFile_name(programRequestDTO.getFileName());
174
        program.setFile_size(programRequestDTO.getFileSize());
175
        program.setFile_type(programRequestDTO.getFileType());
176
        program.setData_url(programRequestDTO.getDataUrl());
177
        final ParseProgram savedProgram = programRepository.save(program);
178
        final ParseSheets parseSheets = parseDataUrlAndSaveGoals(programRequestDTO, savedProgram);
179
        program.setParseExercises(parseSheets.getParseExercises());
180
        program.setParseGoals(parseSheets.getParseGoals());
181
        return programToDto(program);
182
    }
183
184
    private ParseSheets parseDataUrlAndSaveGoals(ProgramRequestDTO programRequestDTO, final ParseProgram savedProgram) {
185
        final ParseSheets parseSheets = parseDataUrl(programRequestDTO, savedProgram);
186
        parseExerciseRepository.saveAll(parseSheets.getParseExercises());
187
        final List<ParseGoal> savedParseGoals = parseGoalRepository.saveAll(parseSheets.getParseGoals());
188
        savedParseGoals.forEach((parseGoal) -> {
0 ignored issues
show
Java 8 introduced by
Remove useless curly braces around statement
Loading history...
189
            parseGoal.getParseUserGroups().forEach((parseUserGroup) -> {
190
                parseUserGroup.setParseGoal(parseGoal);
191
                parseUserGroup.getParseRounds().forEach((parseRound) -> {
192
                    parseRound.setParseUserGroup(parseUserGroup);
193
                    parseRound.getParseParts().forEach((parsePart) -> {
194
                        parsePart.setParseRound(parseRound);
195
                        parsePart.getParseWorkouts().forEach((parseWorkout) -> {
196
                            parseWorkout.setParsePart(parsePart);
197
                            if (parseWorkout.getParseWarmupWorkoutItems() != null) {
198
                                parseWorkout.getParseWarmupWorkoutItems().forEach((parseWarmupWorkoutItem) -> {
0 ignored issues
show
Java 8 introduced by
Remove useless curly braces around statement
Loading history...
199
                                    parseWarmupWorkoutItem.setParseWorkout(parseWorkout);
200
                                });
201
                            }
202
                            if (parseWorkout.getParseWorkoutItems() != null) {
203
                                parseWorkout.getParseWorkoutItems().forEach((parseWorkoutItem) -> {
204
                                    parseWorkoutItem.setParseWorkout(parseWorkout);
205
                                    parseWorkoutItem.getParseWorkoutItemSets().forEach((parseWorkoutItemSet) -> {
0 ignored issues
show
Java 8 introduced by
Remove useless curly braces around statement
Loading history...
206
                                        parseWorkoutItemSet.setParseWorkoutItem(parseWorkoutItem);
207
                                    });
208
                                });
209
                            }
210
                        });
211
                    });
212
                });
213
            });
214
        });
215
        savedParseGoals.forEach((parseGoal) -> {
216
            parseUserGroupRepository.saveAll(parseGoal.getParseUserGroups());
217
            parseGoal.getParseUserGroups().forEach((parseUserGroup) -> {
218
                parseRoundRepository.saveAll(parseUserGroup.getParseRounds());
219
                parseUserGroup.getParseRounds().forEach((parseRound) -> {
220
                    parsePartRepository.saveAll(parseRound.getParseParts());
221
                    parseRound.getParseParts().forEach((parsePart) -> {
222
                        parseWorkoutRepository.saveAll(parsePart.getParseWorkouts());
223
                        parsePart.getParseWorkouts().forEach((parseWorkout) -> {
224
                            parseWarmupWorkoutItemRepository.saveAll(parseWorkout.getParseWarmupWorkoutItems());
225
                            parseWorkoutItemRepository.saveAll(parseWorkout.getParseWorkoutItems());
226
                            parseWorkout.getParseWorkoutItems().forEach(parseWorkoutItem -> {
0 ignored issues
show
Java 8 introduced by
Remove useless curly braces around statement
Loading history...
227
                                 parseWorkoutItemSetRepository.saveAll(parseWorkoutItem.getParseWorkoutItemSets());
228
                            });
229
                        });
230
                    });
231
                });
232
            });
233
        });
234
        return parseSheets;
235
    }
236
237
    ProgramResponseDTO update(Long id, ProgramRequestDTO programRequestDTO) {
238
        final ParseProgram program = programRepository.findById(id).orElse(null);
239
        if (program == null) {
240
            throw new ResourceNotFoundException("Program with id " + id + " not found");
241
        }
242
        program.setName(programRequestDTO.getName());
243
        program.setFile_name(programRequestDTO.getFileName());
244
        program.setFile_size(programRequestDTO.getFileSize());
245
        program.setFile_type(programRequestDTO.getFileType());
246
        program.setData_url(programRequestDTO.getDataUrl());
247
        program.setUpdated(LocalDateTime.now());
248
        parseExerciseRepository.deleteAll(program.getParseExercises());
249
        parseGoalRepository.deleteAll(program.getParseGoals());
250
        final ParseSheets parseSheets = parseDataUrlAndSaveGoals(programRequestDTO, program);
251
        program.setParseExercises(parseSheets.getParseExercises());
252
        program.setParseGoals(parseSheets.getParseGoals());
253
        return programToDto(programRepository.save(program));
254
    }
255
256
    private ParseSheets parseDataUrl(ProgramRequestDTO programRequestDTO, final ParseProgram program) {
257
        final ByteArrayInputStream arrayInputStream = dataUrlToInputStream(programRequestDTO.getDataUrl());
258
        final XlsxProgramParser xlsxProgramParser = XlsxProgramParser.of(arrayInputStream);
259
        final ExcelSheets excelSheets = xlsxProgramParser.getExcelSheets();
260
        return new ParseSheets()
261
                .setParseExercises(excelSheets.getExcelExercises().stream().map(exercise ->
262
                  new ParseExercise()
263
                        .setExercise_id(exercise.getExercise_id())
264
                        .setExercise_name(exercise.getExercise_name())
265
                        .setUser_group_1_percent(exercise.getUser_group_1_percent())
266
                        .setUser_group_2_percent(exercise.getUser_group_2_percent())
267
                        .setUser_group_3_percent(exercise.getUser_group_3_percent())
268
                        .setUser_group_4_percent(exercise.getUser_group_4_percent())
269
                        .setBasis_for_calculations(exercise.getBasis_for_calculations())
270
                        .setParseProgram(program)
271
                ).collect(Collectors.toList()))
272
                .setParseGoals(excelSheets.getExcelGoals().stream().map(goal ->
273
            new ParseGoal()
274
                .setErrors(StringUtils.abbreviate(goal.getErrors().stream().collect(Collectors.joining(", ")), 1000))
275
                .setName(goal.getName())
276
                .setSheet_index(goal.getSheetIndex())
277
                .setLoops(goal.getLoops())
278
                .setParseProgram(program)
279
                .setParseUserGroups(goal.getUserGroups().stream().map(userGroup ->
280
                        new ParseUserGroup()
281
                            .setName(userGroup.getName())
282
                            .setParseRounds(userGroup.getRounds().stream().map(round ->
283
                                new ParseRound()
284
                                    .setName(round.getName())
285
                                    .setParseParts(round.getParts().stream().map(part ->
286
                                        new ParsePart()
287
                                            .setName(part.getName())
288
                                            .setParseWorkouts(part.getWorkouts().stream().map(workout ->
289
                                                createParseWorkout(workout)
290
                                            ).collect(Collectors.toList()))
291
                                    ).collect(Collectors.toList()))
292
                            ).collect(Collectors.toList()))
293
                ).collect(Collectors.toList()))
294
        ).collect(Collectors.toList()));
295
    }
296
297
    private ParseWorkout createParseWorkout(Workout workout) {
298
        return new ParseWorkout()
299
                .setName(workout.getName())
300
                .setParseWarmupWorkoutItems(workout.getWarmup() == null ? Collections.emptyList()
301
                        : Arrays.asList(new ParseWarmupWorkoutItem()
302
                                .setName(workout.getWarmup().getExercise())
303
                                .setExercise_id(workout.getWarmup().getExerciseId())
304
                                .setSpeed(workout.getWarmup().getSpeed())
305
                                .setIncline(workout.getWarmup().getIncline())
306
                                .setTime_in_min(workout.getWarmup().getTimeInMin())))
307
                .setParseWorkoutItems(workout.getWorkoutItems().stream().map(workoutItem ->
308
                        new ParseWorkoutItem()
309
                                .setColumn_index(workoutItem.getColumnIndex())
310
                                .setRow_index(workoutItem.getRowIndex())
311
                                .setName(workoutItem.getInput().getExercise())
312
                                .setExercise_id(workoutItem.getExerciseId())
313
                                .setParseWorkoutItemSets(workoutItem.getInput().getSets().stream().map(set ->
314
                                        new ParseWorkoutItemSet()
315
                                            .setRepetitions(set.getRepetitions())
316
                                            .setRepetitions_to_failure(BooleanUtils.isTrue(set.getRepetitionsToFailure()))
317
                                            .setWeight(set.getWeight())
318
                                            .setBodyweight(BooleanUtils.isTrue(set.getBodyweight()))
319
                                            .setTime_in_min(set.getTimeInMin())
320
                                            .setSpeed(set.getSpeed())
321
                                            .setIncline(set.getIncline())
322
                                            .setResistance(set.getResistance())
323
                                ).collect(Collectors.toList()))
324
                ).collect(Collectors.toList()));
325
    }
326
327
    ByteArrayInputStream dataUrlToInputStream(String dataUrl) {
328
        final String encodedString = dataUrl.substring(dataUrl.indexOf(BASE64_PREFIX) + BASE64_PREFIX_LENGTH);
329
        return new ByteArrayInputStream(Base64.getDecoder().decode(encodedString));
330
    }
331
332
    void dataUrlToOutputStream(String dataUrl, OutputStream outputStream) {
333
        final String encodedString = dataUrl.substring(dataUrl.indexOf(BASE64_PREFIX) + BASE64_PREFIX_LENGTH);
334
        try {
335
            outputStream.write(Base64.getDecoder().decode(encodedString));
336
        } catch (IOException | IllegalArgumentException ex) {
0 ignored issues
show
Bug introduced by
Consider removing the empty block or filling it with code. You can also add a comment to explain the empty block.
Loading history...
337
        }
338
    }
339
340
    ProgramResponseDTO delete(Long id) {
341
        final ParseProgram program = programRepository.findById(id).orElse(null);
342
        if (program == null) {
343
            throw new ResourceNotFoundException("Program with id " + id + " not found");
344
        }
345
        final ProgramResponseDTO responseDTO = programToDto(program);
346
        programRepository.delete(program);
347
        return responseDTO;
348
    }
349
}
350