Преглед изворни кода

Reporting mit kummulierten Werten begonnen! Änderungen vom 26.10. weitestgehend übernommen!

Arne Diekmann пре 8 година
родитељ
комит
2e26289414
33 измењених фајлова са 1005 додато и 152 уклоњено
  1. 16 0
      GreenTree.Nachtragsmanagement.Core/Domain/Misc/ColorMarker.cs
  2. 1 0
      GreenTree.Nachtragsmanagement.Core/GreenTree.Nachtragsmanagement.Core.csproj
  3. 24 3
      GreenTree.Nachtragsmanagement.Data/AppendixObjectContext.cs
  4. 2 0
      GreenTree.Nachtragsmanagement.Data/GreenTree.Nachtragsmanagement.Data.csproj
  5. 25 0
      GreenTree.Nachtragsmanagement.Data/Mapping/Misc/ColorMarkerMap.cs
  6. 33 0
      GreenTree.Nachtragsmanagement.Data/Migrations/Configuration.cs
  7. 24 0
      GreenTree.Nachtragsmanagement.Web/App_Start/FunctionConfig.cs
  8. BIN
      GreenTree.Nachtragsmanagement.Web/Content/Images/fullscreen-16.png
  9. BIN
      GreenTree.Nachtragsmanagement.Web/Content/Images/normalize-16.png
  10. 3 3
      GreenTree.Nachtragsmanagement.Web/Content/devex.css
  11. 62 6
      GreenTree.Nachtragsmanagement.Web/Controllers/AppendixController.cs
  12. 217 10
      GreenTree.Nachtragsmanagement.Web/Controllers/DeviationController.cs
  13. 1 1
      GreenTree.Nachtragsmanagement.Web/Controllers/LoginController.cs
  14. 14 2
      GreenTree.Nachtragsmanagement.Web/Controllers/MiscController.cs
  15. 25 9
      GreenTree.Nachtragsmanagement.Web/Controllers/SiteController.cs
  16. 118 13
      GreenTree.Nachtragsmanagement.Web/Extensions/GridViewSettingsHelper.cs
  17. 137 3
      GreenTree.Nachtragsmanagement.Web/Extensions/MVCxGridViewGeneratorHelper.cs
  18. 4 6
      GreenTree.Nachtragsmanagement.Web/GreenTree.Nachtragsmanagement.Web.csproj
  19. 5 0
      GreenTree.Nachtragsmanagement.Web/Models/Appendix/AppendixDataModel.cs
  20. 13 0
      GreenTree.Nachtragsmanagement.Web/Models/Appendix/OrderInvoiceCreatedDataModel.cs
  21. 2 1
      GreenTree.Nachtragsmanagement.Web/Models/Config/ConfigItemDataModel.cs
  22. 41 1
      GreenTree.Nachtragsmanagement.Web/Models/Deviation/DeviationDataModel.cs
  23. 8 8
      GreenTree.Nachtragsmanagement.Web/Models/Global/PrintGridModel.cs
  24. 5 3
      GreenTree.Nachtragsmanagement.Web/Models/Site/SiteDataModel.cs
  25. 0 51
      GreenTree.Nachtragsmanagement.Web/Reports/XtraReportGridView.Designer.cs
  26. 0 18
      GreenTree.Nachtragsmanagement.Web/Reports/XtraReportGridView.cs
  27. 14 0
      GreenTree.Nachtragsmanagement.Web/Views/Appendices/View.cshtml
  28. 24 0
      GreenTree.Nachtragsmanagement.Web/Views/Appendices/_AppendixEditPartial.cshtml
  29. 100 0
      GreenTree.Nachtragsmanagement.Web/Views/Appendices/_EditOrderInvoiceCreatedPartial.cshtml
  30. 6 0
      GreenTree.Nachtragsmanagement.Web/Views/Config/_ConfigItemValueEditPartial.cshtml
  31. 15 1
      GreenTree.Nachtragsmanagement.Web/Views/Deviations/View.cshtml
  32. 64 0
      GreenTree.Nachtragsmanagement.Web/Views/Home/Index.cshtml
  33. 2 13
      GreenTree.Nachtragsmanagement.Web/Views/Shared/_PrintDocumentViewerPartial.cshtml

+ 16 - 0
GreenTree.Nachtragsmanagement.Core/Domain/Misc/ColorMarker.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.Misc
+{
+    public class ColorMarker : BaseEntity
+    {
+        public string EntityType { get; set; }
+        public int EntityId { get; set; }
+        public string HexColor { get; set; }
+        public int RandomId { get; set; }
+    }
+}

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

@@ -101,6 +101,7 @@
     <Compile Include="Domain\Logging\Log.cs" />
     <Compile Include="Domain\Logging\LogEntityActivity.cs" />
     <Compile Include="Domain\Logging\LogLevel.cs" />
+    <Compile Include="Domain\Misc\ColorMarker.cs" />
     <Compile Include="Domain\Misc\DbContextSpec.cs" />
     <Compile Include="Domain\Misc\MailNotification.cs" />
     <Compile Include="Domain\Site\Site.cs" />

+ 24 - 3
GreenTree.Nachtragsmanagement.Data/AppendixObjectContext.cs

@@ -40,9 +40,25 @@ namespace GreenTree.Nachtragsmanagement.Data
         /// <summary>
         /// Initializes a new instance of the AppendixObjectContext-class
         /// </summary>
+        public AppendixObjectContext() : base("DefaultConnection")
+        {
+            SetDbContextSettings("DefaultConnection");
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the AppendixObjectContext class
+        /// </summary>
         /// <param name="nameOrConnectionString"></param>
         public AppendixObjectContext(string nameOrConnectionString)
             : base(nameOrConnectionString)
+        {
+            SetDbContextSettings(nameOrConnectionString);
+        }
+
+        /// <summary>
+        /// Sets initial DbContext settings and sets
+        /// </summary>
+        private void SetDbContextSettings(string nameOrConnectionString)
         {
             var userSet = Set<User>();
             var roleSet = Set<Role>();
@@ -60,9 +76,10 @@ namespace GreenTree.Nachtragsmanagement.Data
             var dbContextSpecSet = Set<DbContextSpec>();
             var configItemSet = Set<ConfigItem>();
             var loggingSet = Set<Log>();
+            var colorMarkerSet = Set<ColorMarker>();
 
             _dbSets.AddRange(
-                new object[] 
+                new object[]
                 {
                     userSet,
                     roleSet,
@@ -79,12 +96,15 @@ namespace GreenTree.Nachtragsmanagement.Data
                     mailNotificationSet,
                     dbContextSpecSet,
                     configItemSet,
-                    loggingSet
+                    loggingSet,
+                    colorMarkerSet
                 }
             );
 
             //Database.SetInitializer(new CreateDatabaseIfNotExists<AppendixObjectContext>());
-            Database.SetInitializer(new DropCreateDatabaseIfModelChanges<AppendixObjectContext>());
+            //Database.SetInitializer(new DropCreateDatabaseIfModelChanges<AppendixObjectContext>());
+            Database.SetInitializer(
+                new MigrateDatabaseToLatestVersion<AppendixObjectContext, Migrations.Configuration>("DefaultConnection"));
 
             Database.CreateIfNotExists();
 
@@ -116,6 +136,7 @@ namespace GreenTree.Nachtragsmanagement.Data
             modelBuilder.Configurations.Add(new DbContextSpecMap());
             modelBuilder.Configurations.Add(new ConfigItemMap());
             modelBuilder.Configurations.Add(new LogMap());
+            modelBuilder.Configurations.Add(new ColorMarkerMap());
 
             base.OnModelCreating(modelBuilder);
         }

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

@@ -62,12 +62,14 @@
     <Compile Include="Mapping\Deviation\StatusMap.cs" />
     <Compile Include="Mapping\Invoice\InvoiceMap.cs" />
     <Compile Include="Mapping\Logging\LogMap.cs" />
+    <Compile Include="Mapping\Misc\ColorMarkerMap.cs" />
     <Compile Include="Mapping\Misc\DbContextSpecMap.cs" />
     <Compile Include="Mapping\Misc\MailNotificationMap.cs" />
     <Compile Include="Mapping\Site\SiteMap.cs" />
     <Compile Include="Mapping\User\FunctionMap.cs" />
     <Compile Include="Mapping\User\RoleMap.cs" />
     <Compile Include="Mapping\User\UserMap.cs" />
+    <Compile Include="Migrations\Configuration.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>

+ 25 - 0
GreenTree.Nachtragsmanagement.Data/Mapping/Misc/ColorMarkerMap.cs

@@ -0,0 +1,25 @@
+using GreenTree.Nachtragsmanagement.Core.Domain.Misc;
+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.Misc
+{
+    public class ColorMarkerMap : EntityTypeConfiguration<ColorMarker>
+    {
+        public ColorMarkerMap()
+        {
+            ToTable("ColorMarker");
+
+            HasKey(f => f.Id);
+
+            Property(f => f.EntityType);
+            Property(f => f.EntityId);
+            Property(f => f.HexColor);
+            Property(f => f.RandomId);
+        }
+    }
+}

+ 33 - 0
GreenTree.Nachtragsmanagement.Data/Migrations/Configuration.cs

@@ -0,0 +1,33 @@
+using System;
+using System.Data.Entity;
+using System.Data.Entity.Migrations;
+using System.Linq;
+
+namespace GreenTree.Nachtragsmanagement.Data.Migrations
+{
+    internal sealed class Configuration : DbMigrationsConfiguration<AppendixObjectContext>
+    {
+        public Configuration()
+        {
+            AutomaticMigrationsEnabled = true;
+
+            ContextKey = "GreenTree.Nachtragsmanagement.Data.AppendixObjectContext";
+        }
+
+        protected override void Seed(AppendixObjectContext context)
+        {
+            //  This method will be called after migrating to the latest version.
+
+            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
+            //  to avoid creating duplicate seed data. E.g.
+            //
+            //    context.People.AddOrUpdate(
+            //      p => p.FullName,
+            //      new Person { FullName = "Andrew Peters" },
+            //      new Person { FullName = "Brice Lambson" },
+            //      new Person { FullName = "Rowan Miller" }
+            //    );
+            //
+        }
+    }
+}

+ 24 - 0
GreenTree.Nachtragsmanagement.Web/App_Start/FunctionConfig.cs

@@ -178,6 +178,14 @@ namespace GreenTree.Nachtragsmanagement.Web.App_Start
                     Plugin = "System"
                 },
                 new Function
+                {
+                    Name = "Site-Sites-Edit-Comment",
+                    Description = "Baustellen Kommentar editieren",
+                    GroupName = "Site-Sites",
+                    IsMenuMember = false,
+                    Plugin = "System"
+                },
+                new Function
                 {
                     Name = "Site-Sites-Delete",
                     Description = "Baustellen löschen",
@@ -218,6 +226,14 @@ namespace GreenTree.Nachtragsmanagement.Web.App_Start
                     Plugin = "System"
                 },
                 new Function
+                {
+                    Name = "Deviation-Deviations-Edit-Comment",
+                    Description = "Vertragsabweichungen Kommentar editieren",
+                    GroupName = "Deviation-Deviations",
+                    IsMenuMember = false,
+                    Plugin = "System"
+                },
+                new Function
                 {
                     Name = "Deviation-Claims",
                     Description = "VA-Stammdaten",
@@ -274,6 +290,14 @@ namespace GreenTree.Nachtragsmanagement.Web.App_Start
                     Plugin = "System"
                 },
                 new Function
+                {
+                    Name = "Appendix-Appendices-Edit-Comment",
+                    Description = "Nachträge Kommentar editieren",
+                    GroupName = "Appendix-Appendices",
+                    IsMenuMember = false,
+                    Plugin = "System"
+                },
+                new Function
                 {
                     Name = "Appendix-Claims",
                     Description = "NT-Stammdaten",

BIN
GreenTree.Nachtragsmanagement.Web/Content/Images/fullscreen-16.png


BIN
GreenTree.Nachtragsmanagement.Web/Content/Images/normalize-16.png


+ 3 - 3
GreenTree.Nachtragsmanagement.Web/Content/devex.css

@@ -23,9 +23,9 @@
 .devExBorderTop { border-top-style: solid !important; }
 .devExBorderTopGray { border-top-color: #D9D9D9 !important; }
 .devExBorderTopSmall { border-top-width: 1px !important; }
-.devExBorderBottom { border-bottom-style: solid !important; }
-.devExBorderBottomGray { border-bottom-color: #D9D9D9 !important; }
-.devExBorderBottomSmall { border-bottom-width: 1px !important; }
+.devExBorderBottom, .devExBorderBottom:hover { border-bottom-style: solid !important; }
+.devExBorderBottomGray, .devExBorderBottomGray:hover { border-bottom-color: #D9D9D9 !important; }
+.devExBorderBottomSmall, devExBorderBottomSmall:hover { border-bottom-width: 1px !important; }
 .devExAllowDrag { cursor: move; }
 
 .devExDisplayHidden { display: none; }

+ 62 - 6
GreenTree.Nachtragsmanagement.Web/Controllers/AppendixController.cs

@@ -136,7 +136,6 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             {
                 var generator = new MVCReportGeneratonHelper();
 
-                //generator.CustomizeColumn += new CustomizeColumnEventHandler(generator_CustomizeColumn);
                 generator.CustomizeFormattingRules += new CustomizeFormattingRulesEventHandler(generator_CustomizeFormattingRules);
                 generator.CustomizeColumnsCollection += new CustomizeColumnsCollectionEventHandler(generator_CustomizeColumnsCollection);
                 generator.CustomizeGroupColumnSummary += new CustomizeColumnGroupSummaryEventHandler(generator_CustomizeGroupColumnSummary);
@@ -145,11 +144,23 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                 var report = generator.GenerateMVCReport(gridViewState, appendixModels, "Nachtragsliste");
 
                 if (displayMode == "popup")
+                {
                     return PartialView("~/Views/Shared/_PrintPopupPartial.cshtml",
-                        new PrintGridModel(report, "Appendix", "ExportPartialAppendices", "devGridViewAppendix"));
+                        new PrintGridModel(report, "devGridViewAppendix",
+                            new { Controller = "Appendix", Action = "ExportPartialAppendices",
+                                displayMode = "callback", exportformat = String.Empty },
+                            new { Controller = "Appendix", Action = "ExportPartialAppendices",
+                                displayMode = "export", exportformat = String.Empty }));
+                }
                 else if (displayMode == "callback")
+                {
                     return PartialView("~/Views/Shared/_PrintDocumentViewerPartial.cshtml",
-                        new PrintGridModel(report, "Appendix", "ExportPartialAppendices", "devGridViewAppendix"));
+                        new PrintGridModel(report, "devGridViewAppendix",
+                            new { Controller = "Appendix", Action = "ExportPartialAppendices",
+                                displayMode = "callback", exportformat = String.Empty },
+                            new { Controller = "Appendix", Action = "ExportPartialAppendices",
+                                displayMode = "export", exportformat = String.Empty }));
+                }
                 else if (displayMode == "export")
                 {
                     switch (exportformat.ToLower())
@@ -212,6 +223,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                 if (column.FieldName == "RelationOfferingToNegotiation") { column.ColumnWidth = 70; }
                 if (column.FieldName == "RelationOfferingToDeviations") { column.ColumnWidth = 80; }
                 if (column.FieldName == "StateDescription") { column.ColumnWidth = 70; }
+                if (column.FieldName == "OrderInvoiceCreatedDescription") { column.ColumnWidth = 45; }
                 if (column.FieldName == "Comment") { column.IsVisible = false; column.IsDetail = true; }
             }
         }
@@ -283,6 +295,50 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             return PartialView("~/Views/Appendices/_AppendixEditPartial.cshtml", appendixModel);
         }
 
+        /// <summary>
+        /// Gets if an appendix OrderInvoiceCreated field and provides an edit form
+        /// </summary>
+        /// <param name="id">The entity id.</param>
+        public ActionResult EditOrderInvoiceCreated(int id)
+        {
+            var appendix = _appendixService.GetAppendixById(id);
+
+            if (appendix == null)
+                return new EmptyResult();
+
+            var model = new OrderInvoiceCreatedDataModel
+            {
+                AppendixId = appendix.Id,
+                OrderInvoiceCreated = appendix.OrderInvoiceCreated
+            };
+
+            return PartialView("~/Views/Appendices/_EditOrderInvoiceCreatedPartial.cshtml", model);
+        }
+
+        /// <summary>
+        /// Sets the OrderInvoiceCreated status for a given appendix
+        /// </summary>
+        [HttpPost, ValidateInput(false)]
+        public ActionResult EditOrderInvoiceCreated(OrderInvoiceCreatedDataModel model)
+        {
+            if (model == null)
+                return new EmptyResult();
+
+            var appendix = _appendixService.GetAppendixById(model.AppendixId);
+
+            if (appendix == null)
+                return new EmptyResult();
+
+            appendix.OrderInvoiceCreated = model.OrderInvoiceCreated;
+
+            _appendixService.UpdateAppendix(appendix);
+
+            return new JsonResult
+            {
+                Data = "success"
+            };
+        }
+
         /// <summary>
         /// Partial edit result if ModelState is valid, otherwise simple JSON result for success
         /// </summary>
@@ -293,9 +349,9 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             try
             {
                 appendixModel.CategoryValueEntities =
-            appendixModel.CategoryEntities
-                .Select(r => JsonConvert.DeserializeObject<CategoryValueDataModel>(r))
-                .ToList();
+                    appendixModel.CategoryEntities
+                        .Select(r => JsonConvert.DeserializeObject<CategoryValueDataModel>(r))
+                        .ToList();
 
                 for (int i = 0; i < appendixModel.CategoryValueEntities.Count; i++)
                     appendixModel.CategoryValueEntities.ElementAt(i).Json = appendixModel.CategoryEntities.ElementAt(i);

+ 217 - 10
GreenTree.Nachtragsmanagement.Web/Controllers/DeviationController.cs

@@ -1,9 +1,11 @@
 using DevExpress.Web.Mvc;
+using DevExpress.XtraReports.UI;
 using GreenTree.Nachtragsmanagement.Core;
 using GreenTree.Nachtragsmanagement.Core.Authentication;
 using GreenTree.Nachtragsmanagement.Core.Domain.Appendix;
 using GreenTree.Nachtragsmanagement.Core.Domain.Deviation;
 using GreenTree.Nachtragsmanagement.Services.Appendix;
+using GreenTree.Nachtragsmanagement.Services.Configuration;
 using GreenTree.Nachtragsmanagement.Services.Deviation;
 using GreenTree.Nachtragsmanagement.Services.Logging;
 using GreenTree.Nachtragsmanagement.Services.Site;
@@ -13,8 +15,10 @@ using GreenTree.Nachtragsmanagement.Web.Models.Appendix;
 using GreenTree.Nachtragsmanagement.Web.Models.Deviation;
 using GreenTree.Nachtragsmanagement.Web.Models.Global;
 using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
 using System;
 using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
 using System.Net.Mime;
 using System.Web;
@@ -30,19 +34,22 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
         private readonly ISiteService _siteService;
         private readonly IUserHelper _userHelper;
         private readonly ILogger _logger;
+        private readonly IConfigurationService _configurationService;
 
         public DeviationController(
             IDeviationService deviationService,
             IAppendixService appendixService,
             ISiteService siteService,
             IUserHelper userHelper,
-            ILogger logger)
+            ILogger logger,
+            IConfigurationService configurationService)
         {
             _deviationService = deviationService;
             _appendixService = appendixService;
             _siteService = siteService;
             _userHelper = userHelper;
             _logger = logger;
+            _configurationService = configurationService;
 
             ViewData["AllDisturbances"] = _deviationService.GetAllDisturbances();
             ViewData["AllStatuses"] = _deviationService.GetAllStatuses();
@@ -61,7 +68,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
 
             var deviations = _deviationService.GetAllUserAssignedDeviations(currentUser);
             var deviationModels = deviations
-                .Select(u => DeviationDataModel.FromDeviation(u, false))
+                .Select(u => DeviationDataModel.FromDeviation(u, false, _configurationService))
                 .ToList();
 
             return View("~/Views/Deviations/View.cshtml", deviationModels);
@@ -81,7 +88,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                     JsonRequestBehavior = JsonRequestBehavior.AllowGet
                 };
 
-            var deviationModel = DeviationDataModel.FromDeviation(deviation, false);
+            var deviationModel = DeviationDataModel.FromDeviation(deviation, false, _configurationService);
 
             return new JsonResult
             {
@@ -94,15 +101,18 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
         /// Callback result for deviation grid
         /// </summary>
         /// <param name="scrollHeight">The height of the grid scrollable component.</param>
-        public ActionResult PartialDeviations(int scrollHeight = -1)
+        public ActionResult PartialDeviations(string customFilters, int scrollHeight = -1)
         {
             var currentUser = _userHelper.FromCookies();
 
             var deviations = _deviationService.GetAllUserAssignedDeviations(currentUser);
             var deviationModels = deviations
-                .Select(u => DeviationDataModel.FromDeviation(u, false))
+                .Select(u => DeviationDataModel.FromDeviation(u, false, _configurationService))
                 .ToList();
 
+            if (!String.IsNullOrEmpty(customFilters))
+                UseCustomFilters(customFilters, deviationModels);
+
             ViewData["ScrollHeight"] = scrollHeight;
 
             return PartialView("~/Views/Deviations/_DeviationGridPartial.cshtml", deviationModels);
@@ -112,7 +122,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
         /// Export result for deviation grid
         /// </summary>
         [HttpPost]
-        public ActionResult ExportPartialDeviations(string displayMode, string exportformat)
+        public ActionResult ExportPartialDeviations(string customFilters, string displayMode, string exportformat)
         {
             if (String.IsNullOrEmpty(displayMode))
                 return new EmptyResult();
@@ -121,9 +131,12 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
 
             var deviations = _deviationService.GetAllUserAssignedDeviations(currentUser);
             var deviationModels = deviations
-                .Select(u => DeviationDataModel.FromDeviation(u, false))
+                .Select(u => DeviationDataModel.FromDeviation(u, false, _configurationService))
                 .ToList();
 
+            if (!String.IsNullOrEmpty(customFilters))
+                UseCustomFilters(customFilters, deviationModels);
+
             var viewContext = new ViewContext();
             var viewPage = new ViewPage();
             var htmlHelper = new System.Web.Mvc.HtmlHelper(viewContext, viewPage);
@@ -136,18 +149,35 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             {
                 var generator = new MVCReportGeneratonHelper();
 
+                generator.CustomizeFormattingRules += new CustomizeFormattingRulesEventHandler(generator_CustomizeFormattingRules);
                 generator.CustomizeColumnsCollection += new CustomizeColumnsCollectionEventHandler(generator_CustomizeColumnsCollection);
                 generator.CustomizeGroupColumnSummary += new CustomizeColumnGroupSummaryEventHandler(generator_CustomizeGroupColumnSummary);
                 generator.CustomizeTotalColumnSummary += new CustomizeColumnTotalSummaryEventHandler(generator_CustomizeTotalColumnSummary);
+                generator.SummaryReset += new SummaryResetEventHandler(generator_SummaryReset);
+                generator.SummaryRowChanged += new SummaryRowChangedEventHandler(generator_SummaryRowChanged);
+                generator.PageSummaryGetResult += new SummaryGetResultHandler(generator_PageSummaryGetResult);
+                generator.TotalSummaryGetResult += new SummaryGetResultHandler(generator_TotalSummaryGetResult);
 
                 var report = generator.GenerateMVCReport(gridViewState, deviationModels, "Vertragsabweichungsliste");
 
                 if (displayMode == "popup")
+                {
                     return PartialView("~/Views/Shared/_PrintPopupPartial.cshtml",
-                        new PrintGridModel(report, "Deviation", "ExportPartialDeviations", "devGridViewDeviation"));
+                        new PrintGridModel(report, "devGridViewDeviation",
+                            new { Controller = "Deviation", Action = "ExportPartialDeviations",
+                                customFilters = customFilters, displayMode = "callback", exportformat = String.Empty },
+                            new { Controller = "Deviation", Action = "ExportPartialDeviations",
+                                customFilters = customFilters, displayMode = "export", exportformat = String.Empty }));
+                }
                 else if (displayMode == "callback")
+                {
                     return PartialView("~/Views/Shared/_PrintDocumentViewerPartial.cshtml",
-                        new PrintGridModel(report, "Deviation", "ExportPartialDeviations", "devGridViewDeviation"));
+                        new PrintGridModel(report, "devGridViewDeviation",
+                            new { Controller = "Deviation", Action = "ExportPartialDeviations",
+                                customFilters = customFilters, displayMode = "callback", exportformat = String.Empty },
+                            new { Controller = "Deviation", Action = "ExportPartialDeviations",
+                                customFilters = customFilters, displayMode = "export", exportformat = String.Empty }));
+                }
                 else if (displayMode == "export")
                 {
                     switch (exportformat.ToLower())
@@ -158,12 +188,15 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                             settings.TotalSummary["PercentageValue"].DisplayFormat = "{0:c2}";
                             settings.TotalSummary["DaysReceiptToAppendixOffering"].DisplayFormat = "Schnitt = {0:n0}";
                             settings.TotalSummary["SiteDescription"].DisplayFormat = "Anzahl = {0:n0}";
+                            settings.TotalSummary["DisturbanceValuesDescription"].DisplayFormat = "{0:c2}";
                             return GridViewExtension.ExportToXlsx(settings, deviationModels);
                         case "xls":
                             settings.TotalSummary["Value"].DisplayFormat = "{0:c2}";
                             settings.TotalSummary["Percentage"].DisplayFormat = "{0:p0}";
+                            settings.TotalSummary["PercentageValue"].DisplayFormat = "{0:c2}";
                             settings.TotalSummary["DaysReceiptToAppendixOffering"].DisplayFormat = "Schnitt = {0:n0}";
                             settings.TotalSummary["SiteDescription"].DisplayFormat = "Anzahl = {0:n0}";
+                            settings.TotalSummary["DisturbanceValuesDescription"].DisplayFormat = "{0:c2}";
                             return GridViewExtension.ExportToXls(settings, deviationModels);
                         case "pdf":
                             report.Name = "VA-Liste";
@@ -177,6 +210,134 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                 return new EmptyResult();
         }
 
+        private decimal totalCustomSummaryValueDaysReceiptToAppendixOffering = 0;
+        private decimal totalCustomSummaryValueDisturbanceValueSum = 0;
+
+        private decimal accumulatedCustomSummaryValueDaysReceiptToAppendixOffering = 0;
+        private decimal accumulatedCustomSummaryValueDisturbanceValueSum = 0;
+        private decimal accumulatedValue = 0;
+        private decimal accumulatedCount = 0;
+
+        /// <summary>
+        /// Reset custom summaries for corresponding group type
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="e"></param>
+        private void generator_SummaryReset(object source, CustomSummaryResetEventArgs e)
+        {
+            totalCustomSummaryValueDaysReceiptToAppendixOffering = 0;
+            totalCustomSummaryValueDisturbanceValueSum = 0;
+        }
+
+        /// <summary>
+        /// Get custom summary values
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="e"></param>
+        private void generator_SummaryRowChanged(object source, CustomSummaryRowChangedEventArgs e)
+        {
+            if (e.FieldName == "DaysReceiptToAppendixOffering")
+                totalCustomSummaryValueDaysReceiptToAppendixOffering += 
+                    Convert.ToDecimal(((XtraReport)source).GetCurrentColumnValue("DaysReceiptToAppendixOffering"));
+
+            if (e.FieldName == "DisturbanceValuesDescription")
+            {
+                totalCustomSummaryValueDisturbanceValueSum +=
+                    Convert.ToDecimal(((XtraReport)source).GetCurrentColumnValue("DisturbanceValueSum"));
+            }
+        }
+
+        /// <summary>
+        /// Set custom summary result for page
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="e"></param>
+        private void generator_PageSummaryGetResult(object source, SummaryGetResultEventArgs e)
+        {
+            var label = (XRLabel)source;
+
+            if (label.Tag.ToString() == "DaysReceiptToAppendixOffering")
+            {
+                accumulatedCustomSummaryValueDaysReceiptToAppendixOffering += e.CalculatedValues.OfType<int>().Sum();
+                e.Result = accumulatedCustomSummaryValueDaysReceiptToAppendixOffering;
+            }
+
+            if (label.Tag.ToString() == "DisturbanceValueSum")
+            {
+                accumulatedCustomSummaryValueDisturbanceValueSum += e.CalculatedValues.OfType<decimal>().Sum();
+                e.Result = accumulatedCustomSummaryValueDisturbanceValueSum;
+            }
+
+            if (label.Tag.ToString() == "Value")
+            {
+                accumulatedValue += e.CalculatedValues.OfType<decimal>().Sum();
+                e.Result = accumulatedValue;
+            }
+
+            if (label.Tag.ToString() == "SiteDescription")
+            {
+                accumulatedCount += e.CalculatedValues.Count;
+                e.Result = accumulatedCount;
+            }
+
+            e.Handled = true;
+        }
+
+        /// <summary>
+        /// Set custom summary result for full report
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="e"></param>
+        private void generator_TotalSummaryGetResult(object source, SummaryGetResultEventArgs e)
+        {
+            var label = (XRLabel)source;
+
+            if (label.Tag.ToString() == "DaysReceiptToAppendixOffering")
+                e.Result = totalCustomSummaryValueDaysReceiptToAppendixOffering;
+
+            if (label.Tag.ToString() == "DisturbanceValuesDescription")
+                e.Result = totalCustomSummaryValueDisturbanceValueSum;
+
+            e.Handled = true;
+        }
+
+        /// <summary>
+        /// Customize formatting
+        /// </summary>
+        /// <param name="source"></param>
+        /// <param name="e"></param>
+        private void generator_CustomizeFormattingRules(object source, CustomFormattingRulesEventArgs e)
+        {
+            var colorLevel1 = _configurationService.TryGetConfigItemValue<string>(
+                "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.HexColorLevel1", "#FFD800");
+            var ageDaysLevel1 = _configurationService.TryGetConfigItemValue<int>(
+                "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.AgeDaysLevel1", 40);
+
+            var colorLevel2 = _configurationService.TryGetConfigItemValue<string>(
+                "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.HexColorLevel2", "#FF6A00");
+            var ageDaysLevel2 = _configurationService.TryGetConfigItemValue<int>(
+                "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.AgeDaysLevel2", 60);
+
+            var ageDaysLevel1Rule = new FormattingRule
+            {
+                Condition = String.Format("[DaysReceiptDateToday] >= {0}", ageDaysLevel1),
+                Name = "AgeDaysLevel1BackColor"
+            };
+
+            ageDaysLevel1Rule.Formatting.BackColor = ColorTranslator.FromHtml(colorLevel1);
+
+            var ageDaysLevel2Rule = new FormattingRule
+            {
+                Condition = String.Format("[DaysReceiptDateToday] >= {0}", ageDaysLevel2),
+                Name = "AgeDaysLevel2BackColor"
+            };
+
+            ageDaysLevel2Rule.Formatting.BackColor = ColorTranslator.FromHtml(colorLevel2);
+
+            e.Rules.Add(ageDaysLevel1Rule);
+            e.Rules.Add(ageDaysLevel2Rule);
+        }
+
         /// <summary>
         /// Customize created columns
         /// </summary>
@@ -202,6 +363,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             if (e.FieldName == "Percentage") { e.Summary.FormatString = "Bew. Ø = {0:p0}"; }
             if (e.FieldName == "PercentageValue") { e.Summary.FormatString = "S. Bew. ∑ = {0:c2}"; }
             if (e.FieldName == "DaysReceiptToAppendixOffering") { e.Summary.FormatString = "Tage VA-NT = {0:n0}"; }
+            if (e.FieldName == "DisturbanceValuesDescription") { e.Summary.FormatString = "Kat. ∑ = {0:c2}"; }
         }
 
         /// <summary>
@@ -214,6 +376,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             if (e.FieldName == "Percentage") { e.Summary.FormatString = "{0:p0}"; }
             if (e.FieldName == "PercentageValue") { e.Summary.FormatString = "{0:c2}"; }
             if (e.FieldName == "DaysReceiptToAppendixOffering") { e.Summary.FormatString = "{0:n0}"; }
+            if (e.FieldName == "DisturbanceValuesDescription") { e.Summary.FormatString = "{0:c2}"; }
         }
 
         /// <summary>
@@ -223,7 +386,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
         public ActionResult EditDeviation(int id = -1)
         {
             var deviation = _deviationService.GetDeviationById(id);
-            var deviationModel = DeviationDataModel.FromDeviation(deviation, true);
+            var deviationModel = DeviationDataModel.FromDeviation(deviation, true, _configurationService);
 
             var defaultKind = _deviationService.GetDefaultKind();
             var defaultStatus = _deviationService.GetDefaultStatus();
@@ -863,5 +1026,49 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
         }
 
         #endregion
+
+        #region Helper
+
+        /// <summary>
+        /// Uses a customFilter on a collection of deviation data models
+        /// </summary>
+        /// <param name="customFilters">Custom filter string.</param>
+        /// <param name="models">Model list.</param>
+        private void UseCustomFilters(string customFilters, List<DeviationDataModel> models)
+        {
+            var filters = JsonConvert.DeserializeObject(customFilters) as JObject;
+
+            if (filters["DisturbanceValuesDescription"] != null && !String.IsNullOrEmpty(filters["DisturbanceValuesDescription"].Value<string>()))
+            {
+                var removables = new List<DeviationDataModel>();
+                var filterVal = filters["DisturbanceValuesDescription"].Value<string>();
+
+                foreach (var model in models)
+                {
+                    var filterItemExists = model.DisturbanceValueEntities
+                        .Any(d => d.Description.ToLower().Contains(filterVal.ToLower()));
+
+                    if (!filterItemExists)
+                        removables.Add(model);
+                    else
+                    {
+                        var removeableValues = model.DisturbanceValueEntities
+                            .Where(d => !d.Description.ToLower().Contains(filterVal.ToLower()))
+                            .ToList();
+
+                        foreach (var removeableValue in removeableValues)
+                            model.DisturbanceValueEntities.Remove(removeableValue);
+
+                        if (removeableValues.Count > 0)
+                            model.DisturbanceValueEntities.Add(new DisturbanceValueDataModel { Description = "( ausgefilterte Kategorien )" });
+                    }
+                }
+
+                foreach (var removeable in removables)
+                    models.Remove(removeable);
+            }
+        }
+
+        #endregion
     }
 }

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

@@ -64,7 +64,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                 user.CurrentRole = user.Roles.First(r1 => r1.Level == user.Roles.Max(r2 => r2.Level));
 
                 if (model.IsPermanent.HasValue && model.IsPermanent.Value)
-                    _userHelper.ToCookies(user, DateTime.MaxValue);
+                    _userHelper.ToCookies(user, DateTime.Now.AddYears(1));
                 else
                     _userHelper.ToCookies(user, DateTime.Now.AddHours(2));
 

+ 14 - 2
GreenTree.Nachtragsmanagement.Web/Controllers/MiscController.cs

@@ -385,11 +385,23 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                 var report = generator.GenerateMVCReport(gridViewState, logModels, "Logliste");
 
                 if (displayMode == "popup")
+                {
                     return PartialView("~/Views/Shared/_PrintPopupPartial.cshtml",
-                        new PrintGridModel(report, "Misc", "ExportPartialLogs", "devGridViewLog"));
+                        new PrintGridModel(report, "devGridViewLog",
+                            new { Controller = "Misc", Action = "ExportPartialLogs",
+                                displayMode = "callback", exportformat = String.Empty },
+                            new { Controller = "Misc", Action = "ExportPartialLogs",
+                                displayMode = "export", exportformat = String.Empty }));
+                }
                 else if (displayMode == "callback")
+                { 
                     return PartialView("~/Views/Shared/_PrintDocumentViewerPartial.cshtml",
-                        new PrintGridModel(report, "Misc", "ExportPartialLogs", "devGridViewLog"));
+                        new PrintGridModel(report, "devGridViewLog",
+                            new { Controller = "Misc", Action = "ExportPartialLogs",
+                                displayMode = "callback", exportformat = String.Empty },
+                            new { Controller = "Misc", Action = "ExportPartialLogs",
+                                displayMode = "export", exportformat = String.Empty }));
+                }
                 else if (displayMode == "export")
                 {
                     switch (exportformat.ToLower())

+ 25 - 9
GreenTree.Nachtragsmanagement.Web/Controllers/SiteController.cs

@@ -7,6 +7,7 @@ using GreenTree.Nachtragsmanagement.Core.Authentication;
 using GreenTree.Nachtragsmanagement.Core.Domain.Deviation;
 using GreenTree.Nachtragsmanagement.Core.Domain.User;
 using GreenTree.Nachtragsmanagement.Services.Appendix;
+using GreenTree.Nachtragsmanagement.Services.Configuration;
 using GreenTree.Nachtragsmanagement.Services.Deviation;
 using GreenTree.Nachtragsmanagement.Services.Logging;
 using GreenTree.Nachtragsmanagement.Services.Site;
@@ -37,6 +38,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
         private readonly IUserService _userService;
         private readonly IUserHelper _userHelper;
         private readonly ILogger _logger;
+        private readonly IConfigurationService _configurationService;
 
         public SiteController(
             ISiteService siteService,
@@ -44,7 +46,8 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             IAppendixService appendixService,
             IUserService userService,
             IUserHelper userHelper,
-            ILogger logger)
+            ILogger logger,
+            IConfigurationService configurationService)
         {
             _siteService = siteService;
             _deviationService = deviationService;
@@ -52,6 +55,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
             _userService = userService;
             _userHelper = userHelper;
             _logger = logger;
+            _configurationService = configurationService;
 
             ViewData["AllUsers"] = _userService.GetAllUsers();
             ViewData["AllUsersWithRole"] =
@@ -79,7 +83,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
 
             var sites = _siteService.GetAllUserAssignedSites(currentUser);
             var siteModels = sites
-                .Select(u => SiteDataModel.FromSite(u, false))
+                .Select(u => SiteDataModel.FromSite(u, false, _configurationService))
                 .ToList();
 
             return View("~/Views/Sites/View.cshtml", siteModels);
@@ -99,7 +103,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                     JsonRequestBehavior = JsonRequestBehavior.AllowGet
                 };
 
-            var siteModel = SiteDataModel.FromSite(site, false);
+            var siteModel = SiteDataModel.FromSite(site, false, _configurationService);
             var siteTreeModel = SiteTreeDataModel.TreeFromSite(site);
 
             siteModel.SiteTreeData = siteTreeModel;
@@ -121,7 +125,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
 
             var sites = _siteService.GetAllUserAssignedSites(currentUser);
             var siteModels = sites
-                .Select(u => SiteDataModel.FromSite(u, false))
+                .Select(u => SiteDataModel.FromSite(u, false, _configurationService))
                 .ToList();
 
             ViewData["ScrollHeight"] = scrollHeight;
@@ -142,7 +146,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
 
             var sites = _siteService.GetAllUserAssignedSites(currentUser);
             var siteModels = sites
-                .Select(u => SiteDataModel.FromSite(u, false))
+                .Select(u => SiteDataModel.FromSite(u, false, _configurationService))
                 .ToList();
 
             var viewContext = new ViewContext();
@@ -164,11 +168,23 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
                 var report = generator.GenerateMVCReport(gridViewState, siteModels, "Baustellenliste");
 
                 if (displayMode == "popup")
+                {
                     return PartialView("~/Views/Shared/_PrintPopupPartial.cshtml",
-                        new PrintGridModel(report, "Site", "ExportPartialSites", "devGridViewSite"));
+                        new PrintGridModel(report, "devGridViewSite",
+                            new { Controller = "Site", Action = "ExportPartialSites",
+                                displayMode = "callback", exportformat = String.Empty },
+                            new { Controller = "Site", Action = "ExportPartialSites",
+                                displayMode = "export", exportformat = String.Empty }));
+                }
                 else if (displayMode == "callback")
+                {
                     return PartialView("~/Views/Shared/_PrintDocumentViewerPartial.cshtml",
-                        new PrintGridModel(report, "Site", "ExportPartialSites", "devGridViewSite"));
+                        new PrintGridModel(report, "devGridViewSite",
+                            new { Controller = "Site", Action = "ExportPartialSites",
+                                displayMode = "callback", exportformat = String.Empty },
+                            new { Controller = "Site", Action = "ExportPartialSites",
+                                displayMode = "export", exportformat = String.Empty }));
+                }
                 else if (displayMode == "export")
                 {
                     switch (exportformat.ToLower())
@@ -238,7 +254,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
         {
             var site = _siteService.GetSiteById(siteId);
 
-            var siteModel = SiteDataModel.FromSite(site, false);
+            var siteModel = SiteDataModel.FromSite(site, false, _configurationService);
             var siteTreeModel = SiteTreeDataModel.TreeFromSite(site);
 
             siteModel.SiteTreeData = siteTreeModel;
@@ -253,7 +269,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Controllers
         public ActionResult EditSite(int id = -1)
         {
             var site = _siteService.GetSiteById(id);
-            var siteModel = SiteDataModel.FromSite(site, true);
+            var siteModel = SiteDataModel.FromSite(site, true, _configurationService);
 
             var siteTreeModel = SiteTreeDataModel.TreeFromSite(site);
 

+ 118 - 13
GreenTree.Nachtragsmanagement.Web/Extensions/GridViewSettingsHelper.cs

@@ -3,9 +3,11 @@ using DevExpress.Utils;
 using DevExpress.Web;
 using DevExpress.Web.ASPxThemes;
 using DevExpress.Web.Mvc;
+using DevExpress.Web.Mvc.UI;
 using GreenTree.Nachtragsmanagement.Core.Authentication;
 using GreenTree.Nachtragsmanagement.Web.Models.Appendix;
 using System;
+using System.Linq;
 using System.Collections.Generic;
 using System.Web.UI;
 using System.Web.UI.WebControls;
@@ -214,7 +216,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                     else
                         html.ViewContext.Writer.Write(text);
 
-                    if (_userContext.CurrentUser.HasFunction("Site-Sites-Edit"))
+                    if (_userContext.CurrentUser.HasFunction("Site-Sites-Edit-Comment"))
                         html.ViewContext.Writer.Write(
                             (isLongText ? "&nbsp;" : "<br/>") +
                             "<a href=\"#\" onclick='editComment(\"site\"," + id + ",function() { devGridViewSite.PerformCallback(); })'>Bearbeiten</a>");
@@ -357,8 +359,16 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
             });
             s.Columns.Add(column =>
             {
-                column.Caption = "Kst.-Stelle";
+                column.Caption = "Baustelle";
                 column.FieldName = "SiteDescription";
+                column.MinWidth = 150;
+                column.Width = new Unit(10, UnitType.Percentage);
+                column.SettingsHeaderFilter.Mode = GridHeaderFilterMode.CheckedList;
+            });
+            s.Columns.Add(column =>
+            {
+                column.Caption = "Kst.-Stelle";
+                column.FieldName = "SiteCustomNumber";
                 column.MinWidth = 120;
                 column.Width = new Unit(130, UnitType.Pixel);
                 column.SettingsHeaderFilter.Mode = GridHeaderFilterMode.CheckedList;
@@ -427,6 +437,24 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                 column.FieldName = "DisturbanceValuesDescription";
                 column.MinWidth = 190;
                 column.Width = new Unit(220, UnitType.Pixel);
+                column.SetFilterTemplateContent(f =>
+                {
+                    html.DevExpress().TextBox(t =>
+                    {
+                        t.Name = "devTextBoxFilterDisturbanceValuesDescription";
+                        t.Width = new Unit(100, UnitType.Percentage);
+                        t.Properties.ClientSideEvents.Init =
+                            "function (s, e) { " +
+                            "   if (customFilters != null && customFilters['DisturbanceValuesDescription'] != null) {" +
+                            "       s.SetText(customFilters['DisturbanceValuesDescription']); }}";
+                        t.Properties.ClientSideEvents.KeyUp =
+                            "function (s, e) { " +
+                            "   customFilters['DisturbanceValuesDescription'] = s.GetValue(); " +
+                            "   setFilterTimer(customFilterDelay, function () { devGridViewDeviation.PerformCallback(); }); }";
+                    }).Render();
+                });
+                column.UnboundType = DevExpress.Data.UnboundColumnType.Decimal;
+                column.UnboundExpression = "[DisturbanceValueSum]";
             });
             s.Columns.Add(column =>
             {
@@ -460,7 +488,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                     else
                         html.ViewContext.Writer.Write(text);
 
-                    if (_userContext.CurrentUser.HasFunction("Deviation-Deviations-Edit"))
+                    if (_userContext.CurrentUser.HasFunction("Deviation-Deviations-Edit-Comment"))
                         html.ViewContext.Writer.Write(
                             (isLongText ? "&nbsp;" : "<br/>") +
                             "&nbsp;<a href=\"#\" onclick='editComment(\"deviation\"," + id + ",function() { devGridViewDeviation.PerformCallback(); })'>Bearbeiten</a>");
@@ -473,30 +501,48 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
             var totalDaysReceiptToAppendixOfferingSum = 0;
             var totalDaysReceiptToAppendixOfferingCount = 0;
 
+            var totalDisturbanceSum = default(decimal);
+
             s.CustomSummaryCalculate = (sender, e) =>
             {
                 if (e.SummaryProcess == CustomSummaryProcess.Start)
                 {
                     totalDaysReceiptToAppendixOfferingSum = 0;
                     totalDaysReceiptToAppendixOfferingCount = 0;
+
+                    totalDisturbanceSum = 0;
                 }
 
                 if (e.SummaryProcess == CustomSummaryProcess.Calculate)
                 {
-                    var val = e.GetValue("DaysReceiptToAppendixOffering");
+                    var daysReceiptToAppendixOfferingVal = e.GetValue("DaysReceiptToAppendixOffering");
 
-                    if (val != null)
+                    if (daysReceiptToAppendixOfferingVal != null)
                     {
                         totalDaysReceiptToAppendixOfferingCount++;
-                        totalDaysReceiptToAppendixOfferingSum += Convert.ToInt32(val);
+                        totalDaysReceiptToAppendixOfferingSum += Convert.ToInt32(daysReceiptToAppendixOfferingVal);
                     }
+
+                    var disturbanceVal = e.GetValue("DisturbanceValueSum");
+
+                    if (disturbanceVal != null)
+                        totalDisturbanceSum += Convert.ToDecimal(disturbanceVal);
                 }
 
                 if (e.SummaryProcess == CustomSummaryProcess.Finalize)
-                    if (totalDaysReceiptToAppendixOfferingSum == 0 || totalDaysReceiptToAppendixOfferingCount == 0)
-                        e.TotalValue = 0;
-                    else
-                        e.TotalValue = totalDaysReceiptToAppendixOfferingSum / totalDaysReceiptToAppendixOfferingCount;
+                {
+                    var summaryItem = (ASPxSummaryItem)e.Item;
+
+                    if (summaryItem.FieldName == "DaysReceiptToAppendixOffering")
+                    {
+                        if (totalDaysReceiptToAppendixOfferingSum == 0 || totalDaysReceiptToAppendixOfferingCount == 0)
+                            e.TotalValue = 0;
+                        else
+                            e.TotalValue = totalDaysReceiptToAppendixOfferingSum / totalDaysReceiptToAppendixOfferingCount;
+                    }
+                    else if (summaryItem.FieldName == "DisturbanceValuesDescription")
+                        e.TotalValue = totalDisturbanceSum;
+                }
             };
 
             s.TotalSummary.Add(new ASPxSummaryItem
@@ -564,6 +610,27 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                 DisplayFormat = "Tage VA-NT Ø = <i>{0:n0}</i>"
             });
 
+            s.TotalSummary.Add(new ASPxSummaryItem
+            {
+                FieldName = "DisturbanceValuesDescription",
+                SummaryType = DevExpress.Data.SummaryItemType.Custom,
+                DisplayFormat = "Kat. ∑<br/><i>{0:c2}</i>"
+            });
+            s.GroupSummary.Add(new ASPxSummaryItem
+            {
+                FieldName = "DisturbanceValuesDescription",
+                SummaryType = DevExpress.Data.SummaryItemType.Custom,
+                DisplayFormat = "Kat. ∑ = <i>{0:c2}</i>"
+            });
+
+            s.HtmlRowPrepared = (sender, e) =>
+            {
+                var displayColor = e.GetValue("DisplayColor");
+
+                if (displayColor != null && e.RowType == GridViewRowType.Data)
+                    e.Row.BackColor = System.Drawing.ColorTranslator.FromHtml(displayColor.ToString());
+            };
+
             s.ClientLayout = (sender, e) =>
             {
                 if (e.LayoutMode == ClientLayoutMode.Loading)
@@ -592,7 +659,9 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                 e.Handled = true;
             };
 
-            s.ClientSideEvents.BeginCallback = "function (s, e) { e.customArgs['scrollHeight'] = [ gridScrollHeight ]; }";
+            s.ClientSideEvents.BeginCallback = "function (s, e) { " +
+                "e.customArgs['scrollHeight'] = [ gridScrollHeight ]; " +
+                "e.customArgs['customFilters'] = [ JSON.stringify(customFilters) ]; }";
             s.ClientSideEvents.ToolbarItemClick = "function (s, e) { onToolbarItemClick(s, e); }";
 
             s.Styles.Footer.CssClass += "devExGridFooterPanel";
@@ -741,7 +810,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
             });
             s.Columns.Add(column =>
             {
-                column.Caption = "Faktor Angeb. zu VA";
+                column.Caption = "Fak. Ang. zu VA";
                 column.FieldName = "RelationOfferingToDeviations";
                 column.PropertiesEdit.DisplayFormatString = "n2";
                 column.MinWidth = 100;
@@ -749,6 +818,25 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                 column.HeaderStyle.Wrap = DefaultBoolean.True;
             });
             s.Columns.Add(column =>
+            {
+                column.Caption = "AR gestellt";
+                column.FieldName = "OrderInvoiceCreatedDescription";
+                column.MinWidth = 60;
+                column.Width = new Unit(80, UnitType.Pixel);
+                column.HeaderStyle.Wrap = DefaultBoolean.True;
+                column.SettingsHeaderFilter.Mode = GridHeaderFilterMode.CheckedList;
+                column.SetDataItemTemplateContent(c =>
+                {
+                    var id = Convert.ToInt32(DataBinder.Eval(c.DataItem, "Id"));
+                    var description = DataBinder.Eval(c.DataItem, "OrderInvoiceCreatedDescription");
+
+                    if (_userContext.CurrentUser.HasFunction("Appendix-Appendices-Edit"))
+                        html.ViewContext.Writer.Write(description +
+                            "<br/><a href=\"#\" onclick='editOrderInvoiceCreated(" + id + "," +
+                            "   function() { devGridViewAppendix.PerformCallback(); })'>Ändern</a>");
+                });
+            });
+            s.Columns.Add(column =>
             {
                 column.Caption = "Status";
                 column.FieldName = "StateDescription";
@@ -757,6 +845,23 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                 column.SettingsHeaderFilter.Mode = GridHeaderFilterMode.CheckedList;
             });
             s.Columns.Add(column =>
+            {
+                column.Caption = "Bestellsch.-Datum";
+                column.FieldName = "OrderDate";
+                column.PropertiesEdit.DisplayFormatString = "dd.MM.yyyy";
+                column.MinWidth = 110;
+                column.Width = new Unit(110, UnitType.Pixel);
+                column.HeaderStyle.Wrap = DefaultBoolean.True;
+            });
+            s.Columns.Add(column =>
+            {
+                column.Caption = "Bestellsch.-Nummer";
+                column.FieldName = "OrderNumber";
+                column.MinWidth = 90;
+                column.Width = new Unit(110, UnitType.Pixel);
+                column.HeaderStyle.Wrap = DefaultBoolean.True;
+            });
+            s.Columns.Add(column =>
             {
                 column.Caption = "NT-Kategorien";
                 column.FieldName = "CategoryValuesDescription";
@@ -787,7 +892,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                     else
                         html.ViewContext.Writer.Write(text);
 
-                    if (_userContext.CurrentUser.HasFunction("Deviation-Deviations-Edit"))
+                    if (_userContext.CurrentUser.HasFunction("Deviation-Deviations-Edit-Comment"))
                         html.ViewContext.Writer.Write(
                             (isLongText ? "&nbsp;" : "<br/>") +
                             "<a href=\"#\" onclick='editComment(\"appendix\"," + id + ",function() { devGridViewAppendix.PerformCallback(); })'>Bearbeiten</a>");

+ 137 - 3
GreenTree.Nachtragsmanagement.Web/Extensions/MVCxGridViewGeneratorHelper.cs

@@ -23,6 +23,8 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
         public delegate void CustomizeFormattingRulesEventHandler(object source, CustomFormattingRulesEventArgs e);
         public delegate void CustomizeColumnTotalSummaryEventHandler(object source, ColumnSummaryCreationEventArgs e);
         public delegate void CustomizeColumnGroupSummaryEventHandler(object source, ColumnSummaryCreationEventArgs e);
+        public delegate void SummaryResetEventHandler(object source, CustomSummaryResetEventArgs e);
+        public delegate void SummaryRowChangedEventHandler(object source, CustomSummaryRowChangedEventArgs e);
 
         public class MVCReportGeneratonHelper
         {
@@ -41,6 +43,10 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
             public event CustomizeFormattingRulesEventHandler CustomizeFormattingRules;
             public event CustomizeColumnTotalSummaryEventHandler CustomizeTotalColumnSummary;
             public event CustomizeColumnGroupSummaryEventHandler CustomizeGroupColumnSummary;
+            public event SummaryResetEventHandler SummaryReset;
+            public event SummaryRowChangedEventHandler SummaryRowChanged;
+            public event SummaryGetResultHandler PageSummaryGetResult;
+            public event SummaryGetResultHandler TotalSummaryGetResult;
 
             public XtraReport GenerateMVCReport(MVCxGridViewState gridViewState, object model, string title)
             {
@@ -59,6 +65,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                 InitSortings(gridViewState);
                 InitGroupHeaders(gridViewState);
                 InitFilters(gridViewState);
+                InitPageSummaries(gridViewState);
                 InitTotalSummaries(gridViewState);
                 InitPageFooter();
 
@@ -414,6 +421,68 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                 report.FilterString = gridViewState.FilterExpression;
             }
 
+            private void InitPageSummaries(MVCxGridViewState gridViewState)
+            {
+                if (gridViewState.TotalSummary.Count == 0) return;
+
+                report.Bands.Add(new PageFooterBand
+                {
+                    HeightF = bandHeight,
+                    StyleName = "SummaryRow",
+                    PrintOn = PrintOnPages.NotWithReportFooter
+                });
+
+                foreach (MVCxSummaryItemState item in gridViewState.TotalSummary)
+                {
+                    var col = gridViewState.Columns[item.ShowInColumn == string.Empty
+                        ? item.FieldName
+                        : item.ShowInColumn];
+
+                    if (col == null) continue;
+
+                    if (!detailsInfo.Contains(col)) continue;
+
+                    var label = new XRLabel
+                    {
+                        LocationF = new PointF(
+                            ((XRTableCell)detailsInfo[col]).LocationF.X + subGroupOffset * gridViewState.GroupedColumns.Count,
+                            ((XRTableCell)detailsInfo[col]).LocationF.Y),
+                        SizeF = ((XRTableCell)detailsInfo[col]).SizeF
+                    };
+                    label.Summary = new XRSummary
+                    {
+                        Running = SummaryRunning.Page
+                    };
+                    label.Summary.FormatString = item.DisplayFormat;
+                    label.Summary.Func = GetSummaryFunc(item.SummaryType);
+                    label.DataBindings.Add("Text", null, col.FieldName);
+                    label.Tag = item.FieldName;
+
+                    if (item.SummaryType == SummaryItemType.Custom)
+                    {
+                        label.SummaryReset += (source, e) =>
+                        {
+                            if (SummaryReset != null)
+                                SummaryReset(report, new CustomSummaryResetEventArgs { FieldName = item.FieldName });
+                        };
+
+                        label.SummaryRowChanged += (source, e) =>
+                        {
+                            if (SummaryRowChanged != null)
+                                SummaryRowChanged(report, new CustomSummaryRowChangedEventArgs { FieldName = item.FieldName });
+                        };
+                    }
+
+                    if (PageSummaryGetResult != null)
+                        label.SummaryGetResult += PageSummaryGetResult;
+
+                    report.Bands[BandKind.PageFooter].Controls.Add(label);
+
+                    if (CustomizeTotalColumnSummary != null)
+                        CustomizeTotalColumnSummary(report, new ColumnSummaryCreationEventArgs(col.FieldName, label.Summary));
+                }
+            }
+
             private void InitTotalSummaries(MVCxGridViewState gridViewState)
             {
                 if (gridViewState.TotalSummary.Count == 0) return;
@@ -448,6 +517,25 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                     };
                     label.Summary.FormatString = item.DisplayFormat;
                     label.Summary.Func = GetSummaryFunc(item.SummaryType);
+                    label.Tag = item.FieldName;
+
+                    if (item.SummaryType == SummaryItemType.Custom)
+                    {
+                        label.SummaryReset += (source, e) =>
+                        {
+                            if (SummaryReset != null)
+                                SummaryReset(report, new CustomSummaryResetEventArgs { FieldName = item.FieldName });
+                        };
+
+                        label.SummaryRowChanged += (source, e) =>
+                        {
+                            if (SummaryRowChanged != null)
+                                SummaryRowChanged(report, new CustomSummaryRowChangedEventArgs { FieldName = item.FieldName });
+                        };
+                    }
+
+                    if (TotalSummaryGetResult != null)
+                        label.SummaryGetResult += TotalSummaryGetResult;
 
                     report.Bands[BandKind.ReportFooter].Controls.Add(label);
 
@@ -461,9 +549,9 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
                 var userHelper = Singleton<IContainer>.Instance.Resolve<IUserHelper>();
                 var user = userHelper.FromCookies();
 
-                report.Bands.Add(new PageFooterBand
+                report.Bands.Add(new BottomMarginBand
                 {
-                    HeightF = 23f
+                    HeightF = 46f
                 });
 
                 var footerTable = new XRTable
@@ -513,7 +601,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
 
                 footerTable.Rows.Add(footerRow);
 
-                report.Bands[BandKind.PageFooter].Controls.Add(footerTable);
+                report.Bands[BandKind.BottomMargin].Controls.Add(footerTable);
             }
 
             private List<MVCxColumnInfo> GetColumnsInfo(MVCxGridViewState gridViewState, int pagewidth)
@@ -747,6 +835,52 @@ namespace GreenTree.Nachtragsmanagement.Web.Extensions
             }
         }
 
+        public class CustomSummaryResetEventArgs : EventArgs
+        {
+            private string fieldName;
+
+            public string FieldName
+            {
+                get { return fieldName; }
+                set { fieldName = value; }
+            }
+        }
+
+        public class CustomSummaryRowChangedEventArgs : EventArgs
+        {
+            private string fieldName;
+
+            public string FieldName
+            {
+                get { return fieldName; }
+                set { fieldName = value; }
+            }
+        }
+
+        public class CustomSummaryGetResultEventArgs : SummaryGetResultEventArgs
+        {
+            public CustomSummaryGetResultEventArgs(IList calculatedValues) : base(calculatedValues)
+            {
+                
+            }
+
+            private string fieldName;
+
+            public string FieldName
+            {
+                get { return fieldName; }
+                set { fieldName = value; }
+            }
+
+            private XRControl control;
+
+            public XRControl Control
+            {
+                get { return control; }
+                set { control = value; }
+            }
+        }
+
         public class MVCxColumnInfo
         {
             public MVCxColumnInfo(GridViewDataColumnState gridViewColumn)

+ 4 - 6
GreenTree.Nachtragsmanagement.Web/GreenTree.Nachtragsmanagement.Web.csproj

@@ -172,6 +172,7 @@
     <Content Include="Content\devex.css" />
     <Content Include="Content\function.css" />
     <Content Include="Content\global.css" />
+    <Content Include="Content\Images\fullscreen-16.png" />
     <Content Include="Content\Images\function-Misc-Logs-32-contrast.png" />
     <Content Include="Content\Images\function-Misc-Logs-32.png" />
     <Content Include="Content\Images\add-16-contrast.png" />
@@ -210,6 +211,7 @@
     <Content Include="Content\Images\maximize-16.png" />
     <Content Include="Content\Images\minimize-16.png" />
     <Content Include="Content\Images\function-Appendix-Claims-32.png" />
+    <Content Include="Content\Images\normalize-16.png" />
     <Content Include="Content\Images\user-32.png" />
     <Content Include="Content\Images\password-32.png" />
     <Content Include="Content\Images\password-24.png" />
@@ -334,6 +336,7 @@
     <Content Include="Views\Shared\_PrintDocumentViewerPartial.cshtml" />
     <Content Include="Views\Shared\SaveDocumentViewer.cshtml" />
     <Content Include="Views\Deviations\_DeviationAssignPartial.cshtml" />
+    <Content Include="Views\Appendices\_EditOrderInvoiceCreatedPartial.cshtml" />
     <None Include="Web.Debug.config">
       <DependentUpon>Web.config</DependentUpon>
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -354,6 +357,7 @@
     <Compile Include="Extensions\MVCxGridViewGeneratorHelper.cs" />
     <Compile Include="Extensions\MVCxGridViewState.cs" />
     <Compile Include="Models\Admin\Plugins\PluginDataModel.cs" />
+    <Compile Include="Models\Appendix\OrderInvoiceCreatedDataModel.cs" />
     <Compile Include="Models\Config\ConfigItemDataModel.cs" />
     <Compile Include="Models\Global\EditEntityCommentModel.cs" />
     <Compile Include="Models\Global\PrintGridModel.cs" />
@@ -398,12 +402,6 @@
     <Compile Include="Models\Global\OptionDialogModel.cs" />
     <Compile Include="Models\Site\SiteDataModel.cs" />
     <Compile Include="Models\Site\SiteTreeDataModel.cs" />
-    <Compile Include="Reports\XtraReportGridView.cs">
-      <SubType>Component</SubType>
-    </Compile>
-    <Compile Include="Reports\XtraReportGridView.Designer.cs">
-      <DependentUpon>XtraReportGridView.cs</DependentUpon>
-    </Compile>
     <Compile Include="Validation\Admin\User\RoleDataModelValidator.cs" />
     <Compile Include="Validation\Admin\User\UserDataModelValidator.cs" />
     <Compile Include="Models\Global\FooterModel.cs" />

+ 5 - 0
GreenTree.Nachtragsmanagement.Web/Models/Appendix/AppendixDataModel.cs

@@ -25,6 +25,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Appendix
         public int? OrderNumber { get; set; }
         public DateTime? OrderDate { get; set; }
         public bool OrderInvoiceCreated { get; set; }
+        public string OrderInvoiceCreatedDescription { get; set; }
         public string Comment { get; set; }
         public int? StateId { get; set; }
         public StateDataModel State { get; set; }
@@ -107,6 +108,10 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Appendix
                 OrderDate = appendixEntity.OrderDate,
                 Comment = appendixEntity.Comment,
                 OrderInvoiceCreated = appendixEntity.OrderInvoiceCreated,
+                OrderInvoiceCreatedDescription = 
+                    appendixEntity.OrderInvoiceCreated
+                        ? "Ja"
+                        : "Nein",
                 StateId = appendixEntity.StateId,
                 State = appendixEntity.State == null
                     ? null

+ 13 - 0
GreenTree.Nachtragsmanagement.Web/Models/Appendix/OrderInvoiceCreatedDataModel.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+
+namespace GreenTree.Nachtragsmanagement.Web.Models.Appendix
+{
+    public class OrderInvoiceCreatedDataModel
+    {
+        public int AppendixId { get; set; }
+        public bool OrderInvoiceCreated { get; set; }
+    }
+}

+ 2 - 1
GreenTree.Nachtragsmanagement.Web/Models/Config/ConfigItemDataModel.cs

@@ -14,7 +14,8 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Config
             { typeof(System.Int64).FullName, "Große ganze Zahl" },
             { typeof(System.Boolean).FullName, "Wahrheitswert" },
             { typeof(System.Double).FullName, "Kommazahl" },
-            { typeof(System.DateTime).FullName, "Datum" }
+            { typeof(System.DateTime).FullName, "Datum" },
+            { typeof(System.Drawing.Color).FullName, "Farbe" },
         };
 
         public int Id { get; set; }

+ 41 - 1
GreenTree.Nachtragsmanagement.Web/Models/Deviation/DeviationDataModel.cs

@@ -1,4 +1,5 @@
 using GreenTree.Nachtragsmanagement.Core.Domain.Deviation;
+using GreenTree.Nachtragsmanagement.Services.Configuration;
 using GreenTree.Nachtragsmanagement.Web.Models.Appendix;
 using Newtonsoft.Json;
 using System;
@@ -15,6 +16,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Deviation
         public string CustomNumber { get; set; }
         public string Description { get; set; }
         public DateTime? ReceiptDate { get; set; }
+        public int? DaysReceiptDateToday { get; set; }
         public DateTime? AppendixDate { get; set; }
         public decimal Value { get; set; }
         public decimal Percentage { get; set; }
@@ -25,6 +27,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Deviation
         public string KindDescription { get; set; }
         public string Comment { get; set; }
         public string SiteDescription { get; set; }
+        public string SiteCustomNumber { get; set; }
         public int? SiteId { get; set; }
         public string AppendixDescription { get; set; }
         public int? AppendixId { get; set; }
@@ -41,6 +44,17 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Deviation
                     return String.Join(", ", DisturbanceValueEntities.Select(d => d.Description));
             }
         }
+        public decimal? DisturbanceValueSum
+        {
+            get
+            {
+                if (DisturbanceValueEntities == null)
+                    return null;
+                else
+                    return DisturbanceValueEntities.Sum(d => d.Value);
+            }
+        }
+        public string DisplayColor { get; set; }
 
         public DeviationDataModel()
         {
@@ -48,7 +62,8 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Deviation
             DisturbanceValueEntities = new List<DisturbanceValueDataModel>();
         }
 
-        public static DeviationDataModel FromDeviation(Core.Domain.Deviation.Deviation deviationEntity, bool newWhenIsNull)
+        public static DeviationDataModel FromDeviation(Core.Domain.Deviation.Deviation deviationEntity, bool newWhenIsNull, 
+            IConfigurationService configurationService)
         {
             if (deviationEntity == null && newWhenIsNull)
                 return new DeviationDataModel
@@ -66,6 +81,9 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Deviation
                 CustomNumber = deviationEntity.CustomNumber,
                 Description = deviationEntity.Description,
                 ReceiptDate = deviationEntity.ReceiptDate,
+                DaysReceiptDateToday = deviationEntity.ReceiptDate == null
+                    ? (int?)(DateTime.Now - deviationEntity.ReceiptDate).Value.Days
+                    : null,
                 AppendixDate = deviationEntity.AppendixDate,
                 Value = deviationEntity.Value.Value,
                 Percentage = deviationEntity.Percentage.HasValue
@@ -76,6 +94,13 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Deviation
                     : 0,
                 SiteId = deviationEntity.SiteId,
                 SiteDescription = deviationEntity.Site == null
+                    ? deviationEntity.Appendix == null
+                        ? String.Empty
+                        : deviationEntity.Appendix.Site == null
+                            ? String.Empty
+                            : deviationEntity.Appendix.Site.Description
+                    : deviationEntity.Site.Description,
+                SiteCustomNumber = deviationEntity.Site == null
                     ? deviationEntity.Appendix == null
                         ? String.Empty
                         : deviationEntity.Appendix.Site == null
@@ -112,6 +137,21 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Deviation
                         .ToList()
             };
 
+            var colorLevel1 = configurationService.TryGetConfigItemValue<string>(
+                "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.HexColorLevel1", "#FFD800");
+            var ageDaysLevel1 = configurationService.TryGetConfigItemValue<int>(
+                "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.AgeDaysLevel1", 40);
+
+            var colorLevel2 = configurationService.TryGetConfigItemValue<string>(
+                "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.HexColorLevel2", "#FF6A00");
+            var ageDaysLevel2 = configurationService.TryGetConfigItemValue<int>(
+                "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.AgeDaysLevel2", 60);
+
+            if (model.DaysReceiptDateToday >= ageDaysLevel1 && model.DaysReceiptDateToday < ageDaysLevel2 && !model.AppendixId.HasValue)
+                model.DisplayColor = colorLevel1;
+            else if (model.DaysReceiptDateToday >= ageDaysLevel2 && !model.AppendixId.HasValue)
+                model.DisplayColor = colorLevel2;
+
             foreach (var disturbance in model.DisturbanceValueEntities)
             {
                 var json = JsonConvert.SerializeObject(disturbance);

+ 8 - 8
GreenTree.Nachtragsmanagement.Web/Models/Global/PrintGridModel.cs

@@ -8,22 +8,22 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Global
 {
     public class PrintGridModel
     {
+        public XtraReport Report { get; set; }
+        public string GridViewName { get; set; }
+        public object CallbackRouteValues { get; set; }
+        public object ExportRouteValues { get; set; }
+
         public PrintGridModel()
         {
 
         }
 
-        public PrintGridModel(XtraReport report, string controller, string action, string gridViewName)
+        public PrintGridModel(XtraReport report, string gridViewName, object callbackRouteValues, object exportRouteValues)
         {
             Report = report;
-            Controller = controller;
-            Action = action;
             GridViewName = gridViewName;
+            CallbackRouteValues = callbackRouteValues;
+            ExportRouteValues = exportRouteValues;
         }
-
-        public XtraReport Report { get; set; }
-        public string Controller { get; set; }
-        public string Action { get; set; }
-        public string GridViewName { get; set; }
     }
 }

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

@@ -1,4 +1,5 @@
-using GreenTree.Nachtragsmanagement.Web.Models.Admin.User;
+using GreenTree.Nachtragsmanagement.Services.Configuration;
+using GreenTree.Nachtragsmanagement.Web.Models.Admin.User;
 using GreenTree.Nachtragsmanagement.Web.Models.Appendix;
 using GreenTree.Nachtragsmanagement.Web.Models.Deviation;
 using System;
@@ -62,7 +63,8 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Site
             UserDescriptions = new List<string>();
         }
 
-        public static SiteDataModel FromSite(Core.Domain.Site.Site siteEntity, bool newWhenIsNull)
+        public static SiteDataModel FromSite(Core.Domain.Site.Site siteEntity, bool newWhenIsNull, 
+            IConfigurationService configurationService)
         {
             if (siteEntity == null && newWhenIsNull)
                 return new SiteDataModel
@@ -91,7 +93,7 @@ namespace GreenTree.Nachtragsmanagement.Web.Models.Site
                         .ToList(),
                 Deviations = 
                     siteEntity.Deviations
-                        .Select(r => DeviationDataModel.FromDeviation(r, false))
+                        .Select(r => DeviationDataModel.FromDeviation(r, false, configurationService))
                         .ToList(),
                 DeviationValue = 
                     siteEntity.Deviations

+ 0 - 51
GreenTree.Nachtragsmanagement.Web/Reports/XtraReportGridView.Designer.cs

@@ -1,51 +0,0 @@
-namespace GreenTree.Nachtragsmanagement.Web.Reports
-{
-    partial class XtraReportGridView
-    {
-        /// <summary>
-        /// Required designer variable.
-        /// </summary>
-        private System.ComponentModel.IContainer components = null;
-
-        /// <summary> 
-        /// Clean up any resources being used.
-        /// </summary>
-        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && (components != null))
-            {
-                components.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-
-        #region Designer generated code
-
-        /// <summary>
-        /// Required method for Designer support - do not modify
-        /// the contents of this method with the code editor.
-        /// </summary>
-        private void InitializeComponent()
-        {
-            components = new System.ComponentModel.Container();
-            this.Detail = new DevExpress.XtraReports.UI.DetailBand();
-            this.TopMargin = new DevExpress.XtraReports.UI.TopMarginBand();
-            this.BottomMargin = new DevExpress.XtraReports.UI.BottomMarginBand();
-            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
-            this.TopMargin.Height = 100;
-            this.BottomMargin.Height = 100;
-            this.Bands.AddRange(new DevExpress.XtraReports.UI.Band[] {
-            this.Detail,
-            this.TopMargin,
-            this.BottomMargin});
-            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
-        }
-
-        #endregion
-
-        private DevExpress.XtraReports.UI.DetailBand Detail;
-        private DevExpress.XtraReports.UI.TopMarginBand TopMargin;
-        private DevExpress.XtraReports.UI.BottomMarginBand BottomMargin;
-    }
-}

+ 0 - 18
GreenTree.Nachtragsmanagement.Web/Reports/XtraReportGridView.cs

@@ -1,18 +0,0 @@
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using DevExpress.XtraReports.UI;
-using System.Data;
-using System.Web.UI.WebControls;
-
-namespace GreenTree.Nachtragsmanagement.Web.Reports
-{
-    public partial class XtraReportGridView : DevExpress.XtraReports.UI.XtraReport
-    {
-        public XtraReportGridView()
-        {
-            InitializeComponent();
-        }
-    }
-}

+ 14 - 0
GreenTree.Nachtragsmanagement.Web/Views/Appendices/View.cshtml

@@ -9,6 +9,7 @@
 	var gridScrollHeight;
 	var gridScrollOffset = 240;
 	var resizeFinished;
+	var editOrderInvoiceCreatedCallback;
 
 	$(document).ready(function () {
 		gridScrollHeight = calculateGridScrollHeight();
@@ -109,6 +110,19 @@
 			}
 		});
 	}
+
+	function editOrderInvoiceCreated(id, callback) {
+		if (!id) return;
+		editOrderInvoiceCreatedCallback = callback;
+		$.ajax({
+			url: '@Url.Action("EditOrderInvoiceCreated", "Appendix")',
+			data: { id: id },
+			success: function (response) {
+				$(".editOrderInvoiceCreatedContainer").remove();
+				$("body").append(response);
+			}
+		});
+	}
 </script>
 
 @Html.Partial("~/Views/Appendices/_AppendixGridPartial.cshtml", Model)

+ 24 - 0
GreenTree.Nachtragsmanagement.Web/Views/Appendices/_AppendixEditPartial.cshtml

@@ -369,6 +369,30 @@
 			}
 			ViewContext.Writer.Write("</div>");
 
+			ViewContext.Writer.Write("<div class='inlineModelPropertyContainer'>");
+			{
+				ViewContext.Writer.Write("<div class='inlineModelProperty' style='width: 40%'>");
+				{
+					ViewContext.Writer.Write(Html.CustomLabelFor(m => m.OrderNumber, "Bestellschein-Nr.:"));
+					Html.DevExpress().TextBoxFor(m => m.OrderNumber, t =>
+					{
+						t.Width = new Unit(96, UnitType.Percentage);
+					}).Render();
+				}
+				ViewContext.Writer.Write("</div>");
+
+				ViewContext.Writer.Write("<div class='inlineModelProperty' style='width: 36.1%'>");
+				{
+					ViewContext.Writer.Write(Html.CustomLabelFor(m => m.OrderDate, "Bestellscheindatum:"));
+					Html.DevExpress().DateEditFor(m => m.OrderDate, t =>
+					{
+						t.Width = new Unit(100, UnitType.Percentage);
+					}).Render();
+				}
+				ViewContext.Writer.Write("</div>");
+			}
+			ViewContext.Writer.Write("</div>");
+
 			ViewContext.Writer.Write("<div class='inlineModelPropertyContainer'>");
 			{
 				ViewContext.Writer.Write("<div class='inlineModelProperty' style='width: 40%'>");

+ 100 - 0
GreenTree.Nachtragsmanagement.Web/Views/Appendices/_EditOrderInvoiceCreatedPartial.cshtml

@@ -0,0 +1,100 @@
+@using GreenTree.Nachtragsmanagement.Web.Extensions
+
+@model GreenTree.Nachtragsmanagement.Web.Models.Appendix.OrderInvoiceCreatedDataModel
+
+<div class="editOrderInvoiceCreatedContainer">
+
+	<script>
+
+		function saveOrderInvoiceCreated() {
+			var form = $("#orderInvoiceCreatedEditForm");
+			$(form).submit(function (e) {
+				$.ajax({
+					type: "POST",
+					url: '@Url.Action("EditOrderInvoiceCreated", "Appendix")',
+					data: form.serialize(),
+					success: function (response) {
+						setTimeout(function () {
+							$(".editOrderInvoiceCreatedContainer").remove();
+							if (response == "success") {
+								if (typeof editOrderInvoiceCreatedCallback === 'function') {
+									editOrderInvoiceCreatedCallback();
+								}
+							} else {
+								$("body").append(response);
+							}
+						}, 200);
+					}
+				});
+				e.preventDefault();
+			});
+			form.submit();
+		}
+
+	</script>
+
+	@Html.DevExpress().PopupControl(p =>
+{
+	p.Name = "devPopupControlEditOrderInvoiceCreated";
+	p.HeaderText = "Abschlagsrechnung gestellt";
+	p.ShowHeader = true;
+	p.ShowFooter = false;
+	p.Modal = true;
+	p.Width = new Unit(350, UnitType.Pixel);
+	p.MinHeight = new Unit(150, UnitType.Pixel);
+	p.ShowOnPageLoad = true;
+	p.SetContent(() =>
+	{
+		using (Html.BeginForm("EditOrderInvoiceCreated", "Appendix", FormMethod.Post, new { id = "orderInvoiceCreatedEditForm" }))
+		{
+			ViewContext.Writer.Write("<div class='editFormWrapper'>");
+
+			ViewContext.Writer.Write("<input type=\"hidden\" value=\"" + Model.AppendixId + "\" id=\"AppendixId\" name=\"AppendixId\" />");
+
+			ViewContext.Writer.Write(Html.CustomLabelFor(m => m.OrderInvoiceCreated, "AR gestellt:"));
+			ViewContext.Writer.Write("<div style=\"overflow: hidden\">");
+			{
+				ViewContext.Writer.Write("<div style=\"float: left\">");
+				{
+					Html.DevExpress().RadioButtonFor(m => m.OrderInvoiceCreated, t =>
+					{
+						t.Text = "Ja";
+						t.GroupName = "orderInvoiceCreated";
+					}).Render();
+				}
+				ViewContext.Writer.Write("</div>");
+
+				ViewContext.Writer.Write("<div style=\"float: left; margin-left: 8px\">");
+				{
+					Html.DevExpress().RadioButton(t =>
+					{
+						t.Name = "orderInvoiceCreatedFalse";
+						t.Text = "Nein";
+						t.GroupName = "orderInvoiceCreated";
+						t.Checked = !Model.OrderInvoiceCreated;
+					}).Render();
+				}
+				ViewContext.Writer.Write("</div>");
+			}
+			ViewContext.Writer.Write("</div>");
+
+			ViewContext.Writer.Write("</div>");
+
+			Html.RenderPartial(
+				"~/Views/Shared/_PopupButtonPanel.cshtml",
+				new GreenTree.Nachtragsmanagement.Web.Models.Global.PopupModel
+				{
+					PopupName = "devPopupControlEditOrderInvoiceCreated",
+					AcceptFunction = "function (s, e) { saveOrderInvoiceCreated(); }"
+				}
+			);
+		}
+	});
+	p.CloseAction = CloseAction.CloseButton;
+	p.PopupHorizontalAlign = PopupHorizontalAlign.WindowCenter;
+	p.PopupVerticalAlign = PopupVerticalAlign.WindowCenter;
+	p.Styles.Content.Paddings.Padding = new Unit(0, UnitType.Pixel);
+	p.Styles.ModalBackground.Opacity = 0;
+}).GetHtml()
+
+</div>

+ 6 - 0
GreenTree.Nachtragsmanagement.Web/Views/Config/_ConfigItemValueEditPartial.cshtml

@@ -72,6 +72,12 @@
 				t.Width = new Unit(100, UnitType.Percentage);
 			}).GetHtml();
 			break;
+		case "System.Drawing.Color":
+			Html.DevExpress().ColorEditFor(m => m.Value, t =>
+			{
+				t.Width = new Unit(100, UnitType.Percentage);
+			}).GetHtml();
+			break;
 		default:
 			Html.DevExpress().TextBoxFor(m => m.Value, t =>
 			{

+ 15 - 1
GreenTree.Nachtragsmanagement.Web/Views/Deviations/View.cshtml

@@ -9,6 +9,20 @@
 	var gridScrollHeight;
 	var gridScrollOffset = 240;
 	var resizeFinished;
+	var customFilters = {};
+	var customFilterDelay = 800;
+	var timer;
+	var setFilterTimer = function (timeout, func) {
+		if (timer != null) {
+			clearTimeout(timer);
+			timer = null;
+		}
+		if (timer == null) {
+			timer = setTimeout(function () {
+				func();
+			}, timeout);
+		}
+	}
 
 	$(document).ready(function () {
 		gridScrollHeight = calculateGridScrollHeight();
@@ -43,7 +57,7 @@
 			$.ajax({
 				type: "POST",
 				url: '@Url.Action("ExportPartialDeviations", "Deviation")',
-				data: { displayMode: "popup", exportFormat: "" },
+				data: { customFilters: JSON.stringify(customFilters), displayMode: "popup", exportFormat: "" },
 				success: function (response) {
 					parent.$("body").append(response);
 					parent.exportFormat = "pdf";

+ 64 - 0
GreenTree.Nachtragsmanagement.Web/Views/Home/Index.cshtml

@@ -23,6 +23,13 @@
 	var popupUrls = {};
 	var popupMaxOnStartup = {};
 
+	var isFullscreen = false;
+	var isFullscreenMaximized = false;
+	var fullscreenLastX;
+	var fullscreenLastY;
+	var fullscreenLastWidth;
+	var fullscreenLastHeight;
+
 	var contentX = 0;
 	var contentY = 0;
 
@@ -104,6 +111,59 @@
 		}
 	})
 
+	function toggleFullscreenFunction(popupName, imgElem) {
+		var popupElem = $("#" + popupName + "-Popup_PW-1");
+		var controls = ASPxClientControl.GetControlCollection();
+		var popupElementName = popupName + "-Popup";
+		var popupElement = controls.GetByName(popupElementName);
+		var popupControl = MVCxClientPopupControl.Cast(popupElement);
+		if (isFullscreen) {
+			if (isFullscreenMaximized) {
+				popupElem.resizable({
+					disable: true,
+					containment: $(".functionContentContainer"),
+				});
+			} else {
+				popupControl.ShowAtPos(popupLocationsX[popupName], popupLocationsY[popupName]);
+				popupControl.SetWidth(popupWidths[popupName]);
+				popupControl.SetHeight(popupHeights[popupName]);
+				popupStatus[popupName] = "normalized";
+				popupContentElem.addClass("dxpc-shadow");
+				popupHeaderElem.addClass("devExAllowDrag");
+				popupElem.draggable("enable");
+				popupElem.resizable("enable");
+			}
+			isFullscreen = false;
+			$(imgElem).attr("src", '@Url.Content("~/Content/Images/fullScreen-16.png")');
+			popupControl.ShowAtPos(fullscreenLastX, fullscreenLastY);
+			popupControl.SetWidth(fullscreenLastWidth);
+			popupControl.SetHeight(fullscreenLastHeight);
+		} else {
+			fullscreenLastX = popupElem.position().left;
+			fullscreenLastY = popupElem.position().top;
+			fullscreenLastWidth = popupControl.GetWidth();
+			fullscreenLastHeight = popupControl.GetHeight();
+			if (popupStatus[popupName] == "maximized") {
+				isFullscreenMaximized = true;
+			} else {
+				isFullscreenMaximized = false;
+				popupStatus[popupName] = "maximized";
+				popupContentElem.removeClass("dxpc-shadow");
+				popupHeaderElem.removeClass("devExAllowDrag");
+				popupElem.draggable("disable");
+			}
+			popupControl.ShowAtPos(0, 0);
+			popupControl.SetWidth($(window).width());
+			popupControl.SetHeight($(window).height());
+			popupElem.resizable({
+				disable: true,
+				containment: "window"
+			});
+			isFullscreen = true;
+			$(imgElem).attr("src", '@Url.Content("~/Content/Images/normalize-16.png")');
+		}
+	}
+
 	function showFunction(e, parameters) {
 		if (!e) return;
 		var controls = ASPxClientControl.GetControlCollection();
@@ -201,6 +261,7 @@
 			popupHeaderElem.removeClass("devExAllowDrag");
 			popupElem.draggable("disable");
 			popupElem.resizable("disable");
+			isFullscreen = false;
 		} else if (popupStatus[popupName] && popupStatus[popupName] == "maximized") {
 			popupControl.ShowAtPos(popupLocationsX[popupName], popupLocationsY[popupName]);
 			popupControl.SetWidth(popupWidths[popupName]);
@@ -213,6 +274,7 @@
 			// Prevent growing of function container so it breaks below navigation container
 			$(".functionContentContainer").width($(".functionContentContainer").width() - 50);
 			$(".functionContentContainer").width($(".functionContentContainer").width() + 50);
+			isFullscreen = false;
 		}
 	}
 
@@ -284,6 +346,8 @@
 							Url.Content("~/Content/Images/close-16.png") + "\" onclick=\"hideFunction('" + i.Name + "',false);\" />" +
 						"<img class=\"controlIcon\" src=\"" +
 							Url.Content("~/Content/Images/maximize-16.png") + "\" onclick=\"toggleMaximizeFunction('" + i.Name + "');\" />" +
+						"<img class=\"controlIcon\" src=\"" +
+							Url.Content("~/Content/Images/fullScreen-16.png") + "\" onclick=\"toggleFullscreenFunction('" + i.Name + "',this);\" />" +
 						"<img class=\"controlIcon\" src=\"" +
 							Url.Content("~/Content/Images/minimize-16.png") + "\" onclick=\"hideFunction('" + i.Name + "',true);\" />" +
 					"</div>");

+ 2 - 13
GreenTree.Nachtragsmanagement.Web/Views/Shared/_PrintDocumentViewerPartial.cshtml

@@ -5,19 +5,8 @@
 	t.Name = "devDocumentViewerReportGrid";
 	t.Width = new Unit(100, UnitType.Percentage);
 	t.Report = Model.Report;
-	t.CallbackRouteValues = new
-	{
-		Action = Model.Action,
-		Controller = Model.Controller,
-		displayMode = "callback",
-		exportformat = String.Empty
-	};
-	t.ExportRouteValues = new
-	{
-		Action = Model.Action,
-		Controller = Model.Controller,
-		displayMode = "export"
-	};
+	t.CallbackRouteValues = Model.CallbackRouteValues;
+	t.ExportRouteValues = Model.ExportRouteValues;
 	t.ToolbarMode = DocumentViewerToolbarMode.StandardToolbar;
 	t.ClientSideEvents.Init = "function (s, e) { customizeExportToolbar('" + t.Name + "'); }";
 	t.ClientSideEvents.BeforeExportRequest = "function (s, e) { e.customArgs['exportFormat'] = exportFormat; }";