Merge branch 'dev'
This commit is contained in:
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
* DELETE /api/account/invest/holdings/{id} 종목 삭제(매매이력 포함)
|
||||
* GET /api/account/invest/holdings/{id}/trades 매매이력
|
||||
* POST /api/account/invest/holdings/{id}/trades 매수/매도
|
||||
* PUT /api/account/invest/trades/{id} 매매 수정
|
||||
* DELETE /api/account/invest/trades/{id} 매매 삭제
|
||||
*/
|
||||
@RestController
|
||||
@@ -93,6 +94,14 @@ public class InvestController {
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(investService.addTrade(id, req, current.getId()));
|
||||
}
|
||||
|
||||
@PutMapping("/trades/{id}")
|
||||
public TradeResponse updateTrade(
|
||||
@PathVariable Long id,
|
||||
@Valid @RequestBody TradeRequest req,
|
||||
@RequestAttribute(AuthInterceptor.CURRENT_MEMBER) SessionUser current) {
|
||||
return investService.updateTrade(id, req, current.getId());
|
||||
}
|
||||
|
||||
@DeleteMapping("/trades/{id}")
|
||||
public ResponseEntity<Void> deleteTrade(
|
||||
@PathVariable Long id,
|
||||
|
||||
@@ -38,6 +38,8 @@ public interface InvestMapper {
|
||||
|
||||
int insertTrade(InvestTrade trade);
|
||||
|
||||
int updateTrade(InvestTrade trade);
|
||||
|
||||
int deleteTrade(@Param("id") Long id, @Param("memberId") Long memberId);
|
||||
|
||||
int deleteTradesByHolding(@Param("holdingId") Long holdingId, @Param("memberId") Long memberId);
|
||||
|
||||
@@ -138,6 +138,50 @@ public class InvestService {
|
||||
return TradeResponse.from(t);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public TradeResponse updateTrade(Long id, TradeRequest req, Long memberId) {
|
||||
InvestTrade existing = investMapper.findTradeByIdAndMember(id, memberId);
|
||||
if (existing == null) {
|
||||
throw new ApiException(HttpStatus.NOT_FOUND, "매매 내역을 찾을 수 없습니다.");
|
||||
}
|
||||
Long holdingId = existing.getHoldingId();
|
||||
String type = "SELL".equals(req.getTradeType()) ? "SELL" : "BUY";
|
||||
long fee = req.getFee() != null ? req.getFee() : 0L;
|
||||
|
||||
// 편집을 반영한 시점별 시뮬레이션 — 어느 시점에도 보유수량이 음수가 되면 거부
|
||||
java.util.List<InvestTrade> sim = new java.util.ArrayList<>();
|
||||
for (InvestTrade t : investMapper.findTradesByHolding(holdingId, memberId)) {
|
||||
if (t.getId().equals(id)) {
|
||||
sim.add(InvestTrade.builder().id(id).tradeType(type).tradeDate(req.getTradeDate())
|
||||
.quantity(req.getQuantity()).price(req.getPrice()).fee(fee).build());
|
||||
} else {
|
||||
sim.add(t);
|
||||
}
|
||||
}
|
||||
sim.sort(java.util.Comparator.comparing(InvestTrade::getTradeDate)
|
||||
.thenComparing(InvestTrade::getId));
|
||||
BigDecimal running = BigDecimal.ZERO;
|
||||
for (InvestTrade t : sim) {
|
||||
if ("BUY".equals(t.getTradeType())) {
|
||||
running = running.add(t.getQuantity());
|
||||
} else {
|
||||
running = running.subtract(t.getQuantity());
|
||||
if (running.signum() < 0) {
|
||||
throw new ApiException(HttpStatus.BAD_REQUEST,
|
||||
"수정하면 보유수량이 음수가 됩니다. 매도 수량/순서를 확인하세요.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
existing.setTradeType(type);
|
||||
existing.setTradeDate(req.getTradeDate());
|
||||
existing.setQuantity(req.getQuantity());
|
||||
existing.setPrice(req.getPrice());
|
||||
existing.setFee(fee);
|
||||
investMapper.updateTrade(existing);
|
||||
return TradeResponse.from(existing);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteTrade(Long id, Long memberId) {
|
||||
if (investMapper.findTradeByIdAndMember(id, memberId) == null) {
|
||||
|
||||
@@ -87,6 +87,13 @@
|
||||
VALUES (#{memberId}, #{holdingId}, #{tradeType}, #{tradeDate}, #{quantity}, #{price}, #{fee}, NOW())
|
||||
</insert>
|
||||
|
||||
<update id="updateTrade" parameterType="com.sb.web.account.domain.InvestTrade">
|
||||
UPDATE invest_trade
|
||||
SET trade_type = #{tradeType}, trade_date = #{tradeDate},
|
||||
quantity = #{quantity}, price = #{price}, fee = #{fee}
|
||||
WHERE id = #{id} AND member_id = #{memberId}
|
||||
</update>
|
||||
|
||||
<delete id="deleteTrade">
|
||||
DELETE FROM invest_trade WHERE id = #{id} AND member_id = #{memberId}
|
||||
</delete>
|
||||
|
||||
Reference in New Issue
Block a user