-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
223 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package chap03; | ||
|
||
import java.time.LocalDate; | ||
import java.time.YearMonth; | ||
|
||
public class ExpiryDateCalculator { | ||
public LocalDate calculateExpiryDate(PayData payData) { | ||
int addedMonths = payData.getPayAmount() == 100_000 ? 12 : payData.getPayAmount() / 10_000; | ||
|
||
if(payData.getFirstBillingDate() != null){ | ||
return expiryDateUsingFirstBillingDate(payData,addedMonths); | ||
}else{ | ||
return payData.getBillingDate().plusMonths(addedMonths); | ||
} | ||
} | ||
|
||
private LocalDate expiryDateUsingFirstBillingDate(PayData payData, int addedMonths){ | ||
LocalDate candidateExp = payData.getBillingDate().plusMonths(addedMonths); // 후보 만료일 | ||
final int dayOfFirstBilling = payData.getFirstBillingDate().getDayOfMonth(); | ||
|
||
if(dayOfFirstBilling != candidateExp.getDayOfMonth()){ // 첫 납부일의 일자와 후보 만료일의 일자가 다르면 | ||
final int dayLenOfCandiMon = YearMonth.from(candidateExp).lengthOfMonth(); | ||
if(dayLenOfCandiMon < dayOfFirstBilling){ // 후보 만료일이 포함된 달의 마지막 날 < 첫 납부일의 일자 | ||
return candidateExp.withDayOfMonth(dayLenOfCandiMon); | ||
} | ||
return candidateExp.withDayOfMonth(dayOfFirstBilling); // 첫 납부일의 일자를 후보 만료일의 일자로 사용 | ||
}else{ | ||
return candidateExp; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package chap03; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import java.time.LocalDate; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
public class ExpiryDateCalculatorTest { // expiry(expiration) date : 만료일 | ||
|
||
@Test | ||
void 십만원을_납부하면_1년_제공(){ | ||
assertExpiryDate( | ||
PayData.builder() | ||
.billingDate(LocalDate.of(2019, 1, 28)) | ||
.payAmount(100_000) | ||
.build() | ||
, LocalDate.of(2020, 1, 28)); | ||
} | ||
|
||
// 1만원을 납부하면 한 달 뒤 같은 날을 만료일로 계산 | ||
@Test | ||
void 만원_납부하면_한달_뒤가_만료일이_됨() { | ||
// // 처음 작성하는 코드 | ||
// assertEquals(기대하는 만료일, 실제 만료일); | ||
assertExpiryDate( | ||
PayData.builder() | ||
.billingDate(LocalDate.of(2019, 3, 1)) | ||
.payAmount(10_000) | ||
.build() | ||
, LocalDate.of(2019, 4, 1)); | ||
assertExpiryDate( | ||
PayData.builder() | ||
.billingDate(LocalDate.of(2019, 5, 5)) | ||
.payAmount(10_000) | ||
.build() | ||
, LocalDate.of(2019, 6, 5)); | ||
} | ||
|
||
private void assertExpiryDate(PayData payData, LocalDate expectedExpiryDate) { | ||
ExpiryDateCalculator cal = new ExpiryDateCalculator(); | ||
LocalDate realExpiryDate = cal.calculateExpiryDate(payData); | ||
assertEquals(expectedExpiryDate, realExpiryDate); | ||
} | ||
|
||
@Test | ||
void 납부일과_한달_뒤_일자가_같지_않음() { | ||
// LocalDate#plusMonths() 메서드가 알아서 한 달 추가 처리를 해 줌 | ||
assertExpiryDate( | ||
PayData.builder() | ||
.billingDate(LocalDate.of(2019, 1, 31)) | ||
.payAmount(10_000) | ||
.build() | ||
, LocalDate.of(2019, 2, 28)); | ||
assertExpiryDate( | ||
PayData.builder() | ||
.billingDate(LocalDate.of(2019, 5, 31)) | ||
.payAmount(10_000) | ||
.build() | ||
, LocalDate.of(2019, 6, 30)); | ||
assertExpiryDate( | ||
PayData.builder() | ||
.billingDate(LocalDate.of(2020, 1, 31)) | ||
.payAmount(10_000) | ||
.build() | ||
, LocalDate.of(2020, 2, 29)); | ||
} | ||
|
||
@Test | ||
void 첫_납부일과_만료일_일자가_다를때_만원_납부(){ | ||
// case 1 | ||
PayData payData = PayData.builder() | ||
.firstBillingData(LocalDate.of(2019, 1, 31)) // 첫 납부일 | ||
.billingDate(LocalDate.of(2019, 2, 28)) // 납부일 | ||
.payAmount(10_000) | ||
.build(); | ||
assertExpiryDate(payData, LocalDate.of(2019, 3, 31)); | ||
|
||
// case 2 | ||
PayData payData2 = PayData.builder() | ||
.firstBillingData(LocalDate.of(2019, 1, 30)) // 첫 납부일 | ||
.billingDate(LocalDate.of(2019, 2, 28)) // 납부일 | ||
.payAmount(10_000) | ||
.build(); | ||
assertExpiryDate(payData2, LocalDate.of(2019, 3, 30)); | ||
|
||
// case 3 | ||
PayData payData3 = PayData.builder() | ||
.firstBillingData(LocalDate.of(2019, 5, 31)) // 첫 납부일 | ||
.billingDate(LocalDate.of(2019, 6, 30)) // 납부일 | ||
.payAmount(10_000) | ||
.build(); | ||
assertExpiryDate(payData3, LocalDate.of(2019, 7, 31)); | ||
|
||
} | ||
|
||
@Test | ||
void 이만원_이상_납부하면_비례해서_만료일_계산(){ | ||
assertExpiryDate( | ||
PayData.builder() | ||
.billingDate(LocalDate.of(2019, 3, 1)) | ||
.payAmount(20_000) | ||
.build() | ||
, LocalDate.of(2019, 5, 1)); | ||
assertExpiryDate( | ||
PayData.builder() | ||
.billingDate(LocalDate.of(2019, 3, 1)) | ||
.payAmount(30_000) | ||
.build() | ||
, LocalDate.of(2019, 6, 1)); | ||
} | ||
|
||
@Test | ||
void 첫_납부일과_만료일_일자가_다를때_이만원_이상_납부(){ | ||
// case 1 | ||
assertExpiryDate( | ||
PayData.builder() | ||
.firstBillingData(LocalDate.of(2019, 1, 31)) // 첫 납부일 | ||
.billingDate(LocalDate.of(2019, 2, 28)) // 납부일 | ||
.payAmount(20_000) | ||
.build() | ||
, LocalDate.of(2019, 4, 30)); | ||
|
||
// case 2 | ||
assertExpiryDate( | ||
PayData.builder() | ||
.firstBillingData(LocalDate.of(2019, 3, 31)) // 첫 납부일 | ||
.billingDate(LocalDate.of(2019, 4, 30)) // 납부일 | ||
.payAmount(30_000) | ||
.build() | ||
, LocalDate.of(2019, 7, 31)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package chap03; | ||
|
||
import java.time.LocalDate; | ||
|
||
public class PayData { | ||
|
||
private LocalDate firstBillingDate; | ||
private LocalDate billingDate; | ||
private int payAmount; | ||
|
||
private PayData() { | ||
} | ||
|
||
public PayData(LocalDate firstBillingDate, LocalDate billingDate, int payAmount) { | ||
this.firstBillingDate = firstBillingDate; | ||
this.billingDate = billingDate; | ||
this.payAmount = payAmount; | ||
} | ||
public LocalDate getFirstBillingDate() { | ||
return firstBillingDate; | ||
} | ||
public LocalDate getBillingDate() { | ||
return billingDate; | ||
} | ||
public int getPayAmount() { | ||
return payAmount; | ||
} | ||
|
||
public static Builder builder(){ | ||
return new Builder(); | ||
} | ||
|
||
// 간단한 빌더 패턴 적용한 것임 | ||
public static class Builder { | ||
private PayData data = new PayData(); | ||
|
||
public Builder firstBillingData(LocalDate firstBillingDate) { | ||
data.firstBillingDate = firstBillingDate; | ||
return this; | ||
} | ||
|
||
public Builder billingDate(LocalDate billingDate) { | ||
data.billingDate = billingDate; | ||
return this; | ||
} | ||
|
||
public Builder payAmount(int payAmount) { | ||
data.payAmount = payAmount; | ||
return this; | ||
} | ||
|
||
public PayData build(){ | ||
return data; | ||
} | ||
|
||
|
||
} | ||
|
||
} |