git_bsmd/bsmd.database/WAS.cs

628 lines
26 KiB
C#

//
// Class: WAS
// Current CLR: 4.0.30319.34209
// System: Microsoft Visual Studio 10.0
// Author: dani
// Created: 4/2/2015 7:38:45 PM
//
// Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved.
using System;
using System.Text;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Newtonsoft.Json;
namespace bsmd.database
{
[TypeConverter(typeof(MessageClassConverter<WAS>))]
[JsonConverter(typeof(NoTypeConverterJsonConverter<WAS>))]
public class WAS : DatabaseEntity, ISublistContainer
{
public WAS()
{
this.tablename = "[dbo].[WAS]";
this.WasteDisposalValidExemption = false;
}
#region Properties
[JsonIgnore]
public static int[] DKWasteCodes { get; } = { 1100, 1200, 1300, 2100, 2200, 2300, 2311, 2308, 2600, 2300, 2309, 3000, 5100, 5200, 5300, 2300 };
[JsonIgnore]
public static string[] DKWasteTypes { get; } = { "Waste oils - Sludge", "Waste oils - Bilge water", "Waste oils - Other", "Garbage - Food waste", "Garbage - Plastic", "Garbage - Other", "Garbage - Other - Cooking oil", "Garbage - Other - Incinerator ashes and clinkers", "Operational wastes", "Garbage - Other", "Garbage - Other - Animal carcasses", "Sewage", "Cargo residues - Marpol Annex I - Other", "Cargo residues - Marpol Annex II - Other", "Cargo residues - Marpol Annex V - Other", "Garbage - Other" };
[JsonIgnore]
[Obsolete]
public static int[] RequiredCodes { get; } = { 1100, 1200, 1300, 2100, 2200, 2300, 2311, 2308, 2600, 2309, 3000, 5100, 5200, 5300 };
[JsonIgnore]
[Obsolete]
public static string[] RequiredTypes { get; } = { "Oily Residues (sludge)", "Oily Bilge Water", "Waste oil - others (specify)", "Food waste", "Plastics", "Domestic wastes", "Cooking oil", "Incinerator ashes", "Operational wastes", "Animal carcass(es)", "Sewage", "Cargo residues - Marpol Annex I", "Cargo residues - Marpol Annex II", "Cargo residues - Marpol Annex V" };
/// <summary>
/// NSW 7.0 Waste codes
/// </summary>
public static string[] WasteCodes { get; } = {
"101", "102", "103", "104", "105", "999", "201", "202", "203", "204", "401", "501", "502", "503", "504", "505", "506", "507", "508", "509", "510", "511", "601", "602", "991"
};
/// <summary>
/// NSW 7.0 Waste descriptions
/// </summary>
public static string[] WasteCodeDescriptions { get; } =
{
"Oily bilge water",
"Oily residues (sludge)",
"Oily tank washings (slops)",
"Dirty ballast water",
"Scale and sludge from tank cleaning",
"Other (please specify)",
"Category X substance",
"Category Y substance",
"Category Z substance",
"OS - other substances",
"Sewage",
"A. Plastic",
"B. Food waste",
"C. Domestic waste",
"D. Cooking oil",
"E. Incinerator ashes",
"F. Operational waste",
"G. Animal carcasses",
"H. Fishing gear",
"I. E-waste",
"J. Cargo residues (non-HME)",
"K. Cargo residues (HME)",
"Ozone-depleting substances and equipment containing such substances",
"Exhaust gas-cleaning residues",
"Passively fished waste"
};
[ShowReport]
[ENI2Validation]
public bool? WasteDisposalValidExemption { get; set; }
[ShowReport]
[Validation2(ValidationCode.LOCODE_SSN)]
[MaxLength(5)]
[ENI2Validation]
public string LastWasteDisposalPort { get; set; }
[ShowReport]
[Validation2(ValidationCode.LOCODE_SSN)]
[MaxLength(5)]
[ENI2Validation]
public string NextWasteDisposalPort { get; set; }
[ShowReport]
[Validation2(ValidationCode.NOT_NULL)]
[LookupName("WAS.ConfirmationOfCorrectness")]
[ENI2Validation]
public bool? ConfirmationOfCorrectness { get; set; }
[ShowReport]
[Validation2(ValidationCode.NOT_NULL)]
[LookupName("WAS.LastWasteDisposalDate")]
[ENI2Validation]
[DateOnly]
public DateTime? LastWasteDisposalDate { get; set; }
[Obsolete]
[ShowReport]
[Validation2(ValidationCode.NOT_NULL)]
[ENI2Validation]
public byte? WasteDisposalDelivery { get; set; }
[LookupName("WAS.ConfirmationOfSufficiency")]
[ENI2Validation]
public bool? ConfirmationOfSufficiency { get; set; }
public ObservableCollection<Waste> Waste { get; private set; } = new ObservableCollection<Waste>();
[Browsable(false)]
public ObservableCollection<WasteDisposalServiceProvider> WasteDisposalServiceProvider { get; private set; } = new ObservableCollection<WasteDisposalServiceProvider>();
/// <summary>
/// Hilfsproperty, um eine kommaseparierte Liste von WasteDisposalServiceProvider (analog ANSW) im ENI-2 anzuzeigen,
/// bzw im Setter um eine kommaseparierte Liste mit den WasteDisposalServiceProvider Entitäten abzugleichen
/// </summary>
public string WasteDisposalServiceProviderText
{
get
{
StringBuilder sb = new StringBuilder();
for(int i=0;i<this.WasteDisposalServiceProvider.Count;i++)
{
if (i > 0)
sb.Append(", ");
sb.Append(((WasteDisposalServiceProvider) this.WasteDisposalServiceProvider[i]).WasteDisposalServiceProviderName);
}
return sb.ToString();
}
set
{
if (value.IsNullOrEmpty())
{
foreach (WasteDisposalServiceProvider wdsp in this.WasteDisposalServiceProvider)
DBManager.Instance.Delete(wdsp);
this.WasteDisposalServiceProvider.Clear();
}
else
{
string[] serviceProviderNames = value.Split(',');
List<WasteDisposalServiceProvider> foundList = new List<database.WasteDisposalServiceProvider>();
for (int i=0;i<serviceProviderNames.Length;i++)
{
string serviceProviderName = serviceProviderNames[i].Trim();
if(serviceProviderName.Length > 0)
{
WasteDisposalServiceProvider matchingServiceProvider = null;
foreach(WasteDisposalServiceProvider wdsp in this.WasteDisposalServiceProvider)
{
if(wdsp.WasteDisposalServiceProviderName.Equals(serviceProviderName, StringComparison.OrdinalIgnoreCase))
{
matchingServiceProvider = wdsp;
break;
}
}
if(matchingServiceProvider != null)
{
foundList.Add(matchingServiceProvider);
this.WasteDisposalServiceProvider.Remove(matchingServiceProvider);
}
else
{
WasteDisposalServiceProvider newWDSP = new WasteDisposalServiceProvider
{
WAS = this,
WasteDisposalServiceProviderName = serviceProviderName
};
foundList.Add(newWDSP);
}
}
}
// remove remaining service provider (no longer valid)
foreach (WasteDisposalServiceProvider remainingProvider in this.WasteDisposalServiceProvider)
DBManager.Instance.Delete(remainingProvider);
this.WasteDisposalServiceProvider.Clear();
// add existing and new providers
foreach(WasteDisposalServiceProvider wdsp in foundList)
this.WasteDisposalServiceProvider.Add(wdsp);
List<DatabaseEntity> tmpList = new List<DatabaseEntity>(this.WasteDisposalServiceProvider);
DatabaseEntity.ResetIdentifiers(tmpList);
}
}
}
#endregion
#region DatabaseEntity implementation
public override void PrepareSave(System.Data.IDbCommand cmd)
{
SqlCommand scmd = cmd as SqlCommand;
scmd.Parameters.AddWithValue("@P1", this.MessageHeader.Id);
scmd.Parameters.AddWithNullableValue("@P2", this.WasteDisposalValidExemption);
scmd.Parameters.AddWithNullableValue("@P3", this.LastWasteDisposalPort);
scmd.Parameters.AddWithNullableValue("@P4", this.ConfirmationOfCorrectness);
scmd.Parameters.AddWithNullableValue("@P5", this.LastWasteDisposalDate);
scmd.Parameters.AddWithNullableValue("@P6", this.WasteDisposalDelivery);
scmd.Parameters.AddWithNullableValue("@P7", this.ConfirmationOfSufficiency);
if (this.IsNew)
{
this.CreateId();
scmd.Parameters.AddWithValue("@ID", this.Id);
scmd.CommandText = string.Format("INSERT INTO {0} (Id, MessageHeaderId, WasteDisposalValidExemption, " +
"LastWasteDisposalPort, ConfirmationOfCorrectness, LastWasteDisposalDate, WasteDisposalDelivery, " +
"ConfirmationOfSufficiency) VALUES ( @ID, @P1, @P2, @P3, @P4, @P5, @P6, @P7 )", this.Tablename);
}
else
{
scmd.Parameters.AddWithValue("ID", this.Id);
scmd.CommandText = string.Format("UPDATE {0} SET WasteDisposalValidExemption = @P2, LastWasteDisposalPort = @P3, " +
"ConfirmationOfCorrectness = @P4, LastWasteDisposalDate = @P5, WasteDisposalDelivery = @P6, ConfirmationOfSufficiency = @P7 " +
"WHERE Id = @ID", this.Tablename);
}
}
public override void PrepareLoadCommand(System.Data.IDbCommand cmd, Message.LoadFilter filter, params object[] criteria)
{
string query = string.Format("SELECT Id, WasteDisposalValidExemption, LastWasteDisposalPort, ConfirmationOfCorrectness, " +
"LastWasteDisposalDate, WasteDisposalDelivery, ConfirmationOfSufficiency " +
"FROM {0} ", this.Tablename);
switch (filter)
{
case Message.LoadFilter.MESSAGEHEADER:
query += " WHERE MessageHeaderId = @MHID";
((SqlCommand)cmd).Parameters.AddWithValue("@MHID", criteria[0]);
break;
case Message.LoadFilter.ALL:
default:
break;
}
cmd.CommandText = query;
}
public override List<DatabaseEntity> LoadList(System.Data.IDataReader reader)
{
List<DatabaseEntity> result = new List<DatabaseEntity>();
while (reader.Read())
{
WAS was = new WAS
{
id = reader.GetGuid(0)
};
if (!reader.IsDBNull(1)) was.WasteDisposalValidExemption = reader.GetBoolean(1);
if (!reader.IsDBNull(2)) was.LastWasteDisposalPort = reader.GetString(2);
if (!reader.IsDBNull(3)) was.ConfirmationOfCorrectness = reader.GetBoolean(3);
if (!reader.IsDBNull(4)) was.LastWasteDisposalDate = reader.GetDateTime(4);
if (!reader.IsDBNull(5)) was.WasteDisposalDelivery = reader.GetByte(5);
if (!reader.IsDBNull(6)) was.ConfirmationOfSufficiency = reader.GetBoolean(6);
result.Add(was);
}
reader.Close();
return result;
}
#endregion
#region overrides
public override void OverwriteWith(DatabaseEntity otherEntity)
{
if (otherEntity is WAS otherWAS)
{
base.OverwriteWith(otherEntity);
foreach (Waste w in this.Waste)
DBManager.Instance.Delete(w);
this.Waste.Clear();
foreach (Waste w in otherWAS.Waste)
{
Waste newW = w.Clone() as Waste;
newW.WAS = this;
DBManager.Instance.Save(newW);
this.Waste.Add(newW);
}
foreach (WasteDisposalServiceProvider ws in this.WasteDisposalServiceProvider)
DBManager.Instance.Delete(ws);
this.WasteDisposalServiceProvider.Clear();
foreach (WasteDisposalServiceProvider ws in otherWAS.WasteDisposalServiceProvider)
{
WasteDisposalServiceProvider newWS = ws.Clone() as WasteDisposalServiceProvider;
newWS.WAS = this;
DBManager.Instance.Save(newWS);
this.WasteDisposalServiceProvider.Add(newWS);
}
}
}
#endregion
#region ISublistContainer implementation
public ISublistElement GetSublistElementWithIdentifier(string identifier)
{
foreach (Waste waste in this.Waste)
{
if (waste.Identifier.Equals(identifier))
return waste;
}
return null;
}
[Browsable(false)]
[JsonIgnore]
public int NumberOfExcelRows
{
get { return 15; }
}
public void SaveElements()
{
foreach(Waste waste in this.Waste)
{
DBManager.Instance.Save(waste);
}
foreach(WasteDisposalServiceProvider wdsp in this.WasteDisposalServiceProvider)
{
DBManager.Instance.Save(wdsp);
}
}
public void DeleteElements()
{
foreach (Waste waste in this.Waste)
{
DBManager.Instance.Delete(waste);
}
this.Waste.Clear();
foreach (WasteDisposalServiceProvider wdsp in this.WasteDisposalServiceProvider)
{
DBManager.Instance.Delete(wdsp);
}
this.WasteDisposalServiceProvider.Clear();
}
#endregion
#region IMessageParagraph implementation
[Browsable(false)]
[JsonIgnore]
public override string Subtitle
{
get
{
return "Waste/cargo residue";
}
}
[Browsable(false)]
[JsonIgnore]
public override List<IMessageParagraph> ChildParagraphs
{
get
{
List<IMessageParagraph> result = new List<IMessageParagraph>();
foreach (IMessageParagraph imp in this.Waste)
result.Add(imp);
return result;
}
}
#endregion
#region Validation
public override DatabaseEntity.ValidationBlock GetValidationBlock()
{
return (this.WasteDisposalValidExemption ?? false) ? ValidationBlock.BLOCK1 : ValidationBlock.BLOCK2;
}
public override void Validate(List<MessageError> errors, List<MessageViolation> violations)
{
if(this.GetValidationBlock() == ValidationBlock.BLOCK2)
{
foreach (Waste waste in this.Waste)
{
RuleEngine.ValidateProperties(waste, errors, violations);
waste.Validate(errors, violations);
}
foreach(WasteDisposalServiceProvider wdsp in this.WasteDisposalServiceProvider)
{
RuleEngine.ValidateProperties(wdsp, errors, violations);
wdsp.Validate(errors, violations);
}
bool entryMissing = false;
int missingType = 0;
foreach(int wasteCode in RequiredCodes)
{
bool codeFound = false;
foreach(Waste w in this.Waste)
{
if((w.WasteType ?? 0) == wasteCode)
{
codeFound = true; break;
}
}
if(!codeFound)
{
missingType = wasteCode;
entryMissing = true;
break;
}
}
// Extravalidierung für "0" Meldung (5.3.21)
double totalSludgeRetained = 0;
double totalWDALP = 0;
double totalWC = 0;
double totalWAR = 0;
double totalWAGTNP = 0;
double totalWDA = 0;
foreach(Waste w in this.Waste)
{
if (w.WasteType == 1100) totalSludgeRetained += w.WasteAmountRetained_MTQ ?? 0;
if (w.WasteType == 1300) totalSludgeRetained += w.WasteAmountRetained_MTQ ?? 0;
totalWDALP += w.WasteDisposedAtLastPort_MTQ ?? 0;
totalWC += w.WasteCapacity_MTQ ?? 0;
totalWAR += w.WasteAmountRetained_MTQ ?? 0;
totalWAGTNP += w.WasteAmountGeneratedTillNextPort_MTQ ?? 0;
totalWDA += w.WasteDisposalAmount_MTQ ?? 0;
}
if(totalSludgeRetained == 0)
{
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Waste amount retained on board for types 1100 'sludge' and 1300 'oil-others' = 0", null, this.Title, null, this.Tablename));
}
if(totalWDALP == 0)
{
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Total waste is 0 for WasteDisposedAtLastPort for all waste types", null, this.Title, null, this.Tablename));
}
if(totalWC == 0)
{
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Total waste is 0 for WasteCapacity for all waste types", null, this.Title, null, this.Tablename));
}
if(totalWAR == 0)
{
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Total waste is 0 for WasteAmountRetained for all waste types", null, this.Title, null, this.Tablename));
}
if(totalWAGTNP == 0)
{
// herausgenommen lt Karte für 6.4.3 (15.7.21)
// violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Total waste is 0 for WasteAmountGeneratedTillNextPort for all waste types", null, this.Title, null, this.Tablename));
}
if((totalWDA == 0) && !(WasteDisposalDelivery.HasValue && (WasteDisposalDelivery.Value == 2)))
{
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Total waste is 0 for WasteDisposalDelivery for all waste types", null, this.Title, null, this.Tablename));
}
if(entryMissing)
{
errors.Add(RuleEngine.CreateError(ValidationCode.POSITION_COUNT, string.Format("Waste {0}", missingType), null, this.Title, null, this.Tablename));
}
if(!(this.ConfirmationOfCorrectness ?? false))
{
errors.Add(RuleEngine.CreateError(ValidationCode.IMPLAUSIBLE, "Confirmation of correctness not set!", null, this.Title, null, this.Tablename));
}
}
}
#endregion
#region public convenience method
public List<Waste> AddRemainingWasteTypes()
{
List<Waste> result = new List<Waste>();
for (byte wType = 1; wType <= 9; wType++ )
{
bool wasteTypeFound = false;
foreach (Waste w in this.Waste)
{
if ((w.WasteType ?? 0) == wType)
wasteTypeFound = true;
}
if (!wasteTypeFound)
{
Waste newWaste = new Waste
{
WasteType = wType,
WasteAmountGeneratedTillNextPort_MTQ = 0,
WasteAmountRetained_MTQ = 0,
WasteCapacity_MTQ = 0,
WasteDisposalAmount_MTQ = 0,
Identifier = "",
WasteDisposalPort = "ZZUKN",
WasteDescription = "-",
WAS = this
};
this.Waste.Add(newWaste);
result.Add(newWaste);
}
}
return result;
}
/// <summary>
/// Convenience Methode, die fehlende Waste Einträge ergänzt. Verbesserte Version, aus ENI-2 herüberkopiert, damit es auch im
/// Excel_Reader nutzbar wird
/// </summary>
public void AddMissingWaste()
{
foreach (int wasteCode in WAS.RequiredCodes)
{
Waste foundWaste = null;
foreach (Waste waste in this.Waste)
{
if (waste.WasteType.HasValue && waste.WasteType.Value == wasteCode)
{
foundWaste = waste;
break;
}
}
if (foundWaste == null)
{
Waste newWaste = new Waste
{
Identifier = DatabaseEntity.GetNewIdentifier(this.Waste),
WAS = this,
WasteAmountGeneratedTillNextPort_MTQ = 0,
WasteAmountRetained_MTQ = 0,
WasteCapacity_MTQ = 0,
WasteDescription = (wasteCode == 1300) ? "-" : "",
WasteDisposalAmount_MTQ = 0,
WasteDisposalPort = "ZZUKN",
WasteDisposedAtLastPort_MTQ = 0,
WasteType = wasteCode
};
this.Waste.Add(newWaste);
}
else
{
if (!foundWaste.WasteAmountGeneratedTillNextPort_MTQ.HasValue) foundWaste.WasteAmountGeneratedTillNextPort_MTQ = 0;
if (!foundWaste.WasteAmountRetained_MTQ.HasValue) foundWaste.WasteAmountRetained_MTQ = 0;
if (!foundWaste.WasteCapacity_MTQ.HasValue) foundWaste.WasteCapacity_MTQ = 0;
if ((wasteCode == 1300) && foundWaste.WasteDescription.IsNullOrEmpty()) foundWaste.WasteDescription = "-";
if (!foundWaste.WasteDisposalAmount_MTQ.HasValue) foundWaste.WasteDisposalAmount_MTQ = 0;
if (foundWaste.WasteDisposalPort.IsNullOrEmpty()) foundWaste.WasteDisposalPort = "ZZUKN";
if (!foundWaste.WasteDisposedAtLastPort_MTQ.HasValue) foundWaste.WasteDisposedAtLastPort_MTQ = 0;
}
}
// falls Zeile 15 oder mehr vorhanden war / ist werden dort auch noch default Werte ergänzt
foreach(Waste foundWaste in this.Waste)
{
if (!foundWaste.WasteAmountGeneratedTillNextPort_MTQ.HasValue) foundWaste.WasteAmountGeneratedTillNextPort_MTQ = 0;
if (!foundWaste.WasteAmountRetained_MTQ.HasValue) foundWaste.WasteAmountRetained_MTQ = 0;
if (!foundWaste.WasteCapacity_MTQ.HasValue) foundWaste.WasteCapacity_MTQ = 0;
if ((foundWaste.WasteType == 1300) && foundWaste.WasteDescription.IsNullOrEmpty()) foundWaste.WasteDescription = "-";
if (!foundWaste.WasteDisposalAmount_MTQ.HasValue) foundWaste.WasteDisposalAmount_MTQ = 0;
if (foundWaste.WasteDisposalPort.IsNullOrEmpty()) foundWaste.WasteDisposalPort = "ZZUKN";
if (!foundWaste.WasteDisposedAtLastPort_MTQ.HasValue) foundWaste.WasteDisposedAtLastPort_MTQ = 0;
}
}
#endregion
#region ICloneable implementation
public override object Clone()
{
WAS was = this.MemberwiseClone() as WAS;
was.id = null;
was.Waste = new ObservableCollection<Waste>();
was.WasteDisposalServiceProvider = new ObservableCollection<WasteDisposalServiceProvider>();
foreach (Waste waste in this.Waste)
{
Waste clonedWaste = waste.Clone() as Waste;
clonedWaste.WAS = was;
was.Waste.Add(clonedWaste);
}
foreach (WasteDisposalServiceProvider wdsp in this.WasteDisposalServiceProvider)
{
WasteDisposalServiceProvider clonedWDSP = wdsp.Clone() as WasteDisposalServiceProvider;
clonedWDSP.WAS = was;
was.WasteDisposalServiceProvider.Add(clonedWDSP);
}
return was;
}
#endregion
}
}