/** * @ngdoc directive * @name fbNewContact * @function * @param {name} callback Anropas när vi har valt en person - när personen finns i fbNewContactCtrl. * Vi returnerar ett objekt som parameter till callback-funktionen som måste ta emot en parameter vid namn "person" av typen fb.Person * @param {string} buttonText Namnet på knappen som används för att visa dialogen. Denna används med fördel om fbNewContact ska öppnas 'inline'. * @addPersonToOpenContacts Kan användas för att lägga till person i leftNav: Obsolete! * @contextIsTopMenu Används för att säga att vi kommer till dialogen från ett läge där vi inte vill se öppnade kontakter - för stunden endast topMenu. Kan med fördel döpas om i fall vi kommer till detta tillstånd från andra ställen. * @scope Används för att skicka in den typ av kontakt som vi vill skapa. Denna typ skicka sen in till anropet när vi skapar personen. * @inkluderaJuridiskaKontakter Tar med juridiska kontakter, oavsett angiven roll * @description Används för att lägga till ny kontakt. */ angular.module('fasit').directive('fbNewContact', [ '$filter', '$timeout', 'domainService', 'logService', 'personService', 'personSearchService', 'navigationService', 'sideDrawerService', 'stateService', 'postadressService', 'globalTimerService', '$rootScope', function ( $filter: ng.IFilterService, $timeout: ng.ITimeoutService, domainService: fb.IDomainService, logService: fb.ILogService, personService: fb.IPersonService, personSearchService: fb.IPersonSearchService, navigationService: fb.INavigationService, sideDrawerService: fb.ISideDrawerService, stateService: fb.IStateService, postadressService: fb.IPostadressService, globalTimerService: fb.IGlobalTimerService, $rootScope: fb.IRootScope ) { 'use strict'; var compile: any, link: any, defaultButtonText: string = $filter('translate')('NY_KONTAKT.SKAPA_NY_KONTAKT'); var NEW_CONTACT_STATES: fb.IFbNewContactStates = { STATE_2: 2,//Showing search field and results STATE_3: 3,//Showing form where we can type in a new person STATE_4: 4//Showing kopplade kontakter having fetched contact }; //var nameChangedThroughTransferDataClick = false; function checkForIncomingAttributesAndUseDefaultsIfNecessary(attrs: fb.IFbNewContactScope): fb.IFbNewContactScope { if (!angular.isDefined(attrs.buttonText)) { attrs.buttonText = defaultButtonText; } if (angular.isDefined(attrs.getKoppladeKontakter)) { if (!angular.isDefined(attrs.koppladeKontakterSoektyp)) { var errorString = 'Missing required parameter "koppladeKontaterSoekTyp" for fbNewContact. It must be specified if "getKoppladeKontakter" is true.' logService.log(errorString); return null; } } return attrs; } function cleanUp(scope: fb.IFbNewContactScope) { //scope.chosenFromHitta = null; scope.chosenKontakt = []; scope.hittadeKontakter = []; scope.hittadeKontakter['$resolved'] = true; scope.newKontakt = null; scope.state = NEW_CONTACT_STATES.STATE_2; scope.searchButtonHasBeenClicked = null; scope.searchFieldData.value = null; scope.searchIsFromHittaSeResolver = null; scope.searchResultIsFromHittaSe = null; scope.showNewContactDialog = true; scope.chosenContactIsBeingProcessedResolver.$resolved = true; initHittadeKontakter(scope); } function createPersonSearchObjectsFromNavigationObjects(jurPersonTyp, oeppnaKontakter: fb.OeppnaKontakter[], inkluderaJuridiskaKontakter: boolean): fb.PersonSearch[] { var _oeppna; if (!angular.isDefined(jurPersonTyp) || jurPersonTyp === null) { //Det är en KUND. En kund har jurPersonTyp null, 0 eller 4 (dödsbo) _oeppna = _.filter(oeppnaKontakter, function (oeppenKontakt: fb.OeppnaKontakter): boolean { if (oeppenKontakt.JurPersonTyp === null || oeppenKontakt.JurPersonTyp === fb.JuridiskPersonTypId.OSPECIFICERAD || oeppenKontakt.JurPersonTyp === fb.JuridiskPersonTypId.DOEDSBO) { return true; } return false; }); } else { _oeppna = _.where(oeppnaKontakter, { JurPersonTyp: jurPersonTyp }); } var personSearchesArray: fb.PersonSearch[] = []; // Om extra kontakt köpare/säljare kan endast fysiska personer väljas if (!inkluderaJuridiskaKontakter) { _oeppna = _.filter(_oeppna, function (o: fb.OeppnaKontakter) { return o.JurPersonTyp === null; }); } _.each(_oeppna, function (oeppenKontakt: fb.OeppnaKontakter, index: number) { personSearchesArray.push(new fb.PersonSearch({ Namn: oeppenKontakt.Visningstext, PersonId: oeppenKontakt.PersonId, JurPersonTyp: oeppenKontakt.JurPersonTyp, Number: null, Roll: null, Mejl: null, showMoreInfo: false, })); }); personSearchesArray['loading'] = {}; personSearchesArray['$resolved'] = true; return personSearchesArray; } function searchForPersonIfConditionsAreMet(scope: fb.IFbNewContactScope) { if (scope.searchFieldData.value.length >= scope.minimumSearchFieldLength && (scope.state === NEW_CONTACT_STATES.STATE_2)) { scope.chosenKontakt = []; if (scope.hittadeKontakter) { scope.hittadeKontakter['$resolved'] = false; } if (scope.searchFieldData.value.length >= scope.minimumSearchFieldLength) { scope.searchResultIsFromHittaSe = false; var juridiskPersonTypId: number = null; juridiskPersonTypId = convertJurPersonTyp(scope.contactType.value, scope.valdKundTyp.value); var rollId = parseInt(scope.rollId, 10); personSearchService.query(scope.searchFieldData.value, juridiskPersonTypId).$promise.then(function (data: fb.PersonSearch[]) { _.each(data, function (p: fb.PersonSearch) { p.showMoreInfo = false; }); scope.searchHasBeenMade = true; if (!scope.inkluderaJuridiskaKontakter) { scope.hittadeKontakter = _.filter(data, function (p: fb.PersonSearch) { return p.JurPersonTyp === null; }); scope.hittadeKontakter.$promise = data.$promise; scope.hittadeKontakter.$resolved = data['$resolved']; } else { scope.hittadeKontakter = data; } }); } } } function initHittadeKontakter(scope: fb.IFbNewContactScope) { if (!scope.contextIsTopMenu) { //newContactCtrl.getOeppnaKontakter(); var ctrlName = sideDrawerService.currentSideDrawer().obj.controller; var state = stateService.loadState(ctrlName, 1) stateService.clearState(ctrlName, 1); if (state.hittadeKontakter && state.choosenPersonIds && state.valtPersonId) { var removeFromHittade = _.filter(state.choosenPersonIds, function (personId: number) { return personId !== state.valtPersonId }); scope.hittadeKontakter = new fb.List(_.filter(state.hittadeKontakter, function (item: fb.PersonSearch) { return !_.contains(removeFromHittade, item.PersonId) }), fb.PersonSearch); scope.chosenKontakt = [_.find(scope.hittadeKontakter, function (item: fb.PersonSearch) { return item.PersonId === state.valtPersonId })] } else { navigationService.getNavigationObjects().OeppnaObjekt.$promise.then(function () { scope.oeppnaKontakter = navigationService.getNavigationObjects().OeppnaObjekt.OeppnaKontakter; const roll: number = parseInt(scope.rollId, 10); scope.hittadeKontakter = createPersonSearchObjectsFromNavigationObjects(convertJurPersonTyp(scope.contactType.value, scope.valdKundTyp.value), scope.oeppnaKontakter, scope.inkluderaJuridiskaKontakter); }); } } } function convertJurPersonTyp(contactTypeValue, valdKundTypValue): number { switch (contactTypeValue) { case fb.FasITDomain.KontaktTypString.KUND: return valdKundTypValue; case fb.FasITDomain.KontaktTypString.BRF: return fb.JuridiskPersonTypId.BRF; case fb.FasITDomain.KontaktTypString.SAMFAELLIGHET: return fb.JuridiskPersonTypId.SAMFAELLIGHET; case fb.FasITDomain.KontaktTypString.BANK: return fb.JuridiskPersonTypId.BANK; case fb.FasITDomain.KontaktTypString.FOERVALTARE: return fb.JuridiskPersonTypId.FOERVALTARE; case fb.FasITDomain.KontaktTypString.SAMARBETSPARTNER: return fb.JuridiskPersonTypId.SAMARBETSPARTNER; default: return null; } } link = function (scope: fb.IFbNewContactScope, element: fb.IRootElementService, attrs: ng.IAttributes) { scope.chosenKontakt = []; scope.isAlertShowing = false; scope.valdKundTyp = new fb.ChangeTrack(null); scope.minimumSearchFieldLength = 3; scope.isSaving = false; if (_.isUndefined(scope.inkluderaJuridiskaKontakter)) { const roll = parseInt(scope.rollId, 10); scope.inkluderaJuridiskaKontakter = (roll !== fb.ObjektIntressentRollId.SaeljarensKontaktperson && roll !== fb.ObjektIntressentRollId.KoeparensKontaktperson); } var isUtland: boolean; $rootScope.InloggadAnvaendare.promise.then(function () { isUtland = $rootScope.InloggadAnvaendare.BostadsmarknadId === fb.FasITDomain.Bostadsmarknad.UTLAND; }); scope.searchFieldData = new fb.ChangeTrack(attrs['searchQuery'] || ''); if (!scope.contextIsTopMenu) { initHittadeKontakter(scope); } else { scope.hittadeKontakter = []; scope.hittadeKontakter['$resolved'] = true; } if (scope.observeCounters) { if (!scope.observableCounters) { scope.observableCounters = { noOfSearchesMade: 0, noOfPersonsSelected: 0 }; } else if (_.isObject(scope.observableCounters)) { if (!angular.isDefined(scope.observableCounters.noOfSearchesMade)) { scope.observableCounters.noOfSearchesMade = 0; } if (!angular.isDefined(scope.observableCounters.noOfPersonsSelected)) { scope.observableCounters.noOfPersonsSelected = 0; } } } scope.state = NEW_CONTACT_STATES.STATE_2; //scope.searchIsFromHittaSeResolver = newContactCtrl.searchIsFromHittaSeResolver; scope.chosenContactIsBeingProcessedResolver = { $resolved: true }; //createAndAssignNewContact(scope); scope.showNewContactDialog = true; scope.state = NEW_CONTACT_STATES.STATE_2; scope.isBrfOrSammfaellighet = _.contains([fb.FasITDomain.JurPersontyp.BRF, fb.FasITDomain.JurPersontyp.SAMFAELLIGHET, fb.FasITDomain.JurPersontyp.BANK, fb.FasITDomain.JurPersontyp.SAMARBETSPARTNER], convertJurPersonTyp(scope.contactType.value, null)); scope.onAddContactButtonClick = function (skapadDirekt: boolean = false) { checkIfConditionsForSavingNewContactAreFulfilled(scope.newKontakt, scope.contactType.value); if (scope.conditionsSavingForNewContactFulfilled) { scope.getKoppladeKontakter = false; var person: any; scope.chosenContactIsBeingProcessedResolver.$resolved = false; if (convertJurPersonTyp(scope.contactType.value, scope.valdKundTyp.value) !== null) { person = personService.addJuridiskPerson(createJuridiskPerson()); } else { person = personService.addFysiskPerson(createFysiskPerson()); } person.$promise.then( function () { choosePerson(person, skapadDirekt); scope.addError = false; }, function () { scope.chosenContactIsBeingProcessedResolver.$resolved = true; scope.addError = true; }); } }; function createJuridiskPerson(): fb.ObjektWizardJuridiskPersonDO { const juridiskPerson: fb.ObjektWizardJuridiskPersonDO = new fb.ObjektWizardJuridiskPersonDO({ Personnamn: scope.newKontakt.Personnamn.value, Personnummer: scope.newKontakt.Personnummer.value || null, JurPersontyp: convertJurPersonTyp(scope.contactType.value, scope.valdKundTyp.value), AdressText: scope.newKontakt.Adress.value, Postnummer: scope.newKontakt.Postnummer.value, Postort: scope.newKontakt.Ort.value, TelefonnummerMobil: scope.newKontakt.TelefonMobil.value, TelefonnummerDirekt: scope.newKontakt.TelefonBostad.value, TelefonnummerVaexel: scope.newKontakt.TelefonArbete.value, MejlAdress: scope.newKontakt.Epost.value, KundTyp: scope.newKontakt.KundTyp.getStateNumberRepresentation(isUtland) }); return juridiskPerson; } function createFysiskPerson(): fb.ObjektWizardFysiskPerson2DO { const fysiskPerson: fb.ObjektWizardFysiskPerson2DO = new fb.ObjektWizardFysiskPerson2DO({ Foernamn: scope.newKontakt.Foernamn.value || null, Efternamn: scope.newKontakt.Efternamn.value || null, AdressText: scope.newKontakt.Adress.value, Postnummer: scope.newKontakt.Postnummer.value, Personnummer: scope.newKontakt.Personnummer.value || null, Postort: scope.newKontakt.Ort.value, TelefonnummerHem: scope.newKontakt.TelefonBostad.value, TelefonnummerMobil: scope.newKontakt.TelefonMobil.value, TelefonnummerArbete: scope.newKontakt.TelefonArbete.value, MejlAdress: scope.newKontakt.Epost.value, NationalitetId: scope.newKontakt.NationalitetId.value, SpraakId: scope.newKontakt.SpraakId.value, KundTyp: scope.newKontakt.KundTyp.getStateNumberRepresentation(isUtland) }); return fysiskPerson; } function checkIfConditionsForSavingNewContactAreFulfilled(newKontakt: fb.PersonSearchChangeTrack, contactTypeValue: string) { //TODO: Use telephone only if person is of type "kund" var conditionsSavingForNewContactFulfilled = false; //Det räcker att namn är ifyllt för en juridisk person av typ BRF, FRVLT och bank. if (!newKontakt.isValid()) { conditionsSavingForNewContactFulfilled = false; } else if (newKontakt && contactTypeValue !== 'KUND') { conditionsSavingForNewContactFulfilled = !_.isEmpty(newKontakt.Personnamn.value); } else if (convertJurPersonTyp(contactTypeValue, scope.valdKundTyp.value) !== null) { //Juridiska Kunder conditionsSavingForNewContactFulfilled = !_.isEmpty(newKontakt.Personnamn.value); } else { conditionsSavingForNewContactFulfilled = (!_.isEmpty(newKontakt.Foernamn.value) || !_.isEmpty(newKontakt.Efternamn.value)) && ((isUtland && _.isNull(scope.valdKundTyp.value)) ? (!_.isNull(newKontakt.NationalitetId.value) && !_.isNull(newKontakt.SpraakId.value)) : true); } scope.conditionsSavingForNewContactFulfilled = conditionsSavingForNewContactFulfilled; } scope.onNewContactLauncherButtonClick = function () { scope.showNewContactDialog = true; scope.state = NEW_CONTACT_STATES.STATE_2; }; var checkConditionWatch = function (newVal, oldVal) { if (scope.newKontakt) { checkIfConditionsForSavingNewContactAreFulfilled(scope.newKontakt, scope.contactType.value); } } scope.$watch('newKontakt.Personnamn.value', checkConditionWatch); scope.$watch('newKontakt.Foernamn.value', checkConditionWatch); scope.$watch('newKontakt.Efternamn.value', checkConditionWatch); scope.$watch('newKontakt.Mellannamn.value', checkConditionWatch); scope.$watch('newKontakt.TelefonMobil.value', checkConditionWatch); scope.$watch('newKontakt.TelefonBostad.value', checkConditionWatch); scope.$watch('newKontakt.TelefonArbete.value', checkConditionWatch); scope.$watch('newKontakt.Epost.value', checkConditionWatch); scope.$watch('newKontakt.Postnummer.value', checkConditionWatch); scope.$watch('newKontakt.Ort.value', checkConditionWatch); scope.$watch('newKontakt.NationalitetId.value', checkConditionWatch); scope.$watch('newKontakt.SpraakId.value', checkConditionWatch); scope.$watch('valdKundTyp.value', checkConditionWatch); var choosePerson = function (person: fb.Models_IPersonDO, skapadDirekt: boolean = false) { if (scope.showNewContactDialog) { if (!scope.getKoppladeKontakter) { cleanUp(scope); scope.callback({ person: person, skapadDirekt: skapadDirekt }); scope.updateObservableCounters(); } else if (scope.getKoppladeKontakter) {//If we are to find kopplade kontakter then we activate that view scope.retrievedPerson = person; scope.state = NEW_CONTACT_STATES.STATE_4; scope['cleanUp'] = cleanUp; } scope.chosenContactIsBeingProcessedResolver.$resolved = true; } } scope.updateObservableCounters = function () { if (scope.observeCounters) { scope.observableCounters.noOfPersonsSelected = scope.observableCounters.noOfPersonsSelected + 1; } }; scope.onBackToSearchResultsButtonClick = function () { scope.state = NEW_CONTACT_STATES.STATE_2; //cleanUpState3(scope); searchForPersonIfConditionsAreMet(scope); }; var validateNewContactSuggestion = function () { //Måste ha satt åtminstone personnummer eller personnamn if (scope.newContactSuggestion && (scope.newContactSuggestion.Personnummer || scope.newContactSuggestion.Personnamn)) { return true; } return false; }; scope.onCreateNewContactButtonClick = function () { var telephoneMobile: string, personnamn: string, foernamn: string, efternamn: string, personnummer: string, epost: string; if (!scope.searchResultIsFromHittaSe) { var searchString: string = scope.searchFieldData.value; if (searchString) { var testNumber = searchString.replace(/[\s-\+]+/g, ""); // Tar bort whitespace, - och + if (testNumber.length >= 5 && !isNaN(Number(testNumber))) { telephoneMobile = searchString; } else if (searchString.match(/@/)) { epost = searchString; } else { personnamn = searchString; var searchValues = searchString.split(' '); if (searchValues.length > 1) { foernamn = searchValues.slice(0, searchValues.length - 1).join(' '); if (searchValues.length > 1) { efternamn = searchValues.slice(-1).join(' '); } } else { efternamn = searchValues[0]; } } } } if (validateNewContactSuggestion()) { personnamn = scope.newContactSuggestion.Personnamn; foernamn = scope.newContactSuggestion.Foernamn; efternamn = scope.newContactSuggestion.Efternamn; personnummer = scope.newContactSuggestion.Personnummer; epost = scope.newContactSuggestion.Epost } scope.newKontakt = new fb.PersonSearchChangeTrack({ Personnamn: personnamn || null, Foernamn: foernamn || null, Efternamn: efternamn || null, TelefonMobil: telephoneMobile || null, Personnummer: personnummer || null, Epost: epost || null }); scope.soekPaHitta = new fb.ChangeTrack(telephoneMobile); // TODO: Se om inte denna helt kan tas bort if (!scope.searchIsFromHittaSeResolver) { scope.searchIsFromHittaSeResolver = { $resolved: true }; } scope.state = NEW_CONTACT_STATES.STATE_3; if (scope.skapaDirekt && scope.skapaDirekt === 'true') { scope.onAddContactButtonClick(true); } }; scope.onSearchButtonClick = function () { //scope.chosenFromHitta = null; scope.searchButtonHasBeenClicked = true; searchForPersonIfConditionsAreMet(scope); if (scope.observeCounters) { scope.observableCounters.noOfSearchesMade = scope.observableCounters.noOfSearchesMade + 1; } }; function onSearchBottomChooseClick() { scope.alertText = scope.alertWhenPersonIdAdded ? scope.alertWhenPersonIdAdded(parseInt(scope.rollId, 10) || null, [scope.chosenKontakt[0].PersonId]) : null; scope.isAlertShowing = _.isString(scope.alertText); if (scope.isAlertShowing) { return; } scope.chosenContactIsBeingProcessedResolver.$resolved = false; // Visa upp spinner över sökresultat var person = personService.get(scope.chosenKontakt[0].PersonId, false); person.$promise.then(function () { person.$promise.then(function () { choosePerson(person.person); }); }); } scope.onSearchBottomChooseClickWithoutNaerstaaende = function () { scope.getKoppladeKontakter = false; onSearchBottomChooseClick(); }; scope.onSearchBottomChooseClickWithNaerstaaende = function () { scope.getKoppladeKontakter = true; onSearchBottomChooseClick(); }; scope.onTopCancelButtonClick = function () { scope.showNewContactDialog = false; cleanUp(scope); }; scope.onDubblettsammanslaaManuellt = function () { if (sideDrawerService.currentSideDrawer()) { var ctrlName = sideDrawerService.currentSideDrawer().obj.controller; var choosenPersonIds = _.map(scope.chosenKontakt, function (item) { return item.PersonId; }); sideDrawerService.stack('Dubblettsammanslagning', { personIds: choosenPersonIds, importeradPersonId: null }, 1, { hittadeKontakter: scope.hittadeKontakter, choosenPersonIds: choosenPersonIds }, function (data: fb.DubblettsammanslagenPersonWO) { var state = stateService.loadState<{ valtPersonId: number }>(ctrlName, 1); state.valtPersonId = data.PersonId; }) } else { sideDrawerService.setSideDrawer('Dubblettsammanslagning', { personIds: _.map(scope.chosenKontakt, function (item) { return item.PersonId; }), importeradPersonId: null }, undefined, function (data: fb.DubblettsammanslagenPersonWO) { navigationService.findOpenObjekt(fb.FasITDomain.NavigationController.KONTAKT, data.PersonId, true); }); } }; scope.gotoKontaktListSearchString = function () { stateService.addState('Soeklista', 'fbNewContact', function () { return { searchString: scope.searchFieldData.value }; }); stateService.offLoadState('Soeklista', 'fbNewContact'); navigationService.gotoKontaktlista(); }; scope.onDubblettsammanslaaAuto = function () { globalTimerService.globalSave(true); scope.isSaving = true; var personIds = _.map(scope.chosenKontakt, function (item) { return item.PersonId; }); var sammanslagenPerson = personService.dubblettSammanslaa(new fb.DubblettsammanslagningDO({ personIds: personIds, AutomatisktValAvKontaktUppgifter: true })); sammanslagenPerson.$promise.then(function (data) { scope.isSaving = false; navigationService.cleanOeppnaOchStaengda(); if (sideDrawerService.currentSideDrawer()) { _.each(scope.chosenKontakt, function (item) { if (item.PersonId !== data.PersonId) { scope.hittadeKontakter.splice(scope.hittadeKontakter.indexOf(item), 1); } }); scope.chosenKontakt = [_.find(scope.hittadeKontakter, function (item: fb.PersonSearch) { return item.PersonId === data.PersonId })]; } else { navigationService.findOpenObjekt(fb.FasITDomain.NavigationController.KONTAKT, sammanslagenPerson.PersonId, true); } }, function () { scope.isSaving = false; }); }; if (scope.searchFieldData.value !== '') { // Börja sök direkt om en sökquery skickades med scope.onSearchButtonClick(); } scope.newContactSuggestion = { Personnummer: null, Personnamn: null, Foernamn: null, Efternamn: null, Epost: null }; if (scope.exposeScope) { scope.exposeScope.searchFieldData = scope.searchFieldData; scope.exposeScope.onSearchButtonClick = scope.onSearchButtonClick; scope.exposeScope.valdKundTyp = scope.valdKundTyp; scope.exposeScope.newContactSuggestion = scope.newContactSuggestion; } scope.getSearchHeight = function () { var minus = 60; if (scope.isAlertShowing) { minus += 66; } if (scope.searchButtonHasBeenClicked && scope.hittadeKontakter && scope.hittadeKontakter.$resolved) { minus += 28; } if (!(scope.searchButtonHasBeenClicked || scope.contextIsTopMenu)) { minus += 28; } return 'calc(100% - ' + minus + 'px)'; } }; compile = function (element: fb.IRootElementService, attrs: any, linker: any): any { attrs = checkForIncomingAttributesAndUseDefaultsIfNecessary(attrs); return link; }; return { restrict: 'E', scope: { callback: '&', skapaDirekt: '@', buttonText: '@', addPersonToOpenContacts: '=',//TODO: Investigate removal - should be safe to remove contextIsTopMenu: '@', contactType: '=', //Changetrack where value: KUND = Kund, BRF = Bostadsförening, SFF = Samfällighetsförening, BANK = Bank, FRVT = Förvaltare, observeCounters: '=', observableCounters: '=', getKoppladeKontakter: '=?', koppladeKontakterSoektyp: '=', searchQuery: '@', alertWhenPersonIdAdded: '=', rollId: '@', exposeScope: '=', inkluderaJuridiskaKontakter: '=?' }, compile: compile, templateUrl: 'app/Directives/fbNewContact/fbNewContact.html' }; }]);