// Angular imports // import { Component, OnInit, Inject, OnDestroy } from '@angular/core'; import { downgradeComponent } from '@angular/upgrade/static'; declare const angular: angular.IAngularStatic; import * as statics from '@fb/statics'; // RxJS // import { Subject } from 'rxjs/Subject'; // Filters // import { PhoneNumberPipe } from '@fb/common/pipes/phoneNumber.pipe'; import { IBefintligSaeljare } from './fb-side-drawer-kundportal.interface'; const styles: any[] = [require('./fb-side-drawer-kundportal.component.less')]; @Component({ selector: 'fb-side-drawer-kundportal', templateUrl: './fb-side-drawer-kundportal.component.html', styles: styles }) export class FbSideDrawerKundportalComponent implements OnInit, OnDestroy { header: string; dependencyPromise: Promise; flyttaMedBevakningarOptionList: { name: string, value: boolean }[]; allFlyttaMedBevakningar: fb.ChangeTrack = new fb.ChangeTrack(true); existSaeljareUtanPersonnummer: boolean = false; befintligaSaeljareList: IBefintligSaeljare[]; isOpenedFromStatusByte: boolean; dependencyPromiseFailed: boolean = false; dependencyPromiseSuccess: boolean = false; changedBefintligMejl: boolean = false; saveSubjekt: any = new Subject(); befintligaSaeljareListIsInitiated: boolean = false; kundportalInstaellningTree: fb.KundportalInstaellningarLO[]; instaellningarIsDisabled: boolean = true; aerMaeklarObjektGodkaend: boolean; private kundportalInstaellningList: fb.List; // Nu hårdkodas vilka som ska expanderas. Eventuellt borde detta ändras till grupper av radiobuttons private readonly defaultExpandInstaellningOnAerAktivList: number[] = [fb.FasITDomain.KUNDPORTAL_INSTAELLNING_ID.BOSTADSBESKRIVNING]; // Alla där barninställningarna sätter sin rotinställning och vice versa private readonly rotInstaellningIsEntangledWithBarnInstaellningList: number[] = [fb.FasITDomain.KUNDPORTAL_INSTAELLNING_ID.DRIFTSKOSTNADER]; private maeklarObjekt: fb.MaeklarObjektDO; private changedBefintligMejlAngivet: boolean = false; private aktivaSaeljareList: number[] = []; // Lista av säljarna som redan har tillgång till Kundportalen constructor( private readonly phoneNumberPipe: PhoneNumberPipe, @Inject('SideDrawerService') private readonly sideDrawerService: fb.ISideDrawerService, // TODO frha: Migrera kundportalenservicen @Inject('KundportalenService') private readonly kundportalenService: fb.IKundportalenService, @Inject('IntressentService') private readonly intressentService: fb.IIntressentService, @Inject('PersonService') private readonly personService: fb.IPersonService, @Inject('GlobalTimerService') private readonly globalTimerService: fb.IGlobalTimerService ) { } ngOnInit(): void { const params: { maeklarObjekt: fb.MaeklarObjektDO, fraanStatusByte?: boolean } = this.sideDrawerService.getParams(); this.maeklarObjekt = params.maeklarObjekt; this.isOpenedFromStatusByte = !!params.fraanStatusByte; this.flyttaMedBevakningarOptionList = [{ name: 'Ja', value: true }, { name: 'Nej', value: false }]; this.initKundportalInstaellningList(); this.header = this.maeklarObjekt.Adress.AdressText.value; const saeljarePromise: angular.IPromise = this.initBefintligaSaeljareListAndGetPromiseList(); this.setupDependencyPromise(saeljarePromise); this.setKundportalenInstaellningDefault(); this.instaellningarIsDisabled = this.disableInstaellningar(); if (this.maeklarObjekt.$resolved) { this.aerMaeklarObjektGodkaend = !!this.maeklarObjekt.GodkaendViaKundportal.value; } else { this.maeklarObjekt .$promise .then(() => this.aerMaeklarObjektGodkaend = !!this.maeklarObjekt.GodkaendViaKundportal.value) .catch(() => null); } } ngOnDestroy(): void { statics.destroySubscribers([this.saveSubjekt]); } /** * Sparar allt, hämtar lista av nya mottagare och öppnar Epost-utskick side drawer */ skickaEpost(): void { this.handleSaveAndDo(() => this.openEpostUtskick(false, true, true, fb.FasITDomain.TextMallNamn.KUNDPORTALEN_INLOGGNING)); } /** * Sparar allt, hämtar lista av nya mottagare och öppnar SMS-utskick side drawer */ skickaSMS(): void { this.handleSaveAndDo(() => this.openSkickaSMS(true)); } /** * Sparar alla, stänger kundportalen-side drawer och öppnar EpostUtskick-side drawer vid behov */ done(): void { this.handleSaveAndDo(this.openEpostUtskickIfNecessary.bind(this)); } disableStartaKundportalen(): boolean { return !this.befintligaSaeljareList || this.befintligaSaeljareList.length === 0; } onRotInstaellningChange(rotinstaellning: fb.KundportalInstaellningarLO): void { // Om man kryssar i en som ska defaultöppnas, expandera. if (!!this.defaultExpandInstaellningOnAerAktivList.some(def => def === rotinstaellning.KundportalInstaellningId.value) && rotinstaellning.AerAktiverat.value) { rotinstaellning.isExpanded = true; } // Om man ändrar en som är entangled med sina barn, ändra all barn så de får samma värde if (!!this.rotInstaellningIsEntangledWithBarnInstaellningList.some(def => def === rotinstaellning.KundportalInstaellningId.value)) { this.kundportalInstaellningList.toArray() .filter((inst) => inst.RotinstaellningId.value === rotinstaellning.KundportalInstaellningId.value ) .forEach((barnInstaellning) => { barnInstaellning.AerAktiverat.setValue(rotinstaellning.AerAktiverat.value); }); } } onRadiobuttonBarnInstaellningChange(instaellning: fb.KundportalInstaellningarLO): void { const matchInstaellningList: fb.KundportalInstaellningarLO[] = this.kundportalInstaellningList.toArray() .filter(inst => inst.InstaellninggruppId.value === instaellning.InstaellninggruppId.value && inst.KundportalInstaellningId.value === instaellning.KundportalInstaellningId.value); if (!matchInstaellningList.some(inst => inst.AerAktiverat.value)) { matchInstaellningList.forEach(inst => inst.AerAktiverat.setValue(true)); } this.kundportalInstaellningList.toArray() .filter(inst => inst.InstaellninggruppId.value === instaellning.InstaellninggruppId.value && inst.KundportalInstaellningId.value !== instaellning.KundportalInstaellningId.value ).forEach(inst => inst.AerAktiverat.setValue(false)); } onCheckboxBarnInstaellningChange(instaellning: fb.KundportalInstaellningarLO): void { if (this.rotInstaellningIsEntangledWithBarnInstaellningList.some(entangled => entangled === instaellning.RotinstaellningId.value)) { // Kontrollera om rotinställning ska sättas omm let changeRotInstaellning: boolean = false; if (instaellning.AerAktiverat.value) { changeRotInstaellning = true; } else { const barnInstaellningList: fb.KundportalInstaellningarLO[] = this.getSelectableBarnInstaellningTillRotinstaellningList(instaellning.RotinstaellningId.value); changeRotInstaellning = barnInstaellningList.every((bi) => { return !bi.AerAktiverat.value; }); } if (changeRotInstaellning) { const rotInstaellning: fb.KundportalInstaellningarLO = this.kundportalInstaellningList.toArray() .find((inst) => inst.KundportalInstaellningId.value === instaellning.RotinstaellningId.value); rotInstaellning.AerAktiverat.setValue(instaellning.AerAktiverat.value); } } } onMejladressChange(): void { // Om mejladress för befintliga säljare (befintligaSaeljareList) uppdateras så visa // info text för att uppdatera allFlyttaMedBevakningar fält på säljarna const existDirtyAdress: boolean = this.befintligaSaeljareList .some(val => val.person.MejlAdress.Mejladress.dirty); if (existDirtyAdress) { if (!this.changedBefintligMejl && !this.changedBefintligMejlAngivet) { this.changedBefintligMejl = true; this.changedBefintligMejlAngivet = true; this.allFlyttaMedBevakningar.setValue(true); } } } closeDrawer(): void { this.sideDrawerService.closeCurrentSideDrawer(false); } private getSelectableBarnInstaellningTillRotinstaellningList(rotinstaellningId: number): fb.KundportalInstaellningarLO[] { return this.kundportalInstaellningList.toArray() .filter(instaellning => instaellning.RotinstaellningId.value === rotinstaellningId && instaellning.isSelectable) as fb.KundportalInstaellningarLO[]; } private disableInstaellningar(): boolean { return this.maeklarObjekt.UppdragStatus.value === fb.FasITDomain.UppdragStatus.SAALD || this.maeklarObjekt.UppdragStatus.value === fb.FasITDomain.UppdragStatus.AATERTAGEN || this.maeklarObjekt.UppdragStatus.value === fb.FasITDomain.UppdragStatus.INGET_UPPDRAG; } /** * En funktion som returnerar namnet på installningsgruppen om den finns * @param rotId {KundportalInstaellningId: number} * @returns {string} groupnamn */ private getBarnInstaellninggruppNamn(rotId: number): string { const instaellningsGrupp: fb.KundportalInstaellningarLO = this.kundportalInstaellningList.toArray().find(instaellning => instaellning.RotinstaellningId.value === rotId); return instaellningsGrupp ? instaellningsGrupp.InstaellninggruppNamn.value : ''; } private initKundportalInstaellningList(): void { const disableInstaellningFoerBostadsraettList: number[] = [ fb.FasITDomain.KUNDPORTAL_INSTAELLNING_ID.SOPHAEMTNING, fb.FasITDomain.KUNDPORTAL_INSTAELLNING_ID.VAEG_OCH_SAMFAELLIGHET]; const disableInstaellningFoerOevrigaList: number[] = []; this.kundportalInstaellningList = this.kundportalenService.get(this.maeklarObjekt.MaeklarObjektId.value); this.kundportalInstaellningList.$promise.then(() => { const rotInstaellningIdList: number[] = []; this.kundportalInstaellningList.toArray().forEach((instaellning) => { // Ska inställningen starta som expanderad? instaellning.isExpanded = !!this.defaultExpandInstaellningOnAerAktivList.some(def => def === instaellning.KundportalInstaellningId.value) && instaellning.AerAktiverat.value; // Är inställningen valbar för denna objekttyp? instaellning.isSelectable = this.maeklarObjekt.ObjektTypId.value === fb.FasITDomain.ObjektTypId.MOBostadsraett ? !disableInstaellningFoerBostadsraettList.some(disabled => disabled === instaellning.KundportalInstaellningId.value) : !disableInstaellningFoerOevrigaList.some(disabled => disabled === instaellning.KundportalInstaellningId.value); // Är denna en underinställning (som kommer vara valbar)? if (instaellning.RotinstaellningId.value && instaellning.isSelectable) { rotInstaellningIdList.push(instaellning.RotinstaellningId.value); } }); this.kundportalInstaellningTree = this.getRotinstaellningTree(rotInstaellningIdList); }); } private getRotinstaellningTree(idList: number[]): fb.KundportalInstaellningarLO[] { idList = statics.getUniqueArray(idList); const toReturn: fb.KundportalInstaellningarLO[] = []; this.kundportalInstaellningList.toArray() .filter(inst => statics.isUndefined(inst.RotinstaellningId.value)) .forEach((instaellning) => { instaellning.instaellninggruppNamnFoerBarn = this.getBarnInstaellninggruppNamn(instaellning.KundportalInstaellningId.value); instaellning.barn = this.getSelectableBarnInstaellningTillRotinstaellningList(instaellning.KundportalInstaellningId.value); instaellning.harBarn = instaellning.barn.length > 0; const barnSomAerRotList: fb.KundportalInstaellningarLO[] = instaellning.barn.filter(barnInst => idList.some(id2 => id2 === barnInst.KundportalInstaellningId.value)); if (barnSomAerRotList.length > 0) { barnSomAerRotList.forEach(barnSomAerRot => { barnSomAerRot.barn = this.getSelectableBarnInstaellningTillRotinstaellningList(barnSomAerRot.KundportalInstaellningId.value); }); } if (!instaellning.RotinstaellningId.value) { toReturn.push(instaellning); } }); return toReturn; } /** * Öppnar epost-utskick jordgubben * @param medCallback {boolean} För att köra - eller inte - den callback funktionem som finns i SideDrawerService när man stänger epost utskick jordgubben * @param inloggadAnvaendareSomAvsaendare {boolean} för att sätta den inloggade användaren som avsändare istället av den ansvarig mäklare * @param tillAllaAktivaSaeljare {boolean} True: för att sätta alla säljarna som har Kundportalen aktiverat som mottagarem, False för att sätta bara de nya */ private openEpostUtskick(medCallback: boolean = false, inloggadAnvaendareSomAvsaendare: boolean = false, tillAllaAktivaSaeljare: boolean = false, mejlMall: string = fb.FasITDomain.TextMallNamn.KUNDPORTALEN_AKTIVERAD ): void { let callback: any = null; if (medCallback) { callback = this.sideDrawerService.getCallback(); } const tmp: any = () => { if (callback && medCallback) { this.sideDrawerService.clearDrawer(); callback(); } else { this.sideDrawerService.clearDrawer(); } }; this.sideDrawerService.setSideDrawer(fb.FasITDomain.SideDrawerName.EPOST_UTSKICK, { textMallNamn: mejlMall, recipients: tillAllaAktivaSaeljare ? this.getAllaAktivaSaeljare() : this.getNyaMottagare(), sender: inloggadAnvaendareSomAvsaendare ? null : new fb.PersonAvsaendare({ PersonId: this.maeklarObjekt.AnsvarigMaeklareId.value, PersonNamn: this.maeklarObjekt.AnsvarigMaeklareNamn.value }), useCallbackOnAbort: medCallback, maeklarObjektId: this.maeklarObjekt.MaeklarObjektId.value }, undefined, tmp.bind(this)); } private openEpostUtskickIfNecessary(): void { if (this.isOpenedFromStatusByte) { this.openEpostUtskick(true); } else { this.sideDrawerService.clearDrawer(); const nyaMottagare: fb.PersonMottagare[] = this.getNyaMottagare(); if (nyaMottagare && nyaMottagare.length > 0 && !this.aerBostadsbeskrivningenAktiv()) { this.openEpostUtskick(false); } else if (nyaMottagare && nyaMottagare.length > 0 && this.aerBostadsbeskrivningenAktiv()) { this.openEpostUtskickBostadsbeskrivning(true); } else if (this.aerBostadsbeskrivningenAktiv()) { this.openEpostUtskickBostadsbeskrivning(); } } } /** * Öppnar SMS-utskick jordgubben * @param tillAllaAktivaSaeljare {boolean} True: för att sätta alla säljarna som har Kundportalen aktiverat som mottagarem, False för att sätta bara de nya */ private openSkickaSMS(tillAllaAktivaSaeljare: boolean = false): void { this.sideDrawerService.setSideDrawer(fb.FasITDomain.SideDrawerName.SMS_UTSKICK, { textMallNamn: fb.FasITDomain.TextMallNamn.KUNDPORTALEN_SMS, recipients: tillAllaAktivaSaeljare ? this.getAllaAktivaSaeljare() : this.getNyaMottagare(), maeklarObjektId: this.maeklarObjekt.MaeklarObjektId.value }); } /** * Hämtar de säljarna som har aktiverat i den här jorgubben och filtrerar bort som redan har tillgång till Kundportalen, * Den mappar resultatet till en lista av fb.PersonMottagare * @returns {fb.PersonMottagare[]} en lista av mottagare, kompatiblet med Epost och SMS utskick jordgubbe */ private getNyaMottagare(): fb.PersonMottagare[] { return this.befintligaSaeljareList .filter(saeljare => saeljare.part.KundportalAktiverad.value && this.aktivaSaeljareList.indexOf(saeljare.part.PersonId.value) < 0) .map(saeljare => new fb.PersonMottagare({ TelefonnummerMobil: saeljare.part.TelefonnummerMobil !== null ? this.phoneNumberPipe.transform(saeljare.part.TelefonnummerMobil.value) : null, PersonId: saeljare.part.PersonId.value, PersonNamn: saeljare.part.Personnamn.value, MejlAdress: saeljare.person.MejlAdress.Mejladress.value })); } /** * Hämtar alla säljarna som har tillgång till Kondportalen, * Den mappar resultatet till en lista av fb.PersonMottagare * @returns {fb.PersonMottagare[]} en lista av mottagare, kompatiblet med Epost och SMS utskick jordgubbe */ private getAllaAktivaSaeljare(): fb.PersonMottagare[] { return this.befintligaSaeljareList .filter(saeljare => saeljare.part.KundportalAktiverad.value) .map(saeljare => new fb.PersonMottagare({ TelefonnummerMobil: saeljare.part.TelefonnummerMobil !== null ? this.phoneNumberPipe.transform(saeljare.part.TelefonnummerMobil.value) : null, PersonId: saeljare.part.PersonId.value, PersonNamn: saeljare.part.Personnamn.value, MejlAdress: saeljare.person.MejlAdress.Mejladress.value })); } private setKundportalenInstaellningDefault(): void { // Lyssnar på kundportalInstaellningList promis för att sätta upp de inställningarna this.kundportalInstaellningList.$promise.then(() => { // Sätt default värden vid behov då alla inställningar är inaktiverade const aerAktiveratOnlyFalse: boolean = this.kundportalInstaellningList.toArray().filter(value => !value.AerAktiverat || !value.AerAktiverat.value).length === this.kundportalInstaellningList.toArray().length; if (this.kundportalInstaellningList.length > 0 && (this.isOpenedFromStatusByte || aerAktiveratOnlyFalse)) { angular.forEach(this.kundportalInstaellningList, (instaellning: fb.KundportalInstaellningarLO) => { instaellning.AerAktiverat.value = instaellning.AerDefault.value; }); } }); } private setupDependencyPromise(promiseList: angular.IPromise): void { // Vänta på alla promises som den här jordgubben behöver this.dependencyPromise = Promise.all([ this.maeklarObjekt.$promise, this.kundportalInstaellningList.$promise, promiseList ]); this.dependencyPromise.then(() => { this.dependencyPromiseSuccess = true; }).catch(() => { this.dependencyPromiseFailed = true; }); } /** * Lägg till en ny säljare till befintligaSaeljareList lista * @param part {fb.ObjIntressentPartDO} * @param person {fb.Models_IPersonDO} */ private laeggTillSaeljare(part: fb.ObjIntressentPartDO, person: fb.Models_IPersonDO): void { if ((part.ObjIntressentRoll.value === fb.FasITDomain.ObjIntressentRoll.SAELJARE || part.ObjIntressentRoll.value === fb.FasITDomain.ObjIntressentRoll.SAELJARENS_KONTAKTPERSON) && !person.isPersonJuridisk()) { this.befintligaSaeljareList.push({ part: part, person: person, aktiv: this.kanAktiveraKundportalen(part, person) }); // Kontrollera om det finns personer utan personnummer eller av annan nationalitet if (person && (!person.Personnummer || !person.Personnummer.value || (person.NationalitetId && person.NationalitetId.value && person.NationalitetId.value !== fb.FasITDomain.LandId.SVERIGE) )) { this.existSaeljareUtanPersonnummer = true; } if (this.isOpenedFromStatusByte) { part.KundportalAktiverad.setValue(true); } else if (part.KundportalAktiverad.value && person && person.Personnummer && person.Personnummer.value) { // Måste ha svenskt personnummer this.aktivaSaeljareList.push(part.PersonId.value); } } } /** * Kollar om det går att aktivera Kundportalen på den här säljaren * @param part {fb.ObjIntressentPartDO} * @param person {fb.Models_IPersonDO} */ private kanAktiveraKundportalen(part: fb.ObjIntressentPartDO, person: fb.Models_IPersonDO): boolean { return (part.ObjIntressentRoll.value === fb.FasITDomain.ObjIntressentRoll.SAELJARE || part.ObjIntressentRoll.value === fb.FasITDomain.ObjIntressentRoll.SAELJARENS_KONTAKTPERSON) && !person.isPersonJuridisk() && person.Personnummer && person.Personnummer.value && // Säljaren har ett svenskt personnummer (!person.NationalitetId || !person.NationalitetId.value || person.NationalitetId.value === fb.FasITDomain.LandId.SVERIGE); } private initBefintligaSaeljareListAndGetPromiseList(): angular.IPromise { const promiseList: angular.IPromise[] = []; const partList: fb.List = this.intressentService.queryParter(this.maeklarObjekt.MaeklarObjektId.value); const befintligaSaeljarePromise: angular.IPromise = partList.$promise.then(() => { this.befintligaSaeljareList = []; partList.toArray().forEach((part: fb.ObjIntressentPartDO) => { const person: { $promise: any, person: fb.Models_IPersonDO } = this.personService.get(part.PersonId.value, false); person.$promise.then(() => { if (person.person && !person.person.$resolved) { person.person.$promise.then(() => { this.laeggTillSaeljare(part, person ? person.person : null); if (!this.kanAktiveraKundportalen(part, person ? person.person : null) && part.KundportalAktiverad && part.KundportalAktiverad.value) { part.KundportalAktiverad.setValue(false); } }); } else if (!person.person) { return; } else { this.laeggTillSaeljare(part, person ? person.person : null); if (!this.kanAktiveraKundportalen(part, person ? person.person : null) && part.KundportalAktiverad && part.KundportalAktiverad.value) { part.KundportalAktiverad.setValue(false); } } this.befintligaSaeljareListIsInitiated = true; }); promiseList.push(person.$promise); }); return promiseList; }); return befintligaSaeljarePromise; } /** * Spara Kundportal inställningar, uppdatera aktiva säljare samt epost adresser * @returns {angular.IPromise[]} en Array av alla promises som sparar datan */ private spara(): angular.IPromise[] { const saveInstaellningList: fb.KundportalInstaellningarLO[] = this.kundportalInstaellningList.toArray().map(instaellning => new fb.KundportalInstaellningarLO({ KundportalInstaellningId: instaellning.KundportalInstaellningId.value, AerAktiverat: instaellning.AerAktiverat.value !== undefined ? (instaellning.AerAktiverat as any).value : instaellning.AerAktiverat })); this.befintligaSaeljareList.forEach(val => { if (val.person.MejlAdress.Mejladress.dirty) { val.person.MejlAdress.FlyttaMedBevakningar.setValue(this.allFlyttaMedBevakningar.value); } }); const globalTimerSavePromise: any = this.globalTimerService.globalSave(true); const kundportalenServicePromise: angular.IPromise = !this.disableInstaellningar() ? this.kundportalenService.save(this.maeklarObjekt.MaeklarObjektId.value, saveInstaellningList).$promise : null; return [ globalTimerSavePromise, kundportalenServicePromise ]; } /** * Sparar allt, hämtar lista av nya mottagare och öppnar Epost- eller SMS-utskick side drawer */ private handleSaveAndDo(doOnSuccess: () => void): void { const promiseList: angular.IPromise[] = this.spara(); const promise: Promise = Promise.all(promiseList); this.saveSubjekt.next(promise); promise.then(() => { doOnSuccess(); }) .catch(() => { // console.log(err); }); } private aerBostadsbeskrivningenAktiv(): boolean { return this.kundportalInstaellningList.toArray() .some(inst => inst.KundportalInstaellningId.value === fb.FasITDomain.KUNDPORTAL_INSTAELLNING_ID.BOSTADSBESKRIVNING && inst.AerAktiverat.value); } ///** // * Öppnar epost utskick bostadsbeskrivningsjordgubben som sista steg // * @param kundportalAktiveradMejlFoerst {boolean } True: Ifall Kundportalaktiverad-jordgubben ska visas först //*/ private openEpostUtskickBostadsbeskrivning(kundportalAktiveradMejlFoerst: boolean = false): void { // TODO frha: Borde kunna använda denna utan problem. Ända ändringen är att i den vi kallar nu kör man en clearDrawer som inte kördes här this.openEpostUtskick(false, false, true, fb.FasITDomain.TextMallNamn.GRANSKA_BOSTADSBESKRIVNING); if (kundportalAktiveradMejlFoerst) { this.openEpostUtskick(false); } } } angular.module('fasit') .directive('fbSideDrawerKundportal', downgradeComponent({ component: FbSideDrawerKundportalComponent, inputs: [], outputs: [] }) as angular.IDirectiveFactory);