using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using NHibernate; using NHibernate.Linq; using Sleis.Models; using Sleis.Infrastructure; using log4net; using Sleis.Utility; using Sleis.Data; using Sleis.ViewModels; using Sleis.Models.CustomFields; using System.Threading.Tasks; namespace Sleis.Service { public abstract class UnitProcessService : BaseService, IUnitProcessService { public IUnitProcessData UnitProcessData { get; set; } //public ReportFacilityData ReportFacilityData { get; set; } public IEmissionUnitData EmissionUnitData { get; set; } public IRegulationProgramData RegulationProgramData { get; set; } public IControlApproachData ControlApproachData { get; set; } public IControlDeviceData ControlDeviceData { get; set; } public IReleasePointData ReleasePointData { get; set; } public IUnitProcessReleasePointData UnitProcessReleasePointData { get; set; } public IEntityControlDeviceData EntityControlDeviceData { get; set; } public IUnitProcessIdentifierData UnitProcessIdentifierData { get; set; } public ICommentData CommentData { get; set; } public IProcessEmissionService ProcessEmissionService { get; set; } private int reportId = -1; public override void Init() { base.Init(); ArgumentValidationUtility.ThrowOnNull(UnitProcessData, "UnitProcessData"); //ArgumentValidationUtility.ThrowOnNull(ReportFacilityData, "ReportFacilityData"); ArgumentValidationUtility.ThrowOnNull(EmissionUnitData, "EmissionUnitData"); ArgumentValidationUtility.ThrowOnNull(RegulationProgramData, "RegulationProgramData"); ArgumentValidationUtility.ThrowOnNull(ControlApproachData, "ControlApproachData"); ArgumentValidationUtility.ThrowOnNull(ControlDeviceData, "ControlDeviceData"); ArgumentValidationUtility.ThrowOnNull(ReleasePointData, "ReleasePointData"); ArgumentValidationUtility.ThrowOnNull(EntityControlDeviceData, "EntityControlDeviceData"); } public abstract List GetUnitProcessListByReport(int reportId); public abstract List GetUnitProcessListByFacility(int facility); public abstract List GetUnitProcessListByEmissionUnit(int emissionUnitId); public abstract UnitProcess GetUnitProcess(int unitProcessId); protected abstract void LoadModel(UnitProcess model); public abstract List GetEmissionUnitsByReport(int reportId); public abstract List GetUnitProcessListItemsByReport(int reportId, int pageNum, int pageSize); public abstract List GetEmissionUnitsByFacility(int facilityId); public abstract List GetUnitProcessListItemsByFacility(int facilityId, int pageNum, int pageSize); public abstract int CountUnitProcessesByFacility(int facilityId); public abstract int CountUnitProcessesByReport(int reportId); public List GetUnitProcessReleasePointSelection(int reportId, int reportYear) { //Return only operational return ReleasePointData.GetReleasePointsByReport(reportId).Where(x=>x.StatusCode.ToUpper() == "OP" || x.StatusAsOfDate.Value.Year > reportYear) .ToList(); } public abstract List GetUnitProcessListItemsByReport(int reportId); public abstract List GetUnitProcessListItemsByFacility(int facilityId); public abstract List GetUnitProcessListItemsByEmissionUnit(int emissionUnitId); public abstract void Delete(UnitProcess detail, List customFields); public int CheckAndUpdateReleatedEmissions(UnitProcess oldProc, UnitProcess updatedUp) { /* * Not Controlled flag changes * Capture Efficiency changes * Control Device changes * Control Device is inserted or deleted */ //UnitProcess updatedUp = GetUnitProcess(unitProcess.Id); if (updatedUp.ControlApproach != null && oldProc.ControlApproach != null) { if (updatedUp.ControlApproach.NotControlled != oldProc.ControlApproach.NotControlled || updatedUp.ControlApproach.EntityControlDevices.Count != oldProc.ControlApproach.EntityControlDevices.Count || updatedUp.ControlApproach.Efficency != oldProc.ControlApproach.Efficency) { return ProcessEmissionService.RecalculateEmissionsByUnitProcess(updatedUp.Id); } foreach (EntityControlDevice cd in oldProc.ControlApproach.EntityControlDevices) { if (!updatedUp.ControlApproach.EntityControlDevices.Exists(c => c.ControlDeviceId == cd.ControlDeviceId)) { return ProcessEmissionService.RecalculateEmissionsByUnitProcess(updatedUp.Id); } } } return 0; } public void Update(UnitProcessDetailView dv) { //ValidateRules(dv); Validation routine will need to be modified. //reportId = dv.Report.Id; Update(dv.Item, dv.CustomFields); } //ToDo: we may refactor this to base service private void ValidateRules(UnitProcessDetailView dv) { if (dv.Item.Id == 0) { List units = UnitProcessData.GetUnitProcessesByFacility(dv.Report.FacilityId).As>(); //TODO REFACTOR List identifiers = (from d in units select d.Identifier).ToList(); if (identifiers.Contains(dv.Item.Identifier)) { throw new ApplicationException("The Identifier value must be unique for a facility."); } } //we check duplicate regulatory programs //client-side validation make sure the regulatory program is selected from the list List dup = new List(); HashSet uniq = new HashSet(); foreach (UnitProcessRegulationProgram prog in dv.Item.RegulationPrograms) { if (uniq.Contains(prog.ProgramCode)) { dup.Add(prog.ProgramCode); } else { uniq.Add(prog.ProgramCode); } } if (dup.Count > 0) { string msg = string.Join(", ", dup.ToArray()); msg = string.Format("{0} {1}", msg, dup.Count > 1 ? "are duplicate regulatory program codes. The regulatory program must be unique for a unit process." : "is a duplicate regulatory program code. The regulatory program must be unique for a unit process."); throw new ApplicationException(msg); } //check unit process control device dup = new List(); uniq = new HashSet(); foreach (PublicControlDevice device in dv.Item.EntityControlDevice.ControlDevices) { if (uniq.Contains(device.Id.ToString())) { dup.Add(device.Id.ToString()); } else { uniq.Add(device.Id.ToString()); } } if (dup.Count > 0) { string msg = string.Join(", ", dup.ToArray()); msg = string.Format("{0} {1}", msg, dup.Count > 1 ? "are duplicate control device IDs. The control device must be unique for a unit process." : "is a control device ID. The control device must be unique for a unit process."); throw new ApplicationException(msg); } //check duplicate release point dup = new List(); uniq = new HashSet(); foreach (PublicUnitProcessReleasePoint rp in dv.Item.UnitProcessReleasePoints) { if (uniq.Contains(rp.ReleasePointId.ToString())) { dup.Add(rp.ReleasePointId.ToString()); } else { uniq.Add(rp.ReleasePointId.ToString()); } } if (dup.Count > 0) { string msg = string.Join(", ", dup.ToArray()); msg = string.Format("{0} {1}", msg, dup.Count > 1 ? "are duplicate release points. The release point must be unique for a unit process." : "is a duplicate release point. The release point must be unique for a unit process."); throw new ApplicationException(msg); } } public abstract void Update(UnitProcess detail, List customFields); protected abstract void LoadRegulationPrograms(UnitProcess model); protected void LoadModel(List list) { foreach (UnitProcess up in list) { LoadModel(up); LoadRegulationPrograms(up); } //Parallel.ForEach(list, up => LoadModel(up)); } } }