using DevExpress.Web.Mvc; using DevExpress.XtraPrinting; using DevExpress.XtraReports.UI; using GreenTree.Nachtragsmanagement.Core; using GreenTree.Nachtragsmanagement.Core.Authentication; using GreenTree.Nachtragsmanagement.Services.Appendix; using GreenTree.Nachtragsmanagement.Services.Deviation; using GreenTree.Nachtragsmanagement.Services.Logging; using GreenTree.Nachtragsmanagement.Services.Site; using GreenTree.Nachtragsmanagement.Web.Extensions; using GreenTree.Nachtragsmanagement.Web.Framework.Authorization; using GreenTree.Nachtragsmanagement.Web.Models.Appendix; using GreenTree.Nachtragsmanagement.Web.Models.Deviation; using GreenTree.Nachtragsmanagement.Web.Models.Global; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Net.Mime; using System.Web; using System.Web.Mvc; using static GreenTree.Nachtragsmanagement.Web.Extensions.MVCxGridViewGeneratorHelper; namespace GreenTree.Nachtragsmanagement.Web.Controllers { public class AppendixController : Controller { private readonly IDeviationService _deviationSerivce; private readonly IAppendixService _appendixService; private readonly ISiteService _siteService; private readonly IUserHelper _userHelper; private readonly ILogger _logger; public AppendixController( IDeviationService deviationService, IAppendixService appendixService, ISiteService siteService, IUserHelper userHelper, ILogger logger) { _deviationSerivce = deviationService; _appendixService = appendixService; _siteService = siteService; _userHelper = userHelper; _logger = logger; ViewData["AllCategories"] = _appendixService.GetAllCategories(); ViewData["AllStates"] = _appendixService.GetAllStates(); } #region Appendices /// /// Basic appendix view function /// [FunctionAuthorize(true, "Appendix-Appendices")] public ActionResult ViewAppendices() { var currentUser = _userHelper.FromCookies(); var appendices = _appendixService.GetAllUserAssignedAppendices(currentUser); var appendixModels = appendices .Select(u => AppendixDataModel.FromAppendix(u, false)) .ToList(); return View("~/Views/Appendices/View.cshtml", appendixModels); } /// /// Get JSON data of specific appendix /// /// Appendix id. public ActionResult GetAppendix(int id = -1) { var appendix = _appendixService.GetAppendixById(id); if (appendix == null) return new JsonResult { Data = "notFound", JsonRequestBehavior = JsonRequestBehavior.AllowGet }; var appendixModel = AppendixDataModel.FromAppendix(appendix, false); return new JsonResult { Data = JsonConvert.SerializeObject(appendixModel), JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } /// /// Callback result for appendix grid /// public ActionResult PartialAppendices(int scrollHeight = -1) { var currentUser = _userHelper.FromCookies(); var appendices = _appendixService.GetAllUserAssignedAppendices(currentUser); var appendixModels = appendices .Select(u => AppendixDataModel.FromAppendix(u, false)) .ToList(); ViewData["ScrollHeight"] = scrollHeight; return PartialView("~/Views/Appendices/_AppendixGridPartial.cshtml", appendixModels); } /// /// Export result for appendix grid /// [HttpPost] public ActionResult ExportPartialAppendices(string displayMode, string exportformat) { if (String.IsNullOrEmpty(displayMode)) return new EmptyResult(); var currentUser = _userHelper.FromCookies(); var appendices = _appendixService.GetAllUserAssignedAppendices(currentUser); var appendixModels = appendices .Select(u => AppendixDataModel.FromAppendix(u, false)) .ToList(); var viewContext = new ViewContext(); var viewPage = new ViewPage(); var htmlHelper = new System.Web.Mvc.HtmlHelper(viewContext, viewPage); MVCxGridViewState gridViewState = (MVCxGridViewState)Session["AppendixGridViewState"]; var settings = GridViewSettingsHelper.AppendixGridViewSettings(htmlHelper); if (gridViewState != null) { var generator = new MVCReportGeneratonHelper(); generator.CustomizeColumnsCollection += new CustomizeColumnsCollectionEventHandler(generator_CustomizeColumnsCollection); generator.CustomizeGroupColumnSummary += new CustomizeColumnGroupSummaryEventHandler(generator_CustomizeGroupColumnSummary); generator.CustomizeTotalColumnSummary += new CustomizeColumnTotalSummaryEventHandler(generator_CustomizeTotalColumnSummary); var report = generator.GenerateMVCReport(gridViewState, appendixModels); if (displayMode == "popup") return PartialView("~/Views/Shared/_PrintPopupPartial.cshtml", new PrintGridModel(report, "Appendix", "ExportPartialAppendices", "devGridViewAppendix")); else if (displayMode == "callback") return PartialView("~/Views/Shared/_PrintDocumentViewerPartial.cshtml", new PrintGridModel(report, "Appendix", "ExportPartialAppendices", "devGridViewAppendix")); else if (displayMode == "export") { switch (exportformat.ToLower()) { case "xlsx": settings.TotalSummary["OfferingValue"].DisplayFormat = "{0:c2}"; settings.TotalSummary["NegotiationValue"].DisplayFormat = "{0:c2}"; settings.TotalSummary["Description"].DisplayFormat = "Anzahl = {0:n0}"; return GridViewExtension.ExportToXlsx(settings, appendixModels); case "xls": settings.TotalSummary["OfferingValue"].DisplayFormat = "{0:c2}"; settings.TotalSummary["NegotiationValue"].DisplayFormat = "{0:c2}"; settings.TotalSummary["Description"].DisplayFormat = "Anzahl = {0:n0}"; return GridViewExtension.ExportToXls(settings, appendixModels); case "pdf": generator.WritePdfToResponse(Response, "Nachtragsliste.pdf", DispositionTypeNames.Attachment.ToString()); break; } } return new EmptyResult(); } else return new EmptyResult(); } /// /// Customize created columns /// private void generator_CustomizeColumnsCollection(object source, ColumnsCreationEventArgs e) { foreach (var column in e.ColumnsInfo) { if (column.FieldName == "CustomNumber") { column.ColumnWidth = 30; } if (column.FieldName == "SiteDescription") { column.ColumnWidth = 60; } if (column.FieldName == "DeviationDescription") { column.ColumnWidth = 50; } if (column.FieldName == "RelationOfferingToNegotiation") { column.ColumnWidth = 70; } if (column.FieldName == "RelationOfferingToDeviations") { column.ColumnWidth = 80; } if (column.FieldName == "StateDescription") { column.ColumnWidth = 60; } if (column.FieldName == "Comment") { column.IsVisible = false; column.IsDetail = true; } } } /// /// Customize column summary /// private void generator_CustomizeGroupColumnSummary(object source, ColumnSummaryCreationEventArgs e) { if (e.FieldName == "OfferingValue") { e.Summary.FormatString = "Angeb. ∑ = {0:c2}"; } if (e.FieldName == "NegotiationValue") { e.Summary.FormatString = "Verhand. ∑ = {0:c2}"; } if (e.FieldName == "Description") { e.Summary.FormatString = "Alle = {0:n0}"; } } /// /// Customize column summary /// private void generator_CustomizeTotalColumnSummary(object source, ColumnSummaryCreationEventArgs e) { if (e.FieldName == "OfferingValue") { e.Summary.FormatString = "{0:c2}"; } if (e.FieldName == "NegotiationValue") { e.Summary.FormatString = "{0:c2}"; } if (e.FieldName == "Description") { e.Summary.FormatString = "Alle = {0:n0}"; } } /// /// Partial edit for editing of existing or for new appendix /// /// Id for existing appendix, otherweise -1. public ActionResult EditAppendix(int id = -1) { var appendix = _appendixService.GetAppendixById(id); var appendixModel = AppendixDataModel.FromAppendix(appendix, true); var defaultState = _appendixService.GetDefaultState(); if (defaultState != null) ViewData["DefaultState"] = defaultState.Id; return PartialView("~/Views/Appendices/_AppendixEditPartial.cshtml", appendixModel); } /// /// Partial edit for creating a new deviation for a site /// /// Id of the site which the deviation should be appended to. public ActionResult AppendAppendixToSite(int siteId) { var site = _siteService.GetSiteById(siteId); var lastCustomNumber = 0; if (site.Appendices.Any()) lastCustomNumber = site.Appendices .Max(d => StaticHelper.TryParseInt(d.CustomNumber)); var appendixModel = new AppendixDataModel { Id = -1, SiteId = siteId, CustomNumber = (lastCustomNumber + 1).ToString(), Percentage = (decimal)0.5 }; var defaultState = _appendixService.GetDefaultState(); if (defaultState != null) ViewData["DefaultState"] = defaultState.Id; return PartialView("~/Views/Appendices/_AppendixEditPartial.cshtml", appendixModel); } /// /// Partial edit result if ModelState is valid, otherwise simple JSON result for success /// /// Appendix model to be saved. [HttpPost, ValidateInput(false)] public ActionResult EditAppendix(AppendixDataModel appendixModel) { try { appendixModel.CategoryValueEntities = appendixModel.CategoryEntities .Select(r => JsonConvert.DeserializeObject(r)) .ToList(); for (int i = 0; i < appendixModel.CategoryValueEntities.Count; i++) appendixModel.CategoryValueEntities.ElementAt(i).Json = appendixModel.CategoryEntities.ElementAt(i); appendixModel.PercentageValue = appendixModel.OfferingValue * appendixModel.Percentage; if (!ModelState.IsValid) return PartialView("~/Views/Appendices/_AppendixEditPartial.cshtml", appendixModel); var categoryValues = appendixModel.CategoryValueEntities .Select(r => r.ToCategoryValue()) .ToList(); if (appendixModel.Id == -1) { var appendix = appendixModel.ToAppendix(); appendix.SetCategoryValues(categoryValues); _appendixService.InsertAppendix(appendix); _logger.Entity(appendix, Core.Domain.Logging.LogEntityActivity.Insert, _userHelper.FromCookies()); } else { var appendix = _appendixService.GetAppendixById(appendixModel.Id); appendix.CustomNumber = appendixModel.CustomNumber; appendix.Description = appendixModel.Description; appendix.Percentage = appendixModel.Percentage; appendix.OfferingNumber = appendixModel.OfferingNumber; appendix.OfferingDate = appendixModel.OfferingDate; appendix.NegotiationDate = appendixModel.NegotiationDate; appendix.NegotiationValue = appendixModel.NegotiationValue; appendix.ProtocolExists = appendixModel.ProtocolExists; appendix.StateId = appendixModel.StateId; appendix.OrderNumber = appendixModel.OrderNumber; appendix.OrderDate = appendixModel.OrderDate; appendix.OrderInvoiceCreated = appendixModel.OrderInvoiceCreated; appendix.Comment = appendixModel.Comment; appendix.SiteId = appendixModel.SiteId; appendix.SetCategoryValues(categoryValues); _appendixService.UpdateAppendix(appendix); _logger.Entity(appendix, Core.Domain.Logging.LogEntityActivity.Update, _userHelper.FromCookies()); } return new JsonResult { Data = "success" }; } catch (Exception ex) { _logger.Error("Fehler bei Speicherung eines Nachtrags.", ex, _userHelper.FromCookies()); return PartialView("~/Views/Shared/_PopupError.cshtml", ex); } } /// /// Simple JSON result for deleting a specific appendix /// /// Appendix id. [HttpPost] public ActionResult DeleteAppendix(int id) { try { var appendix = _appendixService.GetAppendixById(id); if (appendix != null) _appendixService.DeleteAppendix(appendix); _logger.Entity(appendix, Core.Domain.Logging.LogEntityActivity.Delete, _userHelper.FromCookies()); return new JsonResult { Data = "success" }; } catch (Exception ex) { _logger.Error("Fehler bei Löschung eines Nachtrags.", ex, _userHelper.FromCookies()); return PartialView("~/Views/Shared/_PopupError.cshtml", ex); } } #endregion #region Invoices /// /// Get JSON data of specific invoice /// /// Invoice id. public ActionResult GetInvoice(int id = -1) { var invoice = _appendixService.GetInvoiceById(id); if (invoice == null) return new JsonResult { Data = "notFound", JsonRequestBehavior = JsonRequestBehavior.AllowGet }; var invoiceModel = InvoiceDataModel.FromInvoice(invoice, false); return new JsonResult { Data = JsonConvert.SerializeObject(invoiceModel), JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } /// /// Callback result for Invoice list /// public ActionResult PartialInvoices(int appendixId = -1) { if (appendixId == -1) return PartialView("~/Views/Appendices/_InvoiceListPartial.cshtml", new AppendixDataModel()); var appendix = _appendixService.GetAppendixById(appendixId); if (appendix == null) return PartialView("~/Views/Appendices/_InvoiceListPartial.cshtml", new AppendixDataModel()); var appendixDataModel = AppendixDataModel.FromAppendix(appendix, false); return PartialView("~/Views/Appendices/_InvoiceListPartial.cshtml", appendixDataModel); } /// /// Partial edit for editing of existing or for new invoice /// /// Id for existing invoice, otherweise -1. /// Id of corresponding Appendix public ActionResult EditInvoice(int appendixId, int id = -1) { var invoice = _appendixService.GetInvoiceById(id); var invoiceModel = InvoiceDataModel.FromInvoice(invoice, true); if (id == -1) invoiceModel.AppendixId = appendixId; return PartialView("~/Views/Appendices/_InvoiceEditPartial.cshtml", invoiceModel); } /// /// Partial edit result if ModelState is valid, otherwise simple JSON result for success /// /// Invoice model to be saved. [HttpPost, ValidateInput(false)] public ActionResult EditInvoice(InvoiceDataModel invoiceModel) { try { if (!ModelState.IsValid) return PartialView("~/Views/Appendices/_InvoiceEditPartial.cshtml", invoiceModel); if (invoiceModel.Id == -1) { var invoice = invoiceModel.ToInvoice(); _appendixService.InsertInvoice(invoice); _logger.Entity(invoice, Core.Domain.Logging.LogEntityActivity.Insert, _userHelper.FromCookies()); } else { var invoice = _appendixService.GetInvoiceById(invoiceModel.Id); invoice.CustomNumber = invoiceModel.CustomNumber.Value; invoice.Date = invoiceModel.DateTime.Value; invoice.Value = invoiceModel.Value.Value; _appendixService.UpdateInvoice(invoice); _logger.Entity(invoice, Core.Domain.Logging.LogEntityActivity.Update, _userHelper.FromCookies()); } return new JsonResult { Data = "success" }; } catch (Exception ex) { _logger.Error("Fehler bei Speicherung einer Rechnung.", ex, _userHelper.FromCookies()); return PartialView("~/Views/Shared/_PopupError.cshtml", ex); } } /// /// Simple JSON result for deleting a specific invoice /// /// Invoice id. [HttpPost] public ActionResult DeleteInvoice(int id) { try { var invoice = _appendixService.GetInvoiceById(id); if (invoice != null) _appendixService.DeleteInvoice(invoice); _logger.Entity(invoice, Core.Domain.Logging.LogEntityActivity.Delete, _userHelper.FromCookies()); return new JsonResult { Data = "success" }; } catch (Exception ex) { _logger.Error("Fehler bei Löschung einer Rechnung.", ex, _userHelper.FromCookies()); return PartialView("~/Views/Shared/_PopupError.cshtml", ex); } } #endregion #region Claims /// /// Basic claim view function /// [FunctionAuthorize(true, "Appendix-Claims")] public ActionResult ViewClaims() { return View("~/Views/Appendices/Claims.cshtml"); } /// /// Get JSON data of specific claim /// /// Claim type. /// Claim id. public ActionResult GetClaim(string claimType, int id = -1) { switch (claimType.ToLower()) { case "state": var state = _appendixService.GetStateById(id); if (state == null) return new JsonResult { Data = "notFound", JsonRequestBehavior = JsonRequestBehavior.AllowGet }; else return new JsonResult { Data = JsonConvert.SerializeObject(state), JsonRequestBehavior = JsonRequestBehavior.AllowGet }; case "category": var category = _appendixService.GetCategoryById(id); if (category == null) return new JsonResult { Data = "notFound", JsonRequestBehavior = JsonRequestBehavior.AllowGet }; else return new JsonResult { Data = JsonConvert.SerializeObject(category), JsonRequestBehavior = JsonRequestBehavior.AllowGet }; default: return new JsonResult { Data = "unknownClaimType", JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } } /// /// Callback result for claim grid /// /// Claim type. public ActionResult PartialClaims(string claimType) { switch (claimType.ToLower()) { case "state": return PartialView("~/Views/Appendices/_StateListPartial.cshtml", ViewData["AllStates"]); case "category": return PartialView("~/Views/Appendices/_CategoryListPartial.cshtml", ViewData["AllCategories"]); default: return new EmptyResult(); } } /// /// Partial edit for editing of existing or for new claim /// /// Claim type. /// Id for existing claim, otherweise -1. public ActionResult EditClaim(string claimType = "", int id = -1) { switch (claimType.ToLower()) { case "state": var state = _appendixService.GetStateById(id); var stateModel = StateDataModel.FromState(state, true); return PartialView("~/Views/Appendices/_StateEditPartial.cshtml", stateModel); case "category": var category = _appendixService.GetCategoryById(id); var categoryModel = CategoryDataModel.FromCategory(category, true); return PartialView("~/Views/Appendices/_CategoryEditPartial.cshtml", categoryModel); default: return new EmptyResult(); } } /// /// Partial edit result if ModelState is valid, otherwise simple JSON result for success /// /// State model to be saved. [HttpPost, ValidateInput(false)] public ActionResult EditState(StateDataModel stateModel) { try { if (!ModelState.IsValid) return PartialView("~/Views/Appendices/_StateEditPartial.cshtml", stateModel); var allStates = _appendixService.GetAllStates(); if (stateModel.IsDefault) { foreach (var state in allStates) { state.IsDefault = false; _appendixService.UpdateState(state); } } if (stateModel.IsFinish) { foreach (var state in allStates) { state.IsFinish = false; _appendixService.UpdateState(state); } } if (stateModel.Id == -1) { var claim = stateModel.ToState(); _appendixService.InsertState(claim); _logger.Entity(claim, Core.Domain.Logging.LogEntityActivity.Insert, _userHelper.FromCookies()); } else { var state = _appendixService.GetStateById(stateModel.Id); state.Description = stateModel.Description; state.HexColor = stateModel.HexColor; state.IsDefault = stateModel.IsDefault; state.IsFinish = stateModel.IsFinish; _appendixService.UpdateState(state); _logger.Entity(state, Core.Domain.Logging.LogEntityActivity.Update, _userHelper.FromCookies()); } return new JsonResult { Data = "success" }; } catch (Exception ex) { _logger.Error("Fehler bei Speicherung eines NT-Status.", ex, _userHelper.FromCookies()); return PartialView("~/Views/Shared/_PopupError.cshtml", ex); } } /// /// Partial edit result if ModelState is valid, otherwise simple JSON result for success /// /// Category model to be saved. [HttpPost, ValidateInput(false)] public ActionResult EditCategory(CategoryDataModel categoryModel) { try { if (!ModelState.IsValid) return PartialView("~/Views/Appendices/_CategoryEditPartial.cshtml", categoryModel); if (categoryModel.Id == -1) { var claim = categoryModel.ToCategory(); _appendixService.InsertCategory(claim); _logger.Entity(claim, Core.Domain.Logging.LogEntityActivity.Insert, _userHelper.FromCookies()); } else { var category = _appendixService.GetCategoryById(categoryModel.Id); category.Description = categoryModel.Description; _appendixService.UpdateCategory(category); _logger.Entity(category, Core.Domain.Logging.LogEntityActivity.Update, _userHelper.FromCookies()); } return new JsonResult { Data = "success" }; } catch (Exception ex) { _logger.Error("Fehler bei Löschung einer NT-Kategorie.", ex, _userHelper.FromCookies()); return PartialView("~/Views/Shared/_PopupError.cshtml", ex); } } /// /// Simple JSON result for deleting a specific claim /// /// Claim type. /// Claim id. /// Id of claim which deviations get in place of deleting claim. [HttpPost] public ActionResult DeleteClaim(string claimType, int id, int replaceId) { switch (claimType.ToLower()) { case "state": try { var state = _appendixService.GetStateById(id); var replaceState = _appendixService.GetStateById(replaceId); var stateAppendices = _appendixService.GetAppendicesByState(id); foreach (var appendix in stateAppendices) { appendix.StateId = replaceId; appendix.State = replaceState; _appendixService.UpdateAppendix(appendix); } if (state != null) _appendixService.DeleteState(state); _logger.Entity(state, Core.Domain.Logging.LogEntityActivity.Delete, _userHelper.FromCookies()); } catch (Exception ex) { _logger.Error("Fehler bei Löschung eines NT-Status.", ex, _userHelper.FromCookies()); return PartialView("~/Views/Shared/_PopupError.cshtml", ex); } break; case "category": try { var category = _appendixService.GetCategoryById(id); var replaceCategory = _appendixService.GetCategoryById(replaceId); var allAppendices = _appendixService.GetAllAppendices(); foreach (var appendix in allAppendices) { foreach (var categoryValue in appendix.CategoryValues) { if (categoryValue.CategoryId == id) { categoryValue.Category = replaceCategory; categoryValue.CategoryId = replaceCategory.Id; } } _appendixService.UpdateAppendix(appendix); } if (category != null) _appendixService.DeleteCategory(category); _logger.Entity(category, Core.Domain.Logging.LogEntityActivity.Delete, _userHelper.FromCookies()); } catch (Exception ex) { _logger.Error("Fehler bei Löschung einer NT-Kategorie.", ex, _userHelper.FromCookies()); return PartialView("~/Views/Shared/_PopupError.cshtml", ex); } break; default: return new EmptyResult(); } return new JsonResult { Data = "success" }; } #endregion } }