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 EmissionUnitService : BaseService, Sleis.Service.IEmissionUnitService { public IEmissionUnitData EmissionUnitData { get; set; } //public ReportFacilityData ReportFacilityData { get; set; } public IRegulationProgramData RegulationProgramData { get; set; } public IControlApproachData ControlApproachData { get; set; } public IUnitProcessData UnitProcessData { get; set; } public IControlDeviceData ControlDeviceData { get; set; } public IEntityControlDeviceData EntityControlDeviceData { get; set; } public IEmissionUnitIdentifierData EmissionUnitIdentifierData { get; set; } public IProcessEmissionService ProcessEmissionService { get; set; } public override void Init() { base.Init(); ArgumentValidationUtility.ThrowOnNull(EmissionUnitData, "ReleasePointData"); //ArgumentValidationUtility.ThrowOnNull(ReportFacilityData, "ReportFacilityData")' ArgumentValidationUtility.ThrowOnNull(ControlApproachData, "ControlApproachData"); ArgumentValidationUtility.ThrowOnNull(UnitProcessData, "UnitProcessData"); ArgumentValidationUtility.ThrowOnNull(ControlDeviceData, "ControlDeviceData"); ArgumentValidationUtility.ThrowOnNull(EntityControlDeviceData, "EntityControlDeviceData"); ArgumentValidationUtility.ThrowOnNull(RegulationProgramData, "EmissionUnitRegulationProgramData"); } public int CheckAndUpdateReleatedEmissions(EmissionUnit oldEu, EmissionUnit updatedEu) { /* * Not Controlled flag changes * Capture Efficiency changes * Control Device changes * Control Device is inserted or deleted */ if (oldEu.ControlApproach != null && updatedEu.ControlApproach != null) { if (oldEu.ControlApproach.NotControlled != updatedEu.ControlApproach.NotControlled || oldEu.ControlApproach.EntityControlDevices.Count != updatedEu.ControlApproach.EntityControlDevices.Count || oldEu.ControlApproach.Efficency != updatedEu.ControlApproach.Efficency) { return ProcessEmissionService.RecalculatemMissionsByEmissionUnit(updatedEu.Id); } foreach (EntityControlDevice cd in updatedEu.ControlApproach.EntityControlDevices) { if (!oldEu.ControlApproach.EntityControlDevices.Exists(c => c.ControlDeviceId == cd.ControlDeviceId)) { return ProcessEmissionService.RecalculatemMissionsByEmissionUnit(updatedEu.Id); } } } return 0; } public List GetEmissionUnitListByReport(int reportId) { //FacilityModel fac = FacilityData.GetReportFacility(reportId).Id List list = EmissionUnitData.GetEmissionUnitsByReport(reportId); LoadModel(list); return list; } public List GetEmissionUnitListByFacility(int facilityId) { List list = EmissionUnitData.GetEmissionUnitsByFacility(facilityId); LoadModel(list); return list; } public abstract void Delete(EmissionUnit emissionUnit, List customFields); public abstract EmissionUnit GetEmissionUnit(int emissionUnitId); public abstract void Update(EmissionUnit emissionUnit, List customFields); public abstract List GetEmissionUnitListItemsByReport(int reportId); public abstract List GetEmissionUnitListItemsByFacility(int facilityId); protected abstract List GetRegulationPrograms(int emissionUnitId); public abstract List GetEmissionUnitListItemsByFacility(int facilityId, int pageNum, int pageSize); public abstract List GetEmissionUnitListItemsByReport(int reportId, int pageNum, int pageSize); public abstract int CountEmissionUnitsByFacility(int facilityId); public abstract int CountEmissionUnitsByReport(int reportId); public List GetOperationalEmissionUnits(int facilityId, int reportId, int reportYear) { if (reportId > 0) { return GetOperationalEmissionUnitsByReport(reportId, reportYear).OrderBy(x=>x.Identifier).ToList(); } return GetOperationalEmissionUnits(facilityId, reportYear).OrderBy(x=>x.Identifier).ToList(); } public List GetOperationalEmissionUnits(int facilityId, int reportYear) { if (reportYear > 0) { return GetEmissionUnitListItemsByFacility(facilityId).Where(x => String.Equals(x.StatusCode, "OP", StringComparison.OrdinalIgnoreCase) || (x.StatusEffectiveDate.HasValue && x.StatusEffectiveDate.Value.Year > reportYear && (String.Equals(x.StatusCode, "PS", StringComparison.OrdinalIgnoreCase) || String.Equals(x.StatusCode, "TS", StringComparison.OrdinalIgnoreCase) ))).ToList(); } else if (reportYear == 0 && this.GetType().Equals(typeof(AgencyEmissionUnitService))) { return GetEmissionUnitListItemsByFacility(facilityId).Where(x => String.Equals(x.StatusCode, "OP", StringComparison.OrdinalIgnoreCase) || (x.StatusEffectiveDate.HasValue && x.StatusEffectiveDate.Value.Year > DateTime.Now.Year && (String.Equals(x.StatusCode, "PS", StringComparison.OrdinalIgnoreCase) || String.Equals(x.StatusCode, "TS", StringComparison.OrdinalIgnoreCase) ))).ToList(); } else { throw new InvalidOperationException("Cannot fetch master inventory for public service."); } } public List GetOperationalEmissionUnitsByReport(int reportId, int reportYear) { if (reportYear > 0) { return GetEmissionUnitListItemsByReport(reportId).Where(x => String.Equals(x.StatusCode, "OP", StringComparison.OrdinalIgnoreCase) || (x.StatusEffectiveDate.HasValue && x.StatusEffectiveDate.Value.Year > reportYear && (String.Equals(x.StatusCode, "PS", StringComparison.OrdinalIgnoreCase) || String.Equals(x.StatusCode, "TS", StringComparison.OrdinalIgnoreCase) ))).ToList(); } else if (reportYear == 0 && this.GetType().Equals(typeof(AgencyEmissionUnitService))) { return GetEmissionUnitListItemsByReport(reportId).Where(x => String.Equals(x.StatusCode, "OP", StringComparison.OrdinalIgnoreCase) || (x.StatusEffectiveDate.HasValue && x.StatusEffectiveDate.Value.Year > DateTime.Now.Year && (String.Equals(x.StatusCode, "PS", StringComparison.OrdinalIgnoreCase) || String.Equals(x.StatusCode, "TS", StringComparison.OrdinalIgnoreCase) ))).ToList(); } else { throw new InvalidOperationException("Cannot fetch master inventory for public service."); } } protected void LoadModel(List emissionUnits, bool fullLoaded = false) { foreach (EmissionUnit model in emissionUnits) { LoadModel(model); LoadRegulationPrograms(model); } //Parallel.ForEach(emissionUnits, model => LoadModel(model)); } protected void LoadModel(EmissionUnit model, bool fullLoaded = false) { model.Status = LookupUtility.Get(model.StatusCode); model.Type = LookupUtility.Get(model.TypeCode); model.RegulationPrograms = GetRegulationPrograms(model.Id); model.Uom = LookupUtility.Get(model.UomCode); if (model.LastUpdatedBy != null && model.LastUpdatedBy.Id > 0) { model.LastUpdatedBy = UserData.GetById(model.LastUpdatedBy.Id); } if (fullLoaded) { model.RelatedUnitProcesses = UnitProcessData.GetUnitProcessesByEmissionUnit(model.Id); foreach (UnitProcess up in model.RelatedUnitProcesses) { up.EmissionIdentifier = model.Identifier; } } } protected void LoadList(List list) { foreach(EmissionUnitListItem i in list) { i.Status = LookupUtility.Get(i.StatusCode); i.Type = LookupUtility.Get(i.TypeCode); } } protected void LoadRegulationPrograms(EmissionUnit emissionUnit) { if (Properties.Get(Constants.EnableRegulatoryProgramIn) == Constants.EnableRegulatoryProgramInEmissionUnit) { List list = new List(); list = GetRegulationPrograms(emissionUnit.Id); if (list != null && list.Count > 0) { //clear the dummy data //emissionUnit.EpaRegulationPrograms.Clear(); //emissionUnit.RegulationPrograms.Clear(); emissionUnit.RegulationPrograms = list; foreach (EmissionUnitRegulationProgram pro in list) { SimpleLookupItem it = LookupUtility.Get(pro.ProgramCode); SimpleLookupItem item = new SimpleLookupItem(); item.Code = it.Code; item.Year = it.Year; item.Value = it.Value; item.Value = string.Format("{0} - {1}", item.Code, item.Value); emissionUnit.EpaRegulationPrograms.Add(item); } } } else { emissionUnit.RegulationPrograms = null; emissionUnit.EpaRegulationPrograms = null; } } protected void ValidateRules(EmissionUnitDetailView dv) { if (dv.Item.Id == 0) { List units = EmissionUnitData.Get(eu=>eu.FacilityId==dv.Report.FacilityId).As>(); 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(EmissionUnitRegulationProgram 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 an emission unit.": "is a duplicate regulatory program code. The regulatory program must be unique for an emission unit."); throw new ApplicationException(msg); } //check duplicate emission unit control device /* dup = new List (); uniq = new HashSet (); foreach (PublicControlDeviceModel device in dv.Item.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 an emission unit.": "is a control device ID. The control device must be unique for an emission unit."); throw new ApplicationException(msg); } */ } } }