aodb/app/flight-detail/transactions/transaction-detail.ts

413 lines
16 KiB
TypeScript
Raw Normal View History

2016-12-22 00:00:06 +00:00
import {controller, directive} from '../../infrastructure/Dectorators/Components';
import {ITransactionDetail} from '../services/transactionService';
import {Mod} from './transaction.mod';
import {IFlightInformation} from '../services/flightInformationService';
import {IFlightDetail} from '../../core/service/flightService';
import {ITransactionService, TransactionCode, ITransactionConfig} from '../services/transactionService';
import * as InformationService from '../services/flightInformationService';
import {LookupModel, EditorField, LookupEditorField} from '../services/flightInformationService';
export interface TransactionDetailParams extends ng.ui.IStateParamsService {
transaction: ITransactionDetail;
flight: IFlightDetail;
tranAccess: InformationService.IUserAccessModel;
columnConfig: Array<ITransactionConfig>;
}
export class TransactionDetail implements ITransactionDetail {
constructor(public PublflightId: string,
public Id: string,
public Code:string,
public Name:string,
public Quantity: number,
public Duration: string,
public PONumber: string,
public StartTime: string,
public EndTime: string,
public PhysflightId: string,
public Confirmed: boolean,
public Cancelled: boolean,
public CodeType: number,
public Timestamp: number) {
}
}
enum TransactionType {
QuantityOnly = 1,
TimesOnly,
TimeDurationAndQuantity
}
export class Editor implements InformationService.IFlightEditor {
constructor(public Name: string,
public Type: string,
public Url:string) {
}
}
@controller(Mod, 'transactionDetailController', ['$state', '$scope', '$stateParams', '$ionicPopup', '$rootScope', 'transactionService'])
export class Controller {
public model: ITransactionDetail;
public fields: Array<IFlightInformation>;
public editors: Array<InformationService.IFlightEditor>;
public columnConfig: Array<ITransactionConfig>;
public IsNewAdd: boolean = false;
public flightId: string;
public physFlightId: string;
public lookupModel: LookupModel;
public confirmStatus: string;
public createStatus: string;
public cancelStatus: string;
public editStatus: string;
public selectedTranCode: TransactionCode;
public recalculatingDuration: boolean = false;
public recalculationFromDuration: boolean = false;
constructor(private $state : ng.ui.IStateService,
private $scope: ng.IScope,
private $stateParams: TransactionDetailParams,
private $ionicPopup: ionic.popup.IonicPopupService,
private $rootScope: ng.IRootScopeService,
private transactionService: ITransactionService) {
this.model = $stateParams.transaction;
this.flightId = $stateParams.flight.Id;
this.physFlightId = $stateParams.flight.PhysFlightId;
if (this.model === null) {
this.initNewModel();
this.IsNewAdd = true;
}
this.columnConfig = $stateParams.columnConfig;
if (this.columnConfig === null) {
console.log('failed to get column config');
}
this.editors = [];
this.editors.push({Name: 'readonly', Type: 'readonly', Url: ''});
this.editors.push({Name: 'datetime', Type: 'datetime', Url: ''});
this.editors.push({Name: 'freetext', Type: 'freetext', Url: ''});
this.editors.push({Name: 'lookup', Type: 'lookup', Url: '' }) ;
this.createLookupModel();
this.buildFieldsFromModel();
if (!this.IsNewAdd) {
var trancode = new TransactionCode();
trancode.CodeType = this.model.CodeType;
this.runDisplayLogic(trancode, false);
} else {
this.editorFor(this.fields[1]);
}
}
private initNewModel() {
this.model = new TransactionDetail(this.flightId, '', '', '', 0, '', '', '', '', this.physFlightId, false, false, 1, 0);
}
public OnStartTimeChanged = (newValue, oldValue) => {
if (!this.recalculationFromDuration) {
if (oldValue.Value === newValue.Value) {
return;
}
if (this.fieldByName('EndTime').Value !== '') {
this.recalculatingDuration = true;
this.recalculateDuration();
}
}
this.recalculationFromDuration = false;
}
public OnEndTimeChanged = (newValue, oldValue) => {
if (!this.recalculationFromDuration) {
if (oldValue.Value === newValue.Value) {
return;
}
if (this.fieldByName('StartTime').Value !== '') {
this.recalculatingDuration = true;
this.recalculateDuration();
}
}
this.recalculationFromDuration = false;
}
private recalculateDuration() {
var start = moment(this.fieldByName('StartTime').Value);
var end = moment(this.fieldByName('EndTime').Value);
this.fieldByName('Duration').Value = Math.round(moment.duration(end.diff(start)).asMinutes()).toString();
}
public OnDurationChanged = (newValue, oldValue) => {
if (!this.recalculatingDuration) {
if (oldValue.Value === newValue.Value) {
return;
}
this.recalculationFromDuration = true;
if (this.fieldByName('StartTime').Value !== '') {
this.recalculateEndTimeFromDurationAndCurrentStartTime();
} else {
this.recalculateEndTimeFromStartIsNowPlusDuration();
}
}
this.recalculatingDuration = false;
}
private recalculateEndTimeFromDurationAndCurrentStartTime() {
var currentStart = moment(this.fieldByName('StartTime').Value);
this.fieldByName('EndTime').Value = currentStart.add(this.fieldByName('Duration').Value, 'minutes').toISOString();
}
private recalculateEndTimeFromStartIsNowPlusDuration() {
var startIsNow = moment(new Date());
this.fieldByName('StartTime').Value = startIsNow.toISOString();
this.fieldByName('EndTime').Value = startIsNow.add(this.fieldByName('Duration').Value, 'minutes').toISOString();
}
private addWatches() {
this.$scope.$watch('vm.fields[4]', this.OnStartTimeChanged, true);
this.$scope.$watch('vm.fields[5]', this.OnEndTimeChanged, true);
this.$scope.$watch('vm.fields[6]', this.OnDurationChanged, true);
}
private createLookupModel() {
this.lookupModel = new LookupModel();
this.lookupModel.searchString = '';
this.lookupModel.resultField = 'Name';
this.transactionService.getTransactionCodes()
.then((r) => this.onTransactionCodesLoad(r));
var self = this;
this.lookupModel.results = [];
this.lookupModel.onSelected = (selectedTransactionCode: any) => {
self.runDisplayLogic(selectedTransactionCode, true);
self.selectedTranCode = selectedTransactionCode;
};
this.lookupModel.search = () => {
this.lookupModel.results = self.lookupModel.lookupList.filter(item =>
item.Code.indexOf(self.lookupModel.searchString.toUpperCase()) !== -1 ||
item.Name.indexOf(self.lookupModel.searchString.toUpperCase()) !== -1);
};
}
private onTransactionCodesLoad(request: any) : void {
this.lookupModel.lookupList = request;
this.lookupModel.results = this.lookupModel.lookupList;
}
private findCode(value: any, searchStr: string) {
return value.Name === searchStr;
}
public runDisplayLogic(selectedTransactionCode, notCreatedYet: boolean) {
var trancode = selectedTransactionCode as TransactionCode;
var fields = this.fields as EditorField[];
if (notCreatedYet) {
this.resetFields(fields);
fields[0].Value = selectedTransactionCode.Name;
fields[1].Value = selectedTransactionCode.Code;
}
if (trancode.CodeType === TransactionType.QuantityOnly) {
fields[6].Invisible = true; //duration
fields[4].Invisible = true; //StartTime
fields[5].Invisible = true; //EndTime
} else if (trancode.CodeType === TransactionType.TimesOnly) {
fields[3].Invisible = true;
}
}
private resetFields(fields: EditorField[]) {
for (var i = 0; i < fields.length; i++) {
fields[i].Invisible = false;
if (fields[i].Editor === 'datetime') {
fields[i].Value = '';
} else {
fields[i].Value = null;
}
}
}
private confirmTransaction() {
this.buildModelFromEditorFields();
this.confirmStatus = 'P';
this.transactionService.confirmTransaction(this.model)
.then(() => {
this.confirmStatus = 'S';
this.$state.go('chroma.flight-detail.transaction-list');
});
}
private cancelTransaction() {
this.buildModelFromEditorFields();
this.cancelStatus = 'P';
this.transactionService.cancelTransaction(this.model)
.then(() => {
this.cancelStatus = 'S';
this.$state.go('chroma.flight-detail.transaction-list');
});
}
private buildFieldsFromModel() {
this.fields = [];
this.fields.push(new EditorField('Name', this.model.Name, 'readonly', '', '', '', true, false));
this.fields.push(new LookupEditorField('Code', this.model.Code, this.editorOrReadonly('FLGTTRAN_TRANCATG_CODE', 'lookup'), '', '', this.lookupModel, '', true, false));
this.fields.push(new EditorField('PONumber', this.model.PONumber, this.editorOrReadonly('FLGTTRAN_PO_NUMBER', 'freetext'), '', '', '', true, false));
this.fields.push(new EditorField('Quantity', this.model.Quantity.toString(), this.editorOrReadonly('FLGTTRAN_QUANTITY', 'freetext'), '', '', '', true, false));
this.fields.push(new EditorField('StartTime', this.model.StartTime, this.editorOrReadonly('FLGTTRAN_START_DATE_TIME', 'datetime') , '', '', '', true, false));
this.fields.push(new EditorField('EndTime', this.model.EndTime, this.editorOrReadonly('FLGTTRAN_END_DATE_TIME', 'datetime'), '', '', '', true, false));
this.fields.push(new EditorField('Duration', this.model.Duration, this.editorOrReadonly('FLGTTRAN_DURATION', 'freetext'), '', '', '', true, false));
this.addWatches();
}
private editorOrReadonly(fieldName: string, type: string) {
var editable = this.columnAccessByFieldName(fieldName);
if (editable) {
return type;
}
return 'readonly';
}
private columnAccessByFieldName(name: string) : boolean {
if (this.IsNewAdd !== true) {
return false; //can't edit fields on modify screen
}
let col : ITransactionConfig = this.columnConfig.filter(item => item.ColumnName.indexOf(name) !== - 1)[0];
return col.Editable;
}
private createTransaction() {
this.buildModelFromEditorFields();
if (this.formIsValid()) {
this.transactionService.createTransaction(this.model)
.then(() =>
this.$state.go('chroma.flight-detail.transaction-list')
);
}
}
private formIsValid() : boolean {
let editorFields = this.fields as Array<EditorField>;
var valid = true;
editorFields.forEach(element => {
if (element.Invisible === false) {
if (!this.validateQuantity(element)) {
valid = false;
}
if (!this.validateTimes(element)) {
valid = false;
}
if (!this.validateTimesAndQuantity(element)) {
valid = false;
}
}
});
return valid;
}
private validateQuantity(element: EditorField) : boolean {
if (this.selectedTranCode.CodeType === TransactionType.QuantityOnly || this.selectedTranCode.CodeType === TransactionType.TimeDurationAndQuantity) {
if (element.Name === 'Quantity' && (element.Value === '' || element.Value === null)) {
element.Invalid = true;
return false;
}
}
return true;
}
private validateTimes(element: EditorField) : boolean {
if (this.selectedTranCode.CodeType === TransactionType.TimesOnly || this.selectedTranCode.CodeType === TransactionType.TimeDurationAndQuantity) {
if ((element.Name === 'StartTime' || element.Name === 'EndTime' || element.Name === 'Duration')
&& (element.Value === '' || element.Value === null)) {
element.Invalid = true;
return false;
}
}
return true;
}
private validateTimesAndQuantity(element: EditorField) : boolean {
if (this.selectedTranCode.CodeType === TransactionType.TimeDurationAndQuantity) {
return this.validateTimes(element) && this.validateQuantity(element);
}
return true;
}
private buildModelFromEditorFields() {
var publflgt = this.model.PublflightId;
var Id = this.model.Id;
var physFlightId = this.model.PhysflightId;
var timestamp = this.model.Timestamp;
this.model = new TransactionDetail(publflgt,
Id,
this.fieldByName('Code').Value,
this.fieldByName('Name').Value,
Number(this.fieldByName('Quantity').Value),
this.fieldByName('Duration').Value,
this.fieldByName('PONumber').Value,
this.fieldByName('StartTime').Value,
this.fieldByName('EndTime').Value,
physFlightId,
this.model.Confirmed,
this.model.Cancelled, 1,
timestamp);
}
private fieldByName(name: string) : IFlightInformation {
let field : IFlightInformation = this.fields.filter(item => item.Name.indexOf(name) !== -1)[0];
return field;
}
public editorFor(field: InformationService.IFlightInformation) {
if (field.Editor.toLowerCase() === 'readonly') { return; }
let editor = field.Editor.toLowerCase();
let modalScope: any = this.$rootScope.$new();
let editorDefinition: InformationService.IFlightEditor;
this.editors.forEach(e => {
if (e.Name.toLowerCase() === editor) {
editorDefinition = e;
}
});
modalScope.model = this.model;
modalScope.field = field;
modalScope.editor = editorDefinition;
if (field.Editor.toLowerCase() === 'lookup') {
modalScope.lookupModel = this.lookupModel;
}
modalScope.instance = this.$ionicPopup.show({
templateUrl: `app/flight-detail/editors/${editor}/${editor}-holder.tpl.html`,
cssClass: `editor editor-${editor}`,
title: `Update ${field.Name}`,
scope: modalScope
});
}
}
@directive(Mod, 'chromaTransactionDetail')
export class Directive implements ng.IDirective {
controller: string = Controller.$componentName;
controllerAs: string = 'vm';
templateUrl: string = 'app/flight-detail/transactions/transaction-detail.tpl.html';
restrict: string = 'E';
replace: boolean = false;
scope: any = true;
}