сделал возможность посмотреть подробности по покупкам
This commit is contained in:
gofnnp 2023-03-21 22:42:24 +04:00
parent 00a47756b2
commit 1a503b3163
11 changed files with 280 additions and 69 deletions

View File

@ -7,13 +7,13 @@ import { AppComponent } from './app.component';
import { MainComponent } from './pages/main/main.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { CardComponent } from './components/card/card.component';
import {InputMaskModule} from "primeng/inputmask";
import { InputMaskModule } from 'primeng/inputmask';
import { AuthComponent } from './pages/account/auth/auth.component';
import {ProgressSpinnerModule} from "primeng/progressspinner";
import { ProgressSpinnerModule } from 'primeng/progressspinner';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AccountComponent } from './pages/account/account.component';
import { ExitComponent } from './components/exit/exit.component';
import { HttpClientModule } from '@angular/common/http';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DialogService } from 'primeng/dynamicdialog';
import { BonusProgramComponent } from './pages/account/bonus-program/bonus-program.component';
@ -23,59 +23,64 @@ import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
import { AngularFireModule } from '@angular/fire/compat';
import { AngularFireMessagingModule } from '@angular/fire/compat/messaging';
import {ToastModule} from 'primeng/toast';
import { ToastModule } from 'primeng/toast';
import { MessageService } from 'primeng/api';
import { FooterButtonsComponent } from './components/footer-buttons/footer-buttons.component';
import { UserDataComponent } from './pages/account/user-data/user-data.component';
import { RefSystemComponent } from './pages/account/ref-system/ref-system.component';
import { QRCodeModule } from 'angularx-qrcode';
import { ShareButtonsModule } from 'ngx-sharebuttons/buttons';
import { ShareButtonsModule } from 'ngx-sharebuttons/buttons';
import { ShareIconsModule } from 'ngx-sharebuttons/icons';
import { MessagingService } from './services/messaging.service';
import { NotFoundComponent } from './pages/not-found/not-found.component';
import { ProductsComponent } from './pages/products/products.component';
import { CartComponent } from './pages/cart/cart.component';
import {ListboxModule} from 'primeng/listbox';
import { ListboxModule } from 'primeng/listbox';
import { ProductModalComponent } from './components/product-modal/product-modal.component';
import { CheckboxGroupComponent } from './components/checkbox-group/checkbox-group.component';
import { TreeSelectModule } from 'primeng/treeselect';
import { UserDataOrderComponent } from './components/user-data-order/user-data-order.component';
import {DropdownModule} from "primeng/dropdown";
import {SelectButtonModule} from 'primeng/selectbutton';
import { DropdownModule } from 'primeng/dropdown';
import { SelectButtonModule } from 'primeng/selectbutton';
import { CalendarModule } from 'primeng/calendar';
import {MatIconModule} from '@angular/material/icon';
import { MatIconModule } from '@angular/material/icon';
import { InfoComponent } from './pages/info/info.component';
import { MdbCarouselModule } from 'mdb-angular-ui-kit/carousel';
import { StoreModule } from '@ngrx/store';
import { configReducer } from './state/config/config.reducer';
import { EffectsModule } from '@ngrx/effects';
import { ConfigEffects } from './state/config/config.effects';
import {PaginatorModule} from 'primeng/paginator';
import {InputTextModule} from 'primeng/inputtext';
import { PaginatorModule } from 'primeng/paginator';
import { InputTextModule } from 'primeng/inputtext';
import { ChangeQuantityComponent } from './components/change-quantity/change-quantity.component';
import { MenuComponent } from './components/menu/menu.component';
import { SidebarModule } from 'primeng/sidebar';
import {RippleModule} from 'primeng/ripple';
import {MatTabsModule} from '@angular/material/tabs';
import { RippleModule } from 'primeng/ripple';
import { MatTabsModule } from '@angular/material/tabs';
import { ModifierComponent } from './components/modifier/modifier.component';
import { OptionComponent } from './components/option/option.component';
import { ChangeQuantityOptionDirective } from './directives/change-quantity-option.directive';
import {MatSelectModule} from '@angular/material/select';
import {MatFormFieldModule, MAT_FORM_FIELD_DEFAULT_OPTIONS} from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import {
MatFormFieldModule,
MAT_FORM_FIELD_DEFAULT_OPTIONS,
} from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import {MatBottomSheetModule} from '@angular/material/bottom-sheet';
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
import { TerminalListComponent } from './components/terminal-list/terminal-list.component';
import {MatButtonModule} from '@angular/material/button';
import {MatListModule} from '@angular/material/list';
import {MatSnackBarModule} from '@angular/material/snack-bar';
import { MatButtonModule } from '@angular/material/button';
import { MatListModule } from '@angular/material/list';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { SnackBarComponent } from './components/snack-bar/snack-bar.component';
import {MatDialogModule} from '@angular/material/dialog';
import { PurchaseInfoComponent } from './components/purchase-info/purchase-info.component';
const routes: Routes = [
{ path: '', redirectTo: 'products', pathMatch: 'full' },
{ path: 'products', component: ProductsComponent },
// { path: 'cart', component: CartComponent },
{ path: 'account', component: AccountComponent },
{ path: '**', component: NotFoundComponent }
{ path: '**', component: NotFoundComponent },
];
@NgModule({
@ -106,13 +111,14 @@ const routes: Routes = [
OptionComponent,
ChangeQuantityOptionDirective,
TerminalListComponent,
SnackBarComponent
SnackBarComponent,
PurchaseInfoComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
RouterModule.forRoot(routes, {
scrollPositionRestoration: 'enabled'
scrollPositionRestoration: 'enabled',
}),
InputMaskModule,
ProgressSpinnerModule,
@ -124,7 +130,7 @@ const routes: Routes = [
enabled: environment.production,
// Register the ServiceWorker as soon as the application is stable
// or after 30 seconds (whichever comes first).
registrationStrategy: 'registerWhenStable:30000'
registrationStrategy: 'registerWhenStable:30000',
}),
AngularFireModule.initializeApp(environment.firebase),
AngularFireMessagingModule,
@ -132,7 +138,7 @@ const routes: Routes = [
ReactiveFormsModule,
QRCodeModule,
ShareButtonsModule.withConfig({
debug: true
debug: true,
}),
ShareIconsModule,
ListboxModule,
@ -142,7 +148,7 @@ const routes: Routes = [
CalendarModule,
MatIconModule,
MdbCarouselModule,
StoreModule.forRoot({config: configReducer}),
StoreModule.forRoot({ config: configReducer }),
EffectsModule.forRoot([ConfigEffects]),
PaginatorModule,
InputTextModule,
@ -155,9 +161,18 @@ const routes: Routes = [
MatBottomSheetModule,
MatButtonModule,
MatListModule,
MatSnackBarModule
MatSnackBarModule,
MatDialogModule
],
providers: [DialogService, MessageService, MessagingService, {provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: {appearance: 'outline'}} ],
bootstrap: [AppComponent]
providers: [
DialogService,
MessageService,
MessagingService,
{
provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
useValue: { appearance: 'outline' },
},
],
bootstrap: [AppComponent],
})
export class AppModule { }
export class AppModule {}

View File

@ -0,0 +1,34 @@
<h2 mat-dialog-title>{{ moment(purchaseInfo.date).format("DD.MM.YYYY") }}</h2>
<mat-dialog-content>
<table>
<tbody>
<tr
*ngFor="let good of purchaseInfo.goods_list"
class="woocommerce-orders-table__row woocommerce-orders-table__row--status-processing order"
>
<td
class="woocommerce-orders-table__cell woocommerce-orders-table__cell-order-name"
data-title="Название"
>
{{ good.name }}
</td>
<td
class="woocommerce-orders-table__cell woocommerce-orders-table__cell-order-price"
data-title="Цена"
>
{{ good.price }}
</td>
<td
class="woocommerce-orders-table__cell woocommerce-orders-table__cell-order-quantity"
data-title="Количество"
>
{{ good.quantity }}
</td>
</tr>
</tbody>
</table>
</mat-dialog-content>
<mat-dialog-actions>
<span class="amount">Сумма: {{ purchaseInfo.sum }}</span>
<button mat-stroked-button mat-dialog-close>Закрыть</button>
</mat-dialog-actions>

View File

@ -0,0 +1,45 @@
:host {
.woocommerce-orders-table {
&__cell {
padding: 8px 4px;
border-bottom: 2px solid #dee2e6;
text-align: right !important;
display: block;
&::before {
content: attr(data-title) ": ";
font-weight: 700;
float: left;
margin-right: 20px;
}
}
&__row {
display: block;
&:nth-child(even) {
background: #ebebeb;
}
}
// &__cell-order-actions::before {
// display: none;
// }
&__cell-order-actions {
&.red-color {
color: #ed0000;
}
&.green-color {
color: #00a700;
}
}
&__cell-order-number a {
text-decoration: none;
color: #009688;
}
}
}
.amount {
font-weight: 600;
}
.mat-dialog-actions {
justify-content: space-between;
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PurchaseInfoComponent } from './purchase-info.component';
describe('PurchaseInfoComponent', () => {
let component: PurchaseInfoComponent;
let fixture: ComponentFixture<PurchaseInfoComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PurchaseInfoComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(PurchaseInfoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,24 @@
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import moment from 'moment';
import { PurchaseInfo } from 'src/app/interface/data';
@Component({
selector: 'app-purchase-info',
templateUrl: './purchase-info.component.html',
styleUrls: ['./purchase-info.component.scss']
})
export class PurchaseInfoComponent implements OnInit {
public purchaseInfo!: PurchaseInfo;
readonly moment = moment;
constructor(
public dialogRef: MatDialogRef<PurchaseInfoComponent>,
@Inject(MAT_DIALOG_DATA) public data: {purchaseInfo: PurchaseInfo},
) { }
ngOnInit(): void {
this.purchaseInfo = this.data.purchaseInfo
}
}

View File

@ -56,10 +56,25 @@ export interface Purchase {
// ID: string;
// Transactions: Transaction[];
// IsSingleTransaction?: boolean;
orderNumber: number;
transactionCreateDate: string;
orderSum: number;
transactionSum: number;
transactionType: 'CancelPayFromWallet' | 'PayFromWallet' | 'RefillWallet';
more_info: PurchaseInfo | null;
}
export interface PurchaseInfo {
date: string;
goods_list: [
{
name: string;
price: number;
quantity: number;
}
];
number: string;
sum: number;
}
export interface Transaction {
@ -82,10 +97,10 @@ export interface OrderStatus {
}
export interface DeliveryType {
// cost: number;
// title: string;
// id: number;
// type: string;
// cost: number;
// title: string;
// id: number;
// type: string;
name: string;
iikoId: string;
iikoName: string;

View File

@ -57,7 +57,7 @@ export class BonusProgramComponent implements OnInit {
this.loadingBonuses = true;
this.wpJsonService.getCustomerInfo(environment.systemId, token, environment.icardProxy).subscribe({
next: (res) => {
if (res.customer_info.errorCode === 'Customer_CustomerNotFound') {
if (res.customer_info?.errorCode === 'Customer_CustomerNotFound' || 'Error' in res) {
// this._snackBar.open('Пользователь не найден в системе! Обратитесь к руководству', 'Ок')
this.loadingBonuses = false;
return

View File

@ -21,10 +21,15 @@
<span class="nobr">Сумма чека</span>
</th>
<th
class="woocommerce-orders-table__header woocommerce-orders-table__header-order-actions"
class="woocommerce-orders-table__header woocommerce-orders-table__header-order-bonuses"
>
<span class="nobr">Бонусы</span>
</th>
<th
class="woocommerce-orders-table__header woocommerce-orders-table__header-order-actions"
>
<span class="nobr">Действия</span>
</th>
</tr>
</thead>
<tbody>
@ -55,7 +60,7 @@
</span>
</td>
<td
class="woocommerce-orders-table__cell woocommerce-orders-table__cell-order-actions"
class="woocommerce-orders-table__cell woocommerce-orders-table__cell-order-bonuses"
data-title="Бонусы"
[ngClass]="{
'red-color': purchase.transactionSum ? purchase.transactionSum < 0 : false,
@ -64,6 +69,11 @@
>
{{ purchase.transactionSum }}
</td>
<td *ngIf="purchase.more_info" class="woocommerce-orders-table__cell woocommerce-orders-table__cell-order-actions" data-title="Действия">
<button mat-stroked-button (click)="showPurchaseInfo(purchase.more_info)" >
Подробнее
</button>
</td>
</tr>
</tbody>
</table>

View File

@ -16,7 +16,7 @@
text-align: left;
margin-top: 8px;
width: 100%;
max-width: 400px;
// max-width: 400px;
margin-left: auto;
margin-right: auto;
thead {

View File

@ -1,23 +1,23 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Page, Purchase } from 'src/app/interface/data';
import { Page, Purchase, PurchaseInfo } from 'src/app/interface/data';
import * as moment from 'moment-timezone';
import { lastValueFrom } from 'rxjs';
import { JsonrpcService, RpcService } from 'src/app/services/jsonrpc.service';
import { WpJsonService } from 'src/app/services/wp-json.service';
import { environment } from 'src/environments/environment';
import { CookiesService } from 'src/app/services/cookies.service';
import { MatDialog } from '@angular/material/dialog';
import { PurchaseInfoComponent } from 'src/app/components/purchase-info/purchase-info.component';
@Component({
selector: 'app-orders',
templateUrl: './orders.component.html',
styleUrls: ['./orders.component.scss']
styleUrls: ['./orders.component.scss'],
})
export class OrdersComponent implements OnInit {
@Input() currentPage!: Page;
@Input() handleHttpError!: (error: HttpErrorResponse) => void;
@Output() deauthorization = new EventEmitter<boolean>(false)
@Output() deauthorization = new EventEmitter<boolean>(false);
public lastViewOrder: number = 3;
public ordersLoadingStatus: boolean = true;
readonly moment = moment;
@ -25,45 +25,80 @@ export class OrdersComponent implements OnInit {
public purchasesShortArray: Purchase[] = [];
constructor(
private route: ActivatedRoute,
private router: Router,
private jsonrpc: JsonrpcService,
private wpJsonService: WpJsonService,
private cookiesService: CookiesService,
) { }
public dialog: MatDialog
) {}
ngOnInit(): void {
this.getOrders()
this.getOrders();
}
async getOrders() {
const token = this.cookiesService.getItem('token')
const token = this.cookiesService.getItem('token');
if (!token) {
this.cookiesService.deleteCookie('token')
this.deauthorization.emit(true)
return
this.cookiesService.deleteCookie('token');
this.deauthorization.emit(true);
return;
}
const customerInfo = (await lastValueFrom(
this.wpJsonService.getCustomerInfo(environment.systemId, token, environment.icardProxy)
))
if (customerInfo.customer_info.errorCode === 'Customer_CustomerNotFound') {
const customerInfo = await lastValueFrom(
this.wpJsonService.getCustomerInfo(
environment.systemId,
token,
environment.icardProxy
)
);
if (
customerInfo.customer_info?.errorCode === 'Customer_CustomerNotFound' ||
'Error' in customerInfo
) {
this.ordersLoadingStatus = false;
return
return;
}
const purchases: Purchase[] = (await lastValueFrom(
this.wpJsonService.getTransactions(environment.systemId, token, environment.icardProxy, 30)
))[customerInfo.customer_info.id];
const purchases: Purchase[] = (
await lastValueFrom(
this.wpJsonService.getTransactions(
environment.systemId,
token,
environment.icardProxy,
30
)
)
)[customerInfo.customer_info?.id];
this.purchases = purchases.map<Purchase>((purchase) => {
// const id = purchase.ID.slice(0,36).toLowerCase();
// purchase.Transactions = transactions.filter((transaction) => {
// const same = transaction.Purchase === id;
// transaction.HasPurchase = same;
// return same;
// });
return purchase;
}).filter((purchase: Purchase) => ['PayFromWallet', 'CancelPayFromWallet', 'RefillWallet'].includes(purchase.transactionType));
this.purchasesShortArray = this.purchases.slice(0, this.lastViewOrder)
const purchasesInfo: PurchaseInfo[] = (
await lastValueFrom(
this.wpJsonService.getTransactionsInfo(
environment.systemId,
token,
environment.icardProxy,
30
)
)
)['purchase'];
this.purchases = purchases
.map<Purchase>((purchase) => {
// const id = purchase.ID.slice(0,36).toLowerCase();
// purchase.Transactions = transactions.filter((transaction) => {
// const same = transaction.Purchase === id;
// transaction.HasPurchase = same;
// return same;
// });
purchase.more_info =
purchasesInfo.find(
(purchaseInfo: PurchaseInfo) =>
Number(purchaseInfo.number) === purchase.orderNumber
) || null;
return purchase;
})
.filter((purchase: Purchase) =>
['PayFromWallet', 'CancelPayFromWallet', 'RefillWallet'].includes(
purchase.transactionType
)
);
this.purchasesShortArray = this.purchases.slice(0, this.lastViewOrder);
this.ordersLoadingStatus = false;
}
@ -71,4 +106,10 @@ export class OrdersComponent implements OnInit {
this.lastViewOrder += 4;
this.purchasesShortArray = this.purchases.slice(0, this.lastViewOrder);
}
showPurchaseInfo(purchaseInfo: PurchaseInfo) {
const dialogRef = this.dialog.open(PurchaseInfoComponent, {
data: {purchaseInfo},
});
}
}

View File

@ -58,6 +58,10 @@ export class WpJsonService {
return this._request(`trans/${systemId}/${token}/`, 'GET', null, false, url)
}
getTransactionsInfo(systemId: string, token: string, url: string, delta: number): Observable<any> {
return this._request(`purchase/${systemId}/${token}/`, 'GET', null, false, url)
}
getSiteConfig(): Observable<any> {
return this._request(`/assets/site-config.json`, 'GET', null, false)
}