aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/MainViewVM.cs
blob: 9143f50a88993c45277e71e03bb0242c86d55863 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Core.Commands;
using Tango.PPC.Common;

namespace Tango.PPC.Power.ViewModels
{
    /// <summary>
    /// Represents the main view VM and entry point for <see cref="Synchronization.MyModule"/>.
    /// </summary>
    /// <seealso cref="Tango.PPC.Common.PPCViewModel" />
    public class MainViewVM : PPCViewModel
    {
        /// <summary>
        /// Gets or sets the restart command.
        /// </summary>
        public RelayCommand RestartCommand { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="MainViewVM"/> class.
        /// </summary>
        public MainViewVM()
        {
            RestartCommand = new RelayCommand(RestartApplication);
        }

        /// <summary>
        /// Called when the application has been started
        /// </summary>
        public override void OnApplicationStarted()
        {
            //Start initializing here rather then in the constructor.
        }

        /// <summary>
        /// Restarts the application.
        /// </summary>
        private async void RestartApplication()
        {
            if (await NotificationProvider.ShowQuestion("Are you sure you want to restart the application?"))
            {
                ApplicationManager.Restart();
            }
        }
    }
}
a> 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Tango.BL;
using Tango.BL.Entities;
using Tango.Core.Commands;
using Tango.MachineStudio.Common;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.UsersAndRoles.Navigation;
using Tango.MachineStudio.UsersAndRoles.Providers;
using Tango.SharedUI;
using System.Data.Entity;
using Tango.BL.Builders;
using Tango.BL.ActionLogs;
using Tango.BL.DTO;
using Tango.BL.Enumerations;
using Tango.MachineStudio.Common.Authentication;

namespace Tango.MachineStudio.UsersAndRoles.ViewModels
{
    public class MainViewVM : StudioViewModel
    {
        private ObservablesContext _organizationsContext;
        private ObservablesContext _manageContext;
        private ObservablesContext _userContext;
        private UsersAndRolesNavigationManager _navigation;
        private INotificationProvider _notification;
        private IActionLogManager _actionLogManager;
        private OrganizationDTO _organizationBeforeSave;
        private IAuthenticationProvider _authenticationProvider;
        private UserDTO _userBeforeSave;

        private ObservableCollection<Organization> _organizations;
        public ObservableCollection<Organization> Organizations
        {
            get { return _organizations; }
            set { _organizations = value; RaisePropertyChangedAuto(); }
        }

        private Organization _selectedOrganization;
        public Organization SelectedOrganization
        {
            get { return _selectedOrganization; }
            set { _selectedOrganization = value; RaisePropertyChangedAuto(); }
        }

        private Organization _managedOrganization;
        public Organization ManagedOrganization
        {
            get { return _managedOrganization; }
            set { _managedOrganization = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<Role> _roles;
        public ObservableCollection<Role> Roles
        {
            get { return _roles; }
            set { _roles = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<Role> _managedUserRoles;
        public ObservableCollection<Role> ManagedUserRoles
        {
            get { return _managedUserRoles; }
            set { _managedUserRoles = value; RaisePropertyChangedAuto(); }
        }

        private User _selectedUser;
        public User SelectedUser
        {
            get { return _selectedUser; }
            set { _selectedUser = value; RaisePropertyChangedAuto(); }
        }

        private User _managedUser;
        public User ManagedUser
        {
            get { return _managedUser; }
            set { _managedUser = value; RaisePropertyChangedAuto(); }
        }

        private Place _selectedUserPlace;
        public Place SelectedUserPlace
        {
            get { return _selectedUserPlace; }
            set
            {
                _selectedUserPlace = value;

                if (_selectedUserPlace != null && _selectedUserPlace.Address != null)
                {
                    SetUserPlace(value);
                }
            }
        }

        private Place _selectedOrganizationPlace;
        public Place SelectedOrganizationPlace
        {
            get { return _selectedOrganizationPlace; }
            set
            {
                _selectedOrganizationPlace = value;

                if (_selectedOrganizationPlace != null && _selectedOrganizationPlace.Address != null)
                {
                    SetOrganizationPlace(value);
                }
            }
        }

        private bool _showDeleted;
        public bool ShowDeleted
        {
            get { return _showDeleted; }
            set
            {
                _showDeleted = value;
                if (_showDeleted)
                {
                    //ShowDeletedUsers();
                }
            }
        }


        public RelayCommand ManageOrganizationCommand { get; set; }

        public RelayCommand BackToOrganizationsCommand { get; set; }

        public RelayCommand ManageUserCommand { get; set; }

        public RelayCommand SaveOrganizationCommand { get; set; }

        public RelayCommand AddOrganizationCommand { get; set; }

        public RelayCommand RemoveOrganizationCommand { get; set; }

        public RelayCommand BackToManagedOrganizationCommand { get; set; }

        public RelayCommand<Role> RemoveRoleCommand { get; set; }

        public RelayCommand SaveManagedUserCommand { get; set; }

        public RelayCommand RestoreAndSaveManagedUserCommand { get; set; }

        public RelayCommand AddUserCommand { get; set; }

        public RelayCommand RemoveUserCommand { get; set; }

        public MainViewVM(UsersAndRolesNavigationManager navigation, INotificationProvider notification, IActionLogManager actionLogManager, IAuthenticationProvider authenticationProvider)
        {
            _navigation = navigation;
            _notification = notification;
            _actionLogManager = actionLogManager;
            _authenticationProvider = authenticationProvider;

            ManageOrganizationCommand = new RelayCommand(LoadSelectedOrganization, () => SelectedOrganization != null);
            BackToOrganizationsCommand = new RelayCommand(BackToOrganizations);
            ManageUserCommand = new RelayCommand(LoadSelectedUser, () => SelectedUser != null);
            SaveOrganizationCommand = new RelayCommand(SaveOrganization);
            AddOrganizationCommand = new RelayCommand(AddOrganization);
            RemoveOrganizationCommand = new RelayCommand(RemoveOrganization, () => SelectedOrganization != null);
            BackToManagedOrganizationCommand = new RelayCommand(BackToManagedOrganization);
            RemoveRoleCommand = new RelayCommand<Role>(RemoveUserRole);
            SaveManagedUserCommand = new RelayCommand(SaveManagedUser);
            RestoreAndSaveManagedUserCommand = new RelayCommand(RestoreAndSaveManagedUser);
            AddUserCommand = new RelayCommand(AddNewUser);
            RemoveUserCommand = new RelayCommand(RemoveSelectedUser, () => SelectedUser != null);
            _showDeleted = false;
        }

        public override void OnApplicationReady()
        {
            LoadOrganizations();
        }

        private async void AddOrganization()
        {
            String name = _notification.ShowTextInput("Enter organization name", "Name");

            if (!String.IsNullOrWhiteSpace(name))
            {
                using (_notification.PushTaskItem("Adding new organization..."))
                {
                    Organization org = new Organization();
                    org.Name = name;
                    org.Address = new Address();
                    org.Contact = new Contact();
                    _organizationsContext.Organizations.Add(org);
                    await org.SaveAsync(_organizationsContext);
                    _actionLogManager.InsertLog(ActionLogType.OrganizationCreated, _authenticationProvider.CurrentUser, org.Name, org, "Organization created using Machine Studio.");
                    Organizations = _organizationsContext.Organizations.ToObservableCollection();
                    SelectedOrganization = org;
                    LoadSelectedOrganization();
                }
            }
        }

        private async void RemoveOrganization()
        {
            if (_notification.ShowQuestion("Are you sure you want to remove " + SelectedOrganization.Name + " organization?"))
            {

                using (ObservablesContext db = ObservablesContext.CreateDefault())
                {
                    var usersCount = db.Users.Count(x => x.OrganizationGuid == SelectedOrganization.Guid);

                    if (usersCount > 0)
                    {
                        _notification.ShowError($"The organization cannot be removed as it contains {usersCount} users.");
                        return;
                    }

                    var machinesCount = db.Machines.Count(x => x.OrganizationGuid == SelectedOrganization.Guid);

                    if (machinesCount > 0)
                    {
                        _notification.ShowError($"The organization cannot be removed as it contains {machinesCount} machines.");
                        return;
                    }

                    var sitesCount = db.Sites.Count(x => x.OrganizationGuid == SelectedOrganization.Guid);

                    if (sitesCount > 0)
                    {
                        _notification.ShowError($"The organization cannot be removed as it contains {sitesCount} sites.");
                        return;
                    }
                }


                using (_notification.PushTaskItem("Removing organization..."))
                {
                    await SelectedOrganization.DeleteCascadeAsync(_organizationsContext);
                    _actionLogManager.InsertLog(ActionLogType.OrganizationDeleted, _authenticationProvider.CurrentUser, SelectedOrganization.Name, SelectedOrganization, "Organization deleted using Machine Studio.");
                    await LoadOrganizations();
                }
            }
        }

        private async void SaveOrganization()
        {
            using (_notification.PushTaskItem("Saving organization address and contact..."))
            {
                var organizationAfter = OrganizationDTO.FromObservable(ManagedOrganization);

                await ManagedOrganization.SaveAsync(_manageContext);
                _actionLogManager.InsertLog(ActionLogType.OrganizationSaved, _authenticationProvider.CurrentUser, ManagedOrganization.Name, _organizationBeforeSave, organizationAfter, "Organization saved using Machine Studio.");

                _organizationBeforeSave = organizationAfter;

                await LoadOrganizations();
                SelectedOrganization = Organizations.SingleOrDefault(x => x.Guid == ManagedOrganization.Guid);
            }
        }

        private async void LoadSelectedUser()
        {
            using (_notification.PushTaskItem("Loading user details..."))
            {
                await Task.Factory.StartNew(() =>
                {
                    _userContext = ObservablesContext.CreateDefault();

                    Roles = new RolesCollectionBuilder(_userContext).SetAll().WithPermission().Build();
                    ManagedUser = new UserBuilder(_userContext).WithDeleted().Set(SelectedUser.Guid).WithRolesAndPermissions().Build();
                    ManagedUserRoles = ManagedUser.Roles.ToObservableCollection();

                    _userBeforeSave = UserDTO.FromObservable(ManagedUser);
                });

                _navigation.NavigateTo(UsersAndRolesNavigationView.UserManagementView);
            }
        }

        private void BackToOrganizations()
        {
            _navigation.NavigateTo(UsersAndRolesNavigationView.OrganizationSelectionView);
        }

        private void BackToManagedOrganization()
        {
            _navigation.NavigateTo(UsersAndRolesNavigationView.OrganizationManagementView);
        }

        private void RemoveUserRole(Role role)
        {
            ManagedUserRoles.Remove(role);

            foreach (var userRole in ManagedUser.UsersRoles.Where(x => x.Role == role).ToList())
            {
                _userContext.UsersRoles.Remove(userRole);
            }
        }

        private async void SaveManagedUser()
        {
            try
            {
                ManagedUser.Validate(_userContext);

                if (ManagedUser.Roles.GroupBy(x => x.RoleEnum).Any(x => x.Count() > 1))
                {
                    throw new InvalidOperationException("Cannot save user with duplicate roles.");
                }
            }
            catch (Exception ex)
            {
                _notification.ShowError(ex.Message);
                return;
            }

            using (_notification.PushTaskItem("Saving user details..."))
            {
                var userAfter = UserDTO.FromObservable(ManagedUser);
                await ManagedUser.SaveAsync(_userContext);
                _actionLogManager.InsertLog(ActionLogType.UserSaved, _authenticationProvider.CurrentUser, ManagedUser.Email, _userBeforeSave, userAfter, "User saved using Machine Studio.");
                _userBeforeSave = userAfter;
                LoadSelectedOrganization();
            }
        }

        private async void RestoreAndSaveManagedUser()
        {
            try
            {
                ManagedUser.Validate(_userContext);

                if (ManagedUser.Roles.GroupBy(x => x.RoleEnum).Any(x => x.Count() > 1))
                {
                    throw new InvalidOperationException("Cannot save user with duplicate roles.");
                }
            }
            catch (Exception ex)
            {
                _notification.ShowError(ex.Message);
                return;
            }
            if (_notification.ShowQuestion("Are you sure you wish to re-activate this account?"))
            {
                using (_notification.PushTaskItem("Saving user details..."))
                {
                    ManagedUser.Deleted = false;

                    var userAfter = UserDTO.FromObservable(ManagedUser);
                    await ManagedUser.SaveAsync(_userContext);
                    _actionLogManager.InsertLog(ActionLogType.UserRestored, _authenticationProvider.CurrentUser, ManagedUser.Email, _userBeforeSave, userAfter, "User restored using Machine Studio.");
                    _userBeforeSave = userAfter;
                    LoadSelectedOrganization();
                }
            }
        }

        private async void LoadSelectedOrganization()
        {
            using (_notification.PushTaskItem("Loading organization..."))
            {
                await Task.Factory.StartNew(() =>
                {
                    _manageContext = ObservablesContext.CreateDefault();

                    ManagedOrganization = new OrganizationBuilder(_manageContext).Set(SelectedOrganization.Guid).WithUsers(true).Build();

                    _organizationBeforeSave = OrganizationDTO.FromObservable(ManagedOrganization);
                });

                _navigation.NavigateTo(UsersAndRolesNavigationView.OrganizationManagementView);
            }
        }

        private Task LoadOrganizations()
        {
            return Task.Factory.StartNew(() =>
            {
                _organizationsContext = ObservablesContext.CreateDefault();

                Organizations = new OrganizationsCollectionBuilder(_organizationsContext).SetAll().WithUsers().WithMachines().Build();
            });
        }

        public void OnDropRole(Role role)
        {
            ManagedUser.UsersRoles.Add(new UsersRole()
            {
                Role = role,
                RoleGuid = role.Guid,
                User = ManagedUser,
                UserGuid = ManagedUser.Guid,
            });

            ManagedUserRoles.Add(role);
        }

        private async void RemoveSelectedUser()
        {
            if (_notification.ShowQuestion("Are you sure you want to remove the selected user?"))
            {
                using (_notification.PushTaskItem("Removing user..."))
                {
                    await SelectedUser.DeleteCascadeAsync(_manageContext);
                    _actionLogManager.InsertLog(ActionLogType.UserDeleted, _authenticationProvider.CurrentUser, SelectedUser.Email, SelectedUser, "User deleted using Machine Studio.");
                    LoadSelectedOrganization();
                }
            }
        }

        private void AddNewUser()
        {
            _notification.ShowModalDialog<UserCreationDialogVM>(async (vm) =>
            {
                User user = new User();
                user.Email = vm.Email;
                user.Password = User.GetPasswordHash(vm.Password);
                user.PasswordChangeRequired = true;
                user.Contact = new Contact()
                {
                    FirstName = vm.FirstName,
                    LastName = vm.LastName,
                    Email = vm.Email,
                };

                user.Address = new Address();

                user.UsersRoles.Add(new UsersRole()
                {
                    User = user,
                    Role = _manageContext.Roles.SingleOrDefault(x => x.Code == (int)BL.Enumerations.Roles.User)
                });

                user.UsersRoles.Add(new UsersRole()
                {
                    User = user,
                    Role = _manageContext.Roles.SingleOrDefault(x => x.Code == (int)BL.Enumerations.Roles.MachineStudioUser)
                });

                user.UsersRoles.Add(new UsersRole()
                {
                    User = user,
                    Role = _manageContext.Roles.SingleOrDefault(x => x.Code == (int)BL.Enumerations.Roles.PPCUser)
                });

                try
                {
                    if (!user.Validate(_manageContext))
                    {
                        _notification.ShowError(String.Join(Environment.NewLine, user.ValidationErrors));
                        return;
                    }
                }
                catch (Exception ex)
                {
                    _notification.ShowError(ex.Message);
                    return;
                }

                ManagedOrganization.Users.Add(user);

                using (_notification.PushTaskItem("Adding new user..."))
                {
                    await ManagedOrganization.SaveAsync(_manageContext);
                    _actionLogManager.InsertLog(ActionLogType.UserCreated, _authenticationProvider.CurrentUser, user.Email, user, "User created using Machine Studio.");
                    await LoadOrganizations();
                    SelectedOrganization = Organizations.SingleOrDefault(x => x.Guid == ManagedOrganization.Guid);
                    SelectedUser = user;
                    LoadSelectedUser();
                }
            });
        }

        private void SetUserPlace(Place place)
        {
            ManagedUser.Address.AddressString = place.Address.Road;
            ManagedUser.Address.City = place.Address.City;
            ManagedUser.Address.Country = place.Address.Country;
            ManagedUser.Address.CountryCode = place.Address.CountryCode;
            ManagedUser.Address.Locality = place.Address.CountryCode;
            ManagedUser.Address.PostalCode = place.Address.PostalCode;
            ManagedUser.Address.State = place.Address.State;
        }

        private void SetOrganizationPlace(Place place)
        {
            ManagedOrganization.Address.AddressString = place.Address.Road;
            ManagedOrganization.Address.City = place.Address.City;
            ManagedOrganization.Address.Country = place.Address.Country;
            ManagedOrganization.Address.CountryCode = place.Address.CountryCode;
            ManagedOrganization.Address.Locality = place.Address.CountryCode;
            ManagedOrganization.Address.PostalCode = place.Address.PostalCode;
            ManagedOrganization.Address.State = place.Address.State;
        }

        protected override void RaisePropertyChangedAuto([CallerMemberName] string caller = null)
        {
            base.RaisePropertyChangedAuto(caller);
            InvalidateRelayCommands();
        }
    }
}