Compare commits
No commits in common. "11119fd9ae8d94dd37ab1c0a95c5b1254e70183d" and "7516eaf11fcd3ec5a423d364d06b2e98f13220ce" have entirely different histories.
11119fd9ae
...
7516eaf11f
53 changed files with 6121 additions and 8750 deletions
69
CHANGELOG.md
69
CHANGELOG.md
|
@ -3,73 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [1.4.1] - 2023-01-09
|
## [Unreleased]
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Display app version
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Copyright year
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Remove unnecessary logging in `fullnode.service.ts`.
|
|
||||||
|
|
||||||
## [1.4.0] - 2023-01-09
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Support for WooComerce:
|
|
||||||
- New tab in Settings to generate authentication token.
|
|
||||||
- Display of WooCommerce credentials for configuration.
|
|
||||||
- New service to interact with WooCommerce-related API endpoints.
|
|
||||||
- A "Return To Shop" button added to ZGo Invoice component
|
|
||||||
|
|
||||||
## [1.3.2] - 2022-10-11
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- New component added to export orders in CSV format. Allows users to download orders.
|
|
||||||
|
|
||||||
## [1.3.1] - 2022-10-08
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Bug [#7](https://gitlab.com/pitmutt/zgo/-/issues/7) for saving a viewing key.
|
|
||||||
|
|
||||||
## [1.3.0] - 2022-10-01
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Added new connection for Xero account code
|
|
||||||
- Added new service for Xero integration
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Login updated to price sessions in USD and include the Pro service.
|
|
||||||
- Settings component updated for compatibility with Android devices
|
|
||||||
- Settings component updated to use observable when saving Account Code
|
|
||||||
- xeroService's saveAccountCode function optimized to export observable
|
|
||||||
- Field for Xero's AccountCode added to Settings component's integration tab
|
|
||||||
- Listorders component updated to show date in ANSI international format.
|
|
||||||
- Settings component updated to use owner's invoices field to control
|
|
||||||
integrations tab (Pro version)
|
|
||||||
- Orders list updated to show payment confirmation only when service is
|
|
||||||
activated and a viewing key exists.
|
|
||||||
- Updated Order and Owner model to include new Xero integration fields
|
|
||||||
|
|
||||||
## [1.2.2] - 2022-08-05
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Convenience buttons on checkout for wallets that are not ZIP-321-compliant
|
|
||||||
- PmtService Component first alpha version ready for testing
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Memo for checkout orders
|
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
|
@ -113,7 +47,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed order memo for checkout
|
|
||||||
- Fixed display of amounts in item list when using *zatoshis*
|
- Fixed display of amounts in item list when using *zatoshis*
|
||||||
- Fixed sorting of items in list
|
- Fixed sorting of items in list
|
||||||
- Fixed sorting of orders in list
|
- Fixed sorting of orders in list
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
"budgets": [
|
"budgets": [
|
||||||
{
|
{
|
||||||
"type": "initial",
|
"type": "initial",
|
||||||
"maximumWarning": "5mb",
|
"maximumWarning": "500kb",
|
||||||
"maximumError": "10mb"
|
"maximumError": "1mb"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "anyComponentStyle",
|
"type": "anyComponentStyle",
|
||||||
|
|
12296
package-lock.json
generated
12296
package-lock.json
generated
File diff suppressed because it is too large
Load diff
80
package.json
80
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "zgo",
|
"name": "zgo",
|
||||||
"version": "1.4.1",
|
"version": "1.2.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
|
@ -10,52 +10,50 @@
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-material-components/datetime-picker": "^9.0.0",
|
"@angular/animations": "^14.0.5",
|
||||||
"@angular/animations": "^15.1.2",
|
"@angular/cdk": "^13.3.9",
|
||||||
"@angular/cdk": "^15.1.2",
|
"@angular/common": "^14.0.5",
|
||||||
"@angular/common": "^15.1.2",
|
"@angular/compiler": "^14.0.5",
|
||||||
"@angular/compiler": "^15.1.2",
|
"@angular/core": "^14.0.5",
|
||||||
"@angular/core": "^15.1.2",
|
"@angular/forms": "^14.0.5",
|
||||||
"@angular/forms": "^15.1.2",
|
"@angular/material": "^13.3.9",
|
||||||
"@angular/material": "^15.1.2",
|
"@angular/platform-browser": "^14.0.5",
|
||||||
"@angular/platform-browser": "^15.1.2",
|
"@angular/platform-browser-dynamic": "^14.0.5",
|
||||||
"@angular/platform-browser-dynamic": "^15.1.2",
|
"@angular/router": "^14.0.5",
|
||||||
"@angular/router": "^15.1.2",
|
"@fortawesome/angular-fontawesome": "^0.10.2",
|
||||||
"@fortawesome/angular-fontawesome": "^0.12.1",
|
"@fortawesome/fontawesome-free": "^6.1.1",
|
||||||
"@fortawesome/fontawesome-free": "^6.2.1",
|
"@fortawesome/fontawesome-svg-core": "^6.1.0",
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.2.1",
|
"@fortawesome/free-brands-svg-icons": "^6.1.0",
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.2.1",
|
"@fortawesome/free-regular-svg-icons": "^6.1.0",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.2.1",
|
"@fortawesome/free-solid-svg-icons": "^6.1.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.2.1",
|
"@supercharge/request-ip": "^1.1.2",
|
||||||
"@supercharge/request-ip": "^1.2.0",
|
|
||||||
"angular-local-storage": "^0.7.1",
|
"angular-local-storage": "^0.7.1",
|
||||||
"angular-material-datepicker": "^1.0.2",
|
"async": "^3.2.2",
|
||||||
"async": "^3.2.4",
|
|
||||||
"coingecko-api": "^1.0.10",
|
"coingecko-api": "^1.0.10",
|
||||||
"easyqrcodejs": "^4.4.13",
|
"easyqrcodejs": "^4.4.6",
|
||||||
"material-design-icons": "^3.0.1",
|
"material-design-icons": "^3.0.1",
|
||||||
"rxjs": "~7.8.0",
|
"mongoose": "^6.0.13",
|
||||||
"sha.js": "^2.4.11",
|
"rxjs": "~6.6.0",
|
||||||
"tslib": "^2.5.0",
|
"stdrpc": "^1.3.0",
|
||||||
|
"tslib": "^2.3.0",
|
||||||
"urlsafe-base64": "^1.0.0",
|
"urlsafe-base64": "^1.0.0",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^8.3.2",
|
||||||
"zone.js": "~0.12.0"
|
"zone.js": "~0.11.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^15.1.3",
|
"@angular-devkit/build-angular": "^14.0.5",
|
||||||
"@angular/cli": "^15.1.3",
|
"@angular/cli": "^14.0.6",
|
||||||
"@angular/compiler-cli": "^15.1.2",
|
"@angular/compiler-cli": "^14.0.5",
|
||||||
"@types/jasmine": "~4.3.1",
|
"@types/jasmine": "~3.8.0",
|
||||||
"@types/node": "^18.11.18",
|
"@types/node": "^12.20.33",
|
||||||
"@types/request": "^2.48.8",
|
|
||||||
"@types/urlsafe-base64": "^1.0.28",
|
"@types/urlsafe-base64": "^1.0.28",
|
||||||
"@types/uuid": "^9.0.0",
|
"@types/uuid": "^8.3.1",
|
||||||
"jasmine-core": "~4.5.0",
|
"jasmine-core": "~3.8.0",
|
||||||
"karma": "~6.4.1",
|
"karma": "~6.3.0",
|
||||||
"karma-chrome-launcher": "~3.1.1",
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
"karma-coverage": "~2.2.0",
|
"karma-coverage": "~2.0.3",
|
||||||
"karma-jasmine": "~5.1.0",
|
"karma-jasmine": "~4.0.0",
|
||||||
"karma-jasmine-html-reporter": "~2.0.0",
|
"karma-jasmine-html-reporter": "~1.7.0",
|
||||||
"typescript": "~4.9.4"
|
"typescript": "~4.7.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { ListOrdersComponent } from './listorders/listorders.component';
|
||||||
import { AuthGuardService } from './auth-guard.service';
|
import { AuthGuardService } from './auth-guard.service';
|
||||||
import { NodeResolverService } from './node-resolver.service';
|
import { NodeResolverService } from './node-resolver.service';
|
||||||
import { PmtserviceComponent } from './pmtservice/pmtservice.component';
|
import { PmtserviceComponent } from './pmtservice/pmtservice.component';
|
||||||
import { XeroRegComponent } from './xeroreg/xeroreg.component';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', component: LoginComponent, resolve: { response: NodeResolverService} },
|
{ path: '', component: LoginComponent, resolve: { response: NodeResolverService} },
|
||||||
|
@ -20,7 +19,6 @@ const routes: Routes = [
|
||||||
{ path: 'receipt/:orderId', component: ReceiptComponent},
|
{ path: 'receipt/:orderId', component: ReceiptComponent},
|
||||||
{ path: 'invoice/:orderId', component: InvoiceComponent},
|
{ path: 'invoice/:orderId', component: InvoiceComponent},
|
||||||
{ path: 'pmtservice', component: PmtserviceComponent},
|
{ path: 'pmtservice', component: PmtserviceComponent},
|
||||||
{ path: 'xeroauth', component: XeroRegComponent},
|
|
||||||
{ path: 'login', component: LoginComponent, resolve: { response: NodeResolverService}}
|
{ path: 'login', component: LoginComponent, resolve: { response: NodeResolverService}}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
</main>
|
</main>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<div class="footer" align="center">
|
<div class="footer" align="center">
|
||||||
<p>© 2023 Vergara Technologies LLC</p>
|
<p>© 2022 Vergara Technologies LLC</p>
|
||||||
<p class="tiny">Version 1.4.1</p>
|
|
||||||
<p class="tiny">Price data provided by CoinGecko API</p>
|
<p class="tiny">Price data provided by CoinGecko API</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,9 +17,6 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
import { MatStepperModule } from '@angular/material/stepper';
|
import { MatStepperModule } from '@angular/material/stepper';
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
import { MatTabsModule } from '@angular/material/tabs';
|
|
||||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
|
||||||
import { MatNativeDateModule } from '@angular/material/core';
|
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
@ -49,8 +46,6 @@ import { PromptInvoiceComponent } from './prompt-invoice/prompt-invoice.componen
|
||||||
import { PromptReceiptComponent } from './prompt-receipt/prompt-receipt.component';
|
import { PromptReceiptComponent } from './prompt-receipt/prompt-receipt.component';
|
||||||
import { NotifierComponent } from './notifier/notifier.component';
|
import { NotifierComponent } from './notifier/notifier.component';
|
||||||
import { PmtserviceComponent } from './pmtservice/pmtservice.component';
|
import { PmtserviceComponent } from './pmtservice/pmtservice.component';
|
||||||
import { XeroRegComponent } from './xeroreg/xeroreg.component';
|
|
||||||
import { DbExportComponent } from './db-export/db-export.component';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -78,9 +73,7 @@ import { DbExportComponent } from './db-export/db-export.component';
|
||||||
PromptInvoiceComponent,
|
PromptInvoiceComponent,
|
||||||
PromptReceiptComponent,
|
PromptReceiptComponent,
|
||||||
NotifierComponent,
|
NotifierComponent,
|
||||||
PmtserviceComponent,
|
PmtserviceComponent
|
||||||
XeroRegComponent,
|
|
||||||
DbExportComponent
|
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -103,9 +96,6 @@ import { DbExportComponent } from './db-export/db-export.component';
|
||||||
MatAutocompleteModule,
|
MatAutocompleteModule,
|
||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
MatTabsModule,
|
|
||||||
MatDatepickerModule,
|
|
||||||
MatNativeDateModule,
|
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
FontAwesomeModule
|
FontAwesomeModule
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
|
||||||
import { UntypedFormBuilder, Validators, UntypedFormGroup } from '@angular/forms';
|
import { UntypedFormBuilder, Validators, UntypedFormGroup, FormControl } from '@angular/forms';
|
||||||
import { MatDialog, MatDialogConfig} from '@angular/material/dialog';
|
import { MatDialog, MatDialogConfig} from '@angular/material/dialog';
|
||||||
import { ProgressBarMode } from '@angular/material/progress-bar';
|
import { ProgressBarMode } from '@angular/material/progress-bar';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
import { filter, startWith, map, switchMap } from 'rxjs/operators';
|
||||||
import { MatStepper } from '@angular/material/stepper';
|
import { MatStepper } from '@angular/material/stepper';
|
||||||
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
|
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
|
||||||
import { Country } from '../country.model';
|
import { Country } from '../country.model';
|
||||||
|
@ -11,6 +12,7 @@ import { Owner } from '../owner.model';
|
||||||
import { User } from '../user.model';
|
import { User } from '../user.model';
|
||||||
import { UserService } from '../user.service';
|
import { UserService } from '../user.service';
|
||||||
import { FullnodeService } from '../fullnode.service';
|
import { FullnodeService } from '../fullnode.service';
|
||||||
|
import { SearchOptionsPipe } from '../searchoptions.pipe';
|
||||||
import { ScanComponent } from '../scan/scan.component';
|
import { ScanComponent } from '../scan/scan.component';
|
||||||
import { TermsComponent } from '../terms/terms.component';
|
import { TermsComponent } from '../terms/terms.component';
|
||||||
|
|
||||||
|
@ -24,20 +26,16 @@ export class BusinessComponent implements OnInit {
|
||||||
@ViewChild('stepper', { static: false}) stepper: MatStepper|undefined;
|
@ViewChild('stepper', { static: false}) stepper: MatStepper|undefined;
|
||||||
intervalHolder: any;
|
intervalHolder: any;
|
||||||
nodeAddress: string = '';
|
nodeAddress: string = '';
|
||||||
zecPrice: number = 1;
|
|
||||||
tickets = [
|
tickets = [
|
||||||
{
|
{
|
||||||
value: 1,
|
value: 0.005,
|
||||||
viewValue: '1 day: USD $1'
|
viewValue: '1 day: 0.005 ZEC'
|
||||||
},{
|
},{
|
||||||
value: 6,
|
value: 0.025,
|
||||||
viewValue: '1 week: USD $6'
|
viewValue: '1 week: 0.025 ZEC'
|
||||||
},{
|
},{
|
||||||
value: 22,
|
value: 0.1,
|
||||||
viewValue: '1 month: USD $22'
|
viewValue: '1 month: 0.1 ZEC'
|
||||||
},{
|
|
||||||
value: 30,
|
|
||||||
viewValue: '1 month Pro: USD $30'
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
bizForm: UntypedFormGroup;
|
bizForm: UntypedFormGroup;
|
||||||
|
@ -76,7 +74,6 @@ export class BusinessComponent implements OnInit {
|
||||||
public ownerUpdate: Observable<Owner>;
|
public ownerUpdate: Observable<Owner>;
|
||||||
public addrUpdate: Observable<string>;
|
public addrUpdate: Observable<string>;
|
||||||
public userUpdate: Observable<User>;
|
public userUpdate: Observable<User>;
|
||||||
public priceUpdate: Observable<number>;
|
|
||||||
sessionId = '';
|
sessionId = '';
|
||||||
ownerKnown = false;
|
ownerKnown = false;
|
||||||
termsChecked = false;
|
termsChecked = false;
|
||||||
|
@ -88,10 +85,6 @@ export class BusinessComponent implements OnInit {
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
private router: Router
|
private router: Router
|
||||||
) {
|
) {
|
||||||
this.priceUpdate = fullnodeService.priceUpdate;
|
|
||||||
this.priceUpdate.subscribe(priceInfo => {
|
|
||||||
this.zecPrice = priceInfo;
|
|
||||||
});
|
|
||||||
this.countriesUpdate = userService.countriesUpdate;
|
this.countriesUpdate = userService.countriesUpdate;
|
||||||
this.ownerUpdate = userService.ownerUpdate;
|
this.ownerUpdate = userService.ownerUpdate;
|
||||||
this.userUpdate = userService.userUpdate;
|
this.userUpdate = userService.userUpdate;
|
||||||
|
@ -196,7 +189,7 @@ export class BusinessComponent implements OnInit {
|
||||||
dialogConfig.disableClose = true;
|
dialogConfig.disableClose = true;
|
||||||
dialogConfig.autoFocus = true;
|
dialogConfig.autoFocus = true;
|
||||||
dialogConfig.data = {
|
dialogConfig.data = {
|
||||||
totalZec: (this.payForm.get('session')!.value)/this.zecPrice,
|
totalZec: this.payForm.get('session')!.value,
|
||||||
addr: this.nodeAddress,
|
addr: this.nodeAddress,
|
||||||
session: this.sessionId,
|
session: this.sessionId,
|
||||||
pay: true
|
pay: true
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<div class="container" style="font-family: 'Spartan', sans-serif;
|
<div class="container" style="margin-top: 10px;">
|
||||||
margin-top: 10px;">
|
|
||||||
|
|
||||||
<div class="askPayment">
|
<div class="askPayment">
|
||||||
Scan to make payment
|
Scan to make payment
|
||||||
|
@ -15,7 +14,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div style="margin-top: 10px;">
|
<mat-dialog-actions>
|
||||||
<table cellspacing="0"
|
<table cellspacing="0"
|
||||||
width="100%">
|
width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -33,31 +32,6 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</mat-dialog-actions>
|
||||||
<div style="text-align: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
line-height: 30px;">
|
|
||||||
|
|
||||||
Can't scan?<br>Use this <a [href]="zcashUrl">wallet link</a>, or
|
|
||||||
<div style="display: flex;
|
|
||||||
justify-content: space-between;">
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightgray;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="copyAddress()">Copy Address</button>
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightgray;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="copyAmount()">Copy Amount</button>
|
|
||||||
</div>
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightgray;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="copyMemo()">Copy Memo</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,8 +2,6 @@ import { Inject, Component, OnInit, ViewEncapsulation} from '@angular/core';
|
||||||
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
||||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
||||||
|
|
||||||
import { NotifierService } from '../notifier.service';
|
|
||||||
|
|
||||||
var QRCode = require('easyqrcodejs');
|
var QRCode = require('easyqrcodejs');
|
||||||
var URLSafeBase64 = require('urlsafe-base64');
|
var URLSafeBase64 = require('urlsafe-base64');
|
||||||
var Buffer = require('buffer/').Buffer;
|
var Buffer = require('buffer/').Buffer;
|
||||||
|
@ -24,14 +22,13 @@ export class CheckoutComponent implements OnInit{
|
||||||
constructor(
|
constructor(
|
||||||
private dialogRef: MatDialogRef<CheckoutComponent>,
|
private dialogRef: MatDialogRef<CheckoutComponent>,
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: { totalZec: number, addr: string, orderId: string},
|
@Inject(MAT_DIALOG_DATA) public data: { totalZec: number, addr: string, orderId: string}
|
||||||
private notifierService : NotifierService ) {
|
) {
|
||||||
|
|
||||||
console.log("Entra a Constructor")
|
console.log("Entra a Constructor")
|
||||||
this.address = data.addr;
|
this.address = data.addr;
|
||||||
this.total = data.totalZec;
|
this.total = data.totalZec;
|
||||||
this.orderId = data.orderId;
|
this.orderId = data.orderId;
|
||||||
this.codeString = `zcash:${this.address}?amount=${this.total.toFixed(8)}&memo=${URLSafeBase64.encode(Buffer.from('ZGo Order::'.concat(this.orderId)))}`;
|
this.codeString = `zcash:${this.address}?amount=${this.total.toFixed(6)}&memo=${URLSafeBase64.encode(Buffer.from('Z-Go Order '.concat(this.orderId)))}`;
|
||||||
this.zcashUrl = this.sanitizer.bypassSecurityTrustUrl(this.codeString);
|
this.zcashUrl = this.sanitizer.bypassSecurityTrustUrl(this.codeString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +37,8 @@ export class CheckoutComponent implements OnInit{
|
||||||
{
|
{
|
||||||
text: this.codeString,
|
text: this.codeString,
|
||||||
logo: "/assets/zcash.png",
|
logo: "/assets/zcash.png",
|
||||||
width: 230,
|
width: 220,
|
||||||
height: 230,
|
height: 220,
|
||||||
logoWidth: 60,
|
logoWidth: 60,
|
||||||
logoHeight: 60,
|
logoHeight: 60,
|
||||||
correctLevel: QRCode.CorrectLevel.H
|
correctLevel: QRCode.CorrectLevel.H
|
||||||
|
@ -57,48 +54,4 @@ export class CheckoutComponent implements OnInit{
|
||||||
close() {
|
close() {
|
||||||
this.dialogRef.close(false);
|
this.dialogRef.close(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyAddress() {
|
|
||||||
if (!navigator.clipboard) {
|
|
||||||
// alert("Copy functionality not supported");
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Copy functionality not supported","Close","error");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText(this.address);
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Error copying address","Close","error");
|
|
||||||
// console.error("Error", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
copyAmount() {
|
|
||||||
if (!navigator.clipboard) {
|
|
||||||
// alert("Copy functionality not supported");
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Copy functionality not supported","Close","error");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText(this.total.toString());
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Error while copying ammount","Close","error");
|
|
||||||
// console.error("Error", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copyMemo() {
|
|
||||||
if (!navigator.clipboard) {
|
|
||||||
// alert("Copy functionality not supported");
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Copy functionality not supported","Close","error");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText("ZGo Order::" + this.orderId);
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Error while copying Memo","Close","error");
|
|
||||||
// console.error("Error", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
* {
|
|
||||||
font-family: 'Spartan', sans-serif;
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
padding-top: 30px;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 700;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.datepicker {
|
|
||||||
border-color: dimgray;
|
|
||||||
border-width: 3px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.noorders {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 700;
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 20px;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
border-color: dimgray;
|
|
||||||
border-width: 3px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: #f9e79f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-title {
|
|
||||||
font-family: 'Spartan', sans-serif;
|
|
||||||
background: #ff5722;
|
|
||||||
color: white;
|
|
||||||
font-size: 30px;
|
|
||||||
text-align: center;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.daterange {
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 700;
|
|
||||||
padding-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.downloadbtn {
|
|
||||||
min-width: 120px;
|
|
||||||
max-width: 150px;
|
|
||||||
height: 25px;
|
|
||||||
border-color: dimgray;
|
|
||||||
border-width: 3px;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: lightgray;
|
|
||||||
font-family: 'Spartan', sans-serif;
|
|
||||||
background: #ff5722;
|
|
||||||
color: white;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: center;
|
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .downloadbtntxt {
|
|
||||||
color: white;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
<div class="settings-title">Export Orders</div>
|
|
||||||
<div class='description'>
|
|
||||||
Export orders in a .CSV format file
|
|
||||||
</div>
|
|
||||||
<div class="datepicker"
|
|
||||||
*ngIf="ordersOk()">
|
|
||||||
<mat-form-field appearance="fill">
|
|
||||||
<!--
|
|
||||||
<mat-label >Enter a date range</mat-label>
|
|
||||||
-->
|
|
||||||
<div class="daterange">Date range:</div>
|
|
||||||
<mat-date-range-input [formGroup]="range" [rangePicker]="picker">
|
|
||||||
<input matStartDate formControlName="start" placeholder="Start date">
|
|
||||||
<input matEndDate formControlName="end" placeholder="End date">
|
|
||||||
</mat-date-range-input>
|
|
||||||
<mat-hint>MM/DD/YYYY – MM/DD/YYYY</mat-hint>
|
|
||||||
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
|
|
||||||
<mat-date-range-picker #picker></mat-date-range-picker>
|
|
||||||
|
|
||||||
<mat-error *ngIf="range.controls.start.hasError('matStartDateInvalid')">Invalid start date</mat-error>
|
|
||||||
<mat-error *ngIf="range.controls.end.hasError('matEndDateInvalid')">Invalid end date</mat-error>
|
|
||||||
</mat-form-field>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="noorders"
|
|
||||||
*ngIf="!ordersOk()">
|
|
||||||
<br>
|
|
||||||
You have no orders created.
|
|
||||||
<br>
|
|
||||||
Nothing to do.
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<div style="display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;">
|
|
||||||
<button mat-raised-button
|
|
||||||
(click)="closedbExport()">
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<a mat-raised-button *ngIf="checkReady()" color="primary" [href]="fileUrl"
|
|
||||||
download="orders.csv">Download</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div style="height: 20px;
|
|
||||||
margin-top: 10px;">
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { DbExportComponent } from './db-export.component';
|
|
||||||
|
|
||||||
describe('DbExportComponent', () => {
|
|
||||||
let component: DbExportComponent;
|
|
||||||
let fixture: ComponentFixture<DbExportComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ DbExportComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(DbExportComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,146 +0,0 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { FormGroup, FormControl } from '@angular/forms';
|
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
|
||||||
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { Order } from '../order/order.model';
|
|
||||||
import { FullnodeService } from '../fullnode.service';
|
|
||||||
import { UserService } from '../user.service';
|
|
||||||
import { Owner } from '../owner.model';
|
|
||||||
import { OrderService } from '../order/order.service';
|
|
||||||
import { NotifierService } from '../notifier.service';
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-db-export',
|
|
||||||
templateUrl: './db-export.component.html',
|
|
||||||
styleUrls: ['./db-export.component.css']
|
|
||||||
})
|
|
||||||
|
|
||||||
export class DbExportComponent implements OnInit {
|
|
||||||
|
|
||||||
public orders: Order[] = [];
|
|
||||||
public ownerUpdate: Observable<Owner>;
|
|
||||||
public ordersUpdate: Observable<Order[]>;
|
|
||||||
fileUrl : any;
|
|
||||||
owner : Owner = {
|
|
||||||
address: '',
|
|
||||||
name: '',
|
|
||||||
currency: 'usd',
|
|
||||||
tax: false,
|
|
||||||
taxValue: 0,
|
|
||||||
vat: false,
|
|
||||||
vatValue: 0,
|
|
||||||
first: '',
|
|
||||||
last: '',
|
|
||||||
email: '',
|
|
||||||
street: '',
|
|
||||||
city: '',
|
|
||||||
state: '',
|
|
||||||
postal: '',
|
|
||||||
phone: '',
|
|
||||||
paid: false,
|
|
||||||
website: '',
|
|
||||||
country: '',
|
|
||||||
zats: false,
|
|
||||||
invoices: false,
|
|
||||||
expiration: new Date(Date.now()).toISOString(),
|
|
||||||
payconf: false,
|
|
||||||
viewkey: '',
|
|
||||||
crmToken: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
_ordersOk = false;
|
|
||||||
|
|
||||||
range = new FormGroup({
|
|
||||||
start: new FormControl<Date | null>(null),
|
|
||||||
end: new FormControl<Date | null>(null),
|
|
||||||
});
|
|
||||||
|
|
||||||
constructor(private notifierService : NotifierService,
|
|
||||||
private dialogRef: MatDialogRef<DbExportComponent>,
|
|
||||||
private sanitizer: DomSanitizer,
|
|
||||||
public orderService: OrderService,
|
|
||||||
public userService: UserService) {
|
|
||||||
this.ownerUpdate = userService.ownerUpdate;
|
|
||||||
this.orderService.getAllOrders();
|
|
||||||
this.ordersUpdate = orderService.allOrdersUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
console.log('db-export Init -->');
|
|
||||||
this.owner = this.userService.currentOwner();
|
|
||||||
console.log(this.owner.name);
|
|
||||||
console.log(this.range);
|
|
||||||
this.ordersUpdate.subscribe((orders) => {
|
|
||||||
this.orders = orders;
|
|
||||||
// console.log('Order -> ' + this.orders[0].timestamp);
|
|
||||||
if( this.orders.length != 0 ) {
|
|
||||||
this._ordersOk = true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ordersOk() : boolean {
|
|
||||||
return this._ordersOk;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkReady() : boolean {
|
|
||||||
var data : string = '';
|
|
||||||
var chkRdy : boolean = false;
|
|
||||||
if ( (this.range.value.start != null ) &&
|
|
||||||
(this.range.value.end != null) ) {
|
|
||||||
// process order list
|
|
||||||
const formatter = new Intl.NumberFormat('en-US', {
|
|
||||||
minimumFractionDigits: 8,
|
|
||||||
maximumFractionDigits: 8,
|
|
||||||
});
|
|
||||||
|
|
||||||
// create header
|
|
||||||
data = '"Date","Order ID","Currency","Closed?","Amount","Rate","ZEC","Paid?","Invoice"' + "\n";
|
|
||||||
|
|
||||||
var iniDate = new Date(this.range.value.start);
|
|
||||||
var endDate = new Date(this.range.value.end);
|
|
||||||
for (let i=0; i < this.orders.length; i++){
|
|
||||||
var date = new Date(this.orders[i]!.timestamp!);
|
|
||||||
var orderid = String(this.orders[i]._id);
|
|
||||||
var closed = this.orders[i].closed ? 'Yes' : 'No';
|
|
||||||
/*
|
|
||||||
console.log('Order No. ' +
|
|
||||||
this.orders[i]._id! + ' - totalZec = ' +
|
|
||||||
this.orders[i].totalZec);
|
|
||||||
*/
|
|
||||||
var paid = this.orders[i].paid ? 'Yes' : 'No';
|
|
||||||
if ( (date >= iniDate) && (date <= endDate) ) {
|
|
||||||
data = data +
|
|
||||||
date.getFullYear() + '-' +
|
|
||||||
(date.getMonth()+1).toString().padStart(2,'0') + '-' +
|
|
||||||
date.getDate().toString().padStart(2,'0')
|
|
||||||
+ ',' +
|
|
||||||
orderid + ',' +
|
|
||||||
this.orders[i].currency + ',' +
|
|
||||||
closed + ',' +
|
|
||||||
this.orders[i].total + ',' +
|
|
||||||
this.orders[i].price! + ',' +
|
|
||||||
this.orders[i].totalZec + ',' +
|
|
||||||
paid + ',"' +
|
|
||||||
this.orders[i].externalInvoice + '"' +
|
|
||||||
'\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const blob = new Blob([data], { type: 'application/octet-stream' });
|
|
||||||
this.fileUrl = this.sanitizer.bypassSecurityTrustResourceUrl(window.URL.createObjectURL(blob));
|
|
||||||
|
|
||||||
chkRdy = true;
|
|
||||||
}
|
|
||||||
return chkRdy;
|
|
||||||
}
|
|
||||||
|
|
||||||
closedbExport() {
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
<mat-toolbar color="primary">
|
<mat-toolbar color="primary">
|
||||||
<span align="center">
|
<span align="center">
|
||||||
<img class="logo" src="/assets/logo-new-white_01.png" height="40px" />
|
<img class="logo" src="/assets/logo-new-white.png" height="40px" />
|
||||||
</span>
|
</span>
|
||||||
<span class="spacer"></span>
|
<span class="spacer"></span>
|
||||||
<span align="center">
|
<span align="center">
|
||||||
|
@ -9,6 +9,6 @@
|
||||||
<p class="mini text">{{heightUpdate | async}}</p>
|
<p class="mini text">{{heightUpdate | async}}</p>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<button mat-icon-button (click)="logout()"><mat-icon>logout</mat-icon></button>
|
<button mat-raised-button (click)="logout()"><mat-icon class="logbutton">logout</mat-icon></button>
|
||||||
</span>
|
</span>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
|
|
|
@ -88,65 +88,6 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<div style="height: 15px;"></div>
|
|
||||||
<div width="100%"
|
|
||||||
style="font-size: 14px;
|
|
||||||
font-weight: 700;
|
|
||||||
font-style: italic;
|
|
||||||
text-align: center;">
|
|
||||||
Scan the QR code with your wallet to make payment
|
|
||||||
</div>
|
|
||||||
<div style="text-align: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
line-height: 30px;">
|
|
||||||
<div style="font-family: 'Spartan';
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;">
|
|
||||||
Can't scan?<br>Use this <a [href]="zcashUrl">wallet link</a>, or
|
|
||||||
</div>
|
|
||||||
<div style="display: flex;
|
|
||||||
justify-content: space-between;">
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightgray;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="copyAddress()">Copy Address</button>
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightgray;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="copyAmount()">Copy Amount</button>
|
|
||||||
</div>
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightgray;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="copyMemo()" *ngIf="!isWCOrder">Copy Memo</button>
|
|
||||||
|
|
||||||
<div style="display: flex;
|
|
||||||
justify-content: space-between;"
|
|
||||||
*ngIf="isWCOrder">
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightgray;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="copyMemo()">Copy Memo</button>
|
|
||||||
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightcyan;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="backToShop()" >
|
|
||||||
<fa-icon style="color: #FB4F14;
|
|
||||||
margin-bottom: -2px;
|
|
||||||
margin-right: 5px;
|
|
||||||
font-size: 20px;
|
|
||||||
cursor: pointer;"
|
|
||||||
[icon]="faArrowUpRightFromSquare"> </fa-icon>
|
|
||||||
Return to Shop</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
|
||||||
import { ReceiptService } from '../receipt.service';
|
import { ReceiptService } from '../receipt.service';
|
||||||
import { Order} from '../order/order.model';
|
import { Order} from '../order/order.model';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { faCheck, faHourglass, faArrowUpRightFromSquare } from '@fortawesome/free-solid-svg-icons';
|
import { faCheck, faHourglass } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
import { NotifierService } from '../notifier.service';
|
|
||||||
|
|
||||||
var QRCode = require('easyqrcodejs');
|
var QRCode = require('easyqrcodejs');
|
||||||
var URLSafeBase64 = require('urlsafe-base64');
|
var URLSafeBase64 = require('urlsafe-base64');
|
||||||
|
@ -17,22 +14,17 @@ var Buffer = require('buffer/').Buffer;
|
||||||
templateUrl: './invoice.component.html',
|
templateUrl: './invoice.component.html',
|
||||||
styleUrls: ['./invoice.component.css']
|
styleUrls: ['./invoice.component.css']
|
||||||
})
|
})
|
||||||
|
|
||||||
export class InvoiceComponent implements OnInit {
|
export class InvoiceComponent implements OnInit {
|
||||||
faCheck = faCheck;
|
faCheck = faCheck;
|
||||||
faHourglass = faHourglass;
|
faHourglass = faHourglass;
|
||||||
faArrowUpRightFromSquare = faArrowUpRightFromSquare;
|
|
||||||
orderId;
|
orderId;
|
||||||
public orderUpdate: Observable<Order>;
|
public orderUpdate: Observable<Order>;
|
||||||
public nameUpdate: Observable<string>;
|
public nameUpdate: Observable<string>;
|
||||||
name: string = '';
|
name: string = '';
|
||||||
error: boolean = false;
|
error: boolean = false;
|
||||||
codeString: string = 'Test';
|
codeString: string = 'Test';
|
||||||
public isWCOrder : boolean = false;
|
|
||||||
zcashUrl: SafeUrl = '';
|
|
||||||
externalURL: string = '';
|
|
||||||
order:Order = {
|
order:Order = {
|
||||||
_id: '',
|
|
||||||
address: '',
|
address: '',
|
||||||
session: '',
|
session: '',
|
||||||
timestamp: '',
|
timestamp: '',
|
||||||
|
@ -56,12 +48,9 @@ export class InvoiceComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private _ActiveRoute:ActivatedRoute,
|
private _ActiveRoute:ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private sanitizer: DomSanitizer,
|
public receiptService: ReceiptService
|
||||||
public receiptService: ReceiptService,
|
|
||||||
private notifierService : NotifierService
|
|
||||||
) {
|
) {
|
||||||
this.orderId = this._ActiveRoute.snapshot.paramMap.get("orderId");
|
this.orderId = this._ActiveRoute.snapshot.paramMap.get("orderId");
|
||||||
console.log('constructor - orderId -> ' + this.orderId);
|
|
||||||
this.orderUpdate = receiptService.orderUpdate;
|
this.orderUpdate = receiptService.orderUpdate;
|
||||||
this.nameUpdate = receiptService.nameUpdate;
|
this.nameUpdate = receiptService.nameUpdate;
|
||||||
receiptService.getOrderById(this.orderId!).subscribe(response => {
|
receiptService.getOrderById(this.orderId!).subscribe(response => {
|
||||||
|
@ -77,7 +66,6 @@ export class InvoiceComponent implements OnInit {
|
||||||
logoHeight: 50,
|
logoHeight: 50,
|
||||||
correctLevel: QRCode.CorrectLevel.H
|
correctLevel: QRCode.CorrectLevel.H
|
||||||
});
|
});
|
||||||
this.error = false;
|
|
||||||
} else {
|
} else {
|
||||||
this.error = true;
|
this.error = true;
|
||||||
this.codeString = 'Test';
|
this.codeString = 'Test';
|
||||||
|
@ -85,11 +73,6 @@ export class InvoiceComponent implements OnInit {
|
||||||
});
|
});
|
||||||
this.orderUpdate.subscribe(order => {
|
this.orderUpdate.subscribe(order => {
|
||||||
this.order = order;
|
this.order = order;
|
||||||
if ( order.session.substring(0,1) == 'W') {
|
|
||||||
this.isWCOrder = true;
|
|
||||||
}
|
|
||||||
this.codeString = `zcash:${this.order.address}?amount=${this.order.totalZec.toFixed(8)}&memo=${URLSafeBase64.encode(Buffer.from('ZGo Order::'.concat(this.orderId!)))}`;
|
|
||||||
this.zcashUrl = this.sanitizer.bypassSecurityTrustUrl(this.codeString);
|
|
||||||
});
|
});
|
||||||
this.nameUpdate.subscribe(name => {
|
this.nameUpdate.subscribe(name => {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -99,25 +82,6 @@ export class InvoiceComponent implements OnInit {
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
backToShop() {
|
|
||||||
if ( this.isWCOrder ) {
|
|
||||||
// console.log('External Invoice -> ' + this.order.externalInvoice );
|
|
||||||
const b64URL:string = this.order.externalInvoice.substring(0,this.order.externalInvoice.indexOf("-"));
|
|
||||||
// console.log('encodedURL -> ' + b64URL );
|
|
||||||
const shopURL: string = Buffer.from(b64URL, 'base64').toString();
|
|
||||||
const tmp_orderid = this.order.externalInvoice.substring(this.order.externalInvoice.indexOf('-')+1);
|
|
||||||
const wc_order_key = tmp_orderid.substring(tmp_orderid.indexOf('-')+1);
|
|
||||||
const wc_orderid = tmp_orderid.substring(0,tmp_orderid.indexOf('-'));
|
|
||||||
// console.log('wc_order_id -> ' + wc_orderid);
|
|
||||||
// console.log('wc_order_key -> ' + wc_order_key);
|
|
||||||
// console.log('new URL -> ' + shopURL + '/checkout/order-received/' + wc_orderid + '/?key=' + wc_order_key);
|
|
||||||
if ( shopURL ) {
|
|
||||||
// console.log('Opening URL....' + shopURL);
|
|
||||||
window.open( shopURL + '/checkout/order-received/' + wc_orderid + '/?key=' + wc_order_key,"_blank");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getIconStyle(order : Order) {
|
getIconStyle(order : Order) {
|
||||||
if( order.paid )
|
if( order.paid )
|
||||||
return "font-size: 14px; color: #72cc50; margin-bottom: -2px;";
|
return "font-size: 14px; color: #72cc50; margin-bottom: -2px;";
|
||||||
|
@ -125,49 +89,4 @@ export class InvoiceComponent implements OnInit {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
copyAddress() {
|
|
||||||
if (!navigator.clipboard) {
|
|
||||||
// alert("Copy functionality not supported");
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Copy functionality not supported","Close","error");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText(this.order.address);
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Error copying address","Close","error");
|
|
||||||
// console.error("Error", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copyAmount() {
|
|
||||||
if (!navigator.clipboard) {
|
|
||||||
// alert("Copy functionality not supported");
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Copy functionality not supported","Close","error");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText(this.order.totalZec.toString());
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Error while copying ammount","Close","error");
|
|
||||||
// console.error("Error", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copyMemo() {
|
|
||||||
if (!navigator.clipboard) {
|
|
||||||
// alert("Copy functionality not supported");
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Copy functionality not supported","Close","error");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText("ZGo Order::" + this.order._id);
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Error while copying Memo","Close","error");
|
|
||||||
// console.error("Error", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
<div *ngIf="items.length > 0">
|
<div *ngIf="items.length > 0">
|
||||||
<mat-toolbar color="accent">
|
<div class="availableItems" >
|
||||||
<span align="center" class="text">
|
|
||||||
Available Items:
|
Available Items:
|
||||||
</span>
|
<button mat-raised-button
|
||||||
<span class="spacer"></span>
|
class="buttons-class"
|
||||||
<span align="center">
|
|
||||||
<button mat-icon-button
|
|
||||||
color="primary"
|
|
||||||
(click)="openDialog()">
|
(click)="openDialog()">
|
||||||
<mat-icon aria-button-label="Add Item">
|
<mat-icon class="icon">
|
||||||
add
|
add
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
|
Add item
|
||||||
</button>
|
</button>
|
||||||
</span>
|
|
||||||
</mat-toolbar>
|
</div>
|
||||||
<div style="display: block;
|
<div style="display: block;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
height: 500px;">
|
height: 500px;">
|
||||||
|
@ -57,18 +54,18 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<button mat-icon-button class="icons" (click)="edit(item._id!)">
|
<button mat-icon-button class="icons" (click)="edit(item._id!)">
|
||||||
<mat-icon>edit</mat-icon>
|
<mat-icon inline=true>edit</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button mat-icon-button class="icons" (click)="delete(item._id!)">
|
<button mat-icon-button class="icons" (click)="delete(item._id!)">
|
||||||
<mat-icon>delete</mat-icon>
|
<mat-icon inline=true>delete</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td align="right">
|
<td align="right">
|
||||||
<button mat-icon-button
|
<button mat-raised-button
|
||||||
color="primary"
|
color="primary"
|
||||||
class="buttons-class-cart"
|
class="buttons-class-cart"
|
||||||
(click)="addToOrder(item._id!)">
|
(click)="addToOrder(item._id!)">
|
||||||
<mat-icon>
|
<mat-icon [inline]="true">
|
||||||
shopping_cart
|
shopping_cart
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -97,8 +97,8 @@ img.icon{
|
||||||
}
|
}
|
||||||
|
|
||||||
.orderListTitle {
|
.orderListTitle {
|
||||||
font-family: 'Roboto Mono' !important;
|
font-family: 'Roboto Mono';
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,9 @@
|
||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<h3 class="text">{{(ownerUpdate | async)!.name}}</h3>
|
<h3 class="text">{{(ownerUpdate | async)!.name}}</h3>
|
||||||
<table >
|
|
||||||
<tr>
|
|
||||||
<td width="45%">
|
|
||||||
<button class="text" mat-raised-button [routerLink]="['/shop']" color="primary">
|
<button class="text" mat-raised-button [routerLink]="['/shop']" color="primary">
|
||||||
Back to Shop
|
Back to Shop
|
||||||
</button>
|
</button>
|
||||||
</td>
|
|
||||||
<td width="10%">
|
|
||||||
</td>
|
|
||||||
<td width="45%">
|
|
||||||
<button mat-raised-button color="primary"
|
|
||||||
class="text" (click)="openDbExport()">
|
|
||||||
Export Orders
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
<table class="totalsTbl" width="100%">
|
<table class="totalsTbl" width="100%">
|
||||||
<tr class="totalsHdr">
|
<tr class="totalsHdr">
|
||||||
|
@ -45,13 +31,12 @@
|
||||||
<div class="orderList">
|
<div class="orderList">
|
||||||
<mat-accordion *ngIf = "orders.length > 0">
|
<mat-accordion *ngIf = "orders.length > 0">
|
||||||
<mat-expansion-panel *ngFor = "let order of orders">
|
<mat-expansion-panel *ngFor = "let order of orders">
|
||||||
<mat-expansion-panel-header [collapsedHeight]="'35px'" [expandedHeight]="'30px'" >
|
<mat-expansion-panel-header [collapsedHeight]="'30px'" [expandedHeight]="'30px'" >
|
||||||
<mat-panel-title>
|
<mat-panel-title>
|
||||||
<div class="orderListTitle">
|
<div class="orderListTitle">
|
||||||
<img src="/assets/zec_rv.png"
|
<img src="/assets/zec_rv.png"
|
||||||
style="height: 14px;
|
style="height: 16px;
|
||||||
margin-bottom: -2px;
|
margin-bottom: -2px;"
|
||||||
padding-right: 3px;"
|
|
||||||
>{{order.totalZec | number: '1.08'}}
|
>{{order.totalZec | number: '1.08'}}
|
||||||
</div>
|
</div>
|
||||||
</mat-panel-title>
|
</mat-panel-title>
|
||||||
|
@ -59,14 +44,10 @@
|
||||||
<table width="100%">
|
<table width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<fa-icon *ngIf="payConf"
|
<fa-icon [icon]="getIcon(order)" [style]="getIconStyle(order)" ></fa-icon>
|
||||||
[icon]="getIcon(order)" [style]="getIconStyle(order)" ></fa-icon>
|
|
||||||
</td>
|
</td>
|
||||||
<td align="center"
|
<td align="center">
|
||||||
style="font-family: 'Roboto Mono' !important;
|
{{order.timestamp | date: 'short'}}
|
||||||
font-weight: 700 ;
|
|
||||||
font-size: 14px;">
|
|
||||||
{{order.timestamp | date: 'YYYY-MM-dd, HH:mm'}}
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { OrderService } from '../order/order.service';
|
||||||
import { MatDialog, MatDialogConfig} from '@angular/material/dialog';
|
import { MatDialog, MatDialogConfig} from '@angular/material/dialog';
|
||||||
import { PromptInvoiceComponent } from '../prompt-invoice/prompt-invoice.component';
|
import { PromptInvoiceComponent } from '../prompt-invoice/prompt-invoice.component';
|
||||||
import { PromptReceiptComponent } from '../prompt-receipt/prompt-receipt.component';
|
import { PromptReceiptComponent } from '../prompt-receipt/prompt-receipt.component';
|
||||||
import { DbExportComponent } from '../db-export/db-export.component';
|
|
||||||
|
|
||||||
import { faTimes } from '@fortawesome/free-solid-svg-icons';
|
import { faTimes } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faTimesCircle } from '@fortawesome/free-solid-svg-icons';
|
import { faTimesCircle } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
@ -41,36 +40,10 @@ export class ListOrdersComponent implements OnInit, OnDestroy{
|
||||||
faCheckCircle = faCheckCircle;
|
faCheckCircle = faCheckCircle;
|
||||||
faHourglass = faHourglass;
|
faHourglass = faHourglass;
|
||||||
faTrash = faTrash;
|
faTrash = faTrash;
|
||||||
payConf : boolean = false;
|
|
||||||
owner : Owner = {
|
|
||||||
address: '',
|
|
||||||
name: '',
|
|
||||||
currency: 'usd',
|
|
||||||
tax: false,
|
|
||||||
taxValue: 0,
|
|
||||||
vat: false,
|
|
||||||
vatValue: 0,
|
|
||||||
first: '',
|
|
||||||
last: '',
|
|
||||||
email: '',
|
|
||||||
street: '',
|
|
||||||
city: '',
|
|
||||||
state: '',
|
|
||||||
postal: '',
|
|
||||||
phone: '',
|
|
||||||
paid: false,
|
|
||||||
website: '',
|
|
||||||
country: '',
|
|
||||||
zats: false,
|
|
||||||
invoices: false,
|
|
||||||
expiration: new Date(Date.now()).toISOString(),
|
|
||||||
payconf: false,
|
|
||||||
viewkey: '',
|
|
||||||
crmToken: ''
|
|
||||||
};
|
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public orderService: OrderService,
|
public orderService: OrderService,
|
||||||
public userService: UserService,
|
public userService: UserService,
|
||||||
|
@ -82,24 +55,13 @@ export class ListOrdersComponent implements OnInit, OnDestroy{
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(){
|
ngOnInit(){
|
||||||
// console.log('listOrders Init -->');
|
|
||||||
this.owner = this.userService.currentOwner();
|
|
||||||
// console.log(this.owner.name);
|
|
||||||
this.payConf = this.owner.payconf;
|
|
||||||
// this.payConf = true;
|
|
||||||
// console.log('payConf = ', this.payConf);
|
|
||||||
|
|
||||||
this.ordersUpdate.subscribe((orders) => {
|
this.ordersUpdate.subscribe((orders) => {
|
||||||
this.total = 0;
|
this.total = 0;
|
||||||
this.todayTotal = 0;
|
this.todayTotal = 0;
|
||||||
var today = new Date();
|
var today = new Date();
|
||||||
this.orders = orders;
|
this.orders = orders;
|
||||||
|
|
||||||
console.log(this.ownerUpdate);
|
|
||||||
for (let i=0; i < this.orders.length; i++){
|
for (let i=0; i < this.orders.length; i++){
|
||||||
this.total += this.orders[i].totalZec;
|
this.total += this.orders[i].totalZec;
|
||||||
//
|
|
||||||
|
|
||||||
var date = new Date(this.orders[i]!.timestamp!);
|
var date = new Date(this.orders[i]!.timestamp!);
|
||||||
var diff = (today.getTime() / 1000) - (date.getTime()/1000);
|
var diff = (today.getTime() / 1000) - (date.getTime()/1000);
|
||||||
if (diff < (24*3600)){
|
if (diff < (24*3600)){
|
||||||
|
@ -169,20 +131,4 @@ export class ListOrdersComponent implements OnInit, OnDestroy{
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openDbExport(){
|
|
||||||
const dialogConfig = new MatDialogConfig();
|
|
||||||
|
|
||||||
console.log('openDbExport ---');
|
|
||||||
|
|
||||||
dialogConfig.disableClose = false;
|
|
||||||
dialogConfig.autoFocus = true;
|
|
||||||
dialogConfig.data = this.owner;
|
|
||||||
|
|
||||||
const dialogRef = this.dialog.open(DbExportComponent, dialogConfig);
|
|
||||||
dialogRef.afterClosed().subscribe((val) => {
|
|
||||||
console.log('Returning to order list');
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,10 @@ mat-card.coolcard{
|
||||||
background-color: #FF5722;
|
background-color: #FF5722;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
width: 90%;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
}
|
||||||
mat-card.centercard{
|
mat-card.centercard{
|
||||||
max-width: 450px;
|
max-width: 450px;
|
||||||
border: 1px solid #CCCCCC;
|
border: 1px solid #CCCCCC;
|
||||||
justify-content: center;
|
|
||||||
}
|
}
|
||||||
.icon{
|
.icon{
|
||||||
font-family: 'Material Icons';
|
font-family: 'Material Icons';
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<div align="center" class="text">
|
<div align="center" class="text">
|
||||||
<mat-card class="coolcard">
|
<mat-card class="coolcard">
|
||||||
<mat-card-content>
|
<img src="/assets/logo-new-white.png" height="120px" />
|
||||||
<img mat-card-image src="/assets/logo-new-white_01.png" height="120px" />
|
|
||||||
<p class="text">Last block seen: <span class="numbers">{{ heightUpdate | async }}</span></p>
|
<p class="text">Last block seen: <span class="numbers">{{ heightUpdate | async }}</span></p>
|
||||||
</mat-card-content>
|
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
@ -11,11 +9,15 @@
|
||||||
<h3>The Zcash Register</h3>
|
<h3>The Zcash Register</h3>
|
||||||
<mat-vertical-stepper #stepper linear>
|
<mat-vertical-stepper #stepper linear>
|
||||||
<mat-step label="Connect your wallet to ZGo" editable="false">
|
<mat-step label="Connect your wallet to ZGo" editable="false">
|
||||||
|
<mat-card>
|
||||||
<div align="center" id="info">
|
<div align="center" id="info">
|
||||||
|
<mat-card-actions>
|
||||||
<button mat-raised-button color="primary" (click)="login(stepper)">
|
<button mat-raised-button color="primary" (click)="login(stepper)">
|
||||||
<mat-icon class="icon">login</mat-icon><span class="bigbutton">Link wallet</span>
|
<mat-icon class="icon">login</mat-icon><span class="bigbutton">Link wallet</span>
|
||||||
</button>
|
</button>
|
||||||
|
</mat-card-actions>
|
||||||
</div>
|
</div>
|
||||||
|
</mat-card>
|
||||||
</mat-step>
|
</mat-step>
|
||||||
<mat-step label="ZGo confirms your login on the Zcash blockhain:" editable="false">
|
<mat-step label="ZGo confirms your login on the Zcash blockhain:" editable="false">
|
||||||
<p>{{barMessage}}</p>
|
<p>{{barMessage}}</p>
|
||||||
|
|
|
@ -71,6 +71,18 @@ export class LoginComponent implements OnInit, AfterViewInit {
|
||||||
public userUpdate:Observable<User>;
|
public userUpdate:Observable<User>;
|
||||||
public ownerUpdate:Observable<Owner>;
|
public ownerUpdate:Observable<Owner>;
|
||||||
public txsUpdate: Observable<Tx[]>;
|
public txsUpdate: Observable<Tx[]>;
|
||||||
|
tickets = [
|
||||||
|
{
|
||||||
|
value: 0.001,
|
||||||
|
viewValue: '1 hour: 0.001 ZEC'
|
||||||
|
},{
|
||||||
|
value: 0.005,
|
||||||
|
viewValue: '1 day: 0.005 ZEC'
|
||||||
|
},{
|
||||||
|
value: 0.025,
|
||||||
|
viewValue: '1 week: 0.025 ZEC'
|
||||||
|
}
|
||||||
|
];
|
||||||
prompt: boolean = false;
|
prompt: boolean = false;
|
||||||
confirmedMemo: boolean = false;
|
confirmedMemo: boolean = false;
|
||||||
targetBlock: number = 0;
|
targetBlock: number = 0;
|
||||||
|
|
|
@ -9,7 +9,7 @@ export class NotifierService {
|
||||||
|
|
||||||
constructor(private snackBar:MatSnackBar) { }
|
constructor(private snackBar:MatSnackBar) { }
|
||||||
|
|
||||||
showNotification(displayMessage:string, buttonText: string, messageType: 'error' | 'success' | 'warning') {
|
showNotification(displayMessage:string, buttonText: string, messageType: 'error' | 'success') {
|
||||||
this.snackBar.openFromComponent(NotifierComponent, {
|
this.snackBar.openFromComponent(NotifierComponent, {
|
||||||
data: {
|
data: {
|
||||||
message: displayMessage,
|
message: displayMessage,
|
||||||
|
@ -19,16 +19,7 @@ export class NotifierService {
|
||||||
duration: 4000,
|
duration: 4000,
|
||||||
verticalPosition: 'top',
|
verticalPosition: 'top',
|
||||||
panelClass: [messageType]
|
panelClass: [messageType]
|
||||||
});
|
})
|
||||||
this.playSound();
|
|
||||||
}
|
|
||||||
|
|
||||||
playSound() {
|
|
||||||
// console.log('Play sound called...');
|
|
||||||
let audio = new Audio();
|
|
||||||
audio.src = '../assets/notifier_1.mp3';
|
|
||||||
audio.load();
|
|
||||||
audio.play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -21,7 +21,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
::ng-deep .mat-snack-bar-container.error {
|
::ng-deep .mat-snack-bar-container.error {
|
||||||
background: navajowhite;
|
background: antiquewhite;
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,9 +29,3 @@
|
||||||
background: whitesmoke;
|
background: whitesmoke;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
::ng-deep .mat-snack-bar-container.warning {
|
|
||||||
background: antiquewhite;
|
|
||||||
color: black;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
<div class="notifier" >
|
<div class="notifier" >
|
||||||
<div class="notifier-type">
|
<div class="notifier-type">
|
||||||
{{ data.type | titlecase }}
|
{{ data.type | titlecase }}
|
||||||
|
|
|
@ -32,7 +32,6 @@ export class OrderComponent implements OnInit{
|
||||||
|
|
||||||
faInvoice = faFileInvoiceDollar;
|
faInvoice = faFileInvoiceDollar;
|
||||||
public order: Order = {
|
public order: Order = {
|
||||||
_id: '',
|
|
||||||
address: '',
|
address: '',
|
||||||
session: '',
|
session: '',
|
||||||
timestamp: '',
|
timestamp: '',
|
||||||
|
@ -80,8 +79,6 @@ export class OrderComponent implements OnInit{
|
||||||
this.orderUpdate = orderService.orderUpdate;
|
this.orderUpdate = orderService.orderUpdate;
|
||||||
this.orderUpdate.subscribe((order) => {
|
this.orderUpdate.subscribe((order) => {
|
||||||
this.order = order;
|
this.order = order;
|
||||||
|
|
||||||
console.log('this.order > ' + JSON.stringify(this.order));
|
|
||||||
// ------------------------------------------------
|
// ------------------------------------------------
|
||||||
this.oLines = [];
|
this.oLines = [];
|
||||||
this.myLines = this.order.lines;
|
this.myLines = this.order.lines;
|
||||||
|
@ -186,8 +183,6 @@ export class OrderComponent implements OnInit{
|
||||||
orderId: this.order._id
|
orderId: this.order._id
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log ('order_id : ' + this.order._id);
|
|
||||||
|
|
||||||
const dialogRef = this.dialog.open(PromptInvoiceComponent, dialogConfig);
|
const dialogRef = this.dialog.open(PromptInvoiceComponent, dialogConfig);
|
||||||
dialogRef.afterClosed().subscribe((val) => {
|
dialogRef.afterClosed().subscribe((val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
.invoice {
|
|
||||||
font-family: Roboto Mono !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.zecSign {
|
|
||||||
margin-bottom: -4px;
|
|
||||||
font-size: 18px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoiceHeader {
|
|
||||||
display: flex;
|
|
||||||
font-family: Spartan;
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 26px;
|
|
||||||
color: white;
|
|
||||||
justify-content: space-between;
|
|
||||||
line-height: 40px;
|
|
||||||
padding: 10px;
|
|
||||||
vertical-align: center;
|
|
||||||
max-width: 600px;
|
|
||||||
background: #ff5722;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoiceDetail {
|
|
||||||
font-family: Roboto Mono !important;
|
|
||||||
padding: 10px;
|
|
||||||
max-width: 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoiceHdrTxt1 {
|
|
||||||
font-family: Spartan !important;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 30px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoiceHdrTxt2 {
|
|
||||||
font-family: Spartan !important;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoiceHdrTxt3 {
|
|
||||||
font-family: Spartan !important;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detailTitle1 {
|
|
||||||
border-top: solid 2px;
|
|
||||||
border-bottom: solid 2px;
|
|
||||||
border-color: navy;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detailTitle2 {
|
|
||||||
border-top: solid 2px;
|
|
||||||
border-bottom: solid 2px;
|
|
||||||
border-color: navy;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detailLineRight {
|
|
||||||
border-top: solid 2px;
|
|
||||||
border-bottom: solid 2px;
|
|
||||||
border-color: navy;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detailLineLeft {
|
|
||||||
border-top: solid 2px;
|
|
||||||
border-bottom: solid 2px;
|
|
||||||
border-color: navy;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoice-title {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 700;
|
|
||||||
background: lightcyan;
|
|
||||||
line-height: 30px;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoice-detail {
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 400;
|
|
||||||
padding-top: 4px;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoice-total {
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qrcode {
|
|
||||||
display: flex;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.zecData {
|
|
||||||
width: auto;
|
|
||||||
font-family: Spartan !important;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 700;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
|
@ -1,255 +1 @@
|
||||||
<div style="font-family: 'Spartan';
|
<p>{{ pmtData.ownerId }}</p>
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;">
|
|
||||||
<div class="container">
|
|
||||||
<div class="invoiceHeader">
|
|
||||||
<img class="logo" src="/assets/logo-new-white.png" height="40px" />
|
|
||||||
</div>
|
|
||||||
<div *ngIf="reportType==1">
|
|
||||||
<div style="height: 50px;">
|
|
||||||
</div>
|
|
||||||
<div style="font-weight: 700;
|
|
||||||
font-size: 25px;
|
|
||||||
text-align: center;">
|
|
||||||
Invalid Owner ID!!
|
|
||||||
</div>
|
|
||||||
<div style="height: 40px;">
|
|
||||||
</div>
|
|
||||||
Payment request was not processed!!
|
|
||||||
<div style="height: 20px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="reportType==2">
|
|
||||||
<div style="height: 50px;">
|
|
||||||
</div>
|
|
||||||
<div style="font-weight: 700;
|
|
||||||
font-size: 25px;
|
|
||||||
text-align: center;">
|
|
||||||
Payment service not<br>
|
|
||||||
enabled for<br>
|
|
||||||
{{ owner.name}}
|
|
||||||
</div>
|
|
||||||
<div style="height: 40px;">
|
|
||||||
</div>
|
|
||||||
Payment request was not processed!!
|
|
||||||
<div style="height: 20px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="reportType==3">
|
|
||||||
<div style="height: 50px;">
|
|
||||||
</div>
|
|
||||||
<div style="font-weight: 700;
|
|
||||||
font-size: 25px;
|
|
||||||
text-align: center;">
|
|
||||||
Connection to Xero<br>server failed!!
|
|
||||||
</div>
|
|
||||||
<div style="height: 40px;">
|
|
||||||
</div>
|
|
||||||
Payment request was not processed!!
|
|
||||||
<div style="height: 20px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="reportType==4">
|
|
||||||
<div style="height: 50px;">
|
|
||||||
</div>
|
|
||||||
<div style="font-weight: 700;
|
|
||||||
font-size: 25px;
|
|
||||||
text-align: center;">
|
|
||||||
Invoice<br>{{ pmtData.invoice }}<br>not found!!
|
|
||||||
</div>
|
|
||||||
<div style="height: 40px;">
|
|
||||||
</div>
|
|
||||||
Payment request was not processed!!
|
|
||||||
<div style="height: 20px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="reportType==5">
|
|
||||||
<div style="height: 50px;">
|
|
||||||
</div>
|
|
||||||
<div style="font-weight: 700;
|
|
||||||
font-size: 25px;
|
|
||||||
text-align: center;">
|
|
||||||
Invoice<br>{{ pmtData.invoice }}<br>type invalid!!
|
|
||||||
</div>
|
|
||||||
<div style="height: 40px;">
|
|
||||||
</div>
|
|
||||||
Payment request was not processed!!
|
|
||||||
<div style="height: 20px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="reportType==6">
|
|
||||||
<div style="height: 50px;">
|
|
||||||
</div>
|
|
||||||
<div style="font-weight: 700;
|
|
||||||
font-size: 25px;
|
|
||||||
text-align: center;">
|
|
||||||
Invoice <br>{{ pmtData.invoice }}<br>already paid!!
|
|
||||||
</div>
|
|
||||||
<div style="height: 40px;">
|
|
||||||
</div>
|
|
||||||
Payment request was not processed!!
|
|
||||||
<div style="height: 20px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="reportType==7">
|
|
||||||
<div style="height: 50px;">
|
|
||||||
</div>
|
|
||||||
<div style="font-weight: 700;
|
|
||||||
font-size: 25px;
|
|
||||||
text-align: center;">
|
|
||||||
Currency <br>[ {{ pmtData.currency }} ]<br>not supported!!
|
|
||||||
</div>
|
|
||||||
<div style="height: 40px;">
|
|
||||||
</div>
|
|
||||||
Payment request was not processed!!
|
|
||||||
<div style="height: 20px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="reportType==8">
|
|
||||||
<div style="height: 50px;">
|
|
||||||
</div>
|
|
||||||
<div style="font-weight: 700;
|
|
||||||
font-size: 25px;
|
|
||||||
text-align: center;">
|
|
||||||
Amount does not<br>
|
|
||||||
match value<br>
|
|
||||||
reported by Xero!!
|
|
||||||
</div>
|
|
||||||
<div style="height: 40px;">
|
|
||||||
</div>
|
|
||||||
Payment request was not processed!!
|
|
||||||
<div style="height: 20px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="invoiceDetail"
|
|
||||||
*ngIf="reportType==0"
|
|
||||||
id="invoice">
|
|
||||||
<div class="invoiceHdrTxt1">Invoice</div>
|
|
||||||
<div class="invoiceHdrTxt2">Order ID: {{orderId}}</div>
|
|
||||||
<div class="invoiceHdrTxt3">Date:{{order.timestamp | date}}
|
|
||||||
</div>
|
|
||||||
<div style="height: 10px;"></div>
|
|
||||||
<div class="zecData">Zcash Price: {{order.price | number: '1.02' | currency: order.currency.toUpperCase()}}</div>
|
|
||||||
<div style="height: 2px;"></div>
|
|
||||||
<div class="zecData">Total: <img class="zecSign" src="/assets/zec_rv.png" />{{order.totalZec | number: '1.08'}}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div style="height: 10px;"></div>
|
|
||||||
<table style="width: 100%;"
|
|
||||||
cellspacing="0">
|
|
||||||
<tr class="invoice-title">
|
|
||||||
<th width="55%"
|
|
||||||
class="detailTitle1">
|
|
||||||
Item
|
|
||||||
</th>
|
|
||||||
<th width="15%"
|
|
||||||
class="detailTitle1">
|
|
||||||
Qty.
|
|
||||||
</th>
|
|
||||||
<th width="30%"
|
|
||||||
class="detailTitle2">
|
|
||||||
Price ({{order.currency.toUpperCase()}})
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<tr class="invoice-detail"
|
|
||||||
*ngFor="let item of order.lines">
|
|
||||||
<td width="55%"
|
|
||||||
align="left">
|
|
||||||
{{item.name}}
|
|
||||||
</td>
|
|
||||||
<td width="15%"
|
|
||||||
align="center">
|
|
||||||
{{item.qty}}
|
|
||||||
</td>
|
|
||||||
<td width="30%"
|
|
||||||
align="right">
|
|
||||||
{{( item.qty * item.cost ) | number : '1.02' | currency: order.currency.toUpperCase()}}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="invoice-title">
|
|
||||||
<th width="55%"
|
|
||||||
class="detailLineRight">
|
|
||||||
Invoice Total:
|
|
||||||
</th>
|
|
||||||
<th width="15%"
|
|
||||||
class="detailLineLeft">
|
|
||||||
|
|
||||||
</th>
|
|
||||||
<th width="30%"
|
|
||||||
class="detailLineRight">
|
|
||||||
{{ order.total | currency: order.currency.toUpperCase()}}
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div style="height: 15px;"></div>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td width="75%"
|
|
||||||
style="font-size: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
font-style: italic;
|
|
||||||
text-align: center;">
|
|
||||||
<p *ngIf="order.paid">
|
|
||||||
<fa-icon [icon]="faCheck"
|
|
||||||
color="primary"></fa-icon> Payment confirmed</p>
|
|
||||||
<p *ngIf="!order.paid">
|
|
||||||
<fa-icon [style]="getIconStyle(order)"
|
|
||||||
[icon]="faHourglass"></fa-icon> Payment pending!!</p>
|
|
||||||
</td>
|
|
||||||
<td width="25%">
|
|
||||||
<div style="text-align: right;"
|
|
||||||
id="payment-qr"
|
|
||||||
*ngIf="!order.paid"></div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div style="height: 15px;"></div>
|
|
||||||
<div width="100%"
|
|
||||||
style="font-size: 14px;
|
|
||||||
font-weight: 700;
|
|
||||||
font-style: italic;
|
|
||||||
text-align: center;">
|
|
||||||
Scan the QR code with your wallet to make payment
|
|
||||||
</div>
|
|
||||||
<div style="text-align: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
line-height: 30px;">
|
|
||||||
<div style="font-family: 'Spartan';
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;">
|
|
||||||
Can't scan?<br>Use this <a [href]="zcashUrl">wallet link</a>, or
|
|
||||||
</div>
|
|
||||||
<div style="display: flex;
|
|
||||||
justify-content: space-between;">
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightgray;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="copyAddress()">Copy Address</button>
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightgray;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="copyAmount()">Copy Amount</button>
|
|
||||||
</div>
|
|
||||||
<button style="margin-top: 20px;
|
|
||||||
font-weight: 700;
|
|
||||||
background-color: lightgray;"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="copyMemo()">Copy Memo</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,20 +1,6 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Router, ActivatedRoute, Params } from "@angular/router";
|
import { Router, ActivatedRoute, Params } from "@angular/router";
|
||||||
import { HttpClient, HttpParams, HttpHeaders } from "@angular/common/http";
|
import { PmtData } from "./pmtservice.model"
|
||||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
|
||||||
import { PmtData } from "./pmtservice.model";
|
|
||||||
import { XeroInvoice } from "./xeroinvoice.model";
|
|
||||||
import { Owner } from '../owner.model';
|
|
||||||
// import { Item } from '../items/item.model'
|
|
||||||
import { Order } from '../order/order.model'
|
|
||||||
import { ConfigData } from '../configdata';
|
|
||||||
import { faCheck, faHourglass } from '@fortawesome/free-solid-svg-icons';
|
|
||||||
|
|
||||||
import { NotifierService } from '../notifier.service';
|
|
||||||
|
|
||||||
var QRCode = require('easyqrcodejs');
|
|
||||||
var URLSafeBase64 = require('urlsafe-base64');
|
|
||||||
var Buffer = require('buffer/').Buffer;
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-pmtservice',
|
selector: 'app-pmtservice',
|
||||||
|
@ -24,11 +10,6 @@ var Buffer = require('buffer/').Buffer;
|
||||||
|
|
||||||
export class PmtserviceComponent implements OnInit {
|
export class PmtserviceComponent implements OnInit {
|
||||||
|
|
||||||
faCheck = faCheck;
|
|
||||||
faHourglass = faHourglass;
|
|
||||||
|
|
||||||
beUrl = ConfigData.Be_URL;
|
|
||||||
private reqHeaders: HttpHeaders = new HttpHeaders();
|
|
||||||
|
|
||||||
public pmtData : PmtData = {
|
public pmtData : PmtData = {
|
||||||
ownerId :'',
|
ownerId :'',
|
||||||
|
@ -38,354 +19,18 @@ export class PmtserviceComponent implements OnInit {
|
||||||
shortcode: ''
|
shortcode: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
public invData : XeroInvoice = {
|
constructor(private activatedRoute: ActivatedRoute) {}
|
||||||
inv_Type : '',
|
|
||||||
inv_Id : '',
|
|
||||||
inv_No : '',
|
|
||||||
inv_Contact : '',
|
|
||||||
inv_Currency : '',
|
|
||||||
inv_CurrencyRate : 0,
|
|
||||||
inv_Status : '',
|
|
||||||
inv_Total : 0,
|
|
||||||
inv_Date : new Date(),
|
|
||||||
inv_shortCode : '',
|
|
||||||
inv_ProcDate : new Date()
|
|
||||||
};
|
|
||||||
|
|
||||||
public owner: Owner = {
|
|
||||||
_id: '',
|
|
||||||
address: '',
|
|
||||||
name: '',
|
|
||||||
currency: 'usd',
|
|
||||||
tax: false,
|
|
||||||
taxValue: 0,
|
|
||||||
vat: false,
|
|
||||||
vatValue: 0,
|
|
||||||
first: '',
|
|
||||||
last: '',
|
|
||||||
email: '',
|
|
||||||
street: '',
|
|
||||||
city: '',
|
|
||||||
state: '',
|
|
||||||
postal: '',
|
|
||||||
phone: '',
|
|
||||||
paid: false,
|
|
||||||
website: '',
|
|
||||||
country: '',
|
|
||||||
zats: false,
|
|
||||||
invoices: false,
|
|
||||||
expiration: new Date(Date.now()).toISOString(),
|
|
||||||
payconf: false,
|
|
||||||
viewkey: '',
|
|
||||||
crmToken: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
public order: Order = {
|
|
||||||
_id : '',
|
|
||||||
address: '',
|
|
||||||
session: '',
|
|
||||||
timestamp: '',
|
|
||||||
closed: false,
|
|
||||||
currency: '',
|
|
||||||
price: 0,
|
|
||||||
total: 0,
|
|
||||||
totalZec: 0,
|
|
||||||
paid: false,
|
|
||||||
externalInvoice: '',
|
|
||||||
shortCode: '',
|
|
||||||
lines: [
|
|
||||||
{
|
|
||||||
qty: 1,
|
|
||||||
name: '',
|
|
||||||
cost:0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
private invData_raw : string = '';
|
|
||||||
private invData_buff : any = null;
|
|
||||||
|
|
||||||
public reportType = 1000;
|
|
||||||
public Status = 0;
|
|
||||||
|
|
||||||
codeString: string = '';
|
|
||||||
zcashUrl: SafeUrl = '';
|
|
||||||
zPrice: number = 1.0;
|
|
||||||
name: string = '';
|
|
||||||
error: boolean = false;
|
|
||||||
orderId : string = '';
|
|
||||||
|
|
||||||
constructor(private activatedRoute : ActivatedRoute,
|
|
||||||
private http : HttpClient,
|
|
||||||
private sanitizer: DomSanitizer,
|
|
||||||
private notifierService : NotifierService ) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
var auth = 'Basic ' + Buffer.from(ConfigData.UsrPwd).toString('base64');
|
|
||||||
this.reqHeaders = new HttpHeaders().set('Authorization', auth);
|
|
||||||
this.activatedRoute.queryParams.subscribe((params) => {
|
this.activatedRoute.queryParams.subscribe((params) => {
|
||||||
this.pmtData.ownerId = params["owner"];
|
this.pmtData.ownerId = params["ownerid"];
|
||||||
this.pmtData.invoice = params["invoiceNo"];
|
this.pmtData.invoice = params["invoice"];
|
||||||
this.pmtData.amount = params["amount"];
|
this.pmtData.amount = params["amount"];
|
||||||
this.pmtData.currency = params["currency"];
|
this.pmtData.currency = params["currency"];
|
||||||
this.pmtData.shortcode = params["shortCode"];
|
this.pmtData.shortcode = params["shortcode"];
|
||||||
// console.log(this.pmtData);
|
|
||||||
|
|
||||||
this.getInvoiceData( this.pmtData );
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
getInvoiceData( reqData : PmtData ) {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Verify owner id ( Status = 1 if not exists )
|
|
||||||
// ( Status = 2 if service not available for user )
|
|
||||||
//
|
|
||||||
// console.log('getOwner -> '+ reqData.ownerId);
|
|
||||||
// console.log('received amount -> ' + reqData.amount);
|
|
||||||
const ownParams = new HttpParams().append('id', reqData.ownerId);
|
|
||||||
let obs = this.http.get<{message:string, owner: any}>
|
|
||||||
( this.beUrl+'api/ownerid',
|
|
||||||
{ headers: this.reqHeaders,
|
|
||||||
params: ownParams,
|
|
||||||
observe: 'response'});
|
|
||||||
obs.subscribe((OwnerDataResponse) => {
|
|
||||||
//console.log('api/getowner', OwnerDataResponse.status);
|
|
||||||
if (OwnerDataResponse.status == 200) {
|
|
||||||
this.owner = OwnerDataResponse.body!.owner;
|
|
||||||
console.log('Owner => ' + this.owner.name );
|
|
||||||
//
|
|
||||||
// ==> remove "== false" for production enviroment
|
|
||||||
//
|
|
||||||
if ( this.owner.invoices ) {
|
|
||||||
// process data
|
|
||||||
console.log("Owner check passed!!!");
|
|
||||||
this.getXeroInvoiceData( reqData );
|
|
||||||
} else {
|
|
||||||
console.log("Owner check failed!!!")
|
|
||||||
this.reportType = 2;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
if ( OwnerDataResponse.status == 204 ) {
|
|
||||||
console.log('Res.Status = ' + OwnerDataResponse.status)
|
|
||||||
console.log('Owner id not found!!!');
|
|
||||||
this.reportType = 1;
|
|
||||||
}
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
getXeroInvoiceData( reqData : PmtData ) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Call test Xero API
|
|
||||||
let url : string = "http://localhost:3000/xero/" + reqData.invoice;
|
|
||||||
this.http
|
|
||||||
.get<any>(url)
|
|
||||||
*/
|
|
||||||
console.log('>> find current zcash price');
|
|
||||||
this.getPrice(this.owner.currency);
|
|
||||||
|
|
||||||
console.log('get Invoice -> ' + reqData.invoice);
|
|
||||||
let invParams = new HttpParams();
|
|
||||||
invParams = invParams.append('address', this.owner.address);
|
|
||||||
invParams = invParams.append('inv', reqData.invoice);
|
|
||||||
let inv = this.http.get<{message:string, invData: any}>
|
|
||||||
( this.beUrl+'api/invdata',
|
|
||||||
{ headers: this.reqHeaders,
|
|
||||||
params: invParams,
|
|
||||||
observe: 'response'});
|
|
||||||
inv.subscribe( invDataResponse => {
|
|
||||||
// console.log('Response from ZGo-Xero');
|
|
||||||
// console.log(invDataResponse.status);
|
|
||||||
this.invData_buff = invDataResponse.body;
|
|
||||||
this.invData.inv_Type = this.invData_buff.invdata.inv_Type;
|
|
||||||
this.invData.inv_Id = this.invData_buff.invdata.inv_Id;
|
|
||||||
this.invData.inv_No = this.invData_buff.invdata.inv_No;
|
|
||||||
this.invData.inv_Contact = this.invData_buff.invdata.inv_Contact;
|
|
||||||
this.invData.inv_Currency = this.invData_buff.invdata.inv_Currency;
|
|
||||||
this.invData.inv_CurrencyRate = this.invData_buff.invdata.inv_CurrencyRate;
|
|
||||||
this.invData.inv_Total = this.invData_buff.invdata.inv_Total;
|
|
||||||
this.invData.inv_Status = this.invData_buff.invdata.inv_Status;
|
|
||||||
this.invData.inv_Date = this.invData_buff.invdata.inv_Date;
|
|
||||||
this.invData.inv_shortCode = reqData.shortcode;
|
|
||||||
/*
|
|
||||||
console.log('>>> inv_Type -> ' + this.invData.inv_Type);
|
|
||||||
console.log('>>> inv_Id -> ' + this.invData.inv_Id);
|
|
||||||
console.log('>>> inv_No -> ' + this.invData.inv_No);
|
|
||||||
console.log('>>> inv_Contact -> ' + this.invData.inv_Contact);
|
|
||||||
console.log('>>> inv_Currency-> ' + this.invData.inv_Currency);
|
|
||||||
console.log('>>> inv_CurrencyRate -> ' + this.invData.inv_CurrencyRate);
|
|
||||||
console.log('>>> inv_Total -> ' + this.invData.inv_Total);
|
|
||||||
console.log('>>> inv_Status-> ' + this.invData.inv_Status);
|
|
||||||
console.log('>>> inv_Date -> ' + this.invData.inv_Date);
|
|
||||||
*/
|
|
||||||
if ( this.invData.inv_Type == 'ACCREC' ) {
|
|
||||||
console.log('Invoice type is correct!!');
|
|
||||||
// Test if invoice is not already paid
|
|
||||||
if ( this.invData.inv_Status == 'AUTHORISED') {
|
|
||||||
console.log('invoice is payable');
|
|
||||||
// Test if Invoice's currency is supported
|
|
||||||
if ( this.invData.inv_Currency == reqData.currency ) {
|
|
||||||
console.log('Invoice currency supported');
|
|
||||||
// Test if requested amount is as reported by Xero
|
|
||||||
if ( this.invData.inv_Total == reqData.amount ) {
|
|
||||||
console.log('Invoice amount Ok - create Order');
|
|
||||||
// =====> Create order here
|
|
||||||
this.createOrder();
|
|
||||||
//
|
|
||||||
} else {
|
|
||||||
console.log('Invoice amount does not match')
|
|
||||||
this.reportType = 8;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('Invoice currency not supported');
|
|
||||||
this.reportType = 7;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('Invoice already paid');
|
|
||||||
this.reportType = 6;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('Invoice type is invalid' );
|
|
||||||
this.reportType = 5;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
console.log("Error while getting invData!!!");
|
|
||||||
console.log(error);
|
|
||||||
console.log(error.status);
|
|
||||||
if ( error.status == 500 ) {
|
|
||||||
// Assume that invoice was not found by haskell server
|
|
||||||
this.reportType = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
console.log(this.pmtData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
createOrder() {
|
|
||||||
this.reportType = 0;
|
|
||||||
// console.log('Starting order generation');
|
|
||||||
// console.log('>> find current zcash price');
|
|
||||||
|
|
||||||
this.order = {
|
|
||||||
_id: '',
|
|
||||||
address: this.owner.address,
|
|
||||||
session: 'Xero-' + this.owner._id,
|
|
||||||
currency: this.owner.currency,
|
|
||||||
timestamp: new Date(Date.now()).toISOString(),
|
|
||||||
closed: true,
|
|
||||||
totalZec: this.invData.inv_Total/this.zPrice,
|
|
||||||
price: this.zPrice,
|
|
||||||
total: this.invData.inv_Total,
|
|
||||||
paid: false,
|
|
||||||
externalInvoice: this.invData.inv_No,
|
|
||||||
shortCode: this.invData.inv_shortCode,
|
|
||||||
lines: [{qty: 1,
|
|
||||||
name: 'Invoice from ' + this.owner.name + '[' + this.invData.inv_No + ']',
|
|
||||||
cost: this.invData.inv_Total}]
|
|
||||||
};
|
|
||||||
|
|
||||||
let obs = this.http.post<{message: string, order: Order}>
|
|
||||||
(this.beUrl+'api/orderx',
|
|
||||||
{payload: this.order},
|
|
||||||
{ headers: this.reqHeaders }
|
|
||||||
);
|
|
||||||
obs.subscribe((orderData) => {
|
|
||||||
// console.log('Order created');
|
|
||||||
|
|
||||||
// console.log(orderData.order);
|
|
||||||
this.order = orderData.order
|
|
||||||
console.log('>> order -> ' + JSON.stringify(this.order));
|
|
||||||
this.orderId = String(this.order._id);
|
|
||||||
|
|
||||||
// console.log('Generating QRCode....')
|
|
||||||
|
|
||||||
this.codeString = `zcash:${this.order.address}?amount=${this.order.totalZec.toFixed(8)}&memo=${URLSafeBase64.encode(Buffer.from('ZGo Order::'.concat(this.orderId)))}`;
|
|
||||||
|
|
||||||
var qrcode = new QRCode(document.getElementById("payment-qr"), {
|
|
||||||
text: this.codeString,
|
|
||||||
logo: "/assets/zcash.png",
|
|
||||||
width: 180,
|
|
||||||
height: 180,
|
|
||||||
logoWidth: 50,
|
|
||||||
logoHeight: 50,
|
|
||||||
correctLevel: QRCode.CorrectLevel.H
|
|
||||||
});
|
|
||||||
|
|
||||||
this.codeString = `zcash:${this.order.address}?amount=${this.order.totalZec.toFixed(8)}&memo=${URLSafeBase64.encode(Buffer.from('ZGo Order::'.concat(this.orderId)))}`;
|
|
||||||
this.zcashUrl = this.sanitizer.bypassSecurityTrustUrl(this.codeString);
|
|
||||||
}, error => {
|
|
||||||
console.log(error.message);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getIconStyle(order : Order) {
|
|
||||||
if( order.paid )
|
|
||||||
return "font-size: 14px; color: #72cc50; margin-bottom: -2px;";
|
|
||||||
return "color: #FB4F14; margin-bottom: -2px; cursor: pointer;";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
getPrice(currency: string){
|
|
||||||
//var currency = 'usd';
|
|
||||||
const params = new HttpParams().append('currency', currency);
|
|
||||||
let obs = this.http.get<{message: string, price: any}>(this.beUrl+'api/price', { headers:this.reqHeaders, params: params, observe: 'response'});
|
|
||||||
obs.subscribe((PriceData) => {
|
|
||||||
if (PriceData.status == 200) {
|
|
||||||
this.zPrice = PriceData.body!.price.price;
|
|
||||||
console.log("price", this.zPrice);
|
|
||||||
} else {
|
|
||||||
console.log('No price found for currency', currency);
|
|
||||||
this.zPrice = 1.0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return obs;
|
|
||||||
}
|
|
||||||
|
|
||||||
copyAddress() {
|
|
||||||
if (!navigator.clipboard) {
|
|
||||||
// alert("Copy functionality not supported");
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Copy functionality not supported","Close","error");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText(this.order.address);
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Error copying address","Close","error");
|
|
||||||
// console.error("Error", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
copyAmount() {
|
|
||||||
if (!navigator.clipboard) {
|
|
||||||
// alert("Copy functionality not supported");
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Copy functionality not supported","Close","error");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText(this.order.totalZec.toString());
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Error while copying ammount","Close","error");
|
|
||||||
// console.error("Error", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copyMemo() {
|
|
||||||
if (!navigator.clipboard) {
|
|
||||||
// alert("Copy functionality not supported");
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Copy functionality not supported","Close","error");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText("ZGo Order::" + this.orderId);
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Error while copying Memo","Close","error");
|
|
||||||
// console.error("Error", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1 @@
|
||||||
http://localhost:4200/pmtservice?ownerid=62cca13f5530331e2a97c78e&invoiceNo=INV-0034¤cy=USD&amount=753.95&shortCode=!w8T62
|
http://localhost:4200/pmtservice?ownerid=Rene&amount=30¤cy=USD&invoice=INV-003234&shortcode=abcde
|
||||||
|
|
||||||
https://test.zgo.cash/api/invdata?address=zs17faa6l5ma55s55exq9rnr32tu0wl8nmqg7xp3e6tz0m5ajn2a6yxlc09t03mqdmvyphavvf3sl8&inv=INV-0034
|
|
||||||
|
|
||||||
https://www.paymentservice.com/?invoiceNo=[INVOICENUMBER]¤cy=[CURRENCY]&amount=[AMOUNTDUE]&shortCode=[SHORTCODE]
|
|
||||||
|
|
||||||
https://app.zgo.cash/invoice/
|
|
|
@ -1,13 +0,0 @@
|
||||||
export interface XeroInvoice {
|
|
||||||
inv_Type : string;
|
|
||||||
inv_Id : string;
|
|
||||||
inv_No : string;
|
|
||||||
inv_Contact : string;
|
|
||||||
inv_Currency : string;
|
|
||||||
inv_CurrencyRate : number;
|
|
||||||
inv_Total : number;
|
|
||||||
inv_Status : string;
|
|
||||||
inv_Date : Date;
|
|
||||||
inv_shortCode : string;
|
|
||||||
inv_ProcDate : Date;
|
|
||||||
}
|
|
|
@ -23,37 +23,3 @@
|
||||||
.mat-slide-toggle-content {
|
.mat-slide-toggle-content {
|
||||||
font-family: 'Spartan', sans-serif;
|
font-family: 'Spartan', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.full-width {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.urlLabel {
|
|
||||||
font-family: "Spartan";
|
|
||||||
font-size: 13px;
|
|
||||||
color: dimgray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.urlDetail {
|
|
||||||
font-family: "Spartan";
|
|
||||||
font-size: 10px;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.urlCopyBtn {
|
|
||||||
cursor: pointer;
|
|
||||||
color: dodgerblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small {
|
|
||||||
font-size: 12px;
|
|
||||||
background: #dddddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.heading {
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar {
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1,7 @@
|
||||||
|
|
||||||
<div class="settings-title">Settings</div>
|
<div class="settings-title">Settings</div>
|
||||||
|
|
||||||
<div class="container"
|
<div class="container" style="margin-top: 10px;">
|
||||||
style="margin-top: 10px;
|
|
||||||
height: 450px;
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-right: 10px;">
|
|
||||||
<mat-tab-group mat-tab-align-tabs="start">
|
|
||||||
<mat-tab label="Main" style="height: 400px;">
|
|
||||||
<div class="container" style="margin-bottom: 20px;">
|
|
||||||
<mat-dialog-content [formGroup]="settingsForm">
|
<mat-dialog-content [formGroup]="settingsForm">
|
||||||
<mat-form-field class="settings-field" [style.width.%]="100">
|
<mat-form-field class="settings-field" [style.width.%]="100">
|
||||||
<mat-label>Name</mat-label>
|
<mat-label>Name</mat-label>
|
||||||
|
@ -38,28 +31,18 @@
|
||||||
Confirm payments?
|
Confirm payments?
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
<pre></pre>
|
<pre></pre>
|
||||||
<mat-form-field class="full-width"
|
<mat-form-field [style.width.%]="100">
|
||||||
appearance="fill">
|
|
||||||
<mat-label>Viewing key</mat-label>
|
<mat-label>Viewing key</mat-label>
|
||||||
<textarea matInput placeholder="Your wallet viewing key"
|
<input matInput placeholder="Your wallet viewing key"
|
||||||
formControlName="vKey">
|
formControlName="vKey">
|
||||||
</textarea>
|
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<!--
|
|
||||||
<pre></pre>
|
|
||||||
<mat-slide-toggle formControlName="proVersion"
|
|
||||||
class="settings-toggle"
|
|
||||||
(change)="onChangeProVersion($event)">
|
|
||||||
Enable Integrations
|
|
||||||
</mat-slide-toggle>
|
|
||||||
-->
|
|
||||||
</mat-dialog-content>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container"
|
</mat-dialog-content>
|
||||||
style="display: flex;
|
|
||||||
|
<mat-dialog-actions style="display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;">
|
align-items: center;
|
||||||
|
margin-top: 12px;">
|
||||||
<button mat-raised-button
|
<button mat-raised-button
|
||||||
(click)="close()">
|
(click)="close()">
|
||||||
Cancel
|
Cancel
|
||||||
|
@ -69,195 +52,5 @@
|
||||||
(click)="save()">
|
(click)="save()">
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</mat-dialog-actions>
|
||||||
<div style="height: 20px;
|
|
||||||
margin-top: 10px;">
|
|
||||||
</div>
|
|
||||||
</mat-tab>
|
|
||||||
<mat-tab *ngIf="proVersion"
|
|
||||||
label="Integrations"
|
|
||||||
style="align-items: center;">
|
|
||||||
<mat-tab-group mat-tab-align-tabs="start">
|
|
||||||
<mat-tab label="Xero">
|
|
||||||
<div class="container" style="margin-bottom: 20px;">
|
|
||||||
<mat-dialog-content [formGroup]="accCodForm">
|
|
||||||
<div style="height: 10px;
|
|
||||||
margin-top: 10px;">
|
|
||||||
</div>
|
|
||||||
<div class="container"
|
|
||||||
style="height: 300;">
|
|
||||||
<p style="text-align:center">
|
|
||||||
<a mat-raised-button
|
|
||||||
color="primary"
|
|
||||||
href="{{this.xeroLink}}">
|
|
||||||
{{ linkMsg }}
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<table *ngIf="linked2Xero"
|
|
||||||
[style.width.%]="100"
|
|
||||||
style="margin-top: 10px;">
|
|
||||||
<thead style="width: 100%;">
|
|
||||||
<tr>
|
|
||||||
<th class="urlLabel"
|
|
||||||
style="text-align: left;"
|
|
||||||
width="94%">Payment Service URL:
|
|
||||||
</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<td class="urlDetail"
|
|
||||||
style="text-align: left;"
|
|
||||||
width="94%">
|
|
||||||
<div>
|
|
||||||
<textarea disabled
|
|
||||||
style="font-size: 10px !important;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
min-height: 150px;
|
|
||||||
width: 95%;"
|
|
||||||
cdkTextareaAutosize
|
|
||||||
cdkAutosizeMinRows="6"
|
|
||||||
cdkAutosizeMaxRows="10">{{ pmtServiceURL }}
|
|
||||||
</textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td class="urlCopyBtn">
|
|
||||||
<a (click)='copyUrl()' >
|
|
||||||
<fa-icon [icon]="faCopy"
|
|
||||||
class="copy-button">
|
|
||||||
</fa-icon>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div style="height: 10px;
|
|
||||||
margin-top: 10px;">
|
|
||||||
</div>
|
|
||||||
<mat-form-field *ngIf="linked2Xero"
|
|
||||||
class="settings-field"
|
|
||||||
[style.width.%]="100">
|
|
||||||
<mat-label>Account Code</mat-label>
|
|
||||||
<input matInput
|
|
||||||
width="100%"
|
|
||||||
placeholder="9999999999"
|
|
||||||
formControlName="xAcc"
|
|
||||||
(keyup)="checkStatus($event)">
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</mat-dialog-content>
|
|
||||||
</div>
|
|
||||||
<div class="container"
|
|
||||||
style="display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;">
|
|
||||||
<button mat-raised-button
|
|
||||||
(click)="closeIntegration()">
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
<button *ngIf="saveAccOk"
|
|
||||||
mat-raised-button
|
|
||||||
color="primary"
|
|
||||||
(click)="saveAccCod()">
|
|
||||||
Save Code
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div style="height: 20px;
|
|
||||||
margin-top: 10px;">
|
|
||||||
</div>
|
|
||||||
</mat-tab>
|
|
||||||
<mat-tab label="WooCommerce">
|
|
||||||
<div >
|
|
||||||
<div *ngIf="wooOwner == ''" align="center">
|
|
||||||
<button mat-raised-button color="primary" (click)="generateWooToken()">
|
|
||||||
Generate Token
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<table *ngIf="wooOwner != ''">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td class="heading" style="width: 100%;">Owner:</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div>
|
|
||||||
<textarea disabled
|
|
||||||
style="border: none;
|
|
||||||
outline: none;
|
|
||||||
min-height: 150px;
|
|
||||||
width: 94%;"
|
|
||||||
cdkTextareaAutosize
|
|
||||||
cdkAutosizeMinRows="1"
|
|
||||||
cdkAutosizeMaxRows="3">{{wooOwner}}
|
|
||||||
</textarea>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="urlCopyBtn">
|
|
||||||
<a (click)='copyWooOwner()' >
|
|
||||||
<fa-icon [icon]="faCopy"
|
|
||||||
class="copy-button">
|
|
||||||
</fa-icon>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="heading" style="width: 60%;">Token:</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div>
|
|
||||||
<textarea disabled
|
|
||||||
style="border: none;
|
|
||||||
outline: none;
|
|
||||||
min-height: 150px;
|
|
||||||
width: 94%;"
|
|
||||||
cdkTextareaAutosize
|
|
||||||
cdkAutosizeMinRows="1"
|
|
||||||
cdkAutosizeMaxRows="3">{{wooToken}}
|
|
||||||
</textarea>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="urlCopyBtn">
|
|
||||||
<a (click)='copyWooToken()' >
|
|
||||||
<fa-icon [icon]="faCopy"
|
|
||||||
class="copy-button">
|
|
||||||
</fa-icon>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="heading" style="width: 60%;">URL:</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div>
|
|
||||||
<textarea disabled
|
|
||||||
style="border: none;
|
|
||||||
outline: none;
|
|
||||||
min-height: 150px;
|
|
||||||
width: 94%;"
|
|
||||||
cdkTextareaAutosize
|
|
||||||
cdkAutosizeMinRows="1"
|
|
||||||
cdkAutosizeMaxRows="3">{{wooUrl}}
|
|
||||||
</textarea>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div class="toolbar" align="center">
|
|
||||||
<button mat-raised-button
|
|
||||||
(click)="close()">
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</mat-tab>
|
|
||||||
</mat-tab-group>
|
|
||||||
</mat-tab>
|
|
||||||
</mat-tab-group>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,14 +2,8 @@ import { Inject, Component, OnInit, OnDestroy, ViewEncapsulation } from '@angula
|
||||||
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||||
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
|
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
|
||||||
import { UntypedFormBuilder, Validators, UntypedFormGroup, FormControl } from '@angular/forms';
|
import { UntypedFormBuilder, Validators, UntypedFormGroup, FormControl } from '@angular/forms';
|
||||||
import { Observable } from 'rxjs';
|
import { User } from '../user.model';
|
||||||
import { Owner } from '../owner.model';
|
import { Owner } from '../owner.model';
|
||||||
import { XeroService } from '../xero.service';
|
|
||||||
import { WoocommerceService } from '../woocommerce.service';
|
|
||||||
|
|
||||||
import { NotifierService } from '../notifier.service';
|
|
||||||
import { faCopy } from '@fortawesome/free-solid-svg-icons';
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-settings',
|
selector: 'app-settings',
|
||||||
|
@ -19,20 +13,10 @@ import { faCopy } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
export class SettingsComponent implements OnInit {
|
export class SettingsComponent implements OnInit {
|
||||||
|
|
||||||
// ------------------------------------
|
|
||||||
//
|
|
||||||
faCopy = faCopy;
|
|
||||||
// ------------------------------------
|
|
||||||
settingsForm: UntypedFormGroup;
|
settingsForm: UntypedFormGroup;
|
||||||
accCodForm: UntypedFormGroup;
|
|
||||||
owner: Owner;
|
owner: Owner;
|
||||||
useZats: boolean;
|
useZats: boolean;
|
||||||
proVersion: boolean = false;
|
|
||||||
useVKey: boolean = false;
|
useVKey: boolean = false;
|
||||||
linkMsg: string = 'Link to Xero';
|
|
||||||
xeroAccCod: string = '';
|
|
||||||
saveAccOk: boolean = false;
|
|
||||||
|
|
||||||
coins = [
|
coins = [
|
||||||
{
|
{
|
||||||
label: 'US Dollar',
|
label: 'US Dollar',
|
||||||
|
@ -49,31 +33,11 @@ export class SettingsComponent implements OnInit {
|
||||||
},{
|
},{
|
||||||
label: 'Australian Dollar',
|
label: 'Australian Dollar',
|
||||||
symbol: 'aud'
|
symbol: 'aud'
|
||||||
},{
|
|
||||||
label: 'New Zealand Dollar',
|
|
||||||
symbol: 'nzd'
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
xeroLink: string = '';
|
|
||||||
localToken: string = '';
|
|
||||||
clientId: string = '';
|
|
||||||
wooOwner: string = '';
|
|
||||||
wooToken: string = '';
|
|
||||||
wooUrl: string = '';
|
|
||||||
wooOwnerUpdate: Observable<string>;
|
|
||||||
wooTokenUpdate: Observable<string>;
|
|
||||||
wooUrlUpdate: Observable<string>;
|
|
||||||
|
|
||||||
clientIdUpdate: Observable<string>;
|
|
||||||
accCodeUpdate: Observable<string>;
|
|
||||||
linked2Xero : boolean = false;
|
|
||||||
pmtServiceURL : string = '';
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private notifierService : NotifierService,
|
|
||||||
private fb: UntypedFormBuilder,
|
private fb: UntypedFormBuilder,
|
||||||
public xeroService: XeroService,
|
|
||||||
public wooService: WoocommerceService,
|
|
||||||
private dialogRef: MatDialogRef<SettingsComponent>,
|
private dialogRef: MatDialogRef<SettingsComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: Owner) {
|
@Inject(MAT_DIALOG_DATA) public data: Owner) {
|
||||||
this.useZats = data.zats;
|
this.useZats = data.zats;
|
||||||
|
@ -83,74 +47,18 @@ export class SettingsComponent implements OnInit {
|
||||||
currency: [data.currency, Validators.required],
|
currency: [data.currency, Validators.required],
|
||||||
useZats: [data.zats, Validators.required],
|
useZats: [data.zats, Validators.required],
|
||||||
useVKey: [data.payconf, Validators.required],
|
useVKey: [data.payconf, Validators.required],
|
||||||
// proVersion: [data.invoices, Validators.required],
|
|
||||||
vKey: [data.viewkey]
|
vKey: [data.viewkey]
|
||||||
});
|
});
|
||||||
this.accCodForm = fb.group ({
|
|
||||||
xAcc: [this.xeroAccCod]
|
|
||||||
});
|
|
||||||
|
|
||||||
if (data.payconf) {
|
if (data.payconf) {
|
||||||
this.settingsForm.get('vKey')!.enable();
|
this.settingsForm.get('vKey')!.enable();
|
||||||
}
|
}
|
||||||
this.owner = data;
|
this.owner = data;
|
||||||
this.proVersion = this.owner.invoices;
|
|
||||||
if ( this.owner.crmToken !== '' ) {
|
|
||||||
this.linked2Xero = true;
|
|
||||||
}
|
|
||||||
this.clientIdUpdate = xeroService.clientIdUpdate;
|
|
||||||
xeroService.getXeroConfig();
|
|
||||||
this.clientIdUpdate.subscribe(clientId => {
|
|
||||||
this.clientId = clientId;
|
|
||||||
this.xeroLink = `https://login.xero.com/identity/connect/authorize?response_type=code&client_id=${this.clientId}&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fxeroauth&scope=accounting.transactions offline_access&state=${this.owner.address.substring(0, 6)}`
|
|
||||||
});
|
|
||||||
this.accCodeUpdate = xeroService.accCodeUpdate;
|
|
||||||
xeroService.getXeroAccountCode(this.owner.address);
|
|
||||||
this.accCodeUpdate.subscribe(accData => {
|
|
||||||
this.xeroAccCod = accData;
|
|
||||||
console.log("xeroAccCod -> [" + this.xeroAccCod + "]");
|
|
||||||
this.accCodForm.get('xAcc')!.setValue(this.xeroAccCod);
|
|
||||||
});
|
|
||||||
this.wooOwnerUpdate = wooService.ownerUpdate;
|
|
||||||
this.wooTokenUpdate = wooService.tokenUpdate;
|
|
||||||
this.wooUrlUpdate = wooService.siteurlUpdate;
|
|
||||||
wooService.getWooToken(this.owner._id!);
|
|
||||||
this.wooOwnerUpdate.subscribe(owData => {
|
|
||||||
this.wooOwner = owData;
|
|
||||||
});
|
|
||||||
this.wooTokenUpdate.subscribe(tkData => {
|
|
||||||
this.wooToken = tkData;
|
|
||||||
});
|
|
||||||
this.wooUrlUpdate.subscribe(uData => {
|
|
||||||
this.wooUrl = uData;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.settingsForm.get('vKey')!.disable();
|
|
||||||
this.linkMsg = 'Link to Xero';
|
|
||||||
this.pmtServiceURL + '';
|
|
||||||
if ( this.linked2Xero ) {
|
|
||||||
this.linkMsg = 'Relink to Xero';
|
|
||||||
this.pmtServiceURL = 'https://zgo.cash/pmtservice?owner=' +
|
|
||||||
this.owner._id +
|
|
||||||
'&invoiceNo=[INVOICENUMBER]¤cy=[CURRENCY]&amount=[AMOUNTDUE]&shortCode=[SHORTCODE]';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
safeURL(s: string){
|
|
||||||
return s.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
closeIntegration() {
|
|
||||||
if ( (this.xeroAccCod == '') && (this.linked2Xero) )
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Xero Payment confirmation disabled!!","Close",'warning');
|
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,8 +67,9 @@ export class SettingsComponent implements OnInit {
|
||||||
this.owner.currency = this.settingsForm.value.currency;
|
this.owner.currency = this.settingsForm.value.currency;
|
||||||
this.owner.zats = this.settingsForm.value.useZats;
|
this.owner.zats = this.settingsForm.value.useZats;
|
||||||
this.owner.payconf = this.settingsForm.value.useVKey;
|
this.owner.payconf = this.settingsForm.value.useVKey;
|
||||||
|
|
||||||
this.owner.viewkey = this.settingsForm.value.vKey;
|
this.owner.viewkey = this.settingsForm.value.vKey;
|
||||||
//this.owner.invoices = this.settingsForm.value.proVersion
|
|
||||||
this.dialogRef.close(this.owner);
|
this.dialogRef.close(this.owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,10 +77,6 @@ export class SettingsComponent implements OnInit {
|
||||||
this.useZats = ob.checked;
|
this.useZats = ob.checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeProVersion(ob: MatSlideToggleChange) {
|
|
||||||
this.proVersion = ob.checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
onChangeVKeyOn(ob: MatSlideToggleChange) {
|
onChangeVKeyOn(ob: MatSlideToggleChange) {
|
||||||
// console.log("Viewing key switch is " +
|
// console.log("Viewing key switch is " +
|
||||||
// ( ob.checked ? "[ON]." : "[OFF]." ) );
|
// ( ob.checked ? "[ON]." : "[OFF]." ) );
|
||||||
|
@ -184,100 +89,4 @@ export class SettingsComponent implements OnInit {
|
||||||
this.settingsForm.get('vKey')!.disable();
|
this.settingsForm.get('vKey')!.disable();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
copyUrl() {
|
|
||||||
// console.log("Inside copyUrl()");
|
|
||||||
if (navigator.clipboard) {
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText(this.pmtServiceURL);
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("ZGo URL copied to Clipboard!!","Close",'success');
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
// console.error("Error", err);
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Functionality not available for your browser. Use send button instead.","Close",'error');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copyWooOwner(){
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText(this.wooOwner);
|
|
||||||
this.notifierService.showNotification("Owner ID copied to clipboard", "Close", "success");
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService.showNotification("Copying not available in your browser", "Close", "error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copyWooToken(){
|
|
||||||
try {
|
|
||||||
navigator.clipboard.writeText(this.wooToken);
|
|
||||||
this.notifierService.showNotification("WooCommerce Token copied to clipboard", "Close", "success");
|
|
||||||
} catch (err) {
|
|
||||||
this.notifierService.showNotification("Copying not available in your browser", "Close", "error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
generateWooToken(){
|
|
||||||
this.wooService.createWooToken(this.owner._id!).subscribe(responseData => {
|
|
||||||
if (responseData.status == 202) {
|
|
||||||
this.notifierService.showNotification("WooCommerce Token generated!", "Close", "success");
|
|
||||||
this.wooService.getWooToken(this.owner._id!);
|
|
||||||
this.wooOwnerUpdate.subscribe(owData => {
|
|
||||||
this.wooOwner = owData;
|
|
||||||
});
|
|
||||||
this.wooTokenUpdate.subscribe(tkData => {
|
|
||||||
this.wooToken = tkData;
|
|
||||||
});
|
|
||||||
this.wooUrlUpdate.subscribe(uData => {
|
|
||||||
this.wooUrl = uData;
|
|
||||||
});
|
|
||||||
close();
|
|
||||||
} else {
|
|
||||||
this.notifierService.showNotification("WooCommerce Token generation failed.", "Close", "error");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
saveAccCod() {
|
|
||||||
|
|
||||||
this.xeroAccCod = this.accCodForm.value.xAcc;
|
|
||||||
console.log(">>> " + this.xeroAccCod);
|
|
||||||
if ( this.xeroAccCod.length <= 10 ) {
|
|
||||||
const obs = this.xeroService
|
|
||||||
.setXeroAccountCode(this.owner.address,
|
|
||||||
this.xeroAccCod);
|
|
||||||
obs.subscribe(responseData => {
|
|
||||||
if (responseData.status == 202) {
|
|
||||||
console.log('Account saved');
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Account Code saved!!","Close",'success');
|
|
||||||
} else {
|
|
||||||
console.log('Account not saved -> status[' + responseData.status + ']');
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Account Code not saved","Close",'error');
|
|
||||||
}
|
|
||||||
|
|
||||||
}, error => {
|
|
||||||
console.log('Error saving Account Code -> ' + error.msg)
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.notifierService
|
|
||||||
.showNotification("Invalid Account code (10 chars max.)","Close",'error');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
xeroAccCodChanged( arg: any ) {
|
|
||||||
console.log("Account Code changed: " + arg.target.value);
|
|
||||||
// console.log(arg);
|
|
||||||
this.saveAccOk = (arg.target.value != this.xeroAccCod );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
checkStatus( arg : any ) {
|
|
||||||
console.log('onChange - checkStatus');
|
|
||||||
console.log(arg.target.value);
|
|
||||||
this.saveAccOk = (arg.target.value != this.xeroAccCod );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,8 +197,4 @@ export class UserService{
|
||||||
return obs;
|
return obs;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentOwner() : Owner {
|
|
||||||
return this.dataStore.owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
[routerLink]="['/orders']">
|
[routerLink]="['/orders']">
|
||||||
View Orders
|
View Orders
|
||||||
</button>
|
</button>
|
||||||
<button mat-icon-button color="primary"
|
<button mat-raised-button color="primary"
|
||||||
(click)="openSettings()">
|
class="text" (click)="openSettings()">
|
||||||
<mat-icon class="icon">manage_accounts</mat-icon>
|
<mat-icon class="icon">manage_accounts</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<a mat-icon-button color="primary"
|
<a mat-raised-button color="primary"
|
||||||
href="https://zgo.cash/"
|
href="https://zgo.cash/"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer">
|
rel="noopener noreferrer">
|
||||||
|
|
|
@ -73,9 +73,6 @@ export class ViewerComponent implements OnInit {
|
||||||
this.ownerUpdate.subscribe((owner) => {
|
this.ownerUpdate.subscribe((owner) => {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
});
|
});
|
||||||
|
|
||||||
// console.log(this.owner._id);
|
|
||||||
|
|
||||||
this.userUpdate = userService.userUpdate;
|
this.userUpdate = userService.userUpdate;
|
||||||
this.userUpdate.subscribe((user) => {
|
this.userUpdate.subscribe((user) => {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { WoocommerceService } from './woocommerce.service';
|
|
||||||
|
|
||||||
describe('WoocommerceService', () => {
|
|
||||||
let service: WoocommerceService;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({});
|
|
||||||
service = TestBed.inject(WoocommerceService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,65 +0,0 @@
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
|
||||||
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
|
|
||||||
|
|
||||||
import { ConfigData } from './configdata';
|
|
||||||
|
|
||||||
var Buffer = require('buffer/').Buffer;
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class WoocommerceService {
|
|
||||||
beUrl = ConfigData.Be_URL;
|
|
||||||
private reqHeaders: HttpHeaders;
|
|
||||||
private ownerId: string = '';
|
|
||||||
private token: string = '';
|
|
||||||
private siteurl: string = '';
|
|
||||||
private _ownerIdUpdated: BehaviorSubject<string> = new BehaviorSubject(this.ownerId);
|
|
||||||
private _tokenUpdated: BehaviorSubject<string> = new BehaviorSubject(this.token);
|
|
||||||
private _siteurlUpdated: BehaviorSubject<string> = new BehaviorSubject(this.siteurl);
|
|
||||||
public readonly ownerUpdate: Observable<string> = this._ownerIdUpdated.asObservable();
|
|
||||||
public readonly tokenUpdate: Observable<string> = this._tokenUpdated.asObservable();
|
|
||||||
public readonly siteurlUpdate: Observable<string> = this._siteurlUpdated.asObservable();
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private http: HttpClient
|
|
||||||
) {
|
|
||||||
var auth = 'Basic ' + Buffer.from(ConfigData.UsrPwd).toString('base64');
|
|
||||||
this.reqHeaders = new HttpHeaders().set('Authorization', auth);
|
|
||||||
this._ownerIdUpdated.next(Object.assign({}, this).ownerId);
|
|
||||||
this._tokenUpdated.next(Object.assign({}, this).token);
|
|
||||||
this._siteurlUpdated.next(Object.assign({}, this).siteurl);
|
|
||||||
}
|
|
||||||
|
|
||||||
getWooToken(ownerId: string) {
|
|
||||||
const params = new HttpParams().append('ownerid', ownerId);
|
|
||||||
let obs = this.http.get<{ownerid: string, token: string, siteurl: string}>(this.beUrl + 'api/wootoken', {headers: this.reqHeaders, params: params, observe: 'response'});
|
|
||||||
obs.subscribe(tokenResponse => {
|
|
||||||
if (tokenResponse.status == 200) {
|
|
||||||
this.ownerId = tokenResponse.body!.ownerid;
|
|
||||||
this.token = tokenResponse.body!.token;
|
|
||||||
this.siteurl = tokenResponse.body!.siteurl;
|
|
||||||
this._ownerIdUpdated.next(Object.assign({}, this).ownerId);
|
|
||||||
this._tokenUpdated.next(Object.assign({}, this).token);
|
|
||||||
this._siteurlUpdated.next(Object.assign({}, this).siteurl);
|
|
||||||
} else {
|
|
||||||
console.log('No WooCommerce token found');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return obs;
|
|
||||||
}
|
|
||||||
|
|
||||||
createWooToken(ownerId: string) {
|
|
||||||
const params = new HttpParams().append('ownerid', ownerId);
|
|
||||||
let obs = this.http.post(this.beUrl+'api/wootoken', {}, {headers: this.reqHeaders, params: params, observe: 'response'});
|
|
||||||
obs.subscribe(responseData => {
|
|
||||||
if (responseData.status == 202) {
|
|
||||||
console.log('WooToken created.');
|
|
||||||
} else {
|
|
||||||
console.log('WooToken creation failed.');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return obs;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { XeroService } from './xero.service';
|
|
||||||
|
|
||||||
describe('XeroService', () => {
|
|
||||||
let service: XeroService;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({});
|
|
||||||
service = TestBed.inject(XeroService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,103 +0,0 @@
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
|
||||||
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
|
|
||||||
|
|
||||||
import { ConfigData } from './configdata';
|
|
||||||
|
|
||||||
var Buffer = require('buffer/').Buffer;
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class XeroService {
|
|
||||||
beUrl = ConfigData.Be_URL;
|
|
||||||
clientId: string = '';
|
|
||||||
//clientSecret: string = '';
|
|
||||||
xeroToken: any = {
|
|
||||||
accessToken: '',
|
|
||||||
refreshToken: '',
|
|
||||||
expiresIn: 0,
|
|
||||||
scope: '',
|
|
||||||
tokenType: ''
|
|
||||||
};
|
|
||||||
xeroAcc: string = '';
|
|
||||||
savedAcc : boolean = false;
|
|
||||||
|
|
||||||
public savedAccObs = new Observable((observer) => {
|
|
||||||
console.log("starting savedAccObs");
|
|
||||||
setTimeout(() => {observer.next(this.savedAcc)},1000);
|
|
||||||
})
|
|
||||||
|
|
||||||
private _clientIdUpdated: BehaviorSubject<string> = new BehaviorSubject(this.clientId);
|
|
||||||
//private _clientSecretUpdated: BehaviorSubject<string> = new BehaviorSubject(this.clientSecret);
|
|
||||||
private _tokenUpdated: BehaviorSubject<any> = new BehaviorSubject(this.xeroToken);
|
|
||||||
private _accCodeUpdated: BehaviorSubject<string> = new BehaviorSubject(this.xeroAcc);
|
|
||||||
public readonly clientIdUpdate: Observable<string> = this._clientIdUpdated.asObservable();
|
|
||||||
//public readonly clientSecretUpdate: Observable<string> = this._clientSecretUpdated.asObservable();
|
|
||||||
public readonly tokenUpdate: Observable<any> = this._tokenUpdated.asObservable();
|
|
||||||
public readonly accCodeUpdate: Observable<string> = this._accCodeUpdated.asObservable();
|
|
||||||
private reqHeaders: HttpHeaders;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private http: HttpClient
|
|
||||||
) {
|
|
||||||
var auth = 'Basic ' + Buffer.from(ConfigData.UsrPwd).toString('base64');
|
|
||||||
this.reqHeaders = new HttpHeaders().set('Authorization', auth);
|
|
||||||
this.getXeroConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
getXeroConfig(){
|
|
||||||
let obs = this.http.get<{message: string, xeroConfig: any}>(this.beUrl+'api/xero', { headers:this.reqHeaders, observe: 'response'});
|
|
||||||
|
|
||||||
obs.subscribe(xeroDataResponse => {
|
|
||||||
if (xeroDataResponse.status == 200) {
|
|
||||||
this.clientId = xeroDataResponse.body!.xeroConfig.clientId;
|
|
||||||
//this.clientSecret = xeroDataResponse.body!.xeroConfig.clientSecret;
|
|
||||||
this._clientIdUpdated.next(Object.assign({}, this).clientId);
|
|
||||||
//this._clientSecretUpdated.next(Object.assign({}, this).clientSecret);
|
|
||||||
} else {
|
|
||||||
console.log('No config in DB!');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return obs;
|
|
||||||
}
|
|
||||||
|
|
||||||
getXeroAccessToken(code: string, address: string){
|
|
||||||
const params = new HttpParams().append('code', code).append('address', address);
|
|
||||||
let obs = this.http.get(this.beUrl + 'api/xerotoken' , {headers: this.reqHeaders, params: params, observe: 'response'});
|
|
||||||
return obs;
|
|
||||||
}
|
|
||||||
|
|
||||||
getXeroAccountCode(address: string){
|
|
||||||
const params = new HttpParams().append('address', address);
|
|
||||||
let obs = this.http.get<{message: string, code: string}>(this.beUrl + 'api/xeroaccount', {headers: this.reqHeaders, params: params, observe: 'response'});
|
|
||||||
obs.subscribe(accountResponse => {
|
|
||||||
if (accountResponse.status == 200) {
|
|
||||||
this.xeroAcc = accountResponse.body!.code;
|
|
||||||
this._accCodeUpdated.next(Object.assign({}, this).xeroAcc);
|
|
||||||
} else {
|
|
||||||
console.log('No account in DB');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return obs;
|
|
||||||
}
|
|
||||||
|
|
||||||
setXeroAccountCode(address: string, code: string) {
|
|
||||||
|
|
||||||
const params = new HttpParams().append('address', address).append('code', code);
|
|
||||||
let obs = this.http.post(this.beUrl + 'api/xeroaccount', {}, {headers: this.reqHeaders, params: params, observe: 'response'});
|
|
||||||
/*
|
|
||||||
obs.subscribe(responseData => {
|
|
||||||
if (responseData.status == 202) {
|
|
||||||
console.log('Account saved');
|
|
||||||
this.savedAcc = true;
|
|
||||||
}
|
|
||||||
}, error => {
|
|
||||||
this.savedAcc = false;
|
|
||||||
console.log("error : " + error.msg)
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
return obs;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
.text {
|
|
||||||
font-family: 'Spartan', sans-serif;
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
<div *ngIf="!flag" align="center" class="text">
|
|
||||||
<h1>Connecting to Xero...</h1>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="flag" align="center" class="text">
|
|
||||||
<h1>Connected to Xero!</h1>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { TestComponent } from './test.component';
|
|
||||||
|
|
||||||
describe('TestComponent', () => {
|
|
||||||
let component: TestComponent;
|
|
||||||
let fixture: ComponentFixture<TestComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ TestComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(TestComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,98 +0,0 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
|
||||||
import { UserService } from '../user.service';
|
|
||||||
import { XeroService } from '../xero.service';
|
|
||||||
import { Owner } from '../owner.model';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
|
|
||||||
var Buffer = require('buffer/').Buffer;
|
|
||||||
|
|
||||||
function sleep(ms:number) {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function redirect(r: Router) {
|
|
||||||
await sleep(2000);
|
|
||||||
r.navigate(['/shop']);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-xeroreg',
|
|
||||||
templateUrl: './xeroreg.component.html',
|
|
||||||
styleUrls: ['./xeroreg.component.css']
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
export class XeroRegComponent implements OnInit {
|
|
||||||
public owner:Owner = {
|
|
||||||
address: '',
|
|
||||||
name: '',
|
|
||||||
currency: '',
|
|
||||||
tax: false,
|
|
||||||
taxValue:0,
|
|
||||||
vat: false,
|
|
||||||
vatValue: 0,
|
|
||||||
first: '',
|
|
||||||
last: '',
|
|
||||||
email: '',
|
|
||||||
street: '',
|
|
||||||
city: '',
|
|
||||||
state: '',
|
|
||||||
postal: '',
|
|
||||||
phone: '',
|
|
||||||
paid: false,
|
|
||||||
website: '',
|
|
||||||
country: '',
|
|
||||||
zats: false,
|
|
||||||
invoices: false,
|
|
||||||
expiration: new Date(Date.now()).toISOString(),
|
|
||||||
payconf: false,
|
|
||||||
viewkey: '',
|
|
||||||
crmToken: ''
|
|
||||||
};
|
|
||||||
public ownerUpdate:Observable<Owner>;
|
|
||||||
public flag: boolean = false;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public xeroService: XeroService,
|
|
||||||
public userService: UserService,
|
|
||||||
private router: Router,
|
|
||||||
private activatedRoute: ActivatedRoute
|
|
||||||
) {
|
|
||||||
this.ownerUpdate = userService.ownerUpdate;
|
|
||||||
this.ownerUpdate.subscribe((owner) => {
|
|
||||||
this.owner = owner;
|
|
||||||
});
|
|
||||||
this.userService.findUser();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
|
||||||
this.ownerUpdate.subscribe((owner) => {
|
|
||||||
this.owner = owner;
|
|
||||||
this.activatedRoute.queryParams.subscribe((params) => {
|
|
||||||
console.log(params);
|
|
||||||
if (params.state === this.owner.address.substring(0,6)) {
|
|
||||||
this.xeroService.getXeroAccessToken(params.code, this.owner.address).subscribe(tokenData => {
|
|
||||||
if (tokenData.status == 200) {
|
|
||||||
console.log(tokenData.body!);
|
|
||||||
this.flag = true;
|
|
||||||
redirect(this.router);
|
|
||||||
} else {
|
|
||||||
console.log('Error: '+tokenData.status);
|
|
||||||
this.flag = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log('Error: State mismatch');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 78 KiB |
Binary file not shown.
Before Width: | Height: | Size: 91 KiB |
Binary file not shown.
Binary file not shown.
|
@ -1,31 +1,11 @@
|
||||||
//@import "@angular/material/_theming";
|
@import "@angular/material/_theming";
|
||||||
@use '@angular/material' as mat;
|
|
||||||
|
|
||||||
@include mat.core();
|
@include mat-core();
|
||||||
|
|
||||||
$custom-theme-primary: mat.define-palette(mat.$deep-orange-palette, 500);
|
$custom-theme-primary: mat-palette($mat-deep-orange);
|
||||||
$custom-theme-accent: mat.define-palette(mat.$light-blue-palette, 100, 50, 200);
|
$custom-theme-accent: mat-palette($mat-light-blue, A200, A100, A400);
|
||||||
$custom-theme-warn: mat.define-palette(mat.$red-palette);
|
$custom-theme-warn: mat-palette($mat-red);
|
||||||
|
|
||||||
//$custom-theme: mat.define-light-theme($custom-theme-primary, $custom-theme-accent);
|
$custom-theme: mat-light-theme($custom-theme-primary, $custom-theme-accent, $custom-theme-warn);
|
||||||
|
|
||||||
$my-theme: mat.define-light-theme(
|
@include angular-material-theme($custom-theme);
|
||||||
(color: (
|
|
||||||
primary: $custom-theme-primary,
|
|
||||||
accent: $custom-theme-accent,
|
|
||||||
warn: $custom-theme-warn
|
|
||||||
),
|
|
||||||
typography: mat.define-typography-config(),
|
|
||||||
density: 0
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
//@include angular-material-theme($custom-theme);
|
|
||||||
//@include mat.core-theme($my-theme);
|
|
||||||
|
|
||||||
//@include mat.button-theme($my-theme);
|
|
||||||
//@include mat.toolbar-theme($my-theme);
|
|
||||||
//@include mat.card-theme($my-theme);
|
|
||||||
//@include mat.dialog-theme($my-theme);
|
|
||||||
|
|
||||||
@include mat.all-component-themes($my-theme);
|
|
||||||
|
|
Loading…
Reference in a new issue