Merge pull request #23 from Pear-Trading/Release-v0.0.2

Release v0.0.2
This commit is contained in:
Tom Bloor 2017-09-28 14:38:34 +01:00 committed by GitHub
commit 1171f935a7
40 changed files with 636 additions and 225 deletions

View file

@ -24,9 +24,10 @@
], ],
"environmentSource": "environments/environment.ts", "environmentSource": "environments/environment.ts",
"environments": { "environments": {
"dev": "environments/environment.ts", "dev": "environments/environment.dev.ts",
"prod": "environments/environment.prod.ts", "prod": "environments/environment.prod.ts",
"local": "environments/environment.local.ts" "local": "environments/environment.local.ts",
"ci": "environments/environment.ci.ts"
} }
} }
], ],

3
.gitignore vendored
View file

@ -43,6 +43,9 @@ testem.log
# local env variable # local env variable
/src/environments/environment.local.ts /src/environments/environment.local.ts
/src/environments/environment.prod.ts
/src/environments/environment.dev.ts
/src/environments/environment.ci.ts
# ========================= # =========================
# Operating System Files # Operating System Files

View file

@ -3,6 +3,8 @@ addons:
language: node_js language: node_js
node_js: node_js:
- 8 - 8
before_install:
- openssl aes-256-cbc -K $encrypted_9d2af3734b6c_key -iv $encrypted_9d2af3734b6c_iv -in src/environments/environment.ci.ts.enc -out src/environments/environment.ci.ts -d
before_script: before_script:
- export DISPLAY=:99.0 - export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start - sh -e /etc/init.d/xvfb start

View file

@ -2,6 +2,15 @@
# Next Release # Next Release
# v0.0.2
* Supplier map added to organisation view
* Fix various linter errors
* Payroll Log Data added
* Fixed register box view on login page
* Made the form reset properly if adding a new one
* Added better error messages on register and account edit
# v0.0.1 # v0.0.1
* Added Travis Testing * Added Travis Testing

23
bin/build-releases Executable file
View file

@ -0,0 +1,23 @@
#! /bin/bash
VERSION=`git describe --tags`
echo "Building releases for $VERSION"
echo "Building Prod Release..."
ng build --prod
tar -czf ../LocalLoop-Web-prod-$VERSION.tar.gz dist
echo "Building Dev Release..."
ng build --dev
tar -cvzf ../LocalLoop-Web-dev-$VERSION.tar.gz dist
echo "Cleaning up build artefacts..."
rm -rf dist
echo "Done"

9
package-lock.json generated
View file

@ -1,9 +1,14 @@
{ {
"name": "coreui-angular", "name": "localloop-web",
"version": "1.0.0-alpha.5", "version": "0.0.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
"@agm/core": {
"version": "1.0.0-beta.1",
"resolved": "https://registry.npmjs.org/@agm/core/-/core-1.0.0-beta.1.tgz",
"integrity": "sha512-IVwQGmcaE42SmYY2e5QwqOC0vrSXZCW8BhATY0Vpy3NjbiydSXi9T81hVqKLvuKaB3ves1sv3W++SB1Wj+5B6A=="
},
"@angular-devkit/build-optimizer": { "@angular-devkit/build-optimizer": {
"version": "0.0.13", "version": "0.0.13",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.0.13.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.0.13.tgz",

View file

@ -1,6 +1,6 @@
{ {
"name": "localloop-web", "name": "localloop-web",
"version": "0.0.1", "version": "0.0.2",
"description": "LocalLoop Web - Web interface for LocalLoop app", "description": "LocalLoop Web - Web interface for LocalLoop app",
"author": "", "author": "",
"url": "http://www.peartrade.org", "url": "http://www.peartrade.org",
@ -10,13 +10,15 @@
"start": "ng serve", "start": "ng serve",
"build": "ng build", "build": "ng build",
"test": "ng test", "test": "ng test",
"test:once": "ng test --watch=false", "test:ci": "ng test --watch=false --env=ci",
"lint": "ng lint", "lint": "ng lint",
"e2e": "ng e2e", "e2e": "ng e2e",
"ci": "npm run test:once && npm run e2e" "e2e:ci": "ng e2e --env=ci",
"ci": "npm run test:ci && npm run e2e:ci"
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@agm/core": "^1.0.0-beta.1",
"@angular/common": "4.0.3", "@angular/common": "4.0.3",
"@angular/compiler": "4.0.3", "@angular/compiler": "4.0.3",
"@angular/core": "4.0.3", "@angular/core": "4.0.3",

View file

@ -8,13 +8,13 @@ export class AuthGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (localStorage.getItem('sessionKey')) { if (localStorage.getItem('sessionKey')) {
console.log('session key found') console.log('session key found');
// logged in so return true // logged in so return true
return true; return true;
} }
// not logged in so redirect to login page with the return url // not logged in so redirect to login page with the return url
console.log('no session key found') console.log('no session key found');
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }}); this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
return false; return false;
} }

View file

@ -37,7 +37,7 @@
</form> </form>
</div> </div>
</div> </div>
<div class="card card-inverse card-primary py-5 d-md-down-none" style="width:44%"> <div class="card card-inverse card-primary py-5">
<div class="card-block text-center"> <div class="card-block text-center">
<div> <div>
<h2>Sign up</h2> <h2>Sign up</h2>

View file

@ -6,7 +6,7 @@
<div class="card-block p-4"> <div class="card-block p-4">
<h1>Register</h1> <h1>Register</h1>
<p class="text-muted">Create your account</p> <p class="text-muted">Create your account</p>
<!-- <div class="input-group mb-3"> <!-- <div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-people"></i></span> <span class="input-group-addon"><i class="icon-people"></i></span>
<select required class="form-control" type="text" formControlName="usertype"> <select required class="form-control" type="text" formControlName="usertype">
@ -25,7 +25,7 @@
<span class="input-group-addon">@</span> <span class="input-group-addon">@</span>
<input type="text" class="form-control" formControlName="email" placeholder="Email"> <input type="text" class="form-control" formControlName="email" placeholder="Email">
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-lock"></i></span> <span class="input-group-addon"><i class="icon-lock"></i></span>
<input type="password" class="form-control" formControlName="password" placeholder="Password"> <input type="password" class="form-control" formControlName="password" placeholder="Password">
@ -35,7 +35,7 @@
<span class="input-group-addon"><i class="icon-lock"></i></span> <span class="input-group-addon"><i class="icon-lock"></i></span>
<input type="password" class="form-control" formControlName="confirmpassword" placeholder="Repeat password"> <input type="password" class="form-control" formControlName="confirmpassword" placeholder="Repeat password">
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-people"></i></span> <span class="input-group-addon"><i class="icon-people"></i></span>
<select required class="form-control" type="text" formControlName="usertype"> <select required class="form-control" type="text" formControlName="usertype">
@ -45,7 +45,7 @@
</select> </select>
</div> </div>
</form> </form>
<div [ngSwitch]="signupForm.getForm().value.usertype"> <div [ngSwitch]="signupForm.getForm().value.usertype">
<div *ngSwitchCase="'customer'" > <div *ngSwitchCase="'customer'" >
<form [formGroup]="customerForm.getForm()" (ngSubmit)="onSubmitCustomer()"> <form [formGroup]="customerForm.getForm()" (ngSubmit)="onSubmitCustomer()">
@ -53,17 +53,17 @@
<span class="input-group-addon"><i class="icon-user"></i></span> <span class="input-group-addon"><i class="icon-user"></i></span>
<input type="text" class="form-control" formControlName="display_name" placeholder="Display Name"> <input type="text" class="form-control" formControlName="display_name" placeholder="Display Name">
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-user"></i></span> <span class="input-group-addon"><i class="icon-user"></i></span>
<input type="text" class="form-control" formControlName="full_name" placeholder="Full Name"> <input type="text" class="form-control" formControlName="full_name" placeholder="Full Name">
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-user"></i></span> <span class="input-group-addon"><i class="icon-user"></i></span>
<input type="text" class="form-control" formControlName="postcode" placeholder="Postcode"> <input type="text" class="form-control" formControlName="postcode" placeholder="Postcode">
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-addon">Year of Birth</span> <span class="input-group-addon">Year of Birth</span>
<select class="form-control" type="text" formControlName="year_of_birth"> <select class="form-control" type="text" formControlName="year_of_birth">
@ -80,9 +80,9 @@
<span class="input-group-addon"><i class="icon-user"></i></span> <span class="input-group-addon"><i class="icon-user"></i></span>
<input type="text" class="form-control" formControlName="name" placeholder="Organisation Name"> <input type="text" class="form-control" formControlName="name" placeholder="Organisation Name">
</div> </div>
<!-- Uses the UK SIC 2007 classifications for sector as used by ONS --> <!-- Uses the UK SIC 2007 classifications for sector as used by ONS -->
<div class="input-group mb-3"> <div class="input-group mb-3">
<select required class="form-control" type="text" formControlName="sector"> <select required class="form-control" type="text" formControlName="sector">
<option value=''>Select Organisation Sector</option> <option value=''>Select Organisation Sector</option>
@ -108,17 +108,17 @@
<option value='T'>Household Domestic Business</option> <option value='T'>Household Domestic Business</option>
</select> </select>
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-user"></i></span> <span class="input-group-addon"><i class="icon-user"></i></span>
<input type="text" class="form-control" formControlName="street_name" placeholder="Street Name"> <input type="text" class="form-control" formControlName="street_name" placeholder="Street Name">
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-user"></i></span> <span class="input-group-addon"><i class="icon-user"></i></span>
<input type="text" class="form-control" formControlName="town" placeholder="Town"> <input type="text" class="form-control" formControlName="town" placeholder="Town">
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-user"></i></span> <span class="input-group-addon"><i class="icon-user"></i></span>
<input type="text" class="form-control" formControlName="postcode" placeholder="Postcode"> <input type="text" class="form-control" formControlName="postcode" placeholder="Postcode">
@ -137,7 +137,7 @@
Form validation failed, please ensure the form is filled correctly. Form validation failed, please ensure the form is filled correctly.
</div> </div>
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert"> <div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
Failed to send to server, please try again later. {{registerStatusError}}
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,6 +1,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Validators, FormBuilder, FormGroup } from '@angular/forms'; import { Validators, FormBuilder, FormGroup } from '@angular/forms';
import { ValidationManager } from "ng2-validation-manager"; import { ValidationManager } from 'ng2-validation-manager';
import { Http, Response } from '@angular/http'; import { Http, Response } from '@angular/http';
import { ApiService } from '../providers/api-service'; import { ApiService } from '../providers/api-service';
import {Router } from '@angular/router'; import {Router } from '@angular/router';
@ -16,117 +16,136 @@ export class RegisterComponent {
organisationForm: ValidationManager; organisationForm: ValidationManager;
years: Object[]; years: Object[];
registerStatus: any; registerStatus: any;
registerStatusError = 'Error received, please try again.';
constructor(
private http: Http,
private formBuilder: FormBuilder,
private router: Router,
private api: ApiService,
) {
this.years = [];
let max = new Date().getFullYear() - 10,
min = max - 140;
for (let i = max; i>=min; i--){ constructor(
this.years.push(i); private http: Http,
} private formBuilder: FormBuilder,
this.signupForm = new ValidationManager({ private router: Router,
token: 'required', private api: ApiService,
usertype: 'required', ) {
email: 'required|email', this.years = [];
password: 'required', const max = new Date().getFullYear() - 10,
confirmpassword: 'required|equalTo:password' min = max - 140;
});
this.customerForm = new ValidationManager({ for (let i = max; i >= min; i--) {
display_name: 'required', this.years.push(i);
full_name: 'required',
postcode: 'required',
year_of_birth:'required',
});
this.organisationForm = new ValidationManager({
name: 'required',
sector: 'required',
street_name: 'required',
town: 'required',
postcode: 'required',
});
} }
this.signupForm = new ValidationManager({
token: 'required',
usertype: 'required',
email: 'required|email',
password: 'required',
confirmpassword: 'required|equalTo:password'
});
this.customerForm = new ValidationManager({
display_name: 'required',
full_name: 'required',
postcode: 'required',
year_of_birth: 'required',
});
this.organisationForm = new ValidationManager({
name: 'required',
sector: 'required',
street_name: 'required',
town: 'required',
postcode: 'required',
});
}
onSubmitCustomer() { onSubmitCustomer() {
console.log(this.signupForm.isValid()); console.log(this.signupForm.isValid());
if (!this.signupForm.isValid() && !this.customerForm.isValid()) { if (!this.signupForm.isValid() && !this.customerForm.isValid()) {
console.log("Not Valid!"); console.log('Not Valid!');
this.registerStatus = "validation_failed"; this.registerStatus = 'validation_failed';
console.log(this.registerStatus); console.log(this.registerStatus);
return; return;
} }
let signupForm = this.signupForm.getForm().value; const signupForm = this.signupForm.getForm().value;
let customerForm = this.customerForm.getForm().value; const customerForm = this.customerForm.getForm().value;
let data = { const data = {
token: signupForm.token, token: signupForm.token,
usertype: signupForm.usertype, usertype: signupForm.usertype,
email: signupForm.email, email: signupForm.email,
password: signupForm.password, password: signupForm.password,
display_name: customerForm.display_name, display_name: customerForm.display_name,
full_name: customerForm.full_name, full_name: customerForm.full_name,
postcode: customerForm.postcode, postcode: customerForm.postcode,
year_of_birth:customerForm.year_of_birth, year_of_birth: customerForm.year_of_birth,
}; };
console.log(data); console.log(data);
this.api this.api
.register(data) .register(data)
.subscribe( .subscribe(
result => { result => {
console.log('registered!'); console.log('registered!');
this.registerStatus = "success"; this.registerStatus = 'success';
console.log(this.registerStatus); console.log(this.registerStatus);
this.router.navigate(['/dashboard']); this.router.navigate(['/dashboard']);
}, },
error => { error => {
console.log( error._body ); console.log('Register Error');
this.registerStatus = "send_failed"; console.log(error);
console.log(this.registerStatus) try {
console.log(error.error);
const jsonError = error.json();
console.log('boop');
this.registerStatusError = '"' + jsonError.error + '" Error, ' + jsonError.message;
} catch (e) {
this.registerStatusError = 'There was a server error, please try again later.';
}
this.registerStatus = 'send_failed';
console.log(this.registerStatus);
} }
); );
} }
onSubmitOrganisation() { onSubmitOrganisation() {
console.log(this.signupForm.isValid()); console.log(this.signupForm.isValid());
if (!this.signupForm.isValid() || !this.organisationForm.isValid()) { if (!this.signupForm.isValid() || !this.organisationForm.isValid()) {
console.log("Not Valid!"); console.log('Not Valid!');
this.registerStatus = "validation_failed"; this.registerStatus = 'validation_failed';
console.log(this.registerStatus); console.log(this.registerStatus);
return; return;
} }
let signupForm = this.signupForm.getForm().value; const signupForm = this.signupForm.getForm().value;
let organisationForm = this.organisationForm.getForm().value; const organisationForm = this.organisationForm.getForm().value;
let data = { const data = {
token: signupForm.token, token: signupForm.token,
usertype: signupForm.usertype, usertype: signupForm.usertype,
email: signupForm.email, email: signupForm.email,
password: signupForm.password, password: signupForm.password,
name: organisationForm.name, name: organisationForm.name,
sector: organisationForm.sector, sector: organisationForm.sector,
street_name: organisationForm.street_name, street_name: organisationForm.street_name,
town: organisationForm.town, town: organisationForm.town,
postcode: organisationForm.postcode, postcode: organisationForm.postcode,
}; };
console.log(data); console.log(data);
this.api this.api
.register(data) .register(data)
.subscribe( .subscribe(
result => { result => {
console.log('registered!'); console.log('registered!');
this.registerStatus = "success"; this.registerStatus = 'success';
console.log(this.registerStatus); console.log(this.registerStatus);
this.router.navigate(['/dashboard']); this.router.navigate(['/dashboard']);
}, },
error => { error => {
console.log( error._body ); console.log('Register Error');
this.registerStatus = "send_failed"; console.log(error);
try {
console.log(error.error);
const jsonError = error.json();
console.log('boop');
this.registerStatusError = '"' + jsonError.error + '" Error, ' + jsonError.message;
} catch (e) {
this.registerStatusError = 'There was a server error, please try again later.';
}
this.registerStatus = 'send_failed';
console.log(this.registerStatus); console.log(this.registerStatus);
} }
); );

View file

@ -122,7 +122,7 @@
Form validation failed, please ensure the form is filled correctly. Form validation failed, please ensure the form is filled correctly.
</div> </div>
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert"> <div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
Failed to send to server, please try again later. {{submitStatusError}}
</div> </div>
</div> </div>
</div> </div>
@ -160,7 +160,7 @@
Form validation failed, please ensure the form is filled correctly. Form validation failed, please ensure the form is filled correctly.
</div> </div>
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert"> <div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
Failed to send to server, please try again later. {{submitStatusError}}
</div> </div>
</div> </div>
</div> </div>

View file

@ -14,6 +14,7 @@ export class AccountEditComponent implements OnInit {
accountType: any; accountType: any;
// @ViewChild('fileInput') fileInput; // @ViewChild('fileInput') fileInput;
submitStatus: any; submitStatus: any;
submitStatusError = 'Error received, please try again.';
constructor( constructor(
private http: Http, private http: Http,
@ -71,7 +72,7 @@ export class AccountEditComponent implements OnInit {
console.log(this.settingForm.valid); console.log(this.settingForm.valid);
if (!this.settingForm.valid && !this.settingOrganisationForm.valid) { if (!this.settingForm.valid && !this.settingOrganisationForm.valid) {
console.log('Not Valid!'); console.log('Not Valid!');
this.submitStatus = "validation_failed"; this.submitStatus = 'validation_failed';
console.log(this.submitStatus); console.log(this.submitStatus);
return; return;
} }
@ -107,12 +108,21 @@ export class AccountEditComponent implements OnInit {
.subscribe( .subscribe(
result => { result => {
console.log('data submitted!'); console.log('data submitted!');
this.submitStatus = "success"; this.submitStatus = 'success';
console.log(this.submitStatus); console.log(this.submitStatus);
}, },
error => { error => {
console.log( error._body ); console.log('Edit Error');
this.submitStatus = "send_failed"; console.log(error);
try {
console.log(error.error);
const jsonError = error.json();
console.log('boop');
this.submitStatusError = '"' + jsonError.error + '" Error, ' + jsonError.message;
} catch (e) {
this.submitStatusError = 'There was a server error, please try again later.';
}
this.submitStatus = 'send_failed';
console.log(this.submitStatus); console.log(this.submitStatus);
} }
); );
@ -122,7 +132,7 @@ export class AccountEditComponent implements OnInit {
console.log(this.settingForm.valid); console.log(this.settingForm.valid);
if (!this.settingForm.valid && !this.settingCustomerForm.valid) { if (!this.settingForm.valid && !this.settingCustomerForm.valid) {
console.log('Not Valid!'); console.log('Not Valid!');
this.submitStatus = "validation_failed"; this.submitStatus = 'validation_failed';
console.log(this.submitStatus); console.log(this.submitStatus);
return; return;
} }
@ -155,12 +165,21 @@ export class AccountEditComponent implements OnInit {
.subscribe( .subscribe(
result => { result => {
console.log('data submitted!'); console.log('data submitted!');
this.submitStatus = "success"; this.submitStatus = 'success';
console.log(this.submitStatus); console.log(this.submitStatus);
}, },
error => { error => {
console.log( error._body ); console.log('Edit Error');
this.submitStatus = "send_failed"; console.log(error);
try {
console.log(error.error);
const jsonError = error.json();
console.log('boop');
this.submitStatusError = '"' + jsonError.error + '" Error, ' + jsonError.message;
} catch (e) {
this.submitStatusError = 'There was a server error, please try again later.';
}
this.submitStatus = 'send_failed';
console.log(this.submitStatus); console.log(this.submitStatus);
} }
); );

View file

@ -72,7 +72,7 @@
<button type="submit" (click)="postTransaction()" [disabled]="transactionFormInvalid" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button> <button type="submit" (click)="postTransaction()" [disabled]="transactionFormInvalid" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
</div> </div>
</div> </div>
<div *ngIf="false" class="card"> <div *ngIf="accountType == 'organisation'" class="card">
<div class="card-header"> <div class="card-header">
<strong>Profile & Payroll Data</strong> <strong>Profile & Payroll Data</strong>
<small>Required Data marked in <strong>bold</strong>.</small> <small>Required Data marked in <strong>bold</strong>.</small>

View file

@ -9,7 +9,7 @@ import 'rxjs/add/operator/map';
@Component({ @Component({
templateUrl: 'add-data.component.html', templateUrl: 'add-data.component.html',
}) })
export class AddDataComponent { export class AddDataComponent implements OnInit {
payrollForm: FormGroup; payrollForm: FormGroup;
singleSupplierForm: FormGroup; singleSupplierForm: FormGroup;
employeeForm: FormGroup; employeeForm: FormGroup;
@ -18,7 +18,7 @@ export class AddDataComponent {
singleSupplierFormStatus: any; singleSupplierFormStatus: any;
employeeFormStatus: any; employeeFormStatus: any;
transactionFormStatus: any; transactionFormStatus: any;
transactionFormStatusError: string = 'Error received, please try again.'; transactionFormStatusError = 'Error received, please try again.';
accountType: any; accountType: any;
submitOrg = { submitOrg = {
@ -41,20 +41,20 @@ export class AddDataComponent {
constructor( constructor(
private http: Http, private http: Http,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private api: ApiService, private api: ApiService,
) { ) {
this.payrollForm = this.formBuilder.group({ this.payrollForm = this.formBuilder.group({
entry_period: ['', [Validators.required]], entry_period: ['', [Validators.required]],
employee_amount: ['', [Validators.required]], employee_amount: ['', [Validators.required]],
local_employee_amount: ['', [Validators.required]], local_employee_amount: ['', [Validators.required]],
gross_payroll: ['', [Validators.required]], gross_payroll: ['', [Validators.required]],
payroll_income_tax: ['', [Validators.required]], payroll_income_tax: ['', [Validators.required]],
payroll_employee_ni: ['', [Validators.required]], payroll_employee_ni: ['', [Validators.required]],
payroll_employer_ni: ['', [Validators.required]], payroll_employer_ni: ['', [Validators.required]],
payroll_total_pension: ['', [Validators.required]], payroll_total_pension: ['', [Validators.required]],
payroll_other_benefit: ['', [Validators.required]], payroll_other_benefit: ['', [Validators.required]],
}); });
this.employeeForm = this.formBuilder.group({ this.employeeForm = this.formBuilder.group({
entry_period: ['', [Validators.required]], entry_period: ['', [Validators.required]],
employee_no: ['', [Validators.required]], employee_no: ['', [Validators.required]],
@ -63,7 +63,7 @@ export class AddDataComponent {
employee_ni: ['', [Validators.required]], employee_ni: ['', [Validators.required]],
employee_pension: ['', [Validators.required]], employee_pension: ['', [Validators.required]],
employee_other_benefit: ['', [Validators.required]], employee_other_benefit: ['', [Validators.required]],
}); });
this.myDate = moment().format('YYYY-MM-DD[T]HH:mm'); this.myDate = moment().format('YYYY-MM-DD[T]HH:mm');
// this.myDate = new Date().toISOString().slice(0, 16); // this.myDate = new Date().toISOString().slice(0, 16);
} }
@ -73,13 +73,13 @@ export class AddDataComponent {
this.accountType = localStorage.getItem('usertype'); this.accountType = localStorage.getItem('usertype');
} }
getMinDate(){ getMinDate() {
// gets the April 1st date of the current year // gets the April 1st date of the current year
let aprilDate = moment().month(3).date(1); const aprilDate = moment().month(3).date(1);
let now = moment(); const now = moment();
// Checks if current time is before April 1st, if so returns true // Checks if current time is before April 1st, if so returns true
let beforeApril = now.isBefore(aprilDate); const beforeApril = now.isBefore(aprilDate);
if ( beforeApril == true ) { if ( beforeApril === true ) {
this.minDate = aprilDate.subtract(2, 'years').format('YYYY-MM-DD'); this.minDate = aprilDate.subtract(2, 'years').format('YYYY-MM-DD');
} else { } else {
this.minDate = aprilDate.subtract(1, 'years').format('YYYY-MM-DD'); this.minDate = aprilDate.subtract(1, 'years').format('YYYY-MM-DD');
@ -88,16 +88,16 @@ export class AddDataComponent {
initializeItems() { initializeItems() {
// Dont bother searching for an empty or undefined string // Dont bother searching for an empty or undefined string
if ( this.submitOrg.name == '' ) { if ( this.submitOrg.name === '' ) {
return; return;
} }
var searchData = { const searchData = {
search_name: this.submitOrg.name, search_name: this.submitOrg.name,
}; };
this.api.search(searchData).subscribe( this.api.search(searchData).subscribe(
data => { data => {
if(data.validated.length > 0) { if (data.validated.length > 0) {
this.storeList = data.validated; this.storeList = data.validated;
this.showAddStore = false; this.showAddStore = false;
this.transactionAdditionType = 1; this.transactionAdditionType = 1;
@ -107,7 +107,7 @@ export class AddDataComponent {
this.transactionAdditionType = 2; this.transactionAdditionType = 2;
} }
// handle the case when the storelist is empty // handle the case when the storelist is empty
if(this.storeList.length < 1 ) { if (this.storeList.length < 1) {
this.storeList = null; this.storeList = null;
this.showAddStore = true; this.showAddStore = true;
this.transactionAdditionType = 3; this.transactionAdditionType = 3;
@ -120,7 +120,7 @@ export class AddDataComponent {
} }
// if user select a item from the list // if user select a item from the list
addStore(store){ addStore(store) {
this.submitOrg = store; this.submitOrg = store;
this.transactionFormValidate(); this.transactionFormValidate();
this.organisationId = store.id; this.organisationId = store.id;
@ -132,39 +132,40 @@ export class AddDataComponent {
this.initializeItems(); this.initializeItems();
// set val to the value of the searchbar // set val to the value of the searchbar
let val = ev.target.value; const val = ev.target.value;
// Filter the store list so search seems quicker // Filter the store list so search seems quicker
if (val && val.trim() != '' && this.storeList != null) { if (val && val.trim() !== '' && this.storeList !== null) {
this.storeList = this.storeList.filter( this.storeList = this.storeList.filter(
(item) => { (item) => {
return ( item.name.toLowerCase().indexOf( val.toLowerCase() ) > -1 ); return ( item.name.toLowerCase().indexOf( val.toLowerCase() ) > -1 );
} }
) );
} }
// if nothing is found // if nothing is found
if(!this.storeList === null){ if (!this.storeList === null) {
// display add new store button // display add new store button
this.showAddStore = true; this.showAddStore = true;
} }
} }
transactionFormValidate() { transactionFormValidate() {
if( this.submitOrg.name.length == 0 && if (this.submitOrg.name.length === 0 ||
this.amount == 0 ) { this.submitOrg.town.length === 0 ||
this.amount === 0 ) {
this.transactionFormInvalid = true; this.transactionFormInvalid = true;
}else{ } else {
this.transactionFormInvalid = false; this.transactionFormInvalid = false;
} }
} }
public postTransaction() { public postTransaction() {
var myParams: any; let myParams: any;
let purchaseTime: string; let purchaseTime: string;
purchaseTime = moment(this.myDate, 'YYYY-MM-DD[T]HH:mm').local().format('YYYY-MM-DD[T]HH:mm:ss.SSSZ'); purchaseTime = moment(this.myDate, 'YYYY-MM-DD[T]HH:mm').local().format('YYYY-MM-DD[T]HH:mm:ss.SSSZ');
switch(this.transactionAdditionType){ switch (this.transactionAdditionType) {
case 1: case 1:
myParams = { myParams = {
transaction_type : this.transactionAdditionType, transaction_type : this.transactionAdditionType,
@ -199,16 +200,16 @@ export class AddDataComponent {
.upload(myParams) .upload(myParams)
.subscribe( .subscribe(
result => { result => {
if ( result.success == true ) { if ( result.success === true ) {
console.log('Successful Upload'); console.log('Successful Upload');
console.log(result); console.log(result);
this.transactionFormStatus = "success"; this.transactionFormStatus = 'success';
console.log(this.transactionFormStatus); console.log(this.transactionFormStatus);
this.resetForm(); this.resetForm();
} else { } else {
console.log('Upload Error'); console.log('Upload Error');
this.transactionFormStatusError = JSON.stringify(result.status) + 'Error, ' + JSON.stringify(result.message); this.transactionFormStatusError = JSON.stringify(result.status) + 'Error, ' + JSON.stringify(result.message);
this.transactionFormStatus = "send_failed"; this.transactionFormStatus = 'send_failed';
console.log(this.transactionFormStatus); console.log(this.transactionFormStatus);
} }
}, },
@ -217,13 +218,13 @@ export class AddDataComponent {
console.log(error); console.log(error);
try { try {
console.log(error.error); console.log(error.error);
let jsonError = error.json(); const jsonError = error.json();
console.log("boop"); console.log('boop');
this.transactionFormStatusError = '"' + jsonError.error + '" Error, ' + jsonError.message; this.transactionFormStatusError = '"' + jsonError.error + '" Error, ' + jsonError.message;
} catch(e) { } catch (e) {
this.transactionFormStatusError = 'There was a server error, please try again later.'; this.transactionFormStatusError = 'There was a server error, please try again later.';
} }
this.transactionFormStatus = "send_failed"; this.transactionFormStatus = 'send_failed';
console.log(this.transactionFormStatus); console.log(this.transactionFormStatus);
} }
); );
@ -239,60 +240,61 @@ export class AddDataComponent {
this.storeList = null; this.storeList = null;
this.amount = null; this.amount = null;
this.transactionFormInvalid = true; this.transactionFormInvalid = true;
this.showAddStore = false;
} }
onSubmitPayroll() { onSubmitPayroll() {
console.log(this.payrollForm.value); console.log(this.payrollForm.value);
this.api this.api
.orgPayroll(this.payrollForm.value) .orgPayroll(this.payrollForm.value)
.subscribe( .subscribe(
result => { result => {
console.log('data submitted!'); console.log('data submitted!');
this.payrollFormStatus = "success"; this.payrollFormStatus = 'success';
console.log(this.payrollFormStatus); console.log(this.payrollFormStatus);
}, },
error => { error => {
console.log( error._body ); console.log( error._body );
this.payrollFormStatus = "send_failed"; this.payrollFormStatus = 'send_failed';
console.log(this.payrollFormStatus); console.log(this.payrollFormStatus);
} }
); );
} }
onSubmitSingleSupplier() { onSubmitSingleSupplier() {
console.log(this.singleSupplierForm.value); console.log(this.singleSupplierForm.value);
this.api this.api
.orgSupplier(this.singleSupplierForm.value) .orgSupplier(this.singleSupplierForm.value)
.subscribe( .subscribe(
result => { result => {
console.log('data submitted!'); console.log('data submitted!');
this.singleSupplierFormStatus = "success"; this.singleSupplierFormStatus = 'success';
console.log(this.singleSupplierFormStatus); console.log(this.singleSupplierFormStatus);
}, },
error => { error => {
console.log( error._body ); console.log( error._body );
this.singleSupplierFormStatus = "send_failed"; this.singleSupplierFormStatus = 'send_failed';
console.log(this.singleSupplierFormStatus); console.log(this.singleSupplierFormStatus);
} }
); );
} }
onSubmitEmployee() { onSubmitEmployee() {
console.log(this.employeeForm.value); console.log(this.employeeForm.value);
this.api this.api
.orgEmployee(this.employeeForm.value) .orgEmployee(this.employeeForm.value)
.subscribe( .subscribe(
result => { result => {
console.log('data submitted!'); console.log('data submitted!');
this.employeeFormStatus = "success"; this.employeeFormStatus = 'success';
console.log(this.employeeFormStatus); console.log(this.employeeFormStatus);
}, },
error => { error => {
console.log( error._body ); console.log( error._body );
this.employeeFormStatus = "send_failed"; this.employeeFormStatus = 'send_failed';
console.log(this.employeeFormStatus); console.log(this.employeeFormStatus);
} }
); );

View file

@ -15,7 +15,7 @@ export class DashboardCustomerComponent implements OnInit {
/* Setting up dashboard's main variables*/ /* Setting up dashboard's main variables*/
name: any; name: any;
email:any; email: any;
myPearPoints: any; myPearPoints: any;
trends: any; trends: any;
myRank: any; myRank: any;

View file

@ -4,6 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ChartsModule } from 'ng2-charts/ng2-charts'; import { ChartsModule } from 'ng2-charts/ng2-charts';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { NgxPaginationModule } from 'ngx-pagination'; import { NgxPaginationModule } from 'ngx-pagination';
import { AgmCoreModule, GoogleMapsAPIWrapper } from '@agm/core';
import { CurrencyPipe } from '@angular/common'; import { CurrencyPipe } from '@angular/common';
@ -13,6 +14,8 @@ import { AccountEditComponent } from './account-edit.component';
import { AddDataComponent } from './add-data.component'; import { AddDataComponent } from './add-data.component';
import { FeedbackComponent } from './feedback.component'; import { FeedbackComponent } from './feedback.component';
import { TransactionLogComponent } from './transaction-log.component'; import { TransactionLogComponent } from './transaction-log.component';
import { PayrollLogComponent } from './payroll-log.component';
import { MapComponent } from './map.component';
import { GraphWidget } from '../widgets/graph-widget.component'; import { GraphWidget } from '../widgets/graph-widget.component';
import { OrgBarSnippetComponent } from '../snippets/org-snippet-bar.component'; import { OrgBarSnippetComponent } from '../snippets/org-snippet-bar.component';
@ -22,6 +25,10 @@ import { DashboardRoutingModule } from './dashboard.routing';
import { OrgResultComponent } from '../shared/org-result.component'; import { OrgResultComponent } from '../shared/org-result.component';
import { OrgTableComponent } from '../shared/org-table.component'; import { OrgTableComponent } from '../shared/org-table.component';
import { TransactionResultComponent } from '../shared/transaction-result.component'; import { TransactionResultComponent } from '../shared/transaction-result.component';
import { PayrollResultComponent } from '../shared/payroll-result.component';
// API key env variable import
import { environment } from '../../environments/environment';
@NgModule({ @NgModule({
imports: [ imports: [
@ -30,6 +37,9 @@ import { TransactionResultComponent } from '../shared/transaction-result.compone
FormsModule, FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
ChartsModule, ChartsModule,
AgmCoreModule.forRoot({
apiKey: environment.mapApiKey
}),
BsDropdownModule, BsDropdownModule,
NgxPaginationModule, NgxPaginationModule,
DashboardRoutingModule, DashboardRoutingModule,
@ -43,13 +53,17 @@ import { TransactionResultComponent } from '../shared/transaction-result.compone
OrgTableComponent, OrgTableComponent,
TransactionLogComponent, TransactionLogComponent,
TransactionResultComponent, TransactionResultComponent,
PayrollLogComponent,
PayrollResultComponent,
MapComponent,
FeedbackComponent, FeedbackComponent,
GraphWidget, GraphWidget,
OrgBarSnippetComponent, OrgBarSnippetComponent,
GraphPanel, GraphPanel,
], ],
providers: [ providers: [
CurrencyPipe CurrencyPipe,
GoogleMapsAPIWrapper,
], ],
}) })
export class DashboardModule { } export class DashboardModule { }

View file

@ -12,6 +12,8 @@ import { AccountEditComponent } from './account-edit.component';
import { AddDataComponent } from './add-data.component'; import { AddDataComponent } from './add-data.component';
import { FeedbackComponent } from './feedback.component'; import { FeedbackComponent } from './feedback.component';
import { TransactionLogComponent } from './transaction-log.component'; import { TransactionLogComponent } from './transaction-log.component';
import { PayrollLogComponent } from './payroll-log.component';
import { MapComponent } from './map.component';
// Using child path to allow for FullLayout theming // Using child path to allow for FullLayout theming
const routes: Routes = [ const routes: Routes = [
@ -48,6 +50,18 @@ const routes: Routes = [
component: TransactionLogComponent, component: TransactionLogComponent,
data: { title: 'Transaction Log' }, data: { title: 'Transaction Log' },
}, },
{
path: 'map',
component: MapComponent,
data: { title: 'Supplier Map' },
canActivate: [OrgGuard],
},
{
path: 'payroll-log',
component: PayrollLogComponent,
data: { title: 'Payroll Log' },
canActivate: [OrgGuard],
},
{ {
path: 'feedback', path: 'feedback',
component: FeedbackComponent, component: FeedbackComponent,

View file

@ -7,18 +7,18 @@ import 'rxjs/add/operator/map';
@Component({ @Component({
templateUrl: 'feedback.component.html', templateUrl: 'feedback.component.html',
}) })
export class FeedbackComponent { export class FeedbackComponent implements OnInit {
feedbackForm: FormGroup; feedbackForm: FormGroup;
loggedInEmail: string; loggedInEmail: string;
noEmail: boolean = false; noEmail = false;
username: any; username: any;
feedbackFormStatus: any; feedbackFormStatus: any;
feedbackFormStatusError: string = 'Error received, please try again.'; feedbackFormStatusError = 'Error received, please try again.';
constructor( constructor(
private http: Http, private http: Http,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private api: ApiService, private api: ApiService,
) { ) {
this.feedbackForm = this.formBuilder.group({ this.feedbackForm = this.formBuilder.group({
email: ['', [Validators.required]], email: ['', [Validators.required]],
@ -28,7 +28,7 @@ export class FeedbackComponent {
ngOnInit(): void { ngOnInit(): void {
if(localStorage.getItem('email')) { if (localStorage.getItem('email')) {
this.loggedInEmail = localStorage.getItem('email'); this.loggedInEmail = localStorage.getItem('email');
} }
console.log('loggedInEmail: ' + this.loggedInEmail); console.log('loggedInEmail: ' + this.loggedInEmail);
@ -55,10 +55,10 @@ export class FeedbackComponent {
.feedback(this.feedbackForm.value) .feedback(this.feedbackForm.value)
.subscribe( .subscribe(
result => { result => {
if ( result.success == true ) { if ( result.success === true ) {
console.log('Successful Upload'); console.log('Successful Upload');
console.log(result); console.log(result);
this.feedbackFormStatus = "success"; this.feedbackFormStatus = 'success';
console.log(this.feedbackFormStatus); console.log(this.feedbackFormStatus);
this.feedbackForm.patchValue({ this.feedbackForm.patchValue({
feedbacktext: '', feedbacktext: '',
@ -66,7 +66,7 @@ export class FeedbackComponent {
} else { } else {
console.log('Upload Error'); console.log('Upload Error');
this.feedbackFormStatusError = JSON.stringify(result.status) + 'Error, ' + JSON.stringify(result.message); this.feedbackFormStatusError = JSON.stringify(result.status) + 'Error, ' + JSON.stringify(result.message);
this.feedbackFormStatus = "send_failed"; this.feedbackFormStatus = 'send_failed';
console.log(this.feedbackFormStatus); console.log(this.feedbackFormStatus);
} }
}, },
@ -75,13 +75,13 @@ export class FeedbackComponent {
console.log(error); console.log(error);
try { try {
console.log(error.error); console.log(error.error);
let jsonError = error.json(); const jsonError = error.json();
console.log("boop"); console.log('boop');
this.feedbackFormStatusError = '"' + jsonError.error + '" Error, ' + jsonError.message; this.feedbackFormStatusError = '"' + jsonError.error + '" Error, ' + jsonError.message;
} catch(e) { } catch (e) {
this.feedbackFormStatusError = 'There was a server error, please try again later.'; this.feedbackFormStatusError = 'There was a server error, please try again later.';
} }
this.feedbackFormStatus = "send_failed"; this.feedbackFormStatus = 'send_failed';
console.log(this.feedbackFormStatus); console.log(this.feedbackFormStatus);
} }
); );

View file

@ -0,0 +1,41 @@
<div class="animated fadeIn">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<strong>Supplier Map</strong>
<small>Required Data marked in <strong>bold</strong>.</small>
</div>
<div [ngSwitch]="dataReceived">
<div *ngSwitchCase="'no'"class="card-block">
<div class="alert alert-danger" role="alert">
No map data received, check your connection.
</div>
</div>
<div *ngSwitchCase="'yes'">
<!-- this creates a google map on the page with the given lat/lng from -->
<!-- the component as the initial center of the map: -->
<agm-map
(mapReady)="onMapReady($event)"
[latitude]="lat"
[longitude]="lng"
[zoom]="zoom"
[scaleControl]="true"
(idle)="viewBoundsChanged($event)">
<agm-marker
*ngFor="let m of markers"
[latitude]="m.latitude"
[longitude]="m.longitude"
[label]="m.name[0]">
<agm-info-window>
<strong>{{m.name}}</strong>
</agm-info-window>
</agm-marker>
</agm-map>
</div>
</div>
</div>
</div>
</div><!--/.row-->
</div>

View file

@ -0,0 +1,66 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Http, Response } from '@angular/http';
import { ApiService } from '../providers/api-service';
import { AgmCoreModule } from '@agm/core';
import 'rxjs/add/operator/map';
@Component({
templateUrl: 'map.component.html',
})
export class MapComponent implements OnInit {
lat: number = 54.0466;
lng: number = -2.8007;
zoom: number = 12;
dataReceived: string = 'yes';
markers: Array<{latitude: number, longitude: number, name: string}>;
map: any;
constructor(
private http: Http,
private api: ApiService,
) { }
ngOnInit(): void { }
public onMapReady(map: any) {
this.map = map;
}
public viewBoundsChanged() {
console.log("finding bounds");
const resp = this.map.getBounds();
console.log("found bounds");
console.log(resp.getNorthEast().lat());
console.log(resp.getNorthEast().lng());
console.log(resp.getSouthWest().lat());
console.log(resp.getSouthWest().lng());
const mapData = {
north_east: {
latitude: resp.getNorthEast().lat(),
longitude: resp.getNorthEast().lng()
},
south_west: {
latitude: resp.getSouthWest().lat(),
longitude: resp.getSouthWest().lng()
},
}
this.api.getMapData(mapData).subscribe(
result => {
this.dataReceived = 'yes';
this.markers = result.suppliers;
},
error => {
// this.dataReceived = 'no';
console.log('Retrieval Error');
console.log( error._body );
}
);
}
}

View file

@ -0,0 +1,49 @@
<div class="animated fadeIn">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<strong>Log of Payroll submissions</strong>
<small>Sorted descending from submission date.</small>
</div>
<div *ngIf="!noPayrollList" class="card-block">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Entry Period</th>
<th>Gross Payroll</th>
<th>Employees</th>
</tr>
</thead>
<tbody>
<tr payroll-result *ngFor="let payroll of payrollList | paginate: paginateConfig" [payroll]="payroll"></tr>
</tbody>
</table>
<pagination-template #p="paginationApi"
[id]="paginateConfig.id"
(pageChange)="loadPayrolls($event)">
<ul class="pagination">
<li class="page-item" [class.disabled]="p.isFirstPage()">
<a class="page-link clickable" *ngIf="!p.isFirstPage()" (click)="p.previous()">Prev</a>
</li>
<li *ngFor="let page of p.pages" class="page-item" [class.active]="p.getCurrent() === page.value">
<a class="page-link clickable" (click)="p.setCurrent(page.value)" *ngIf="p.getCurrent() !== page.value">
<span>{{ page.label }}</span>
</a>
<div class="page-link" *ngIf="p.getCurrent() === page.value">
<span>{{ page.label }}</span>
</div>
</li>
<li class="page-item" [class.disabled]="p.isLastPage()">
<a class="page-link clickable" *ngIf="!p.isLastPage()" (click)="p.next()">Next</a>
</li>
</ul>
</pagination-template>
</div>
<div *ngIf="noPayrollList" class="card-block">
No Payroll data available.
</div>
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,77 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Http, Response } from '@angular/http';
import { ApiService } from '../providers/api-service';
// import { PaginatePipe } from 'ngx-pagination';
import {PaginationInstance} from 'ngx-pagination';
// import { PaginationControlsComponent } from 'ngx-pagination';
// import { PaginationControlsDirective } from 'ngx-pagination';
// import { TransactionResultComponent } from '../shared/transaction-result.component';
import * as moment from 'moment';
import 'rxjs/add/operator/map';
@Component({
templateUrl: 'payroll-log.component.html',
})
export class PayrollLogComponent implements OnInit {
payrollList;
noPayrollList = true;
myDate: any;
minDate: any;
public paginateConfig: PaginationInstance = {
id: 'transpaginate',
itemsPerPage: 10,
currentPage: 1,
totalItems: 0
};
constructor(
private http: Http,
private api: ApiService,
) {
this.myDate = moment().format('YYYY-MM-DD[T]HH:mm');
// this.myDate = new Date().toISOString().slice(0, 16);
}
ngOnInit(): void {
this.getMinDate();
this.loadPayrolls(1);
}
getMinDate(){
// gets the April 1st date of the current year
let aprilDate = moment().month(3).date(1);
let now = moment();
// Checks if current time is before April 1st, if so returns true
let beforeApril = now.isBefore(aprilDate);
if ( beforeApril == true ) {
this.minDate = aprilDate.subtract(2, 'years').format('YYYY-MM-DD');
} else {
this.minDate = aprilDate.subtract(1, 'years').format('YYYY-MM-DD');
}
}
loadPayrolls(logPage: number) {
console.log(logPage);
this.api.payrollList(logPage).subscribe(
result => {
if(result.payrolls.length > 0) {
this.payrollList = result.payrolls;
//TODO Rename in server
this.paginateConfig.totalItems = result.page_no;
this.paginateConfig.currentPage = logPage;
this.noPayrollList = false;
} else {
// handle the case when the payrollList is empty
this.payrollList = null;
this.noPayrollList = true;
}
},
error => {
console.log(error);
}
);
}
}

View file

@ -12,12 +12,13 @@ import 'rxjs/add/operator/map';
@Component({ @Component({
templateUrl: 'transaction-log.component.html', templateUrl: 'transaction-log.component.html',
}) })
export class TransactionLogComponent { export class TransactionLogComponent implements OnInit {
transactionList; transactionList;
noTransactionList = true; noTransactionList = true;
myDate: any; myDate: any;
minDate: any; minDate: any;
public p: any;
public paginateConfig: PaginationInstance = { public paginateConfig: PaginationInstance = {
id: 'transpaginate', id: 'transpaginate',
@ -28,8 +29,8 @@ export class TransactionLogComponent {
constructor( constructor(
private http: Http, private http: Http,
private api: ApiService, private api: ApiService,
) { ) {
this.myDate = moment().format('YYYY-MM-DD[T]HH:mm'); this.myDate = moment().format('YYYY-MM-DD[T]HH:mm');
// this.myDate = new Date().toISOString().slice(0, 16); // this.myDate = new Date().toISOString().slice(0, 16);
} }
@ -39,13 +40,13 @@ export class TransactionLogComponent {
this.loadTransactions(1); this.loadTransactions(1);
} }
getMinDate(){ getMinDate() {
// gets the April 1st date of the current year // gets the April 1st date of the current year
let aprilDate = moment().month(3).date(1); const aprilDate = moment().month(3).date(1);
let now = moment(); const now = moment();
// Checks if current time is before April 1st, if so returns true // Checks if current time is before April 1st, if so returns true
let beforeApril = now.isBefore(aprilDate); const beforeApril = now.isBefore(aprilDate);
if ( beforeApril == true ) { if ( beforeApril === true ) {
this.minDate = aprilDate.subtract(2, 'years').format('YYYY-MM-DD'); this.minDate = aprilDate.subtract(2, 'years').format('YYYY-MM-DD');
} else { } else {
this.minDate = aprilDate.subtract(1, 'years').format('YYYY-MM-DD'); this.minDate = aprilDate.subtract(1, 'years').format('YYYY-MM-DD');
@ -56,9 +57,9 @@ export class TransactionLogComponent {
console.log(logPage); console.log(logPage);
this.api.transList(logPage).subscribe( this.api.transList(logPage).subscribe(
result => { result => {
if(result.transactions.length > 0) { if (result.transactions.length > 0) {
this.transactionList = result.transactions; this.transactionList = result.transactions;
//TODO Rename in server // TODO Rename in server
this.paginateConfig.totalItems = result.page_no; this.paginateConfig.totalItems = result.page_no;
this.paginateConfig.currentPage = logPage; this.paginateConfig.currentPage = logPage;
this.noTransactionList = false; this.noTransactionList = false;

View file

@ -40,11 +40,21 @@
<i class="icon-envelope-letter"></i> Enter Feedback <i class="icon-envelope-letter"></i> Enter Feedback
</a> </a>
</li> </li>
<li *ngIf="accountType == 'organisation'" class="nav-item">
<a class="nav-link" routerLinkActive="active" [routerLink]="['/map']">
<i class="icon-map"></i> Supplier Map
</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" routerLinkActive="active" [routerLink]="['/transaction-log']"> <a class="nav-link" routerLinkActive="active" [routerLink]="['/transaction-log']">
<i class="icon-basket"></i> Transaction Log <i class="icon-basket"></i> Transaction Log
</a> </a>
</li> </li>
<li *ngIf="accountType == 'organisation'" class="nav-item">
<a class="nav-link" routerLinkActive="active" [routerLink]="['/payroll-log']">
<i class="icon-basket"></i> Payroll Log
</a>
</li>
</ul> </ul>
</nav> </nav>
</div> </div>

View file

@ -7,16 +7,16 @@ import { Router } from '@angular/router';
templateUrl: './full-layout.component.html', templateUrl: './full-layout.component.html',
}) })
export class FullLayoutComponent implements OnInit { export class FullLayoutComponent implements OnInit {
displayName: any; public displayName: string;
public accountType: any;
public disabled = false;
public status: {isopen: boolean} = {isopen: false};
constructor( constructor(
private api: ApiService, private api: ApiService,
private router: Router, private router: Router,
) {} ) {}
public disabled = false;
public status: {isopen: boolean} = {isopen: false};
public toggled(open: boolean): void { public toggled(open: boolean): void {
console.log('Dropdown is now: ', open); console.log('Dropdown is now: ', open);
} }
@ -30,6 +30,7 @@ export class FullLayoutComponent implements OnInit {
// getDisplayName function from api didnt work // getDisplayName function from api didnt work
ngOnInit(): void { ngOnInit(): void {
this.displayName = localStorage.getItem('displayname') || 'User'; this.displayName = localStorage.getItem('displayname') || 'User';
this.accountType = localStorage.getItem('usertype');
} }
userLogout() { userLogout() {

View file

@ -7,9 +7,9 @@
<h4 class="pt-3">Oops! You're lost.</h4> <h4 class="pt-3">Oops! You're lost.</h4>
<p class="text-muted">The page you are looking for was not found.</p> <p class="text-muted">The page you are looking for was not found.</p>
</div> </div>
<span class="input-group-btn"> <span class="input-group-btn">
<button class="btn btn-primary btn-lg" type="button"(click)="goBack()">Go Back</button> <button class="btn btn-primary btn-lg" type="button"(click)="goBack()">Go Back</button>
</span> </span>
</div> </div>
</div> </div>
</div> </div>

View file

@ -7,11 +7,10 @@ import { Location } from '@angular/common';
export class P404Component { export class P404Component {
constructor( constructor(
private location: Location private location: Location,
) { ) { }
}
goBack(): void { goBack(): void {
this.location.back(); this.location.back();
} }
} }

View file

@ -8,8 +8,8 @@
<p class="text-muted">The page you are looking for is temporarily unavailable.</p> <p class="text-muted">The page you are looking for is temporarily unavailable.</p>
</div> </div>
<span class="input-group-btn"> <span class="input-group-btn">
<button class="btn btn-primary btn-lg" type="button"(click)="goBack()">Go Back</button> <button class="btn btn-primary btn-lg" type="button"(click)="goBack()">Go Back</button>
</span> </span>
</div> </div>
</div> </div>
</div> </div>

View file

@ -7,11 +7,10 @@ import { Location } from '@angular/common';
export class P500Component { export class P500Component {
constructor( constructor(
private location: Location private location: Location,
) { ) { }
}
goBack(): void { goBack(): void {
this.location.back(); this.location.back();
} }
} }

View file

@ -136,12 +136,25 @@ export class ApiService {
).map( response => response.json() ); ).map( response => response.json() );
} }
// gets payroll list for log
public payrollList(data) {
const key = this.sessionKey;
return this.http.post(
this.apiUrl + '/v1/organisation/payroll',
{
session_key : key,
page : data
}
).map( response => response.json() );
}
// handles Org data added // handles Org data added
public orgPayroll(data) { public orgPayroll(data) {
data.session_key = this.sessionKey; data.session_key = this.sessionKey;
return this.http.post( return this.http.post(
this.apiUrl + '/org/payroll', this.apiUrl + '/v1/organisation/payroll/add',
data data
).map( response => response.json() ); ).map( response => response.json() );
} }
@ -149,7 +162,7 @@ export class ApiService {
public orgSupplier(data) { public orgSupplier(data) {
data.session_key = this.sessionKey; data.session_key = this.sessionKey;
return this.http.post( return this.http.post(
this.apiUrl + '/org/supplier', this.apiUrl + '/v1/organisation/supplier/add',
data data
).map( response => response.json() ); ).map( response => response.json() );
} }
@ -157,7 +170,7 @@ export class ApiService {
public orgEmployee(data) { public orgEmployee(data) {
data.session_key = this.sessionKey; data.session_key = this.sessionKey;
return this.http.post( return this.http.post(
this.apiUrl + '/org/employee', this.apiUrl + '/v1/organisation/employee/add',
data data
).map( response => response.json() ); ).map( response => response.json() );
} }
@ -251,6 +264,15 @@ export class ApiService {
).map( response => response.json() ); ).map( response => response.json() );
} }
// Initial Map Data
public getMapData(data) {
data.session_key = this.sessionKey;
return this.http.post(
this.apiUrl + '/v1/supplier/location',
data
).map( response => response.json() );
}
// Basic Customer User stats API // Basic Customer User stats API
public basicStats() { public basicStats() {
const key = this.sessionKey; const key = this.sessionKey;

View file

@ -9,6 +9,7 @@ interface OrgData {
} }
@Component({ @Component({
// tslint:disable-next-line
selector: '[org-result]', selector: '[org-result]',
templateUrl: 'org-result.component.html', templateUrl: 'org-result.component.html',
}) })
@ -19,6 +20,6 @@ export class OrgResultComponent {
public orgClick(): void { public orgClick(): void {
this.onClick.emit( this.onClick.emit(
this.org this.org
) );
} }
} }

View file

@ -10,6 +10,7 @@ interface OrgData {
} }
@Component({ @Component({
// tslint:disable-next-line
selector: 'org-table', selector: 'org-table',
templateUrl: 'org-table.component.html', templateUrl: 'org-table.component.html',
}) })

View file

@ -0,0 +1,3 @@
<td>{{payrollDate}}</td>
<td>{{payroll.gross_payroll | currency:'GBP':true:'1.2-2' }}</td>
<td>{{payroll.employee_amount}}</td>

View file

@ -0,0 +1,22 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import * as moment from 'moment';
interface PayrollData {
entry_period: string;
gross_payroll: number;
employee_amount: number;
}
@Component({
// tslint:disable-next-line
selector: '[payroll-result]',
templateUrl: 'payroll-result.component.html',
})
export class PayrollResultComponent implements OnInit {
@Input() public payroll: PayrollData;
public payrollDate: string;
ngOnInit(): void {
this.payrollDate = moment(this.payroll.entry_period).format('MMMM YYYY');
}
}

View file

@ -3,11 +3,12 @@ import * as moment from 'moment';
interface TransactionData { interface TransactionData {
seller: number; seller: number;
value: string; value: number;
purchase_time: string; purchase_time: string;
} }
@Component({ @Component({
// tslint:disable-next-line
selector: '[transaction-result]', selector: '[transaction-result]',
templateUrl: 'transaction-result.component.html', templateUrl: 'transaction-result.component.html',
}) })

View file

@ -0,0 +1,2 @@
ײֶ<67><D7B0>^f^ױ<>jA<6A>Fמ£†ֳ₪י$<24>אQםhֿ0<D6BF>L•+l™<6C>Dבג)9;
@¾&;q<>ƒט ©<C2A0>׀ iEֻײץֱװ0ו#ׂ¡<D782>ְְֵ<D6B0>׳bK<62>װס<D7B0>7<EFBFBD>U¦%¸x<C2B8>_x/6m‡=P <0C>q‡¶F™A$|װײ'Aט£½b1ױ<31><32>~הג/,אd¡×זLֲ”P<05>¢>S L

View file

@ -1,4 +0,0 @@
export const environment = {
production: true,
apiUrl: 'https://app.peartrade.org/api'
};

View file

@ -5,5 +5,6 @@
export const environment = { export const environment = {
production: false, production: false,
apiUrl: 'https://dev.peartrade.org/api' apiUrl: 'https://dev.peartrade.org/api',
mapApiKey: 'CHANGEME',
}; };

View file

@ -14,6 +14,12 @@
background-color: #0f81a8; background-color: #0f81a8;
color: #e8ebed; color: #e8ebed;
} }
// Map styling
agm-map {
height: 75vh;
}
// white title font variant on type-2 as defined in _widgets.css // white title font variant on type-2 as defined in _widgets.css
.horizontal-bars { .horizontal-bars {
padding: 0; padding: 0;