dev #14384 Правка ошибок отображения WPA КофеЛайк: change user info data

This commit is contained in:
nikolay 2023-07-03 11:52:56 +04:00
parent b7cc0ed72d
commit 656e41b8cf
10 changed files with 142 additions and 166 deletions

View File

@ -199,14 +199,29 @@ export interface UserInfoWalletBalance {
wallet: UserInfoWallet; wallet: UserInfoWallet;
} }
export interface CurrentInfo {
current_cashback: number;
current_level: number;
}
export interface LastPurchase {
last_purchase_date: string;
last_purchase_sum: number;
}
export interface NextLevel {
cashback: number;
next_level: number;
sum_for_next_level: number;
}
export interface UserInfo { export interface UserInfo {
OrdersSum: number; current_level_and_cashback?: CurrentInfo;
categories: UserInfoCategory[]; last_purchase?: LastPurchase;
customer_level: number;
id: string; id: string;
name: string | null;
phone: string; phone: string;
walletBalances: UserInfoWalletBalance[] | { error: ResponseError }; walletBalances: number;
next_level: NextLevel;
} }
export interface ResponseError { export interface ResponseError {

View File

@ -1,7 +1,7 @@
<h2>Ваш предыдущий заказ</h2> <h2>Ваш предыдущий заказ</h2>
<div class="info-order"> <div class="info-order">
<p class="flex"><span>Дата: </span> <p class="flex"><span>Дата: </span>
<span *ngIf="!loading">{{(lastOrder?.transactionCreateDate | date:'dd.MM.yyyyг.') || 'Данные не найдены'}}</span> <span *ngIf="!loading">{{(lastOrder?.last_purchase_date | date:'dd.MM.yyyyг.') || 'Данные не найдены'}}</span>
<ng-container *ngIf="loading"> <ng-container *ngIf="loading">
<ng-container <ng-container
*ngTemplateOutlet="spinner; context: { $implicit: 24 }" *ngTemplateOutlet="spinner; context: { $implicit: 24 }"
@ -9,7 +9,7 @@
</ng-container> </ng-container>
</p> </p>
<p class="flex"><span>На сумму: </span> <p class="flex"><span>На сумму: </span>
<span *ngIf="!loading">{{lastOrder?.orderSum ? lastOrder?.orderSum + ' ₽' : 'Данные не найдены'}}</span> <span *ngIf="!loading">{{lastOrder ? lastOrder.last_purchase_sum + ' ₽' : 'Данные не найдены'}}</span>
<ng-container *ngIf="loading"> <ng-container *ngIf="loading">
<ng-container <ng-container
*ngTemplateOutlet="spinner; context: { $implicit: 24 }" *ngTemplateOutlet="spinner; context: { $implicit: 24 }"

View File

@ -1,5 +1,5 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { Purchase } from 'src/app/interface/data'; import { LastPurchase } from 'src/app/interface/data';
@Component({ @Component({
selector: 'app-last-order[lastOrder]', selector: 'app-last-order[lastOrder]',
@ -7,12 +7,11 @@ import { Purchase } from 'src/app/interface/data';
styleUrls: ['./last-order.component.scss'] styleUrls: ['./last-order.component.scss']
}) })
export class LastOrderComponent implements OnInit { export class LastOrderComponent implements OnInit {
@Input() lastOrder?: Purchase; @Input() lastOrder?: LastPurchase;
@Input() loading!: boolean; @Input() loading!: boolean;
constructor() { } constructor() { }
ngOnInit(): void { ngOnInit(): void {
} }
} }

View File

@ -3,17 +3,12 @@
<div class="guest-card"> <div class="guest-card">
<div class="top-info"> <div class="top-info">
<div class="top-info__level"> <div class="top-info__level">
<p id="level">Уровень {{ authService.userInfo.customer_level }}</p> <p id="level">Уровень {{ authService.userInfo.current_level_and_cashback?.current_level ?? '--' }}</p>
<p id="level-percent">Кэшбек {{ authService.currentLvlPeriod.percent }}%</p> <p id="level-percent">Кэшбек {{ authService.currentLvlPeriod.percent }}%</p>
</div> </div>
<p class="top-info__bonus"> <p class="top-info__bonus">
<ng-container *ngIf="!isNegativeBalance"> {{ Math.floor(authService.userInfo.walletBalances) }}
{{ Math.floor(authService.getBalanceAmount($any(authService.userInfo.walletBalances))) }} бонусов
бонусов
</ng-container>
<ng-container *ngIf="isNegativeBalance">
Ошибка! Отрицательный баланс бонусов
</ng-container>
</p> </p>
</div> </div>
<div class="guest-card__qr" (click)="qrCodeClick()"> <div class="guest-card__qr" (click)="qrCodeClick()">
@ -29,9 +24,7 @@
<ng-container *ngIf="authService.currentLvlPeriod.end"> <ng-container *ngIf="authService.currentLvlPeriod.end">
Осталось купить на сумму Осталось купить на сумму
<span class="price">{{ <span class="price">{{
authService.currentLvlPeriod.end - authService.userInfo.next_level.sum_for_next_level
(authService.userInfo.OrdersSum) +
1
}}</span> }}</span>
рублей, тогда кэшбек будет рублей, тогда кэшбек будет
<span class="percent" <span class="percent"
@ -39,7 +32,7 @@
> >
с с
{{ {{
authService.purchaseData.currentPeriod[1] authService.currentPeriod[1]
.locale("ru") .locale("ru")
.format("D MMMM") .format("D MMMM")
}} }}
@ -53,7 +46,7 @@
</div> </div>
<span id="bonuses-condition"></span> <span id="bonuses-condition"></span>
<app-last-order <app-last-order
[lastOrder]="authService.purchaseData.lastPurchase" [lastOrder]="authService.userInfo?.last_purchase"
[loading]="authService.loading" [loading]="authService.loading"
></app-last-order> ></app-last-order>
<a class="guest-card__loyalty-program" routerLink="loyality-program" <a class="guest-card__loyalty-program" routerLink="loyality-program"

View File

@ -17,11 +17,6 @@ export class GuestCardComponent implements OnInit {
private isQrCodeClicked: boolean = false; private isQrCodeClicked: boolean = false;
public Math: Math = Math; public Math: Math = Math;
public showBack: boolean = false; public showBack: boolean = false;
public negativeBalance: boolean = false;
get isNegativeBalance(): boolean {
return !Array.isArray(this.authService.userInfo?.walletBalances);
}
constructor( constructor(
private _bottomSheet: MatBottomSheet, private _bottomSheet: MatBottomSheet,
@ -32,7 +27,6 @@ export class GuestCardComponent implements OnInit {
) { } ) { }
ngOnInit(): void { ngOnInit(): void {
this.negativeBalance = !Array.isArray(this.authService.userInfo?.walletBalances);
this.showBack = getTypeDevice() === DeviceType.android; this.showBack = getTypeDevice() === DeviceType.android;
this.requestPermission(); this.requestPermission();

View File

@ -1,11 +1,7 @@
<app-navbar <app-navbar
*ngIf="phoneForm.value.phone && !isShowNumber" *ngIf="phoneForm.value.phone && !isShowNumber"
[title]="phoneForm.value.phone" [title]="phoneForm.value.phone"
[backEvent]="backToPhoneForm" [backEvent]="backToPhoneForm"
[ngStyle]="{
position: 'absolute',
top: 0
}"
></app-navbar> ></app-navbar>
<h1>Участвуй в программе лояльности COFFEE LIKE</h1> <h1>Участвуй в программе лояльности COFFEE LIKE</h1>
<p class="description">Начни получать бонусы прямо сейчас</p> <p class="description">Начни получать бонусы прямо сейчас</p>

View File

@ -1,5 +1,4 @@
:host { :host {
padding-top: 48px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;

View File

@ -1,105 +1,105 @@
<app-navbar title="Программа лояльности" [backEvent]="goBack"></app-navbar> <app-navbar title="Программа лояльности" [backEvent]="goBack"></app-navbar>
<ng-container *ngIf="authService.currentLvlPeriod"> <ng-container *ngIf="authService.currentLvlPeriod">
<div class="loyality-program"> <div class="loyality-program">
<app-accordion header="Условия начисления бонусов"> <app-accordion header="Условия начисления бонусов">
<p> <p>
Ваш текущий уровень {{ authService.userInfo?.customer_level }}, Ваш текущий уровень {{ authService.userInfo?.current_level_and_cashback?.current_level ?? '--' }},
поэтому вам начисляется {{ authService.currentLvlPeriod.percent }}% от суммы покупки. поэтому вам начисляется {{ authService.currentLvlPeriod.percent }}% от суммы покупки.
</p> </p>
<p> <p>
Смена уровня произойдет в начале следующего квартала, Смена уровня произойдет в начале следующего квартала,
{{ authService.purchaseData.currentPeriod[1] {{ authService.currentPeriod[1]
.locale("ru") .locale("ru")
.format("DD.MM.YY") }}. .format("DD.MM.YY") }}.
</p> </p>
</app-accordion> </app-accordion>
<app-accordion header="Уровни бонусной программы"> <app-accordion header="Уровни бонусной программы">
<p> <p>
Начисление Бонусных баллов происходит по дифференцированной шкале в Начисление Бонусных баллов происходит по дифференцированной шкале в
зависимости от уровня: зависимости от уровня:
</p> </p>
<ng-container
*ngFor="let item of lvlPeriods; let index = index; let last = last"
>
<ng-container *ngIf="!last">
<ul>
<span [style]="{ color: item.color }">Уровень {{ index + 1 }}</span>
<li>
Сумма покупок за прошлый квартал {{ item.start }}-{{ item.end }}
руб.
</li>
<li>Начисляемый бонус {{ item.percent }}% от суммы покупки</li>
</ul>
<br />
</ng-container>
<ng-container *ngIf="last">
<ul>
<span [style]="{ color: item.color }">Уровень {{ index + 1 }}</span>
<li>Сумма покупок за прошлый квартал — от {{ item.start }} руб.</li>
<li>Начисляемый бонус, в % от суммы покупки - {{ item.percent }}%</li>
</ul>
</ng-container>
</ng-container>
</app-accordion>
<app-accordion header="Условия «оплаты» покупки бонусами">
<p>
Участник может использовать Бонусы для «оплаты» до 100% стоимости любой
покупки.
</p>
<p>
Списание Бонусов происходит из расчета 1:1 (один Бонус дает скидку 1
российский рубль / 1 тенге / 1 белорусский рубль. Скидка, предоставляемая
Участнику при списании Бонусов, уменьшает цену товаров в заказе в
соответствии с условиями ПЛ.
</p>
<p>
Для списания Бонусов Участник должен попросить об этом в кофе-баре сети
«COFFEE LIKE» кассира до момента пробития фискального чека, после чего им
будет проверена возможность списания Бонусов.
</p>
<p>
Для всех Участников возможно списание без использования мобильного
приложения.
</p>
<p>Полученные Бонусы не подлежат обмену на денежные средства.</p>
</app-accordion>
<app-accordion header="Особые условия">
<p>
Начисленные на счет бонусы сгорают по прошествии 90 дней с момента
совершения последней покупки с начислением или списанием бонусов.
</p>
<ng-container
*ngFor="let item of lvlPeriods; let index = index; let last = last"
>
<ng-container *ngIf="!last">
<ul> <ul>
<span [style]="{ color: item.color }">Уровень {{ index + 1 }}</span> Возврат покупки, за которую бонусы были начислены:
<li> <li>
Сумма покупок за прошлый квартал {{ item.start }}-{{ item.end }} В случае, если бонусов на счету достаточно для списания, бонусы
руб. списываются в полном ранее начисленном за возвращаемый товар объеме.
</li> </li>
<li>Начисляемый бонус {{ item.percent }}% от суммы покупки</li> <li>
В случае, если бонусов на счету недостаточно, формируется минусовой
баланс.
</li>
</ul> </ul>
<br />
</ng-container>
<ng-container *ngIf="last">
<ul> <ul>
<span [style]="{ color: item.color }">Уровень {{ index + 1 }}</span> Возврат покупки, которая была оплачена бонусами:
<li>Сумма покупок за прошлый квартал — от {{ item.start }} руб.</li> <li>
<li>Начисляемый бонус, в % от суммы покупки - {{ item.percent }}%</li> В случае предъявления Участником кассового или товарного чека, сумма
бонусов, списанная для оплаты возвращаемого товара, зачисляется на счет
участника.
</li>
<li>
В случае возврата товара с применением оплаты бонусами, клиенту
возвращается денежная сумма в размере, внесенном Участником в оплату
товара при покупке, за вычетом суммы, оплаченной бонусами.
</li>
</ul> </ul>
</ng-container> </app-accordion>
</ng-container>
</app-accordion>
<app-accordion header="Условия «оплаты» покупки бонусами"> </div>
<p>
Участник может использовать Бонусы для «оплаты» до 100% стоимости любой
покупки.
</p>
<p>
Списание Бонусов происходит из расчета 1:1 (один Бонус дает скидку 1
российский рубль / 1 тенге / 1 белорусский рубль. Скидка, предоставляемая
Участнику при списании Бонусов, уменьшает цену товаров в заказе в
соответствии с условиями ПЛ.
</p>
<p>
Для списания Бонусов Участник должен попросить об этом в кофе-баре сети
«COFFEE LIKE» кассира до момента пробития фискального чека, после чего им
будет проверена возможность списания Бонусов.
</p>
<p>
Для всех Участников возможно списание без использования мобильного
приложения.
</p>
<p>Полученные Бонусы не подлежат обмену на денежные средства.</p>
</app-accordion>
<app-accordion header="Особые условия">
<p>
Начисленные на счет бонусы сгорают по прошествии 90 дней с момента
совершения последней покупки с начислением или списанием бонусов.
</p>
<ul> <app-footer></app-footer>
Возврат покупки, за которую бонусы были начислены:
<li>
В случае, если бонусов на счету достаточно для списания, бонусы
списываются в полном ранее начисленном за возвращаемый товар объеме.
</li>
<li>
В случае, если бонусов на счету недостаточно, формируется минусовой
баланс.
</li>
</ul>
<ul>
Возврат покупки, которая была оплачена бонусами:
<li>
В случае предъявления Участником кассового или товарного чека, сумма
бонусов, списанная для оплаты возвращаемого товара, зачисляется на счет
участника.
</li>
<li>
В случае возврата товара с применением оплаты бонусами, клиенту
возвращается денежная сумма в размере, внесенном Участником в оплату
товара при покупке, за вычетом суммы, оплаченной бонусами.
</li>
</ul>
</app-accordion>
</div>
<app-footer></app-footer>
</ng-container> </ng-container>

View File

@ -1,3 +1,4 @@
.loyality-program { .loyality-program {
max-width: 600px;
margin: 0 auto;
} }

View File

@ -4,34 +4,25 @@ import { WpJsonService } from './wp-json.service';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
import { JsonrpcService, RpcService } from './jsonrpc.service'; import { JsonrpcService, RpcService } from './jsonrpc.service';
import { MessageService } from 'primeng/api'; import { MessageService } from 'primeng/api';
import { UserInfo, Purchase, lvlPeriod, UserInfoWalletBalance, ResponseError } from '../interface/data'; import { UserInfo, lvlPeriod, UserInfoWalletBalance, Moment } from '../interface/data';
import { lvlPeriods } from 'src/app/app.constants'; import { lvlPeriods } from 'src/app/app.constants';
import moment, { Moment } from 'moment-timezone'; import moment from 'moment-timezone';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
export interface IPurchaseData {
currentPeriod: Moment[];
lastPeriod: Moment[];
currentAmount?: number;
lastPurchase?: Purchase;
}
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class AuthService { export class AuthService {
public purchaseData: IPurchaseData = { lastPeriod: Moment[] = [];
currentPeriod: [], currentPeriod: Moment[] = [];
lastPeriod: [],
lastPurchase: undefined,
};
userInfo?: UserInfo; userInfo?: UserInfo;
loading: boolean = false; loading: boolean = false;
error: any; error: any;
timeLeft: number = 0; timeLeft: number = 0;
get currentLvlPeriod(): lvlPeriod { get currentLvlPeriod(): lvlPeriod {
return lvlPeriods[this.userInfo ? this.userInfo.customer_level - 1 : 0]; return lvlPeriods[
this.userInfo?.current_level_and_cashback ? this.userInfo?.current_level_and_cashback.current_level - 1 : 0];
} }
constructor( constructor(
@ -90,13 +81,14 @@ export class AuthService {
this.userInfo = value.customer_info; this.userInfo = value.customer_info;
this.cookiesService.setCookie('phone-number', this.userInfo!.phone?.slice(2)); this.cookiesService.setCookie('phone-number', this.userInfo!.phone?.slice(2));
this.getLastPurchase();
} }
}, },
error: (e) => { error: (e) => {
this.error = e; this.error = e;
}, },
complete: () => {
this.loading = false;
}
}); });
} }
@ -234,31 +226,18 @@ export class AuthService {
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
if (moment().isBetween(quarters[i][0], quarters[i][1])) { if (moment().isBetween(quarters[i][0], quarters[i][1])) {
this.purchaseData.lastPeriod = quarters[i - 1]; this.lastPeriod = quarters[i - 1];
this.purchaseData.currentPeriod = quarters[i]; this.currentPeriod = quarters[i];
} }
} }
} }
getNextLevel(): lvlPeriod { getNextLevel(): lvlPeriod {
if (this.userInfo?.customer_level === lvlPeriods.length) { if (this.userInfo?.next_level.next_level) {
return lvlPeriods[lvlPeriods.length - 1]; return lvlPeriods[this.userInfo.next_level.next_level];
} }
return this.userInfo && lvlPeriods[this.userInfo?.customer_level] || lvlPeriods[0];
}
getLastPurchase() { return lvlPeriods[0];
this.loading = true;
if (this.userInfo) {
this.wpJsonService.getLastPurchase(environment.systemId, this.token!).subscribe({
next: (res) => {
this.purchaseData.lastPurchase = res[this.userInfo!.id][0];
},
complete: () => {
this.loading = false;
},
});
}
} }
getBalanceAmount(loyaltyPrograms: UserInfoWalletBalance[]) { getBalanceAmount(loyaltyPrograms: UserInfoWalletBalance[]) {