-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathStore.js
More file actions
113 lines (93 loc) · 3.19 KB
/
Copy pathStore.js
File metadata and controls
113 lines (93 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import StoreMachine from '../models/StoreMachine.js';
import Promotion from '../models/Promotion.js';
import Output from '../views/Output.js';
import Input from '../views/Input.js';
import retryOnError from '../utils/retryOnError.js';
import mergeSameItems from '../utils/mergeSameItems.js';
import Receipt from '../models/Receipt.js';
class Store {
#storeMachine;
/**
* @type {Promotion}
*/
#promotion;
constructor() {
this.#storeMachine = new StoreMachine();
}
async run() {
let continueShoppingFlag = true;
while (continueShoppingFlag) {
await this.#runStore();
continueShoppingFlag = await this.#checkMoreShopping();
}
}
async #runStore() {
this.openStore();
await retryOnError(this.#purchase.bind(this));
await this.#applyPromotion();
const membership = await this.#checkMembership();
this.#managePurchaseResult(membership);
}
openStore() {
Output.greeting();
const products = this.#storeMachine.getProducts();
Output.productsInfo(products);
}
async #purchase() {
const inputList = await Input.purchase();
const purchaseList = mergeSameItems(inputList);
this.#storeMachine.checkCanBuy(purchaseList);
}
async #applyPromotion() {
const promotionItems = this.#storeMachine.getPromotionItemList();
this.#promotion = new Promotion(promotionItems);
const availableMoreGiftList = this.#promotion.getAvailableMoreGiftList();
await this.#noticeMissingItems(availableMoreGiftList);
const disablePromotionList = this.#promotion.getDisablePromotionList();
await this.#noticeDisablePromotions(disablePromotionList);
this.#storeMachine.applyPromotion(this.#promotion.getBuyAndGetList());
}
async #checkMembership() {
const answer = await retryOnError(() => Input.noticeMembership());
if (answer === 'N') return false;
return true;
}
#managePurchaseResult(membership) {
this.#storeMachine.updateQuantity();
const receipt = this.#storeMachine.noticeReceipt(
(purchase) => new Receipt(purchase, membership)
);
this.#printReceipt(receipt);
}
async #checkMoreShopping() {
const answer = await retryOnError(() => Input.moreShopping());
if (answer === 'N') return false;
return true;
}
async #noticeMissingItems(availableMoreGiftList) {
for (const item of availableMoreGiftList) {
const { name, canGetMoreCount: giftCount } = item;
const answer = await retryOnError(() => Input.noticeMoreGift(name, giftCount));
if (answer === 'N') return;
this.#promotion.manageExtraGift(name);
}
}
async #noticeDisablePromotions(disablePromotionList) {
for (const item of disablePromotionList) {
const { name, disablePromotionCount: itemCount } = item;
const answer = await retryOnError(() => Input.noticeDisablePromotion(name, itemCount));
if (answer === 'Y') return;
this.#promotion.manageDisablePromotionItem(name);
}
}
/**
*
* @param {Receipt} receipt
*/
#printReceipt(receipt) {
receipt.purchaseItems((list) => Output.purchaseItems(list));
receipt.giftItems((list) => Output.giftItems(list));
receipt.receiptResult((list) => Output.receiptResult(list));
}
}
export default Store;