Просмотр исходного кода

Darstellung der TreeList für Baustellen-Nachträge und -Vertragsabweichungen fast fertiggestellt!

Arne Diekmann 8 лет назад
Родитель
Сommit
02a68f28cb
29 измененных файлов с 1119 добавлено и 318 удалено
  1. 25 10
      GreenTree.Nachtragsmanagement.Core/Domain/Appendix/Appendix.cs
  2. 26 0
      GreenTree.Nachtragsmanagement.Core/Domain/Appendix/CategoryValue.cs
  3. 16 0
      GreenTree.Nachtragsmanagement.Core/Domain/Appendix/State.cs
  4. 7 20
      GreenTree.Nachtragsmanagement.Core/Domain/Deviation/Deviation.cs
  5. 26 0
      GreenTree.Nachtragsmanagement.Core/Domain/Deviation/DisturbanceValue.cs
  6. 3 0
      GreenTree.Nachtragsmanagement.Core/GreenTree.Nachtragsmanagement.Core.csproj
  7. 4 0
      GreenTree.Nachtragsmanagement.Data/AppendixObjectContext.cs
  8. 3 0
      GreenTree.Nachtragsmanagement.Data/GreenTree.Nachtragsmanagement.Data.csproj
  9. 8 3
      GreenTree.Nachtragsmanagement.Data/Mapping/Appendix/AppendixMap.cs
  10. 25 0
      GreenTree.Nachtragsmanagement.Data/Mapping/Appendix/CategoryValueMap.cs
  11. 21 0
      GreenTree.Nachtragsmanagement.Data/Mapping/Appendix/StateMap.cs
  12. 3 3
      GreenTree.Nachtragsmanagement.Data/Mapping/Deviation/DeviationMap.cs
  13. 25 0
      GreenTree.Nachtragsmanagement.Data/Mapping/Deviation/DisturbanceValueMap.cs
  14. 62 1
      GreenTree.Nachtragsmanagement.Services/Appendix/AppendixService.cs
  15. 39 1
      GreenTree.Nachtragsmanagement.Services/Appendix/IAppendixService.cs
  16. 1 1
      GreenTree.Nachtragsmanagement.Web/Controllers/AppendixController.cs
  17. 2 2
      GreenTree.Nachtragsmanagement.Web/Controllers/DeviationController.cs
  18. 23 0
      GreenTree.Nachtragsmanagement.Web/Controllers/SiteController.cs
  19. 496 113
      GreenTree.Nachtragsmanagement.Web/Global.asax.cs
  20. 3 0
      GreenTree.Nachtragsmanagement.Web/GreenTree.Nachtragsmanagement.Web.csproj
  21. 11 9
      GreenTree.Nachtragsmanagement.Web/Models/Appendix/AppendixDataModel.cs
  22. 6 4
      GreenTree.Nachtragsmanagement.Web/Models/Deviation/DeviationDataModel.cs
  23. 3 2
      GreenTree.Nachtragsmanagement.Web/Models/Site/SiteDataModel.cs
  24. 153 0
      GreenTree.Nachtragsmanagement.Web/Models/Site/SiteTreeDataModel.cs
  25. 4 2
      GreenTree.Nachtragsmanagement.Web/Views/Shared/_FunctionLayout.cshtml
  26. 4 2
      GreenTree.Nachtragsmanagement.Web/Views/Shared/_Layout.cshtml
  27. 20 144
      GreenTree.Nachtragsmanagement.Web/Views/Sites/_SiteEditPartial.cshtml
  28. 99 0
      GreenTree.Nachtragsmanagement.Web/Views/Sites/_SiteEditTreePartial.cshtml
  29. 1 1
      GreenTree.Nachtragsmanagement.Web/Views/Sites/_SiteGridPartial.cshtml

+ 25 - 10
GreenTree.Nachtragsmanagement.Core/Domain/Appendix/Appendix.cs

@@ -11,9 +11,9 @@ namespace GreenTree.Nachtragsmanagement.Core.Domain.Appendix
         #region Fields
 
         /// <summary>
-        /// Categories related to the appendix
+        /// Categories values related to the appendix
         /// </summary>
-        private ICollection<Category> _categories;
+        private ICollection<CategoryValue> _categoryValues;
 
         /// <summary>
         /// Deviations related to the appendix
@@ -35,7 +35,7 @@ namespace GreenTree.Nachtragsmanagement.Core.Domain.Appendix
         /// <summary>
         /// The lot
         /// </summary>
-        public string Lot { get; set; }
+        public string Description { get; set; }
 
         /// <summary>
         /// Monetary value of all corresponding deviations
@@ -55,12 +55,12 @@ namespace GreenTree.Nachtragsmanagement.Core.Domain.Appendix
         /// <summary>
         /// Date when corresponding offer was created
         /// </summary>
-        public DateTime OfferingDate { get; set; }
+        public DateTime? OfferingDate { get; set; }
 
         /// <summary>
         /// Date of negotiation
         /// </summary>
-        public DateTime NegotiationDate { get; set; }
+        public DateTime? NegotiationDate { get; set; }
 
         /// <summary>
         /// Value of negotiation
@@ -72,6 +72,11 @@ namespace GreenTree.Nachtragsmanagement.Core.Domain.Appendix
         /// </summary>
         public bool ProtocolExists { get; set; }
 
+        /// <summary>
+        /// Determines if an order invoice has been created
+        /// </summary>
+        public bool OrderInvoiceCreated { get; set; }
+
         /// <summary>
         /// Number of the corresponding order
         /// </summary>
@@ -80,13 +85,23 @@ namespace GreenTree.Nachtragsmanagement.Core.Domain.Appendix
         /// <summary>
         /// Date of the corresponding order
         /// </summary>
-        public DateTime OrderDate { get; set; }
+        public DateTime? OrderDate { get; set; }
 
         /// <summary>
         /// Editable comment
         /// </summary>
         public string Comment { get; set; }
 
+        /// <summary>
+        /// Id of corresponding state
+        /// </summary>
+        public int? StateId { get; set; }
+
+        /// <summary>
+        /// Corresponding site
+        /// </summary>
+        public State State { get; set; }
+
         /// <summary>
         /// Id of corresponding site
         /// </summary>
@@ -98,12 +113,12 @@ namespace GreenTree.Nachtragsmanagement.Core.Domain.Appendix
         public Site.Site Site { get; set; }
 
         /// <summary>
-        /// Categories related to the appendix
+        /// Category values related to the appendix
         /// </summary>
-        public virtual ICollection<Category> Categories
+        public virtual ICollection<CategoryValue> CategoryValues
         {
-            get { return _categories ?? ( _categories = new List<Category>()); }
-            protected set { _categories = value; }
+            get { return _categoryValues ?? (_categoryValues = new List<CategoryValue>()); }
+            protected set { _categoryValues = value; }
         }
 
         /// <summary>

+ 26 - 0
GreenTree.Nachtragsmanagement.Core/Domain/Appendix/CategoryValue.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GreenTree.Nachtragsmanagement.Core.Domain.Appendix
+{
+    public class CategoryValue : BaseEntity
+    {
+        /// <summary>
+        /// Id of corresponding category
+        /// </summary>
+        public int? CategoryId { get; set; }
+
+        /// <summary>
+        /// Corresponding category
+        /// </summary>
+        public Category Category { get; set; }
+
+        /// <summary>
+        /// Monetary value
+        /// </summary>
+        public decimal Value { get; set; }
+    }
+}

+ 16 - 0
GreenTree.Nachtragsmanagement.Core/Domain/Appendix/State.cs

@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GreenTree.Nachtragsmanagement.Core.Domain.Appendix
+{
+    public class State : BaseEntity
+    {
+        /// <summary>
+        /// Description
+        /// </summary>
+        public string Description { get; set; }
+    }
+}

+ 7 - 20
GreenTree.Nachtragsmanagement.Core/Domain/Deviation/Deviation.cs

@@ -11,9 +11,9 @@ namespace GreenTree.Nachtragsmanagement.Core.Domain.Deviation
         #region Fields
 
         /// <summary>
-        /// Disturbances related to the deviation
+        /// Disturbance values related to the deviation
         /// </summary>
-        private ICollection<Disturbance> _disturbances;
+        private ICollection<DisturbanceValue> _disturbanceValues;
 
         #endregion
 
@@ -30,7 +30,7 @@ namespace GreenTree.Nachtragsmanagement.Core.Domain.Deviation
         /// <summary>
         /// Date when deviation were created
         /// </summary>
-        public DateTime ReceiptDate { get; set; }
+        public DateTime? ReceiptDate { get; set; }
 
         /// <summary>
         /// Editable comment
@@ -93,25 +93,12 @@ namespace GreenTree.Nachtragsmanagement.Core.Domain.Deviation
         public Kind Kind { get; set; }
 
         /// <summary>
-        /// Disturbances related to the deviation
+        /// Disturbances values related to the deviation
         /// </summary>
-        public virtual ICollection<Disturbance> Disturbances
+        public virtual ICollection<DisturbanceValue> DisturbanceValues
         {
-            get { return _disturbances ?? (_disturbances = new List<Disturbance>()); }
-            protected set { _disturbances = value; }
+            get { return _disturbanceValues ?? (_disturbanceValues = new List<DisturbanceValue>()); }
+            protected set { _disturbanceValues = value; }
         }
-
-        #region Helper
-
-        /// <summary>
-        /// Adds missing disturbances and removes not selected disturbances
-        /// </summary>
-        /// <param name="disturbances">Deviation disturbances.</param>
-        public void SetDisturbances(ICollection<Disturbance> disturbances)
-        {
-            Disturbances = disturbances;
-        }
-
-        #endregion
     }
 }

+ 26 - 0
GreenTree.Nachtragsmanagement.Core/Domain/Deviation/DisturbanceValue.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GreenTree.Nachtragsmanagement.Core.Domain.Deviation
+{
+    public class DisturbanceValue : BaseEntity
+    {
+        /// <summary>
+        /// Id of corresponding disturbance
+        /// </summary>
+        public int? DisturbanceId { get; set; }
+
+        /// <summary>
+        /// Corresponding disturbance
+        /// </summary>
+        public Disturbance Disturbance { get; set; }
+
+        /// <summary>
+        /// Monetary value
+        /// </summary>
+        public decimal Value { get; set; }
+    }
+}

+ 3 - 0
GreenTree.Nachtragsmanagement.Core/GreenTree.Nachtragsmanagement.Core.csproj

@@ -89,8 +89,11 @@
     <Compile Include="Data\IRepository.cs" />
     <Compile Include="Domain\Appendix\Appendix.cs" />
     <Compile Include="Domain\Appendix\Category.cs" />
+    <Compile Include="Domain\Appendix\CategoryValue.cs" />
+    <Compile Include="Domain\Appendix\State.cs" />
     <Compile Include="Domain\Deviation\Deviation.cs" />
     <Compile Include="Domain\Deviation\Disturbance.cs" />
+    <Compile Include="Domain\Deviation\DisturbanceValue.cs" />
     <Compile Include="Domain\Deviation\Kind.cs" />
     <Compile Include="Domain\Deviation\Status.cs" />
     <Compile Include="Domain\Invoice\Invoice.cs" />

+ 4 - 0
GreenTree.Nachtragsmanagement.Data/AppendixObjectContext.cs

@@ -52,6 +52,7 @@ namespace GreenTree.Nachtragsmanagement.Data
             var disturbanceSet = Set<Disturbance>();
             var deviationSet = Set<Deviation>();
             var categorySet = Set<Category>();
+            var stateSet = Set<State>();
             var appendixSet = Set<Appendix>();
             var mailNotificationSet = Set<MailNotification>();
             var notificationEventSet = Set<NotificationEvent>();
@@ -71,6 +72,7 @@ namespace GreenTree.Nachtragsmanagement.Data
                     disturbanceSet,
                     deviationSet,
                     categorySet,
+                    stateSet,
                     appendixSet,
                     mailNotificationSet,
                     notificationEventSet,
@@ -101,8 +103,10 @@ namespace GreenTree.Nachtragsmanagement.Data
             modelBuilder.Configurations.Add(new StatusMap());
             modelBuilder.Configurations.Add(new KindMap());
             modelBuilder.Configurations.Add(new DisturbanceMap());
+            modelBuilder.Configurations.Add(new DisturbanceValueMap());
             modelBuilder.Configurations.Add(new DeviationMap());
             modelBuilder.Configurations.Add(new CategoryMap());
+            modelBuilder.Configurations.Add(new CategoryValueMap());
             modelBuilder.Configurations.Add(new AppendixMap());
             modelBuilder.Configurations.Add(new MailNotificationMap());
             modelBuilder.Configurations.Add(new NotificationEventMap());

+ 3 - 0
GreenTree.Nachtragsmanagement.Data/GreenTree.Nachtragsmanagement.Data.csproj

@@ -52,6 +52,9 @@
     <Compile Include="IDbContext.cs" />
     <Compile Include="Mapping\Appendix\AppendixMap.cs" />
     <Compile Include="Mapping\Appendix\CategoryMap.cs" />
+    <Compile Include="Mapping\Appendix\CategoryValueMap.cs" />
+    <Compile Include="Mapping\Appendix\StateMap.cs" />
+    <Compile Include="Mapping\Deviation\DisturbanceValueMap.cs" />
     <Compile Include="Mapping\Deviation\DeviationMap.cs" />
     <Compile Include="Mapping\Deviation\DisturbanceMap.cs" />
     <Compile Include="Mapping\Deviation\KindMap.cs" />

+ 8 - 3
GreenTree.Nachtragsmanagement.Data/Mapping/Appendix/AppendixMap.cs

@@ -15,12 +15,16 @@ namespace GreenTree.Nachtragsmanagement.Data.Mapping.Appendix
 
             HasKey(a => a.Id);
 
+            HasOptional(a => a.State)
+                .WithMany()
+                .HasForeignKey(a => a.StateId);
+
             HasOptional(a => a.Site)
                 .WithMany(s => s.Appendices)
                 .HasForeignKey(a => a.SiteId);
 
             Property(a => a.CustomNumber);
-            Property(a => a.Lot);
+            Property(a => a.Description);
             Property(a => a.Comment);
             Property(a => a.Value);
             Property(a => a.Probability);
@@ -29,12 +33,13 @@ namespace GreenTree.Nachtragsmanagement.Data.Mapping.Appendix
             Property(a => a.NegotiationDate);
             Property(a => a.NegotiationValue);
             Property(a => a.ProtocolExists);
+            Property(a => a.OrderInvoiceCreated);
             Property(a => a.OrderNumber);
             Property(a => a.OrderDate);
 
-            HasMany(s => s.Categories)
+            HasMany(s => s.CategoryValues)
                 .WithMany()
-                .Map(a => a.ToTable("AppendixCategories"));
+                .Map(a => a.ToTable("AppendixCategoryValues"));
 
             HasMany(s => s.Deviations)
                 .WithOptional();

+ 25 - 0
GreenTree.Nachtragsmanagement.Data/Mapping/Appendix/CategoryValueMap.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Entity.ModelConfiguration;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GreenTree.Nachtragsmanagement.Data.Mapping.Appendix
+{
+    public class CategoryValueMap : EntityTypeConfiguration<Core.Domain.Appendix.CategoryValue>
+    {
+        public CategoryValueMap()
+        {
+            ToTable("CategoryValue");
+
+            HasKey(f => f.Id);
+
+            Property(f => f.Value);
+
+            HasOptional(d => d.Category)
+                .WithMany()
+                .HasForeignKey(d => d.CategoryId);
+        }
+    }
+}

+ 21 - 0
GreenTree.Nachtragsmanagement.Data/Mapping/Appendix/StateMap.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Entity.ModelConfiguration;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GreenTree.Nachtragsmanagement.Data.Mapping.Deviation
+{
+    public class StateMap : EntityTypeConfiguration<Core.Domain.Appendix.State>
+    {
+        public StateMap()
+        {
+            ToTable("State");
+
+            HasKey(f => f.Id);
+
+            Property(f => f.Description);
+        }
+    }
+}

+ 3 - 3
GreenTree.Nachtragsmanagement.Data/Mapping/Deviation/DeviationMap.cs

@@ -39,9 +39,9 @@ namespace GreenTree.Nachtragsmanagement.Data.Mapping.Deviation
                 .WithMany()
                 .HasForeignKey(d => d.KindId);
 
-            HasMany(s => s.Disturbances)
-                .WithMany() 
-                .Map(a => a.ToTable("DeviationDisturbances"));
+            HasMany(s => s.DisturbanceValues)
+                .WithMany()
+                .Map(a => a.ToTable("DeviationDisturbanceValues"));
         }
     }
 }

+ 25 - 0
GreenTree.Nachtragsmanagement.Data/Mapping/Deviation/DisturbanceValueMap.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Entity.ModelConfiguration;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GreenTree.Nachtragsmanagement.Data.Mapping.Deviation
+{
+    public class DisturbanceValueMap : EntityTypeConfiguration<Core.Domain.Deviation.DisturbanceValue>
+    {
+        public DisturbanceValueMap()
+        {
+            ToTable("DisturbanceValue");
+
+            HasKey(f => f.Id);
+
+            Property(f => f.Value);
+
+            HasOptional(d => d.Disturbance)
+                .WithMany()
+                .HasForeignKey(d => d.DisturbanceId);
+        }
+    }
+}

+ 62 - 1
GreenTree.Nachtragsmanagement.Services/Appendix/AppendixService.cs

@@ -16,6 +16,7 @@ namespace GreenTree.Nachtragsmanagement.Services.Appendix
         private readonly IRepository<Core.Domain.Appendix.Appendix> _appendixRepository;
         private readonly IRepository<Category> _categoryRepository;
         private readonly IRepository<Invoice> _invoiceRepository;
+        private readonly IRepository<State> _stateRepository;
 
         #endregion
 
@@ -27,11 +28,13 @@ namespace GreenTree.Nachtragsmanagement.Services.Appendix
         public AppendixService(
             IRepository<Core.Domain.Appendix.Appendix> appendixRepository,
             IRepository<Category> categoryRepository,
-            IRepository<Invoice> invoiceRepository)
+            IRepository<Invoice> invoiceRepository,
+            IRepository<State> stateRepository)
         {
             _appendixRepository = appendixRepository;
             _categoryRepository = categoryRepository;
             _invoiceRepository = invoiceRepository;
+            _stateRepository = stateRepository;
         }
 
         #endregion
@@ -219,5 +222,63 @@ namespace GreenTree.Nachtragsmanagement.Services.Appendix
         }
 
         #endregion
+
+        #region State
+
+        /// <summary>
+        /// Gets all states
+        /// </summary>
+        public IList<State> GetAllStates()
+        {
+            return _stateRepository.Table.ToList();
+        }
+
+        /// <summary>
+        /// Gets a state by specified Id
+        /// </summary>
+        /// <param name="id">State identifier.</param>
+        public State GetStateById(int id)
+        {
+            return _stateRepository.GetById(id);
+        }
+
+        /// <summary>
+        /// Gets all states to the specified ids
+        /// </summary>
+        public IList<State> GetStatesByIds(int[] ids)
+        {
+            return _stateRepository.Table
+                .Where(r => ids.Contains(r.Id))
+                .ToList();
+        }
+
+        /// <summary>
+        /// Insert a appendix
+        /// </summary>
+        /// <param name="state">State.</param>
+        public void InsertState(State state)
+        {
+            _stateRepository.Insert(state);
+        }
+
+        /// <summary>
+        /// Update a state
+        /// </summary>
+        /// <param name="state">State.</param>
+        public void UpdateState(State state)
+        {
+            _stateRepository.Update(state);
+        }
+
+        /// <summary>
+        /// Delete a state
+        /// </summary>
+        /// <param name="state">State.</param>
+        public void DeleteState(State state)
+        {
+            _stateRepository.Delete(state);
+        }
+
+        #endregion
     }
 }

+ 39 - 1
GreenTree.Nachtragsmanagement.Services/Appendix/IAppendixService.cs

@@ -129,5 +129,43 @@ namespace GreenTree.Nachtragsmanagement.Services.Appendix
         void DeleteInvoice(Invoice invoice);
 
         #endregion
+
+        #region State
+
+        /// <summary>
+        /// Gets all states
+        /// </summary>
+        IList<State> GetAllStates();
+
+        /// <summary>
+        /// Gets a state by specified Id
+        /// </summary>
+        /// <param name="id">State identifier.</param>
+        State GetStateById(int id);
+
+        /// <summary>
+        /// Gets all states to the specified ids
+        /// </summary>
+        IList<State> GetStatesByIds(int[] ids);
+
+        /// <summary>
+        /// Insert a state
+        /// </summary>
+        /// <param name="state">State.</param>
+        void InsertState(State state);
+
+        /// <summary>
+        /// Update a state
+        /// </summary>
+        /// <param name="state">State.</param>
+        void UpdateState(State state);
+
+        /// <summary>
+        /// Delete a state
+        /// </summary>
+        /// <param name="state">State.</param>
+        void DeleteState(State state);
+
+        #endregion
     }
-}
+}

+ 1 - 1
GreenTree.Nachtragsmanagement.Web/Controllers/AppendixController.cs

@@ -112,7 +112,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                 var appendix = _appendixService.GetAppendixById(appendixModel.Id);
 
                 appendix.CustomNumber = appendixModel.CustomNumber;
-                appendix.Lot = appendixModel.Lot;
+                appendix.Description = appendixModel.Description;
                 appendix.Probability = appendixModel.Probability;
                 appendix.OfferingNumber = appendixModel.OfferingNumber;
                 appendix.OfferingDate = appendixModel.OfferingDate;

+ 2 - 2
GreenTree.Nachtragsmanagement.Web/Controllers/DeviationController.cs

@@ -118,7 +118,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             {
                 var deviation = deviationModel.ToDeviation();
 
-                deviation.SetDisturbances(selectedDisturbances);
+                //deviation.SetDisturbances(selectedDisturbances);
 
                 _deviationService.InsertDeviation(deviation);
             }
@@ -135,7 +135,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                 deviation.KindId = deviationModel.KindId;
                 deviation.Comment = deviationModel.Comment;
 
-                deviation.SetDisturbances(selectedDisturbances);
+                //deviation.SetDisturbances(selectedDisturbances);
 
                 _deviationService.UpdateDeviation(deviation);
             }

+ 23 - 0
GreenTree.Nachtragsmanagement.Web/Controllers/SiteController.cs

@@ -66,7 +66,10 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                 };
 
             var siteModel = SiteDataModel.FromSite(site, false);
+            var siteTreeModel = SiteTreeDataModel.TreeFromSite(site);
 
+            siteModel.SiteTreeData = siteTreeModel;
+            
             return new JsonResult
             {
                 Data = JsonConvert.SerializeObject(siteModel),
@@ -87,6 +90,22 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             return PartialView("~/Views/Sites/_SiteGridPartial.cshtml", siteModels);
         }
 
+        /// <summary>
+        /// Callback result for site appendices
+        /// </summary>
+        /// <param name="siteId">Id of site.</param>
+        public ActionResult PartialDeviationAppendices(int siteId)
+        {
+            var site = _siteService.GetSiteById(siteId);
+
+            var siteModel = SiteDataModel.FromSite(site, false);
+            var siteTreeModel = SiteTreeDataModel.TreeFromSite(site);
+
+            siteModel.SiteTreeData = siteTreeModel;
+
+            return PartialView("~/Views/Sites/_SiteEditTreePartial.cshtml", siteModel);
+        }
+
         /// <summary>
         /// Partial edit for editing of existing or for new site
         /// </summary>
@@ -96,6 +115,10 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             var site = _siteService.GetSiteById(id);
             var siteModel = SiteDataModel.FromSite(site, true);
 
+            var siteTreeModel = SiteTreeDataModel.TreeFromSite(site);
+
+            siteModel.SiteTreeData = siteTreeModel;
+
             return PartialView("~/Views/Sites/_SiteEditPartial.cshtml", siteModel);
         }
 

+ 496 - 113
GreenTree.Nachtragsmanagement.Web/Global.asax.cs

@@ -21,6 +21,10 @@ using GreenTree.Nachtragsmanagement.Core.Domain.Misc;
 using GreenTree.Nachtragsmanagement.Core.Domain.User;
 using GreenTree.Nachtragsmanagement.Core.Domain.Deviation;
 using GreenTree.Nachtragsmanagement.Services.Deviation;
+using GreenTree.Nachtragsmanagement.Core.Domain.Site;
+using GreenTree.Nachtragsmanagement.Core.Domain.Appendix;
+using GreenTree.Nachtragsmanagement.Services.Appendix;
+using GreenTree.Nachtragsmanagement.Services.Site;
 
 namespace GreenTree.Nachtragsmanagement.Web
 {
@@ -68,31 +72,345 @@ namespace GreenTree.Nachtragsmanagement.Web
         {
             // Get services
 
-            var dbContext = Singleton<IContainer>.Instance.Resolve<IDbContext>();
             var userService = Singleton<IContainer>.Instance.Resolve<IUserService>();
             var deviationService = Singleton<IContainer>.Instance.Resolve<IDeviationService>();
+            var appendixService = Singleton<IContainer>.Instance.Resolve<IAppendixService>();
+            var siteService = Singleton<IContainer>.Instance.Resolve<ISiteService>();
+            var dbContext = Singleton<IContainer>.Instance.Resolve<IDbContext>();
+
+            try
+            {
+                // Check if test data is already created
+
+                var isTestDataGeneratedEntity = dbContext.Get<DbContextSpec>().FirstOrDefault(d => d.Name == "IsTestDataGenerated");
+
+                if (isTestDataGeneratedEntity != null && Convert.ToBoolean(isTestDataGeneratedEntity.Value))
+                    return;
+
+                // Create roles
+
+                var r1 = new Role
+                {
+                    Description = "Administrator",
+                    Level = 100
+                };
+                userService.InsertRole(r1);
+
+                var r2 = new Role
+                {
+                    Description = "Kaufmann",
+                    Level = 10
+                };
+                userService.InsertRole(r2);
+
+                var r3 = new Role
+                {
+                    Description = "Nachtragsmanager",
+                    Level = 10
+                };
+                userService.InsertRole(r3);
+
+                var r4 = new Role
+                {
+                    Description = "Bauleiter",
+                    Level = 10
+                };
+                userService.InsertRole(r4);
+
+                // Create users
+
+                var u1 = new User
+                {
+                    Forename = "Arne",
+                    Lastname = "Diekmann",
+                    CustomNumber = "a.diekmann",
+                    MailAddress = "a.diekmann@greentreestudios.de",
+                    Password = StaticHelper.GetMD5Hash("14595809")
+                };
+                userService.InsertUser(u1);
+
+                var u2 = new User
+                {
+                    Forename = "Rocco",
+                    Lastname = "Lavella",
+                    CustomNumber = "r.lavella",
+                    MailAddress = "lavella@schweerbau.de",
+                    Password = StaticHelper.GetMD5Hash("lavella")
+                };
+                userService.InsertUser(u2);
+
+                var u3 = new User
+                {
+                    Forename = "Felix",
+                    Lastname = "Bramstedt",
+                    CustomNumber = "f.bramstedt",
+                    MailAddress = "bramstedt@schweerbau.de",
+                    Password = StaticHelper.GetMD5Hash("bramstedt")
+                };
+                userService.InsertUser(u3);
+
+                var u4 = new User
+                {
+                    Forename = "Kletus",
+                    Lastname = "Lingemann",
+                    CustomNumber = "k.lingemann",
+                    MailAddress = "lingemann@schweerbau.de",
+                    Password = StaticHelper.GetMD5Hash("lingemann")
+                };
+                userService.InsertUser(u4);
+
+                var u5 = new User
+                {
+                    Forename = "Max",
+                    Lastname = "Moede",
+                    CustomNumber = "m.moede",
+                    MailAddress = "moede@schweerbau.de",
+                    Password = StaticHelper.GetMD5Hash("moede")
+                };
+                userService.InsertUser(u5);
+
+                var u6 = new User
+                {
+                    Forename = "Max",
+                    Lastname = "Dammeier",
+                    CustomNumber = "m.dammeier",
+                    MailAddress = "dammeier@schweerbau.de",
+                    Password = StaticHelper.GetMD5Hash("dammeier")
+                };
+                userService.InsertUser(u6);
+
+                var u7 = new User
+                {
+                    Forename = "Max",
+                    Lastname = "Poppe",
+                    CustomNumber = "m.poppe",
+                    MailAddress = "poppe@schweerbau.de",
+                    Password = StaticHelper.GetMD5Hash("poppe")
+                };
+                userService.InsertUser(u7);
+
+                var u8 = new User
+                {
+                    Forename = "Max",
+                    Lastname = "Lehmann",
+                    CustomNumber = "m.lehmann",
+                    MailAddress = "lehmann@schweerbau.de",
+                    Password = StaticHelper.GetMD5Hash("poppe")
+                };
+                userService.InsertUser(u8);
+
+                var u9 = new User
+                {
+                    Forename = "Max",
+                    Lastname = "Wernecke",
+                    CustomNumber = "m.wernecke",
+                    MailAddress = "wernecke@schweerbau.de",
+                    Password = StaticHelper.GetMD5Hash("wernecke")
+                };
+                userService.InsertUser(u9);
+
+                // Add users to roles
+
+                u1.Roles.Add(r1);
+                u2.Roles.Add(r1);
+                u3.Roles.Add(r1);
+                u4.Roles.Add(r3);
+                u4.Roles.Add(r3);
+                u5.Roles.Add(r4);
+                u7.Roles.Add(r4);
+                u6.Roles.Add(r2);
+                u9.Roles.Add(r2);
+
+                // Get all functions and add them to the admin role
+
+                var allFunctions = userService.GetAllFunctions();
+
+                r1.SetFunctions(allFunctions);
+                userService.UpdateRole(r1);
+
+                // Get all appendix manager function and add them to the apendix manager / merchant role
+
+                var deviationFunctions = allFunctions
+                    .Where(f => f.Name.StartsWith("Deviation"));
+
+                foreach (var function in deviationFunctions)
+                {
+                    r2.Functions.Add(function);
+                    r3.Functions.Add(function);
+                    r4.Functions.Add(function);
+                }
+
+                var appendixFunctions = allFunctions
+                    .Where(f => f.Name.StartsWith("Appendix"));
+
+                foreach (var function in appendixFunctions)
+                {
+                    r2.Functions.Add(function);
+                    r3.Functions.Add(function);
+                    r4.Functions.Add(function);
+                }
+
+                userService.UpdateRole(r2);
+                userService.UpdateRole(r3);
+                userService.UpdateRole(r4);
+
+                // Create appendix base data
+
+                var categories = new[]
+                {
+                new Category { Description = "RPM" },
+                new Category { Description = "RM" },
+                new Category { Description = "Stopftechnik" },
+                new Category { Description = "Umbauzug" },
+                new Category { Description = "Logistik" },
+                new Category { Description = "Oberbau" },
+                new Category { Description = "Erdbau" },
+                new Category { Description = "Kabeltiefbau" },
+                new Category { Description = "Entwässerung" },
+                new Category { Description = "Sonstiges" }
+            };
+
+                foreach (var category in categories)
+                    appendixService.InsertCategory(category);
 
-            // Check if test data is already created
+                var states = new[]
+                {
+                new State { Description = "Offen" },
+                new State { Description = "Erinnerung Verhandlung" },
+                new State { Description = "Verhandelt" },
+                new State { Description = "Erledigt / Entfällt" }
+            };
+
+                foreach (var state in states)
+                    appendixService.InsertState(state);
+
+                var appendices = new[]
+                {
+                new Appendix
+                {
+                    CustomNumber = "3",
+                    Description = "Lückenschluss Weiche 523",
+                    State = states[0],
+                    StateId = states[0].Id,
+                    CategoryValues =
+                    {
+                        new CategoryValue { Category = categories[2], CategoryId = categories[2].Id, Value = 44000 },
+                        new CategoryValue { Category = categories[3], CategoryId = categories[3].Id, Value = 30000 },
+                    },
+                    Value = Convert.ToDecimal(74833.6),
+                    NegotiationValue = 70000,
+                    OfferingDate = new DateTime(2016, 12, 20),
+                    Comment = "hier 3 % NA enthalten = Delta zu iTWO  = 77148,04€, Abgabeddatum per Mail, Post später"
+                },
+                new Appendix
+                {
+                    CustomNumber = "6",
+                    Description = "Erschwerniss masch. Gleisbau ZEB 22",
+                    State = states[0],
+                    StateId = states[0].Id,
+                    CategoryValues =
+                    {
+                        new CategoryValue { Category = categories[0], CategoryId = categories[0].Id, Value = 43000 }
+                    },
+                    Value = Convert.ToDecimal(43514.35),
+                    NegotiationValue = 40000,
+                    OfferingDate = new DateTime(2016, 12, 20),
+                    Comment = "Teilweise Abrechnung über HLV in Höhe von 5322,12€ (nicht in Summe oben enthalten) hier 3 % NA enthalten = Delta zu iTWO  = 44860,15€ Abgabeddatum per Mail, Post später"
+                },
+                new Appendix
+                {
+                    CustomNumber = "1",
+                    Description = "Umsetzen von Haufwerken",
+                    State = states[0],
+                    StateId = states[0].Id,
+                    CategoryValues =
+                    {
+                        new CategoryValue { Category = categories[9], CategoryId = categories[9].Id, Value = 2500 }
+                    },
+                    Value = Convert.ToDecimal(2549.18),
+                    NegotiationValue = 2000,
+                    OfferingDate = new DateTime(2017, 2, 2),
+                    Comment = "Beginn der Frist der Nachtragsprüfung 16.02.17"
+                },
+                new Appendix
+                {
+                    CustomNumber = "2",
+                    Description = "Nichtbereitstellung der Ladevorrichtung",
+                    State = states[0],
+                    StateId = states[0].Id,
+                    CategoryValues =
+                    {
+                        new CategoryValue { Category = categories[4], CategoryId = categories[4].Id }
+                    },
+                    Value = Convert.ToDecimal(23738.06),
+                    NegotiationValue = 20000,
+                    OfferingDate = new DateTime(2017, 2, 3),
+                    Comment = "Aufmaße noch nicht erstellt"
+                }
+            };
 
-            var isTestDataGeneratedEntity = dbContext.Get<DbContextSpec>().FirstOrDefault(d => d.Name == "IsTestDataGenerated");
+                foreach (var appendix in appendices)
+                    appendixService.InsertAppendix(appendix);
+
+                // Create site base data
+
+                var sites = new[]
+                {
+                new Site
+                {
+                    CustomNumber = "2101000",
+                    Description = "POS Nord Kaiserslautern Los 19-21",
+                    Appendices =
+                    {
+                        appendices[0],
+                        appendices[1]
+                    },
+                    Finished = false,
+                    Start = new DateTime(2016, 1, 1),
+                    Users =
+                    {
+                        u4,
+                        u5,
+                        u6
+                    }
+                },
+                new Site
+                {
+                    CustomNumber = "211200",
+                    Description = "GE Geisenheim-Rüdesheim",
+                    Appendices =
+                    {
+                        appendices[2],
+                        appendices[3]
+                    },
+                    Finished = false,
+                    Start = new DateTime(2016, 1, 1),
+                    Users =
+                    {
+                        u7,
+                        u8,
+                        u9
+                    }
+                }
+            };
 
-            if (isTestDataGeneratedEntity != null && Convert.ToBoolean(isTestDataGeneratedEntity.Value))
-                return;
+                foreach (var site in sites)
+                    siteService.InsertSite(site);
 
-            // Create base data
+                // Create deviation base data
 
-            var kinds = new []
-            {
+                var kinds = new[]
+                {
                 new Kind { Shortance = "MK", Description = "Mehrkosten" },
                 new Kind { Shortance = "BH", Description = "Behinderung" },
                 new Kind { Shortance = "BD", Description = "Bedenken" }
             };
 
-            foreach (var kind in kinds)
-                deviationService.InsertKind(kind);
+                foreach (var kind in kinds)
+                    deviationService.InsertKind(kind);
 
-            var disturbances = new[]
-            {
+                var disturbances = new[]
+                {
                 new Disturbance { Description = "RPM" },
                 new Disturbance { Description = "RM" },
                 new Disturbance { Description = "Stopftechnik" },
@@ -105,119 +423,184 @@ namespace GreenTree.Nachtragsmanagement.Web
                 new Disturbance { Description = "Sonstiges" }
             };
 
-            foreach (var disturbance in disturbances)
-                deviationService.InsertDisturbance(disturbance);
+                foreach (var disturbance in disturbances)
+                    deviationService.InsertDisturbance(disturbance);
 
-            var statuses = new []
-            {
+                var statuses = new[]
+                {
                 new Status { Description = "Standard" },
                 new Status { Description = "Entfällt" },
                 new Status { Description = "Strittig" },
                 new Status { Description = "Abr. über HLV" }
             };
 
-            foreach (var status in statuses)
-                deviationService.InsertStatus(status);
-
-            // Create roles
-
-            var r1 = new Role
-            {
-                Description = "Administrator",
-                Level = 100
-            };
-            userService.InsertRole(r1);
-
-            var r2 = new Role
-            {
-                Description = "Kaufmann",
-                Level = 10
-            };
-            userService.InsertRole(r2);
-
-            var r3 = new Role
-            {
-                Description = "Nachtragsmanager",
-                Level = 10
-            };
-            userService.InsertRole(r3);
-
-            // Create users
-
-            var u1 = new User
-            {
-                Forename = "Arne",
-                Lastname = "Diekmann",
-                CustomNumber = "a.diekmann",
-                MailAddress = "a.diekmann@greentreestudios.de",
-                Password = StaticHelper.GetMD5Hash("14595809")
-            };
-            userService.InsertUser(u1);
-
-            var u2 = new User
-            {
-                Forename = "Rocco",
-                Lastname = "Lavella",
-                CustomNumber = "r.lavella",
-                MailAddress = "lavella@schweerbau.de",
-                Password = StaticHelper.GetMD5Hash("lavella")
-            };
-            userService.InsertUser(u2);
-
-            var u3 = new User
-            {
-                Forename = "Kletus",
-                Lastname = "Lingemann",
-                CustomNumber = "k.lingemann",
-                MailAddress = "k.lingemann@schweerbau.de",
-                Password = StaticHelper.GetMD5Hash("lingemann")
-            };
-            userService.InsertUser(u3);
-
-            // Add users to roles
-
-            u1.Roles.Add(r1);
-            u2.Roles.Add(r1);
-            u3.Roles.Add(r3);
-
-            // Get all functions and add them to the admin role
-
-            var allFunctions = userService.GetAllFunctions();
-
-            r1.SetFunctions(allFunctions);
-            userService.UpdateRole(r1);
-
-            // Get all appendix manager function and add them to the apendix manager / merchant role
-
-            var deviationFunctions = allFunctions
-                .Where(f => f.Name.StartsWith("Deviation"));
-
-            foreach (var function in deviationFunctions)
-            {
-                r2.Functions.Add(function);
-                r3.Functions.Add(function);
+                foreach (var status in statuses)
+                    deviationService.InsertStatus(status);
+
+                var deviations = new[]
+                {
+                    new Deviation
+                    {
+                        CustomNumber = "1",
+                        Description = "Mehrleistung Stopfen",
+                        Kind = kinds[0],
+                        KindId = kinds[0].Id,
+                        DisturbanceValues =
+                        {
+                            new DisturbanceValue { Disturbance = disturbances[2], DisturbanceId = disturbances[2].Id, Value = 40000 }
+                        },
+                        Status = statuses[0],
+                        StatusId = statuses[0].Id,
+                        Value = 40000,
+                        Percentage = 100,
+                        Appendix = appendices[0],
+                        AppendixId = appendices[0].Id,
+                        AppendixDate = appendices[0].OfferingDate
+                    },
+                    new Deviation
+                    {
+                        CustomNumber = "2",
+                        Description = "Bodenausbau konventionell",
+                        Kind = kinds[0],
+                        KindId = kinds[0].Id,
+                        DisturbanceValues =
+                        {
+                            new DisturbanceValue { Disturbance = disturbances[6], DisturbanceId = disturbances[6].Id, Value = 30000 }
+                        },
+                        Status = statuses[1],
+                        StatusId = statuses[1].Id,
+                        Value = 30000,
+                        Percentage = 0,
+                        Appendix = appendices[0],
+                        AppendixId = appendices[0].Id,
+                        AppendixDate = appendices[0].OfferingDate
+                    },
+                    new Deviation
+                    {
+                        CustomNumber = "3",
+                        Description = "Einbau PSS im Weichenbereich",
+                        Kind = kinds[0],
+                        KindId = kinds[0].Id,
+                        DisturbanceValues =
+                        {
+                            new DisturbanceValue { Disturbance = disturbances[6], DisturbanceId = disturbances[6].Id, Value = 2000 }
+                        },
+                        Status = statuses[0],
+                        StatusId = statuses[0].Id,
+                        Value = 2000,
+                        Percentage = 100,
+                        Appendix = appendices[1],
+                        AppendixId = appendices[1].Id,
+                        AppendixDate = appendices[1].OfferingDate
+                    },
+                    new Deviation
+                    {
+                        CustomNumber = "4",
+                        Description = "Hindernisse bei der PLV mit RPM",
+                        Kind = kinds[1],
+                        KindId = kinds[1].Id,
+                        DisturbanceValues =
+                        {
+                            new DisturbanceValue { Disturbance = disturbances[0], DisturbanceId = disturbances[0].Id, Value = 40000 }
+                        },
+                        Status = statuses[2],
+                        StatusId = statuses[2].Id,
+                        Value = 40000,
+                        Percentage = 30,
+                        Site = sites[0],
+                        SiteId = sites[0].Id
+                    },
+                    new Deviation
+                    {
+                        CustomNumber = "1",
+                        Description = "Umsetzen von Haufwerken",
+                        Kind = kinds[0],
+                        KindId = kinds[0].Id,
+                        DisturbanceValues =
+                        {
+                            new DisturbanceValue { Disturbance = disturbances[6], DisturbanceId = disturbances[6].Id, Value = 2500 }
+                        },
+                        Status = statuses[0],
+                        StatusId = statuses[0].Id,
+                        Value = 2500,
+                        Percentage = 100,
+                        Appendix = appendices[2],
+                        AppendixId = appendices[2].Id,
+                        AppendixDate = appendices[2].OfferingDate
+                    },
+                    new Deviation
+                    {
+                        CustomNumber = "2",
+                        Description = "Nichtbereitsstellung der Ladevorrichtung Nr. 1",
+                        Kind = kinds[0],
+                        KindId = kinds[0].Id,
+                        DisturbanceValues =
+                        {
+                            new DisturbanceValue { Disturbance = disturbances[5], DisturbanceId = disturbances[5].Id, Value = 10000 }
+                        },
+                        Status = statuses[0],
+                        StatusId = statuses[0].Id,
+                        Value = 10000,
+                        Percentage = 100,
+                        Appendix = appendices[3],
+                        AppendixId = appendices[3].Id,
+                        AppendixDate = appendices[3].OfferingDate
+                    },
+                    new Deviation
+                    {
+                        CustomNumber = "5",
+                        Description = "Nichtbereitsstellung der Ladevorrichtung Nr. 2",
+                        Kind = kinds[0],
+                        KindId = kinds[0].Id,
+                        DisturbanceValues =
+                        {
+                            new DisturbanceValue { Disturbance = disturbances[5], DisturbanceId = disturbances[5].Id, Value = 10000 }
+                        },
+                        Status = statuses[3],
+                        StatusId = statuses[3].Id,
+                        Value = 10000,
+                        Percentage = 110,
+                        Appendix = appendices[3],
+                        AppendixId = appendices[3].Id,
+                        AppendixDate = appendices[3].OfferingDate
+                    },
+                    new Deviation
+                    {
+                        CustomNumber = "6",
+                        Description = "Verspannung Los 2",
+                        Kind = kinds[0],
+                        KindId = kinds[0].Id,
+                        DisturbanceValues =
+                        {
+                            new DisturbanceValue { Disturbance = disturbances[5], DisturbanceId = disturbances[5].Id, Value = 6000 }
+                        },
+                        Status = statuses[2],
+                        StatusId = statuses[2].Id,
+                        Value = 6000,
+                        Percentage = 50,
+                        Site = sites[1],
+                        SiteId = sites[1].Id
+                    }
+                };
+
+                foreach (var deviation in deviations)
+                    deviationService.InsertDeviation(deviation);
             }
-
-            var appendixFunctions = allFunctions
-                .Where(f => f.Name.StartsWith("Appendix"));
-
-            foreach (var function in appendixFunctions)
+            finally
             {
-                r2.Functions.Add(function);
-                r3.Functions.Add(function);
-            }
+                // Create DbContecSpecification object
 
-            userService.UpdateRole(r2);
-            userService.UpdateRole(r3);
+                var db1 = new DbContextSpec
+                {
+                    Name = "IsTestDataGenerated",
+                    Value = "True"
+                };
+                dbContext.Get<DbContextSpec>().Add(db1);
 
-            // Create DbContecSpecification object
+                dbContext.SaveChanges();
+            }
 
-            var db1 = new DbContextSpec
-            {
-                Name = "IsTestDataGenerated",
-                Value = "True"
-            };
-            dbContext.Get<DbContextSpec>().Add(db1);
+            var allDeviations = deviationService.GetAllDeviations();
         }
 
         #endregion

+ 3 - 0
GreenTree.Nachtragsmanagement.Web/GreenTree.Nachtragsmanagement.Web.csproj

@@ -26,6 +26,7 @@
     <IISExpressUseClassicPipelineMode />
     <UseGlobalApplicationHostFile />
     <UpgradeBackupLocation />
+    <Use64BitIISExpress />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -272,6 +273,7 @@
     <Content Include="Views\Sites\_SiteEditPartial.cshtml" />
     <Content Include="Views\Sites\_SiteGridPartial.cshtml" />
     <Content Include="Views\Sites\View.cshtml" />
+    <Content Include="Views\Sites\_SiteEditTreePartial.cshtml" />
     <None Include="Web.Debug.config">
       <DependentUpon>Web.config</DependentUpon>
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -319,6 +321,7 @@
     <Compile Include="Models\Global\YesNoDialogModel.cs" />
     <Compile Include="Models\Global\OptionDialogModel.cs" />
     <Compile Include="Models\Site\SiteDataModel.cs" />
+    <Compile Include="Models\Site\SiteTreeDataModel.cs" />
     <Compile Include="Validation\Admin\User\RoleDataModelValidator.cs" />
     <Compile Include="Validation\Admin\User\UserDataModelValidator.cs" />
     <Compile Include="Models\Global\FooterModel.cs" />

+ 11 - 9
GreenTree.Nachtragsmanagement.Web/Models/Appendix/AppendixDataModel.cs

@@ -9,15 +9,15 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Appendix
     {
         public int Id { get; set; }
         public string CustomNumber { get; set; }
-        public string Lot { get; set; }
+        public string Description { get; set; }
         public decimal? Probability { get; set; }
         public int? OfferingNumber { get; set; }
-        public DateTime OfferingDate { get; set; }
-        public DateTime NegotiationDate { get; set; }
+        public DateTime? OfferingDate { get; set; }
+        public DateTime? NegotiationDate { get; set; }
         public decimal? NegotiationValue { get; set; }
         public bool ProtocolExists { get; set; }
         public int? OrderNumber { get; set; }
-        public DateTime OrderDate { get; set; }
+        public DateTime? OrderDate { get; set; }
         public string Comment { get; set; }
         public int? SiteId { get; set; }
         public string SiteDescription { get; set; }
@@ -41,7 +41,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Appendix
             {
                 Id = appendixEntity.Id,
                 CustomNumber = appendixEntity.CustomNumber,
-                Lot = appendixEntity.Lot,
+                Description = appendixEntity.Description,
                 Probability = appendixEntity.Probability,
                 OfferingNumber = appendixEntity.OfferingNumber,
                 OfferingDate = appendixEntity.OfferingDate,
@@ -56,12 +56,14 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Appendix
                     ? null
                     : appendixEntity.Site.Description,
                 CategoryValues =
-                    appendixEntity.Categories
+                    appendixEntity.CategoryValues
                         .Select(r => r.Id)
                         .ToList(),
                 CategoryDescriptions =
-                    appendixEntity.Categories
-                        .Select(r => r.Description)
+                    appendixEntity.CategoryValues
+                        .Select(r => r.Category == null
+                            ? String.Empty
+                            : r.Category.Description)
                         .ToList(),
                 DeviationValues =
                     appendixEntity.Deviations
@@ -80,7 +82,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Appendix
             {
                 Id = this.Id,
                 CustomNumber = this.CustomNumber,
-                Lot = this.Lot,
+                Description = this.Description,
                 Probability = this.Probability,
                 OfferingNumber = this.OfferingNumber,
                 OfferingDate = this.OfferingDate,

+ 6 - 4
GreenTree.Nachtragsmanagement.Web/Models/Deviation/DeviationDataModel.cs

@@ -12,7 +12,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Deviation
         public int Id { get; set; }
         public string CustomNumber { get; set; }
         public string Description { get; set; }
-        public DateTime ReceiptDate { get; set; }
+        public DateTime? ReceiptDate { get; set; }
         public DateTime? AppendixDate { get; set; }
         public decimal Value { get; set; }
         public int Percentage { get; set; }
@@ -85,12 +85,14 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Deviation
                     : deviationEntity.Kind.Description,
                 Comment = deviationEntity.Comment,
                 DisturbanceValues =
-                    deviationEntity.Disturbances
+                    deviationEntity.DisturbanceValues
                         .Select(r => r.Id)
                         .ToList(),
                 DisturbanceDescriptions =
-                    deviationEntity.Disturbances
-                        .Select(r => r.Description)
+                    deviationEntity.DisturbanceValues
+                        .Select(r => r.Disturbance == null
+                            ? String.Empty
+                            : r.Disturbance.Description)
                         .ToList()
             };
         }

+ 3 - 2
GreenTree.Nachtragsmanagement.Web/Models/Site/SiteDataModel.cs

@@ -57,6 +57,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Site
                     return String.Join(", ", UserDescriptions);
             }
         }
+        public ICollection<SiteTreeDataModel> SiteTreeData { get; set; }
 
         public SiteDataModel()
         {
@@ -100,9 +101,9 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Site
                     siteEntity.Deviations
                         .Select(r => DeviationDataModel.FromDeviation(r, false))
                         .ToList(),
-                DeviationValue =
+                DeviationValue = 
                     siteEntity.Deviations
-                        .Sum(r => r.Value * (r.Percentage.Value / 100)),
+                        .Sum(r => r.Value * ((decimal)r.Percentage.Value / (decimal)100)),
                 AppendixValues =
                     siteEntity.Appendices
                         .Select(r => r.Id)

+ 153 - 0
GreenTree.Nachtragsmanagement.Web/Models/Site/SiteTreeDataModel.cs

@@ -0,0 +1,153 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+
+namespace GreenTree.Nachtragsmanagement.Web.Models.Site
+{
+    public class SiteTreeDataModel
+    {
+        public int Id { get; set; }
+        public string TreeKey { get; set; }
+        public string TreeParentKey { get; set; }
+        public string CustomNumber { get; set; }
+        public string Description { get; set; }
+        public DateTime? ReceiptDate { get; set; }
+        public decimal? Value { get; set; }
+        public int? StatusId { get; set; }
+        public string StatusDescription { get; set; }
+        public ICollection<int> DistCatValues { get; set; }
+        public ICollection<string> DistCatDescriptions { get; set; }
+        public string DistCatDescription
+        {
+            get
+            {
+                if (DistCatDescriptions == null)
+                    return String.Empty;
+                else
+                    return String.Join(", ", DistCatDescriptions);
+            }
+        }
+        public string Comment { get; set; }
+
+        public SiteTreeDataModel()
+        {
+            DistCatValues = new List<int>();
+            DistCatDescriptions = new List<string>();
+        }
+
+        public static List<SiteTreeDataModel> TreeFromSite(Core.Domain.Site.Site siteEntity)
+        {
+            var result = new List<SiteTreeDataModel>();
+
+            if (siteEntity == null)
+                return result;
+
+            var emptyAppendix = new SiteTreeDataModel
+            {
+                Id = 0,
+                TreeKey = "a_0",
+                TreeParentKey = String.Empty,
+                CustomNumber = "Offene VA"
+            };
+
+            result.Add(emptyAppendix);
+
+            var openDeviations = siteEntity.Deviations
+                .Where(d => d.Appendix == null);
+
+            foreach (var openDeviation in openDeviations)
+            {
+                result.Add(new SiteTreeDataModel
+                {
+                    Id = openDeviation.Id,
+                    TreeKey = String.Format("d_{0}", openDeviation.Id),
+                    TreeParentKey = emptyAppendix.TreeKey,
+                    CustomNumber = openDeviation.CustomNumber,
+                    Description = openDeviation.Description,
+                    ReceiptDate = openDeviation.ReceiptDate,
+                    DistCatValues = 
+                        openDeviation.DisturbanceValues
+                            .Select(d => d.Id)
+                            .ToList(),
+                    DistCatDescriptions =
+                        openDeviation.DisturbanceValues
+                            .Select(r => r.Disturbance == null
+                                ? String.Empty
+                                : r.Disturbance.Description)
+                            .ToList(),
+                    StatusId = openDeviation.StatusId,
+                    StatusDescription = openDeviation.Status == null
+                        ? String.Empty
+                        : openDeviation.Status.Description,
+                    Value = openDeviation.Value.Value * ((decimal)openDeviation.Percentage.Value / (decimal)100),
+                    Comment = openDeviation.Comment
+                });
+            }
+
+            foreach (var appendix in siteEntity.Appendices)
+            {
+                var parentAppendix = new SiteTreeDataModel
+                {
+                    Id = appendix.Id,
+                    TreeKey = String.Format("a_{0}", appendix.Id),
+                    TreeParentKey = String.Empty,
+                    CustomNumber = appendix.CustomNumber,
+                    Description = appendix.Description,
+                    ReceiptDate = appendix.OfferingDate,
+                    DistCatValues =
+                        appendix.CategoryValues
+                            .Select(d => d.Id)
+                            .ToList(),
+                    DistCatDescriptions =
+                        appendix.CategoryValues
+                            .Select(r => r.Category == null
+                                ? String.Empty
+                                : r.Category.Description)
+                            .ToList(),
+                    StatusId = appendix.StateId,
+                    StatusDescription = appendix.State == null
+                        ? String.Empty
+                        : appendix.State.Description,
+                    Value = appendix.NegotiationValue,
+                    Comment = appendix.Comment
+                };
+
+                result.Add(parentAppendix);
+
+                foreach (var deviation in appendix.Deviations)
+                {
+                    var childDeviation = new SiteTreeDataModel
+                    {
+                        Id = deviation.Id,
+                        TreeKey = String.Format("d_{0}", deviation.Id),
+                        TreeParentKey = parentAppendix.TreeKey,
+                        CustomNumber = deviation.CustomNumber,
+                        Description = deviation.Description,
+                        ReceiptDate = deviation.ReceiptDate,
+                        DistCatValues =
+                            deviation.DisturbanceValues
+                                .Select(d => d.Id)
+                                .ToList(),
+                        DistCatDescriptions =
+                            deviation.DisturbanceValues
+                                .Select(r => r.Disturbance == null
+                                    ? String.Empty
+                                    : r.Disturbance.Description)
+                                .ToList(),
+                        StatusId = deviation.StatusId,
+                        StatusDescription = deviation.Status == null
+                        ? String.Empty
+                        : deviation.Status.Description,
+                        Value = deviation.Value.Value * (deviation.Percentage.Value / 100),
+                        Comment = deviation.Comment
+                    };
+
+                    result.Add(childDeviation);
+                }
+            }
+
+            return result;
+        }
+    }
+}

+ 4 - 2
GreenTree.Nachtragsmanagement.Web/Views/Shared/_FunctionLayout.cshtml

@@ -10,13 +10,15 @@
 		new StyleSheet { ExtensionSuite = ExtensionSuite.NavigationAndLayout },
 		new StyleSheet { ExtensionSuite = ExtensionSuite.Editors },
 		new StyleSheet { ExtensionSuite = ExtensionSuite.Report },
-		new StyleSheet { ExtensionSuite = ExtensionSuite.GridView }
+		new StyleSheet { ExtensionSuite = ExtensionSuite.GridView },
+		new StyleSheet { ExtensionSuite = ExtensionSuite.TreeList }
 	)
     @Html.DevExpress().GetScripts(
 		new Script { ExtensionSuite = ExtensionSuite.NavigationAndLayout },
 		new Script { ExtensionSuite = ExtensionSuite.Editors },
 		new Script { ExtensionSuite = ExtensionSuite.Report },
-		new Script { ExtensionSuite = ExtensionSuite.GridView }
+		new Script { ExtensionSuite = ExtensionSuite.GridView },
+		new Script { ExtensionSuite = ExtensionSuite.TreeList }
 	)
 
 	<link rel="stylesheet" type="text/css" href="~/Content/global.css" />

+ 4 - 2
GreenTree.Nachtragsmanagement.Web/Views/Shared/_Layout.cshtml

@@ -10,13 +10,15 @@
 		new StyleSheet { ExtensionSuite = ExtensionSuite.NavigationAndLayout },
 		new StyleSheet { ExtensionSuite = ExtensionSuite.Editors },
 		new StyleSheet { ExtensionSuite = ExtensionSuite.Report },
-		new StyleSheet { ExtensionSuite = ExtensionSuite.GridView }
+		new StyleSheet { ExtensionSuite = ExtensionSuite.GridView },
+		new StyleSheet { ExtensionSuite = ExtensionSuite.TreeList }
 	)
     @Html.DevExpress().GetScripts(
 		new Script { ExtensionSuite = ExtensionSuite.NavigationAndLayout },
 		new Script { ExtensionSuite = ExtensionSuite.Editors },
 		new Script { ExtensionSuite = ExtensionSuite.Report },
-		new Script { ExtensionSuite = ExtensionSuite.GridView }
+		new Script { ExtensionSuite = ExtensionSuite.GridView },
+		new Script { ExtensionSuite = ExtensionSuite.TreeList }
 	)
 
 	@*@System.Web.Optimization.Scripts.Render("~/bundles/jquery")

+ 20 - 144
GreenTree.Nachtragsmanagement.Web/Views/Sites/_SiteEditPartial.cshtml

@@ -14,6 +14,20 @@
 
 	</script>
 
+	<style>
+		.siteTreeList {
+
+		}
+
+		.siteTreeList > tbody > tr > td > table > tbody > tr:nth-child(2n) {
+			background-color: #F7F7F7;
+		}
+
+		.siteTreeList > tbody > tr > td > table > tbody > tr:nth-child(2n) > td:first-child {
+			background-color: #F7F7F7;
+		}
+	</style>
+
 	@Html.DevExpress().PopupControl(s =>
 {
 	s.Name = "devPopupControlEditSite";
@@ -31,7 +45,7 @@
 	s.PopupVerticalAlign = PopupVerticalAlign.TopSides;
 	s.PopupVerticalOffset = 10;
 	s.AllowDragging = false;
-	s.AllowResize = false;
+	s.AllowResize = true;
 	s.ShowFooter = false;
 	s.ShowOnPageLoad = true;
 	s.SetContent(() =>
@@ -94,150 +108,12 @@
 			ViewContext.Writer.Write("</div>");
 
 			ViewContext.Writer.Write(Html.CustomLabelFor(m => m.Deviations, "Vertragsabweichungen / Nachträge:"));
-			Html.DevExpress().TreeList(t =>
-			{
-				t.Name = "devTreeListSiteDeviationAppendices";
-				t.KeyFieldName = "Id";
-				t.ParentFieldName = "ParentId";
-				t.CallbackRouteValues = new { Controller = "Site", Action = "PartialDeviationAppendices" };
-				t.Width = Unit.Percentage(100);
 
-				t.Columns.Add(column =>
-				{
-					column.Caption = "#";
-					column.SetDataCellTemplateContent(c =>
-					{
-						ViewContext.Writer.Write(
-							"<a href=\"#\" onclick=\"editDeviation(" + DataBinder.Eval(c.DataItem, "Id") + ")\">Bearbeiten</a>&nbsp;" +
-							"<a href=\"#\" onclick=\"confirmDelete(" + DataBinder.Eval(c.DataItem, "Id") + ")\">Löschen</a>"
-						);
-					});
-				});
-				t.Columns.Add("CustomNumber", "Nummer");
-				t.Columns.Add("Description", "Bezeichnung");
-				t.Columns.Add(column =>
-				{
-					column.Caption = "Eingang";
-					column.FieldName = "ReceiptDate";
-					column.PropertiesEdit.DisplayFormatString = "dd.MM.yyyy";
-				});
-				t.Columns.Add(column =>
-				{
-					column.Caption = "Schätzung bew.";
-					column.FieldName = "PercentageValue";
-					column.PropertiesEdit.DisplayFormatString = "c2";
-				});
-				t.Columns.Add("StatusDescription", "Status");
-				t.Columns.Add("DisturbanceDescription", "Kategorien");
-				t.Columns.Add("Comment", "Kommentar");
-			}).Render();
-			//ViewContext.Writer.Write(Html.CustomLabelFor(m => m.Deviations, "Vertragsabweichungen:"));
-			//Html.DevExpress().GridView(t =>
-			//{
-			//	t.Name = "devGridViewSiteDeviations";
-			//	t.KeyFieldName = "Id";
-			//	t.CallbackRouteValues = new { Controller = "Deviation", Action = "PartialDeviations" };
-			//	t.Width = Unit.Percentage(100);
-
-			//	t.Columns.Add(column =>
-			//	{
-			//		column.Caption = "#";
-			//		column.SetDataItemTemplateContent(c =>
-			//		{
-			//			ViewContext.Writer.Write(
-			//				"<a href=\"#\" onclick=\"editDeviation(" + DataBinder.Eval(c.DataItem, "Id") + ")\">Bearbeiten</a>&nbsp;" +
-			//				"<a href=\"#\" onclick=\"confirmDelete(" + DataBinder.Eval(c.DataItem, "Id") + ")\">Löschen</a>"
-			//			);
-			//		});
-			//		column.SetHeaderTemplateContent(c =>
-			//		{
-			//			ViewContext.Writer.Write(
-			//				"<a href=\"#\" onclick=\"editDeviation(-1)\">Neu</a>&nbsp;");
-			//		});
-			//		column.Settings.AllowDragDrop = DefaultBoolean.False;
-			//		column.Settings.AllowSort = DefaultBoolean.False;
-			//		column.Width = 70;
-			//	});
-			//	t.Columns.Add("CustomNumber", "Nummer");
-			//	t.Columns.Add("Description", "Bezeichnung");
-			//	t.Columns.Add(column =>
-			//	{
-			//		column.Caption = "Eingang";
-			//		column.FieldName = "ReceiptDate";
-			//		column.PropertiesEdit.DisplayFormatString = "dd.MM.yyyy";
-			//	});
-			//	t.Columns.Add(column =>
-			//	{
-			//		column.Caption = "Schätzung bew.";
-			//		column.FieldName = "PercentageValue";
-			//		column.PropertiesEdit.DisplayFormatString = "c2";
-			//	});
-			//	t.Columns.Add("StatusDescription", "Status");
-			//	t.Columns.Add("DisturbanceDescription", "Kategorien");
-			//	t.Columns.Add("KindDescription", "Art");
-			//	t.Columns.Add("AppendixDescription", "Nachtrag");
-			//	t.Columns.Add("Comment", "Kommentar");
-			//}).Bind(Model.Deviations).Render();
-
-			//ViewContext.Writer.Write(Html.CustomLabelFor(m => m.Appendices, "Nachträge:"));
-			//Html.DevExpress().GridView(t =>
-			//{
-			//	t.Name = "devGridViewSiteAppendices";
-			//	t.KeyFieldName = "Id";
-			//	t.CallbackRouteValues = new { Controller = "Deviation", Action = "PartialDeviations" };
-			//	t.Width = Unit.Percentage(100);
-
-			//	t.Columns.Add(column =>
-			//	{
-			//		column.Caption = "#";
-			//		column.SetDataItemTemplateContent(c =>
-			//		{
-			//			ViewContext.Writer.Write(
-			//				"<a href=\"#\" onclick=\"editDeviation(" + DataBinder.Eval(c.DataItem, "Id") + ")\">Bearbeiten</a>&nbsp;" +
-			//				"<a href=\"#\" onclick=\"confirmDelete(" + DataBinder.Eval(c.DataItem, "Id") + ")\">Löschen</a>"
-			//			);
-			//		});
-			//		column.SetHeaderTemplateContent(c =>
-			//		{
-			//			ViewContext.Writer.Write(
-			//				"<a href=\"#\" onclick=\"editDeviation(-1)\">Neu</a>&nbsp;");
-			//		});
-			//		column.Settings.AllowDragDrop = DefaultBoolean.False;
-			//		column.Settings.AllowSort = DefaultBoolean.False;
-			//		column.Width = 70;
-			//	});
-			//	t.Columns.Add("CustomNumber", "Nummer");
-			//	t.Columns.Add("Description", "Bezeichnung");
-			//	t.Columns.Add(column =>
-			//	{
-			//		column.Caption = "Angebotssumme";
-			//		column.FieldName = "Value";
-			//		column.PropertiesEdit.DisplayFormatString = "c2";
-			//	});
-			//	t.Columns.Add(column =>
-			//	{
-			//		column.Caption = "Eingang";
-			//		column.FieldName = "ReceiptDate";
-			//		column.PropertiesEdit.DisplayFormatString = "dd.MM.yyyy";
-			//	});
-			//	t.Columns.Add(column =>
-			//	{
-			//		column.Caption = "Verhandlungssumme";
-			//		column.FieldName = "NegotiationValue";
-			//		column.PropertiesEdit.DisplayFormatString = "c2";
-			//	});
-			//	t.Columns.Add("StatusDescription", "Status");
-			//	t.Columns.Add("DisturbanceDescription", "Kategorien");
-			//	t.Columns.Add("Comment", "Kommentar");
-			//}).Bind(Model.Appendices).Render();
-
-			//ViewContext.Writer.Write(Html.CustomLabelFor(m => m.Comment, "Kommentar:"));
-			//ViewContext.Writer.Write(Html.ValidationMessageFor(m => m.Comment).ToHtmlString());
-			//Html.DevExpress().MemoFor(m => m.Comment, t =>
-			//{
-			//	t.Width = new Unit(100, UnitType.Percentage);
-			//	t.Height = new Unit(90, UnitType.Pixel);
-			//}).Render();
+			ViewContext.Writer.Write("<div style='width: 100%; overflow: auto; max-height: 500px; border: 1px solid #d0d0d0'>");
+			{
+				ViewContext.Writer.Write(Html.Partial("~/Views/Sites/_SiteEditTreePartial.cshtml", Model).ToHtmlString());
+			}
+			ViewContext.Writer.Write("</div>");
 
 			ViewContext.Writer.Write("</div>");
 

+ 99 - 0
GreenTree.Nachtragsmanagement.Web/Views/Sites/_SiteEditTreePartial.cshtml

@@ -0,0 +1,99 @@
+@using GreenTree.Nachtragsmanagement.Web.Extensions
+
+@{ 
+	var userContext = GreenTree.Nachtragsmanagement.Core.CommonHelper.UserContext();
+}
+
+@model GreenTree.Nachtragsmanagement.Web.Models.Site.SiteDataModel
+
+@Html.DevExpress().TreeList(t =>
+{
+	t.Name = "devTreeListSiteDeviationAppendices";
+	t.KeyFieldName = "TreeKey";
+	t.ParentFieldName = "TreeParentKey";
+	t.CallbackRouteValues = new { Controller = "Site", Action = "PartialDeviationAppendices", siteId = Model.Id };
+	t.Width = Unit.Percentage(100);
+	t.Settings.GridLines = GridLines.Vertical;
+
+	t.Columns.Add(column =>
+	{
+		column.Caption = "#";
+		column.SetDataCellTemplateContent(c =>
+		{
+			var treeKey = DataBinder.Eval(c.DataItem, "TreeKey").ToString();
+
+			if (treeKey.StartsWith("a"))
+			{
+				ViewContext.Writer.Write(
+					"<a href=\"#\" onclick=\"addDeviationToAppendix(" + DataBinder.Eval(c.DataItem, "Id") + ")\">Neue VA</a>&nbsp;");
+			}
+
+			ViewContext.Writer.Write(
+				"<a href=\"#\" onclick=\"addDeviationToAppendix(" + DataBinder.Eval(c.DataItem, "Id") + ")\">Bearbeiten</a>&nbsp;");
+			ViewContext.Writer.Write(
+				"<a href=\"#\" onclick=\"confirmDeleteAppendix(" + DataBinder.Eval(c.DataItem, "Id") + ")\">Löschen</a>");
+		});
+	});
+
+	t.Columns.Add(column =>
+	{
+		column.Caption = "Nummer";
+		column.SetDataCellTemplateContent(c =>
+		{
+			var treeKey = DataBinder.Eval(c.DataItem, "TreeKey").ToString();
+
+			if (treeKey.StartsWith("a"))
+			{
+				ViewContext.Writer.Write("<b>" + DataBinder.Eval(c.DataItem, "CustomNumber") + "</b>");
+			}
+		});
+	});
+	t.Columns.Add("Description", "Bezeichnung");
+	t.Columns.Add(column =>
+	{
+		column.Caption = "Eingang";
+		column.FieldName = "ReceiptDate";
+		column.PropertiesEdit.DisplayFormatString = "dd.MM.yyyy";
+	});
+	t.Columns.Add(column =>
+	{
+		column.Caption = "Bewertung";
+		column.FieldName = "Value";
+		column.PropertiesEdit.DisplayFormatString = "c2";
+	});
+	t.Columns.Add("StatusDescription", "Status");
+	t.Columns.Add("DistCatDescription", "Kategorien");
+	t.Columns.Add(column =>
+	{
+		column.Caption = "Kommentar";
+		column.CellStyle.Wrap = DefaultBoolean.True;
+		column.SetDataCellTemplateContent(c =>
+		{
+			var id = Convert.ToInt32(DataBinder.Eval(c.DataItem, "Id"));
+			var treeKey = DataBinder.Eval(c.DataItem, "TreeKey").ToString();
+
+			var comment = DataBinder.Eval(c.DataItem, "Comment");
+			var text = comment == null
+				? String.Empty
+				: comment.ToString();
+
+			if (text.ToString().Length > 40)
+			{
+				ViewContext.Writer.Write(text.Substring(0, 40) + " ...");
+
+				if (treeKey.StartsWith("a"))
+					ViewContext.Writer.Write("<a href=\"#\" onclick='parent.showComment(\"appendix\"," + id + ")'><br />Anzeigen</a>");
+				else
+					ViewContext.Writer.Write("<a href=\"#\" onclick='parent.showComment(\"appendix\"," + id + ")'><br />Anzeigen</a>");
+			}
+			else
+				ViewContext.Writer.Write(text);
+		});
+	});
+
+	t.ControlStyle.CssClass += "siteTreeList";
+	t.Styles.Cell.VerticalAlign = VerticalAlign.Top;
+	t.Styles.Cell.Paddings.PaddingTop = new Unit(14, UnitType.Pixel);
+	t.Styles.Cell.Paddings.PaddingBottom = new Unit(14, UnitType.Pixel);
+	t.Styles.AlternatingNode.BackColor = System.Drawing.Color.FromArgb(247, 247, 247);
+}).Bind(Model.SiteTreeData).GetHtml()

+ 1 - 1
GreenTree.Nachtragsmanagement.Web/Views/Sites/_SiteGridPartial.cshtml

@@ -37,7 +37,7 @@
 			column.Width = 70;
 		});
 	}
-	s.Columns.Add("CustomNumber", "Nummer");
+	s.Columns.Add("CustomNumber", "Kostenstelle");
 	s.Columns.Add("Description", "Bauvorhaben");
 	s.Columns.Add(column =>
 	{