diff --git a/angular/src/app/app.constants.ts b/angular/src/app/app.constants.ts index 5dd5046..54e6130 100644 --- a/angular/src/app/app.constants.ts +++ b/angular/src/app/app.constants.ts @@ -1,4 +1,4 @@ -import {OrderStatus, Page, PageCode} from "./interface/data"; +import {OrderStatus, Page, PageCode, lvlPeriod} from "./interface/data"; export const PageList: Page[] = [ { @@ -64,4 +64,30 @@ export const orderStatuses: OrderStatus = { 'OnWay': 'В пути', 'Delivered': 'Выполнен', 'Closed': 'Выполнен', -}; \ No newline at end of file +}; + +export const lvlPeriods: lvlPeriod[] = [ + { + percent: 3, + start: 0, + end: 1600, + color: '#f2c94c' + }, + { + percent: 6, + start: 1601, + end: 3600, + color: '#f2994a' + }, + { + percent: 10, + start: 3601, + end: 8600, + color: '#6fcf97' + }, + { + percent: 15, + start: 8601, + color: '#6fcf97' + }, +] \ No newline at end of file diff --git a/angular/src/app/interface/data.ts b/angular/src/app/interface/data.ts index 3d47836..ddf3934 100644 --- a/angular/src/app/interface/data.ts +++ b/angular/src/app/interface/data.ts @@ -1,170 +1,179 @@ - - export enum PageCode { - Auth, - Orders, - BonusProgram, - RefSystem, - UserData + Auth, + Orders, + BonusProgram, + RefSystem, + UserData, } - + export interface Page { - code: PageCode; - component?: any; - name: string; - description?: string; - getMethod?: string; - resName?: string; - onSideBar: boolean + code: PageCode; + component?: any; + name: string; + description?: string; + getMethod?: string; + resName?: string; + onSideBar: boolean; } export interface UserDataForm { - first_name: string; - birthdate: string; - gender: string; + first_name: string; + birthdate: string; + gender: string; } export interface BonusProgramAccount { - BonusProgramName: string; - BonusProgramTypeID: string; - CardNumber: number; - Bonuses: number; - HoldedBonuses: number; - BonusProgramAccounts: BonusProgramAccount[]; - DateBonusBurn: string; - _links: any[]; - _embedded: any; + BonusProgramName: string; + BonusProgramTypeID: string; + CardNumber: number; + Bonuses: number; + HoldedBonuses: number; + BonusProgramAccounts: BonusProgramAccount[]; + DateBonusBurn: string; + _links: any[]; + _embedded: any; } export interface Purchase { - PurchaseId?: string; - CustomerId?: string; - PurchaseDate: string; - PurchaseState?: number; - CardNumber?: number; - Address?: string - CheckSummary?: number - BonusSummary?: number - ID: string; - Transactions: Transaction[]; - IsSingleTransaction?: boolean; + PurchaseId?: string; + CustomerId?: string; + PurchaseDate: string; + PurchaseState?: number; + CardNumber?: number; + Address?: string; + CheckSummary?: number; + BonusSummary?: number; + ID: string; + Transactions: Transaction[]; + IsSingleTransaction?: boolean; + transactionCreateDate?: string; + transactionType?: 'CancelPayFromWallet' | 'PayFromWallet' | 'RefillWallet'; + transactionSum: number; + orderSum?: number; } export interface Transaction { - User: string; - Purchase: string; - Date: string; - Value: number; - TransactionType: number; - UserBonusesSnapshot: number; - BonusPercent: number; - DateActiveBonus: string; - AccountBonus: string; - Bonus: string; - ID:string; - HasPurchase?:boolean; + User: string; + Purchase: string; + Date: string; + Value: number; + TransactionType: number; + UserBonusesSnapshot: number; + BonusPercent: number; + DateActiveBonus: string; + AccountBonus: string; + Bonus: string; + ID: string; + HasPurchase?: boolean; } -export interface OrderStatus{ - [key: string]: string; +export interface OrderStatus { + [key: string]: string; +} + +export interface lvlPeriod { + percent: number; + start: number; + end?: number; + color: string; } export interface DeliveryType { - cost: number; - title: string; - id: number; + cost: number; + title: string; + id: number; } export interface AcceptedOrder { - id: number; - status: string; - currency_symbol: string; + id: number; + status: string; + currency_symbol: string; + total: number; + address: { + city: string; + street: string; + house: number; + flat: number; + }; + payment_method: string; + shipping: { + name: string; total: number; - address: { - city: string; - street: string; - house: number; - flat: number; - }; - payment_method: string; - shipping: { - name: string; - total: number; - }; - date_created: string; - items: OrderProduct[] + }; + date_created: string; + items: OrderProduct[]; } -export interface Product{ - id: number; - name: string; - price: string; - image_url: string; - image_gallery: string[]; - category_id: number; - description?: string; - stock_status: string; - currency_symbol: string; - modifier_data: Modifier[]; - short_description?: string; - guid?: string; +export interface Product { + id: number; + name: string; + price: string; + image_url: string; + image_gallery: string[]; + category_id: number; + description?: string; + stock_status: string; + currency_symbol: string; + modifier_data: Modifier[]; + short_description?: string; + guid?: string; } -export interface Modifier{ - id: number; - name: string; - category_type: string; - minimum_options: number; - maximum_options: number; - global_categories: string; - required: number; - options: Option[]; - allOptions?: Option[]; +export interface Modifier { + id: number; + name: string; + category_type: string; + minimum_options: number; + maximum_options: number; + global_categories: string; + required: number; + options: Option[]; + allOptions?: Option[]; } -export interface Option{ - id: number; - name: string; - price: string; - prechecked: string; - active?: boolean; +export interface Option { + id: number; + name: string; + price: string; + prechecked: string; + active?: boolean; } -export interface OrderProduct{ - id: number; - amount: number; - name: string; - price: number; - modifiers: { - [name: string]: OrderModifier[] - } +export interface OrderProduct { + id: number; + amount: number; + name: string; + price: number; + modifiers: { + [name: string]: OrderModifier[]; + }; } -export interface OrderModifier{ - name: string; - id: number; - price: number; +export interface OrderModifier { + name: string; + id: number; + price: number; } export interface DeliveryData { - paymentMethod: PaymentMethod; - deliveryDate: Date | null; - deliveryType: DeliveryType | null; - persons: number; - comment: string; + paymentMethod: PaymentMethod; + deliveryDate: Date | null; + deliveryType: DeliveryType | null; + persons: number; + comment: string; } export interface PaymentMethod { - type: string; - label: string; + type: string; + label: string; } export interface UserData { - first_name: string | null; - last_name: string | null; - street: string | null; - house: string | null; - flat: string | null; - city: string; - phone: string | null; -} \ No newline at end of file + first_name: string | null; + last_name: string | null; + street: string | null; + house: string | null; + flat: string | null; + city: string; + phone: string | null; +} diff --git a/angular/src/app/pages/guest-card/guest-card.component.html b/angular/src/app/pages/guest-card/guest-card.component.html index 72ea414..4681ca6 100644 --- a/angular/src/app/pages/guest-card/guest-card.component.html +++ b/angular/src/app/pages/guest-card/guest-card.component.html @@ -1,162 +1,198 @@ - - - -
-
+
+
+ -
-
- Текущий баланс бонусов: - - {{ - getBalanceAmount(user?.customer_info?.walletBalances) - }} - бонусов -
- -

- Расчет начисления бонусов - 10% от суммы покупок за период с - 11.01.2023г. по 31.03.2023 г. -

-

- За период с 11.01.2023г. по 31.03.2023 г. сумма ваших покупок составила - 3700 руб. -

-

Начисляемый бонус 10% от суммы покупок

-
- -

- Участник может использовать Бонусы для «оплаты» до 100% стоимости любой - покупки. -

-

- Списание Бонусов происходит из расчета 1:1 (один Бонус дает скидку 1 - российский рубль / 1 тенге / 1 белорусский рубль. Скидка, - предоставляемая Участнику при списании Бонусов, уменьшает цену товаров в - заказе в соответствии с условиями ПЛ. -

-

- Для списания Бонусов Участник должен попросить об этом в кофе-баре сети - «COFFEE LIKE» кассира до момента пробития фискального чека, после чего - им будет проверена возможность списания Бонусов. -

-

- Для всех Участников возможно списание без использования мобильного - приложения. -

-

Полученные Бонусы не подлежат обмену на денежные средства.

-
- -

- Начисленные на счет бонусы сгорают по прошествии 90 дней с момента - совершения последней покупки с начислением или списанием бонусов. -

- -
    - Возврат покупки, за которую бонусы были начислены: -
  • - В случае, если бонусов на счету достаточно для списания, бонусы - списываются в полном ранее начисленном за возвращаемый товар объеме. -
  • -
  • - В случае, если бонусов на счету недостаточно, формируется минусовой - баланс. -
  • -
- -
    - Возврат покупки, которая была оплачена бонусами: -
  • - В случае предъявления Участником кассового или товарного чека, сумма - бонусов, списанная для оплаты возвращаемого товара, зачисляется на - счет участника. -
  • -
  • - В случае возврата товара с применением оплаты бонусами, клиенту - возвращается денежная сумма в размере, внесенном Участником в оплату - товара при покупке, за вычетом суммы, оплаченной бонусами. -
  • -
-
- -
- Сумма ваших покупок за период с 01.04.2023г. - 1200 руб. -
- -

- Начисление Бонусных баллов происходит по дифференцированной шкале в - зависимости от уровня: -

- -
    - Уровень 1 -
  • Сумма покупок за предыдущий период 0-1600 руб.
  • -
  • Начисляемый бонус 3% от суммы покупки
  • -
-
-
    - Уровень 2 -
  • Сумма покупок за предыдущий период 1601-3600 руб.
  • -
  • Начисляемый бонус 6% от суммы покупки
  • -
-
-
    - Уровень 3 -
  • Сумма покупок за предыдущий период  3601-8600 руб.
  • -
  • Начисляемый бонус 10% от суммы покупки
  • -
-
-
    - Уровень 4 -
  • Сумма покупок за предыдущий период — от 8601 руб.
  • -
  • Начисляемый бонус, в % от суммы покупки - 15%
  • -
-
- -
-

- До следующего уровня за период с 01.04.2023 по 30.06.2023г осталось - совершить покупки на 401 рублей -

- - -

Узнать условия начисления бонусов

-
-
- -
- -
-
- Скачай приложение -
- Подробнее о правилах
- Программы лояльности
+ + + +
+
+ Текущий баланс бонусов: + + {{ getBalanceAmount(customerInfo?.walletBalances) }} + бонусов
- + + +

+ Расчет начисления бонусов - 10% от суммы покупок за период с 11.01.2023г. + по 31.03.2023 г. +

+

+ За период с 11.01.2023г. по 31.03.2023 г. сумма ваших покупок составила + 3700 руб. +

+

Начисляемый бонус 10% от суммы покупок

+
+ +

+ Участник может использовать Бонусы для «оплаты» до 100% стоимости любой + покупки. +

+

+ Списание Бонусов происходит из расчета 1:1 (один Бонус дает скидку 1 + российский рубль / 1 тенге / 1 белорусский рубль. Скидка, предоставляемая + Участнику при списании Бонусов, уменьшает цену товаров в заказе в + соответствии с условиями ПЛ. +

+

+ Для списания Бонусов Участник должен попросить об этом в кофе-баре сети + «COFFEE LIKE» кассира до момента пробития фискального чека, после чего им + будет проверена возможность списания Бонусов. +

+

+ Для всех Участников возможно списание без использования мобильного + приложения. +

+

Полученные Бонусы не подлежат обмену на денежные средства.

+
+ +

+ Начисленные на счет бонусы сгорают по прошествии 90 дней с момента + совершения последней покупки с начислением или списанием бонусов. +

- - +
    + Возврат покупки, за которую бонусы были начислены: +
  • + В случае, если бонусов на счету достаточно для списания, бонусы + списываются в полном ранее начисленном за возвращаемый товар объеме. +
  • +
  • + В случае, если бонусов на счету недостаточно, формируется минусовой + баланс. +
  • +
+ +
    + Возврат покупки, которая была оплачена бонусами: +
  • + В случае предъявления Участником кассового или товарного чека, сумма + бонусов, списанная для оплаты возвращаемого товара, зачисляется на счет + участника. +
  • +
  • + В случае возврата товара с применением оплаты бонусами, клиенту + возвращается денежная сумма в размере, внесенном Участником в оплату + товара при покупке, за вычетом суммы, оплаченной бонусами. +
  • +
+
+ +
+ Сумма ваших покупок за период с + {{ purchaseData.currentPeriod[0].format("DD.MM.yyyyг.") }} - + {{ purchaseData.currentAmount }} руб. + + + +
+ +

+ Начисление Бонусных баллов происходит по дифференцированной шкале в + зависимости от уровня: +

+ + + +
    + Уровень {{ index + 1 }} +
  • + Сумма покупок за предыдущий период {{ item.start }}-{{ item.end }} + руб. +
  • +
  • Начисляемый бонус {{ item.percent }}% от суммы покупки
  • +
+
+
+ +
    + Уровень {{ index + 1 }} +
  • Сумма покупок за предыдущий период — от {{ item.start }} руб.
  • +
  • Начисляемый бонус, в % от суммы покупки - {{ item.percent }}%
  • +
+
+
+
+ +
+ + +

+ До следующего уровня за период с + {{ purchaseData.currentPeriod[0].format("DD.MM.yyyyг") }} по + {{ purchaseData.currentPeriod[1].format("DD.MM.yyyyг") }} + осталось совершить покупки на {{ currentLvlPeriod.end - (purchaseData.currentAmount || 0) + 1 }} рублей +

+ +
+ +

+ У Вас последний уровень бонусной программы. Процент начисляемых бонусов: {{currentLvlPeriod.percent}}% +

+
+
+ + + + +

+ + Узнать условия начисления бонусов + +

+
+
+ +
+ +
+
+ Скачай приложение +
+ Подробнее о правилах
+ Программы лояльности
+
+ + + diff --git a/angular/src/app/pages/guest-card/guest-card.component.scss b/angular/src/app/pages/guest-card/guest-card.component.scss index 1ad1850..3795539 100644 --- a/angular/src/app/pages/guest-card/guest-card.component.scss +++ b/angular/src/app/pages/guest-card/guest-card.component.scss @@ -62,6 +62,7 @@ font-size: 16px; line-height: 19px; letter-spacing: -0.5px; + grid-template-columns: calc(100% - 24px) 24px; span { color: #219653; @@ -70,6 +71,9 @@ &__level-info { padding: 36px; + display: flex; + flex-direction: column; + align-items: center; h2 { font-style: normal; @@ -152,7 +156,10 @@ font-size: 12px; line-height: 16px; text-align: center; - color: #28af49; + a { + text-decoration: none; + color: #28af49; + } } } diff --git a/angular/src/app/pages/guest-card/guest-card.component.ts b/angular/src/app/pages/guest-card/guest-card.component.ts index 7500b37..908d046 100644 --- a/angular/src/app/pages/guest-card/guest-card.component.ts +++ b/angular/src/app/pages/guest-card/guest-card.component.ts @@ -7,9 +7,21 @@ import { CookiesService } from 'src/app/services/cookies.service'; import { WpJsonService } from 'src/app/services/wp-json.service'; import { environment } from 'src/environments/environment'; import moment from 'moment'; +import { Purchase, lvlPeriod } from 'src/app/interface/data'; +import { lvlPeriods } from 'src/app/app.constants'; interface Moment extends moment.Moment {} +export interface IPurchaseData { + currentPeriod: Moment[]; + lastPeriod: Moment[]; + lastPurchases: Purchase[]; + currentPurchases: Purchase[]; + lastAmount?: number; + currentAmount?: number; + $loading: boolean; +} + @Component({ selector: 'app-guest-card', templateUrl: './guest-card.component.html', @@ -18,10 +30,35 @@ interface Moment extends moment.Moment {} export class GuestCardComponent implements OnInit { public qrCodeSize: number = 85; private isQrCodeClicked: boolean = false; - public customerInfo!: Observable; - public purchases!: Observable; + public customerInfo!: any; + public purchases!: Purchase[]; + public lastPurchase!: Purchase; + public purchaseData: IPurchaseData = { + currentPeriod: [], + lastPeriod: [], + lastPurchases: [], + currentPurchases: [], + $loading: true, + get currentAmount():number { + // const amount = this.currentPurchases.reduce((accumulator, currentValue) => { + // if (currentValue.transactionType !== 'PayFromWallet') return 0; + // return accumulator + currentValue.transactionSum; + // }, 0); + // return amount * -1 + return 8601 + }, + get lastAmount():number { + const amount = this.lastPurchases.reduce((accumulator, currentValue) => { + if (currentValue.transactionType !== 'PayFromWallet') return 0; + return accumulator + currentValue.transactionSum; + }, 0); + return amount * -1 + } + }; public discountLevel: number = 4.2; + public lvlPeriods: lvlPeriod[] = lvlPeriods; + public currentLvlPeriod!: lvlPeriod; constructor( private _bottomSheet: MatBottomSheet, @@ -32,13 +69,44 @@ export class GuestCardComponent implements OnInit { ngOnInit(): void { const token = this.cookiesService.getItem('token'); - this.customerInfo = this.wpJsonService.getCustomerInfo( - environment.systemId, - token || '', - environment.icardProxy - ); - this.purchases = this.getPurchases(); - this.purchases.subscribe((value) => console.log(value)); + this.getCurrentQuarterOfYear(); + this.wpJsonService + .getCustomerInfo( + environment.systemId, + token || '', + environment.icardProxy + ) + .subscribe({ + next: (value) => { + this.customerInfo = value.customer_info; + this.getPurchases().subscribe((value) => { + this.purchases = value[this.customerInfo?.id].filter( + (purchase: Purchase) => + [ + 'PayFromWallet', + 'CancelPayFromWallet', + 'RefillWallet', + ].includes(purchase.transactionType || '') + ); + this.lastPurchase = value[this.customerInfo?.id].filter( + (purchase: Purchase) => + [ + 'PayFromWallet', + ].includes(purchase.transactionType || '') + )[0] + + this.purchaseData.lastPurchases = this.purchases.filter((value: Purchase) => { + return moment(value.transactionCreateDate).isBetween(this.purchaseData.lastPeriod[0], this.purchaseData.lastPeriod[1]) + }) + this.purchaseData.currentPurchases = this.purchases.filter((value: Purchase) => { + return moment(value.transactionCreateDate).isBetween(this.purchaseData.currentPeriod[0], this.purchaseData.currentPeriod[1]) + }) + const currentAmount = this.purchaseData.currentAmount || 0 + this.currentLvlPeriod = this.lvlPeriods.find((item) => item.start <= currentAmount && currentAmount <= (item.end || Infinity))! + this.purchaseData.$loading = false; + }); + }, + }); } qrCodeClick() { @@ -63,26 +131,50 @@ export class GuestCardComponent implements OnInit { } getPurchases( - start: Date | Moment = moment().startOf('month'), + start: Date | Moment = moment().subtract(1, 'months').startOf('month'), end: Date | Moment = moment() ): Observable { const token = this.cookiesService.getItem('token'); const delta = moment(end).diff(moment(start), 'days'); - return this.wpJsonService.getTransactionsInfo( + return this.wpJsonService.getTransactions( environment.systemId, token ?? '', environment.icardProxy ); } + getCurrentQuarterOfYear() { + const quarters = [ + [ + moment().subtract(1, 'years').endOf('year').subtract(3, 'months'), + moment().subtract(1, 'years').endOf('year'), + ], + [moment().startOf('year'), moment().startOf('year').add(3, 'months')], + [ + moment().startOf('year').add(3, 'months'), + moment().startOf('year').add(6, 'months'), + ], + [ + moment().startOf('year').add(6, 'months'), + moment().startOf('year').add(9, 'months'), + ], + [ + moment().startOf('year').add(9, 'months'), + moment().startOf('year').add(12, 'months'), + ], + ]; + + for (let i = 0; i < 4; i++) { + if (moment().isBetween(quarters[i][0], quarters[i][1])) { + this.purchaseData.lastPeriod = quarters[i - 1]; + this.purchaseData.currentPeriod = quarters[i]; + } + } + } + getBalanceAmount(loyaltyPrograms: any[]) { - console.log(loyaltyPrograms); - - return loyaltyPrograms.reduce( - (accumulator, currentValue) => { - return accumulator + currentValue.balance - }, - 0 - ); + return loyaltyPrograms.reduce((accumulator, currentValue) => { + return accumulator + currentValue.balance; + }, 0); } }