165 lines
7.3 KiB
Swift
165 lines
7.3 KiB
Swift
import Foundation
|
|
|
|
enum GiftDateFormatter {
|
|
static func yyyyMMdd(fromUTC text: String?) -> String? {
|
|
format(text, format: "yyyy.MM.dd")
|
|
}
|
|
|
|
static func mmDD(fromUTC text: String?) -> String? {
|
|
format(text, format: "MM.dd")
|
|
}
|
|
|
|
private static func format(_ text: String?, format: String) -> String? {
|
|
guard let text, let date = DateParser.parse(text) else { return nil }
|
|
|
|
let formatter = DateFormatter()
|
|
formatter.locale = Locale(identifier: "en_US_POSIX")
|
|
formatter.timeZone = .autoupdatingCurrent
|
|
formatter.dateFormat = format
|
|
return formatter.string(from: date)
|
|
}
|
|
}
|
|
|
|
enum GiftDisplayPolicy {
|
|
static func listCard(from item: GiftListItemResponse) -> GiftListCardDisplayModel? {
|
|
guard let direction = GiftDirection(rawValue: item.direction),
|
|
let status = GiftStatus(rawValue: item.status) else {
|
|
return nil
|
|
}
|
|
|
|
return GiftListCardDisplayModel(
|
|
applicationNo: item.applicationNo,
|
|
direction: direction,
|
|
status: status,
|
|
counterpartNickname: item.counterpartNickname,
|
|
counterpartProfileImageUrl: item.counterpartProfileImageUrl,
|
|
categoryName: item.categoryName,
|
|
sizeName: item.sizeName,
|
|
createdDateText: GiftDateFormatter.yyyyMMdd(fromUTC: item.createdAt),
|
|
statusDisplay: listStatus(direction: direction, status: status, statusName: item.statusName)
|
|
)
|
|
}
|
|
|
|
static func sentDetail(from detail: GiftDetailResponse) -> SentGiftDetailDisplayModel? {
|
|
guard let status = status(from: detail, expectedDirection: .sent) else { return nil }
|
|
|
|
return SentGiftDetailDisplayModel(
|
|
status: status,
|
|
statusName: detail.statusName,
|
|
undeliverableReason: detail.delivery.undeliverableReason,
|
|
recipientCreatorNickname: detail.giftInfo.recipientCreatorNickname,
|
|
sizeName: detail.giftInfo.sizeName,
|
|
categoryName: detail.giftInfo.categoryName,
|
|
applicationNo: detail.applicationNo,
|
|
paidCan: detail.giftInfo.paidCan,
|
|
tracking: detail.giftInfo.tracking,
|
|
shippingRequestedDateText: GiftDateFormatter.yyyyMMdd(fromUTC: detail.giftInfo.shippingRequestedAt),
|
|
applicationDateText: GiftDateFormatter.yyyyMMdd(
|
|
fromUTC: detail.statusTimeline.first { $0.status == GiftStatus.received.rawValue }?.occurredAt
|
|
),
|
|
canceledDateText: GiftDateFormatter.yyyyMMdd(fromUTC: detail.delivery.canceledAt),
|
|
senderInfo: detail.senderInfo.map(GiftAddressDisplayModel.init),
|
|
mailbox: detail.mailbox.map(GiftAddressDisplayModel.init),
|
|
trackingRequired: detail.trackingRequired,
|
|
progress: progress(from: detail.statusTimeline)
|
|
)
|
|
}
|
|
|
|
static func receivedDetail(from detail: GiftDetailResponse) -> ReceivedGiftDetailDisplayModel? {
|
|
guard let status = status(from: detail, expectedDirection: .received) else { return nil }
|
|
|
|
return ReceivedGiftDetailDisplayModel(
|
|
status: status,
|
|
statusName: detail.statusName,
|
|
undeliverableReason: detail.delivery.undeliverableReason,
|
|
senderNickname: detail.giftInfo.senderNickname,
|
|
sizeName: detail.giftInfo.sizeName,
|
|
categoryName: detail.giftInfo.categoryName,
|
|
shippingRequestedDateText: GiftDateFormatter.yyyyMMdd(fromUTC: detail.giftInfo.shippingRequestedAt),
|
|
recipientAddressRequired: status == .undeliverable ? false : detail.recipientAddressRequired,
|
|
recipientAddress: status == .undeliverable ? nil : detail.recipientAddress.map(GiftAddressDisplayModel.init),
|
|
progress: progress(from: detail.statusTimeline)
|
|
)
|
|
}
|
|
|
|
static func sizeDescription(for sizeCode: String) -> String? {
|
|
guard let size = GiftSize(rawValue: sizeCode) else { return nil }
|
|
|
|
switch size {
|
|
case .small:
|
|
return "세 변의 합 100cm 이하 · 5kg 이하"
|
|
case .medium:
|
|
return "세 변의 합 120cm 이하 · 15kg 이하"
|
|
case .large:
|
|
return "세 변의 합 160cm 이하 · 20kg 이하"
|
|
}
|
|
}
|
|
|
|
private static func listStatus(
|
|
direction: GiftDirection,
|
|
status: GiftStatus,
|
|
statusName: String
|
|
) -> GiftListStatusDisplayModel {
|
|
switch (direction, status) {
|
|
case (.sent, .received):
|
|
return GiftListStatusDisplayModel(title: "운송장 등록 필요", subtitle: nil)
|
|
case (.sent, .trackingRegistered):
|
|
return GiftListStatusDisplayModel(title: "발송 확인", subtitle: nil)
|
|
case (.sent, .arrivedAtMailbox):
|
|
return GiftListStatusDisplayModel(title: "사서함 도착", subtitle: nil)
|
|
case (.sent, .inspectionCompleted):
|
|
return GiftListStatusDisplayModel(title: "선물 검수 완료", subtitle: nil)
|
|
case (.sent, .delivered):
|
|
return GiftListStatusDisplayModel(title: "전달 완료", subtitle: nil)
|
|
case (.sent, .undeliverable):
|
|
return GiftListStatusDisplayModel(title: "전달 불가", subtitle: nil)
|
|
case (.sent, .canceled):
|
|
return GiftListStatusDisplayModel(title: "신청 취소", subtitle: nil)
|
|
case (.received, .trackingRegistered):
|
|
return GiftListStatusDisplayModel(title: "배송지 입력 필요", subtitle: "전달 예정")
|
|
case (.received, .arrivedAtMailbox):
|
|
return GiftListStatusDisplayModel(title: "선물 검수", subtitle: "선물 확인 중")
|
|
case (.received, .inspectionCompleted):
|
|
return GiftListStatusDisplayModel(title: "선물 검수 완료", subtitle: "배송 중")
|
|
case (.received, .delivered):
|
|
return GiftListStatusDisplayModel(title: "전달 완료", subtitle: nil)
|
|
case (.received, .undeliverable):
|
|
return GiftListStatusDisplayModel(title: "전달 불가", subtitle: nil)
|
|
default:
|
|
return GiftListStatusDisplayModel(title: statusName, subtitle: nil)
|
|
}
|
|
}
|
|
|
|
private static func status(
|
|
from detail: GiftDetailResponse,
|
|
expectedDirection: GiftDirection
|
|
) -> GiftStatus? {
|
|
guard GiftDirection(rawValue: detail.direction) == expectedDirection else { return nil }
|
|
return GiftStatus(rawValue: detail.status)
|
|
}
|
|
|
|
private static func progress(from timeline: [GiftStatusTimelineResponse]) -> [GiftProgressDisplayModel] {
|
|
GiftProgressStep.allCases.map { step in
|
|
let occurredAt = timeline.first { $0.status == step.rawValue }?.occurredAt
|
|
return GiftProgressDisplayModel(
|
|
step: step,
|
|
occurredDateText: GiftDateFormatter.mmDD(fromUTC: occurredAt)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
private extension GiftAddressDisplayModel {
|
|
init(_ senderInfo: GiftSenderInfoResponse) {
|
|
self.init(name: senderInfo.name, phoneNumber: senderInfo.phoneNumber, address: senderInfo.address)
|
|
}
|
|
|
|
init(_ recipientAddress: GiftRecipientAddressResponse) {
|
|
self.init(name: recipientAddress.name, phoneNumber: recipientAddress.phoneNumber, address: recipientAddress.address)
|
|
}
|
|
|
|
init(_ mailbox: GiftMailboxResponse) {
|
|
self.init(name: mailbox.name, phoneNumber: mailbox.phoneNumber, address: mailbox.address)
|
|
}
|
|
}
|