From bee561beba38f3aab23bdd0da30ea73484a02676 Mon Sep 17 00:00:00 2001 From: Alexandra Date: Thu, 16 Apr 2026 13:22:24 +0200 Subject: [PATCH] CaritasVerbandDuerenJuelichEvBeWo/Export/DiamantExporter.cs - NEU (analog zur Familienhilfe) --- .../CaritasVerbandDuerenJuelichEvBeWo.csproj | 2 + .../Export/CustomDataExporter.cs | 32 + .../Export/DiamantExporter.cs | 629 ++++++++++++++++++ 3 files changed, 663 insertions(+) create mode 100644 ReportImp/CaritasVerbandDuerenJuelichEvBeWo/Export/CustomDataExporter.cs create mode 100644 ReportImp/CaritasVerbandDuerenJuelichEvBeWo/Export/DiamantExporter.cs diff --git a/ReportImp/CaritasVerbandDuerenJuelichEvBeWo/CaritasVerbandDuerenJuelichEvBeWo.csproj b/ReportImp/CaritasVerbandDuerenJuelichEvBeWo/CaritasVerbandDuerenJuelichEvBeWo.csproj index 06416ad2f..a26e30147 100644 --- a/ReportImp/CaritasVerbandDuerenJuelichEvBeWo/CaritasVerbandDuerenJuelichEvBeWo.csproj +++ b/ReportImp/CaritasVerbandDuerenJuelichEvBeWo/CaritasVerbandDuerenJuelichEvBeWo.csproj @@ -57,6 +57,8 @@ + + Component diff --git a/ReportImp/CaritasVerbandDuerenJuelichEvBeWo/Export/CustomDataExporter.cs b/ReportImp/CaritasVerbandDuerenJuelichEvBeWo/Export/CustomDataExporter.cs new file mode 100644 index 000000000..5aaccf96d --- /dev/null +++ b/ReportImp/CaritasVerbandDuerenJuelichEvBeWo/Export/CustomDataExporter.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using BeWo.Service.Core; +using BeWo.Service.Plugins; +using BS.Shared.Core; +using BS.Shared.DataContracts; +using Utils = BS.Shared.Core.Utils; + +namespace CaritasverbandDuerenJuelichEV.Export +{ + public class SkmDataExporter : DataExporter + { + public override string CreateExportString(string pFileID, string[] pHeaderCaption, string[][] pContent) + { + + if (pHeaderCaption != null && pHeaderCaption.Length > 0 && pHeaderCaption[0].Contains("Diamant")) + { + return DiamantExporter.CreateExportString(pHeaderCaption, pContent); + } + return base.CreateExportString(pFileID, pHeaderCaption, pContent); + + } + + public override QueryDC CreateQuery(QueryDC query) + { + var q = DiamantExporter.CreateQuery(query); + CreateBuchungsExportProtokollEintrag(q); + + return q; + } + } +} diff --git a/ReportImp/CaritasVerbandDuerenJuelichEvBeWo/Export/DiamantExporter.cs b/ReportImp/CaritasVerbandDuerenJuelichEvBeWo/Export/DiamantExporter.cs new file mode 100644 index 000000000..3fabd1dcb --- /dev/null +++ b/ReportImp/CaritasVerbandDuerenJuelichEvBeWo/Export/DiamantExporter.cs @@ -0,0 +1,629 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Text; +using BeWo.Data.Access; +using BeWo.Data.Entities; +using BeWo.Report.DefaultReports; +using BeWo.Report.ReportObjects; +using BeWo.Service.Plugins; +using BS.Shared.DataContracts; + +namespace CaritasverbandDuerenJuelichEV.Export +{ + public class DiamantExporter + { + + public static QueryDC CreateQuery(QueryDC query) + { + DateTime dt = DateTime.Now; + DateTime.TryParse(query.Parameter[0].Value.ToString(), out dt); + + if (query.Title == "Diamant Export Stammdaten") + { + query.FileName = String.Format("005S{0:yyMM}.er2", dt); + query.QueryResult = GetDebitorenString(dt); + } + else + { + long? customerOid = null; + + if (query.Parameter.Count > 1) + { + if (query.Parameter[1].Value != null) + { + long oid = 0; + if (Int64.TryParse(query.Parameter[1].Value.ToString(), out oid)) + { + customerOid = oid; + } + } + } + + if (query.Title == "Diamant Korrektur") + { + query.FileName = String.Format("005F{0:yyMM}.er2", dt); + query.QueryResult = GetKorrekturString(dt, customerOid); + } + else + { + query.FileName = String.Format("005F{0:yyyyMM}.er2", dt); + var dtAbgrenzungen = ExecuteQuery(GetAbgrenzungsLvrLwlSql(), dt); + Dictionary oid2InvoiceNumbers; + query.QueryResult = GetAbrechnungenString(dt, customerOid, dtAbgrenzungen, out oid2InvoiceNumbers); + query.Attachments = CreateAttachmentFile(dt, dtAbgrenzungen, oid2InvoiceNumbers); + } + + } + + return query; + } + + public static string CreateExportString(string[] pHeaderCaption, string[][] pContent) + { + if (pHeaderCaption != null && pHeaderCaption.Length > 1 && pHeaderCaption[0].Contains("Diamant")) + { + DateTime dt = DateTime.Now; + DateTime.TryParse(pHeaderCaption[1], out dt); + return GetAbrechnungenString(dt, null); + } + return null; + } + + private static string GetKorrekturString(DateTime dt, long? customerOid) + { + var exports = DAOFactory.GenericDAO.GetAllActive(); + + foreach (var exp in exports) + { + if (exp.Name == "Diamant Export Buchungssätze") + { + if (exp.Parameter.Contains(String.Format("Monat={0:dd.MM.yyyy}", dt))) + { + return GetKorrekturString(exp, customerOid); + } + } + } + + return ""; + } + + private static string GetKorrekturString(BuchungsExport exp, long? customerOid) + { + StringBuilder sb = new StringBuilder(); + var lines = exp.Export.Split(new string[] {"F,0,005,,,AR,"}, StringSplitOptions.RemoveEmptyEntries); + + foreach (var line in lines) + { + if (!customerOid.HasValue) + { + sb.Append("F,0,005,,,AG,"); + sb.Append(line); + } + else + { + var cust = DAOFactory.GenericDAO.LoadByID(customerOid.Value); + + String name = String.Format("{0}, {1}", cust.Person.LastName, cust.Person.FirstName); + String contains = String.Format("\"{0}\"", name); + if (line.Contains(contains)) + { + sb.Append("F,0,005,,,AG,"); + sb.Append(line); + } + } + } + return sb.ToString(); + } + + public static String GetDebitorenString(DateTime date) + { + var dt = ExecuteQuery(GetDebitorenSql(date), date); + + StringBuilder sb = new StringBuilder(); + foreach (DataRow row in dt.Rows) + { + if (sb.Length > 0) + { + sb.AppendLine(); + } + for (int i = 0; i < row.ItemArray.Length; i++) + { + if (i > 0) + { + sb.Append(","); + } + var item = row[i]; + bool quote = i == 4 || i == 5 || i == 6 || i > 24; + + if (quote) + { + sb.Append('"'); + sb.Append(item); + sb.Append('"'); + } + else + { + sb.Append(item); + } + } + + } + //Debitorenstamm + //S,0, D,200001,,"Bezeichnung1","Bezeichnung2",,,1200,,,,,,,,,,,,,,,,,"Name1","Name2", "Name3","Straße","PLZ","Ort" + return sb.ToString(); + } + + public static String GetAbrechnungenString(DateTime date, long? customerOid, DataTable dtAbgrenzungen = null) + { + Dictionary _; + return GetAbrechnungenString(date, customerOid, dtAbgrenzungen, out _); + } + + public static String GetAbrechnungenString(DateTime date, long? customerOid, DataTable dtAbgrenzungen, out Dictionary oid2InvoiceNumbers) + { + StringBuilder sb = new StringBuilder(); + + // 1. Monatliche Abrechnungen + var s = GetMonatlicheAbrechnungString(date, customerOid); + if (!String.IsNullOrWhiteSpace(s)) + { + sb.Append(s); + } + + // 2. Spitzabrechnungen + s = GetSpitzabrechnungString(date, customerOid); + if (!String.IsNullOrWhiteSpace(s)) + { + if (sb.Length > 0) + sb.AppendLine(); + sb.Append(s); + } + + // 3. Abgrenzungsbuchungen LVR/LWL + // DataTable wird von außen übergeben (aus CreateQuery), um doppelte SQL-Ausführung zu vermeiden. + // Falls nicht übergeben (z.B. aus CreateExportString), wird die SQL hier ausgeführt. + var abgrenzungenTable = dtAbgrenzungen ?? ExecuteQuery(GetAbgrenzungsLvrLwlSql(), date); + s = GetAbgrenzungsString(abgrenzungenTable, out oid2InvoiceNumbers); + if (!String.IsNullOrWhiteSpace(s)) + { + if (sb.Length > 0) + sb.AppendLine(); + sb.Append(s); + } + + if (sb.Length > 0) + sb.AppendLine(); + + return sb.ToString(); + } + + public static String GetMonatlicheAbrechnungString(DateTime date, long? customerOid) + { + // Export enthält Rechnungsangaben Zeilen (Zeile F) und Kostenstellen/Rechnungspositionsangaben (Zeile K) in zwei Zeilen + // Kommen aus Export in einer Zeile und werden hier getrennt, aber nur falls die Rechnung mehrere Positionen hat + // Systemrechnungsnummern (ib.InvoiceNumber) werden direkt verwendet, kein Generator + var dt = ExecuteQuery(GetMonatlicheAbrechnungSql(), date); + return BuildDiamantLines(dt, null); + } + + public static String GetSpitzabrechnungString(DateTime date, long? customerOid) + { + // Systemrechnungsnummern (ib.InvoiceNumber) werden direkt verwendet, kein Generator + var dt = ExecuteQuery(GetSpitzabrechnungSql(), date); + return BuildDiamantLines(dt, null); + } + + public static String GetAbgrenzungsString(DataTable dt, out Dictionary oid2GeneratedNumber) + { + // Abgrenzungsbuchungen für LVR/LWL haben keine Systemrechnungsnummern → pro Buchung (Zeile) eine Rechnungsnummer über den Generator vergeben + + var generator = PluginLoader.FindClass(); + var invoiceNumberDC = generator.LoadInvoiceNumber(); + oid2GeneratedNumber = new Dictionary(); + int invoiceCount = 0; + + if (invoiceNumberDC != null && invoiceNumberDC.Use) + { + foreach (DataRow row in dt.Rows) + { + string oid = row[0].ToString(); + if (!oid2GeneratedNumber.ContainsKey(oid)) + { + invoiceCount++; + // id = leer, da kein bestehender Bezug zur InvoiceNumber + oid2GeneratedNumber[oid] = generator.GetNextInvoiceNumber(invoiceCount, String.Empty); + } + } + } + + string result = BuildDiamantLines(dt, oid2GeneratedNumber); + + // Rechnungsnummern-Zähler in der DB hochschreiben + if (invoiceCount > 0) + { + generator.IncreaseInvoiceNumber(invoiceCount, new List()); + } + + return result; + } + + + // Gemeinsame Schleife für alle Buchungsarten im Diamant-Format. + // Spalte 0: OID (zur Deduplizierung bei mehreren Positionen pro Rechnung). + // Spalten 1-33: F-Zeile (Rechnungskopf). Ab Spalte 34 (stopIdx): K-Zeile (Kostenstelle/Position). + // Wenn oid2GeneratedNumber != null und die OID enthält, wird Spalte 10 (Rechnungsnummer) durch die generierte Nummer ersetzt. Andernfalls wird der DB-Wert verwendet. + private static String BuildDiamantLines(DataTable dt, Dictionary oid2GeneratedNumber) + { + const int startIdx = 1; + const int stopIdx = 34; // ab da beginnen Angaben zu Kostenstelle → zweite Zeile + + StringBuilder sb = new StringBuilder(); + Dictionary oid2Row = new Dictionary(); + + foreach (DataRow row in dt.Rows) + { + string oid = row[0].ToString(); + + if (!oid2Row.ContainsKey(oid)) + { + // Erste Zeile für diese OID: F-Zeile + erste K-Zeile + oid2Row.Add(oid, row); + + if (sb.Length > 0) + sb.AppendLine(); + + for (int i = startIdx; i < row.ItemArray.Length; i++) + { + var item = row[i]; + + if (i == 10 && oid2GeneratedNumber != null && oid2GeneratedNumber.ContainsKey(oid)) + { + // Generierte Rechnungsnummer statt DB-Wert + sb.Append(oid2GeneratedNumber[oid]); + sb.Append(";"); + } + else if (i == 15 || i == 42) + { + sb.Append(String.Format("{0}", item.ToString().Replace(",", "."))); + sb.Append(";"); + } + else if (i == 16) + { + sb.Append('"'); + sb.Append(item); + sb.Append('"'); + } + else if (i == stopIdx) + { + sb.AppendLine(); + sb.Append(item); + sb.Append(";"); + } + else if (i == 12 || i == 44) + { + string konto = SetKonto(item); + sb.Append(String.Format("{0}", konto)); + sb.Append(";"); + } + else + { + sb.Append(item); + sb.Append(";"); + } + } + } + else + { + // Weitere Zeile für dieselbe OID: nur zusätzliche K-Zeile ausgeben + if (sb.Length > 0) + sb.AppendLine(); + + for (int i = startIdx; i < row.ItemArray.Length; i++) + { + var item = row[i]; + // F-Zeilen-Spalten überspringen, nur Kostenstellen ausgeben + if (i == stopIdx) + { + sb.Append(item); + sb.Append(";"); + } + else if (i == 42) + { + sb.Append(String.Format("{0}", item.ToString().Replace(",", "."))); + sb.Append(";"); + } + else if (i == 44) + { + string konto = SetKonto(item); + sb.Append(String.Format("{0}", konto)); + sb.Append(";"); + } + else if (i > stopIdx) + { + sb.Append(item); + sb.Append(";"); + } + } + } + } + + return sb.ToString(); + } + + private static string SetKonto(object item) + { + string konto = "84190"; // eigentlich alles außer Selbstzahler + if (item != null) + { + if (item.ToString().ToLower().Contains("selbstzahler")) + { + konto = "84191"; + } + } + return konto; + } + + private static String GetDebitorenSql(DateTime date) + { + String sql = @" +SELECT +distinct +'S', +'0', +'D', +c.DebitorNumber, +CONCAT(p.`LastName`, ' ', p.`FirstName`), +CONCAT(p.`LastName`, ' ', p.`FirstName`), +cb2sc.CustomerRefenrenceNumber, +null, +null, +null, +null, +null, +null, +null, +'D', +'30 Tage netto', +null, +null, +null, +null, +null, +null, +null, +null, +null, +p.`FirstName`, +p.`LastName`, +'', +'', +a.Street, +a.PostalCode, +a.Town +FROM `customer` c +INNER JOIN `person` p ON p.`Oid` = c.`PersonOid` +INNER JOIN supportconcept sc on sc.CustomerOID = c.Oid +INNER JOIN costbearer2supportconcept cb2sc on cb2sc.SupportConceptOID = sc.Oid +LEFT JOIN Address a on p.addressOid = a.oid +WHERE c.isactive=1 +order by p.`LastName`, p.FirstName +"; + return sql; + } + + private static String GetMonatlicheAbrechnungSql() + { + String sql = @" + +SELECT +CONCAT(cb2sc.Oid, ib.InvoiceNumber, Round(sip.Claim, 0)) AS OID, +'F', +'0', +'99', +null, +null, +'AR', +':Abrechnungsmonat', +':Periode', +null, +ib.InvoiceNumber, +c.DebitorNumber, +CONCAT(ii.ItemDescription, ' ', org.Name), +null, +null, +Round(sip.Claim, 2) AS 'Betrag', +CONCAT('Re. ', p.`LastName`, ', ', p.`FirstName`) as 'Verwendung', +null, null, null, 'EUR', +null, null, null, '14', null, null, null, null, null, null, null, null, null, +'K', 0, c.CostCenter, null, 'V', null, null, null, Round(ii.AmountTotal * -1, 2), null, CONCAT(ii.ItemDescription, ' ', org.Name), null, null, null, null, null, null + FROM + person p + INNER JOIN customer c on c.personoid = p.oid + INNER JOIN supportconcept sc on sc.customeroid = c.oid + INNER JOIN costbearer2supportconcept cb2sc on cb2sc.supportconceptoid = sc.oid + INNER JOIN costbearer cb on cb2sc.costbeareroid = cb.oid + INNER JOIN organisation org on org.costbeareroid = cb.oid + INNER JOIN invoicebase ib on ib.costbearer2supportconceptoid = cb2sc.oid + INNER JOIN serviceinvoice si on si.invoicebaseoid = ib.oid + INNER JOIN serviceinvoiceperiod sip on sip.serviceinvoiceoid = si.oid + INNER JOIN invoiceitem ii on ii.ServiceInvoicePeriodOid = sip.oid +WHERE c.`IsActive` = 1 AND sc.`IsActive` = 1 and ib.isactive = 1 and ib.type <> 1 +and ib.`AccountingPeriodEnd` >= ':Monat_Start' AND ib.`AccountingPeriodStart` < ':Monat_End' + +ORDER BY ib.invoicenumber +"; + return sql; + } + + private static String GetSpitzabrechnungSql() + { + String sql = @" +SELECT +CONCAT(cb2sc.Oid, ib.InvoiceNumber) AS OID, +'F', +'0', +'99', +null, +null, +'AR', +':Abrechnungsmonat', +':Periode', +null, +ib.InvoiceNumber, +c.DebitorNumber, +CONCAT('Spitzabrechnung ', org.Name), +null, +null, +Round(si.Claim, 2) AS 'Betrag', +CONCAT('Re. ', p.`LastName`, ', ', p.`FirstName`) as 'Verwendung', +null, null, null, 'EUR', +null, null, null, '14', null, null, null, null, null, null, null, null, null, +'K', 0, c.CostCenter, null, 'V', null, null, null, Round(si.Claim * -1, 2), null, CONCAT('Spitzabrechnung ', org.Name), null, null, null, null, null, null +FROM person p +INNER JOIN customer c on c.personoid = p.oid +INNER JOIN supportconcept sc on sc.customeroid = c.oid +INNER JOIN costbearer2supportconcept cb2sc on cb2sc.supportconceptoid = sc.oid +INNER JOIN costbearer cb on cb2sc.costbeareroid = cb.oid +INNER JOIN organisation org on org.costbeareroid = cb.oid +INNER JOIN invoicebase ib on ib.costbearer2supportconceptoid = cb2sc.oid +INNER JOIN settlementinvoice si on si.invoicebaseoid = ib.oid +WHERE c.`IsActive` = 1 AND sc.`IsActive` = 1 and ib.isactive = 1 +AND ib.`AccountingPeriodEnd` >= ':Monat_Start' AND ib.`AccountingPeriodStart` < ':Monat_End' +ORDER BY ib.invoicenumber +"; + return sql; + } + + private static String GetAbgrenzungsLvrLwlSql() + { + String sql = @" +SELECT +CAST(stunden.cb2sc_oid AS CHAR) AS OID, +'F', +'0', +'99', +null, +null, +'AR', +':Abrechnungsmonat', +':Periode', +null, +null AS InvoiceNumber, +stunden.DebitorNumber, +CONCAT('Abgrenzung ', stunden.OrgName), +null, +null, +ROUND(stunden.Stunden * stunden.Stundensatz, 2) AS Betrag, +CONCAT('Abgr. ', stunden.LastName, ', ', stunden.FirstName) as Verwendung, +null, null, null, 'EUR', +null, null, null, '14', null, null, null, null, null, null, null, null, null, +'K', 0, stunden.CostCenter, null, 'V', null, null, null, +ROUND(stunden.Stunden * stunden.Stundensatz * -1, 2), +null, +CONCAT('Abgrenzung ', stunden.OrgName), +null, null, null, null, null, null +FROM ( + SELECT + cb2sc.Oid AS cb2sc_oid, + c.DebitorNumber, + org.Name AS OrgName, + p.LastName, + p.FirstName, + SUM(sr.roundedduration / IF(sr.GroupEmployeeCount IS NULL, 1, sr.GroupEmployeeCount)) / 60 AS Stunden, + (SELECT crp.CostRateValue + FROM costrateperiod crp + WHERE crp.ObjectTid = 22 AND crp.CostRateType = 0 AND crp.ObjectOid = cb2sc.CostBearerOid + AND (crp.EndDate IS NULL OR crp.EndDate > ':Monat_Start') + ORDER BY IF(crp.EndDate IS NULL, MAKEDATE(9999,365), crp.EndDate) LIMIT 1) AS Stundensatz, + c.CostCenter + FROM supportconcept sc + INNER JOIN costbearer2supportconcept cb2sc ON sc.Oid = cb2sc.SupportConceptOid + INNER JOIN costbearer cb ON cb2sc.CostBearerOid = cb.Oid + INNER JOIN organisation org ON org.CostBearerOid = cb.Oid + INNER JOIN customer c ON sc.CustomerOid = c.Oid + INNER JOIN person p ON c.PersonOid = p.Oid + INNER JOIN servicerecord sr ON sr.CostBearer2SupportConceptOid = cb2sc.Oid + INNER JOIN servicedescription sd ON sr.ServiceDescriptionOid = sd.Oid + INNER JOIN servicecategory scat ON sd.ServiceCategoryOid = scat.Oid + WHERE c.IsActive = 1 AND sc.IsActive = 1 + AND (org.Name = 'LVR' OR org.Name = 'LWL') + AND sr.StartDate >= ':Monat_Start' AND sr.StartDate < ':Monat_End' + AND scat.Billable = 1 + GROUP BY cb2sc.Oid, c.DebitorNumber, org.Name, p.LastName, p.FirstName, c.CostCenter + HAVING SUM(sr.roundedduration) > 0 +) AS stunden +ORDER BY stunden.LastName, stunden.FirstName +"; + return sql; + } + + private static List CreateAttachmentFile(DateTime date, DataTable dtAbgrenzungen, Dictionary oid2GeneratedNumber) + { + try + { + // Spalten aus der bereits ausgeführten Abgrenzungs-DataTable verwenden: + // 0 = OID, 11 = DebitorNumber, 12 = 'Abgrenzung OrgName', 15 = Betrag, 16 = 'Abgr. Nachname, Vorname' + DataTable table = new DataTable(); + string[] spalten = { "Rechnungsnr.", "Empfänger", "Debitornr.", "Erlöskonto", "Kostenstelle", "Verwendung", "Betrag" }; + foreach (var spalte in spalten) + table.Columns.Add(spalte, typeof(string)); + + foreach (DataRow booking in dtAbgrenzungen.Rows) + { + string oid = booking[0].ToString(); + string invoiceNumber = String.Empty; + if (oid2GeneratedNumber != null && oid2GeneratedNumber.ContainsKey(oid)) + invoiceNumber = oid2GeneratedNumber[oid]; + + string erloeskonto = SetKonto(booking[12]); + + DataRow row = table.NewRow(); + row[0] = invoiceNumber; + row[1] = booking[12].ToString().Replace("Abgrenzung ", ""); + row[2] = booking[11]; + row[3] = erloeskonto; + row[4] = booking[36]; // c.CostCenter + row[5] = booking[16].ToString().Replace("Abgr. ", ""); + row[6] = String.Format("{0:0.00}", booking[15]); + table.Rows.Add(row); + } + + var queryReportObject = QueryRO.Create(new Query() { Title = "Export" }, table); + queryReportObject.Name = String.Format("Abgrenzungsbuchungen {0:MMMM yyyy}", date); + + var queryReport = new Bericht(); + queryReport.SetReportDataSource(queryReportObject); + queryReport.CreateDocument(); + + var pdf = new FileAttachmentDC(); + pdf.FileName = String.Format("Abgrenzungsbuchungen{0:MMyyyy}.pdf", date); + using (var ms = new MemoryStream()) + { + queryReport.ExportToPdf(ms); + pdf.BinaryData = ms.ToArray(); + } + + return new List { pdf }; + } + catch (Exception) + { + return null; + } + } + + public static DataTable ExecuteQuery(String sql, DateTime dt) + { + var newsql = sql; + newsql = newsql.Replace(":PeriodeSlash", String.Format("{0:MM/yyyy}", dt)); + newsql = newsql.Replace(":Periode", String.Format("{0:MMyyyy}", dt)); + newsql = newsql.Replace(":Abrechnungsmonat", String.Format("{0:ddMMyyyy}", dt)); + newsql = newsql.Replace(":Monat_Start", String.Format("{0:yyyy-MM}-01", dt)); + dt = dt.AddMonths(1); + newsql = newsql.Replace(":Monat_End", String.Format("{0:yyyy-MM}-01", dt)); + + return DAOFactory.AdoDAO.ExecuteQuery(newsql).Tables[0]; + } + } +}