Replace O(n^2) per-keystroke rebuild with indexed unique names, a single-pass filter, and debounce so typing stays responsive with ~15k items.
2602 lines
100 KiB
C#
2602 lines
100 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Globalization;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Text.RegularExpressions;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using System.Data.SQLite;
|
||
using System.Data.OleDb;
|
||
using System.Data.Common;
|
||
using Elfisa.UI.Controls;
|
||
using Электронная_Фармация.Classes;
|
||
using Электронная_Фармация.HelpForms;
|
||
|
||
namespace Электронная_Фармация.UserControls
|
||
{
|
||
public partial class UCPriceList : UserControl
|
||
{
|
||
public UCPriceList(string workWithConsignee)
|
||
{
|
||
InitializeComponent();
|
||
_WorkWithConsignee = workWithConsignee;
|
||
}
|
||
|
||
public string ConsigneeName => txtConsignee?.Text ?? string.Empty;
|
||
|
||
SQLiteDataAdapter daPriceList;
|
||
DataSet dsPriceList;
|
||
BindingSource bsPriceList = new BindingSource();
|
||
DataAdapter daPriceListMain;
|
||
DataTable tablePriceList;
|
||
string _WorkWithConsignee;
|
||
decimal _percentageAsDefault;
|
||
bool _suppressMarkupPersist;
|
||
string _selectedSupplierFilter = string.Empty;
|
||
bool _suppressSupplierFilterEvents;
|
||
bool _suppressPriceListSelectionEvents;
|
||
bool _suppressBrowseEvents;
|
||
int _committedSupplierFilterIndex;
|
||
DataTable _fullPriceTable;
|
||
PriceBrowseMode _browseMode = PriceBrowseMode.Browse;
|
||
string _selectedBaseName = string.Empty;
|
||
string _selectedMg = string.Empty;
|
||
int _browseSplitterDistance = 0;
|
||
ModernSplitContainer splitNameMgBrowse;
|
||
ModernDataGridView dgvBrowseNames;
|
||
ModernDataGridView dgvBrowseMg;
|
||
List<string> _uniqueBaseNames = new List<string>();
|
||
Dictionary<string, List<string>> _mgByBaseName =
|
||
new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
|
||
Timer _searchDebounceTimer;
|
||
const int SearchDebounceMs = 180;
|
||
static readonly Regex DosageRegex = new Regex(
|
||
@"(\d+(?:[.,]\d+)?\s*(?:мг|мкг|г|мл|МЕ|ме)\b)",
|
||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||
const string EmptyMgDisplay = "(без МГ)";
|
||
|
||
private enum PriceBrowseMode
|
||
{
|
||
Browse,
|
||
Offers
|
||
}
|
||
|
||
string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
|
||
|
||
public void RefreshFromDatabase()
|
||
{
|
||
loadPriceListV2();
|
||
InitializeSupplierFilter();
|
||
loadTempOrderItems();
|
||
ApplyPriceListFilters();
|
||
}
|
||
|
||
private void UCPriceList_Load(object sender, EventArgs e)
|
||
{
|
||
EnsureBrowseSplit();
|
||
UiThemeHelper.ApplyToControlTree(this);
|
||
Tag = "chrome-child";
|
||
|
||
AlignSearchRow();
|
||
|
||
panel1.SizeChanged += (_, __) => LayoutMarkupRow();
|
||
LayoutMarkupRow();
|
||
|
||
txtConsignee.Enabled = false;
|
||
txtConsignee.Text = _WorkWithConsignee;
|
||
//loadConsignees();
|
||
//loadPriceList(string.Empty);
|
||
loadPriceListV2();
|
||
InitializeSupplierFilter();
|
||
loadTempOrderItems();
|
||
loadInfoAboutDefaultMarkup();
|
||
txtSearchGoodNameInPriceList.Focus();
|
||
}
|
||
|
||
private void EnsureBrowseSplit()
|
||
{
|
||
if (splitNameMgBrowse != null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
dgvBrowseNames = CreateBrowseGrid("dgvBrowseNames");
|
||
dgvBrowseMg = CreateBrowseGrid("dgvBrowseMg");
|
||
|
||
splitNameMgBrowse = new ModernSplitContainer
|
||
{
|
||
Name = "splitNameMgBrowse",
|
||
Dock = DockStyle.Fill,
|
||
Orientation = Orientation.Vertical,
|
||
SplitterWidth = 4,
|
||
Visible = false
|
||
};
|
||
splitNameMgBrowse.Panel1.Controls.Add(dgvBrowseNames);
|
||
splitNameMgBrowse.Panel2.Controls.Add(dgvBrowseMg);
|
||
|
||
TLPPriceList.Controls.Add(splitNameMgBrowse, 0, 0);
|
||
splitNameMgBrowse.BringToFront();
|
||
|
||
dgvBrowseNames.SelectionChanged += dgvBrowseNames_SelectionChanged;
|
||
dgvBrowseMg.CellClick += dgvBrowseMg_CellClick;
|
||
dgvBrowseNames.KeyPress += dgvPriceList_KeyPress;
|
||
dgvBrowseMg.KeyPress += dgvPriceList_KeyPress;
|
||
splitNameMgBrowse.SplitterMoved += (_, __) =>
|
||
{
|
||
if (splitNameMgBrowse.SplitterDistance > 80)
|
||
{
|
||
_browseSplitterDistance = splitNameMgBrowse.SplitterDistance;
|
||
}
|
||
};
|
||
}
|
||
|
||
private static ModernDataGridView CreateBrowseGrid(string name)
|
||
{
|
||
var grid = new ModernDataGridView
|
||
{
|
||
Name = name,
|
||
Dock = DockStyle.Fill,
|
||
AllowUserToAddRows = false,
|
||
AllowUserToDeleteRows = false,
|
||
AllowUserToResizeRows = false,
|
||
AllowUserToResizeColumns = true,
|
||
MultiSelect = false,
|
||
ReadOnly = true,
|
||
RowHeadersVisible = false,
|
||
SelectionMode = DataGridViewSelectionMode.FullRowSelect,
|
||
AutoGenerateColumns = true,
|
||
Font = new Font("Segoe UI", 13F, FontStyle.Regular),
|
||
TabStop = true
|
||
};
|
||
return grid;
|
||
}
|
||
|
||
private void AlignSearchRow()
|
||
{
|
||
const int searchY = 9;
|
||
const int searchHeight = 32;
|
||
const int clearGap = 2;
|
||
|
||
txtSearchGoodNameInPriceList.SetBounds(78, searchY, 313, searchHeight);
|
||
btnClearSearchInPriceList.SetBounds(
|
||
txtSearchGoodNameInPriceList.Right + clearGap,
|
||
searchY,
|
||
32,
|
||
searchHeight);
|
||
ModernButtonStyles.ApplyClear(btnClearSearchInPriceList);
|
||
|
||
btnClearSupplierFilter.Height = searchHeight;
|
||
}
|
||
|
||
private void LayoutMarkupRow()
|
||
{
|
||
// Keep markup row readable at different DPI/window sizes.
|
||
try
|
||
{
|
||
var paddingLeft = 8;
|
||
var y = 30;
|
||
var gap = 8;
|
||
|
||
label4.Location = new Point(paddingLeft, y + 2);
|
||
|
||
numericPercent.Location = new Point(label4.Right + 6, y);
|
||
numericPercent.Width = 56;
|
||
|
||
checkUsePercentageAsDefault.AutoSize = true;
|
||
checkUsePercentageAsDefault.Location = new Point(
|
||
Math.Max(numericPercent.Right + gap, panel1.ClientSize.Width - checkUsePercentageAsDefault.PreferredSize.Width - 10),
|
||
y + 2);
|
||
|
||
lblPriceForGood.AutoSize = false;
|
||
lblPriceForGood.AutoEllipsis = true;
|
||
lblPriceForGood.Location = new Point(numericPercent.Right + gap, y + 2);
|
||
lblPriceForGood.Height = 22;
|
||
lblPriceForGood.Width = Math.Max(90, checkUsePercentageAsDefault.Left - lblPriceForGood.Left - gap);
|
||
}
|
||
catch
|
||
{
|
||
// best-effort layout; ignore
|
||
}
|
||
}
|
||
|
||
private void InitializeSupplierFilter()
|
||
{
|
||
try
|
||
{
|
||
_suppressSupplierFilterEvents = true;
|
||
comboSupplierFilter.BeginUpdate();
|
||
comboSupplierFilter.Items.Clear();
|
||
comboSupplierFilter.Items.Add("Все поставщики");
|
||
|
||
var suppliers = new List<string>();
|
||
using (var con = new SQLiteConnection(connectionStringToLocalDB))
|
||
{
|
||
con.Open();
|
||
using (var cmd = new SQLiteCommand("select SupplierName from PriceList where SupplierName is not null and SupplierName <> '' group by SupplierName order by SupplierName asc;", con))
|
||
{
|
||
using (var reader = cmd.ExecuteReader())
|
||
{
|
||
while (reader.Read())
|
||
{
|
||
var value = reader.GetString(0);
|
||
if (!string.IsNullOrWhiteSpace(value))
|
||
{
|
||
suppliers.Add(value);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
foreach (var s in suppliers)
|
||
{
|
||
comboSupplierFilter.Items.Add(s);
|
||
}
|
||
|
||
comboSupplierFilter.SelectedIndex = 0;
|
||
_selectedSupplierFilter = string.Empty;
|
||
_committedSupplierFilterIndex = comboSupplierFilter.SelectedIndex;
|
||
btnClearSupplierFilter.Visible = false;
|
||
}
|
||
finally
|
||
{
|
||
comboSupplierFilter.EndUpdate();
|
||
_suppressSupplierFilterEvents = false;
|
||
}
|
||
}
|
||
|
||
private void ApplyPriceListFilters()
|
||
{
|
||
if (_browseMode == PriceBrowseMode.Browse)
|
||
{
|
||
ShowBrowseView();
|
||
return;
|
||
}
|
||
|
||
if (_fullPriceTable == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// Фильтр по базовому имени/МГ применим только к полной таблице прайса.
|
||
if (!ReferenceEquals(bsPriceList.DataSource, _fullPriceTable)
|
||
|| !_fullPriceTable.Columns.Contains("Базовое наименование")
|
||
|| !_fullPriceTable.Columns.Contains("МГ"))
|
||
{
|
||
ShowOffersView(_selectedBaseName, string.IsNullOrEmpty(_selectedMg) ? EmptyMgDisplay : _selectedMg);
|
||
return;
|
||
}
|
||
|
||
var parts = new List<string>();
|
||
|
||
if (!string.IsNullOrWhiteSpace(_selectedSupplierFilter))
|
||
{
|
||
var escapedSupplier = _selectedSupplierFilter.Replace("'", "''");
|
||
parts.Add($"[Поставщик] = '{escapedSupplier}'");
|
||
}
|
||
|
||
if (!string.IsNullOrWhiteSpace(_selectedBaseName))
|
||
{
|
||
var escapedName = _selectedBaseName.Replace("'", "''");
|
||
var escapedMg = (_selectedMg ?? string.Empty).Replace("'", "''");
|
||
parts.Add($"[Базовое наименование] = '{escapedName}'");
|
||
parts.Add($"[МГ] = '{escapedMg}'");
|
||
}
|
||
else if (!string.IsNullOrWhiteSpace(GoodsFilter))
|
||
{
|
||
var escaped = GoodsFilter.Replace("'", "''");
|
||
parts.Add($"[Наименование] like '%{escaped}%'");
|
||
}
|
||
|
||
try
|
||
{
|
||
bsPriceList.Filter = parts.Count == 0 ? string.Empty : string.Join(" AND ", parts);
|
||
}
|
||
catch (EvaluateException)
|
||
{
|
||
ShowOffersView(_selectedBaseName, string.IsNullOrEmpty(_selectedMg) ? EmptyMgDisplay : _selectedMg);
|
||
}
|
||
}
|
||
|
||
private void comboSupplierFilter_SelectionChangeCommitted(object sender, EventArgs e)
|
||
{
|
||
// Defer until the dropdown has fully closed.
|
||
BeginInvoke(new Action(ApplySupplierFilterFromCombo));
|
||
}
|
||
|
||
private void ApplySupplierFilterFromCombo()
|
||
{
|
||
if (_suppressSupplierFilterEvents)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (comboSupplierFilter.SelectedIndex == _committedSupplierFilterIndex)
|
||
{
|
||
return;
|
||
}
|
||
|
||
_committedSupplierFilterIndex = comboSupplierFilter.SelectedIndex;
|
||
|
||
var selected = comboSupplierFilter.SelectedItem as string;
|
||
if (string.IsNullOrWhiteSpace(selected) || selected == "Все поставщики")
|
||
{
|
||
_selectedSupplierFilter = string.Empty;
|
||
btnClearSupplierFilter.Visible = false;
|
||
}
|
||
else
|
||
{
|
||
_selectedSupplierFilter = selected;
|
||
btnClearSupplierFilter.Visible = true;
|
||
}
|
||
|
||
ApplyPriceListFilters();
|
||
}
|
||
|
||
private void btnClearSupplierFilter_Click(object sender, EventArgs e)
|
||
{
|
||
_suppressSupplierFilterEvents = true;
|
||
comboSupplierFilter.SelectedIndex = 0;
|
||
_suppressSupplierFilterEvents = false;
|
||
|
||
_committedSupplierFilterIndex = comboSupplierFilter.SelectedIndex;
|
||
_selectedSupplierFilter = string.Empty;
|
||
btnClearSupplierFilter.Visible = false;
|
||
ApplyPriceListFilters();
|
||
}
|
||
|
||
private DataTable LoadPriceListTable(string supplierName)
|
||
{
|
||
var tablePrice = new DataTable();
|
||
|
||
var q = "select * from PriceList";
|
||
if (!string.IsNullOrWhiteSpace(supplierName))
|
||
{
|
||
q += " where SupplierName = @supplierName";
|
||
}
|
||
|
||
using (var con = new SQLiteConnection(connectionStringToLocalDB))
|
||
{
|
||
con.Open();
|
||
using (var cmd = new SQLiteCommand(q, con))
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(supplierName))
|
||
{
|
||
cmd.Parameters.AddWithValue("@supplierName", supplierName);
|
||
}
|
||
|
||
using (var da = new SQLiteDataAdapter(cmd))
|
||
{
|
||
da.Fill(tablePrice);
|
||
}
|
||
}
|
||
}
|
||
|
||
return tablePrice;
|
||
}
|
||
|
||
private void ApplyPriceListTable(DataTable tablePrice)
|
||
{
|
||
// Keep existing logic: just rename columns and re-bind.
|
||
tablePrice.Columns[0].ColumnName = "ИД товара";
|
||
tablePrice.Columns[1].ColumnName = "Код товара";
|
||
tablePrice.Columns[2].ColumnName = "ИД поставщика";
|
||
tablePrice.Columns[3].ColumnName = "Наименование";
|
||
tablePrice.Columns[4].ColumnName = "Поставщик";
|
||
tablePrice.Columns[5].ColumnName = "Цена";
|
||
tablePrice.Columns[6].ColumnName = "Остаток";
|
||
tablePrice.Columns[7].ColumnName = "Срок годности";
|
||
tablePrice.Columns[8].ColumnName = "Описание";
|
||
tablePrice.Columns[9].ColumnName = "Заказ";
|
||
tablePrice.Columns[10].ColumnName = "Сумма";
|
||
tablePrice.Columns[12].ColumnName = "ИДПрайсЛистАйтем";
|
||
|
||
if (tablePrice.Columns.Contains("TradeName"))
|
||
{
|
||
tablePrice.Columns["TradeName"].ColumnName = "Торговое название";
|
||
}
|
||
|
||
if (tablePrice.Columns.Contains("Dosage"))
|
||
{
|
||
tablePrice.Columns["Dosage"].ColumnName = "Дозировка";
|
||
}
|
||
|
||
if (tablePrice.Columns.Contains("MarkupPercent"))
|
||
{
|
||
tablePrice.Columns["MarkupPercent"].ColumnName = "Наценка %";
|
||
}
|
||
|
||
EnsureDerivedBrowseColumns(tablePrice);
|
||
_fullPriceTable = tablePrice;
|
||
RebuildBrowseIndex(tablePrice);
|
||
_selectedBaseName = string.Empty;
|
||
_selectedMg = string.Empty;
|
||
ShowBrowseView();
|
||
}
|
||
|
||
private void RebuildBrowseIndex(DataTable tablePrice)
|
||
{
|
||
var names = new SortedSet<string>(StringComparer.OrdinalIgnoreCase);
|
||
var mgMap = new Dictionary<string, SortedSet<string>>(StringComparer.OrdinalIgnoreCase);
|
||
|
||
foreach (DataRow row in tablePrice.Rows)
|
||
{
|
||
var baseName = row["Базовое наименование"]?.ToString() ?? string.Empty;
|
||
if (string.IsNullOrWhiteSpace(baseName))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
names.Add(baseName);
|
||
if (!mgMap.TryGetValue(baseName, out var dosages))
|
||
{
|
||
dosages = new SortedSet<string>(StringComparer.OrdinalIgnoreCase);
|
||
mgMap[baseName] = dosages;
|
||
}
|
||
|
||
dosages.Add(row["МГ"]?.ToString() ?? string.Empty);
|
||
}
|
||
|
||
_uniqueBaseNames = names.ToList();
|
||
_mgByBaseName = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
|
||
foreach (var pair in mgMap)
|
||
{
|
||
var list = new List<string>(pair.Value.Count);
|
||
foreach (var dosage in pair.Value)
|
||
{
|
||
list.Add(string.IsNullOrEmpty(dosage) ? EmptyMgDisplay : dosage);
|
||
}
|
||
|
||
_mgByBaseName[pair.Key] = list;
|
||
}
|
||
}
|
||
|
||
private void EnsureSearchDebounceTimer()
|
||
{
|
||
if (_searchDebounceTimer != null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
_searchDebounceTimer = new Timer { Interval = SearchDebounceMs };
|
||
_searchDebounceTimer.Tick += (_, __) =>
|
||
{
|
||
_searchDebounceTimer.Stop();
|
||
ResetBrowseToNames();
|
||
};
|
||
}
|
||
|
||
private void ScheduleBrowseSearchRefresh(bool immediate = false)
|
||
{
|
||
EnsureSearchDebounceTimer();
|
||
_searchDebounceTimer.Stop();
|
||
if (immediate)
|
||
{
|
||
ResetBrowseToNames();
|
||
return;
|
||
}
|
||
|
||
_searchDebounceTimer.Start();
|
||
}
|
||
|
||
private void HideOptionalColumn(string columnName)
|
||
{
|
||
if (dgvPriceList.Columns.Contains(columnName))
|
||
{
|
||
dgvPriceList.Columns[columnName].Visible = false;
|
||
}
|
||
}
|
||
|
||
private void EnsureDerivedBrowseColumns(DataTable tablePrice)
|
||
{
|
||
if (!tablePrice.Columns.Contains("Базовое наименование"))
|
||
{
|
||
tablePrice.Columns.Add("Базовое наименование", typeof(string));
|
||
}
|
||
|
||
if (!tablePrice.Columns.Contains("МГ"))
|
||
{
|
||
tablePrice.Columns.Add("МГ", typeof(string));
|
||
}
|
||
|
||
foreach (DataRow row in tablePrice.Rows)
|
||
{
|
||
var drugName = row["Наименование"]?.ToString() ?? string.Empty;
|
||
var tradeName = tablePrice.Columns.Contains("Торговое название")
|
||
? row["Торговое название"]?.ToString()
|
||
: null;
|
||
var dosage = tablePrice.Columns.Contains("Дозировка")
|
||
? row["Дозировка"]?.ToString()
|
||
: null;
|
||
|
||
if (string.IsNullOrWhiteSpace(dosage))
|
||
{
|
||
dosage = ExtractDosageFromName(drugName);
|
||
}
|
||
|
||
dosage = (dosage ?? string.Empty).Trim();
|
||
row["МГ"] = dosage;
|
||
row["Базовое наименование"] = BuildBaseName(drugName, tradeName, dosage);
|
||
}
|
||
}
|
||
|
||
private static string ExtractDosageFromName(string drugName)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(drugName))
|
||
{
|
||
return string.Empty;
|
||
}
|
||
|
||
var match = DosageRegex.Match(drugName);
|
||
return match.Success ? match.Value.Trim() : string.Empty;
|
||
}
|
||
|
||
private static string BuildBaseName(string drugName, string tradeName, string dosage)
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(tradeName))
|
||
{
|
||
return tradeName.Trim();
|
||
}
|
||
|
||
var name = drugName ?? string.Empty;
|
||
if (!string.IsNullOrWhiteSpace(dosage))
|
||
{
|
||
var idx = name.IndexOf(dosage, StringComparison.OrdinalIgnoreCase);
|
||
if (idx >= 0)
|
||
{
|
||
name = name.Remove(idx, dosage.Length);
|
||
}
|
||
}
|
||
|
||
name = Regex.Replace(name, @"\s{2,}", " ").Trim(' ', ',', '-', '.', ';');
|
||
return string.IsNullOrWhiteSpace(name) ? (drugName ?? string.Empty).Trim() : name;
|
||
}
|
||
|
||
private void ShowBrowseView()
|
||
{
|
||
if (_fullPriceTable == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
EnsureBrowseSplit();
|
||
_browseMode = PriceBrowseMode.Browse;
|
||
_selectedMg = string.Empty;
|
||
|
||
try
|
||
{
|
||
bsPriceList.RemoveFilter();
|
||
}
|
||
catch
|
||
{
|
||
bsPriceList.Filter = string.Empty;
|
||
}
|
||
|
||
var search = (GoodsFilter ?? string.Empty).Trim();
|
||
IList<string> namesToShow;
|
||
if (string.IsNullOrWhiteSpace(search))
|
||
{
|
||
namesToShow = _uniqueBaseNames;
|
||
}
|
||
else
|
||
{
|
||
var matching = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||
foreach (DataRow row in _fullPriceTable.Rows)
|
||
{
|
||
var baseName = row["Базовое наименование"]?.ToString() ?? string.Empty;
|
||
if (string.IsNullOrWhiteSpace(baseName) || matching.Contains(baseName))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
var drugName = row["Наименование"]?.ToString() ?? string.Empty;
|
||
var mgText = row["МГ"]?.ToString() ?? string.Empty;
|
||
if (baseName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0
|
||
|| drugName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0
|
||
|| mgText.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0)
|
||
{
|
||
matching.Add(baseName);
|
||
}
|
||
}
|
||
|
||
namesToShow = matching
|
||
.OrderBy(n => n, StringComparer.OrdinalIgnoreCase)
|
||
.ToList();
|
||
}
|
||
|
||
var namesTable = new DataTable();
|
||
namesTable.Columns.Add("Наименование", typeof(string));
|
||
namesTable.BeginLoadData();
|
||
foreach (var baseName in namesToShow)
|
||
{
|
||
namesTable.Rows.Add(baseName);
|
||
}
|
||
namesTable.EndLoadData();
|
||
|
||
try
|
||
{
|
||
_suppressBrowseEvents = true;
|
||
dgvBrowseNames.SuspendLayout();
|
||
dgvBrowseNames.DataSource = namesTable;
|
||
ConfigureSingleColumnGrid(dgvBrowseNames, "Наименование");
|
||
ClearMgPanel();
|
||
|
||
if (!string.IsNullOrWhiteSpace(_selectedBaseName))
|
||
{
|
||
SelectBrowseName(_selectedBaseName);
|
||
}
|
||
else
|
||
{
|
||
dgvBrowseNames.ClearSelection();
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
dgvBrowseNames.ResumeLayout();
|
||
_suppressBrowseEvents = false;
|
||
}
|
||
|
||
ShowBrowsePanels(true);
|
||
if (!string.IsNullOrWhiteSpace(_selectedBaseName) && dgvBrowseNames.SelectedRows.Count > 0)
|
||
{
|
||
FillMgPanelForName(_selectedBaseName);
|
||
}
|
||
|
||
ShowMePriceWithMarkupPercentForSelectedGood();
|
||
}
|
||
|
||
private void ClearMgPanel()
|
||
{
|
||
var empty = new DataTable();
|
||
empty.Columns.Add("МГ", typeof(string));
|
||
dgvBrowseMg.DataSource = empty;
|
||
ConfigureSingleColumnGrid(dgvBrowseMg, "МГ");
|
||
dgvBrowseMg.ClearSelection();
|
||
}
|
||
|
||
private void FillMgPanelForName(string baseName)
|
||
{
|
||
var mgTable = new DataTable();
|
||
mgTable.Columns.Add("МГ", typeof(string));
|
||
|
||
if (_mgByBaseName.TryGetValue(baseName, out var dosages))
|
||
{
|
||
foreach (var dosage in dosages)
|
||
{
|
||
mgTable.Rows.Add(dosage);
|
||
}
|
||
}
|
||
|
||
try
|
||
{
|
||
_suppressBrowseEvents = true;
|
||
dgvBrowseMg.DataSource = mgTable;
|
||
ConfigureSingleColumnGrid(dgvBrowseMg, "МГ");
|
||
dgvBrowseMg.ClearSelection();
|
||
}
|
||
finally
|
||
{
|
||
_suppressBrowseEvents = false;
|
||
}
|
||
}
|
||
|
||
private void ConfigureSingleColumnGrid(ModernDataGridView grid, string columnName)
|
||
{
|
||
grid.AutoGenerateColumns = true;
|
||
grid.AllowUserToResizeColumns = true;
|
||
grid.Font = new Font("Segoe UI", 13F, FontStyle.Regular);
|
||
|
||
foreach (DataGridViewColumn column in grid.Columns)
|
||
{
|
||
var match = string.Equals(column.Name, columnName, StringComparison.Ordinal)
|
||
|| string.Equals(column.HeaderText, columnName, StringComparison.Ordinal);
|
||
column.Visible = match;
|
||
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
|
||
column.Resizable = DataGridViewTriState.True;
|
||
column.MinimumWidth = 80;
|
||
}
|
||
}
|
||
|
||
private void SelectBrowseName(string baseName)
|
||
{
|
||
for (var i = 0; i < dgvBrowseNames.Rows.Count; i++)
|
||
{
|
||
var value = dgvBrowseNames.Rows[i].Cells["Наименование"]?.Value?.ToString();
|
||
if (string.Equals(value, baseName, StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
dgvBrowseNames.ClearSelection();
|
||
dgvBrowseNames.Rows[i].Selected = true;
|
||
if (dgvBrowseNames.Columns.Contains("Наименование"))
|
||
{
|
||
dgvBrowseNames.CurrentCell = dgvBrowseNames.Rows[i].Cells["Наименование"];
|
||
}
|
||
|
||
dgvBrowseNames.FirstDisplayedScrollingRowIndex = Math.Max(0, i);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
private void ShowBrowsePanels(bool browseVisible)
|
||
{
|
||
EnsureBrowseSplit();
|
||
|
||
if (browseVisible)
|
||
{
|
||
dgvPriceList.Visible = false;
|
||
splitNameMgBrowse.Visible = true;
|
||
splitNameMgBrowse.BringToFront();
|
||
|
||
var width = Math.Max(200, splitNameMgBrowse.Width);
|
||
var preferred = _browseSplitterDistance > 80
|
||
? _browseSplitterDistance
|
||
: Math.Max(180, width / 2);
|
||
preferred = Math.Min(preferred, Math.Max(120, width - 120));
|
||
try
|
||
{
|
||
splitNameMgBrowse.SplitterDistance = preferred;
|
||
}
|
||
catch
|
||
{
|
||
// splitter not ready yet
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (splitNameMgBrowse.SplitterDistance > 80)
|
||
{
|
||
_browseSplitterDistance = splitNameMgBrowse.SplitterDistance;
|
||
}
|
||
|
||
splitNameMgBrowse.Visible = false;
|
||
dgvPriceList.Visible = true;
|
||
dgvPriceList.BringToFront();
|
||
}
|
||
}
|
||
|
||
private void ShowOffersView(string baseName, string mgDisplay)
|
||
{
|
||
if (_fullPriceTable == null || string.IsNullOrWhiteSpace(baseName))
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (splitNameMgBrowse != null && splitNameMgBrowse.SplitterDistance > 80)
|
||
{
|
||
_browseSplitterDistance = splitNameMgBrowse.SplitterDistance;
|
||
}
|
||
|
||
_selectedBaseName = baseName;
|
||
_selectedMg = string.Equals(mgDisplay, EmptyMgDisplay, StringComparison.Ordinal)
|
||
? string.Empty
|
||
: (mgDisplay ?? string.Empty);
|
||
|
||
_suppressSupplierFilterEvents = true;
|
||
if (comboSupplierFilter.Items.Count > 0)
|
||
{
|
||
comboSupplierFilter.SelectedIndex = 0;
|
||
}
|
||
_suppressSupplierFilterEvents = false;
|
||
_committedSupplierFilterIndex = comboSupplierFilter.SelectedIndex;
|
||
_selectedSupplierFilter = string.Empty;
|
||
btnClearSupplierFilter.Visible = false;
|
||
|
||
BindOffersTable();
|
||
ApplyOffersColumns();
|
||
ShowBrowsePanels(false);
|
||
|
||
var escapedName = _selectedBaseName.Replace("'", "''");
|
||
var escapedMg = _selectedMg.Replace("'", "''");
|
||
try
|
||
{
|
||
bsPriceList.Filter = $"[Базовое наименование] = '{escapedName}' AND [МГ] = '{escapedMg}'";
|
||
}
|
||
catch (EvaluateException ex)
|
||
{
|
||
AppDebugLog.Error("PriceList", "Не удалось применить фильтр наименование+МГ", ex);
|
||
bsPriceList.RemoveFilter();
|
||
}
|
||
|
||
FocusOffersGridForInput();
|
||
}
|
||
|
||
private void FocusOffersGridForInput()
|
||
{
|
||
if (!IsHandleCreated)
|
||
{
|
||
return;
|
||
}
|
||
|
||
BeginInvoke(new Action(() =>
|
||
{
|
||
if (_browseMode != PriceBrowseMode.Offers || !dgvPriceList.Visible)
|
||
{
|
||
return;
|
||
}
|
||
|
||
EnsureOffersRowSelected();
|
||
dgvPriceList.Focus();
|
||
}));
|
||
}
|
||
|
||
private bool EnsureOffersRowSelected()
|
||
{
|
||
if (_browseMode != PriceBrowseMode.Offers || dgvPriceList.Rows.Count == 0)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (dgvPriceList.SelectedRows.Count > 0)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
for (var i = 0; i < dgvPriceList.Rows.Count; i++)
|
||
{
|
||
var row = dgvPriceList.Rows[i];
|
||
if (row.IsNewRow)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
_suppressPriceListSelectionEvents = true;
|
||
try
|
||
{
|
||
row.Selected = true;
|
||
var columnIndex = GetPreferredOffersSelectionColumnIndex();
|
||
if (columnIndex >= 0 && columnIndex < row.Cells.Count)
|
||
{
|
||
dgvPriceList.CurrentCell = row.Cells[columnIndex];
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
_suppressPriceListSelectionEvents = false;
|
||
}
|
||
|
||
ShowMePriceWithMarkupPercentForSelectedGood();
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
private int GetPreferredOffersSelectionColumnIndex()
|
||
{
|
||
if (dgvPriceList.Columns.Contains("Наименование"))
|
||
{
|
||
return dgvPriceList.Columns["Наименование"].Index;
|
||
}
|
||
|
||
return dgvPriceList.Columns.Count > 3 ? 3 : 0;
|
||
}
|
||
|
||
private void BindOffersTable()
|
||
{
|
||
try
|
||
{
|
||
_suppressBrowseEvents = true;
|
||
_suppressPriceListSelectionEvents = true;
|
||
_browseMode = PriceBrowseMode.Offers;
|
||
|
||
try
|
||
{
|
||
bsPriceList.RemoveFilter();
|
||
}
|
||
catch
|
||
{
|
||
bsPriceList.Filter = string.Empty;
|
||
}
|
||
|
||
bsPriceList.DataSource = _fullPriceTable;
|
||
dgvPriceList.DataSource = bsPriceList;
|
||
dgvPriceList.AutoGenerateColumns = true;
|
||
dgvPriceList.Font = new Font("Segoe UI", 13, FontStyle.Regular);
|
||
dgvPriceList.AllowUserToResizeColumns = true;
|
||
if (dgvPriceList.Rows.Count > 0)
|
||
{
|
||
dgvPriceList.ClearSelection();
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
_suppressPriceListSelectionEvents = false;
|
||
_suppressBrowseEvents = false;
|
||
ShowMePriceWithMarkupPercentForSelectedGood();
|
||
}
|
||
}
|
||
|
||
private void ApplyOffersColumns()
|
||
{
|
||
if (dgvPriceList.Columns.Count == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
foreach (DataGridViewColumn column in dgvPriceList.Columns)
|
||
{
|
||
column.Visible = true;
|
||
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
|
||
column.Resizable = DataGridViewTriState.True;
|
||
}
|
||
|
||
if (dgvPriceList.Columns.Count > 0) dgvPriceList.Columns[0].Visible = false;
|
||
if (dgvPriceList.Columns.Count > 1) dgvPriceList.Columns[1].Visible = false;
|
||
if (dgvPriceList.Columns.Count > 2) dgvPriceList.Columns[2].Visible = false;
|
||
if (dgvPriceList.Columns.Count > 7) dgvPriceList.Columns[7].Visible = true;
|
||
if (dgvPriceList.Columns.Count > 8) dgvPriceList.Columns[8].Visible = false;
|
||
if (dgvPriceList.Columns.Count > 11) dgvPriceList.Columns[11].Visible = false;
|
||
if (dgvPriceList.Columns.Count > 12) dgvPriceList.Columns[12].Visible = false;
|
||
|
||
HideOptionalColumn("Торговое название");
|
||
HideOptionalColumn("Дозировка");
|
||
HideOptionalColumn("Наценка %");
|
||
HideOptionalColumn("Базовое наименование");
|
||
HideOptionalColumn("МГ");
|
||
|
||
if (dgvPriceList.Columns.Count > 3) dgvPriceList.Columns[3].Width = 760;
|
||
if (dgvPriceList.Columns.Count > 4) dgvPriceList.Columns[4].Width = 150;
|
||
if (dgvPriceList.Columns.Count > 5) dgvPriceList.Columns[5].Width = 120;
|
||
if (dgvPriceList.Columns.Count > 6) dgvPriceList.Columns[6].Width = 100;
|
||
if (dgvPriceList.Columns.Count > 7) dgvPriceList.Columns[7].Width = 140;
|
||
if (dgvPriceList.Columns.Count > 9) dgvPriceList.Columns[9].Width = 100;
|
||
if (dgvPriceList.Columns.Count > 10) dgvPriceList.Columns[10].Width = 100;
|
||
}
|
||
|
||
private void dgvBrowseNames_SelectionChanged(object sender, EventArgs e)
|
||
{
|
||
if (_suppressBrowseEvents || _browseMode != PriceBrowseMode.Browse)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (dgvBrowseNames.SelectedRows.Count == 0)
|
||
{
|
||
_selectedBaseName = string.Empty;
|
||
ClearMgPanel();
|
||
return;
|
||
}
|
||
|
||
var name = dgvBrowseNames.SelectedRows[0].Cells["Наименование"]?.Value?.ToString() ?? string.Empty;
|
||
_selectedBaseName = name;
|
||
_selectedMg = string.Empty;
|
||
if (string.IsNullOrWhiteSpace(name))
|
||
{
|
||
ClearMgPanel();
|
||
return;
|
||
}
|
||
|
||
FillMgPanelForName(name);
|
||
ShowMePriceWithMarkupPercentForSelectedGood();
|
||
}
|
||
|
||
private void dgvBrowseMg_CellClick(object sender, DataGridViewCellEventArgs e)
|
||
{
|
||
if (_suppressBrowseEvents || e.RowIndex < 0 || e.RowIndex >= dgvBrowseMg.Rows.Count)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (_browseMode != PriceBrowseMode.Browse || string.IsNullOrWhiteSpace(_selectedBaseName))
|
||
{
|
||
return;
|
||
}
|
||
|
||
var mg = dgvBrowseMg.Rows[e.RowIndex].Cells["МГ"]?.Value?.ToString() ?? string.Empty;
|
||
ShowOffersView(_selectedBaseName, mg);
|
||
}
|
||
|
||
private void NavigateBrowseBack()
|
||
{
|
||
if (_browseMode == PriceBrowseMode.Offers)
|
||
{
|
||
// Оставляем выбранное наименование, справа снова покажем его МГ.
|
||
_selectedMg = string.Empty;
|
||
ShowBrowseView();
|
||
}
|
||
}
|
||
|
||
private void ResetBrowseToNames()
|
||
{
|
||
_selectedBaseName = string.Empty;
|
||
_selectedMg = string.Empty;
|
||
ShowBrowseView();
|
||
}
|
||
|
||
private void HandleBackspaceInPriceList(int rowIndex, string idPriceListItem)
|
||
{
|
||
if (_browseMode == PriceBrowseMode.Offers)
|
||
{
|
||
if (rowIndex >= 0
|
||
&& rowIndex < dgvPriceList.Rows.Count
|
||
&& dgvPriceList.Rows[rowIndex].Cells.Count > 9)
|
||
{
|
||
var qty = dgvPriceList.Rows[rowIndex].Cells[9].Value?.ToString() ?? string.Empty;
|
||
if (!string.IsNullOrWhiteSpace(qty))
|
||
{
|
||
if (!string.IsNullOrEmpty(idPriceListItem))
|
||
{
|
||
deleteGood(rowIndex, idPriceListItem);
|
||
}
|
||
else
|
||
{
|
||
dgvPriceList.Rows[rowIndex].Cells[9].Value = string.Empty;
|
||
dgvPriceList.Rows[rowIndex].Cells[10].Value = string.Empty;
|
||
}
|
||
|
||
return;
|
||
}
|
||
}
|
||
|
||
ResetBrowseToNames();
|
||
if (dgvBrowseNames != null && dgvBrowseNames.Visible)
|
||
{
|
||
dgvBrowseNames.Focus();
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
if (GoodsFilter.Length == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
GoodsFilter = GoodsFilter.Substring(0, GoodsFilter.Length - 1);
|
||
txtSearchGoodNameInPriceList.Text = GoodsFilter;
|
||
ScheduleBrowseSearchRefresh(immediate: GoodsFilter.Length == 0);
|
||
|
||
if (GoodsFilter.Length == 0)
|
||
{
|
||
timerForResetSearch.Enabled = false;
|
||
timerForResetSearch.Stop();
|
||
}
|
||
else
|
||
{
|
||
timerForResetSearch.Enabled = true;
|
||
timerForResetSearch.Start();
|
||
}
|
||
}
|
||
|
||
|
||
void loadInfoAboutDefaultMarkup()
|
||
{
|
||
decimal percentageMarkupDefault = 0m;
|
||
var fromConsignee = ConsigneeHelper.GetClientMarkupPercent(_WorkWithConsignee);
|
||
if (fromConsignee.HasValue)
|
||
{
|
||
percentageMarkupDefault = fromConsignee.Value;
|
||
}
|
||
else
|
||
{
|
||
percentageMarkupDefault = Properties.Settings.Default.ClientMarkupPercent;
|
||
if (percentageMarkupDefault <= 0)
|
||
{
|
||
percentageMarkupDefault = Properties.Settings.Default.IntDefaultPercentMarkup;
|
||
}
|
||
|
||
if (percentageMarkupDefault < 0)
|
||
{
|
||
percentageMarkupDefault = MarkupHelper.FallbackMarkupPercent;
|
||
}
|
||
|
||
// Первый запуск для этой аптеки — сразу закрепим текущее значение за аптекой.
|
||
if (!string.IsNullOrWhiteSpace(_WorkWithConsignee))
|
||
{
|
||
try
|
||
{
|
||
ConsigneeHelper.SetClientMarkupPercent(_WorkWithConsignee, percentageMarkupDefault);
|
||
}
|
||
catch
|
||
{
|
||
// колонка может ещё не быть — при следующем старте миграция добавит
|
||
}
|
||
}
|
||
}
|
||
|
||
_percentageAsDefault = percentageMarkupDefault;
|
||
_suppressMarkupPersist = true;
|
||
try
|
||
{
|
||
numericPercent.DecimalPlaces = 2;
|
||
numericPercent.Increment = 0.1m;
|
||
numericPercent.Value = Math.Max(
|
||
numericPercent.Minimum,
|
||
Math.Min(numericPercent.Maximum, percentageMarkupDefault));
|
||
}
|
||
finally
|
||
{
|
||
_suppressMarkupPersist = false;
|
||
}
|
||
}
|
||
|
||
private decimal GetMarkupPercentForRow(DataGridViewRow row)
|
||
{
|
||
// Для превью/спиннера всегда используем процент аптеки, который задал клиент.
|
||
// Серверные значения в колонке «Наценка %» не перетирают ручной ввод.
|
||
return _percentageAsDefault;
|
||
}
|
||
|
||
public void loadSupplierTabs(string SupplierName)
|
||
{
|
||
string tabName;
|
||
|
||
if (SupplierName == string.Empty)
|
||
{
|
||
tabName = "Корзина";
|
||
}
|
||
else
|
||
{
|
||
tabName = SupplierName;
|
||
}
|
||
|
||
TabPage pageSupplier = new TabPage($"{tabName}");
|
||
if (SupplierName == string.Empty)
|
||
{
|
||
pageSupplier.Tag = "cart";
|
||
}
|
||
|
||
UCOrderItems UCOrderItemsBySuppliers = new UCOrderItems(SupplierName);
|
||
UCOrderItemsBySuppliers.ParentForm = this;
|
||
UCOrderItemsBySuppliers.Dock = DockStyle.Fill;
|
||
|
||
pageSupplier.Controls.Add(UCOrderItemsBySuppliers);
|
||
|
||
tabOrderItems.TabPages.Add(pageSupplier);
|
||
tabOrderItems.SelectTab(pageSupplier);
|
||
}
|
||
|
||
public void loadTempOrderItems()
|
||
{
|
||
string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
|
||
|
||
List<String> SuppliersFromOrder = new List<String>();
|
||
|
||
var consigneeSafe = (_WorkWithConsignee ?? string.Empty).Replace("'", "''");
|
||
string qShowMeSuppliersFromOrder = $@"
|
||
select
|
||
[SupplierName]
|
||
from [TempOrderItems]
|
||
where [ConsigneeName] = '{consigneeSafe}'
|
||
group by [SupplierName]
|
||
";
|
||
|
||
tabOrderItems.TabPages.Clear();
|
||
|
||
int tabPagesCount = tabOrderItems.TabCount;
|
||
|
||
loadSupplierTabs(string.Empty);
|
||
|
||
using (SQLiteConnection conSuppliersTempOrderGroup = new SQLiteConnection(connectionStringToLocalDB))
|
||
{
|
||
try
|
||
{
|
||
conSuppliersTempOrderGroup.Open();
|
||
SQLiteCommand cmdShowMeSuppliersFromOrder = new SQLiteCommand(qShowMeSuppliersFromOrder, conSuppliersTempOrderGroup);
|
||
SQLiteDataReader dr = cmdShowMeSuppliersFromOrder.ExecuteReader();
|
||
|
||
while (dr.Read())
|
||
{
|
||
loadSupplierTabs(dr.GetString(0));
|
||
}
|
||
}
|
||
catch(Exception ex)
|
||
{
|
||
ToastNotification.ShowError($"Ошибка при создании вкладок: {ex.Message}");
|
||
}
|
||
finally
|
||
{
|
||
conSuppliersTempOrderGroup.Close();
|
||
}
|
||
}
|
||
dgvPriceList.Focus();
|
||
}
|
||
|
||
|
||
public void loadPriceListV2()
|
||
{
|
||
ApplyPriceListTable(LoadPriceListTable(string.Empty));
|
||
ApplyPriceListFilters();
|
||
}
|
||
|
||
private void loadPriceListV2(string supplierFilter)
|
||
{
|
||
ApplyPriceListTable(LoadPriceListTable(string.Empty));
|
||
_selectedSupplierFilter = supplierFilter ?? string.Empty;
|
||
ApplyPriceListFilters();
|
||
}
|
||
|
||
#region старая загрузка прайсов
|
||
public void loadPriceListV1(string FilterAddon)
|
||
{
|
||
string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
|
||
|
||
string qShowMePriceList = $@"
|
||
select
|
||
pl.[GoodCode] as [Код товара],
|
||
pl.[GoodName] as [Наименование],
|
||
pl.[ProducerName] as [Производитель],
|
||
pl.[SupplierName] as [Поставщик],
|
||
pl.[BestBefore] as [Срок годности],
|
||
pl.[JNVLS] as [ЖНВЛП?],
|
||
pl.[AvaibleCount] as [Доступно],
|
||
pl.[PriceSupplierWithNDS] as [Цена],
|
||
pl.[CountIWantBuy] as [Заказано],
|
||
pl.[SumIWantBuy] as [Сумма],
|
||
pl.[Marked] as [Признак маркировки]
|
||
from [PriceList] pl
|
||
where pl.AvaibleCount > 0
|
||
and pl.ConsigneesCode = (select codeConsignees from Consignees where ConsigneesName = '{_WorkWithConsignee}')
|
||
{FilterAddon}
|
||
order by pl.goodname asc
|
||
";
|
||
|
||
SQLiteConnection conPriceList = new SQLiteConnection(connectionStringToLocalDB);
|
||
try
|
||
{
|
||
conPriceList.Open();
|
||
daPriceList = new SQLiteDataAdapter(qShowMePriceList, conPriceList);
|
||
dsPriceList = new DataSet();
|
||
daPriceList.Fill(dsPriceList, "PriceList");
|
||
|
||
|
||
dgvPriceList.DataSource = dsPriceList.Tables["PriceList"];
|
||
|
||
//dgvPriceList.AutoGenerateColumns = true;
|
||
BindingSource bsPriceList = new BindingSource();
|
||
bsPriceList.DataSource = dsPriceList.Tables["PriceList"];
|
||
|
||
|
||
|
||
dgvPriceList.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing;
|
||
dgvPriceList.RowHeadersVisible = false;
|
||
|
||
dgvPriceList.Columns[0].ReadOnly = true;
|
||
dgvPriceList.Columns[1].ReadOnly = true;
|
||
dgvPriceList.Columns[2].ReadOnly = true;
|
||
dgvPriceList.Columns[3].ReadOnly = true;
|
||
dgvPriceList.Columns[4].ReadOnly = true;
|
||
dgvPriceList.Columns[5].ReadOnly = true;
|
||
dgvPriceList.Columns[6].ReadOnly = true;
|
||
dgvPriceList.Columns[7].ReadOnly = true;
|
||
dgvPriceList.Columns[8].ReadOnly = true;
|
||
dgvPriceList.Columns[9].ReadOnly = false;
|
||
dgvPriceList.Columns[10].ReadOnly = true;
|
||
|
||
dgvPriceList.Columns[9].DefaultCellStyle.Format = "N0";
|
||
|
||
dgvPriceList.DefaultCellStyle.Font = new Font("Segoe UI", 10, FontStyle.Regular);
|
||
|
||
|
||
//dgvPriceList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
|
||
|
||
dgvPriceList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
|
||
|
||
dgvPriceList.Columns["Код товара"].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
|
||
dgvPriceList.Columns["Код товара"].Width = 1;
|
||
|
||
dgvPriceList.Columns["Наименование"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
||
dgvPriceList.Columns["Производитель"].Width = 200;
|
||
dgvPriceList.Columns["Поставщик"].Width = 130;
|
||
dgvPriceList.Columns["Срок годности"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
||
//dgvPriceList.Columns["Доступно"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
||
//dgvPriceList.Columns["Цена"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
||
//dgvPriceList.Columns["Заказано"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
||
//dgvPriceList.Columns["Сумма"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
||
//dgvPriceList.Columns["Признак маркировки"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
||
|
||
dgvPriceList.Columns["ЖНВЛП?"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ToastNotification.ShowError($"Ошибка загрузки прайс-листа: {ex.Message}");
|
||
}
|
||
finally
|
||
{
|
||
conPriceList.Close();
|
||
}
|
||
|
||
}
|
||
#endregion
|
||
|
||
|
||
|
||
void AddItemInOrdersItems(string GoodCode, string GoodName, string SupplierName, string ItemConsigner, string BestBefore, string CountItem, string SumItem, string PriceItem)
|
||
{
|
||
string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
|
||
|
||
using (SQLiteConnection conTempOrder = new SQLiteConnection(connectionStringToLocalDB))
|
||
{
|
||
|
||
|
||
string qInsertDataInTempTableOrderItems = $@"
|
||
insert into [TempOrderItems] values (
|
||
'{GoodCode}',
|
||
'{GoodName}',
|
||
'{SupplierName}',
|
||
'{ItemConsigner}',
|
||
'{CountItem}',
|
||
'{SumItem}',
|
||
'{PriceItem}',
|
||
'{BestBefore}'
|
||
)
|
||
";
|
||
|
||
string qShowMeCountsOfOrderedThatGood = $@"
|
||
select count(GoodCode) from TempOrderItems where
|
||
GoodCode = '{GoodCode}' and
|
||
GoodName = '{GoodName}' and
|
||
SupplierName = '{SupplierName}' and
|
||
ConsigneesName = '{ItemConsigner}' and
|
||
SupplierPrice = '{PriceItem}' and
|
||
BestBefore = '{BestBefore}'
|
||
";
|
||
|
||
string qUpdateOrderedPriceListItems = $@"
|
||
update TempOrderItems
|
||
set OrderedCountItems = '{CountItem}',
|
||
SumOrderedItems = '{SumItem}'
|
||
where
|
||
GoodCode = '{GoodCode}' and
|
||
GoodName = '{GoodName}' and
|
||
SupplierName = '{SupplierName}' and
|
||
ConsigneesName = '{ItemConsigner}' and
|
||
SupplierPrice = '{PriceItem}' and
|
||
BestBefore = '{BestBefore}'
|
||
";
|
||
|
||
try
|
||
{
|
||
conTempOrder.Open();
|
||
int RowCountsOfThatGood = 0;
|
||
SQLiteCommand cmdCheckCountOfOrderedItems = new SQLiteCommand(qShowMeCountsOfOrderedThatGood, conTempOrder);
|
||
RowCountsOfThatGood = Convert.ToInt32(cmdCheckCountOfOrderedItems.ExecuteScalar());
|
||
if (RowCountsOfThatGood > 0)
|
||
{
|
||
SQLiteCommand cmdUpdatePriceListItems = new SQLiteCommand(qUpdateOrderedPriceListItems, conTempOrder);
|
||
cmdUpdatePriceListItems.ExecuteNonQuery();
|
||
}
|
||
else
|
||
{
|
||
SQLiteCommand cmdFillTempOrderItems = new SQLiteCommand(qInsertDataInTempTableOrderItems, conTempOrder);
|
||
cmdFillTempOrderItems.ExecuteNonQuery();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ToastNotification.ShowError($"Ошибка заполнения корзины: {ex.Message}");
|
||
}
|
||
finally
|
||
{
|
||
conTempOrder.Close();
|
||
}
|
||
loadTempOrderItems();
|
||
}
|
||
}
|
||
|
||
private void btnSendOrder_Click(object sender, EventArgs e)
|
||
{
|
||
string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
|
||
|
||
string OrderNumber = $"EP-{DateTime.Now.Millisecond.ToString()}{DateTime.Now.Date.ToString("mmdd")}";
|
||
string OrderDate = DateTime.Now.ToString("yyyy-MM-dd");//DateTime.Now.ToShortDateString();
|
||
|
||
|
||
|
||
using (SQLiteConnection conCreateOrder = new SQLiteConnection(connectionStringToLocalDB))
|
||
{
|
||
try
|
||
{
|
||
conCreateOrder.Open();
|
||
|
||
string CountOrderedItems;
|
||
string SumOrderedItems;
|
||
|
||
string qShowMeCountOrderedItems = "select count(GoodCode) from TempOrderItems where OrderedCountItems > 0";
|
||
string qShowMeSumOrderedItems = "select sum(SumOrderedItems) from TempOrderItems where OrderedCountItems > 0";
|
||
|
||
SQLiteCommand cmdShowMeCountOfOrderedItems = new SQLiteCommand(qShowMeCountOrderedItems, conCreateOrder);
|
||
SQLiteCommand cmdShowMeSumOfOrderedItems = new SQLiteCommand(qShowMeSumOrderedItems, conCreateOrder);
|
||
|
||
qShowMeCountOrderedItems = Convert.ToString(cmdShowMeCountOfOrderedItems.ExecuteScalar());
|
||
qShowMeSumOrderedItems = Convert.ToString(cmdShowMeSumOfOrderedItems.ExecuteScalar());
|
||
|
||
string qCreateOrder = $@"
|
||
insert into [Orders] (OrderNumber, OrderDate, OrderedItemsCount, OrderSum, OrderState)
|
||
values
|
||
(
|
||
'{OrderNumber}',
|
||
select strftime('%Y-%m-%d','{OrderDate}'),
|
||
'{qShowMeCountOrderedItems}',
|
||
'{qShowMeSumOrderedItems}',
|
||
'SAVE'
|
||
)
|
||
";
|
||
|
||
|
||
|
||
SQLiteCommand cmdCreateOrder = new SQLiteCommand(qCreateOrder, conCreateOrder);
|
||
cmdCreateOrder.ExecuteNonQuery();
|
||
|
||
foreach (DataGridViewRow row in dgvOrder.Rows)
|
||
{
|
||
string qCreateOrderItems = $@"
|
||
insert into OrderItems (idOrder, GoodCode, GoodName, codeSuppliers, codeConsignees, OrderedCountItems, SupplierPrice, SumOrderedItems, BestBefore, ProducerName, ProducerPrice)
|
||
values
|
||
(
|
||
(select idOrder from Orders where OrderNumber = '{OrderNumber}'),
|
||
'{row.Cells[0].Value.ToString()}',
|
||
'{row.Cells[1].Value.ToString()}',
|
||
(select codeSuppliers from Suppliers where SuppliersName = '{row.Cells[2].Value.ToString()}'),
|
||
(select codeConsignees from Consignees where ConsigneesName = '{row.Cells[3].Value.ToString()}'),
|
||
'{row.Cells[5].Value.ToString()}',
|
||
'{row.Cells[4].Value.ToString()}',
|
||
'{row.Cells[6].Value.ToString()}',
|
||
'{row.Cells[7].Value.ToString()}',
|
||
'{row.Cells[8].Value.ToString()}',
|
||
'{row.Cells[9].Value.ToString()}'
|
||
)
|
||
";
|
||
|
||
SQLiteCommand cmdCreateOrderItems = new SQLiteCommand(qCreateOrderItems, conCreateOrder);
|
||
cmdCreateOrderItems.ExecuteNonQuery();
|
||
}
|
||
EraseOrder();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ToastNotification.ShowError($"Ошибка формирования заказа: {ex.Message}");
|
||
}
|
||
finally
|
||
{
|
||
conCreateOrder.Close();
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
#region TODO: что-то с заказом, потом доделать под актуальную версию
|
||
// void IWantBuyThisGood()
|
||
// {
|
||
// int selectedRowIndex = dgvPriceList.CurrentRow.Index;
|
||
// //int IWantBuyGood = Convert.ToInt32(dgvPriceList.Rows[selectedRowIndex].Cells[10].Value.ToString());
|
||
// int IWantBuyGood = Convert.ToInt32(dgvPriceList.Rows[selectedRowIndex].Cells[8].Value.ToString());
|
||
|
||
// if (IWantBuyGood <= 0)
|
||
// {
|
||
// ErasePriceListOrderItem();
|
||
// }
|
||
// else if (IWantBuyGood > 0)
|
||
// {
|
||
// double SuppliersPrice = Convert.ToDouble(dgvPriceList.Rows[selectedRowIndex].Cells[7].Value.ToString());
|
||
// double SumGoodsIWantBuy = SuppliersPrice * IWantBuyGood;
|
||
// string sumBuy = SumGoodsIWantBuy.ToString();
|
||
// dgvPriceList.Rows[selectedRowIndex].Cells[9].Value = sumBuy.ToString();
|
||
// //dgvPriceList.Rows[selectedRowIndex].Cells[11].Value = "1";//SumGoodsIWantBuy.ToString();
|
||
// //dgvPriceList.CurrentRow.Cells[11].Value = SumGoodsIWantBuy.ToString();
|
||
|
||
// string qUpdateCountAndSumInPriceListTable = $@"
|
||
//update PriceList set
|
||
//[CountIWantBuy] = '{IWantBuyGood.ToString()}',
|
||
//[SumIWantBuy] = '{sumBuy.ToString()}'
|
||
//where
|
||
//[GoodCode] = '{dgvPriceList.Rows[selectedRowIndex].Cells[0].Value.ToString()}'
|
||
//and [GoodName] = '{dgvPriceList.Rows[selectedRowIndex].Cells[1].Value.ToString()}'
|
||
//and [ProducerName] = '{dgvPriceList.Rows[selectedRowIndex].Cells[2].Value.ToString()}'
|
||
//and [SupplierName] = '{dgvPriceList.Rows[selectedRowIndex].Cells[3].Value.ToString()}'
|
||
//and [ConsigneesCode] = (select codeConsignees from Consignees where ConsigneesName = '{_WorkWithConsignee}')
|
||
//";
|
||
// string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
|
||
|
||
// //dgvPriceList.Rows[selectedRowIndex].DefaultCellStyle.Font = new Font("Segoe UI", 10, FontStyle.Bold);
|
||
|
||
// using (SQLiteConnection conUpdateBuyingGoods = new SQLiteConnection(connectionStringToLocalDB))
|
||
// {
|
||
// try
|
||
// {
|
||
// conUpdateBuyingGoods.Open();
|
||
// SQLiteCommand cmdUpdateBuyingGoods = new SQLiteCommand(qUpdateCountAndSumInPriceListTable, conUpdateBuyingGoods);
|
||
// cmdUpdateBuyingGoods.ExecuteNonQuery();
|
||
// }
|
||
// catch (Exception ex)
|
||
// {
|
||
// MessageBox.Show($"Возникла ошибка при обновлении данных о закупке товаров. Текст ошибки:\n{ex.ToString()}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
// }
|
||
// finally
|
||
// {
|
||
// conUpdateBuyingGoods.Close();
|
||
// }
|
||
// }
|
||
|
||
|
||
|
||
// string ItemConsigner = txtConsignee.Text;
|
||
// //if (ItemConsigner == "" | ItemConsigner == "Грузополучатель")
|
||
// //{
|
||
// // MessageBox.Show("Пожалуйста, укажите грузополучателя.", "Предупреждение", MessageBoxButtons.OK, MessageBoxIcon.Hand);
|
||
// //}
|
||
// //else
|
||
// //{
|
||
// string GoodCode = dgvPriceList.Rows[selectedRowIndex].Cells[0].Value.ToString();
|
||
// string GoodName = dgvPriceList.Rows[selectedRowIndex].Cells[1].Value.ToString();
|
||
// string SupplierName = dgvPriceList.Rows[selectedRowIndex].Cells[3].Value.ToString();
|
||
// string BestBefore = dgvPriceList.Rows[selectedRowIndex].Cells[4].Value.ToString();
|
||
// string CountItem = dgvPriceList.Rows[selectedRowIndex].Cells[8].Value.ToString();
|
||
// string SumItem = dgvPriceList.Rows[selectedRowIndex].Cells[9].Value.ToString();
|
||
// string PriceItem = dgvPriceList.Rows[selectedRowIndex].Cells[7].Value.ToString();
|
||
|
||
// AddItemInOrdersItems(GoodCode, GoodName, SupplierName, ItemConsigner, BestBefore, CountItem, SumItem, PriceItem);
|
||
// //}
|
||
|
||
// }
|
||
|
||
// }
|
||
#endregion
|
||
|
||
private void dgvPriceList_CellEndEdit(object sender, DataGridViewCellEventArgs e)
|
||
{
|
||
//IWantBuyThisGood();
|
||
|
||
//int RowIndex = dgvPriceList.SelectedRows[0].Index;
|
||
//if (dgvPriceList.Rows[RowIndex].Cells[4].Value != string.Empty)
|
||
//{
|
||
|
||
// Font customFont = new Font("Segoe UI", 13, FontStyle.Bold);
|
||
|
||
// dgvPriceList.Rows[RowIndex].DefaultCellStyle.Font = customFont;
|
||
//}
|
||
|
||
}
|
||
|
||
|
||
private void btnClearSearchInPriceList_Click(object sender, EventArgs e)
|
||
{
|
||
txtSearchGoodNameInPriceList.Text = string.Empty;
|
||
GoodsFilter = string.Empty;
|
||
ScheduleBrowseSearchRefresh(immediate: true);
|
||
//loadPriceList(string.Empty);
|
||
}
|
||
|
||
|
||
private void btnEraseOrder_Click(object sender, EventArgs e)
|
||
{
|
||
//DialogResult drAreYouSeriesAboutEraseOrder = MessageBox.Show("Вы уверены, что хотите очистить корзину?", "Сообщение", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||
|
||
//if (drAreYouSeriesAboutEraseOrder == DialogResult.Yes)
|
||
//{
|
||
// EraseOrder();
|
||
//}
|
||
|
||
}
|
||
|
||
void EraseOrder()
|
||
{
|
||
string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
|
||
|
||
string qUpdatePriceListBuyingItems = $@"
|
||
update PriceList set
|
||
[CountIWantBuy] = null,
|
||
[SumIWantBuy] = null
|
||
from (select GoodCode, GoodName, SupplierName, SupplierPrice from TempOrderItems) as tempOrder
|
||
where
|
||
tempOrder.GoodCode = PriceList.GoodCode
|
||
and tempOrder.GoodName = PriceList.GoodName
|
||
";
|
||
string qEraseOrder = "delete from TempOrderItems";
|
||
|
||
using (SQLiteConnection conEraseOrder = new SQLiteConnection(connectionStringToLocalDB))
|
||
{
|
||
try
|
||
{
|
||
conEraseOrder.Open();
|
||
SQLiteCommand cmdUpdateBuyingItems = new SQLiteCommand(qUpdatePriceListBuyingItems, conEraseOrder);
|
||
SQLiteCommand cmdEraseOrder = new SQLiteCommand(qEraseOrder, conEraseOrder);
|
||
cmdUpdateBuyingItems.ExecuteNonQuery();
|
||
cmdEraseOrder.ExecuteNonQuery();
|
||
loadTempOrderItems();
|
||
//loadPriceList(string.Empty);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ToastNotification.ShowError($"Ошибка очистки корзины: {ex.Message}");
|
||
}
|
||
finally
|
||
{
|
||
conEraseOrder.Close();
|
||
}
|
||
}
|
||
}
|
||
|
||
string SumIWantBuy = string.Empty;
|
||
int lastSelectedRowIndex;
|
||
string GoodsFilter = string.Empty;
|
||
string stringIWantBuy = string.Empty;
|
||
|
||
private static bool IsGoodsSearchKey(char keyChar, bool allowDigitsAndSeparators = true)
|
||
{
|
||
if ((keyChar >= 'A' && keyChar <= 'Z')
|
||
|| (keyChar >= 'a' && keyChar <= 'z')
|
||
|| (keyChar >= 'А' && keyChar <= 'Я')
|
||
|| (keyChar >= 'а' && keyChar <= 'я')
|
||
|| keyChar == (char)Keys.Subtract)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
if (!allowDigitsAndSeparators)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return (keyChar >= '0' && keyChar <= '9')
|
||
|| keyChar == ' '
|
||
|| keyChar == '.'
|
||
|| keyChar == ',';
|
||
}
|
||
|
||
private void dgvPriceList_KeyPress(object sender, KeyPressEventArgs e)
|
||
{
|
||
if (e.KeyChar == (Char)Keys.Escape)
|
||
{
|
||
if (_browseMode != PriceBrowseMode.Browse)
|
||
{
|
||
NavigateBrowseBack();
|
||
}
|
||
else
|
||
{
|
||
txtSearchGoodNameInPriceList.Text = string.Empty;
|
||
GoodsFilter = string.Empty;
|
||
ScheduleBrowseSearchRefresh(immediate: true);
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
int RowIndex = -1;
|
||
string idPriceListItem = string.Empty;
|
||
|
||
if (_browseMode == PriceBrowseMode.Offers)
|
||
{
|
||
if (IsOrderQuantityStartKey(e.KeyChar))
|
||
{
|
||
EnsureOffersRowSelected();
|
||
if (!dgvPriceList.Focused)
|
||
{
|
||
dgvPriceList.Focus();
|
||
}
|
||
}
|
||
|
||
if (dgvPriceList.SelectedRows.Count > 0)
|
||
{
|
||
RowIndex = dgvPriceList.SelectedRows[0].Index;
|
||
if (RowIndex >= 0
|
||
&& RowIndex < dgvPriceList.Rows.Count
|
||
&& dgvPriceList.Rows[RowIndex].Cells.Count > 11)
|
||
{
|
||
idPriceListItem = dgvPriceList.Rows[RowIndex].Cells[11].Value?.ToString() ?? string.Empty;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (e.KeyChar == (Char)Keys.Back)
|
||
{
|
||
HandleBackspaceInPriceList(RowIndex, idPriceListItem);
|
||
return;
|
||
}
|
||
|
||
if (_browseMode != PriceBrowseMode.Offers)
|
||
{
|
||
if (IsGoodsSearchKey(e.KeyChar))
|
||
{
|
||
dgvPriceList.ClearSelection();
|
||
GoodsFilter += e.KeyChar.ToString();
|
||
txtSearchGoodNameInPriceList.Text = GoodsFilter;
|
||
ScheduleBrowseSearchRefresh();
|
||
timerForResetSearch.Enabled = true;
|
||
timerForResetSearch.Start();
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
if (IsGoodsSearchKey(e.KeyChar, allowDigitsAndSeparators: false))
|
||
{
|
||
dgvPriceList.ClearSelection();
|
||
GoodsFilter += e.KeyChar.ToString();
|
||
txtSearchGoodNameInPriceList.Text = GoodsFilter;
|
||
ScheduleBrowseSearchRefresh();
|
||
timerForResetSearch.Enabled = true;
|
||
timerForResetSearch.Start();
|
||
return;
|
||
}
|
||
else if ((e.KeyChar >= (Char)Keys.D1 && e.KeyChar <= (Char)Keys.D9) ||
|
||
(e.KeyChar >= (Char)Keys.NumPad1 && e.KeyChar <= (Char)Keys.NumPad9) || (RowIndex >= 0 && e.KeyChar == (Char)Keys.D0 && dgvPriceList.Rows[RowIndex].Cells[10].Value.ToString().Length > 1) || (RowIndex >= 0 && e.KeyChar == (Char)Keys.NumPad0 && dgvPriceList.Rows[RowIndex].Cells[10].Value.ToString().Length > 1))
|
||
{
|
||
if (RowIndex < 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (!TryReadInt32(dgvPriceList.Rows[RowIndex].Cells[6].Value, out var quantityForSale))
|
||
{
|
||
return;
|
||
}
|
||
|
||
stringIWantBuy = dgvPriceList.Rows[RowIndex].Cells[9].Value.ToString() + e.KeyChar.ToString();
|
||
if (!TryReadInt32(stringIWantBuy, out var iWantBuy))
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (iWantBuy <= quantityForSale)
|
||
{
|
||
dgvPriceList.Rows[RowIndex].Cells[9].Value = iWantBuy.ToString();
|
||
|
||
if (!TryReadDecimal(dgvPriceList.Rows[RowIndex].Cells[5].Value, out var priceForOne))
|
||
{
|
||
return;
|
||
}
|
||
|
||
dgvPriceList.Rows[RowIndex].Cells[10].Value = (iWantBuy * priceForOne).ToString();
|
||
}
|
||
else if (iWantBuy > quantityForSale)
|
||
{
|
||
DialogResult drIWantBuyAll = UiDialogs.ConfirmYesNoCancel($"Для заказа доступно только {quantityForSale.ToString()}. Заказать доступное количество?", "Заказ", FindForm());
|
||
|
||
if (drIWantBuyAll == DialogResult.Yes)
|
||
{
|
||
dgvPriceList.Rows[RowIndex].Cells[9].Value = quantityForSale.ToString();
|
||
|
||
if (!TryReadDecimal(dgvPriceList.Rows[RowIndex].Cells[5].Value, out var priceForOne))
|
||
{
|
||
return;
|
||
}
|
||
|
||
dgvPriceList.Rows[RowIndex].Cells[10].Value = (quantityForSale * priceForOne).ToString();
|
||
}
|
||
}
|
||
}
|
||
else if (e.KeyChar == (Char)Keys.Delete)
|
||
{
|
||
if (RowIndex < 0 || string.IsNullOrEmpty(idPriceListItem)) return;
|
||
deleteGood(RowIndex, idPriceListItem);
|
||
}
|
||
else if (RowIndex >= 0 && dgvPriceList.Rows[RowIndex].Cells[9].Value?.ToString() == string.Empty && e.KeyChar == (Char)Keys.D0)
|
||
{
|
||
|
||
}
|
||
else if (e.KeyChar == (Char)Keys.Down || e.KeyChar == (Char)Keys.Up)
|
||
{
|
||
if (RowIndex < 0 || string.IsNullOrEmpty(idPriceListItem)) return;
|
||
timerForResetSearch.Enabled = false;
|
||
timerForResetSearch.Stop();
|
||
|
||
foreach (DataGridViewRow row in dgvPriceList.Rows)
|
||
{
|
||
if (TryReadInt32(row.Cells[9].Value, out var orderedCount) && orderedCount == 0)
|
||
{
|
||
int rowIndex = row.Index;
|
||
deleteGood(rowIndex, idPriceListItem);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (RowIndex < 0 || RowIndex >= dgvPriceList.Rows.Count) return;
|
||
|
||
string summaZakaza = dgvPriceList.Rows[RowIndex].Cells[10].Value?.ToString() ?? string.Empty;
|
||
|
||
|
||
if (summaZakaza.Trim().Length > 0)
|
||
{
|
||
string Zakaz = dgvPriceList.Rows[RowIndex].Cells[9].Value.ToString();
|
||
|
||
creatingTempOrder(idPriceListItem, Zakaz, summaZakaza);
|
||
|
||
}
|
||
|
||
#region старое добавление товара в PLI
|
||
//tabOrderItems.
|
||
|
||
//dgvPriceList.EndEdit();
|
||
//bsPriceList.EndEdit();
|
||
|
||
//daPriceListMain.Update(dsPriceList);
|
||
|
||
////dsPriceList.Tables.Clear();
|
||
//dsPriceList.WriteXml("PriceList.xml", XmlWriteMode.DiffGram);
|
||
//dsPriceList.Tables.Add(tablePriceList.Copy());
|
||
|
||
//dsPriceList.Tables["PriceList"].AcceptChanges();
|
||
|
||
//tablePriceList = (dgvPriceList.DataSource as DataTable);
|
||
|
||
|
||
|
||
//daPriceListMain.Update();
|
||
//bsPriceList.DataSource = (dgvPriceList.DataSource as DataTable);
|
||
//daPriceListMain.Update(dsPriceList);
|
||
#endregion
|
||
}
|
||
|
||
void creatingTempOrder(string idPriceListItem, string zakaz, string summaZakaza)
|
||
{
|
||
var consigneeSafe = (_WorkWithConsignee ?? string.Empty).Replace("'", "''");
|
||
string qUpdatePriceList = $"update [PriceList] set [Zakaz] = '{zakaz}', [SummaZakaza] = '{summaZakaza}' where [id_PriceList_Item] = '{idPriceListItem}'";
|
||
string qDeleteFromTempOrder = $"delete from [TempOrderItems] where [id_PriceList_Item] = '{idPriceListItem}' and [ConsigneeName] = '{consigneeSafe}'";
|
||
string qCreateNewTempOrder = $"insert into TempOrderItems([ConsigneeName],[guid_es],[es_code],[supplier_id],[DrugName],[SupplierName],[Price],[Quantity],[ExpiryPeriod],[Description],[Zakaz],[SummaZakaza],[id_PriceList_Item],[supplier_price_id]) select '{consigneeSafe}',[guid_es],[es_code],[supplier_id],[DrugName],[SupplierName],[Price],[Quantity],[ExpiryPeriod],[Description],[Zakaz],[SummaZakaza],[id_PriceList_Item],[supplier_price_id] from [PriceList] where [id_PriceList_Item] = '{idPriceListItem}'";
|
||
|
||
using(SQLiteConnection sqlCon = new SQLiteConnection(connectionStringToLocalDB))
|
||
{
|
||
try
|
||
{
|
||
sqlCon.Open();
|
||
|
||
SQLiteCommand cmdUpdatePriceList = new SQLiteCommand(qUpdatePriceList, sqlCon);
|
||
SQLiteCommand cmdDeleteFromTempOrder = new SQLiteCommand(qDeleteFromTempOrder, sqlCon);
|
||
SQLiteCommand cmdCreateNewTempOrder = new SQLiteCommand(qCreateNewTempOrder, sqlCon);
|
||
|
||
cmdUpdatePriceList.ExecuteNonQuery();
|
||
cmdDeleteFromTempOrder.ExecuteNonQuery();
|
||
cmdCreateNewTempOrder.ExecuteNonQuery();
|
||
|
||
loadTempOrderItems();
|
||
|
||
}
|
||
catch(Exception ex)
|
||
{
|
||
//MessageBox.Show($"Возникла ошибка при обновлении данных прайс-листов. Текст ошибки:\n{ex.ToString()}", "Обработка прайс-листов", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
finally
|
||
{
|
||
sqlCon.Close();
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void deleteGood(int index, string IdPriceListItem)
|
||
{
|
||
var consigneeSafe = (_WorkWithConsignee ?? string.Empty).Replace("'", "''");
|
||
dgvPriceList.Rows[index].Cells[9].Value = string.Empty;
|
||
dgvPriceList.Rows[index].Cells[10].Value = string.Empty;
|
||
|
||
string IdPLI = IdPriceListItem;
|
||
|
||
string qClearPriceList = $"update [PriceList] set [Zakaz] = null, [SummaZakaza] = null where id_PriceList_Item = '{IdPLI}'";
|
||
string qDeleteFromTempOrder = $"delete from [TempOrderItems] where [id_PriceList_Item] = '{IdPLI}' and [ConsigneeName] = '{consigneeSafe}'";
|
||
|
||
using(SQLiteConnection sqlCon = new SQLiteConnection(connectionStringToLocalDB))
|
||
{
|
||
try
|
||
{
|
||
sqlCon.Open();
|
||
|
||
SQLiteCommand cmdClearPriceListItem = new SQLiteCommand(qClearPriceList, sqlCon);
|
||
SQLiteCommand cmdDeleteFromTempOrder = new SQLiteCommand(qDeleteFromTempOrder, sqlCon);
|
||
|
||
cmdClearPriceListItem.ExecuteNonQuery();
|
||
cmdDeleteFromTempOrder.ExecuteNonQuery();
|
||
|
||
loadTempOrderItems();
|
||
}
|
||
catch(Exception ex)
|
||
{
|
||
//MessageBox.Show($"При обновлении данных прайс-листа возникла ошибка. Текст ошибки:\n{ex.ToString()}", "Обработка прайс-листов", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
finally
|
||
{
|
||
sqlCon.Close();
|
||
}
|
||
}
|
||
}
|
||
|
||
#region TODO: старый метод, не работает
|
||
//private void dgvPriceList_KeyPress(object sender, KeyPressEventArgs e)
|
||
//{
|
||
|
||
// if ((e.KeyChar >= 'A' && e.KeyChar <= 'Z') || (e.KeyChar >= 'a' && e.KeyChar <= 'z') || (e.KeyChar >= 'А' && e.KeyChar <= 'Я') || (e.KeyChar >= 'а' && e.KeyChar <= 'я') || (e.KeyChar == (Char)Keys.Subtract))
|
||
// {
|
||
// if (e.KeyChar == (Char)Keys.Enter || e.KeyChar == (Char)Keys.Tab)
|
||
// {
|
||
|
||
// }
|
||
// else
|
||
// {
|
||
// timerForResetSearch.Enabled = false;
|
||
// timerForResetSearch.Stop();
|
||
// txtSearchGoodNameInPriceList.Text += e.KeyChar.ToString();
|
||
|
||
|
||
|
||
// string GoodNameFilter = txtSearchGoodNameInPriceList.Text;
|
||
// //GoodNameFilter = GoodNameFilter.Replace(" ", "%");
|
||
// //GoodNameFilter = GoodNameFilter.Replace(" ", "%");
|
||
// //string filterAddon = $" and pl.[GoodName] LIKE '%{GoodNameFilter.ToLower()}%'";
|
||
// //MessageBox.Show(GoodNameFilter);
|
||
// (dgvPriceList.DataSource as DataTable).DefaultView.RowFilter = $"[Наименование] like '%{GoodNameFilter.ToLower()}%'";
|
||
|
||
// timerForResetSearch.Enabled = true;
|
||
// timerForResetSearch.Start();
|
||
|
||
// if (dgvPriceList.RowCount < 1)
|
||
// {
|
||
// MessageBox.Show($"Подходящий товар не найден.", "Поиск", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
// txtSearchGoodNameInPriceList.Text = string.Empty;
|
||
// //loadPriceList(string.Empty);
|
||
|
||
// (dgvPriceList.DataSource as DataTable).DefaultView.RowFilter = string.Empty;
|
||
// timerForResetSearch.Stop();
|
||
// }
|
||
|
||
|
||
// }
|
||
|
||
// }
|
||
// else if ((e.KeyChar >= (Char)Keys.D0 && e.KeyChar <= (Char)Keys.D9) ||
|
||
// (e.KeyChar >= (Char)Keys.NumPad0 && e.KeyChar <= (Char)Keys.NumPad9))
|
||
// {
|
||
// txtSearchGoodNameInPriceList.Text = string.Empty;
|
||
// int selectedRowIndex = dgvPriceList.SelectedCells[0].RowIndex;
|
||
// if (selectedRowIndex != lastSelectedRowIndex)
|
||
// {
|
||
// SumIWantBuy = string.Empty;
|
||
// }
|
||
// SumIWantBuy += e.KeyChar.ToString();
|
||
// if (SumIWantBuy == "0")
|
||
// {
|
||
// ErasePriceListOrderItem();
|
||
// }
|
||
// else
|
||
// {
|
||
// int AvaibleCountGood = Convert.ToInt32(dgvPriceList.Rows[selectedRowIndex].Cells[6].Value.ToString());
|
||
|
||
|
||
// if (AvaibleCountGood < Convert.ToInt32(SumIWantBuy))
|
||
// {
|
||
// MessageBox.Show("Заказано максимальное количество товара", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
// SumIWantBuy = AvaibleCountGood.ToString();
|
||
// }
|
||
// dgvPriceList.Rows[selectedRowIndex].Cells[8].Value = SumIWantBuy;
|
||
// //IWantBuyThisGood();
|
||
// lastSelectedRowIndex = selectedRowIndex;
|
||
// }
|
||
// }
|
||
// else if (e.KeyChar == (Char)Keys.Back || e.KeyChar == (Char)Keys.Escape)
|
||
// {
|
||
// txtSearchGoodNameInPriceList.Text = string.Empty;
|
||
// (dgvPriceList.DataSource as DataTable).DefaultView.RowFilter = string.Empty;
|
||
// //loadPriceList(string.Empty);
|
||
// }
|
||
// else if (e.KeyChar == (Char)Keys.Delete)
|
||
// {
|
||
// ErasePriceListOrderItem();
|
||
// }
|
||
// else if (e.KeyChar != (Char)Keys.Enter)
|
||
// {
|
||
// txtSearchGoodNameInPriceList.Text += e.KeyChar.ToString();
|
||
|
||
// string GoodNameFilter = txtSearchGoodNameInPriceList.Text;
|
||
// //GoodNameFilter = GoodNameFilter.Replace(" ", "%");
|
||
// //string filterAddon = $" and pl.[GoodName] LIKE '%{GoodNameFilter.ToLower()}%'";
|
||
|
||
// (dgvPriceList.DataSource as DataTable).DefaultView.RowFilter = $"[Наименование] like '%{GoodNameFilter.ToLower()}%'";
|
||
|
||
// if (dgvPriceList.RowCount < 1)
|
||
// {
|
||
// MessageBox.Show($"Подходящий товар не найден.", "Поиск", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
// txtSearchGoodNameInPriceList.Text = string.Empty;
|
||
// (dgvPriceList.DataSource as DataTable).DefaultView.RowFilter = string.Empty;
|
||
// //loadPriceList(string.Empty);
|
||
// }
|
||
// }
|
||
//}
|
||
#endregion
|
||
|
||
void ErasePriceListOrderItem()
|
||
{
|
||
int rowIndex = dgvPriceList.SelectedCells[0].RowIndex;
|
||
|
||
string goodCode = dgvPriceList.Rows[rowIndex].Cells[0].Value.ToString();
|
||
string goodName = dgvPriceList.Rows[rowIndex].Cells[1].Value.ToString();
|
||
string SupplierName = dgvPriceList.Rows[rowIndex].Cells[3].Value.ToString();
|
||
string PriceGood = dgvPriceList.Rows[rowIndex].Cells[7].Value.ToString();
|
||
string SumOrder = dgvPriceList.Rows[rowIndex].Cells[9].Value.ToString();
|
||
|
||
string qUpdatePriceList = $@"update PriceList set
|
||
[CountIWantBuy] = null,
|
||
[SumIWantBuy] = null
|
||
where [GoodCode] = '{goodCode}'
|
||
and [GoodName] = '{goodName}'
|
||
and [SupplierName] = '{SupplierName}'";
|
||
|
||
|
||
string qDeleteFromTempOrder = $@"delete from TempOrderItems
|
||
where [GoodCode] = '{goodCode}'
|
||
and [GoodName] = '{goodName}'
|
||
and [SupplierName] = '{SupplierName}'
|
||
and [SupplierPrice] = '{PriceGood}'
|
||
and SumOrderedItems = '{SumOrder}'";
|
||
|
||
string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
|
||
using (SQLiteConnection conEraceOrderOfSelectedGood = new SQLiteConnection(connectionStringToLocalDB))
|
||
{
|
||
try
|
||
{
|
||
conEraceOrderOfSelectedGood.Open();
|
||
|
||
SQLiteCommand cmdEraseOrderedGoodFromPriceList = new SQLiteCommand(qUpdatePriceList, conEraceOrderOfSelectedGood);
|
||
SQLiteCommand cmdDeleteOrderedGoodFromTempOrder = new SQLiteCommand(qDeleteFromTempOrder, conEraceOrderOfSelectedGood);
|
||
|
||
cmdEraseOrderedGoodFromPriceList.ExecuteNonQuery();
|
||
cmdDeleteOrderedGoodFromTempOrder.ExecuteNonQuery();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ToastNotification.ShowError($"Ошибка удаления из заказа: {ex.Message}");
|
||
}
|
||
finally
|
||
{
|
||
conEraceOrderOfSelectedGood.Close();
|
||
//loadPriceList(string.Empty);
|
||
loadTempOrderItems();
|
||
}
|
||
}
|
||
}
|
||
|
||
void ShowMePriceWithMarkupPercentForSelectedGood()
|
||
{
|
||
try
|
||
{
|
||
if (_browseMode != PriceBrowseMode.Offers)
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(_selectedBaseName))
|
||
{
|
||
lblSelectedGoodName.Text = _selectedBaseName;
|
||
}
|
||
else if (dgvBrowseNames?.SelectedRows.Count > 0 && dgvBrowseNames.Columns.Contains("Наименование"))
|
||
{
|
||
lblSelectedGoodName.Text = dgvBrowseNames.SelectedRows[0].Cells["Наименование"]?.Value?.ToString() ?? string.Empty;
|
||
}
|
||
else
|
||
{
|
||
lblSelectedGoodName.Text = string.Empty;
|
||
}
|
||
|
||
lblPriceForGood.Text = string.Empty;
|
||
return;
|
||
}
|
||
|
||
var currentRow = dgvPriceList.CurrentRow;
|
||
if (currentRow == null || currentRow.IsNewRow)
|
||
{
|
||
lblSelectedGoodName.Text = string.Empty;
|
||
lblPriceForGood.Text = string.Empty;
|
||
return;
|
||
}
|
||
|
||
var nameCell = currentRow.Cells[3].Value;
|
||
lblSelectedGoodName.Text = nameCell == null || nameCell == DBNull.Value
|
||
? string.Empty
|
||
: nameCell.ToString();
|
||
|
||
if (!TryReadDouble(currentRow.Cells[5].Value, out var priceForGood))
|
||
{
|
||
lblPriceForGood.Text = string.Empty;
|
||
return;
|
||
}
|
||
|
||
var markupPercentage = GetMarkupPercentForRow(currentRow);
|
||
_suppressMarkupPersist = true;
|
||
try
|
||
{
|
||
numericPercent.Value = Math.Max(
|
||
numericPercent.Minimum,
|
||
Math.Min(numericPercent.Maximum, markupPercentage));
|
||
}
|
||
finally
|
||
{
|
||
_suppressMarkupPersist = false;
|
||
}
|
||
|
||
lblPriceForGood.Text = $"= {priceForGood:0.##} руб";
|
||
}
|
||
catch
|
||
{
|
||
lblSelectedGoodName.Text = string.Empty;
|
||
lblPriceForGood.Text = string.Empty;
|
||
}
|
||
}
|
||
|
||
private static bool TryReadDouble(object value, out double result)
|
||
{
|
||
return TryReadNumber(value, out result);
|
||
}
|
||
|
||
private static bool TryReadDecimal(object value, out decimal result)
|
||
{
|
||
return TryReadNumber(value, out result);
|
||
}
|
||
|
||
private static bool TryReadInt32(object value, out int result)
|
||
{
|
||
return TryReadNumber(value, out result);
|
||
}
|
||
|
||
private static bool TryReadNumber<T>(object value, out T result) where T : struct
|
||
{
|
||
result = default;
|
||
|
||
if (value == null || value == DBNull.Value)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (value is T typedValue)
|
||
{
|
||
result = typedValue;
|
||
return true;
|
||
}
|
||
|
||
if (value is decimal decimalValue && typeof(T) == typeof(double))
|
||
{
|
||
result = (T)(object)(double)decimalValue;
|
||
return true;
|
||
}
|
||
|
||
if (value is double doubleValue && typeof(T) == typeof(decimal))
|
||
{
|
||
result = (T)(object)(decimal)doubleValue;
|
||
return true;
|
||
}
|
||
|
||
if (value is float floatValue && typeof(T) == typeof(double))
|
||
{
|
||
result = (T)(object)(double)floatValue;
|
||
return true;
|
||
}
|
||
|
||
if (value is float floatValueDecimal && typeof(T) == typeof(decimal))
|
||
{
|
||
result = (T)(object)(decimal)floatValueDecimal;
|
||
return true;
|
||
}
|
||
|
||
var text = NormalizeNumberText(value.ToString());
|
||
if (string.IsNullOrEmpty(text))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (typeof(T) == typeof(double))
|
||
{
|
||
if (double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out var invariantDouble))
|
||
{
|
||
result = (T)(object)invariantDouble;
|
||
return true;
|
||
}
|
||
|
||
if (double.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out var currentDouble))
|
||
{
|
||
result = (T)(object)currentDouble;
|
||
return true;
|
||
}
|
||
|
||
if (double.TryParse(text.Replace(',', '.'), NumberStyles.Number, CultureInfo.InvariantCulture, out var normalizedDouble))
|
||
{
|
||
result = (T)(object)normalizedDouble;
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
if (typeof(T) == typeof(decimal))
|
||
{
|
||
if (decimal.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out var invariantDecimal))
|
||
{
|
||
result = (T)(object)invariantDecimal;
|
||
return true;
|
||
}
|
||
|
||
if (decimal.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out var currentDecimal))
|
||
{
|
||
result = (T)(object)currentDecimal;
|
||
return true;
|
||
}
|
||
|
||
if (decimal.TryParse(text.Replace(',', '.'), NumberStyles.Number, CultureInfo.InvariantCulture, out var normalizedDecimal))
|
||
{
|
||
result = (T)(object)normalizedDecimal;
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
if (typeof(T) == typeof(int))
|
||
{
|
||
if (int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out var invariantInt))
|
||
{
|
||
result = (T)(object)invariantInt;
|
||
return true;
|
||
}
|
||
|
||
if (int.TryParse(text, NumberStyles.Integer, CultureInfo.CurrentCulture, out var currentInt))
|
||
{
|
||
result = (T)(object)currentInt;
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
private static string NormalizeNumberText(string text)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(text))
|
||
{
|
||
return string.Empty;
|
||
}
|
||
|
||
text = text.Trim().Replace('\u00A0', ' ').Replace(" ", string.Empty).Replace(',', '.');
|
||
var builder = new StringBuilder();
|
||
var started = false;
|
||
var hasDecimalSeparator = false;
|
||
|
||
foreach (var ch in text)
|
||
{
|
||
if (char.IsDigit(ch))
|
||
{
|
||
builder.Append(ch);
|
||
started = true;
|
||
continue;
|
||
}
|
||
|
||
if (ch == '.' && started && !hasDecimalSeparator)
|
||
{
|
||
builder.Append(ch);
|
||
hasDecimalSeparator = true;
|
||
continue;
|
||
}
|
||
|
||
if (ch == '-' && !started)
|
||
{
|
||
builder.Append(ch);
|
||
continue;
|
||
}
|
||
|
||
if (started)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
return builder.ToString();
|
||
}
|
||
|
||
private static bool IsOrderQuantityStartKey(char keyChar)
|
||
{
|
||
return (keyChar >= (char)Keys.D1 && keyChar <= (char)Keys.D9)
|
||
|| (keyChar >= (char)Keys.NumPad1 && keyChar <= (char)Keys.NumPad9);
|
||
}
|
||
|
||
private void dgvPriceList_SelectionChanged(object sender, EventArgs e)
|
||
{
|
||
if (_suppressPriceListSelectionEvents)
|
||
{
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
SumIWantBuy = string.Empty;
|
||
|
||
if (timerForResetSearch.Enabled == true)
|
||
{
|
||
timerForResetSearch.Enabled = false;
|
||
timerForResetSearch.Stop();
|
||
}
|
||
|
||
ShowMePriceWithMarkupPercentForSelectedGood();
|
||
}
|
||
catch
|
||
{
|
||
lblSelectedGoodName.Text = string.Empty;
|
||
lblPriceForGood.Text = string.Empty;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
private void btnImport_Click(object sender, EventArgs e)
|
||
{
|
||
#region импорт из FTP
|
||
string fileName = "0027379.dbf";
|
||
string filePath = @"ftp:\\lboefc91:Oop3OoF4@lbo.protek.ru\session\Rostov_na_Donu\TestFTPFile\";
|
||
string connectionToDbf = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};Extended Properties=dBASE IV;User ID=Admin;Password=;";
|
||
|
||
using (OleDbConnection oleCon = new OleDbConnection(connectionToDbf))
|
||
{
|
||
var sql = $"select '{DateTime.Now.ToShortDateString()}' as [DatePriceList], '1' as [ConsigneesCode], '2' as [SupplierCode], CODE, PRODUCT, PRODUCER, 'Поставщик 2' as [SupplierName], EXP, VTIMPORT, REGCOST, QUANTITY, COST, COUNTRY, NDS, PRODCOST, '0' as [Marked] from {fileName}";
|
||
OleDbCommand cmd = new OleDbCommand(sql, oleCon);
|
||
oleCon.Open();
|
||
OleDbDataAdapter daDbfReader = new OleDbDataAdapter(cmd);
|
||
DataTable tablePriceFromDbf = new DataTable();
|
||
daDbfReader.Fill(tablePriceFromDbf);
|
||
|
||
|
||
string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
|
||
using (SQLiteConnection conFillPriceListByNewData = new SQLiteConnection(connectionStringToLocalDB))
|
||
{
|
||
try
|
||
{
|
||
conFillPriceListByNewData.Open();
|
||
|
||
foreach (DataRow dr in tablePriceFromDbf.Rows)
|
||
{
|
||
string dbfPriceListDate = dr["DatePriceList"].ToString();
|
||
string dbfConsigneesCode = dr["ConsigneesCode"].ToString();
|
||
string dbfCode = dr["CODE"].ToString();
|
||
string dbfGood = dr["PRODUCT"].ToString().ToLower();
|
||
string dbfProducer = dr["PRODUCER"].ToString();
|
||
string dbfSupplierCode = dr["SupplierCode"].ToString();
|
||
string dbfBestBefore = Convert.ToDateTime(dr["EXP"]).ToShortDateString();
|
||
string dbfJNVLS = dr["VTIMPORT"].ToString();
|
||
string dbfPriceReestr = dr["REGCOST"].ToString();
|
||
string dbfQuantity = dr["QUANTITY"].ToString();
|
||
string dbfPriceSupplierWithNds = dr["COST"].ToString();
|
||
string dbfCountry = dr["COUNTRY"].ToString();
|
||
string dbfNDS = dr["NDS"].ToString();
|
||
string dbfPriceProducer = dr["PRODCOST"].ToString();
|
||
string dbfMarked = dr["Marked"].ToString();
|
||
|
||
dbfGood = dbfGood.Replace("'", "");
|
||
dbfProducer = dbfProducer.Replace("'", "");
|
||
//dbfSupplierName = dbfSupplierName.Replace("'", "");
|
||
dbfCountry = dbfCountry.Replace("'", "");
|
||
|
||
string qShowMeLastDateOfPriceList = $"select PriceListDate from PriceListFromSuppliers where ConsigneesCode = '{dbfConsigneesCode}' and CodeSuppliers = '{dbfSupplierCode}'";
|
||
SQLiteCommand cmdShowMeLastPriceListDate = new SQLiteCommand(qShowMeLastDateOfPriceList, conFillPriceListByNewData);
|
||
|
||
DateTime dateLastPriceListDate = Convert.ToDateTime(cmdShowMeLastPriceListDate.ExecuteScalar().ToString());
|
||
MessageBox.Show($"{dbfPriceListDate} \n{dateLastPriceListDate}");
|
||
|
||
if (Convert.ToDateTime(dbfPriceListDate) > dateLastPriceListDate)
|
||
{
|
||
|
||
}
|
||
|
||
string qInsertDataInLocalDB = $@"insert into PriceList (PriceListDate, GoodCode, GoodName, ProducerName, SupplierName, BestBefore, JNVLS, PriceReestr, AvaibleCount, PriceSupplierWithNDS, NDS , Marked)
|
||
values ('{dbfPriceListDate}','{dbfCode}','{dbfGood}','{dbfProducer}', '3','{dbfBestBefore}','{dbfJNVLS}','{dbfPriceReestr}', '{dbfQuantity}', '{dbfPriceSupplierWithNds}', '{dbfCountry}', '{dbfNDS}', '{dbfPriceProducer}', '{dbfMarked}')
|
||
";
|
||
MessageBox.Show(qInsertDataInLocalDB);
|
||
|
||
SQLiteCommand cmdInsertDataInPriceList = new SQLiteCommand(qInsertDataInLocalDB, conFillPriceListByNewData);
|
||
cmdInsertDataInPriceList.ExecuteNonQuery();
|
||
}
|
||
}
|
||
catch { }
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
#region старыйИмпорт из локального файла
|
||
//string fileName = "0027379.dbf";
|
||
//string filePath = @"C:\!ElectroPharmacy\ElectoPharmacyOrder\";
|
||
//string connectionToDbf = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};Extended Properties=dBASE IV;User ID=Admin;Password=;";
|
||
|
||
//using (OleDbConnection oleCon = new OleDbConnection(connectionToDbf))
|
||
//{
|
||
// var sql = $"select '{DateTime.Now.ToShortDateString()}' as [DatePriceList], '1' as [ConsigneesCode], '2' as [SupplierCode], CODE, PRODUCT, PRODUCER, 'Поставщик 2' as [SupplierName], EXP, VTIMPORT, REGCOST, QUANTITY, COST, COUNTRY, NDS, PRODCOST, '0' as [Marked] from {fileName}";
|
||
// OleDbCommand cmd = new OleDbCommand(sql, oleCon);
|
||
// oleCon.Open();
|
||
// OleDbDataAdapter daDbfReader = new OleDbDataAdapter(cmd);
|
||
// DataTable tablePriceFromDbf = new DataTable();
|
||
// daDbfReader.Fill(tablePriceFromDbf);
|
||
|
||
|
||
// string connectionStringToLocalDB = AppConfig.SqliteConnectionString;
|
||
// using (SQLiteConnection conFillPriceListByNewData = new SQLiteConnection(connectionStringToLocalDB))
|
||
// {
|
||
// try
|
||
// {
|
||
// conFillPriceListByNewData.Open();
|
||
|
||
// foreach (DataRow dr in tablePriceFromDbf.Rows)
|
||
// {
|
||
// string dbfPriceListDate = dr["DatePriceList"].ToString();
|
||
// string dbfConsigneesCode = dr["ConsigneesCode"].ToString();
|
||
// string dbfCode = dr["CODE"].ToString();
|
||
// string dbfGood = dr["PRODUCT"].ToString().ToLower();
|
||
// string dbfProducer = dr["PRODUCER"].ToString();
|
||
// string dbfSupplierCode = dr["SupplierCode"].ToString();
|
||
// string dbfBestBefore = Convert.ToDateTime(dr["EXP"]).ToShortDateString();
|
||
// string dbfJNVLS = dr["VTIMPORT"].ToString();
|
||
// string dbfPriceReestr = dr["REGCOST"].ToString();
|
||
// string dbfQuantity = dr["QUANTITY"].ToString();
|
||
// string dbfPriceSupplierWithNds = dr["COST"].ToString();
|
||
// string dbfCountry = dr["COUNTRY"].ToString();
|
||
// string dbfNDS = dr["NDS"].ToString();
|
||
// string dbfPriceProducer = dr["PRODCOST"].ToString();
|
||
// string dbfMarked = dr["Marked"].ToString();
|
||
|
||
// dbfGood = dbfGood.Replace("'", "");
|
||
// dbfProducer = dbfProducer.Replace("'", "");
|
||
// //dbfSupplierName = dbfSupplierName.Replace("'", "");
|
||
// dbfCountry = dbfCountry.Replace("'", "");
|
||
|
||
// string qShowMeLastDateOfPriceList = $"select PriceListDate from PriceListFromSuppliers where ConsigneesCode = '{dbfConsigneesCode}' and CodeSuppliers = '{dbfSupplierCode}'";
|
||
// SQLiteCommand cmdShowMeLastPriceListDate = new SQLiteCommand(qShowMeLastDateOfPriceList, conFillPriceListByNewData);
|
||
|
||
// DateTime dateLastPriceListDate = Convert.ToDateTime(cmdShowMeLastPriceListDate.ExecuteScalar().ToString());
|
||
// MessageBox.Show($"{dbfPriceListDate} \n{dateLastPriceListDate}");
|
||
|
||
// if (Convert.ToDateTime(dbfPriceListDate) > dateLastPriceListDate)
|
||
// {
|
||
|
||
// }
|
||
|
||
// string qInsertDataInLocalDB = $@"insert into PriceList (PriceListDate, GoodCode, GoodName, ProducerName, SupplierName, BestBefore, JNVLS, PriceReestr, AvaibleCount, PriceSupplierWithNDS, NDS , Marked)
|
||
// values ('{dbfPriceListDate}','{dbfCode}','{dbfGood}','{dbfProducer}', '{dbfSupplierCode}','{dbfBestBefore}','{dbfJNVLS}','{dbfPriceReestr}', '{dbfQuantity}', '{dbfPriceSupplierWithNds}', '{dbfCountry}', '{dbfNDS}', '{dbfPriceProducer}', '{dbfMarked}')
|
||
// ";
|
||
// //MessageBox.Show(qInsertDataInLocalDB);
|
||
|
||
// SQLiteCommand cmdInsertDataInPriceList = new SQLiteCommand(qInsertDataInLocalDB, conFillPriceListByNewData);
|
||
// cmdInsertDataInPriceList.ExecuteNonQuery();
|
||
// }
|
||
// }
|
||
// catch(Exception ex)
|
||
// {
|
||
// MessageBox.Show(ex.ToString());
|
||
// }
|
||
// finally
|
||
// {
|
||
// conFillPriceListByNewData.Close();
|
||
// loadPriceList(string.Empty);
|
||
// }
|
||
// }
|
||
//}
|
||
#endregion
|
||
}
|
||
|
||
private void dgvPriceList_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
|
||
{
|
||
if (e.RowIndex == this.dgvPriceList.RowCount - 1) return;
|
||
|
||
}
|
||
|
||
private void txtSearchGoodNameInPriceList_Enter(object sender, EventArgs e)
|
||
{
|
||
dgvPriceList.Focus();
|
||
}
|
||
|
||
private void numericPercent_ValueChanged(object sender, EventArgs e)
|
||
{
|
||
if (!_suppressMarkupPersist)
|
||
{
|
||
PersistClientMarkupPercent();
|
||
}
|
||
|
||
if (numericPercent.Value != _percentageAsDefault)
|
||
{
|
||
checkUsePercentageAsDefault.Checked = false;
|
||
}
|
||
|
||
ShowMePriceWithMarkupPercentForSelectedGood();
|
||
}
|
||
|
||
private void PersistClientMarkupPercent()
|
||
{
|
||
var value = numericPercent.Value;
|
||
_percentageAsDefault = value;
|
||
|
||
if (!string.IsNullOrWhiteSpace(_WorkWithConsignee))
|
||
{
|
||
try
|
||
{
|
||
ConsigneeHelper.SetClientMarkupPercent(_WorkWithConsignee, value);
|
||
}
|
||
catch
|
||
{
|
||
// ignore transient DB errors; value stays in UI
|
||
}
|
||
}
|
||
|
||
// Глобальный fallback на случай новой аптеки без своего значения.
|
||
Properties.Settings.Default.ClientMarkupPercent = value;
|
||
Properties.Settings.Default.IntDefaultPercentMarkup =
|
||
Convert.ToInt32(Math.Round(value, MidpointRounding.AwayFromZero));
|
||
Properties.Settings.Default.Save();
|
||
}
|
||
|
||
private void UCPriceList_Paint(object sender, PaintEventArgs e)
|
||
{
|
||
if (comboSupplierFilter.DroppedDown)
|
||
{
|
||
return;
|
||
}
|
||
|
||
dgvPriceList.Focus();
|
||
}
|
||
|
||
private void btnImport_MouseEnter(object sender, EventArgs e)
|
||
{
|
||
//btnImport.Focus();
|
||
}
|
||
|
||
private void btnImport_MouseLeave(object sender, EventArgs e)
|
||
{
|
||
//dgvPriceList.Focus()
|
||
}
|
||
|
||
private void checkUsePercentageAsDefault_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
if (checkUsePercentageAsDefault.Checked)
|
||
{
|
||
PersistClientMarkupPercent();
|
||
}
|
||
}
|
||
|
||
private void timerForResetSearch_Tick(object sender, EventArgs e)
|
||
{
|
||
txtSearchGoodNameInPriceList.Text = string.Empty;
|
||
GoodsFilter = string.Empty;
|
||
ScheduleBrowseSearchRefresh(immediate: true);
|
||
timerForResetSearch.Enabled = false;
|
||
timerForResetSearch.Stop();
|
||
}
|
||
|
||
private void btnMoreInfoAboutGood_Click(object sender, EventArgs e)
|
||
{
|
||
if (dgvPriceList.CurrentRow == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
var goodName = dgvPriceList.CurrentRow.Cells["Наименование"]?.Value?.ToString()
|
||
?? dgvPriceList.CurrentRow.Cells[2]?.Value?.ToString()
|
||
?? string.Empty;
|
||
var description = dgvPriceList.CurrentRow.Cells["Описание"]?.Value?.ToString()
|
||
?? dgvPriceList.CurrentRow.Cells[8]?.Value?.ToString()
|
||
?? string.Empty;
|
||
|
||
var aboutGood = new HelpForms.HF_AboutGood
|
||
{
|
||
goodName = goodName,
|
||
goodDescription = description
|
||
};
|
||
UiThemeHelper.ApplyToControlTree(aboutGood);
|
||
aboutGood.ShowDialog(FindForm());
|
||
}
|
||
|
||
|
||
|
||
|
||
//private void dgvPriceList_Paint(object sender, PaintEventArgs e)
|
||
//{
|
||
// //foreach (DataGridViewRow row in dgvPriceList.Rows)
|
||
// //{
|
||
|
||
// // if (row.Cells[8].Value.ToString() != "")
|
||
// // {
|
||
|
||
// // row.DefaultCellStyle.Font = new Font("Segoe UI", 10, FontStyle.Bold);
|
||
// // }
|
||
// //}
|
||
|
||
// //dgvPriceList.Focus();
|
||
//}
|
||
}
|
||
}
|
||
|
||
|