Implement Xero service
This commit is contained in:
parent
451bf6745c
commit
7ef0e16df5
10 changed files with 152 additions and 33 deletions
|
@ -34,6 +34,8 @@ export class InvoiceComponent implements OnInit {
|
||||||
total: 0,
|
total: 0,
|
||||||
totalZec: 0,
|
totalZec: 0,
|
||||||
paid: false,
|
paid: false,
|
||||||
|
externalInvoice: '',
|
||||||
|
shortCode: '',
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
qty: 1,
|
qty: 1,
|
||||||
|
|
|
@ -41,6 +41,8 @@ export class OrderComponent implements OnInit{
|
||||||
total:0,
|
total:0,
|
||||||
totalZec: 0,
|
totalZec: 0,
|
||||||
paid: false,
|
paid: false,
|
||||||
|
externalInvoice: '',
|
||||||
|
shortCode: '',
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
qty: 1,
|
qty: 1,
|
||||||
|
|
|
@ -11,5 +11,7 @@ export interface Order {
|
||||||
total: number,
|
total: number,
|
||||||
totalZec: number,
|
totalZec: number,
|
||||||
lines: LineItem[],
|
lines: LineItem[],
|
||||||
paid: boolean
|
paid: boolean,
|
||||||
|
externalInvoice: string,
|
||||||
|
shortCode: string
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ export class OrderService {
|
||||||
total: 0,
|
total: 0,
|
||||||
totalZec: 0,
|
totalZec: 0,
|
||||||
paid: false,
|
paid: false,
|
||||||
|
externalInvoice: '',
|
||||||
|
shortCode: '',
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
qty: 1,
|
qty: 1,
|
||||||
|
@ -163,6 +165,8 @@ export class OrderService {
|
||||||
price: 0,
|
price: 0,
|
||||||
total: 0,
|
total: 0,
|
||||||
paid: false,
|
paid: false,
|
||||||
|
externalInvoice: '',
|
||||||
|
shortCode: '',
|
||||||
lines: [lineItem]
|
lines: [lineItem]
|
||||||
};
|
};
|
||||||
let obs = this.http.post<{message: string, order: Order}>(this.beUrl+'api/order', {payload: order}, { headers: this.reqHeaders });
|
let obs = this.http.post<{message: string, order: Order}>(this.beUrl+'api/order', {payload: order}, { headers: this.reqHeaders });
|
||||||
|
@ -190,6 +194,8 @@ export class OrderService {
|
||||||
totalZec: 0,
|
totalZec: 0,
|
||||||
price: 0,
|
price: 0,
|
||||||
paid: false,
|
paid: false,
|
||||||
|
externalInvoice: '',
|
||||||
|
shortCode: '',
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
qty: 1,
|
qty: 1,
|
||||||
|
@ -223,6 +229,8 @@ export class OrderService {
|
||||||
total: 0,
|
total: 0,
|
||||||
totalZec: 0,
|
totalZec: 0,
|
||||||
paid: false,
|
paid: false,
|
||||||
|
externalInvoice: '',
|
||||||
|
shortCode: '',
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
qty: 1,
|
qty: 1,
|
||||||
|
|
|
@ -51,6 +51,8 @@ export class ReceiptService {
|
||||||
total: 0,
|
total: 0,
|
||||||
totalZec: 0,
|
totalZec: 0,
|
||||||
paid: false,
|
paid: false,
|
||||||
|
externalInvoice: '',
|
||||||
|
shortCode: '',
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
qty: 1,
|
qty: 1,
|
||||||
|
|
|
@ -25,6 +25,8 @@ export class ReceiptComponent implements OnInit {
|
||||||
total: 0,
|
total: 0,
|
||||||
totalZec: 0,
|
totalZec: 0,
|
||||||
paid: false,
|
paid: false,
|
||||||
|
externalInvoice: '',
|
||||||
|
shortCode: '',
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
qty: 1,
|
qty: 1,
|
||||||
|
|
|
@ -2,12 +2,9 @@ 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 { User } from '../user.model';
|
import { Observable } from 'rxjs';
|
||||||
import { Owner } from '../owner.model';
|
import { Owner } from '../owner.model';
|
||||||
|
import { XeroService } from '../xero.service';
|
||||||
var crypto = require('sha.js');
|
|
||||||
var URLSafeBase64 = require('urlsafe-base64');
|
|
||||||
var Buffer = require('buffer/').Buffer;
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-settings',
|
selector: 'app-settings',
|
||||||
|
@ -41,9 +38,12 @@ export class SettingsComponent implements OnInit {
|
||||||
];
|
];
|
||||||
xeroLink: string = '';
|
xeroLink: string = '';
|
||||||
localToken: string = '';
|
localToken: string = '';
|
||||||
|
clientId: string = '';
|
||||||
|
clientIdUpdate: Observable<string>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private fb: UntypedFormBuilder,
|
private fb: UntypedFormBuilder,
|
||||||
|
public xeroService: XeroService,
|
||||||
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;
|
||||||
|
@ -59,15 +59,16 @@ export class SettingsComponent implements OnInit {
|
||||||
this.settingsForm.get('vKey')!.enable();
|
this.settingsForm.get('vKey')!.enable();
|
||||||
}
|
}
|
||||||
this.owner = data;
|
this.owner = data;
|
||||||
|
|
||||||
|
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%2Ftest&scope=accounting.transactions offline_access&state=1234`
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.localToken = localStorage.getItem('s4z_token')!;
|
|
||||||
const hash = crypto('sha256').update(this.owner.address).digest('base64');
|
|
||||||
//const hash2 = URLSafeBase64.encode(crypto('sha256').update(this.localToken));
|
|
||||||
console.log(hash);
|
|
||||||
console.log(this.safeURL(hash));
|
|
||||||
this.xeroLink = `https://login.xero.com/identity/connect/authorize?response_type=code&client_id=CA4A8C8DA0AE462186B34DBD42074D2D&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Ftest&scope=accounting.transactions offline_access&state=1234`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
safeURL(s: string){
|
safeURL(s: string){
|
||||||
|
|
16
src/app/xero.service.spec.ts
Normal file
16
src/app/xero.service.spec.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
});
|
73
src/app/xero.service.ts
Normal file
73
src/app/xero.service.ts
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
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: ''
|
||||||
|
};
|
||||||
|
private _clientIdUpdated: BehaviorSubject<string> = new BehaviorSubject(this.clientId);
|
||||||
|
private _clientSecretUpdated: BehaviorSubject<string> = new BehaviorSubject(this.clientSecret);
|
||||||
|
private _tokenUpdated: BehaviorSubject<any> = new BehaviorSubject(this.xeroToken);
|
||||||
|
public readonly clientIdUpdate: Observable<string> = this._clientIdUpdated.asObservable();
|
||||||
|
public readonly clientSecretUpdate: Observable<string> = this._clientSecretUpdated.asObservable();
|
||||||
|
public readonly tokenUpdate: Observable<any> = this._tokenUpdated.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){
|
||||||
|
this.getXeroConfig().subscribe(xeroDataResponse => {
|
||||||
|
console.log('XAT: '+this.clientId);
|
||||||
|
var xeroAuth = 'Basic ' + Buffer.from(`${this.clientId}:${this.clientSecret}`).toString('base64');
|
||||||
|
var xeroHeaders = new HttpHeaders().set('Authorization', xeroAuth).append('Content-Type', 'application/x-www-form-urlencoded');
|
||||||
|
let obs = this.http.post('https://identity.xero.com/connect/token', `grant_type=authorization_code&code=${code}&redirect_uri=http://localhost:4200/test` , {headers: xeroHeaders, observe: 'response'})
|
||||||
|
obs.subscribe(tokenData => {
|
||||||
|
if (tokenData.status == 200) {
|
||||||
|
console.log(tokenData.body!);
|
||||||
|
this.xeroToken = tokenData.body!;
|
||||||
|
this._tokenUpdated.next(Object.assign({}, this).xeroToken);
|
||||||
|
} else {
|
||||||
|
console.log('Error: '+tokenData.status);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,8 @@ import { ActivatedRoute } from '@angular/router';
|
||||||
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
|
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
|
||||||
import { UserService } from '../user.service';
|
import { UserService } from '../user.service';
|
||||||
import { Owner } from '../owner.model';
|
import { Owner } from '../owner.model';
|
||||||
//import { XeroClient } from 'xero-node';
|
import { Observable } from 'rxjs';
|
||||||
|
import { XeroService } from '../xero.service';
|
||||||
|
|
||||||
var Buffer = require('buffer/').Buffer;
|
var Buffer = require('buffer/').Buffer;
|
||||||
|
|
||||||
|
@ -16,26 +17,36 @@ var Buffer = require('buffer/').Buffer;
|
||||||
|
|
||||||
export class XeroRegComponent implements OnInit {
|
export class XeroRegComponent implements OnInit {
|
||||||
|
|
||||||
reqHeaders: HttpHeaders;
|
clientId: string = '';
|
||||||
constructor(private http: HttpClient,
|
clientSecret: string = '';
|
||||||
|
xeroToken: any;
|
||||||
|
clientIdUpdate: Observable<string>;
|
||||||
|
clientSecretUpdate: Observable<string>;
|
||||||
|
tokenUpdate: Observable<any>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public xeroService: XeroService,
|
||||||
private activatedRoute: ActivatedRoute
|
private activatedRoute: ActivatedRoute
|
||||||
) {
|
) {
|
||||||
//const secret = 'J8Ft70Tk6theIFNYpuDRPvzuc271_dyjq7EJlzPFh8lpXXvV';
|
this.tokenUpdate = xeroService.tokenUpdate;
|
||||||
var auth = 'Basic ' + Buffer.from('CA4A8C8DA0AE462186B34DBD42074D2D:J8Ft70Tk6theIFNYpuDRPvzuc271_dyjq7EJlzPFh8lpXXvV').toString('base64');
|
this.clientIdUpdate = xeroService.clientIdUpdate;
|
||||||
this.reqHeaders = new HttpHeaders().set('Authorization', auth).append('Content-Type', 'application/x-www-form-urlencoded');
|
xeroService.getXeroConfig();
|
||||||
//this.session = localStorage.getItem('s4z_token')!;
|
this.clientIdUpdate.subscribe(clientId => {
|
||||||
//this.ownerUpdate = userService.ownerUpdate;
|
this.clientId = clientId;
|
||||||
//this.ownerUpdate.subscribe(ownerData => {
|
});
|
||||||
//this.owner = ownerData;
|
this.clientSecretUpdate = xeroService.clientSecretUpdate;
|
||||||
//});
|
this.clientSecretUpdate.subscribe(clientSecret => {
|
||||||
|
this.clientSecret = clientSecret;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.activatedRoute.queryParams.subscribe((params) => {
|
this.activatedRoute.queryParams.subscribe((params) => {
|
||||||
console.log(params);
|
console.log(params);
|
||||||
this.http.post('https://identity.xero.com/connect/token', `grant_type=authorization_code&code=${params.code}&redirect_uri=http://localhost:4200/test` , {headers: this.reqHeaders, observe: 'response'})
|
this.xeroService.getXeroAccessToken(params.code)
|
||||||
.subscribe(responseData => {
|
this.tokenUpdate.subscribe(token => {
|
||||||
console.log(responseData);
|
console.log(token);
|
||||||
|
this.xeroToken = token;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue