Advertisement
Guest User

Untitled

a guest
Sep 16th, 2019
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 52.74 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using Microinvest.Core.Common;
  6. using Microinvest.Core.Common.ExpressionEvaluator;
  7. using Microinvest.Core.Infrastructure;
  8. using Microinvest.Core.Interfaces.DatabaseServices;
  9. using Microinvest.Core.Interfaces.Model;
  10. using Microinvest.Core.Validation;
  11. using Microinvest.Hotel.Core.Common;
  12. using Microinvest.Hotel.Core.Events;
  13. using Microinvest.Hotel.Core.Events.TPayloadClasses;
  14. using Microinvest.Hotel.Core.Interfaces.Helpers;
  15. using Microinvest.Hotel.Core.Interfaces.Model;
  16. using Microinvest.Hotel.Core.Interfaces.Services;
  17. using Microinvest.Hotel.Core.Interfaces.UI;
  18. using Microinvest.Hotel.Core.ViewModels.Helpers;
  19. using Microinvest.Prism.Commands;
  20. using Microinvest.Prism.Events;
  21. using Microinvest.Unity;
  22.  
  23. namespace Microinvest.Hotel.Core.ViewModels.Operations
  24. {
  25.     /// <summary>
  26.     /// Базов клас за редакция на детайли към операция
  27.     /// </summary>
  28.     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "N/A")]
  29.     public class OperationDetailsListBaseViewModel : BaseViewModel
  30.     {
  31.         #region Declarations
  32.  
  33.         /// <summary> Колекция с текущи детайли </summary>
  34.         private IEnumerable<IOperationDetail> sourceDetails;
  35.  
  36.         /// <summary> Колекция с нефилтрирани детайли </summary>
  37.         private IList<OperationDetailBaseViewModel> internalOperationDetails;
  38.  
  39.         /// <summary> променлива за избран елемент от списъка </summary>
  40.         private OperationDetailBaseViewModel selectedOperationDetail;
  41.  
  42.         /// <summary> променлива за команда за добавяне на услуги </summary>
  43.         private DelegateCommand<object> addOperationDetailCommand;
  44.  
  45.         /// <summary> променлива за команда за изтриване на услуга </summary>
  46.         private DelegateCommand<object> deleteOperationDetailCommand;
  47.  
  48.         /// <summary> променлива за команда за изтриване на услуга </summary>
  49.         private DelegateCommand<object> addAdvanceCommand;
  50.  
  51.         /// <summary> променлива за сървис за цени </summary>
  52.         private IPricesService priceService;
  53.  
  54.         /// <summary> флаг за направено плащане </summary>
  55.         private bool isPaymentMade;
  56.  
  57.         /// <summary> авансова сума </summary>
  58.         private decimal advancePayment;
  59.  
  60.         /// <summary>Списък с ДДС групи</summary>
  61.         private IEnumerable<IVatGroup> vatGroups;
  62.  
  63.         /// <summary>Избрана ДДС група</summary>
  64.         private IVatGroup selectedVatGroup;
  65.  
  66.         /// <summary>Избрани ли са всички боксове</summary>
  67.         private bool isCheckedAll;
  68.  
  69.         /// <summary>
  70.         /// Списък с филтрирани детайли
  71.         /// </summary>
  72.         private IEnumerable<OperationDetailBaseViewModel> operationDetails;
  73.  
  74.         /// <summary> Настанени използва се при инициализацията на пакети</summary>
  75.         private HashSet<ICustomer> accomodatedCustomers;
  76.  
  77.         /// <summary> Сървис за кеш на клиенти и нощивки </summary>
  78.         private ICustomersAccomodationCacheService customersOvernightsCacheService;
  79.         #endregion
  80.  
  81.         #region Initialization
  82.  
  83.         /// <summary>
  84.         /// Конструктор
  85.         /// </summary>
  86.         /// <param name="container"></param>
  87.         /// <param name="details"></param>
  88.         /// <param name="operationHelper"></param>
  89.         public OperationDetailsListBaseViewModel(IUnityContainer container, IEnumerable<IOperationDetail> details, IOperationHelper operationHelper)
  90.         {
  91.             this.Container = container;
  92.             this.sourceDetails = details;
  93.             this.OperationHelper = operationHelper;
  94.  
  95.             if (this.Container.IsRegistered<IEventAggregator>())
  96.                 this.Container.Resolve<IEventAggregator>().GetEvent<OperationDetailChangedEvent>().Subscribe(OnOperationChanged);
  97.  
  98.             customersOvernightsCacheService = new CustomersAccomodationCacheService(Container, OperationHelper.Operation);
  99.             accomodatedCustomers = new HashSet<ICustomer>();
  100.         }
  101.  
  102.         #endregion
  103.  
  104.         #region Properties
  105.  
  106.         /// <summary>
  107.         /// Свойство за маркиране на всички  
  108.         /// </summary>
  109.         public bool IsCheckedAll
  110.         {
  111.             get
  112.             {
  113.                 return isCheckedAll;
  114.             }
  115.  
  116.             set
  117.             {
  118.                 if (isCheckedAll == value) return;
  119.  
  120.                 isCheckedAll = value;
  121.  
  122.                 if (isCheckedAll)
  123.                 {
  124.                     foreach (var detail in this.OperationDetails.Where(d => d.IsCheckBoxEnabled))
  125.                     {
  126.                         detail.IsChecked = true;
  127.                     }
  128.                 }
  129.                 else
  130.                 {
  131.                     foreach (var detail in this.OperationDetails.Where(d => d.IsCheckBoxEnabled))
  132.                     {
  133.                         detail.IsChecked = false;
  134.                     }
  135.                 }
  136.  
  137.                 OnPropertyChanged("IsCheckedAll");
  138.             }
  139.         }
  140.  
  141.         /// <summary>
  142.         /// Сървис за цени
  143.         /// </summary>
  144.         public IPricesService PriceService
  145.         {
  146.             get
  147.             {
  148.                 if (priceService == null)
  149.                     priceService = Container.Resolve<IPricesService>();
  150.                 return priceService;
  151.             }
  152.         }
  153.  
  154.         /// <summary>
  155.         /// Свойство за обмяна на данни м/у ViewModel-ите на операция
  156.         /// </summary>
  157.         public IOperationHelper OperationHelper { get; private set; }
  158.  
  159.         /// <summary>
  160.         /// Колекция с нефилтрирани детайли
  161.         /// </summary>
  162.         internal IList<OperationDetailBaseViewModel> InternalOperationDetails
  163.         {
  164.             get
  165.             {
  166.                 if (internalOperationDetails == null)
  167.                 {
  168.                     if (sourceDetails != null)
  169.                         internalOperationDetails = new List<OperationDetailBaseViewModel>(sourceDetails.Where(s => !s.IsDeleted).Select(opd => CreateOperationDetailViewModel(opd)));
  170.                     else
  171.                         internalOperationDetails = new List<OperationDetailBaseViewModel>();
  172.                 }
  173.  
  174.                 return internalOperationDetails;
  175.             }
  176.  
  177.             set
  178.             {
  179.                 if (this.internalOperationDetails == value) return;
  180.  
  181.                 this.internalOperationDetails = value;
  182.                 OnPropertyChanged("InternalOperationDetails");
  183.                 OnPropertyChanged("OperationDetails");
  184.             }
  185.         }
  186.  
  187.         /// <summary>
  188.         /// Списък с филтрирани детайли  
  189.         /// </summary>
  190.         public IEnumerable<OperationDetailBaseViewModel> OperationDetails
  191.         {
  192.             get
  193.             {
  194.                 operationDetails = InternalOperationDetails.Where(n => !n.IsDeleted).OrderBy(d => d.Date).ThenBy(d => !d.IsCustom);
  195.                 return operationDetails;
  196.             }
  197.         }
  198.  
  199.         /// <summary>
  200.         /// Свойство за избран елемент от списъка  
  201.         /// </summary>
  202.         public OperationDetailBaseViewModel SelectedOperationDetail
  203.         {
  204.             get
  205.             {
  206.                 return selectedOperationDetail;
  207.             }
  208.  
  209.             set
  210.             {
  211.                 if (selectedOperationDetail == value)
  212.                     return;
  213.                 selectedOperationDetail = value;
  214.  
  215.                 OnPropertyChanged("SelectedOperationDetail");
  216.                 DeleteOperationDetailCommand.RaiseCanExecuteChanged();
  217.             }
  218.         }
  219.  
  220.         /// <summary>
  221.         /// Авансова сума
  222.         /// </summary>
  223.         public decimal AdvancePayment
  224.         {
  225.             get
  226.             {
  227.                 return advancePayment;
  228.             }
  229.  
  230.             set
  231.             {
  232.                 if (advancePayment == value)
  233.                     return;
  234.                 advancePayment = value;
  235.                 OnPropertyChanged("AdvancePayment");
  236.                 AddAdvanceCommand.RaiseCanExecuteChanged();
  237.             }
  238.         }
  239.  
  240.         /// <summary>
  241.         /// Свойство за команда за добавяне на услуги
  242.         /// </summary>
  243.         public DelegateCommand<object> AddOperationDetailCommand
  244.         {
  245.             get
  246.             {
  247.                 if (addOperationDetailCommand == null)
  248.                 {
  249.                     addOperationDetailCommand = new DelegateCommand<object>(AddOperationDetail, CanAddOperationDetail);
  250.                 }
  251.  
  252.                 return addOperationDetailCommand;
  253.             }
  254.         } // AccommodationCommand
  255.  
  256.         /// <summary>
  257.         /// Свойство за команда за добавяне на услуги
  258.         /// </summary>
  259.         public DelegateCommand<object> AddAdvanceCommand
  260.         {
  261.             get
  262.             {
  263.                 if (addAdvanceCommand == null)
  264.                 {
  265.                     addAdvanceCommand = new DelegateCommand<object>(AddAdvance, CanAddAdvance);
  266.                 }
  267.  
  268.                 return addAdvanceCommand;
  269.             }
  270.         } // AccommodationCommand
  271.  
  272.         /// <summary>
  273.         /// Свойство за команда за изтриване на услуга
  274.         /// </summary>
  275.         public DelegateCommand<object> DeleteOperationDetailCommand
  276.         {
  277.             get
  278.             {
  279.                 if (deleteOperationDetailCommand == null)
  280.                 {
  281.                     this.deleteOperationDetailCommand = new DelegateCommand<object>(
  282.                        DeleteOperation,
  283.                        ce => { return selectedOperationDetail != null && selectedOperationDetail.IsCustom; });
  284.                 }
  285.  
  286.                 return deleteOperationDetailCommand;
  287.             }
  288.         } // DeleteOperationDetailCommand
  289.  
  290.         /// <summary>
  291.         /// Флаг оказващ дали имаме извършено плащане
  292.         /// </summary>
  293.         public bool IsPaymentMade
  294.         {
  295.             get
  296.             {
  297.                 return isPaymentMade;
  298.             }
  299.  
  300.             set
  301.             {
  302.                 if (isPaymentMade == value)
  303.                     return;
  304.                 isPaymentMade = value;
  305.                 OnPropertyChanged("IsPaymentMade");
  306.             }
  307.         }
  308.  
  309.         /// <summary>
  310.         /// Списък с ДДС групи
  311.         /// </summary>
  312.         public IEnumerable<IVatGroup> VatGroups
  313.         {
  314.             get
  315.             {
  316.                 if (vatGroups == null)
  317.                     vatGroups = this.Container.Resolve<IVatGroupsDatabaseService>().GetAll().Select((vat) => { vat.Value = Math.Round(vat.Value, 2); return vat; });
  318.                 return vatGroups;
  319.             }
  320.         }
  321.  
  322.         /// <summary>
  323.         /// Свойство за избрана ДДС група
  324.         /// </summary>
  325.         public IVatGroup SelectedVatGroup
  326.         {
  327.             get
  328.             {
  329.                 if (selectedVatGroup == null)
  330.                     selectedVatGroup = VatGroups.Where(v => v.VatGroupId == Container.Resolve<IVatGroupsDatabaseService>().GetDefaultVatGroup().VatGroupId).FirstOrDefault();
  331.  
  332.                 return selectedVatGroup;
  333.             }
  334.  
  335.             set
  336.             {
  337.                 if (selectedVatGroup == value)
  338.                     return;
  339.                 selectedVatGroup = value;
  340.                 OnPropertyChanged("SelectedVatGroup", true);
  341.             }
  342.         }
  343.  
  344.         #endregion Properties
  345.  
  346.         #region Methods
  347.  
  348.         /// <summary>
  349.         /// Метод, който оказва дали може да бъде добавена операция
  350.         /// </summary>
  351.         /// <param name="arg"></param>
  352.         /// <returns></returns>
  353.         private bool CanAddOperationDetail(object arg)
  354.         {
  355.             return OperationHelper != null && Container.Resolve<IOperationsServices>().CanAddServices(OperationHelper.State);
  356.         }
  357.  
  358.         /// <summary>
  359.         /// Добавяне на операция
  360.         /// </summary>
  361.         /// <param name="obj"></param>
  362.         private void AddOperationDetail(object obj)
  363.         {
  364.             OperationDetailBaseViewModel detailVM = null;
  365.             DateTime dtTemp = DateTime.Today;
  366.             detailVM = CreateOperationDetailViewModel(null);
  367.             detailVM.IsPaymentMade = false;
  368.             detailVM.IsCustom = true;
  369.             detailVM.Date = dtTemp;
  370.             detailVM.Quantity = 1;
  371.  
  372.             ApplyPriceRules(detailVM);
  373.             InternalOperationDetails.Add(detailVM);
  374.  
  375.             operationDetails = null;
  376.             OnPropertyChanged("OperationDetails", true);
  377.             SelectedOperationDetail = detailVM;
  378.             OperationHelper.RefreshAmount();
  379.         }
  380.  
  381.         /// <summary>
  382.         /// Метод, който оказва дали може да бъде добавена операция
  383.         /// </summary>
  384.         /// <param name="arg"></param>
  385.         /// <returns></returns>
  386.         private bool CanAddAdvance(object arg)
  387.         {
  388.             foreach (var item in OperationDetails.ToList())
  389.             {
  390.                 if (SelectedVatGroup.VatGroupId == 1)
  391.                 {
  392.                     bool isAdvanceSmallerThanCustomDetails = AdvancePayment <= OperationDetails.Where(i => !i.IsPaymentMade && i.IsCustom).Select(i => i.CurrentPrice).Sum();
  393.  
  394.                     if (!item.IsPaymentMade && AdvancePayment > 0 && isAdvanceSmallerThanCustomDetails)
  395.                     {
  396.                         return true;
  397.                     }
  398.                 }
  399.                 else
  400.                 {
  401.                     bool isAdvanceSmallerThanNotCustomDetails = AdvancePayment <= OperationDetails.Where(i => !i.IsPaymentMade && !i.IsCustom).Select(i => i.CurrentPrice).Sum();
  402.  
  403.                     if (!item.IsPaymentMade && AdvancePayment > 0 && isAdvanceSmallerThanNotCustomDetails)
  404.                     {
  405.                         return true;
  406.                     }
  407.                 }
  408.             }
  409.  
  410.             return false;
  411.         }
  412.  
  413.         /// <summary>
  414.         /// Добавяне на операция
  415.         /// </summary>
  416.         /// <param name="obj"></param>
  417.         private void AddAdvance(object obj)
  418.         {
  419.             OperationDetailBaseViewModel detailVM = null;
  420.             DateTime dtTemp = DateTime.Today;
  421.             IOperationDetail operDetail = Container.Resolve<IOperationDetail>();
  422.             detailVM = CreateOperationDetailViewModel(operDetail);
  423.             detailVM.OperationItem = this.Container.Resolve<IOperationItemsDatabaseService>().GetAllAdvances().Where(a => a.ServiceAndItem.VatGroup.VatGroupId == SelectedVatGroup.VatGroupId).FirstOrDefault();
  424.             detailVM.Description = detailVM.OperationItem == null ? Translator.GetString("strAdvancePayment") : detailVM.OperationItem.ServiceAndItem.Description;
  425.             detailVM.IsPaymentMade = false;
  426.             detailVM.IsCustom = true;
  427.             detailVM.Date = dtTemp;
  428.             detailVM.Quantity = 1;
  429.             detailVM.PriceValue = advancePayment * -1;
  430.             detailVM.CustomPrice = detailVM.PriceValue;
  431.  
  432.             ApplyPriceRules(detailVM);
  433.             InternalOperationDetails.Add(detailVM);
  434.  
  435.             AddPayment(detailVM);
  436.  
  437.             operationDetails = null;
  438.             OnPropertyChanged("OperationDetails", true);
  439.             SelectedOperationDetail = detailVM;
  440.             OperationHelper.RefreshAmount();
  441.         }
  442.  
  443.         /// <summary>
  444.         /// Добавя плащане
  445.         /// </summary>
  446.         /// <param name="detail"></param>
  447.         private void AddPayment(OperationDetailBaseViewModel detail)
  448.         {
  449.             IOperationPayment operationPayment = this.Container.Resolve<IOperationPayment>();
  450.  
  451.             operationPayment.Date = ApplicationDate.Now;
  452.             IOperationDetail operDetail = detail.OperationDetail;
  453.             if (operDetail != null)
  454.             {
  455.                 operDetail.Payments.Add(operationPayment);
  456.             }
  457.  
  458.             operationPayment.Amount = detail.PriceValue;
  459.         }
  460.  
  461.         /// <summary>
  462.         /// Метод за изтриване на операция
  463.         /// </summary>
  464.         /// <param name="o"></param>
  465.         protected virtual void DeleteOperation(object o)
  466.         {
  467.             // премахваме ViewModel-a от списъка
  468.             selectedOperationDetail.IsDeleted = true;
  469.  
  470.             // избираме предишната стая от списъка
  471.             var service = Container.Resolve<IOperationItemsDatabaseService>();
  472.             var itemToSelect = OperationDetails.FirstOrDefault(od => service.AreEqual(selectedOperationDetail.OperationItem, od.OperationItem));
  473.  
  474.             if (itemToSelect == null)
  475.                 itemToSelect = OperationDetails.FirstOrDefault(od => od.IsCustom);
  476.  
  477.             foreach (var detail in OperationDetails)
  478.                 detail.IsChanged = true;
  479.  
  480.             operationDetails = null;
  481.             OnPropertyChanged("OperationDetails", true);
  482.             SelectedOperationDetail = itemToSelect;
  483.             OperationHelper.RefreshAmount();
  484.         }
  485.  
  486.         /// <summary>
  487.         /// Прихваща добавяне на операция от склад про
  488.         /// </summary>
  489.         /// <param name="obj"></param>
  490.         private void OnOperationChanged(object obj)
  491.         {
  492.             IOperationDetail item = obj as IOperationDetail;
  493.  
  494.             OperationDetailBaseViewModel detailVM = null;
  495.             detailVM = CreateOperationDetailViewModel(item);
  496.             detailVM.IsCustom = true;
  497.             detailVM.Date = item.Date;
  498.             detailVM.Quantity = 1;
  499.             detailVM.PriceValue = item.Price;
  500.             detailVM.CustomDescription = item.CustomDescription;
  501.  
  502.             ApplyPriceRules(detailVM);
  503.  
  504.             InternalOperationDetails.Add(detailVM);
  505.  
  506.             OnPropertyChanged("OperationDetails");
  507.  
  508.             OperationHelper.RefreshAmount();
  509.         }
  510.  
  511.         /// <summary>
  512.         /// Метод, който създава ViewModel за детайл
  513.         /// </summary>
  514.         /// <param name="detail"></param>
  515.         /// <returns></returns>
  516.         protected virtual OperationDetailBaseViewModel CreateOperationDetailViewModel(IOperationDetail detail)
  517.         {
  518.             return new OperationDetailBaseViewModel(Container, detail, OperationHelper);
  519.         }
  520.  
  521.         /// <summary>
  522.         /// Метод, който инициализира детайлите на операцията
  523.         /// </summary>
  524.         /// <param name="customers"></param>
  525.         /// <param name="children"></param>
  526.         /// <param name="onLoad"></param>
  527.         /// <param name="operationState"></param>
  528.         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Justification = "Complexity - нужда от refactoring")]
  529.         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Complexity - нужда от refactoring")]
  530.         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Complexity - нужда от refactoring")]
  531.         public void InitOperationDetails(IEnumerable<ICustomer> customers, IEnumerable<ICustomer> children = null, bool onLoad = false, OperationStateType operationState = OperationStateType.Default)
  532.         {
  533.             // пач
  534.             bool flag = true;
  535.             //// Изчистваме детайли ако има въведени
  536.             foreach (OperationDetailBaseViewModel item in OperationHelper.OperationDetailsViewModel.OperationDetails)
  537.             {
  538.                 if (!OperationHelper.IsNew)
  539.                     flag = OperationHelper.State == OperationStateType.Reservation
  540.                         || OperationHelper.State == OperationStateType.Active
  541.                         || OperationHelper.State == OperationStateType.AutoReservation
  542.                         || item.Date.Date >= DateTime.Now.Date;
  543.  
  544.                 if (flag)
  545.                 {
  546.                     if (!item.IsCustom)
  547.                     {
  548.                         item.IsDeleted = true;
  549.                         continue;
  550.                     }
  551.                     else
  552.                     {
  553.                         if (item.PriceValue > 0)
  554.                         {
  555.                             if (item.OperationDetail != null)
  556.                                 item.AmountLeftToPay = (item.CurrentPrice * item.Quantity) - item.OperationDetail.Payments.Sum(payment => payment.Amount);
  557.                             else
  558.                                 item.AmountLeftToPay = item.CurrentPrice * item.Quantity;
  559.                         }
  560.                     }
  561.                 }
  562.             }
  563.  
  564.             DateTime dtTemp = OperationHelper.FromDate;
  565.  
  566.             if (!OperationHelper.IsNew && !(OperationHelper.State == OperationStateType.Reservation
  567.                 || OperationHelper.State == OperationStateType.AutoReservation
  568.                 || OperationHelper.State == OperationStateType.Active))
  569.             {
  570.                 if (dtTemp.Date <= ApplicationDate.Now && OperationHelper.IsInEditMode)
  571.                     dtTemp = ApplicationDate.Now;
  572.             }
  573.  
  574.             IOperationsDatabaseService operationService = Container.Resolve<IOperationsDatabaseService>();
  575.  
  576.             do
  577.             {
  578.                 IOperationDetail detail = Container.Resolve<IOperationDetail>();
  579.  
  580.                 if (OperationHelper.Operation != null && OperationHelper.Operation.Details != null)
  581.                 {
  582.                     IEnumerable<IOperationDetail> details = operationService.GetContextOperation(OperationHelper.Operation).Details.Where(d => d.OperationItem.OperationItemId == OperationHelper.OperationItem.OperationItemId && d.Date == dtTemp && d.IsDeleted == false);
  583.                     if (details.Count() == 0)
  584.                         details = operationService.GetContextOperation(OperationHelper.Operation).Details.Where(d => d.OperationItem.ServiceAndItem.EnumServicesAndItemsType == OperationHelper.OperationItem.ServiceAndItem.EnumServicesAndItemsType && d.Date == dtTemp && d.IsDeleted == false);
  585.                     detail = details.LastOrDefault(d => d.Payments.Count != 0) ?? details.LastOrDefault();
  586.                 }
  587.  
  588.                 OperationDetailBaseViewModel detailVM = CreateOperationDetailViewModel(detail);
  589.                 detailVM.OperationItem = OperationHelper.OperationItem;
  590.  
  591.                 if (OperationHelper.Pricelist != null)
  592.                     detailVM.Package = OperationHelper.Pricelist.Package;
  593.                 detailVM.IsDeleted = false;
  594.                 detailVM.Date = dtTemp;
  595.                 detailVM.Quantity = 1;
  596.  
  597.                 if (OperationHelper.OperationItem == null)
  598.                     detailVM.Description = string.Empty;
  599.                 else
  600.                     detailVM.Description = OperationHelper.OperationItem.ServiceAndItem.Description;
  601.  
  602.                 if (customers != null)
  603.                 {
  604.                     if (!onLoad)
  605.                     {
  606.                         if (detailVM.Date.Date >= ApplicationDate.Now.Date)
  607.                         {
  608.                             foreach (var customer in detailVM.InternalCustomers.Where(c => !c.Customer.IsChild))
  609.                                 customer.IsDeleted = true;
  610.  
  611.                             foreach (var customer in customers)
  612.                                 detailVM.OnCustomerChange(customer, true);
  613.                         }
  614.                     }
  615.                 }
  616.  
  617.                 if (children != null)
  618.                 {
  619.                     if (!onLoad)
  620.                     {
  621.                         if (detailVM.Date.Date >= ApplicationDate.Now.Date)
  622.                         {
  623.                             foreach (var customer in detailVM.InternalCustomers.Where(c => c.Customer.IsChild))
  624.                                 customer.IsDeleted = true;
  625.  
  626.                             foreach (var child in children)
  627.                                 detailVM.OnCustomerChange(child, true);
  628.                         }
  629.                     }
  630.                 }
  631.  
  632.                 detailVM.PriceValue = PriceService.CalculateAccommodationPrice(dtTemp, detailVM.OperationItem, OperationHelper.Pricelist, detailVM.Customers.Select(c => c.Customer));
  633.  
  634.                 if (detailVM != null && detailVM.PriceRules != null)
  635.                 {
  636.                     //// Добавяме ценови правила
  637.                     ApplyPriceRules(detailVM);
  638.                 }
  639.  
  640.                 if (detailVM.OperationDetail != null)
  641.                 {
  642.                     detailVM.AmountLeftToPay = (detailVM.CurrentPrice * detailVM.Quantity) - detailVM.OperationDetail.Payments.Sum(s => s.Amount);
  643.                 }
  644.  
  645.                 if (detail != null)
  646.                     detailVM.IsPaymentMade = (detailVM.PriceValue * detailVM.Quantity) - detail.Payments.Sum(s => s.Amount) == 0;
  647.                 InternalOperationDetails.Add(detailVM);
  648.  
  649.                 //// Loop
  650.                 dtTemp = dtTemp.AddDays(1);
  651.                 detailVM.IsChanged = false;
  652.             }
  653.             while (operationState == OperationStateType.End ? dtTemp.Date < ApplicationDate.Now.Date : dtTemp.Date < OperationHelper.ToDate.Date);
  654.  
  655.             OnPropertyChanged("OperationDetails", true);
  656.             OnPropertyChanged("InternalOperationDetails");
  657.             OnPropertyChanged("Balance");
  658.  
  659.             if (OperationHelper.Package != null)
  660.                 ReinitMealsFromPackage(onLoad);
  661.         }
  662.  
  663.         /// <summary>
  664.         /// Метод за обновяване на добавените услуги при смяна на избран пакет
  665.         /// </summary>
  666.         /// <param name="oldPackage"></param>
  667.         /// <param name="newPackage"></param>
  668.         public void InitOperationDetailsFromPackage(IPackage oldPackage, IPackage newPackage)
  669.         {
  670.             foreach (var item in OperationHelper.OperationDetailsViewModel.OperationDetails)
  671.             {
  672.                 if (oldPackage != null && item.Package != null && item.Package.PackageId == oldPackage.PackageId)
  673.                 {
  674.                     item.IsDeleted = true;
  675.                 }
  676.             }
  677.  
  678.             if (newPackage != null)
  679.             {
  680.                 foreach (var detail in newPackage.Items.Where(i => !i.ServiceAndItem.IsDeleted))
  681.                 {
  682.                     if (detail.ServiceAndItem.EnumServicesAndItemsType.Type == ServiceAndItemGroupTypes.Meals)
  683.                     {
  684.                         AddMealsFromPackage(detail, newPackage);
  685.                     }
  686.                     else
  687.                     {
  688.                         var detailVM = CreateOperationDetailViewModel(null);
  689.  
  690.                         detailVM.IsCustom = true;
  691.                         detailVM.OperationItem = detail;
  692.                         detailVM.IsFromPackage = true;
  693.                         detailVM.Package = newPackage;
  694.                         detailVM.Date = DateTime.Now;
  695.                         detailVM.Quantity = 1;
  696.                         detailVM.PriceValue = 0;
  697.                         detailVM.Description = detail.ServiceAndItem.Description;
  698.  
  699.                         InternalOperationDetails.Add(detailVM);
  700.                     }
  701.                 }
  702.             }
  703.  
  704.             OnPropertyChanged("OperationDetails");
  705.             OnPropertyChanged("Balance");
  706.         }
  707.  
  708.         #region Meals Initialization && Cache
  709.  
  710.         /// <summary>
  711.         /// Метод за добавяне на услугите за пансион от пакета
  712.         /// </summary>
  713.         /// <param name="detail"></param>
  714.         /// <param name="package"></param>
  715.         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Refactor")]
  716.         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Refactor")]
  717.         private void AddMealsFromPackage(IOperationItem detail, IPackage package)
  718.         {
  719.             accomodatedCustomers.Clear();
  720.  
  721.             foreach (DateTime date in customersOvernightsCacheService.CustomerOvernightsCache.Keys)
  722.             {
  723.                 if (date > OperationHelper.ToDate)
  724.                     break;
  725.  
  726.                 if (detail.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Dinner
  727.                      && date.Date == OperationHelper.ToDate.Date)
  728.                     break;
  729.  
  730.                 int childAccomodatedWithoutAgeGroupInThePackage = CalculateChildsOutOfAgeGroupsInThePackage(customersOvernightsCacheService.CustomerOvernightsCache[date], package);
  731.  
  732.                 int newAccomodatedChildCount = 0;
  733.                 int newAccomodatedAdultsCount = 0;
  734.  
  735.                 if (detail.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast && !customersOvernightsCacheService.CustomerOvernightsCache[date].All(cust => accomodatedCustomers.Contains(cust)))
  736.                 {
  737.                     //// Проверяваме за новонастанени
  738.                     if (detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null && customersOvernightsCacheService.CustomerOvernightsCache[date].Any(d => d.Age != null))
  739.                     {
  740.                         newAccomodatedChildCount = customersOvernightsCacheService.CustomerOvernightsCache[date].Count(cust => cust.IsChild && cust.Age.Value >= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.FromAge &&
  741.                                                    cust.Age.Value <= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.ToAge && !accomodatedCustomers.Contains(cust)) - childAccomodatedWithoutAgeGroupInThePackage;
  742.                     }
  743.  
  744.                     newAccomodatedAdultsCount = customersOvernightsCacheService.CustomerOvernightsCache[date].Count(cust => !cust.IsChild && !accomodatedCustomers.Contains(cust)) + childAccomodatedWithoutAgeGroupInThePackage;
  745.                     foreach (ICustomer customer in customersOvernightsCacheService.CustomerOvernightsCache[date])
  746.                         accomodatedCustomers.Add(customer);
  747.                 }
  748.  
  749.                 OperationDetailBaseViewModel detailMealVM = CreateOperationDetailViewModel(null);
  750.                 if (detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup == null)
  751.                 {
  752.                     detailMealVM.IsCustom = true;
  753.                     detailMealVM.OperationItem = detail;
  754.                     detailMealVM.IsFromPackage = true;
  755.                     detailMealVM.Package = package;
  756.                     detailMealVM.Quantity = customersOvernightsCacheService.CustomerOvernightsCache[date].Count(c => !c.IsChild && !c.IsDeleted) + childAccomodatedWithoutAgeGroupInThePackage - newAccomodatedAdultsCount;
  757.                     detailMealVM.PriceValue = 0;
  758.                     detailMealVM.Description = detail.ServiceAndItem.Description;
  759.                     detailMealVM.Date = date;
  760.                 }
  761.                 else
  762.                 {
  763.                     int childsCount = customersOvernightsCacheService.CustomerOvernightsCache[date].Count(c => c.IsChild && c.Age.HasValue
  764.                                 && detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null
  765.                                 && c.Age >= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.FromAge
  766.                                 && c.Age <= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.ToAge);
  767.  
  768.                     if (childsCount > 0)
  769.                     {
  770.                         OperationDetailBaseViewModel detailMealVMChild = CreateOperationDetailViewModel(null);
  771.                         detailMealVMChild.IsCustom = true;
  772.                         detailMealVMChild.OperationItem = detail;
  773.                         detailMealVMChild.IsFromPackage = true;
  774.                         detailMealVMChild.Package = package;
  775.                         detailMealVMChild.PriceValue = 0;
  776.                         detailMealVMChild.Description = detail.ServiceAndItem.Description;
  777.                         detailMealVMChild.Date = date;
  778.                         detailMealVMChild.Quantity = childsCount - newAccomodatedChildCount;
  779.  
  780.                         OperationDetailBaseViewModel detailToCheckChild = internalOperationDetails.FirstOrDefault(d => d.OperationItem == detailMealVMChild.OperationItem && !d.IsDeleted && d.Date.Date == detailMealVMChild.Date.Date &&
  781.                         d.OperationItem.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null);
  782.                         if (detailToCheckChild != null)
  783.                         {
  784.                             internalOperationDetails.FirstOrDefault(d => d.OperationItem == detailMealVMChild.OperationItem && !d.IsDeleted && d.Date.Date == detailMealVMChild.Date.Date && d.OperationItem.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null).Quantity++;
  785.                         }
  786.                         else if (detailMealVMChild.Quantity > 0)
  787.                             internalOperationDetails.Add(detailMealVMChild);
  788.                     }
  789.                 }
  790.  
  791.                 OperationDetailBaseViewModel detailToCheck = internalOperationDetails.FirstOrDefault(d => d.OperationItem == detailMealVM.OperationItem && !d.IsDeleted && d.Date.Date == detailMealVM.Date.Date);
  792.                 if (detailToCheck != null)
  793.                 {
  794.                     internalOperationDetails.FirstOrDefault(d => d.OperationItem == detailMealVM.OperationItem && !d.IsDeleted && d.Date.Date == detailMealVM.Date.Date).Quantity++;
  795.                 }
  796.                 else if (detailMealVM.Quantity > 0)
  797.                 {
  798.                     internalOperationDetails.Add(detailMealVM);
  799.                 }
  800.  
  801.  
  802.                 if (detail.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast)
  803.                 {
  804.                     IEnumerable<ICustomer> lastDayStand;
  805.                     if (customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(date.AddDays(1)))
  806.                         lastDayStand = customersOvernightsCacheService.CustomerOvernightsCache[date].Where(customer => !customersOvernightsCacheService.CustomerOvernightsCache[date.AddDays(1)].Contains(customer));
  807.                     else
  808.                         lastDayStand = customersOvernightsCacheService.CustomerOvernightsCache[date];
  809.  
  810.                     if (lastDayStand != null && lastDayStand.Count() != 0)
  811.                         AddLastDayBreakfastForLeavingGuests(detail, package, date.AddDays(1), lastDayStand.Where(customer => !customer.IsChild && !customer.IsDeleted).Count(), childAccomodatedWithoutAgeGroupInThePackage);
  812.                 }
  813.             }
  814.  
  815.             OnPropertyChanged("InternalOperationDetails", true);
  816.         }
  817.  
  818.         /// <summary>
  819.         /// Метод който изчислява колко деца са извън възрастовите групи зададени за текущия пакет
  820.         /// </summary>
  821.         /// <param name="customers"></param>
  822.         /// <param name="package"></param>
  823.         /// <returns></returns>
  824.         private int CalculateChildsOutOfAgeGroupsInThePackage(IEnumerable<ICustomer> customers, IPackage package)
  825.         {
  826.             decimal maxAgeDeclaregInAgeGroupsInPackag = 0;
  827.             decimal minAgeDeclaregInAgeGroupsInPackag = 0;
  828.  
  829.             if (package.Items.Any(item => item.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null))
  830.             {
  831.                 maxAgeDeclaregInAgeGroupsInPackag = package.Items.Where(item => item.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null)
  832.                                                                      .Max(item => item.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.ToAge);
  833.                 minAgeDeclaregInAgeGroupsInPackag = package.Items.Where(item => item.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null)
  834.                                                                      .Min(item => item.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.FromAge);
  835.             }
  836.  
  837.             int childsCount = customers.Where(customer => customer.IsChild && !customer.IsDeleted)
  838.                                        .Count(customer => (customer.Age.HasValue && customer.Age.Value > maxAgeDeclaregInAgeGroupsInPackag)
  839.                                                           || (customer.Age.HasValue && customer.Age.Value < minAgeDeclaregInAgeGroupsInPackag)
  840.                                                           || CalculateAge(customer) == null
  841.                                                           || CalculateAge(customer) > maxAgeDeclaregInAgeGroupsInPackag
  842.                                                           || CalculateAge(customer) < minAgeDeclaregInAgeGroupsInPackag);
  843.             return childsCount;
  844.         }
  845.  
  846.         /// <summary>
  847.         /// Метод който изцислява на колко години е дад. дете
  848.         /// </summary>
  849.         /// <param name="customer"></param>
  850.         /// <returns></returns>
  851.         private decimal? CalculateAge(ICustomer customer)
  852.         {
  853.             decimal? age = customer.Age;
  854.             if (customer.Birthdate.HasValue)
  855.             {
  856.                 age = DateTime.Today.Year - customer.Birthdate.Value.Year;
  857.                 if (customer.Birthdate.Value.Date > DateTime.Today.AddYears((int)-age))
  858.                     age--;
  859.             }
  860.  
  861.             return age;
  862.         }
  863.  
  864.         /// <summary>
  865.         /// Добавя закуски в последния ден на резервцията
  866.         /// </summary>
  867.         /// <param name="detail"></param>
  868.         /// <param name="package"></param>
  869.         /// <param name="date"></param>
  870.         /// <param name="adultsCount"></param>
  871.         /// <param name="childAccomodatedWithoutAgeGroupInThePackage"></param>
  872.         private void AddLastDayBreakfastForLeavingGuests(IOperationItem detail, IPackage package, DateTime date, int adultsCount, int childAccomodatedWithoutAgeGroupInThePackage = 0)
  873.         {
  874.             OperationDetailBaseViewModel detailMealVM = CreateOperationDetailViewModel(null);
  875.             if (detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup == null)
  876.             {
  877.                 detailMealVM.IsCustom = true;
  878.                 detailMealVM.OperationItem = detail;
  879.                 detailMealVM.IsFromPackage = true;
  880.                 detailMealVM.Package = package;
  881.                 detailMealVM.Quantity = adultsCount + childAccomodatedWithoutAgeGroupInThePackage;
  882.                 detailMealVM.PriceValue = 0;
  883.                 detailMealVM.Description = detail.ServiceAndItem.Description;
  884.                 detailMealVM.Date = date;
  885.                 internalOperationDetails.Add(detailMealVM);
  886.             }
  887.             else
  888.             {
  889.                 int childrenCount = 0;
  890.                 if (customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(date.AddDays(-1)))
  891.                     childrenCount = customersOvernightsCacheService.CustomerOvernightsCache[date.AddDays(-1)].Count(c => c.IsChild && c.Age.HasValue
  892.                                         && detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null
  893.                                         && c.Age >= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.FromAge
  894.                                         && c.Age <= detail.ServiceAndItem.EnumServicesAndItemsType.AgeGroup.ToAge);
  895.  
  896.                 if (childrenCount != 0)
  897.                 {
  898.                     var detailMealVMChild = CreateOperationDetailViewModel(null);
  899.  
  900.                     detailMealVMChild.IsCustom = true;
  901.                     detailMealVMChild.OperationItem = detail;
  902.                     detailMealVMChild.IsFromPackage = true;
  903.                     detailMealVMChild.Package = package;
  904.                     detailMealVMChild.Quantity = childrenCount;
  905.                     detailMealVMChild.PriceValue = 0;
  906.                     detailMealVMChild.Description = detail.ServiceAndItem.Description;
  907.                     detailMealVMChild.Date = date;
  908.                     internalOperationDetails.Add(detailMealVMChild);
  909.                 }
  910.             }
  911.         }
  912.  
  913.         #endregion
  914.  
  915.         /// <summary>
  916.         /// Метод за реинициализация на пансиона
  917.         /// </summary>
  918.         /// <param name="onLoad"></param>
  919.         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Refactor")]
  920.         public void ReinitMealsFromPackage(bool onLoad = false)
  921.         {
  922.             foreach (var detail in InternalOperationDetails.Where(d => !d.IsDeleted && d.IsCustom && d.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Type == ServiceAndItemGroupTypes.Meals))
  923.             {
  924.                 if (detail.Date.Date >= ApplicationDate.Now.Date)
  925.                 {
  926.                     DateTime tempDate = customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(detail.Date.Date) ? detail.Date.Date : detail.Date.Date.AddDays(-1);
  927.                     IAgeGroup ageGroup = null;
  928.                     int currentDayCustomersCount = 0;
  929.                     int previousDayCustomersCount = 0;
  930.  
  931.                     if (detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.AgeGroup != null && customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(tempDate))
  932.                     {
  933.                         ageGroup = detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.AgeGroup;
  934.                         currentDayCustomersCount = customersOvernightsCacheService.CustomerOvernightsCache[tempDate].Count(a => (a.IsChild && a.Age.HasValue && a.Age >= ageGroup.FromAge && a.Age <= ageGroup.ToAge)
  935.                                                                                                                    || (a.Age == null && a.IsChild && (CalculateAge(a) >= ageGroup.FromAge
  936.                                                                                                                    || CalculateAge(a) <= ageGroup.FromAge)));
  937.                         previousDayCustomersCount = !customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(tempDate.AddDays(-1)) ?
  938.                            0 : customersOvernightsCacheService.CustomerOvernightsCache[tempDate.AddDays(-1)].Count(a => (a.IsChild && a.Age.HasValue && a.Age >= ageGroup.FromAge && a.Age <= ageGroup.ToAge)
  939.                                                                                                                    || (a.Age == null && a.IsChild && (CalculateAge(a) >= ageGroup.FromAge
  940.                                                                                                                    || CalculateAge(a) <= ageGroup.FromAge)));
  941.                         if (detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast && currentDayCustomersCount > previousDayCustomersCount)
  942.                             detail.Quantity = currentDayCustomersCount - previousDayCustomersCount;
  943.                         else if ((detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast || detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Lunch)
  944.                             && currentDayCustomersCount < previousDayCustomersCount)
  945.                             detail.Quantity = customersOvernightsCacheService.CustomerOvernightsCache[detail.Date.AddDays(-1)].Count(p => p.IsChild);
  946.                         else
  947.                             detail.Quantity = currentDayCustomersCount;
  948.                     }
  949.                     else if (customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(tempDate))
  950.                     {
  951.                         currentDayCustomersCount = customersOvernightsCacheService.CustomerOvernightsCache[tempDate].Count(a => !a.IsChild);
  952.                         previousDayCustomersCount = !customersOvernightsCacheService.CustomerOvernightsCache.ContainsKey(tempDate.AddDays(-1)) ?
  953.                            0 : customersOvernightsCacheService.CustomerOvernightsCache[tempDate.AddDays(-1)].Count(a => !a.IsChild);
  954.  
  955.                         if (detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast && currentDayCustomersCount > previousDayCustomersCount)
  956.                             detail.Quantity = currentDayCustomersCount - previousDayCustomersCount;
  957.                         else if ((detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Breakfast || detail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Identifier == ServicesAndItemsType.Lunch)
  958.                             && currentDayCustomersCount < previousDayCustomersCount)
  959.                             detail.Quantity = customersOvernightsCacheService.CustomerOvernightsCache[detail.Date.AddDays(-1)].Count(p => !p.IsChild);
  960.                         else
  961.                             detail.Quantity = currentDayCustomersCount;
  962.                     }
  963.  
  964.                     if (onLoad)
  965.                         detail.IsChanged = false;
  966.                 }
  967.             }
  968.  
  969.             OnPropertyChanged("InternalOperationDetails");
  970.         }
  971.  
  972.         /// <summary>
  973.         /// Метод, който прилага ценовите правила към детайла на операцията
  974.         /// </summary>
  975.         /// <param name="detailVM"></param>
  976.         private void ApplyPriceRules(OperationDetailBaseViewModel detailVM)
  977.         {
  978.             if (detailVM == null)
  979.                 return;
  980.  
  981.             detailVM.PriceRules.Clear();
  982.             var dict = detailVM.GetPriceRuleValues();
  983.             OperatorSymbolsBase expressionSymbols = new OperatorSymbolsBase();
  984.  
  985.             IExpressionContext context = Container.Resolve<IExpressionContext>();
  986.             foreach (var kvp in dict)
  987.                 context.AddVariable(kvp.Key, kvp.Value);
  988.  
  989.             foreach (IPriceRule priceRule in Container.Resolve<IPriceRulesDatabaseService>().GetPriceRules().Where(pr => pr.Status))
  990.             {
  991.                 // Добавяме параметрите на ценовото правило
  992.                 foreach (var par in priceRule.Parameters)
  993.                     context.AddVariable(par.Identifier, par.Value);
  994.  
  995.                 if (priceRule.ActionIdentifier != "SendEmail")
  996.                 {
  997.                     var tree = RpnParser.CreateExpressionTree(expressionSymbols, priceRule.Script);
  998.                     var value = tree.CalculateValue(context);
  999.  
  1000.                     if (value.GetType() == typeof(bool) && (bool)value)
  1001.                     {
  1002.                         detailVM.AddPriceRule(priceRule);
  1003.                     }
  1004.                 }
  1005.             }
  1006.         }
  1007.  
  1008.         /// <summary>
  1009.         /// Метод, който променя ползвана стока/услуга за всички детайли
  1010.         /// </summary>
  1011.         /// <param name="newOperationItem"></param>
  1012.         public void OnOperationItemChange(IOperationItem newOperationItem)
  1013.         {
  1014.             foreach (var item in OperationHelper.GetOperationItemRelatedDetails())
  1015.                 item.OperationItem = newOperationItem;
  1016.  
  1017.             IsChanged = true;
  1018.         }
  1019.  
  1020.         /// <summary>
  1021.         /// Метод, който променя списък с клиенти към детайлите на операция
  1022.         /// </summary>
  1023.         /// <param name="customer"></param>
  1024.         /// <param name="isAdded">Флаг, дали е добавен или изтрит. True ако е добавен, иначе False. </param>
  1025.         /// <param name="oldCustomer"></param>
  1026.         internal void OnCustomerChange(ICustomer customer, bool isAdded, ICustomer oldCustomer = null)
  1027.         {
  1028.             foreach (var item in InternalOperationDetails.Where(d => !d.IsDeleted && d.OperationItem != null && d.OperationItem.ServiceAndItem.Identifier == ServiceAndItemsType.Room))
  1029.             {
  1030.                 if (!OperationHelper.IsNew && OperationHelper.State == OperationStateType.Active && item.Date.Date < ApplicationDate.Now)
  1031.                     continue;
  1032.  
  1033.                 item.OnCustomerChange(customer, isAdded, oldCustomer);
  1034.                 //// От тук само добавя клиенти !!!!
  1035.                 Container.Resolve<IEventAggregator>().GetEvent<CustomersAccomodationChangedEvent>()
  1036.                         .Publish(new AccomodationChangedEventArgs<ICustomer>(isAdded, item.Date, customer));
  1037.  
  1038.                 if (!item.IsFromPackage)
  1039.                     item.PriceValue = PriceService.CalculateAccommodationPrice(item.Date, item.OperationItem, OperationHelper.Pricelist, item.Customers.Select(c => c.Customer), item.CurrentPrice);
  1040.             }
  1041.  
  1042.             if (OperationHelper.Package != null)
  1043.                 ReinitMealsFromPackage();
  1044.         }
  1045.  
  1046.         /// <summary>
  1047.         /// Метод, който запазва данните в базата
  1048.         /// </summary>
  1049.         /// <param name="dbService"></param>
  1050.         public void Save(IOperationsDatabaseService dbService)
  1051.         {
  1052.             if (!IsChanged)
  1053.                 return;
  1054.  
  1055.             var enumServicesDatabaseServise = Container.Resolve<IEnumServiceAndItemTypesDatabaseService>();
  1056.  
  1057.             foreach (var operationDetail in InternalOperationDetails)
  1058.             {
  1059.                 //// Пач
  1060.                 if (operationDetail.Date == DateTime.MinValue.Date)
  1061.                     continue;
  1062.                 if (!operationDetail.IsDeleted)
  1063.                 {
  1064.                     bool isnew = operationDetail.OperationItem.ServiceAndItem.Identifier == ServiceAndItemsType.Room;
  1065.                     if (isnew && operationDetail.OperationDetail != null)
  1066.                     {
  1067.                         operationDetail.OperationDetail.IsDeleted = true;
  1068.                     }
  1069.  
  1070.                     if (operationDetail.OperationItem.ServiceAndItem.EnumServicesAndItemsType != null
  1071.                         && operationDetail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.Type ==
  1072.                         ServiceAndItemGroupTypes.Custom
  1073.                         && !operationDetail.OperationItem.ServiceAndItem.EnumServicesAndItemsType.IsUsed)
  1074.                     {
  1075.                         var service = enumServicesDatabaseServise.GetAllTypes().FirstOrDefault(s =>
  1076.                             s.EnumServicesAndItemsTypeId == operationDetail.OperationItem.ServiceAndItem
  1077.                                 .EnumServicesAndItemsType.EnumServicesAndItemsTypeId);
  1078.                         service.IsUsed = true;
  1079.                     }
  1080.  
  1081.                     operationDetail.Save(dbService, isnew);
  1082.                 }
  1083.                 else if (!OperationHelper.IsNew && !operationDetail.IsNew)
  1084.                 {
  1085.                     dbService.RemoveOperationDetail(operationDetail.OperationDetail);
  1086.                 }
  1087.             }
  1088.  
  1089.             enumServicesDatabaseServise.SaveChanges();
  1090.             this.Container.Resolve<IEventAggregator>().GetEvent<OperationDetailsChangedEvent>().Publish(this.InternalOperationDetails);
  1091.         }
  1092.  
  1093.         /// <summary>
  1094.         /// Метод за валидация на въведените данни
  1095.         /// </summary>
  1096.         /// <returns></returns>
  1097.         public virtual List<ValidationResult> Validate()
  1098.         {
  1099.             List<ValidationResult> res = new List<ValidationResult>();
  1100.             ValidationResult tmpRes;
  1101.  
  1102.             foreach (var item in OperationDetails)
  1103.             {
  1104.                 tmpRes = item.ValidateOperationDetail();
  1105.                 if (tmpRes.ErrorLevel != ErrorLevel.NoError)
  1106.                     res.Add(tmpRes);
  1107.             }
  1108.  
  1109.             return res;
  1110.         }
  1111.  
  1112.         /// <summary>
  1113.         /// Опреснява командата за плащане
  1114.         /// </summary>
  1115.         public void RefreshPaymentCommand()
  1116.         {
  1117.             foreach (var detail in OperationDetails.ToList())
  1118.             {
  1119.                 detail.EditPaymentsCommand.RaiseCanExecuteChanged();
  1120.             }
  1121.         }
  1122.  
  1123.         #endregion Methods
  1124.     }
  1125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement