Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Linq;
- using Microinvest.Core.Common;
- using Microinvest.Core.Common.ExpressionEvaluator;
- using Microinvest.Core.Infrastructure;
- using Microinvest.Core.Interfaces.DatabaseServices;
- using Microinvest.Core.Interfaces.Model;
- using Microinvest.Core.Validation;
- using Microinvest.Hotel.Core.Common;
- using Microinvest.Hotel.Core.Events;
- using Microinvest.Hotel.Core.Events.TPayloadClasses;
- using Microinvest.Hotel.Core.Interfaces.Helpers;
- using Microinvest.Hotel.Core.Interfaces.Model;
- using Microinvest.Hotel.Core.Interfaces.Services;
- using Microinvest.Hotel.Core.Interfaces.UI;
- using Microinvest.Hotel.Core.ViewModels.Helpers;
- using Microinvest.Prism.Commands;
- using Microinvest.Prism.Events;
- using Microinvest.Unity;
- namespace Microinvest.Hotel.Core.ViewModels.Operations
- {
- /// <summary>
- /// Базов клас за редакция на детайли към операция
- /// </summary>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "N/A")]
- public class OperationDetailsListBaseViewModel : BaseViewModel
- {
- #region Declarations
- /// <summary> Колекция с текущи детайли </summary>
- private IEnumerable<IOperationDetail> sourceDetails;
- /// <summary> Колекция с нефилтрирани детайли </summary>
- private IList<OperationDetailBaseViewModel> internalOperationDetails;
- /// <summary> променлива за избран елемент от списъка </summary>
- private OperationDetailBaseViewModel selectedOperationDetail;
- /// <summary> променлива за команда за добавяне на услуги </summary>
- private DelegateCommand<object> addOperationDetailCommand;
- /// <summary> променлива за команда за изтриване на услуга </summary>
- private DelegateCommand<object> deleteOperationDetailCommand;
- /// <summary> променлива за команда за изтриване на услуга </summary>
- private DelegateCommand<object> addAdvanceCommand;
- /// <summary> променлива за сървис за цени </summary>
- private IPricesService priceService;
- /// <summary> флаг за направено плащане </summary>
- private bool isPaymentMade;
- /// <summary> авансова сума </summary>
- private decimal advancePayment;
- /// <summary>Списък с ДДС групи</summary>
- private IEnumerable<IVatGroup> vatGroups;
- /// <summary>Избрана ДДС група</summary>
- private IVatGroup selectedVatGroup;
- /// <summary>Избрани ли са всички боксове</summary>
- private bool isCheckedAll;
- /// <summary>
- /// Списък с филтрирани детайли
- /// </summary>
- private IEnumerable<OperationDetailBaseViewModel> operationDetails;
- /// <summary> Настанени използва се при инициализацията на пакети</summary>
- private HashSet<ICustomer> accomodatedCustomers;
- /// <summary> Сървис за кеш на клиенти и нощивки </summary>
- private ICustomersAccomodationCacheService customersOvernightsCacheService;
- #endregion
- #region Initialization
- /// <summary>
- /// Конструктор
- /// </summary>
- /// <param name="container"></param>
- /// <param name="details"></param>
- /// <param name="operationHelper"></param>
- public OperationDetailsListBaseViewModel(IUnityContainer container, IEnumerable<IOperationDetail> details, IOperationHelper operationHelper)
- {
- this.Container = container;
- this.sourceDetails = details;
- this.OperationHelper = operationHelper;
- if (this.Container.IsRegistered<IEventAggregator>())
- this.Container.Resolve<IEventAggregator>().GetEvent<OperationDetailChangedEvent>().Subscribe(OnOperationChanged);
- customersOvernightsCacheService = new CustomersAccomodationCacheService(Container, OperationHelper.Operation);
- accomodatedCustomers = new HashSet<ICustomer>();
- }
- #endregion
- #region Properties
- /// <summary>
- /// Свойство за маркиране на всички
- /// </summary>
- public bool IsCheckedAll
- {
- get
- {
- return isCheckedAll;
- }
- set
- {
- if (isCheckedAll == value) return;
- isCheckedAll = value;
- if (isCheckedAll)
- {
- foreach (var detail in this.OperationDetails.Where(d => d.IsCheckBoxEnabled))
- {
- detail.IsChecked = true;
- }
- }
- else
- {
- foreach (var detail in this.OperationDetails.Where(d => d.IsCheckBoxEnabled))
- {
- detail.IsChecked = false;
- }
- }
- OnPropertyChanged("IsCheckedAll");
- }
- }
- /// <summary>
- /// Сървис за цени
- /// </summary>
- public IPricesService PriceService
- {
- get
- {
- if (priceService == null)
- priceService = Container.Resolve<IPricesService>();
- return priceService;
- }
- }
- /// <summary>
- /// Свойство за обмяна на данни м/у ViewModel-ите на операция
- /// </summary>
- public IOperationHelper OperationHelper { get; private set; }
- /// <summary>
- /// Колекция с нефилтрирани детайли
- /// </summary>
- internal IList<OperationDetailBaseViewModel> InternalOperationDetails
- {
- get
- {
- if (internalOperationDetails == null)
- {
- if (sourceDetails != null)
- internalOperationDetails = new List<OperationDetailBaseViewModel>(sourceDetails.Where(s => !s.IsDeleted).Select(opd => CreateOperationDetailViewModel(opd)));
- else
- internalOperationDetails = new List<OperationDetailBaseViewModel>();
- }
- return internalOperationDetails;
- }
- set
- {
- if (this.internalOperationDetails == value) return;
- this.internalOperationDetails = value;
- OnPropertyChanged("InternalOperationDetails");
- OnPropertyChanged("OperationDetails");
- }
- }
- /// <summary>
- /// Списък с филтрирани детайли
- /// </summary>
- public IEnumerable<OperationDetailBaseViewModel> OperationDetails
- {
- get
- {
- operationDetails = InternalOperationDetails.Where(n => !n.IsDeleted).OrderBy(d => d.Date).ThenBy(d => !d.IsCustom);
- return operationDetails;
- }
- }
- /// <summary>
- /// Свойство за избран елемент от списъка
- /// </summary>
- public OperationDetailBaseViewModel SelectedOperationDetail
- {
- get
- {
- return selectedOperationDetail;
- }
- set
- {
- if (selectedOperationDetail == value)
- return;
- selectedOperationDetail = value;
- OnPropertyChanged("SelectedOperationDetail");
- DeleteOperationDetailCommand.RaiseCanExecuteChanged();
- }
- }
- /// <summary>
- /// Авансова сума
- /// </summary>
- public decimal AdvancePayment
- {
- get
- {
- return advancePayment;
- }
- set
- {
- if (advancePayment == value)
- return;
- advancePayment = value;
- OnPropertyChanged("AdvancePayment");
- AddAdvanceCommand.RaiseCanExecuteChanged();
- }
- }
- /// <summary>
- /// Свойство за команда за добавяне на услуги
- /// </summary>
- public DelegateCommand<object> AddOperationDetailCommand
- {
- get
- {
- if (addOperationDetailCommand == null)
- {
- addOperationDetailCommand = new DelegateCommand<object>(AddOperationDetail, CanAddOperationDetail);
- }
- return addOperationDetailCommand;
- }
- } // AccommodationCommand
- /// <summary>
- /// Свойство за команда за добавяне на услуги
- /// </summary>
- public DelegateCommand<object> AddAdvanceCommand
- {
- get
- {
- if (addAdvanceCommand == null)
- {
- addAdvanceCommand = new DelegateCommand<object>(AddAdvance, CanAddAdvance);
- }
- return addAdvanceCommand;
- }
- } // AccommodationCommand
- /// <summary>
- /// Свойство за команда за изтриване на услуга
- /// </summary>
- public DelegateCommand<object> DeleteOperationDetailCommand
- {
- get
- {
- if (deleteOperationDetailCommand == null)
- {
- this.deleteOperationDetailCommand = new DelegateCommand<object>(
- DeleteOperation,
- ce => { return selectedOperationDetail != null && selectedOperationDetail.IsCustom; });
- }
- return deleteOperationDetailCommand;
- }
- } // DeleteOperationDetailCommand
- /// <summary>
- /// Флаг оказващ дали имаме извършено плащане
- /// </summary>
- public bool IsPaymentMade
- {
- get
- {
- return isPaymentMade;
- }
- set
- {
- if (isPaymentMade == value)
- return;
- isPaymentMade = value;
- OnPropertyChanged("IsPaymentMade");
- }
- }
- /// <summary>
- /// Списък с ДДС групи
- /// </summary>
- public IEnumerable<IVatGroup> VatGroups
- {
- get
- {
- if (vatGroups == null)
- vatGroups = this.Container.Resolve<IVatGroupsDatabaseService>().GetAll().Select((vat) => { vat.Value = Math.Round(vat.Value, 2); return vat; });
- return vatGroups;
- }
- }
- /// <summary>
- /// Свойство за избрана ДДС група
- /// </summary>
- public IVatGroup SelectedVatGroup
- {
- get
- {
- if (selectedVatGroup == null)
- selectedVatGroup = VatGroups.Where(v => v.VatGroupId == Container.Resolve<IVatGroupsDatabaseService>().GetDefaultVatGroup().VatGroupId).FirstOrDefault();
- return selectedVatGroup;
- }
- set
- {
- if (selectedVatGroup == value)
- return;
- selectedVatGroup = value;
- OnPropertyChanged("SelectedVatGroup", true);
- }
- }
- #endregion Properties
- #region Methods
- /// <summary>
- /// Метод, който оказва дали може да бъде добавена операция
- /// </summary>
- /// <param name="arg"></param>
- /// <returns></returns>
- private bool CanAddOperationDetail(object arg)
- {
- return OperationHelper != null && Container.Resolve<IOperationsServices>().CanAddServices(OperationHelper.State);
- }
- /// <summary>
- /// Добавяне на операция
- /// </summary>
- /// <param name="obj"></param>
- private void AddOperationDetail(object obj)
- {
- OperationDetailBaseViewModel detailVM = null;
- DateTime dtTemp = DateTime.Today;
- detailVM = CreateOperationDetailViewModel(null);
- detailVM.IsPaymentMade = false;
- detailVM.IsCustom = true;
- detailVM.Date = dtTemp;
- detailVM.Quantity = 1;
- ApplyPriceRules(detailVM);
- InternalOperationDetails.Add(detailVM);
- operationDetails = null;
- OnPropertyChanged("OperationDetails", true);
- SelectedOperationDetail = detailVM;
- OperationHelper.RefreshAmount();
- }
- /// <summary>
- /// Метод, който оказва дали може да бъде добавена операция
- /// </summary>
- /// <param name="arg"></param>
- /// <returns></returns>
- private bool CanAddAdvance(object arg)
- {
- foreach (var item in OperationDetails.ToList())
- {
- if (SelectedVatGroup.VatGroupId == 1)
- {
- bool isAdvanceSmallerThanCustomDetails = AdvancePayment <= OperationDetails.Where(i => !i.IsPaymentMade && i.IsCustom).Select(i => i.CurrentPrice).Sum();
- if (!item.IsPaymentMade && AdvancePayment > 0 && isAdvanceSmallerThanCustomDetails)
- {
- return true;
- }
- }
- else
- {
- bool isAdvanceSmallerThanNotCustomDetails = AdvancePayment <= OperationDetails.Where(i => !i.IsPaymentMade && !i.IsCustom).Select(i => i.CurrentPrice).Sum();
- if (!item.IsPaymentMade && AdvancePayment > 0 && isAdvanceSmallerThanNotCustomDetails)
- {
- return true;
- }
- }
- }
- return false;
- }
- /// <summary>
- /// Добавяне на операция
- /// </summary>
- /// <param name="obj"></param>
- private void AddAdvance(object obj)
- {
- OperationDetailBaseViewModel detailVM = null;
- DateTime dtTemp = DateTime.Today;
- IOperationDetail operDetail = Container.Resolve<IOperationDetail>();
- detailVM = CreateOperationDetailViewModel(operDetail);
- detailVM.OperationItem = this.Container.Resolve<IOperationItemsDatabaseService>().GetAllAdvances().Where(a => a.ServiceAndItem.VatGroup.VatGroupId == SelectedVatGroup.VatGroupId).FirstOrDefault();
- detailVM.Description = detailVM.OperationItem == null ? Translator.GetString("strAdvancePayment") : detailVM.OperationItem.ServiceAndItem.Description;
- detailVM.IsPaymentMade = false;
- detailVM.IsCustom = true;
- detailVM.Date = dtTemp;
- detailVM.Quantity = 1;
- detailVM.PriceValue = advancePayment * -1;
- detailVM.CustomPrice = detailVM.PriceValue;
- ApplyPriceRules(detailVM);
- InternalOperationDetails.Add(detailVM);
- AddPayment(detailVM);
- operationDetails = null;
- OnPropertyChanged("OperationDetails", true);
- SelectedOperationDetail = detailVM;
- OperationHelper.RefreshAmount();
- }
- /// <summary>
- /// Добавя плащане
- /// </summary>
- /// <param name="detail"></param>
- private void AddPayment(OperationDetailBaseViewModel detail)
- {
- IOperationPayment operationPayment = this.Container.Resolve<IOperationPayment>();
- operationPayment.Date = ApplicationDate.Now;
- IOperationDetail operDetail = detail.OperationDetail;
- if (operDetail != null)
- {
- operDetail.Payments.Add(operationPayment);
- }
- operationPayment.Amount = detail.PriceValue;
- }
- /// <summary>
- /// Метод за изтриване на операция
- /// </summary>
- /// <param name="o"></param>
- protected virtual void DeleteOperation(object o)
- {
- // премахваме ViewModel-a от списъка
- selectedOperationDetail.IsDeleted = true;
- // избираме предишната стая от списъка
- var service = Container.Resolve<IOperationItemsDatabaseService>();
- var itemToSelect = OperationDetails.FirstOrDefault(od => service.AreEqual(selectedOperationDetail.OperationItem, od.OperationItem));
- if (itemToSelect == null)
- itemToSelect = OperationDetails.FirstOrDefault(od => od.IsCustom);
- foreach (var detail in OperationDetails)
- detail.IsChanged = true;
- operationDetails = null;
- OnPropertyChanged("OperationDetails", true);
- SelectedOperationDetail = itemToSelect;
- OperationHelper.RefreshAmount();
- }
- /// <summary>
- /// Прихваща добавяне на операция от склад про
- /// </summary>
- /// <param name="obj"></param>
- private void OnOperationChanged(object obj)
- {
- IOperationDetail item = obj as IOperationDetail;
- OperationDetailBaseViewModel detailVM = null;
- detailVM = CreateOperationDetailViewModel(item);
- detailVM.IsCustom = true;
- detailVM.Date = item.Date;
- detailVM.Quantity = 1;
- detailVM.PriceValue = item.Price;
- detailVM.CustomDescription = item.CustomDescription;
- ApplyPriceRules(detailVM);
- InternalOperationDetails.Add(detailVM);
- OnPropertyChanged("OperationDetails");
- OperationHelper.RefreshAmount();
- }
- /// <summary>
- /// Метод, който създава ViewModel за детайл
- /// </summary>
- /// <param name="detail"></param>
- /// <returns></returns>
- protected virtual OperationDetailBaseViewModel CreateOperationDetailViewModel(IOperationDetail detail)
- {
- return new OperationDetailBaseViewModel(Container, detail, OperationHelper);
- }
- /// <summary>
- /// Метод, който инициализира детайлите на операцията
- /// </summary>
- /// <param name="customers"></param>
- /// <param name="children"></param>
- /// <param name="onLoad"></param>
- /// <param name="operationState"></param>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Justification = "Complexity - нужда от refactoring")]
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Complexity - нужда от refactoring")]
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Complexity - нужда от refactoring")]
- public void InitOperationDetails(IEnumerable<ICustomer> customers, IEnumerable<ICustomer> children = null, bool onLoad = false, OperationStateType operationState = OperationStateType.Default)
- {
- // пач
- bool flag = true;
- //// Изчистваме детайли ако има въведени
- foreach (OperationDetailBaseViewModel item in OperationHelper.OperationDetailsViewModel.OperationDetails)
- {
- if (!OperationHelper.IsNew)
- flag = OperationHelper.State == OperationStateType.Reservation
- || OperationHelper.State == OperationStateType.Active
- || OperationHelper.State == OperationStateType.AutoReservation
- || item.Date.Date >= DateTime.Now.Date;
- if (flag)
- {
- if (!item.IsCustom)
- {
- item.IsDeleted = true;
- continue;
- }
- else
- {
- if (item.PriceValue > 0)
- {
- if (item.OperationDetail != null)
- item.AmountLeftToPay = (item.CurrentPrice * item.Quantity) - item.OperationDetail.Payments.Sum(payment => payment.Amount);
- else
- item.AmountLeftToPay = item.CurrentPrice * item.Quantity;
- }
- }
- }
- }
- DateTime dtTemp = OperationHelper.FromDate;
- if (!OperationHelper.IsNew && !(OperationHelper.State == OperationStateType.Reservation
- || OperationHelper.State == OperationStateType.AutoReservation
- || OperationHelper.State == OperationStateType.Active))
- {
- if (dtTemp.Date <= ApplicationDate.Now && OperationHelper.IsInEditMode)
- dtTemp = ApplicationDate.Now;
- }
- IOperationsDatabaseService operationService = Container.Resolve<IOperationsDatabaseService>();
- do
- {
- IOperationDetail detail = Container.Resolve<IOperationDetail>();
- if (OperationHelper.Operation != null && OperationHelper.Operation.Details != null)
- {
- IEnumerable<IOperationDetail> details = operationService.GetContextOperation(OperationHelper.Operation).Details.Where(d => d.OperationItem.OperationItemId == OperationHelper.OperationItem.OperationItemId && d.Date == dtTemp && d.IsDeleted == false);
- if (details.Count() == 0)
- details = operationService.GetContextOperation(OperationHelper.Operation).Details.Where(d => d.OperationItem.ServiceAndItem.EnumServicesAndItemsType == OperationHelper.OperationItem.ServiceAndItem.EnumServicesAndItemsType && d.Date == dtTemp && d.IsDeleted == false);
- detail = details.LastOrDefault(d => d.Payments.Count != 0) ?? details.LastOrDefault();
- }
- OperationDetailBaseViewModel detailVM = CreateOperationDetailViewModel(detail);
- detailVM.OperationItem = OperationHelper.OperationItem;
- if (OperationHelper.Pricelist != null)
- detailVM.Package = OperationHelper.Pricelist.Package;
- detailVM.IsDeleted = false;
- detailVM.Date = dtTemp;
- detailVM.Quantity = 1;
- if (OperationHelper.OperationItem == null)
- detailVM.Description = string.Empty;
- else
- detailVM.Description = OperationHelper.OperationItem.ServiceAndItem.Description;
- if (customers != null)
- {
- if (!onLoad)
- {
- if (detailVM.Date.Date >= ApplicationDate.Now.Date)
- {
- foreach (var customer in detailVM.InternalCustomers.Where(c => !c.Customer.IsChild))
- customer.IsDeleted = true;
- foreach (var customer in customers)
- detailVM.OnCustomerChange(customer, true);
- }
- }
- }
- if (children != null)
- {
- if (!onLoad)
- {
- if (detailVM.Date.Date >= ApplicationDate.Now.Date)
- {
- foreach (var customer in detailVM.InternalCustomers.Where(c => c.Customer.IsChild))
- customer.IsDeleted = true;
- foreach (var child in children)
- detailVM.OnCustomerChange(child, true);
- }
- }
- }
- detailVM.PriceValue = PriceService.CalculateAccommodationPrice(dtTemp, detailVM.OperationItem, OperationHelper.Pricelist, detailVM.Customers.Select(c => c.Customer));
- if (detailVM != null && detailVM.PriceRules != null)
- {
- //// Добавяме ценови правила
- ApplyPriceRules(detailVM);
- }
- if (detailVM.OperationDetail != null)
- {
- detailVM.AmountLeftToPay = (detailVM.CurrentPrice * detailVM.Quantity) - detailVM.OperationDetail.Payments.Sum(s => s.Amount);
- }
- if (detail != null)
- detailVM.IsPaymentMade = (detailVM.PriceValue * detailVM.Quantity) - detail.Payments.Sum(s => s.Amount) == 0;
- InternalOperationDetails.Add(detailVM);
- //// Loop
- dtTemp = dtTemp.AddDays(1);
- detailVM.IsChanged = false;
- }
- while (operationState == OperationStateType.End ? dtTemp.Date < ApplicationDate.Now.Date : dtTemp.Date < OperationHelper.ToDate.Date);
- OnPropertyChanged("OperationDetails", true);
- OnPropertyChanged("InternalOperationDetails");
- OnPropertyChanged("Balance");
- if (OperationHelper.Package != null)
- ReinitMealsFromPackage(onLoad);
- }
- /// <summary>
- /// Метод за обновяване на добавените услуги при смяна на избран пакет
- /// </summary>
- /// <param name="oldPackage"></param>
- /// <param name="newPackage"></param>
- public void InitOperationDetailsFromPackage(IPackage oldPackage, IPackage newPackage)
- {
- foreach (var item in OperationHelper.OperationDetailsViewModel.OperationDetails)
- {
- if (oldPackage != null && item.Package != null && item.Package.PackageId == oldPackage.PackageId)
- {
- item.IsDeleted = true;
- }
- }
- if (newPackage != null)
- {
- foreach (var detail in newPackage.Items.Where(i => !i.ServiceAndItem.IsDeleted))
- {
- if (detail.ServiceAndItem.EnumServicesAndItemsType.Type == ServiceAndItemGroupTypes.Meals)
- {
- AddMealsFromPackage(detail, newPackage);
- }
- else
- {
- var detailVM = CreateOperationDetailViewModel(null);
- detailVM.IsCustom = true;
- detailVM.OperationItem = detail;
- detailVM.IsFromPackage = true;
- detailVM.Package = newPackage;
- detailVM.Date = DateTime.Now;
- detailVM.Quantity = 1;
- detailVM.PriceValue = 0;
- detailVM.Description = detail.ServiceAndItem.Description;
- InternalOperationDetails.Add(detailVM);
- }
- }
- }
- OnPropertyChanged("OperationDetails");
- OnPropertyChanged("Balance");
- }
- #region Meals Initialization && Cache
- /// <summary>
- /// Метод за добавяне на услугите за пансион от пакета
- /// </summary>
- /// <param name="detail"></param>
- /// <param name="package"></param>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Refactor")]
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Refactor")]
- private void AddMealsFromPackage(IOperationItem detail, IPackage package)
- {
- accomodatedCustomers.Clear();
- foreach (DateTime date in customersOvernightsCacheService.CustomerOvernightsCache.Keys)
- {
- if (date > OperationHelper.ToDate)
- break;
- if (detail.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Dinner
- && date.Date == OperationHelper.ToDate.Date)
- break;
- int childAccomodatedWithoutAgeGroupInThePackage = CalculateChildsOutOfAgeGroupsInThePackage(customersOvernightsCacheService.CustomerOvernightsCache[date], package);
- int newAccomodatedChildCount = 0;
- int newAccomodatedAdultsCount = 0;
- if (detail.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast && !customersOvernightsCacheService.CustomerOvernightsCache[date].All(cust => accomodatedCustomers.Contains(cust)))
- {
- //// Проверяваме за новонастанени
- if (detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null && customersOvernightsCacheService.CustomerOvernightsCache[date].Any(d => d.Age != null))
- {
- newAccomodatedChildCount = customersOvernightsCacheService.CustomerOvernightsCache[date].Count(cust => cust.IsChild && cust.Age.Value >= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.FromAge &&
- cust.Age.Value <= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.ToAge && !accomodatedCustomers.Contains(cust)) - childAccomodatedWithoutAgeGroupInThePackage;
- }
- newAccomodatedAdultsCount = customersOvernightsCacheService.CustomerOvernightsCache[date].Count(cust => !cust.IsChild && !accomodatedCustomers.Contains(cust)) + childAccomodatedWithoutAgeGroupInThePackage;
- foreach (ICustomer customer in customersOvernightsCacheService.CustomerOvernightsCache[date])
- accomodatedCustomers.Add(customer);
- }
- OperationDetailBaseViewModel detailMealVM = CreateOperationDetailViewModel(null);
- if (detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup == null)
- {
- detailMealVM.IsCustom = true;
- detailMealVM.OperationItem = detail;
- detailMealVM.IsFromPackage = true;
- detailMealVM.Package = package;
- detailMealVM.Quantity = customersOvernightsCacheService.CustomerOvernightsCache[date].Count(c => !c.IsChild && !c.IsDeleted) + childAccomodatedWithoutAgeGroupInThePackage - newAccomodatedAdultsCount;
- detailMealVM.PriceValue = 0;
- detailMealVM.Description = detail.ServiceAndItem.Description;
- detailMealVM.Date = date;
- }
- else
- {
- int childsCount = customersOvernightsCacheService.CustomerOvernightsCache[date].Count(c => c.IsChild && c.Age.HasValue
- && detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null
- && c.Age >= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.FromAge
- && c.Age <= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.ToAge);
- if (childsCount > 0)
- {
- OperationDetailBaseViewModel detailMealVMChild = CreateOperationDetailViewModel(null);
- detailMealVMChild.IsCustom = true;
- detailMealVMChild.OperationItem = detail;
- detailMealVMChild.IsFromPackage = true;
- detailMealVMChild.Package = package;
- detailMealVMChild.PriceValue = 0;
- detailMealVMChild.Description = detail.ServiceAndItem.Description;
- detailMealVMChild.Date = date;
- detailMealVMChild.Quantity = childsCount - newAccomodatedChildCount;
- OperationDetailBaseViewModel detailToCheckChild = internalOperationDetails.FirstOrDefault(d => d.OperationItem == detailMealVMChild.OperationItem && !d.IsDeleted && d.Date.Date == detailMealVMChild.Date.Date &&
- d.OperationItem.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null);
- if (detailToCheckChild != null)
- {
- internalOperationDetails.FirstOrDefault(d => d.OperationItem == detailMealVMChild.OperationItem && !d.IsDeleted && d.Date.Date == detailMealVMChild.Date.Date && d.OperationItem.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null).Quantity++;
- }
- else if (detailMealVMChild.Quantity > 0)
- internalOperationDetails.Add(detailMealVMChild);
- }
- }
- OperationDetailBaseViewModel detailToCheck = internalOperationDetails.FirstOrDefault(d => d.OperationItem == detailMealVM.OperationItem && !d.IsDeleted && d.Date.Date == detailMealVM.Date.Date);
- if (detailToCheck != null)
- {
- internalOperationDetails.FirstOrDefault(d => d.OperationItem == detailMealVM.OperationItem && !d.IsDeleted && d.Date.Date == detailMealVM.Date.Date).Quantity++;
- }
- else if (detailMealVM.Quantity > 0)
- {
- internalOperationDetails.Add(detailMealVM);
- }
- if (detail.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast)
- {
- IEnumerable<ICustomer> lastDayStand;
- if (customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(date.AddDays(1)))
- lastDayStand = customersOvernightsCacheService.CustomerOvernightsCache[date].Where(customer => !customersOvernightsCacheService.CustomerOvernightsCache[date.AddDays(1)].Contains(customer));
- else
- lastDayStand = customersOvernightsCacheService.CustomerOvernightsCache[date];
- if (lastDayStand != null && lastDayStand.Count() != 0)
- AddLastDayBreakfastForLeavingGuests(detail, package, date.AddDays(1), lastDayStand.Where(customer => !customer.IsChild && !customer.IsDeleted).Count(), childAccomodatedWithoutAgeGroupInThePackage);
- }
- }
- OnPropertyChanged("InternalOperationDetails", true);
- }
- /// <summary>
- /// Метод който изчислява колко деца са извън възрастовите групи зададени за текущия пакет
- /// </summary>
- /// <param name="customers"></param>
- /// <param name="package"></param>
- /// <returns></returns>
- private int CalculateChildsOutOfAgeGroupsInThePackage(IEnumerable<ICustomer> customers, IPackage package)
- {
- decimal maxAgeDeclaregInAgeGroupsInPackag = 0;
- decimal minAgeDeclaregInAgeGroupsInPackag = 0;
- if (package.Items.Any(item => item.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null))
- {
- maxAgeDeclaregInAgeGroupsInPackag = package.Items.Where(item => item.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null)
- .Max(item => item.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.ToAge);
- minAgeDeclaregInAgeGroupsInPackag = package.Items.Where(item => item.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null)
- .Min(item => item.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.FromAge);
- }
- int childsCount = customers.Where(customer => customer.IsChild && !customer.IsDeleted)
- .Count(customer => (customer.Age.HasValue && customer.Age.Value > maxAgeDeclaregInAgeGroupsInPackag)
- || (customer.Age.HasValue && customer.Age.Value < minAgeDeclaregInAgeGroupsInPackag)
- || CalculateAge(customer) == null
- || CalculateAge(customer) > maxAgeDeclaregInAgeGroupsInPackag
- || CalculateAge(customer) < minAgeDeclaregInAgeGroupsInPackag);
- return childsCount;
- }
- /// <summary>
- /// Метод който изцислява на колко години е дад. дете
- /// </summary>
- /// <param name="customer"></param>
- /// <returns></returns>
- private decimal? CalculateAge(ICustomer customer)
- {
- decimal? age = customer.Age;
- if (customer.Birthdate.HasValue)
- {
- age = DateTime.Today.Year - customer.Birthdate.Value.Year;
- if (customer.Birthdate.Value.Date > DateTime.Today.AddYears((int)-age))
- age--;
- }
- return age;
- }
- /// <summary>
- /// Добавя закуски в последния ден на резервцията
- /// </summary>
- /// <param name="detail"></param>
- /// <param name="package"></param>
- /// <param name="date"></param>
- /// <param name="adultsCount"></param>
- /// <param name="childAccomodatedWithoutAgeGroupInThePackage"></param>
- private void AddLastDayBreakfastForLeavingGuests(IOperationItem detail, IPackage package, DateTime date, int adultsCount, int childAccomodatedWithoutAgeGroupInThePackage = 0)
- {
- OperationDetailBaseViewModel detailMealVM = CreateOperationDetailViewModel(null);
- if (detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup == null)
- {
- detailMealVM.IsCustom = true;
- detailMealVM.OperationItem = detail;
- detailMealVM.IsFromPackage = true;
- detailMealVM.Package = package;
- detailMealVM.Quantity = adultsCount + childAccomodatedWithoutAgeGroupInThePackage;
- detailMealVM.PriceValue = 0;
- detailMealVM.Description = detail.ServiceAndItem.Description;
- detailMealVM.Date = date;
- internalOperationDetails.Add(detailMealVM);
- }
- else
- {
- int childrenCount = 0;
- if (customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(date.AddDays(-1)))
- childrenCount = customersOvernightsCacheService.CustomerOvernightsCache[date.AddDays(-1)].Count(c => c.IsChild && c.Age.HasValue
- && detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null
- && c.Age >= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.FromAge
- && c.Age <= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.ToAge);
- if (childrenCount != 0)
- {
- var detailMealVMChild = CreateOperationDetailViewModel(null);
- detailMealVMChild.IsCustom = true;
- detailMealVMChild.OperationItem = detail;
- detailMealVMChild.IsFromPackage = true;
- detailMealVMChild.Package = package;
- detailMealVMChild.Quantity = childrenCount;
- detailMealVMChild.PriceValue = 0;
- detailMealVMChild.Description = detail.ServiceAndItem.Description;
- detailMealVMChild.Date = date;
- internalOperationDetails.Add(detailMealVMChild);
- }
- }
- }
- #endregion
- /// <summary>
- /// Метод за реинициализация на пансиона
- /// </summary>
- /// <param name="onLoad"></param>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Refactor")]
- public void ReinitMealsFromPackage(bool onLoad = false)
- {
- foreach (var detail in InternalOperationDetails.Where(d => !d.IsDeleted && d.IsCustom && d.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Type == ServiceAndItemGroupTypes.Meals))
- {
- if (detail.Date.Date >= ApplicationDate.Now.Date)
- {
- DateTime tempDate = customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(detail.Date.Date) ? detail.Date.Date : detail.Date.Date.AddDays(-1);
- IAgeGroup ageGroup = null;
- int currentDayCustomersCount = 0;
- int previousDayCustomersCount = 0;
- if (detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null && customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(tempDate))
- {
- ageGroup = detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.AgeGroup;
- currentDayCustomersCount = customersOvernightsCacheService.CustomerOvernightsCache[tempDate].Count(a => (a.IsChild && a.Age.HasValue && a.Age >= ageGroup.FromAge && a.Age <= ageGroup.ToAge)
- || (a.Age == null && a.IsChild && (CalculateAge(a) >= ageGroup.FromAge
- || CalculateAge(a) <= ageGroup.FromAge)));
- previousDayCustomersCount = !customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(tempDate.AddDays(-1)) ?
- 0 : customersOvernightsCacheService.CustomerOvernightsCache[tempDate.AddDays(-1)].Count(a => (a.IsChild && a.Age.HasValue && a.Age >= ageGroup.FromAge && a.Age <= ageGroup.ToAge)
- || (a.Age == null && a.IsChild && (CalculateAge(a) >= ageGroup.FromAge
- || CalculateAge(a) <= ageGroup.FromAge)));
- if (detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast && currentDayCustomersCount > previousDayCustomersCount)
- detail.Quantity = currentDayCustomersCount - previousDayCustomersCount;
- else if ((detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast || detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Lunch)
- && currentDayCustomersCount < previousDayCustomersCount)
- detail.Quantity = customersOvernightsCacheService.CustomerOvernightsCache[detail.Date.AddDays(-1)].Count(p => p.IsChild);
- else
- detail.Quantity = currentDayCustomersCount;
- }
- else if (customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(tempDate))
- {
- currentDayCustomersCount = customersOvernightsCacheService.CustomerOvernightsCache[tempDate].Count(a => !a.IsChild);
- previousDayCustomersCount = !customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(tempDate.AddDays(-1)) ?
- 0 : customersOvernightsCacheService.CustomerOvernightsCache[tempDate.AddDays(-1)].Count(a => !a.IsChild);
- if (detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast && currentDayCustomersCount > previousDayCustomersCount)
- detail.Quantity = currentDayCustomersCount - previousDayCustomersCount;
- else if ((detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast || detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Lunch)
- && currentDayCustomersCount < previousDayCustomersCount)
- detail.Quantity = customersOvernightsCacheService.CustomerOvernightsCache[detail.Date.AddDays(-1)].Count(p => !p.IsChild);
- else
- detail.Quantity = currentDayCustomersCount;
- }
- if (onLoad)
- detail.IsChanged = false;
- }
- }
- OnPropertyChanged("InternalOperationDetails");
- }
- /// <summary>
- /// Метод, който прилага ценовите правила към детайла на операцията
- /// </summary>
- /// <param name="detailVM"></param>
- private void ApplyPriceRules(OperationDetailBaseViewModel detailVM)
- {
- if (detailVM == null)
- return;
- detailVM.PriceRules.Clear();
- var dict = detailVM.GetPriceRuleValues();
- OperatorSymbolsBase expressionSymbols = new OperatorSymbolsBase();
- IExpressionContext context = Container.Resolve<IExpressionContext>();
- foreach (var kvp in dict)
- context.AddVariable(kvp.Key, kvp.Value);
- foreach (IPriceRule priceRule in Container.Resolve<IPriceRulesDatabaseService>().GetPriceRules().Where(pr => pr.Status))
- {
- // Добавяме параметрите на ценовото правило
- foreach (var par in priceRule.Parameters)
- context.AddVariable(par.Identifier, par.Value);
- if (priceRule.ActionIdentifier != "SendEmail")
- {
- var tree = RpnParser.CreateExpressionTree(expressionSymbols, priceRule.Script);
- var value = tree.CalculateValue(context);
- if (value.GetType() == typeof(bool) && (bool)value)
- {
- detailVM.AddPriceRule(priceRule);
- }
- }
- }
- }
- /// <summary>
- /// Метод, който променя ползвана стока/услуга за всички детайли
- /// </summary>
- /// <param name="newOperationItem"></param>
- public void OnOperationItemChange(IOperationItem newOperationItem)
- {
- foreach (var item in OperationHelper.GetOperationItemRelatedDetails())
- item.OperationItem = newOperationItem;
- IsChanged = true;
- }
- /// <summary>
- /// Метод, който променя списък с клиенти към детайлите на операция
- /// </summary>
- /// <param name="customer"></param>
- /// <param name="isAdded">Флаг, дали е добавен или изтрит. True ако е добавен, иначе False. </param>
- /// <param name="oldCustomer"></param>
- internal void OnCustomerChange(ICustomer customer, bool isAdded, ICustomer oldCustomer = null)
- {
- foreach (var item in InternalOperationDetails.Where(d => !d.IsDeleted && d.OperationItem != null && d.OperationItem.ServiceAndItem.Identifier == ServiceAndItemsType.Room))
- {
- if (!OperationHelper.IsNew && OperationHelper.State == OperationStateType.Active && item.Date.Date < ApplicationDate.Now)
- continue;
- item.OnCustomerChange(customer, isAdded, oldCustomer);
- //// От тук само добавя клиенти !!!!
- Container.Resolve<IEventAggregator>().GetEvent<CustomersAccomodationChangedEvent>()
- .Publish(new AccomodationChangedEventArgs<ICustomer>(isAdded, item.Date, customer));
- if (!item.IsFromPackage)
- item.PriceValue = PriceService.CalculateAccommodationPrice(item.Date, item.OperationItem, OperationHelper.Pricelist, item.Customers.Select(c => c.Customer), item.CurrentPrice);
- }
- if (OperationHelper.Package != null)
- ReinitMealsFromPackage();
- }
- /// <summary>
- /// Метод, който запазва данните в базата
- /// </summary>
- /// <param name="dbService"></param>
- public void Save(IOperationsDatabaseService dbService)
- {
- if (!IsChanged)
- return;
- var enumServicesDatabaseServise = Container.Resolve<IEnumServiceAndItemTypesDatabaseService>();
- foreach (var operationDetail in InternalOperationDetails)
- {
- //// Пач
- if (operationDetail.Date == DateTime.MinValue.Date)
- continue;
- if (!operationDetail.IsDeleted)
- {
- bool isnew = operationDetail.OperationItem.ServiceAndItem.Identifier == ServiceAndItemsType.Room;
- if (isnew && operationDetail.OperationDetail != null)
- {
- operationDetail.OperationDetail.IsDeleted = true;
- }
- if (operationDetail.OperationItem.ServiceAndItem.EnumServicesAndItemsType != null
- && operationDetail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Type ==
- ServiceAndItemGroupTypes.Custom
- && !operationDetail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.IsUsed)
- {
- var service = enumServicesDatabaseServise.GetAllTypes().FirstOrDefault(s =>
- s.EnumServicesAndItemsTypeId == operationDetail.OperationItem.ServiceAndItem
- .EnumServicesAndItemsType.EnumServicesAndItemsTypeId);
- service.IsUsed = true;
- }
- operationDetail.Save(dbService, isnew);
- }
- else if (!OperationHelper.IsNew && !operationDetail.IsNew)
- {
- dbService.RemoveOperationDetail(operationDetail.OperationDetail);
- }
- }
- enumServicesDatabaseServise.SaveChanges();
- this.Container.Resolve<IEventAggregator>().GetEvent<OperationDetailsChangedEvent>().Publish(this.InternalOperationDetails);
- }
- /// <summary>
- /// Метод за валидация на въведените данни
- /// </summary>
- /// <returns></returns>
- public virtual List<ValidationResult> Validate()
- {
- List<ValidationResult> res = new List<ValidationResult>();
- ValidationResult tmpRes;
- foreach (var item in OperationDetails)
- {
- tmpRes = item.ValidateOperationDetail();
- if (tmpRes.ErrorLevel != ErrorLevel.NoError)
- res.Add(tmpRes);
- }
- return res;
- }
- /// <summary>
- /// Опреснява командата за плащане
- /// </summary>
- public void RefreshPaymentCommand()
- {
- foreach (var detail in OperationDetails.ToList())
- {
- detail.EditPaymentsCommand.RaiseCanExecuteChanged();
- }
- }
- #endregion Methods
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement