Skip to content

Commit 49498ab

Browse files
committed
feat: admin can add a price in stamps catalogs.
Fix #1340
1 parent 9153c9b commit 49498ab

File tree

13 files changed

+278
-2
lines changed

13 files changed

+278
-2
lines changed

NEWS.txt

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- (feature) add preliminary support for hidden images
55
- (feature) admin can add a comment to a series
66
- (feature) admin can add a release year to a series
7+
- (feature) admin can add a price in Michel, Scott, Yvert, Gibbons, Solovyov, and Zagorski catalogs
78
- (improvement) on a country info page show the series with an image
89
- (feature) add a condition (MNH/MNHOG/MVLH/CTO/cancelled) to a series sale
910

src/main/config/spotbugs-filter.xml

+8
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@
102102
</Or>
103103
<Bug pattern="EI_EXPOSE_REP,EI_EXPOSE_REP2" />
104104
</Match>
105+
<Match>
106+
<Class name="ru.mystamps.web.feature.series.AddCatalogPriceDbDto" />
107+
<Or>
108+
<Method name="getUpdatedAt" />
109+
<Method name="setUpdatedAt" />
110+
</Or>
111+
<Bug pattern="EI_EXPOSE_REP,EI_EXPOSE_REP2" />
112+
</Match>
105113
<Match>
106114
<Class name="ru.mystamps.web.feature.series.PurchaseAndSaleDto" />
107115
<Bug pattern="EI_EXPOSE_REP,EI_EXPOSE_REP2" />

src/main/frontend/src/components/AddCatalogPriceForm.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ class AddCatalogPriceForm extends React.PureComponent {
6565
const data = response.data;
6666
if (data.hasOwnProperty('fieldErrors')) {
6767
const fieldErrors = [];
68-
if (data.fieldErrors.price) {
69-
fieldErrors.push(...data.fieldErrors.price);
68+
if (data.fieldErrors.value) {
69+
fieldErrors.push(...data.fieldErrors.value);
7070
}
7171

7272
this.setState({
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (C) 2009-2020 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
19+
package ru.mystamps.web.feature.series;
20+
21+
import lombok.Getter;
22+
import lombok.Setter;
23+
24+
import java.math.BigDecimal;
25+
import java.util.Date;
26+
27+
@Getter
28+
@Setter
29+
public class AddCatalogPriceDbDto {
30+
private Integer seriesId;
31+
private BigDecimal price;
32+
private Date updatedAt;
33+
private Integer updatedBy;
34+
}

src/main/java/ru/mystamps/web/feature/series/JdbcSeriesDao.java

+65
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,24 @@ public class JdbcSeriesDao implements SeriesDao {
102102
@Value("${series.add_similar_series}")
103103
private String addSimilarSeriesSql;
104104

105+
@Value("${series.add_michel_price}")
106+
private String addMichelPriceSql;
107+
108+
@Value("${series.add_scott_price}")
109+
private String addScottPriceSql;
110+
111+
@Value("${series.add_yvert_price}")
112+
private String addYvertPriceSql;
113+
114+
@Value("${series.add_gibbons_price}")
115+
private String addGibbonsPriceSql;
116+
117+
@Value("${series.add_solovyov_price}")
118+
private String addSolovyovPriceSql;
119+
120+
@Value("${series.add_zagorski_price}")
121+
private String addZagorskiPriceSql;
122+
105123
@Override
106124
public Integer add(AddSeriesDbDto series) {
107125
Map<String, Object> params = new HashMap<>();
@@ -349,4 +367,51 @@ public void markAsSimilar(Integer seriesId, Integer similarSeriesId) {
349367
);
350368
}
351369

370+
@Override
371+
public void addMichelPrice(AddCatalogPriceDbDto dto) {
372+
addCatalogPrice(addMichelPriceSql, dto);
373+
}
374+
375+
@Override
376+
public void addScottPrice(AddCatalogPriceDbDto dto) {
377+
addCatalogPrice(addScottPriceSql, dto);
378+
}
379+
380+
@Override
381+
public void addYvertPrice(AddCatalogPriceDbDto dto) {
382+
addCatalogPrice(addYvertPriceSql, dto);
383+
}
384+
385+
@Override
386+
public void addGibbonsPrice(AddCatalogPriceDbDto dto) {
387+
addCatalogPrice(addGibbonsPriceSql, dto);
388+
}
389+
390+
@Override
391+
public void addSolovyovPrice(AddCatalogPriceDbDto dto) {
392+
addCatalogPrice(addSolovyovPriceSql, dto);
393+
}
394+
395+
@Override
396+
public void addZagorskiPrice(AddCatalogPriceDbDto dto) {
397+
addCatalogPrice(addZagorskiPriceSql, dto);
398+
}
399+
400+
private void addCatalogPrice(String query, AddCatalogPriceDbDto dto) {
401+
Map<String, Object> params = new HashMap<>();
402+
params.put("series_id", dto.getSeriesId());
403+
params.put("price", dto.getPrice());
404+
params.put("updated_at", dto.getUpdatedAt());
405+
params.put("updated_by", dto.getUpdatedBy());
406+
407+
int affected = jdbcTemplate.update(query, params);
408+
409+
// @todo #1340 Update series: handle refuse to update an existing price gracefully
410+
Validate.validState(
411+
affected == 1,
412+
"Unexpected number of affected rows after updating series: %d",
413+
affected
414+
);
415+
}
416+
352417
}

src/main/java/ru/mystamps/web/feature/series/RestSeriesController.java

+27
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@
3434
import java.io.IOException;
3535
import java.util.List;
3636

37+
import static ru.mystamps.web.feature.series.StampsCatalog.GIBBONS;
38+
import static ru.mystamps.web.feature.series.StampsCatalog.MICHEL;
39+
import static ru.mystamps.web.feature.series.StampsCatalog.SCOTT;
40+
import static ru.mystamps.web.feature.series.StampsCatalog.SOLOVYOV;
41+
import static ru.mystamps.web.feature.series.StampsCatalog.YVERT;
42+
import static ru.mystamps.web.feature.series.StampsCatalog.ZAGORSKI;
43+
3744
@Validated
3845
@RestController
3946
@RequiredArgsConstructor
@@ -43,6 +50,7 @@ class RestSeriesController {
4350

4451
// @todo #785 Update series: add integration test
4552
// @todo #785 Update series: add validation for a comment
53+
// @todo #1340 Update series: add validation for a price
4654
// @todo #1343 Update series: add validation for a release year
4755
@PatchMapping(SeriesUrl.INFO_SERIES_PAGE)
4856
public ResponseEntity<Void> updateSeries(
@@ -67,6 +75,7 @@ public ResponseEntity<Void> updateSeries(
6775
continue;
6876
}
6977

78+
// CheckStyle: ignore LineLength for next 27 lines
7079
switch (patch.getPath()) {
7180
case "/comment":
7281
seriesService.addComment(seriesId, patch.getValue());
@@ -77,6 +86,24 @@ public ResponseEntity<Void> updateSeries(
7786
Integer.valueOf(patch.getValue()),
7887
currentUserId);
7988
break;
89+
case "/michel_price":
90+
seriesService.addPrice(MICHEL, seriesId, patch.bigDecimalValue(), currentUserId);
91+
break;
92+
case "/scott_price":
93+
seriesService.addPrice(SCOTT, seriesId, patch.bigDecimalValue(), currentUserId);
94+
break;
95+
case "/yvert_price":
96+
seriesService.addPrice(YVERT, seriesId, patch.bigDecimalValue(), currentUserId);
97+
break;
98+
case "/gibbons_price":
99+
seriesService.addPrice(GIBBONS, seriesId, patch.bigDecimalValue(), currentUserId);
100+
break;
101+
case "/solovyov_price":
102+
seriesService.addPrice(SOLOVYOV, seriesId, patch.bigDecimalValue(), currentUserId);
103+
break;
104+
case "/zagorski_price":
105+
seriesService.addPrice(ZAGORSKI, seriesId, patch.bigDecimalValue(), currentUserId);
106+
break;
80107
default:
81108
// @todo #785 Update series: properly fail on invalid path
82109
break;

src/main/java/ru/mystamps/web/feature/series/SeriesDao.java

+7
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,11 @@ public interface SeriesDao {
4545
Integer findQuantityById(Integer seriesId);
4646

4747
void markAsSimilar(Integer seriesId, Integer similarSeriesId);
48+
49+
void addMichelPrice(AddCatalogPriceDbDto dto);
50+
void addScottPrice(AddCatalogPriceDbDto dto);
51+
void addYvertPrice(AddCatalogPriceDbDto dto);
52+
void addGibbonsPrice(AddCatalogPriceDbDto dto);
53+
void addSolovyovPrice(AddCatalogPriceDbDto dto);
54+
void addZagorskiPrice(AddCatalogPriceDbDto dto);
4855
}

src/main/java/ru/mystamps/web/feature/series/SeriesService.java

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
package ru.mystamps.web.feature.series;
1919

20+
import java.math.BigDecimal;
2021
import java.util.Date;
2122
import java.util.List;
2223

@@ -26,6 +27,7 @@ public interface SeriesService {
2627
Integer add(AddSeriesDto dto, Integer userId, boolean userCanAddComments);
2728
void addComment(Integer seriesId, String comment);
2829
void addReleaseYear(Integer seriesId, Integer year, Integer userId);
30+
void addPrice(StampsCatalog catalog, Integer seriesId, BigDecimal price, Integer userId);
2931
void addImageToSeries(AddImageDto dto, Integer seriesId, Integer userId);
3032
void replaceImage(ReplaceImageDto dto, Integer seriesId, Integer userId);
3133
long countAll();

src/main/java/ru/mystamps/web/feature/series/SeriesServiceImpl.java

+40
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626
import ru.mystamps.web.feature.image.ImageService;
2727
import ru.mystamps.web.support.spring.security.HasAuthority;
2828

29+
import java.math.BigDecimal;
2930
import java.util.Collections;
3031
import java.util.Date;
3132
import java.util.List;
33+
import java.util.Locale;
3234
import java.util.Set;
3335

3436
// FIXME: move stamps related methods to separate interface (#88)
@@ -157,6 +159,44 @@ public void addReleaseYear(Integer seriesId, Integer year, Integer userId) {
157159
log.info("Series #{}: release year set to {}", seriesId, year);
158160
}
159161

162+
// @todo #1340 SeriesServiceImpl.addPrice(): add unit tests
163+
@Override
164+
@Transactional
165+
@PreAuthorize(HasAuthority.CREATE_SERIES)
166+
// CheckStyle: ignore LineLength for next 1 line
167+
public void addPrice(StampsCatalog catalog, Integer seriesId, BigDecimal price, Integer userId) {
168+
Validate.isTrue(seriesId != null, "Series id must be non null");
169+
Validate.isTrue(price != null, "Price must be non null");
170+
Validate.isTrue(userId != null, "User id must be non null");
171+
172+
AddCatalogPriceDbDto dto = new AddCatalogPriceDbDto();
173+
dto.setSeriesId(seriesId);
174+
dto.setPrice(price);
175+
dto.setUpdatedBy(userId);
176+
177+
Date now = new Date();
178+
dto.setUpdatedAt(now);
179+
180+
// CheckStyle: ignore MethodParamPad for next 5 lines
181+
switch (catalog) {
182+
case MICHEL: seriesDao.addMichelPrice (dto); break;
183+
case SCOTT: seriesDao.addScottPrice (dto); break;
184+
case YVERT: seriesDao.addYvertPrice (dto); break;
185+
case GIBBONS: seriesDao.addGibbonsPrice (dto); break;
186+
case SOLOVYOV: seriesDao.addSolovyovPrice(dto); break;
187+
case ZAGORSKI: seriesDao.addZagorskiPrice(dto); break;
188+
default:
189+
throw new IllegalStateException("Unknown stamps catalog: " + catalog);
190+
}
191+
192+
log.info(
193+
"Series #{}: {} price set to {}",
194+
seriesId,
195+
catalog.toString().toLowerCase(Locale.ENGLISH),
196+
price
197+
);
198+
}
199+
160200
@Override
161201
@Transactional
162202
@PreAuthorize("isAuthenticated()")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (C) 2009-2020 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
19+
package ru.mystamps.web.feature.series;
20+
21+
public enum StampsCatalog {
22+
MICHEL,
23+
SCOTT,
24+
YVERT,
25+
GIBBONS,
26+
SOLOVYOV,
27+
ZAGORSKI
28+
}

src/main/java/ru/mystamps/web/support/spring/mvc/PatchRequest.java

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import javax.validation.constraints.NotEmpty;
2626
import javax.validation.constraints.NotNull;
27+
import java.math.BigDecimal;
2728

2829
// See for details: http://jsonpatch.com
2930
@Getter
@@ -47,4 +48,8 @@ public enum Operation {
4748
@NotEmpty
4849
private String value;
4950

51+
public BigDecimal bigDecimalValue() {
52+
return new BigDecimal(value);
53+
}
54+
5055
}

src/main/resources/sql/series_dao_queries.properties

+48
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,51 @@ VALUES \
246246
( :series_id \
247247
, :similar_series_id \
248248
)
249+
250+
series.add_michel_price = \
251+
UPDATE series \
252+
SET michel_price = :price \
253+
, updated_at = :updated_at \
254+
, updated_by = :updated_by \
255+
WHERE id = :series_id \
256+
AND michel_price IS NULL
257+
258+
series.add_scott_price = \
259+
UPDATE series \
260+
SET scott_price = :price \
261+
, updated_at = :updated_at \
262+
, updated_by = :updated_by \
263+
WHERE id = :series_id \
264+
AND scott_price IS NULL
265+
266+
series.add_yvert_price = \
267+
UPDATE series \
268+
SET yvert_price = :price \
269+
, updated_at = :updated_at \
270+
, updated_by = :updated_by \
271+
WHERE id = :series_id \
272+
AND yvert_price IS NULL
273+
274+
series.add_gibbons_price = \
275+
UPDATE series \
276+
SET gibbons_price = :price \
277+
, updated_at = :updated_at \
278+
, updated_by = :updated_by \
279+
WHERE id = :series_id \
280+
AND gibbons_price IS NULL
281+
282+
series.add_solovyov_price = \
283+
UPDATE series \
284+
SET solovyov_price = :price \
285+
, updated_at = :updated_at \
286+
, updated_by = :updated_by \
287+
WHERE id = :series_id \
288+
AND solovyov_price IS NULL
289+
290+
series.add_zagorski_price = \
291+
UPDATE series \
292+
SET zagorski_price = :price \
293+
, updated_at = :updated_at \
294+
, updated_by = :updated_by \
295+
WHERE id = :series_id \
296+
AND zagorski_price IS NULL

0 commit comments

Comments
 (0)