aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/NavigationObjects
ModeNameSize
-rw-r--r--JobNavigationObject.cs799logstatsplain
-rw-r--r--JobSummeryNavigationObject.cs357logstatsplain
-rw-r--r--TwineCatalogNavigationObject.cs360logstatsplain
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Data;
using Tango.BL;
using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.Core.Commands;
using Tango.Core.DI;
using Tango.DragAndDrop;
using Tango.PPC.Common;
using Tango.PPC.Jobs.Dialogs;
using Tango.PPC.Jobs.Messages;
using Tango.PPC.Jobs.Views;

namespace Tango.PPC.Jobs.ViewModels
{
    /// <summary>
    /// Represents the jobs view model.
    /// </summary>
    /// <seealso cref="Tango.PPC.Common.PPCViewModel" />
    public class JobsViewVM : PPCViewModel
    {
        private ObservablesContext _db; //Holds the db context for the job list.

        #region Properties

        private ObservableCollection<Job> _jobs;
        /// <summary>
        /// Gets or sets the collection of jobs.
        /// </summary>
        public ObservableCollection<Job> Jobs
        {
            get { return _jobs; }
            set { _jobs = value; RaisePropertyChangedAuto(); }
        }

        private ICollectionView _jobsCollectionView;
        /// <summary>
        /// Gets or sets the jobs collection view.
        /// </summary>
        public ICollectionView JobsCollectionView
        {
            get { return _jobsCollectionView; }
            set
            {
                _jobsCollectionView = value;
                RaisePropertyChangedAuto();
            }
        }

        private ObservableCollection<Job> _selectedJobs;
        /// <summary>
        /// Gets or sets the selected jobs.
        /// </summary>
        public ObservableCollection<Job> SelectedJobs
        {
            get { return _selectedJobs; }
            set { _selectedJobs = value; RaisePropertyChangedAuto(); }
        }

        private bool _isLoadingJobs;
        /// <summary>
        /// Gets or sets a value indicating whether this instance is loading jobs.
        /// </summary>
        public bool IsLoadingJobs
        {
            get { return _isLoadingJobs; }
            set { _isLoadingJobs = value; RaisePropertyChangedAuto(); }
        }

        private bool _isMultiSelecting;
        /// <summary>
        /// Gets or sets a value indicating whether this the jobs list is in multi select mode.
        /// </summary>
        public bool IsMultiSelecting
        {
            get { return _isMultiSelecting; }
            set { _isMultiSelecting = value; RaisePropertyChangedAuto(); }
        }

        private JobCategories _filterCategory;
        /// <summary>
        /// Gets or sets the filter category.
        /// </summary>
        public JobCategories FilterCategory
        {
            get { return _filterCategory; }
            set
            {
                _filterCategory = value; RaisePropertyChangedAuto();
                FilterJobCategory(value);
            }
        }

        #endregion

        #region Commands

        /// <summary>
        /// Gets or sets the job selected command.
        /// </summary>
        public RelayCommand<Object> JobSelectedCommand { get; set; }

        /// <summary>
        /// Gets or sets the job drag and drop command.
        /// </summary>
        public RelayCommand<DropEventArgs> JobDragedDroppedCommand { get; set; }

        /// <summary>
        /// Gets or sets the clear selection command.
        /// </summary>
        public RelayCommand ClearSelectionCommand { get; set; }

        /// <summary>
        /// Gets or sets the add job command.
        /// </summary>
        public RelayCommand AddJobCommand { get; set; }

        /// <summary>
        /// Gets or sets the delete jobs command.
        /// </summary>
        public RelayCommand DeleteJobsCommand { get; set; }

        /// <summary>
        /// Gets or sets the clone jobs command.
        /// </summary>
        public RelayCommand CloneJobsCommand { get; set; }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="JobsViewVM"/> class.
        /// </summary>
        public JobsViewVM()
        {
            Jobs = new ObservableCollection<Job>();
            SelectedJobs = new ObservableCollection<Job>();

            JobSelectedCommand = new RelayCommand<Object>((x) => SelectJob(x as Job));
            JobDragedDroppedCommand = new RelayCommand<DropEventArgs>((e) =>
            {
                Job draggedJob = e.Draggable.DataContext as Job;
                Job droppedJob = e.Droppable.DataContext as Job;

                DragAndDropJob(draggedJob, droppedJob);
            });

            ClearSelectionCommand = new RelayCommand(ClearSelection);
            AddJobCommand = new RelayCommand(AddNewJob);
            DeleteJobsCommand = new RelayCommand(() => DeleteJobs(SelectedJobs));
            CloneJobsCommand = new RelayCommand(() => CloneJobs(SelectedJobs));

            RegisterForMessage<JobRemovedMessage>(HandleJobRemovedMessage);
            RegisterForMessage<JobSavedMessage>(HandleJobSavedMessage);
        }

        #endregion

        #region Drag & Drop

        /// <summary>
        /// Called when a job has been dragged and dropped into another job.
        /// </summary>
        /// <param name="draggedJob">The dragged job.</param>
        /// <param name="droppedJob">The dropped job.</param>
        private void DragAndDropJob(Job draggedJob, Job droppedJob)
        {
            if (draggedJob.JobIndex > droppedJob.JobIndex)
            {
                draggedJob.JobIndex = droppedJob.JobIndex - 1;
            }
            else
            {
                draggedJob.JobIndex = droppedJob.JobIndex + 1;
            }

            int index = 1;

            foreach (var job in Jobs.OrderBy(x => x.JobIndex))
            {
                job.JobIndex = index++;
            }

            JobsCollectionView.Refresh();
        }

        #endregion

        #region Job Selection & Loading

        /// <summary>
        /// Selects the job.
        /// </summary>
        /// <param name="job">The job.</param>
        public async void SelectJob(Job job)
        {
            await NavigationManager.NavigateTo<JobsModule>(nameof(JobSummeryView));
            RaiseMessage(new JobSelectedMessage() { Job = job });
        }

        /// <summary>
        /// Loads the jobs from database.
        /// </summary>
        public void LoadJobs()
        {
            Task.Factory.StartNew(() =>
            {
                IsLoadingJobs = true;

                Thread.Sleep(500);

                if (_db != null)
                {
                    _db.Dispose();
                }

                _db = ObservablesContext.CreateDefault();

                var jobs = _db.Jobs.Where(x => x.Machine.Guid == MachineProvider.Machine.Guid).ToObservableCollection();

                InvokeUI(() =>
                {
                    Jobs = jobs.Where(x => x.Machine.Guid == MachineProvider.Machine.Guid).ToObservableCollection();
                    JobsCollectionView = CollectionViewSource.GetDefaultView(Jobs);
                    JobsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Job.LastUpdated), ListSortDirection.Descending));
                    FilterJobCategory(FilterCategory);
                    IsLoadingJobs = false;
                });
            });
        }

        /// <summary>
        /// Clears the job selection.
        /// </summary>
        public void ClearSelection()
        {
            SelectedJobs.Clear();
            IsMultiSelecting = false;
        }

        /// <summary>
        /// Filters the jobs list by the specified <see cref="JobCategories">job category</see>.
        /// </summary>
        /// <param name="jobCategory">The job category.</param>
        public void FilterJobCategory(JobCategories jobCategory)
        {
            JobsCollectionView.Filter = (job) =>
            {
                return (job as Job).JobCategories.Contains(jobCategory);
            };
        }

        /// <summary>
        /// Adds a new job.
        /// </summary>
        private async void AddNewJob()
        {
            var machine = MachineProvider.Machine;

            JobTypePickerViewVM vm = new JobTypePickerViewVM(machine.SupportedJobTypes.Count > 0 ? machine.SupportedJobTypes : Enum.GetValues(typeof(JobTypes)).Cast<JobTypes>().ToList());

            if (machine.SupportedJobTypes.Count != 1)
            {
                vm = await NotificationProvider.ShowDialog<JobTypePickerViewVM>(vm);
                if (!vm.DialogResult) return;
            }
            else
            {
                vm.SelectedJobType = machine.SupportedJobTypes.First();
            }

            Job job = new Job();
            job.Name = "untitled";
            job.NumberOfHeads = 1;
            job.NumberOfUnits = 1;
            job.SampleUnitsOrMeters = 1;
            job.CreationDate = DateTime.UtcNow;
            job.JobStatus = JobStatuses.Draft;
            job.JobType = vm.SelectedJobType.Value;
            job.ColorSpaceGuid = machine.DefaultColorSpace != null ? machine.DefaultColorSpaceGuid : Adapter.ColorSpaces.FirstOrDefault(x => x.Code == ColorSpaces.RGB.ToInt32()).Guid;
            job.MachineGuid = MachineProvider.Machine.Guid;
            job.UserGuid = AuthenticationProvider.CurrentUser.Guid;
            job.RmlGuid = machine.DefaultRml != null ? machine.DefaultRmlGuid : Adapter.Rmls.FirstOrDefault().Guid;
            job.WindingMethodGuid = Adapter.WindingMethods.FirstOrDefault().Guid;
            job.SpoolTypeGuid = machine.DefaultSpoolType != null ? machine.DefaultSpoolTypeGuid : Adapter.SpoolTypes.FirstOrDefault().Guid;

            job.AddSolidSegment(machine.DefaultSegmentLength > 0 ? machine.DefaultSegmentLength : 10);

            _db.Jobs.Add(job);

            await _db.SaveChangesAsync();

            Jobs.Add(job);

            RaiseMessage(new JobSelectedMessage() { Job = job });

            await Task.Delay(200);
            await NavigationManager.NavigateTo<JobsModule>(nameof(JobView));
        }

        /// <summary>
        /// Deletes the specified jobs from db.
        /// </summary>
        /// <param name="jobs">The jobs.</param>
        private async void DeleteJobs(ObservableCollection<Job> jobs)
        {
            if (await NotificationProvider.ShowQuestion("Are you sure you want to delete the selected jobs"))
            {
                foreach (var job in jobs)
                {
                    await job.DeleteCascadeAsync(_db);
                    Jobs.Remove(job);
                }

                await _db.SaveChangesAsync();
                ClearSelection();
            }
        }

        /// <summary>
        /// Clones the specified jobs.
        /// </summary>
        /// <param name="jobs">The jobs.</param>
        private async void CloneJobs(ObservableCollection<Job> jobs)
        {
            int index = Jobs.Max(x => x.JobIndex);

            List<Job> clonedJobs = new List<Job>();

            foreach (var job in SelectedJobs)
            {
                var cloned = job.Clone();
                cloned.JobIndex = ++index;
                _db.Jobs.Add(cloned);
                clonedJobs.Add(cloned);
            }

            await _db.SaveChangesAsync();

            foreach (var job in clonedJobs)
            {
                Jobs.Add(job);
            }

            ClearSelection();
        }

        #endregion

        #region Message Handling

        private void HandleJobRemovedMessage(JobRemovedMessage msg)
        {
            var job = Jobs.SingleOrDefault(x => x.Guid == msg.Job.Guid);
            Jobs.Remove(job);
            _db.Entry(job).State = System.Data.Entity.EntityState.Detached;
        }

        private void HandleJobSavedMessage(JobSavedMessage msg)
        {
            LoadJobs();
        }

        #endregion

        #region Override Methods

        /// <summary>
        /// Called when the application has been started.
        /// </summary>
        public override void OnApplicationStarted()
        {
            LoadJobs();
        }

        /// <summary>
        /// Called when the navigation system has navigated to this VM view.
        /// </summary>
        public override void OnNavigatedTo()
        {
            base.OnNavigatedTo();
        }

        public override void OnNavigatedFrom()
        {
            base.OnNavigatedFrom();
        }
        #endregion
    }
}