You've already forked openaccounting-web
mirror of
https://github.com/openaccounting/oa-web.git
synced 2025-12-09 09:01:24 +13:00
Merge pull request #8 from pnagurny/feature/timezones
Feature/timezones
This commit is contained in:
16
package-lock.json
generated
16
package-lock.json
generated
@@ -595,6 +595,14 @@
|
|||||||
"@types/jasmine": "*"
|
"@types/jasmine": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/moment-timezone": {
|
||||||
|
"version": "0.5.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/moment-timezone/-/moment-timezone-0.5.12.tgz",
|
||||||
|
"integrity": "sha512-hnHH2+Efg2vExr/dSz+IX860nSiyk9Sk4pJF2EmS11lRpMcNXeB4KBW5xcgw2QPsb9amTXdsVNEe5IoJXiT0uw==",
|
||||||
|
"requires": {
|
||||||
|
"moment": ">=2.14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "8.9.5",
|
"version": "8.9.5",
|
||||||
"resolved": "http://registry.npmjs.org/@types/node/-/node-8.9.5.tgz",
|
"resolved": "http://registry.npmjs.org/@types/node/-/node-8.9.5.tgz",
|
||||||
@@ -6408,6 +6416,14 @@
|
|||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"moment-timezone": {
|
||||||
|
"version": "0.5.25",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.25.tgz",
|
||||||
|
"integrity": "sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw==",
|
||||||
|
"requires": {
|
||||||
|
"moment": ">= 2.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"move-concurrently": {
|
"move-concurrently": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||||
|
|||||||
@@ -28,8 +28,10 @@
|
|||||||
"@angular/platform-browser-dynamic": "^6.1.0",
|
"@angular/platform-browser-dynamic": "^6.1.0",
|
||||||
"@angular/router": "^6.1.0",
|
"@angular/router": "^6.1.0",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^3.3.1",
|
"@ng-bootstrap/ng-bootstrap": "^3.3.1",
|
||||||
|
"@types/moment-timezone": "^0.5.12",
|
||||||
"bootstrap": "^4.1.3",
|
"bootstrap": "^4.1.3",
|
||||||
"core-js": "^2.5.4",
|
"core-js": "^2.5.4",
|
||||||
|
"moment-timezone": "^0.5.25",
|
||||||
"rxjs": "~6.2.0",
|
"rxjs": "~6.2.0",
|
||||||
"rxjs-compat": "6.0.0",
|
"rxjs-compat": "6.0.0",
|
||||||
"zone.js": "~0.8.26"
|
"zone.js": "~0.8.26"
|
||||||
|
|||||||
@@ -590,13 +590,6 @@ export class AccountService {
|
|||||||
return this.apiService.deleteAccount(id);
|
return this.apiService.deleteAccount(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPeriodStart(): Date {
|
|
||||||
let date = new Date();
|
|
||||||
date.setDate(1);
|
|
||||||
date.setHours(0, 0, 0, 0);
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
createDefaultAccounts(tree: AccountTree): Observable<any> {
|
createDefaultAccounts(tree: AccountTree): Observable<any> {
|
||||||
let assetAccount = tree.getAccountByName('Assets', 1);
|
let assetAccount = tree.getAccountByName('Assets', 1);
|
||||||
let equityAccount = tree.getAccountByName('Equity', 1);
|
let equityAccount = tree.getAccountByName('Equity', 1);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export class ApiService {
|
|||||||
private httpOptions = {
|
private httpOptions = {
|
||||||
headers: new HttpHeaders({
|
headers: new HttpHeaders({
|
||||||
'content-type': 'application/json',
|
'content-type': 'application/json',
|
||||||
'accept-version': '^1.0.1'
|
'accept-version': '^1.3.0'
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
private orgId: string;
|
private orgId: string;
|
||||||
@@ -231,6 +231,11 @@ export class ApiService {
|
|||||||
.pipe(catchError(this.handleError));
|
.pipe(catchError(this.handleError));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
putOrg(org: Org): Observable<Org> {
|
||||||
|
return this.http.put<Org>(this.url + '/orgs/' + this.orgId, org, this.httpOptions)
|
||||||
|
.pipe(catchError(this.handleError));
|
||||||
|
}
|
||||||
|
|
||||||
getPricesNearestInTime(date: Date): Observable<Price[]> {
|
getPricesNearestInTime(date: Date): Observable<Price[]> {
|
||||||
let query = '/orgs/' + this.orgId + '/prices?nearestDate=' + date.getTime();
|
let query = '/orgs/' + this.orgId + '/prices?nearestDate=' + date.getTime();
|
||||||
return this.http.get<Price[]>(this.url + query, this.httpOptions)
|
return this.http.get<Price[]>(this.url + query, this.httpOptions)
|
||||||
|
|||||||
@@ -59,6 +59,14 @@ export class OrgService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateOrg(org: Org): Observable<Org> {
|
||||||
|
return this.apiService.putOrg(org)
|
||||||
|
.do(org => {
|
||||||
|
this.org = org;
|
||||||
|
this.sessionService.switchOrg(this.org);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
getInvites(): Observable<Invite[]> {
|
getInvites(): Observable<Invite[]> {
|
||||||
return this.apiService.getInvites();
|
return this.apiService.getInvites();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import 'rxjs/add/operator/retryWhen';
|
|||||||
import 'rxjs/add/operator/repeatWhen';
|
import 'rxjs/add/operator/repeatWhen';
|
||||||
import 'rxjs/add/operator/delay';
|
import 'rxjs/add/operator/delay';
|
||||||
|
|
||||||
var version = '^1.0.1';
|
var version = '^1.3.0';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WebSocketService {
|
export class WebSocketService {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row" *ngFor="let recentTx of recentTxs" [routerLink]="'/accounts/'+recentTx.account.id+'/transactions'" [ngClass]="{hidden: recentTx.hidden}">
|
<div class="row" *ngFor="let recentTx of recentTxs" [routerLink]="'/accounts/'+recentTx.account.id+'/transactions'" [ngClass]="{hidden: recentTx.hidden}">
|
||||||
<div class="col-3 col-md-2 date">
|
<div class="col-3 col-md-2 date">
|
||||||
{{recentTx.tx.date | date:"M/d"}}
|
{{recentTx.tx.date | datetz:"M/D":org.timezone}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-5 col-md-6 description">
|
<div class="col-5 col-md-6 description">
|
||||||
{{recentTx.tx.description}}
|
{{recentTx.tx.description}}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { SessionService } from '../core/session.service';
|
|||||||
import { Transaction, Split } from '../shared/transaction';
|
import { Transaction, Split } from '../shared/transaction';
|
||||||
import { Org } from '../shared/org';
|
import { Org } from '../shared/org';
|
||||||
import { Account, AccountTree } from '../shared/account';
|
import { Account, AccountTree } from '../shared/account';
|
||||||
|
import { DateUtil } from '../shared/dateutil';
|
||||||
import { TxListPage } from '../transaction/list';
|
import { TxListPage } from '../transaction/list';
|
||||||
import { IncomeReport } from '../reports/income';
|
import { IncomeReport } from '../reports/income';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
@@ -46,11 +47,12 @@ export class DashboardPage implements OnInit {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.sessionService.setLoading(true);
|
this.sessionService.setLoading(true);
|
||||||
this.log.debug('dashboard init');
|
this.log.debug('dashboard init');
|
||||||
let periodStart = this.accountService.getPeriodStart();
|
|
||||||
|
|
||||||
this.org = this.orgService.getCurrentOrg();
|
this.org = this.orgService.getCurrentOrg();
|
||||||
this.log.debug('org', this.org);
|
this.log.debug('org', this.org);
|
||||||
|
|
||||||
|
let periodStart = DateUtil.getPeriodStart(this.org.timezone);
|
||||||
|
|
||||||
let tree$ = this.accountService.getAccountTreeWithPeriodBalance(periodStart);
|
let tree$ = this.accountService.getAccountTreeWithPeriodBalance(periodStart);
|
||||||
|
|
||||||
tree$.do(tree => {
|
tree$.do(tree => {
|
||||||
|
|||||||
@@ -33,6 +33,14 @@
|
|||||||
<label for="precision">Decimal Places</label>
|
<label for="precision">Decimal Places</label>
|
||||||
<input formControlName="precision" type="text" class="form-control" id="precision" placeholder="Decimal Places">
|
<input formControlName="precision" type="text" class="form-control" id="precision" placeholder="Decimal Places">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="timezone">Timezone</label>
|
||||||
|
<select class="form-control" id="timezone" formControlName="timezone">
|
||||||
|
<option *ngFor="let tz of timezones" [value]="tz">
|
||||||
|
{{tz}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="createDefaultAccounts">Create default accounts<br>(can be customized later)</label>
|
<label for="createDefaultAccounts">Create default accounts<br>(can be customized later)</label>
|
||||||
<input formControlName="createDefaultAccounts" id="createDefaultAccounts" type="checkbox" class="form-control" />
|
<input formControlName="createDefaultAccounts" id="createDefaultAccounts" type="checkbox" class="form-control" />
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { OrgService } from '../core/org.service';
|
|||||||
import { Org } from '../shared/org';
|
import { Org } from '../shared/org';
|
||||||
import { AppError } from '../shared/error';
|
import { AppError } from '../shared/error';
|
||||||
import { Util } from '../shared/util';
|
import { Util } from '../shared/util';
|
||||||
|
import { DateUtil } from '../shared/dateutil';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-neworg',
|
selector: 'app-neworg',
|
||||||
@@ -22,16 +23,22 @@ export class NewOrgPage {
|
|||||||
public error: AppError;
|
public error: AppError;
|
||||||
public joinOrgForm: FormGroup;
|
public joinOrgForm: FormGroup;
|
||||||
public joinOrgError: AppError;
|
public joinOrgError: AppError;
|
||||||
|
public timezones: string[];
|
||||||
|
public defaultTz: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private log: Logger,
|
private log: Logger,
|
||||||
private orgService: OrgService,
|
private orgService: OrgService,
|
||||||
private fb: FormBuilder
|
private fb: FormBuilder
|
||||||
) {
|
) {
|
||||||
|
this.timezones = DateUtil.getTimezones();
|
||||||
|
this.defaultTz = DateUtil.getDefaultTimezone();
|
||||||
|
|
||||||
this.form = fb.group({
|
this.form = fb.group({
|
||||||
'name': ['', Validators.required],
|
'name': ['', Validators.required],
|
||||||
'currency': ['USD', Validators.required],
|
'currency': ['USD', Validators.required],
|
||||||
'precision': [2, Validators.required],
|
'precision': [2, Validators.required],
|
||||||
|
'timezone': [this.defaultTz, Validators.required],
|
||||||
'createDefaultAccounts': [true, Validators.required]
|
'createDefaultAccounts': [true, Validators.required]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,42 @@
|
|||||||
<h1>Organization</h1>
|
<h1>Organization</h1>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2>Choose Organization</h2>
|
<h2>Current Organization</h2>
|
||||||
|
|
||||||
|
<form [formGroup]="updateOrgForm" (ngSubmit)="updateOrgSubmit()">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="name" class="col-sm-3 col-form-label">Name</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input formControlName="name" type="text" class="form-control" id="name" placeholder="Organization name">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="currency" class="col-sm-3 col-form-label">Currency</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input formControlName="currency" type="text" class="form-control" id="currency" placeholder="Currency">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="precision" class="col-sm-3 col-form-label">Decimal Places</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input formControlName="precision" type="text" class="form-control" id="precision" placeholder="Decimal Places">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="timezone" class="col-sm-3 col-form-label">Timezone</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select class="form-control" id="timezone" formControlName="timezone">
|
||||||
|
<option *ngFor="let tz of timezones" [value]="tz">
|
||||||
|
{{tz}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p *ngIf="updateOrgError" class="error">{{updateOrgError.message}}</p>
|
||||||
|
<button class="btn btn-primary" type="submit" [disabled]="!updateOrgForm.valid">Save Changes</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h2>Switch Organization</h2>
|
||||||
|
|
||||||
<form [formGroup]="chooseOrgForm" (ngSubmit)="chooseOrgSubmit()">
|
<form [formGroup]="chooseOrgForm" (ngSubmit)="chooseOrgSubmit()">
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
@@ -15,7 +50,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p *ngIf="chooseOrgError" class="error">{{chooseOrgError.message}}</p>
|
<p *ngIf="chooseOrgError" class="error">{{chooseOrgError.message}}</p>
|
||||||
<button class="btn btn-primary" type="submit" [disabled]="!chooseOrgForm.valid">Update</button>
|
<button class="btn btn-primary" type="submit" [disabled]="!chooseOrgForm.valid">Select</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -103,6 +138,16 @@
|
|||||||
<input formControlName="precision" type="text" class="form-control" id="precision" placeholder="Decimal Places">
|
<input formControlName="precision" type="text" class="form-control" id="precision" placeholder="Decimal Places">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="timezone" class="col-sm-3 col-form-label">Timezone</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select class="form-control" id="timezone" formControlName="timezone">
|
||||||
|
<option *ngFor="let tz of timezones" [value]="tz">
|
||||||
|
{{tz}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label for="createDefaultAccounts" class="col-sm-3 col-form-label">Create default accounts<br>(can be customized later)</label>
|
<label for="createDefaultAccounts" class="col-sm-3 col-form-label">Create default accounts<br>(can be customized later)</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { Org } from '../shared/org';
|
|||||||
import { Invite } from '../shared/invite';
|
import { Invite } from '../shared/invite';
|
||||||
import { AppError } from '../shared/error';
|
import { AppError } from '../shared/error';
|
||||||
import { Util } from '../shared/util';
|
import { Util } from '../shared/util';
|
||||||
|
import { DateUtil } from '../shared/dateutil';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-org',
|
selector: 'app-org',
|
||||||
@@ -30,7 +31,11 @@ export class OrgPage {
|
|||||||
public inviteFormError: AppError;
|
public inviteFormError: AppError;
|
||||||
public newOrgForm: FormGroup;
|
public newOrgForm: FormGroup;
|
||||||
public newOrgError: AppError;
|
public newOrgError: AppError;
|
||||||
|
public updateOrgForm: FormGroup;
|
||||||
|
public updateOrgError: AppError;
|
||||||
public invites: Invite[];
|
public invites: Invite[];
|
||||||
|
public timezones: string[];
|
||||||
|
public defaultTz: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private log: Logger,
|
private log: Logger,
|
||||||
@@ -38,8 +43,18 @@ export class OrgPage {
|
|||||||
private fb: FormBuilder
|
private fb: FormBuilder
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
this.timezones = DateUtil.getTimezones();
|
||||||
|
this.defaultTz = DateUtil.getDefaultTimezone();
|
||||||
|
|
||||||
this.invites = null;
|
this.invites = null;
|
||||||
|
|
||||||
|
this.updateOrgForm = fb.group({
|
||||||
|
'name': ['', Validators.required],
|
||||||
|
'currency': [{value: '', disabled: true}, Validators.required],
|
||||||
|
'precision': [{value: null, disabled: true}, Validators.required],
|
||||||
|
'timezone': ['', Validators.required]
|
||||||
|
});
|
||||||
|
|
||||||
this.chooseOrgForm = fb.group({
|
this.chooseOrgForm = fb.group({
|
||||||
'id': [null, Validators.required]
|
'id': [null, Validators.required]
|
||||||
});
|
});
|
||||||
@@ -56,6 +71,7 @@ export class OrgPage {
|
|||||||
'name': ['', Validators.required],
|
'name': ['', Validators.required],
|
||||||
'currency': ['', Validators.required],
|
'currency': ['', Validators.required],
|
||||||
'precision': [null, Validators.required],
|
'precision': [null, Validators.required],
|
||||||
|
'timezone': [this.defaultTz, Validators.required],
|
||||||
'createDefaultAccounts': [true, Validators.required]
|
'createDefaultAccounts': [true, Validators.required]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -63,12 +79,22 @@ export class OrgPage {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.currentOrg = this.orgService.getCurrentOrg();
|
this.currentOrg = this.orgService.getCurrentOrg();
|
||||||
|
|
||||||
|
this.updateOrgForm.setValue(
|
||||||
|
{
|
||||||
|
name: this.currentOrg.name,
|
||||||
|
currency: this.currentOrg.currency,
|
||||||
|
precision: this.currentOrg.precision,
|
||||||
|
timezone: this.currentOrg.timezone
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
this.chooseOrgForm.setValue({id: this.currentOrg.id});
|
this.chooseOrgForm.setValue({id: this.currentOrg.id});
|
||||||
this.newOrgForm.setValue(
|
this.newOrgForm.setValue(
|
||||||
{
|
{
|
||||||
name: '',
|
name: '',
|
||||||
currency: this.currentOrg.currency,
|
currency: this.currentOrg.currency,
|
||||||
precision: this.currentOrg.precision,
|
precision: this.currentOrg.precision,
|
||||||
|
timezone: this.defaultTz,
|
||||||
createDefaultAccounts: true
|
createDefaultAccounts: true
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -139,6 +165,22 @@ export class OrgPage {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateOrgSubmit() {
|
||||||
|
let org = this.currentOrg;
|
||||||
|
org.name = this.updateOrgForm.get('name').value;
|
||||||
|
org.timezone = this.updateOrgForm.get('timezone').value;
|
||||||
|
|
||||||
|
this.orgService.updateOrg(org)
|
||||||
|
.subscribe(
|
||||||
|
org => {
|
||||||
|
this.log.debug(org);
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.updateOrgError = error;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
deleteInvite(invite: Invite) {
|
deleteInvite(invite: Invite) {
|
||||||
this.orgService.deleteInvite(invite.id).subscribe(() => {
|
this.orgService.deleteInvite(invite.id).subscribe(() => {
|
||||||
this.invites = this.invites.filter(inv => {
|
this.invites = this.invites.filter(inv => {
|
||||||
|
|||||||
@@ -11,8 +11,11 @@ import {
|
|||||||
AbstractControl
|
AbstractControl
|
||||||
} from '@angular/forms';
|
} from '@angular/forms';
|
||||||
import { Util } from '../shared/util';
|
import { Util } from '../shared/util';
|
||||||
|
import { DateUtil } from '../shared/dateutil';
|
||||||
import { PriceService } from '../core/price.service';
|
import { PriceService } from '../core/price.service';
|
||||||
import { Price } from '../shared/price';
|
import { Price } from '../shared/price';
|
||||||
|
import { SessionService } from '../core/session.service';
|
||||||
|
import { Org } from '../shared/org';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -23,15 +26,18 @@ import { Observable } from 'rxjs/Observable';
|
|||||||
export class PriceModal {
|
export class PriceModal {
|
||||||
public form: FormGroup;
|
public form: FormGroup;
|
||||||
public error: AppError;
|
public error: AppError;
|
||||||
|
public org: Org;
|
||||||
private originalDate: Date;
|
private originalDate: Date;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public activeModal: NgbActiveModal,
|
public activeModal: NgbActiveModal,
|
||||||
private log: Logger,
|
private log: Logger,
|
||||||
private priceService: PriceService,
|
private priceService: PriceService,
|
||||||
|
private sessionService: SessionService,
|
||||||
private fb: FormBuilder
|
private fb: FormBuilder
|
||||||
) {
|
) {
|
||||||
let dateString = Util.getLocalDateString(new Date());
|
this.org = this.sessionService.getOrg();
|
||||||
|
let dateString = DateUtil.getLocalDateString(new Date(), this.org.timezone);
|
||||||
|
|
||||||
this.form = fb.group({
|
this.form = fb.group({
|
||||||
'id': [null],
|
'id': [null],
|
||||||
@@ -47,7 +53,7 @@ export class PriceModal {
|
|||||||
this.form.patchValue({
|
this.form.patchValue({
|
||||||
id: data.id,
|
id: data.id,
|
||||||
currency: data.currency,
|
currency: data.currency,
|
||||||
date: Util.getLocalDateString(data.date),
|
date: DateUtil.getLocalDateString(data.date, this.org.timezone),
|
||||||
price: data.price
|
price: data.price
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -56,18 +62,11 @@ export class PriceModal {
|
|||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
let date = this.form.value.id ? this.originalDate : new Date();
|
let date = this.form.value.id ? this.originalDate : new Date();
|
||||||
let formDate = Util.getDateFromLocalDateString(this.form.value.date);
|
let formDate = DateUtil.getDateFromLocalDateString(this.form.value.date, this.org.timezone);
|
||||||
|
|
||||||
if(formDate.getTime()) {
|
if(formDate.getTime() && !DateUtil.isSameDay(date, formDate, this.org.timezone)) {
|
||||||
// make the time be at the very end of the day
|
// make the time be at the very end of the day
|
||||||
formDate.setHours(23, 59, 59, 999);
|
DateUtil.setEndOfDay(formDate, this.org.timezone);
|
||||||
}
|
|
||||||
|
|
||||||
let sameDay = formDate.getFullYear() === date.getFullYear() &&
|
|
||||||
formDate.getMonth() === date.getMonth() &&
|
|
||||||
formDate.getDate() === date.getDate();
|
|
||||||
|
|
||||||
if(formDate.getTime() && !sameDay) {
|
|
||||||
date = formDate;
|
date = formDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<ng-container *ngIf="isExpanded(currency)">
|
<ng-container *ngIf="isExpanded(currency)">
|
||||||
<div class="row" *ngFor="let price of prices$[currency] | async" depth="2">
|
<div class="row" *ngFor="let price of prices$[currency] | async" depth="2">
|
||||||
<div class="col-4 date">
|
<div class="col-4 date">
|
||||||
{{price.date | date:"M/d/y"}}
|
{{price.date | datetz:"M/D/YYYY":org.timezone}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4 price">
|
<div class="col-4 price">
|
||||||
{{price.price * multiplier | currencyFormat:org.precision:org.currency}}
|
{{price.price * multiplier | currencyFormat:org.precision:org.currency}}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { PriceService } from '../core/price.service';
|
|||||||
import { Price } from '../shared/price';
|
import { Price } from '../shared/price';
|
||||||
import { Org } from '../shared/org';
|
import { Org } from '../shared/org';
|
||||||
import { AppError } from '../shared/error';
|
import { AppError } from '../shared/error';
|
||||||
import { Util } from '../shared/util';
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import 'rxjs/add/observable/forkJoin';
|
import 'rxjs/add/observable/forkJoin';
|
||||||
import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<div class="col-6 inflows">
|
<div class="col-6 inflows">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div *ngFor="let item of inflows" class="row">
|
<div *ngFor="let item of inflows" class="row">
|
||||||
<div class="col-3">{{item.tx.date | date:"M/d/y"}}</div>
|
<div class="col-3">{{item.tx.date | datetz:"M/D/YYYY":org.timezone}}</div>
|
||||||
<div class="col-4">{{item.tx.description}}</div>
|
<div class="col-4">{{item.tx.description}}</div>
|
||||||
<div class="col-3">{{item.amount | currencyFormat:account.precision:account.currency}}</div>
|
<div class="col-3">{{item.amount | currencyFormat:account.precision:account.currency}}</div>
|
||||||
<div class="col-2">
|
<div class="col-2">
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<div class="col-6 outflows">
|
<div class="col-6 outflows">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div *ngFor="let item of outflows" class="row">
|
<div *ngFor="let item of outflows" class="row">
|
||||||
<div class="col-3">{{item.tx.date | date:"M/d/y"}}</div>
|
<div class="col-3">{{item.tx.date | datetz:"M/D/YYYY":org.timezone}}</div>
|
||||||
<div class="col-4">{{item.tx.description}}</div>
|
<div class="col-4">{{item.tx.description}}</div>
|
||||||
<div class="col-3">{{item.amount | currencyFormat:account.precision:account.currency}}</div>
|
<div class="col-3">{{item.amount | currencyFormat:account.precision:account.currency}}</div>
|
||||||
<div class="col-2">
|
<div class="col-2">
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export class ReconcileModal {
|
|||||||
public balance: number;
|
public balance: number;
|
||||||
public reconciled: number;
|
public reconciled: number;
|
||||||
public error: AppError;
|
public error: AppError;
|
||||||
|
public org: Org;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public activeModal: NgbActiveModal,
|
public activeModal: NgbActiveModal,
|
||||||
@@ -52,7 +53,9 @@ export class ReconcileModal {
|
|||||||
private txService: TransactionService,
|
private txService: TransactionService,
|
||||||
private sessionService: SessionService,
|
private sessionService: SessionService,
|
||||||
private fb: FormBuilder
|
private fb: FormBuilder
|
||||||
) {}
|
) {
|
||||||
|
this.org = this.sessionService.getOrg();
|
||||||
|
}
|
||||||
|
|
||||||
setData(account: Account, rec: Reconciliation) {
|
setData(account: Account, rec: Reconciliation) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
<h2>Past Reconciliations</h2>
|
<h2>Past Reconciliations</h2>
|
||||||
|
|
||||||
<div *ngFor="let rec of pastReconciliations; index as i">
|
<div *ngFor="let rec of pastReconciliations; index as i">
|
||||||
Period: {{rec.startDate | date:"M/d/y"}} - {{rec.endDate | date:"M/d/y"}}<br>
|
Period: {{rec.startDate | datetz:"M/D/YYYY":org.timezone}} - {{rec.endDate | datetz:"M/D/YYYY":org.timezone}}<br>
|
||||||
Beginning Balance: {{rec.startBalance | currencyFormat:account.precision:account.currency}}<br>
|
Beginning Balance: {{rec.startBalance | currencyFormat:account.precision:account.currency}}<br>
|
||||||
Ending Balance: {{rec.endBalance | currencyFormat:account.precision:account.currency}}<br>
|
Ending Balance: {{rec.endBalance | currencyFormat:account.precision:account.currency}}<br>
|
||||||
<a *ngIf="i === 0" [routerLink]="" (click)="delete()">Delete</a>
|
<a *ngIf="i === 0" [routerLink]="" (click)="delete()">Delete</a>
|
||||||
|
|||||||
@@ -14,8 +14,10 @@ import { OrgService } from '../core/org.service';
|
|||||||
import { TransactionService } from '../core/transaction.service';
|
import { TransactionService } from '../core/transaction.service';
|
||||||
import { Account, AccountApi, AccountTree } from '../shared/account';
|
import { Account, AccountApi, AccountTree } from '../shared/account';
|
||||||
import { Transaction } from '../shared/transaction';
|
import { Transaction } from '../shared/transaction';
|
||||||
|
import { Org } from '../shared/org';
|
||||||
import { AppError } from '../shared/error';
|
import { AppError } from '../shared/error';
|
||||||
import { Util } from '../shared/util';
|
import { Util } from '../shared/util';
|
||||||
|
import { DateUtil } from '../shared/dateutil';
|
||||||
import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { ReconcileModal } from './reconcile-modal';
|
import { ReconcileModal } from './reconcile-modal';
|
||||||
import { Reconciliation } from './reconciliation';
|
import { Reconciliation } from './reconciliation';
|
||||||
@@ -37,6 +39,7 @@ export class ReconcilePage {
|
|||||||
public pastReconciliations: Reconciliation[];
|
public pastReconciliations: Reconciliation[];
|
||||||
public unreconciledTxs: Transaction[];
|
public unreconciledTxs: Transaction[];
|
||||||
public error: AppError;
|
public error: AppError;
|
||||||
|
public org: Org;
|
||||||
private accountTree: AccountTree;
|
private accountTree: AccountTree;
|
||||||
@ViewChild('confirmDeleteModal') confirmDeleteModal: ElementRef;
|
@ViewChild('confirmDeleteModal') confirmDeleteModal: ElementRef;
|
||||||
|
|
||||||
@@ -50,7 +53,7 @@ export class ReconcilePage {
|
|||||||
private modalService: NgbModal,
|
private modalService: NgbModal,
|
||||||
private sessionService: SessionService) {
|
private sessionService: SessionService) {
|
||||||
|
|
||||||
let org = this.orgService.getCurrentOrg();
|
this.org = this.orgService.getCurrentOrg();
|
||||||
this.accountForm = fb.group({
|
this.accountForm = fb.group({
|
||||||
'accountId': [null, Validators.required]
|
'accountId': [null, Validators.required]
|
||||||
});
|
});
|
||||||
@@ -85,8 +88,8 @@ export class ReconcilePage {
|
|||||||
let value = this.newReconcile.getRawValue();
|
let value = this.newReconcile.getRawValue();
|
||||||
|
|
||||||
let rec = new Reconciliation();
|
let rec = new Reconciliation();
|
||||||
rec.startDate = Util.getDateFromLocalDateString(value.startDate);
|
rec.startDate = DateUtil.getDateFromLocalDateString(value.startDate, this.org.timezone);
|
||||||
rec.endDate = Util.getDateFromLocalDateString(value.endDate);
|
rec.endDate = DateUtil.getDateFromLocalDateString(value.endDate, this.org.timezone);
|
||||||
rec.startBalance = Math.round(parseFloat(value.startBalance) * Math.pow(10, this.account.precision));
|
rec.startBalance = Math.round(parseFloat(value.startBalance) * Math.pow(10, this.account.precision));
|
||||||
rec.endBalance = Math.round(parseFloat(value.endBalance) * Math.pow(10, this.account.precision));
|
rec.endBalance = Math.round(parseFloat(value.endBalance) * Math.pow(10, this.account.precision));
|
||||||
|
|
||||||
@@ -104,7 +107,7 @@ export class ReconcilePage {
|
|||||||
|
|
||||||
this.newReconcile.patchValue(
|
this.newReconcile.patchValue(
|
||||||
{
|
{
|
||||||
startDate: Util.getLocalDateString(rec.endDate),
|
startDate: DateUtil.getLocalDateString(rec.endDate, this.org.timezone),
|
||||||
startBalance: rec.endBalance / Math.pow(10, this.account.precision),
|
startBalance: rec.endBalance / Math.pow(10, this.account.precision),
|
||||||
endBalance: 0,
|
endBalance: 0,
|
||||||
endDate: ''
|
endDate: ''
|
||||||
@@ -201,7 +204,7 @@ export class ReconcilePage {
|
|||||||
|
|
||||||
if(!dates.length) {
|
if(!dates.length) {
|
||||||
if(firstStartDate) {
|
if(firstStartDate) {
|
||||||
this.newReconcile.patchValue({startDate: Util.getLocalDateString(firstStartDate)});
|
this.newReconcile.patchValue({startDate: DateUtil.getLocalDateString(firstStartDate, this.org.timezone)});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -226,7 +229,7 @@ export class ReconcilePage {
|
|||||||
|
|
||||||
this.newReconcile.patchValue(
|
this.newReconcile.patchValue(
|
||||||
{
|
{
|
||||||
startDate: Util.getLocalDateString(lastRec.endDate),
|
startDate: DateUtil.getLocalDateString(lastRec.endDate, this.org.timezone),
|
||||||
startBalance: lastRec.endBalance / Math.pow(10, this.account.precision)
|
startBalance: lastRec.endBalance / Math.pow(10, this.account.precision)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -270,7 +273,7 @@ export class ReconcilePage {
|
|||||||
if(lastRec) {
|
if(lastRec) {
|
||||||
this.newReconcile.patchValue(
|
this.newReconcile.patchValue(
|
||||||
{
|
{
|
||||||
startDate: Util.getLocalDateString(lastRec.endDate),
|
startDate: DateUtil.getLocalDateString(lastRec.endDate, this.org.timezone),
|
||||||
startBalance: lastRec.endBalance / Math.pow(10, this.account.precision)
|
startBalance: lastRec.endBalance / Math.pow(10, this.account.precision)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<h1>Balance Sheet<br>{{date | date:"shortDate"}} (<a [routerLink]="" (click)="toggleShowOptionsForm()">options</a>)</h1>
|
<h1>Balance Sheet<br>{{date.getTime() - 1 | datetz:"M/D/YYYY":org.timezone}} (<a [routerLink]="" (click)="toggleShowOptionsForm()">options</a>)</h1>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<div *ngIf="showOptionsForm" class="card card-body">
|
<div *ngIf="showOptionsForm" class="card card-body">
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
ValidationErrors
|
ValidationErrors
|
||||||
} from '@angular/forms';
|
} from '@angular/forms';
|
||||||
import { AppError } from '../shared/error';
|
import { AppError } from '../shared/error';
|
||||||
import { Util } from '../shared/util';
|
import { DateUtil } from '../shared/dateutil';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-balancesheet',
|
selector: 'app-balancesheet',
|
||||||
@@ -62,15 +62,16 @@ export class BalanceSheetReport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.org = this.orgService.getCurrentOrg();
|
||||||
|
|
||||||
this.form = fb.group({
|
this.form = fb.group({
|
||||||
date: [Util.getLocalDateString(this.date), Validators.required],
|
date: [DateUtil.getLocalDateStringExcl(this.date, this.org.timezone), Validators.required],
|
||||||
priceSource: [this.priceSource, Validators.required]
|
priceSource: [this.priceSource, Validators.required]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.sessionService.setLoading(true);
|
this.sessionService.setLoading(true);
|
||||||
this.org = this.orgService.getCurrentOrg();
|
|
||||||
this.amounts = {};
|
this.amounts = {};
|
||||||
this.assetAccount = null;
|
this.assetAccount = null;
|
||||||
|
|
||||||
@@ -133,7 +134,7 @@ export class BalanceSheetReport {
|
|||||||
this.treeSubscription.unsubscribe();
|
this.treeSubscription.unsubscribe();
|
||||||
//this.dataService.setLoading(true);
|
//this.dataService.setLoading(true);
|
||||||
this.showOptionsForm = false;
|
this.showOptionsForm = false;
|
||||||
this.date = Util.getDateFromLocalDateString(this.form.value.date);
|
this.date = DateUtil.getDateFromLocalDateStringExcl(this.form.value.date, this.org.timezone);
|
||||||
this.priceSource = this.form.value.priceSource;
|
this.priceSource = this.form.value.priceSource;
|
||||||
|
|
||||||
let reportData = this.configService.get('reportData');
|
let reportData = this.configService.get('reportData');
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<h1>Income Statement<br>{{startDate | date:"shortDate"}} - {{endDate.getTime() - 1 | date:"shortDate"}} (<a [routerLink]="" (click)="toggleShowDateForm()">edit</a>)</h1>
|
<h1>Income Statement<br>{{startDate | datetz:"M/D/YYYY":org.timezone}} - {{endDate.getTime() - 1 | datetz:"M/D/YYYY":org.timezone}} (<a [routerLink]="" (click)="toggleShowDateForm()">edit</a>)</h1>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<form *ngIf="showDateForm" [formGroup]="form" (ngSubmit)="onSubmit()">
|
<form *ngIf="showDateForm" [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
ValidationErrors
|
ValidationErrors
|
||||||
} from '@angular/forms';
|
} from '@angular/forms';
|
||||||
import { AppError } from '../shared/error';
|
import { AppError } from '../shared/error';
|
||||||
import { Util } from '../shared/util';
|
import { DateUtil } from '../shared/dateutil';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-income',
|
selector: 'app-income',
|
||||||
@@ -44,11 +44,16 @@ export class IncomeReport {
|
|||||||
private orgService: OrgService,
|
private orgService: OrgService,
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
private sessionService: SessionService) {
|
private sessionService: SessionService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.sessionService.setLoading(true);
|
||||||
|
this.org = this.orgService.getCurrentOrg();
|
||||||
|
|
||||||
this.startDate = new Date();
|
this.startDate = new Date();
|
||||||
this.startDate.setDate(1);
|
DateUtil.setFirstOfMonth(this.startDate, this.org.timezone);
|
||||||
this.startDate.setHours(0, 0, 0, 0);
|
DateUtil.setBeginOfDay(this.startDate, this.org.timezone);
|
||||||
this.endDate = new Date(this.startDate);
|
this.endDate = DateUtil.getOneMonthLater(this.startDate, this.org.timezone);
|
||||||
this.endDate.setMonth(this.startDate.getMonth() + 1);
|
|
||||||
|
|
||||||
let reportData = this.configService.get('reportData');
|
let reportData = this.configService.get('reportData');
|
||||||
|
|
||||||
@@ -63,15 +68,10 @@ export class IncomeReport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.form = fb.group({
|
this.form = this.fb.group({
|
||||||
startDate: [Util.getLocalDateString(this.startDate), Validators.required],
|
startDate: [DateUtil.getLocalDateString(this.startDate, this.org.timezone), Validators.required],
|
||||||
endDate: [Util.getLocalDateString(new Date(this.endDate.getTime() - 1)), Validators.required]
|
endDate: [DateUtil.getLocalDateStringExcl(this.endDate, this.org.timezone), Validators.required]
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.sessionService.setLoading(true);
|
|
||||||
this.org = this.orgService.getCurrentOrg();
|
|
||||||
|
|
||||||
this.treeSubscription = this.accountService.getAccountTreeWithPeriodBalance(this.startDate, this.endDate)
|
this.treeSubscription = this.accountService.getAccountTreeWithPeriodBalance(this.startDate, this.endDate)
|
||||||
.subscribe(tree => {
|
.subscribe(tree => {
|
||||||
@@ -91,9 +91,8 @@ export class IncomeReport {
|
|||||||
this.treeSubscription.unsubscribe();
|
this.treeSubscription.unsubscribe();
|
||||||
//this.dataService.setLoading(true);
|
//this.dataService.setLoading(true);
|
||||||
this.showDateForm = false;
|
this.showDateForm = false;
|
||||||
this.startDate = Util.getDateFromLocalDateString(this.form.value.startDate);
|
this.startDate = DateUtil.getDateFromLocalDateString(this.form.value.startDate, this.org.timezone);
|
||||||
this.endDate = Util.getDateFromLocalDateString(this.form.value.endDate);
|
this.endDate = DateUtil.getDateFromLocalDateStringExcl(this.form.value.endDate, this.org.timezone);
|
||||||
this.endDate.setDate(this.endDate.getDate() + 1);
|
|
||||||
|
|
||||||
let reportData = this.configService.get('reportData');
|
let reportData = this.configService.get('reportData');
|
||||||
|
|
||||||
|
|||||||
14
src/app/shared/datetz.pipe.ts
Normal file
14
src/app/shared/datetz.pipe.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import * as moment from 'moment-timezone/builds/moment-timezone-with-data-2012-2022.min';
|
||||||
|
//import * as moment from 'moment-timezone';
|
||||||
|
|
||||||
|
@Pipe({name: 'datetz'})
|
||||||
|
export class DateTzPipe implements PipeTransform {
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
transform(date: Date, format: string, tz: string): string {
|
||||||
|
let m = moment(date).tz(tz || moment.tz.guess());
|
||||||
|
return m.format(format);
|
||||||
|
}
|
||||||
|
}
|
||||||
175
src/app/shared/dateutil.ts
Normal file
175
src/app/shared/dateutil.ts
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
import * as moment from 'moment-timezone/builds/moment-timezone-with-data-2012-2022.min';
|
||||||
|
//import * as moment from 'moment-timezone';
|
||||||
|
|
||||||
|
const defaultTz = moment.tz.guess();
|
||||||
|
|
||||||
|
export class DateUtil {
|
||||||
|
static getLocalDateString(input: Date, tz: string) {
|
||||||
|
let m = moment(input).tz(tz || defaultTz);
|
||||||
|
|
||||||
|
let year = m.format('YYYY');
|
||||||
|
let month = m.format('MM');
|
||||||
|
let date = m.format('DD');
|
||||||
|
|
||||||
|
if(month.length < 2) {
|
||||||
|
month = '0' + month;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(date.length < 2) {
|
||||||
|
date = '0' + date;
|
||||||
|
}
|
||||||
|
|
||||||
|
return year + '-' + month + '-' + date;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getLocalDateStringExcl(input: Date, tz: string) {
|
||||||
|
let m = moment(input.getTime() - 1).tz(tz || defaultTz);
|
||||||
|
|
||||||
|
let year = m.format('YYYY');
|
||||||
|
let month = m.format('MM');
|
||||||
|
let date = m.format('DD');
|
||||||
|
|
||||||
|
if(month.length < 2) {
|
||||||
|
month = '0' + month;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(date.length < 2) {
|
||||||
|
date = '0' + date;
|
||||||
|
}
|
||||||
|
|
||||||
|
return year + '-' + month + '-' + date;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDateFromLocalDateString(input: string, tz: string) {
|
||||||
|
let parts = input.split('-');
|
||||||
|
|
||||||
|
let m = moment().tz(tz || defaultTz);
|
||||||
|
m.hours(0);
|
||||||
|
m.minutes(0);
|
||||||
|
m.seconds(0);
|
||||||
|
m.milliseconds(0);
|
||||||
|
m.year(parseInt(parts[0]));
|
||||||
|
m.month(parseInt(parts[1]) - 1);
|
||||||
|
m.date(parseInt(parts[2]));
|
||||||
|
|
||||||
|
return m.toDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDateFromLocalDateStringExcl(input: string, tz: string) {
|
||||||
|
let parts = input.split('-');
|
||||||
|
|
||||||
|
let m = moment().tz(tz || defaultTz);
|
||||||
|
m.hours(0);
|
||||||
|
m.minutes(0);
|
||||||
|
m.seconds(0);
|
||||||
|
m.milliseconds(0);
|
||||||
|
m.year(parseInt(parts[0]));
|
||||||
|
m.month(parseInt(parts[1]) - 1);
|
||||||
|
m.date(parseInt(parts[2]) + 1);
|
||||||
|
|
||||||
|
return m.toDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
static setFirstOfMonth(input: Date, tz: string) {
|
||||||
|
let m = moment(input).tz(tz || defaultTz);
|
||||||
|
|
||||||
|
m.date(1);
|
||||||
|
input.setTime(m.valueOf());
|
||||||
|
}
|
||||||
|
|
||||||
|
static setBeginOfDay(input: Date, tz: string) {
|
||||||
|
let m = moment(input).tz(tz || defaultTz);
|
||||||
|
|
||||||
|
m.hours(0);
|
||||||
|
m.minutes(0);
|
||||||
|
m.seconds(0);
|
||||||
|
m.milliseconds(0);
|
||||||
|
input.setTime(m.valueOf());
|
||||||
|
}
|
||||||
|
|
||||||
|
static setEndOfDay(input: Date, tz: string) {
|
||||||
|
let m = moment(input).tz(tz || defaultTz);
|
||||||
|
|
||||||
|
m.hours(23);
|
||||||
|
m.minutes(59);
|
||||||
|
m.seconds(59);
|
||||||
|
m.milliseconds(999);
|
||||||
|
input.setTime(m.valueOf());
|
||||||
|
}
|
||||||
|
|
||||||
|
static getOneMonthLater(input: Date, tz: string): Date {
|
||||||
|
let m = moment(input).tz(tz || defaultTz);
|
||||||
|
|
||||||
|
m.month(m.month() + 1);
|
||||||
|
|
||||||
|
return m.toDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
static computeTransactionDate(formDate: Date, txDate: Date, tz: string): Date {
|
||||||
|
if(!formDate || !formDate.getTime()) {
|
||||||
|
return txDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
let formMoment = moment(formDate).tz(tz || defaultTz);
|
||||||
|
let txMoment = moment(txDate).tz(tz || defaultTz);
|
||||||
|
|
||||||
|
// make the time be at the very end of the day
|
||||||
|
formMoment.hours(23);
|
||||||
|
formMoment.minutes(59);
|
||||||
|
formMoment.seconds(59);
|
||||||
|
formMoment.milliseconds(999);
|
||||||
|
|
||||||
|
let sameDay = formMoment.year() === txMoment.year() &&
|
||||||
|
formMoment.month() === txMoment.month() &&
|
||||||
|
formMoment.date() === txMoment.date();
|
||||||
|
|
||||||
|
if(sameDay) {
|
||||||
|
return txDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(formDate < txDate) {
|
||||||
|
// make time end of day for past dates
|
||||||
|
formMoment.hours(23);
|
||||||
|
formMoment.minutes(59);
|
||||||
|
formMoment.seconds(59);
|
||||||
|
formMoment.milliseconds(999);
|
||||||
|
} else {
|
||||||
|
// make time beginning of day for future dates
|
||||||
|
formMoment.hours(0);
|
||||||
|
formMoment.minutes(0);
|
||||||
|
formMoment.seconds(0);
|
||||||
|
formMoment.milliseconds(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return formMoment.toDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
static isSameDay(date1: Date, date2: Date, tz: string) {
|
||||||
|
let m1 = moment(date1).tz(tz || defaultTz);
|
||||||
|
let m2 = moment(date2).tz(tz || defaultTz);
|
||||||
|
|
||||||
|
return m1.year() === m2.year() &&
|
||||||
|
m1.month() === m2.month() &&
|
||||||
|
m1.date() === m2.date();
|
||||||
|
}
|
||||||
|
|
||||||
|
static getPeriodStart(tz: string): Date {
|
||||||
|
let m = moment().tz(tz || defaultTz);
|
||||||
|
m.date(1);
|
||||||
|
m.hours(0);
|
||||||
|
m.minutes(0);
|
||||||
|
m.seconds(0);
|
||||||
|
m.milliseconds(0);
|
||||||
|
|
||||||
|
return m.toDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
static getTimezones(): string[] {
|
||||||
|
let timezones = [''];
|
||||||
|
return timezones.concat(moment.tz.names());
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDefaultTimezone(): string {
|
||||||
|
return defaultTz;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ export class Org {
|
|||||||
name: string;
|
name: string;
|
||||||
currency: string;
|
currency: string;
|
||||||
precision: number;
|
precision: number;
|
||||||
|
timezone: string;
|
||||||
constructor(options: any = {}) {
|
constructor(options: any = {}) {
|
||||||
this.id = options.id;
|
this.id = options.id;
|
||||||
this.inserted = options.inserted ? new Date(options.inserted) : null;
|
this.inserted = options.inserted ? new Date(options.inserted) : null;
|
||||||
@@ -12,5 +13,6 @@ export class Org {
|
|||||||
this.name = options.name;
|
this.name = options.name;
|
||||||
this.currency = options.currency;
|
this.currency = options.currency;
|
||||||
this.precision = options.precision && parseInt(options.precision);
|
this.precision = options.precision && parseInt(options.precision);
|
||||||
|
this.timezone = options.timezone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,11 +3,12 @@ import { DecimalPipe } from '@angular/common';
|
|||||||
import { CurrencyFormatPipe } from './currency-format.pipe';
|
import { CurrencyFormatPipe } from './currency-format.pipe';
|
||||||
import { AccountNamePipe } from './account-name.pipe';
|
import { AccountNamePipe } from './account-name.pipe';
|
||||||
import { AccountBalancePipe } from './account-balance.pipe';
|
import { AccountBalancePipe } from './account-balance.pipe';
|
||||||
|
import { DateTzPipe } from './datetz.pipe';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [],
|
imports: [],
|
||||||
declarations: [CurrencyFormatPipe, AccountNamePipe, AccountBalancePipe],
|
declarations: [CurrencyFormatPipe, AccountNamePipe, AccountBalancePipe, DateTzPipe],
|
||||||
exports: [CurrencyFormatPipe, AccountNamePipe, AccountBalancePipe],
|
exports: [CurrencyFormatPipe, AccountNamePipe, AccountBalancePipe, DateTzPipe],
|
||||||
providers: [DecimalPipe, CurrencyFormatPipe]
|
providers: [DecimalPipe, CurrencyFormatPipe]
|
||||||
})
|
})
|
||||||
export class SharedModule { }
|
export class SharedModule { }
|
||||||
@@ -1,30 +1,4 @@
|
|||||||
export class Util {
|
export class Util {
|
||||||
static getLocalDateString(input: Date) {
|
|
||||||
let year = input.getFullYear().toString();
|
|
||||||
let month = (input.getMonth() + 1).toString();
|
|
||||||
let date = input.getDate().toString();
|
|
||||||
|
|
||||||
if(month.length < 2) {
|
|
||||||
month = '0' + month;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(date.length < 2) {
|
|
||||||
date = '0' + date;
|
|
||||||
}
|
|
||||||
|
|
||||||
return year + '-' + month + '-' + date;
|
|
||||||
}
|
|
||||||
|
|
||||||
static getDateFromLocalDateString(input: string) {
|
|
||||||
let parts = input.split('-');
|
|
||||||
let date = new Date();
|
|
||||||
date.setHours(0, 0, 0, 0);
|
|
||||||
date.setFullYear(parseInt(parts[0]));
|
|
||||||
date.setMonth(parseInt(parts[1]) - 1, parseInt(parts[2]));
|
|
||||||
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newGuid() {
|
static newGuid() {
|
||||||
let arr = new Uint8Array(16);
|
let arr = new Uint8Array(16);
|
||||||
window.crypto.getRandomValues(arr);
|
window.crypto.getRandomValues(arr);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
AbstractControl
|
AbstractControl
|
||||||
} from '@angular/forms';
|
} from '@angular/forms';
|
||||||
import { Util } from '../shared/util';
|
import { Util } from '../shared/util';
|
||||||
|
import { DateUtil } from '../shared/dateutil';
|
||||||
import { OrgService } from '../core/org.service';
|
import { OrgService } from '../core/org.service';
|
||||||
import { TransactionService } from '../core/transaction.service';
|
import { TransactionService } from '../core/transaction.service';
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ export class AdvancedEdit {
|
|||||||
|
|
||||||
this.org = this.orgService.getCurrentOrg();
|
this.org = this.orgService.getCurrentOrg();
|
||||||
|
|
||||||
let dateString = Util.getLocalDateString(item.tx.date);
|
let dateString = DateUtil.getLocalDateString(item.tx.date, this.org.timezone);
|
||||||
|
|
||||||
this.form = new FormGroup({
|
this.form = new FormGroup({
|
||||||
date: new FormControl(dateString),
|
date: new FormControl(dateString),
|
||||||
@@ -110,20 +111,9 @@ export class AdvancedEdit {
|
|||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
let date = this.item.tx.id ? this.item.tx.date : new Date();
|
let date = this.item.tx.id ? this.item.tx.date : new Date();
|
||||||
let formDate = Util.getDateFromLocalDateString(this.form.value.date);
|
let formDate = DateUtil.getDateFromLocalDateString(this.form.value.date, this.org.timezone);
|
||||||
|
|
||||||
if(formDate.getTime()) {
|
date = DateUtil.computeTransactionDate(formDate, date, this.org.timezone);
|
||||||
// make the time be at the very end of the day
|
|
||||||
formDate.setHours(23, 59, 59, 999);
|
|
||||||
}
|
|
||||||
|
|
||||||
let sameDay = formDate.getFullYear() === date.getFullYear() &&
|
|
||||||
formDate.getMonth() === date.getMonth() &&
|
|
||||||
formDate.getDate() === date.getDate();
|
|
||||||
|
|
||||||
if(formDate.getTime() && !sameDay) {
|
|
||||||
date = formDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
let tx = new Transaction({
|
let tx = new Transaction({
|
||||||
id: this.item.tx.id,
|
id: this.item.tx.id,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<form [id]="'form' + item.tx.id + item.activeSplitIndex" [formGroup]="item.form" *ngFor="let item of items; let i = index">
|
<form [id]="'form' + item.tx.id + item.activeSplitIndex" [formGroup]="item.form" *ngFor="let item of items; let i = index">
|
||||||
<div class="row" (click)="editTransaction(item, $event)" [ngClass]="{odd: !(i % 2), editing: item.editing}">
|
<div class="row" (click)="editTransaction(item, $event)" [ngClass]="{odd: !(i % 2), editing: item.editing}">
|
||||||
<div class="col custom-3 date">
|
<div class="col custom-3 date">
|
||||||
<span *ngIf="!item.editing" class="date">{{item.tx.date | date:"M/d/y"}}</span>
|
<span *ngIf="!item.editing" class="date">{{item.tx.date | datetz:"M/D/YYYY":org.timezone}}</span>
|
||||||
<input *ngIf="item.editing" type="date" formControlName="date" placeholder="Date" class="form-control" (keyup.enter)="onEnter(item, $event)"/>
|
<input *ngIf="item.editing" type="date" formControlName="date" placeholder="Date" class="form-control" (keyup.enter)="onEnter(item, $event)"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col custom-7 description">
|
<div class="col custom-7 description">
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Component, Input, OnInit, ViewChild, ElementRef, AfterViewChecked, Rend
|
|||||||
import { Logger } from '../core/logger';
|
import { Logger } from '../core/logger';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { TransactionService } from '../core/transaction.service';
|
import { TransactionService } from '../core/transaction.service';
|
||||||
|
import { OrgService } from '../core/org.service';
|
||||||
import { AccountService } from '../core/account.service';
|
import { AccountService } from '../core/account.service';
|
||||||
import { Account, AccountTree } from '../shared/account';
|
import { Account, AccountTree } from '../shared/account';
|
||||||
import { Transaction, Split} from '../shared/transaction';
|
import { Transaction, Split} from '../shared/transaction';
|
||||||
@@ -17,11 +18,13 @@ import {
|
|||||||
} from '@angular/forms';
|
} from '@angular/forms';
|
||||||
import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { Util } from '../shared/util';
|
import { Util } from '../shared/util';
|
||||||
|
import { DateUtil } from '../shared/dateutil';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import 'rxjs/add/operator/mergeMap';
|
import 'rxjs/add/operator/mergeMap';
|
||||||
import { AdvancedEdit } from './advancededit';
|
import { AdvancedEdit } from './advancededit';
|
||||||
import { TxItem } from './txitem';
|
import { TxItem } from './txitem';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
import { Org } from '../shared/org';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-txlist',
|
selector: 'app-txlist',
|
||||||
@@ -34,6 +37,7 @@ export class TxListPage implements OnInit, AfterViewChecked {
|
|||||||
public account: Account;
|
public account: Account;
|
||||||
public items: TxItem[];
|
public items: TxItem[];
|
||||||
public error: AppError;
|
public error: AppError;
|
||||||
|
public org: Org;
|
||||||
private accountId: string;
|
private accountId: string;
|
||||||
private accountTree: AccountTree;
|
private accountTree: AccountTree;
|
||||||
private balance: number;
|
private balance: number;
|
||||||
@@ -54,6 +58,7 @@ export class TxListPage implements OnInit, AfterViewChecked {
|
|||||||
private log: Logger,
|
private log: Logger,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private txService: TransactionService,
|
private txService: TransactionService,
|
||||||
|
private orgService: OrgService,
|
||||||
private accountService: AccountService,
|
private accountService: AccountService,
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
private renderer: Renderer,
|
private renderer: Renderer,
|
||||||
@@ -70,6 +75,7 @@ export class TxListPage implements OnInit, AfterViewChecked {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.accountId = this.route.snapshot.paramMap.get('id'); //+this.route.snapshot.paramMap.get('id');
|
this.accountId = this.route.snapshot.paramMap.get('id'); //+this.route.snapshot.paramMap.get('id');
|
||||||
|
this.org = this.orgService.getCurrentOrg();
|
||||||
|
|
||||||
this.accountService.getAccountTree().subscribe(tree => {
|
this.accountService.getAccountTree().subscribe(tree => {
|
||||||
this.account = tree.accountMap[this.accountId];
|
this.account = tree.accountMap[this.accountId];
|
||||||
@@ -88,7 +94,7 @@ export class TxListPage implements OnInit, AfterViewChecked {
|
|||||||
splits: []
|
splits: []
|
||||||
});
|
});
|
||||||
|
|
||||||
newTx.date.setHours(23, 59, 59, 999);
|
DateUtil.setEndOfDay(newTx.date, this.org.timezone);
|
||||||
|
|
||||||
newTx.splits.push(new Split({
|
newTx.splits.push(new Split({
|
||||||
accountId: this.account.id
|
accountId: this.account.id
|
||||||
@@ -403,7 +409,7 @@ export class TxListPage implements OnInit, AfterViewChecked {
|
|||||||
|
|
||||||
item.editing = true;
|
item.editing = true;
|
||||||
|
|
||||||
let dateString = Util.getLocalDateString(item.tx.date);
|
let dateString = DateUtil.getLocalDateString(item.tx.date, this.org.timezone);
|
||||||
|
|
||||||
this.log.debug(item);
|
this.log.debug(item);
|
||||||
let debit = this.getDebit(item);
|
let debit = this.getDebit(item);
|
||||||
@@ -622,9 +628,9 @@ export class TxListPage implements OnInit, AfterViewChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let date = item.tx.id ? item.tx.date : new Date();
|
let date = item.tx.id ? item.tx.date : new Date();
|
||||||
let formDate = Util.getDateFromLocalDateString(item.form.value.date);
|
let formDate = DateUtil.getDateFromLocalDateString(item.form.value.date, this.org.timezone);
|
||||||
|
|
||||||
date = this.computeTransactionDate(formDate, date);
|
date = DateUtil.computeTransactionDate(formDate, date, this.org.timezone);
|
||||||
|
|
||||||
let tx = new Transaction({
|
let tx = new Transaction({
|
||||||
id: item.tx.id,
|
id: item.tx.id,
|
||||||
@@ -707,7 +713,7 @@ export class TxListPage implements OnInit, AfterViewChecked {
|
|||||||
splits: []
|
splits: []
|
||||||
});
|
});
|
||||||
|
|
||||||
newTx.date.setHours(23, 59, 59, 999);
|
DateUtil.setEndOfDay(newTx.date, this.org.timezone);
|
||||||
|
|
||||||
newTx.splits.push(new Split({
|
newTx.splits.push(new Split({
|
||||||
accountId: this.account.id
|
accountId: this.account.id
|
||||||
@@ -731,23 +737,6 @@ export class TxListPage implements OnInit, AfterViewChecked {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
computeTransactionDate(formDate: Date, txDate: Date): Date {
|
|
||||||
if(formDate.getTime()) {
|
|
||||||
// make the time be at the very end of the day
|
|
||||||
formDate.setHours(23, 59, 59, 999);
|
|
||||||
}
|
|
||||||
|
|
||||||
let sameDay = formDate.getFullYear() === txDate.getFullYear() &&
|
|
||||||
formDate.getMonth() === txDate.getMonth() &&
|
|
||||||
formDate.getDate() === txDate.getDate();
|
|
||||||
|
|
||||||
if(formDate.getTime() && !sameDay) {
|
|
||||||
txDate = formDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
return txDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteTransaction(item) {
|
deleteTransaction(item) {
|
||||||
this.modalService.open(this.confirmDeleteModal).result.then((result) => {
|
this.modalService.open(this.confirmDeleteModal).result.then((result) => {
|
||||||
this.log.debug('delete');
|
this.log.debug('delete');
|
||||||
@@ -842,11 +831,11 @@ export class TxListPage implements OnInit, AfterViewChecked {
|
|||||||
autocomplete(item: TxItem, tx: Transaction) {
|
autocomplete(item: TxItem, tx: Transaction) {
|
||||||
this.log.debug('chose tx', tx);
|
this.log.debug('chose tx', tx);
|
||||||
|
|
||||||
let formDate = Util.getDateFromLocalDateString(item.form.value.date);
|
let formDate = DateUtil.getDateFromLocalDateString(item.form.value.date, this.org.timezone);
|
||||||
item.tx = new Transaction(
|
item.tx = new Transaction(
|
||||||
{
|
{
|
||||||
id: item.tx.id,
|
id: item.tx.id,
|
||||||
date: this.computeTransactionDate(formDate, new Date()),
|
date: DateUtil.computeTransactionDate(formDate, new Date(), this.org.timezone),
|
||||||
description: tx.description,
|
description: tx.description,
|
||||||
splits: tx.splits
|
splits: tx.splits
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ import { TransactionService } from '../core/transaction.service';
|
|||||||
import { OrgService } from '../core/org.service';
|
import { OrgService } from '../core/org.service';
|
||||||
import { Account, AccountApi, AccountTree } from '../shared/account';
|
import { Account, AccountApi, AccountTree } from '../shared/account';
|
||||||
import { Util } from '../shared/util';
|
import { Util } from '../shared/util';
|
||||||
|
import { DateUtil } from '../shared/dateutil';
|
||||||
import { AppError } from '../shared/error';
|
import { AppError } from '../shared/error';
|
||||||
import { Transaction, Split } from '../shared/transaction';
|
import { Transaction, Split } from '../shared/transaction';
|
||||||
import { Logger } from '../core/logger';
|
import { Logger } from '../core/logger';
|
||||||
|
import { Org } from '../shared/org';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-txnew',
|
selector: 'app-txnew',
|
||||||
@@ -45,6 +47,7 @@ export class NewTransactionPage {
|
|||||||
public openingBalances: Account;
|
public openingBalances: Account;
|
||||||
public accountTree: AccountTree;
|
public accountTree: AccountTree;
|
||||||
public accountMap: any;
|
public accountMap: any;
|
||||||
|
public org;
|
||||||
@ViewChild('acc') acc: any;
|
@ViewChild('acc') acc: any;
|
||||||
@ViewChild('amount') amount: ElementRef
|
@ViewChild('amount') amount: ElementRef
|
||||||
|
|
||||||
@@ -57,12 +60,10 @@ export class NewTransactionPage {
|
|||||||
private orgService: OrgService,
|
private orgService: OrgService,
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
private log: Logger) {
|
private log: Logger) {
|
||||||
|
|
||||||
this.numAccountsShown = 3;
|
this.numAccountsShown = 3;
|
||||||
|
this.org = this.orgService.getCurrentOrg();
|
||||||
|
|
||||||
let org = this.orgService.getCurrentOrg();
|
let dateString = DateUtil.getLocalDateString(new Date(), this.org.timezone);
|
||||||
|
|
||||||
let dateString = Util.getLocalDateString(new Date());
|
|
||||||
this.form = this.fb.group({
|
this.form = this.fb.group({
|
||||||
type: ['', Validators.required],
|
type: ['', Validators.required],
|
||||||
firstAccountPrimary: [null, Validators.required],
|
firstAccountPrimary: [null, Validators.required],
|
||||||
@@ -226,20 +227,9 @@ export class NewTransactionPage {
|
|||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
let date = new Date();
|
let date = new Date();
|
||||||
let formDate = Util.getDateFromLocalDateString(this.form.value.date);
|
let formDate = DateUtil.getDateFromLocalDateString(this.form.value.date, this.org.timezone);
|
||||||
|
|
||||||
if (formDate.getTime()) {
|
date = DateUtil.computeTransactionDate(formDate, date, this.org.timezone);
|
||||||
// make the time be at the very end of the day
|
|
||||||
formDate.setHours(23, 59, 59, 999);
|
|
||||||
}
|
|
||||||
|
|
||||||
let sameDay = formDate.getFullYear() === date.getFullYear() &&
|
|
||||||
formDate.getMonth() === date.getMonth() &&
|
|
||||||
formDate.getDate() === date.getDate();
|
|
||||||
|
|
||||||
if (formDate.getTime() && !sameDay) {
|
|
||||||
date = formDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
let tx = new Transaction({
|
let tx = new Transaction({
|
||||||
id: Util.newGuid(),
|
id: Util.newGuid(),
|
||||||
|
|||||||
Reference in New Issue
Block a user