using System; using System.Collections.Generic; using System.Data.SQLite; namespace Электронная_Фармация.Classes { /// /// Аптека = грузополучатель + LocationId. Прайс общий, заказы уходят с location_id выбранной аптеки. /// public static class ConsigneeHelper { public static string GetDefaultConsigneeName() { try { using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString)) { connection.Open(); using (var command = new SQLiteCommand( @"SELECT ConsigneesName FROM Consignees ORDER BY ConsigneesUseAsDefault DESC, ConsigneesName LIMIT 1", connection)) { var result = command.ExecuteScalar(); return result == null || result == DBNull.Value ? string.Empty : result.ToString().Trim(); } } } catch { return string.Empty; } } public static string GetLocationIdByName(string consigneeName) { if (string.IsNullOrWhiteSpace(consigneeName)) { return string.Empty; } using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString)) { connection.Open(); using (var command = new SQLiteCommand( @"SELECT ifnull(LocationId, '') FROM Consignees WHERE ConsigneesName = @name LIMIT 1", connection)) { command.Parameters.AddWithValue("@name", consigneeName.Trim()); var result = command.ExecuteScalar(); return result == null || result == DBNull.Value ? string.Empty : result.ToString().Trim(); } } } public static string ResolveLocationId(string consigneeName) { var fromConsignee = GetLocationIdByName(consigneeName); if (!string.IsNullOrWhiteSpace(fromConsignee)) { return fromConsignee; } return AppConfig.LocationId ?? string.Empty; } /// /// Помечает аптеку активной и синхронизирует AppConfig.LocationId. /// public static void SetActiveConsignee(string consigneeName) { if (string.IsNullOrWhiteSpace(consigneeName)) { return; } var name = consigneeName.Trim(); using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString)) { connection.Open(); using (var tx = connection.BeginTransaction()) { using (var clear = new SQLiteCommand( "UPDATE Consignees SET ConsigneesUseAsDefault = 0", connection, tx)) { clear.ExecuteNonQuery(); } using (var setDefault = new SQLiteCommand( @"UPDATE Consignees SET ConsigneesUseAsDefault = 1 WHERE ConsigneesName = @name", connection, tx)) { setDefault.Parameters.AddWithValue("@name", name); setDefault.ExecuteNonQuery(); } tx.Commit(); } var locationId = GetLocationIdByName(name); if (!string.IsNullOrWhiteSpace(locationId)) { AppConfig.SetLocationId(locationId); } } } public static void SetLocationId(string consigneeName, string locationId) { if (string.IsNullOrWhiteSpace(consigneeName)) { return; } using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString)) { connection.Open(); using (var command = new SQLiteCommand( @"UPDATE Consignees SET LocationId = @loc WHERE ConsigneesName = @name", connection)) { command.Parameters.AddWithValue("@loc", (locationId ?? string.Empty).Trim()); command.Parameters.AddWithValue("@name", consigneeName.Trim()); command.ExecuteNonQuery(); } } } public static void MigrateGlobalLocationIdIfNeeded(SQLiteConnection connection) { var global = AppConfig.LocationId; if (string.IsNullOrWhiteSpace(global)) { return; } using (var command = new SQLiteCommand( @"UPDATE Consignees SET LocationId = @loc WHERE (LocationId IS NULL OR trim(LocationId) = '') AND ( ConsigneesUseAsDefault = 1 OR (SELECT COUNT(*) FROM Consignees) = 1 )", connection)) { command.Parameters.AddWithValue("@loc", global.Trim()); command.ExecuteNonQuery(); } } public static void ApplyLocationIdToEmptyConsignees(string locationId) { if (string.IsNullOrWhiteSpace(locationId)) { return; } using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString)) { connection.Open(); using (var command = new SQLiteCommand( @"UPDATE Consignees SET LocationId = @loc WHERE LocationId IS NULL OR trim(LocationId) = ''", connection)) { command.Parameters.AddWithValue("@loc", locationId.Trim()); command.ExecuteNonQuery(); } } } public static IList GetKnownSupplierIds() { var result = new List(); using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString)) { connection.Open(); using (var command = new SQLiteCommand( @"SELECT DISTINCT trim(supplier_id) FROM PriceList WHERE supplier_id IS NOT NULL AND trim(supplier_id) <> '' ORDER BY 1", connection)) using (var reader = command.ExecuteReader()) { while (reader.Read()) { var id = reader.GetString(0); if (!string.IsNullOrWhiteSpace(id)) { result.Add(id); } } } } return result; } /// /// Процент наценки, который клиент задал вручную для аптеки. /// null = ещё не сохраняли, брать fallback. /// public static decimal? GetClientMarkupPercent(string consigneeName) { if (string.IsNullOrWhiteSpace(consigneeName)) { return null; } try { using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString)) { connection.Open(); using (var command = new SQLiteCommand( @"SELECT ClientMarkupPercent FROM Consignees WHERE ConsigneesName = @name LIMIT 1", connection)) { command.Parameters.AddWithValue("@name", consigneeName.Trim()); var result = command.ExecuteScalar(); if (result == null || result == DBNull.Value) { return null; } if (result is decimal d) { return d; } if (decimal.TryParse( Convert.ToString(result, System.Globalization.CultureInfo.InvariantCulture), System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var parsed)) { return parsed; } return null; } } } catch { return null; } } /// /// Сохраняет процент наценки клиента для конкретной аптеки. /// Не сбрасывается при обновлении прайса. /// public static void SetClientMarkupPercent(string consigneeName, decimal markupPercent) { if (string.IsNullOrWhiteSpace(consigneeName)) { return; } using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString)) { connection.Open(); using (var command = new SQLiteCommand( @"UPDATE Consignees SET ClientMarkupPercent = @pct WHERE ConsigneesName = @name", connection)) { command.Parameters.AddWithValue("@pct", markupPercent); command.Parameters.AddWithValue("@name", consigneeName.Trim()); command.ExecuteNonQuery(); } } } /// /// Если у аптеки ещё нет сохранённого процента — записать стартовое значение с сервера. /// Уже введённые клиентом значения не трогаем. /// public static void SeedClientMarkupPercentIfEmpty(decimal? serverMarkupPercent) { if (!serverMarkupPercent.HasValue) { return; } using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString)) { connection.Open(); using (var command = new SQLiteCommand( @"UPDATE Consignees SET ClientMarkupPercent = @pct WHERE ClientMarkupPercent IS NULL", connection)) { command.Parameters.AddWithValue("@pct", serverMarkupPercent.Value); command.ExecuteNonQuery(); } } } /// /// Синхронизирует поля заказа в `PriceList` (Zakaz/SummaZakaza) с корзиной выбранной аптеки. /// Данные корзины хранятся в TempOrderItems с фильтром по ConsigneeName, а PriceList обновляется /// только для текущего активного просмотра. /// public static void SyncCartToPriceList(string consigneeName) { var consignee = (consigneeName ?? string.Empty).Trim().Replace("'", "''"); using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString)) { connection.Open(); using (var tx = connection.BeginTransaction()) { using (var clear = new SQLiteCommand( @"UPDATE [PriceList] SET [Zakaz] = NULL, [SummaZakaza] = NULL;", connection, tx)) { clear.ExecuteNonQuery(); } using (var sync = new SQLiteCommand( @"UPDATE [PriceList] SET [Zakaz] = ( SELECT t.[Zakaz] FROM [TempOrderItems] t WHERE t.[ConsigneeName] = @consignee AND t.[id_PriceList_Item] = [PriceList].[id_PriceList_Item] LIMIT 1 ), [SummaZakaza] = ( SELECT t.[SummaZakaza] FROM [TempOrderItems] t WHERE t.[ConsigneeName] = @consignee AND t.[id_PriceList_Item] = [PriceList].[id_PriceList_Item] LIMIT 1 ) WHERE EXISTS ( SELECT 1 FROM [TempOrderItems] t WHERE t.[ConsigneeName] = @consignee AND t.[id_PriceList_Item] = [PriceList].[id_PriceList_Item] );", connection, tx)) { sync.Parameters.AddWithValue("@consignee", consignee); sync.ExecuteNonQuery(); } tx.Commit(); } } } } }