Files
bnhtrade/src/bnhtrade.Core/Data/Database/SqlWhereBuilder.cs
Bobbie Hodgetts 29f9fae508 Added invoice export function and started implementation of unitofwork pattern (#43)
* complete read invoices from db

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* updated nuget package spapi

* WIP

* wip, now test

* wip, jut need to fix tax inclusive line amounts not supported

* wip

* wip, before I f everything up

* no, it complies now, this is the one before I f everything up

* wip

* wip

* wip, logic ready for testing

* wip it builds!!!!

* wip tested, working, need to complete the gui section

* wip

* wip

* wip - created export invoice data delete, time for testing

* wip testing phase

* wip - delete function fully tested and working

* wip on to sorting out the issue with settlement invoices not tallying

* wip

* wip

* wip

* wip

* wip before I complete change the ReadInvoiceLineItem sections

* that appears to have worked, on with the main quest

* no it's doesn't work, saving before i remove the confusing cache system (just use a dictionary!!)

* wipping picadilli

* wip

* wip

* implemented uow on inovice export, now for testing

* wip

* wip all tested do invoice currency convertion fearure

* wip

* pretty much done so long as xero accepts the exported invoices

* Complete!
2025-06-26 23:29:22 +01:00

303 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
namespace bnhtrade.Core.Data.Database
{
/// <summary>
/// Step 1: Call the methods for each where clause you want to create. This can be done multiple times to create an sql where string. Pay attention
/// to the prefixes that you'll require between each where clause, as each time a method is called the sql statement will be appended to the previous sql
/// string.
///
/// Step 2: Appened the created sql string to your sql statement, NB the WHERE statemet is not included by default.
///
/// Step 3: Once you've created your sql command object, add the parameters to it using the method contained within this class.
///
/// Step 4: exceute your sql commend.
/// </summary>
public class SqlWhereBuilder
{
private int parameterCount = 0;
public SqlWhereBuilder()
{
Init();
}
public string SqlWhereString { get; private set; }
public bool IsSetSqlWhereString
{
get
{
if (SqlWhereString == null || string.IsNullOrEmpty(SqlWhereString))
{
return false;
}
else
{
return true;
}
}
}
public Dictionary<string, object> ParameterList { get; private set; }
public int ParameterListCount
{
get
{
if (ParameterList == null || ParameterList.Any() == false)
{
return 0;
}
else
{
return ParameterList.Count();
}
}
}
/// <summary>
/// Initialises the class
/// </summary>
public void Init()
{
parameterCount = 0;
SqlWhereString = "";
ParameterList = new Dictionary<string, object>();
}
// delete this once all references use the new Microsoft.Data.SqlClient
public void AddParametersToSqlCommand(System.Data.SqlClient.SqlCommand cmd)
{
if (ParameterList != null)
{
foreach (var item in ParameterList)
{
cmd.Parameters.AddWithValue(item.Key, item.Value);
}
}
}
public void AddParametersToSqlCommand(Microsoft.Data.SqlClient.SqlCommand cmd)
{
if (ParameterList != null)
{
foreach (var item in ParameterList)
{
cmd.Parameters.AddWithValue(item.Key, item.Value);
}
}
}
/// <summary>
/// Append an 'Like' statement (with AND between each like string) and parameter list to the class properties
/// </summary>
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="phraseList">List of phrases to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void LikeAnd(string columnReference, IEnumerable<string> phraseList, string wherePrefix = null)
{
Like(columnReference, phraseList, true, wherePrefix);
}
/// <summary>
/// Append an 'Like' statement (with OR between each like string) and parameter list to the class properties
/// </summary>
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="phraseList">List of phrases to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void LikeOr(string columnReference, IEnumerable<string> phraseList, string wherePrefix = null)
{
Like(columnReference, phraseList, false, wherePrefix);
}
private void Like(string columnReference, IEnumerable<string> phraseList, bool isAnd, string wherePrefix = null)
{
if (phraseList == null || !phraseList.Any())
{
return;
}
// ensure no values are repeated
var distinctList = phraseList.Distinct().ToList();
// clean the list
for (int i = 0; i < distinctList.Count; i++)
{
if (string.IsNullOrEmpty(distinctList[i]))
{
distinctList.RemoveAt(i);
i--;
}
}
// check again
if (distinctList == null || !distinctList.Any())
{
return;
}
string sqlWhere = @"
";
if (wherePrefix != null)
{
sqlWhere += wherePrefix;
}
int listCount = distinctList.Count();
for (int i = 0; i < listCount; i++, parameterCount++)
{
if (i > 0)
{
if (isAnd)
{
sqlWhere += " AND ";
}
else
{
sqlWhere += " OR ";
}
}
sqlWhere += " ( " + columnReference + " LIKE '%' + ";
string param = "@parameter" + parameterCount;
sqlWhere += param;
ParameterList.Add(param, distinctList[i]);
sqlWhere += " + '%' ) ";
}
SqlWhereString = SqlWhereString + sqlWhere;
}
/// <summary>
/// Append an 'In' statement and parameter list to the class properties
/// </summary>
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="orValueList">List of values to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void In(string columnReference, IEnumerable<object> orValueList, string wherePrefix = null)
{
if (orValueList == null || !orValueList.Any())
{
return;
}
var distinctList = orValueList.Distinct().ToList();
string sqlWhere = @"
";
if (wherePrefix != null)
{
sqlWhere += wherePrefix;
}
sqlWhere += " " + columnReference + " IN ( ";
int listCount = distinctList.Count();
for (int i = 0; i < listCount; i++, parameterCount++)
{
if (i > 0)
{
sqlWhere += ", ";
}
string param = "@parameter" + parameterCount;
sqlWhere += param;
ParameterList.Add(param, distinctList[i]);
}
sqlWhere += " ) ";
SqlWhereString = SqlWhereString + sqlWhere;
}
/// <summary>
/// Append an 'In' statement and parameter list to the class properties
/// </summary>
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="orValueList">List of values to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void In(string columnReference, IEnumerable<string> orValueList, string wherePrefix = null)
{
var objectList = new List<object>();
if (orValueList != null && orValueList.Any())
{
foreach (string value in orValueList)
{
objectList.Add(value.ToString());
}
}
In(columnReference, objectList, wherePrefix);
}
/// <summary>
/// Append an 'In' statement and parameter list to the class properties
/// </summary>
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="orValueList">List of values to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void In(string columnReference, IEnumerable<int> orValueList, string wherePrefix = null)
{
var objectList = new List<object>();
if (orValueList != null && orValueList.Any())
{
foreach (var value in orValueList)
{
objectList.Add(value.ToString());
}
}
In(columnReference, objectList, wherePrefix);
}
/// <summary>
/// Append an 'In' statement and parameter list to the class properties
/// </summary>
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="orValueList">List of values to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void In(string columnReference, IEnumerable<uint> orValueList, string wherePrefix = null)
{
var objectList = new List<object>();
if (orValueList != null && orValueList.Any())
{
foreach (var value in orValueList)
{
objectList.Add(value.ToString());
}
}
In(columnReference, objectList, wherePrefix);
}
public void In(string columnReference, IEnumerable<DateTime> orValueList, string wherePrefix = null)
{
var objectList = new List<object>();
if (orValueList != null && orValueList.Any())
{
foreach(var value in orValueList)
{
objectList.Add(value.ToString());
}
}
In(columnReference, objectList, wherePrefix);
}
}
}