FormProductEdit.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. using qdr.app.studiou.orders2printpack.Extensions;
  2. using qdr.app.studiou.orders2printpack.ProductStorage;
  3. using qdr.app.studiou.orders2printpack.Properties;
  4. using Quadarax.Foundation.Core.IO;
  5. using Quadarax.Foundation.Core.Value;
  6. using Quadarax.Foundation.Core.Value.Generators;
  7. using System.ComponentModel;
  8. using System.Data;
  9. namespace qdr.app.studiou.orders2printpack
  10. {
  11. public partial class FormProductEdit : Form
  12. {
  13. #region *** Enumerations ***
  14. public enum DetailType
  15. {
  16. Product,
  17. Variant,
  18. Category
  19. }
  20. #endregion
  21. #region *** Private Fields ***
  22. private ProductStorage.ProductStorage _storage = new ProductStorage.ProductStorage();
  23. private DetailType _detailType = DetailType.Product;
  24. private ProductDto? _currentDetailProduct;
  25. private VariantDto? _currentDetailVariant;
  26. private CategoryDto? _currentDetailCategory;
  27. private TinyHash _hashGenerator = new TinyHash(10);
  28. private ProductDto _productClipboard = new ProductDto();
  29. private VariantDto _variantClipboard = new VariantDto();
  30. private CategoryDto _categoryClipboard = new CategoryDto();
  31. #endregion
  32. #region *** Constructor ***
  33. public FormProductEdit()
  34. {
  35. InitializeComponent();
  36. _storage.AppendVariantsFromString(AppSettings.Default.PredefinedVariants);
  37. _storage.AppendCategoriesFromString(AppSettings.Default.PredefinedCategories);
  38. tsslblOutput.Text = "Soubor nezadán";
  39. RefreshViews();
  40. RefreshTools();
  41. }
  42. #endregion
  43. #region *** Form Handlers ***
  44. protected override void OnClosing(CancelEventArgs e)
  45. {
  46. AppSettings.Default.PredefinedVariants = _storage.GetVariantsAsString();
  47. AppSettings.Default.PredefinedCategories = _storage.GetCategoriesAsString();
  48. AppSettings.Default.Save();
  49. base.OnClosing(e);
  50. }
  51. #endregion
  52. #region *** Toolbar Handlers ***
  53. private void tbbutSave_Click(object sender, EventArgs e)
  54. {
  55. if (tsslblOutput.Text == "Soubor nezadán")
  56. {
  57. if (dlgSaveFile.ShowDialog() == DialogResult.OK)
  58. tsslblOutput.Text = dlgSaveFile.FileName;
  59. else
  60. return;
  61. }
  62. SaveProductFile(tsslblOutput.Text);
  63. MessageBox.Show($"Data ({_storage.Products.Count()} položek) byla uložena do souboru '{tsslblOutput.Text}'", "Uloženo", MessageBoxButtons.OK, MessageBoxIcon.Information);
  64. }
  65. private void tbbutNew_Click(object sender, EventArgs e)
  66. {
  67. _storage = new ProductStorage.ProductStorage();
  68. _storage.AppendVariantsFromString(AppSettings.Default.PredefinedVariants);
  69. _storage.AppendCategoriesFromString(AppSettings.Default.PredefinedCategories);
  70. _currentDetailProduct = null;
  71. if (dlgSaveFile.ShowDialog() == DialogResult.OK)
  72. SaveProductFile(dlgSaveFile.FileName);
  73. ClearDetail();
  74. RefreshViews();
  75. RefreshTools();
  76. }
  77. private void tbbutOpen_Click(object sender, EventArgs e)
  78. {
  79. if (dlgOpenFile.ShowDialog() == DialogResult.OK)
  80. OpenProductFile(dlgOpenFile.FileName);
  81. }
  82. private void tbbutProduct_Click(object sender, EventArgs e)
  83. {
  84. tbbutProduct.Checked = !tbbutProduct.Checked;
  85. RefreshProductList();
  86. }
  87. private void tbbutVariant_Click(object sender, EventArgs e)
  88. {
  89. tbbutVariant.Checked = !tbbutVariant.Checked;
  90. RefreshProductList();
  91. }
  92. private void tbbutProdNew_Click(object sender, EventArgs e)
  93. {
  94. AddNewProduct();
  95. RefreshTools();
  96. }
  97. private void tbbutProdVarNew_Click(object sender, EventArgs e)
  98. {
  99. AddNewProductVariant();
  100. RefreshTools();
  101. }
  102. private void tbbutDetSave_Click(object sender, EventArgs e)
  103. {
  104. switch (_detailType)
  105. {
  106. case DetailType.Product:
  107. SaveDetail(_currentDetailProduct);
  108. RefreshProductList();
  109. break;
  110. case DetailType.Variant:
  111. SaveDetail(_currentDetailVariant);
  112. RefreshVariantList();
  113. RefreshProductList();
  114. break;
  115. case DetailType.Category:
  116. SaveDetail(_currentDetailCategory);
  117. RefreshCategoryList();
  118. break;
  119. }
  120. }
  121. private void tbbutProdDelete_Click(object sender, EventArgs e)
  122. {
  123. var selected = GetSelectedProduct();
  124. if (selected == null)
  125. return;
  126. if (!ConfirmMessage($"Opravdu chcete smazat {selected.Length} vybraných produktů?"))
  127. return;
  128. _storage.RemoveProduct(selected.Select(x => x.GetIdentifier()).ToArray());
  129. RefreshProductList();
  130. RefreshTools();
  131. }
  132. private void tbbutProdClone_Click(object sender, EventArgs e)
  133. {
  134. var selected = GetSelectedProduct()?.FirstOrDefault();
  135. if (selected == null)
  136. return;
  137. CloneProduct(selected);
  138. RefreshTools();
  139. }
  140. private void tbbutDetCopy_Click(object sender, EventArgs e)
  141. {
  142. switch (_detailType)
  143. {
  144. case DetailType.Product:
  145. if (_currentDetailProduct == null)
  146. return;
  147. _currentDetailProduct.CopyTo(_productClipboard);
  148. break;
  149. case DetailType.Variant:
  150. if (_currentDetailVariant == null)
  151. return;
  152. _currentDetailVariant.CopyTo(_variantClipboard);
  153. break;
  154. case DetailType.Category:
  155. if (_currentDetailCategory == null)
  156. return;
  157. _currentDetailCategory.CopyTo(_categoryClipboard);
  158. break;
  159. }
  160. }
  161. private void tbbutDetPaste_Click(object sender, EventArgs e)
  162. {
  163. switch (_detailType)
  164. {
  165. case DetailType.Product:
  166. if (_currentDetailProduct == null)
  167. return;
  168. _productClipboard.Id = _currentDetailProduct.Id;
  169. ShowDetail(_productClipboard);
  170. break;
  171. case DetailType.Variant:
  172. if (_currentDetailVariant == null)
  173. return;
  174. ShowDetail(_variantClipboard);
  175. break;
  176. case DetailType.Category:
  177. if (_currentDetailCategory == null)
  178. return;
  179. ShowDetail(_categoryClipboard);
  180. break;
  181. }
  182. }
  183. private void tbbutVarNew_Click(object sender, EventArgs e)
  184. {
  185. AddNewVariant();
  186. }
  187. private void tbbutVarDelete_Click(object sender, EventArgs e)
  188. {
  189. var selected = GetSelectedVariants();
  190. if (selected == null)
  191. return;
  192. if (!ConfirmMessage($"Opravdu chcete smazat {selected.Length} vybraných variant?"))
  193. return;
  194. _storage.RemoveVariants(selected.Select(x => x.GetIdentifier()).ToArray());
  195. RefreshVariantList();
  196. }
  197. private void tbbutVarApply_Click(object sender, EventArgs e)
  198. {
  199. ApplyProductVariant();
  200. RefreshProductList();
  201. }
  202. private void tbbutCatNew_Click(object sender, EventArgs e)
  203. {
  204. AddNewCategory();
  205. }
  206. private void tbbutCatDelete_Click(object sender, EventArgs e)
  207. {
  208. var selected = GetSelectedCategories();
  209. if (selected == null)
  210. return;
  211. if (!ConfirmMessage($"Opravdu chcete smazat {selected.Length} vybraných kategorií?"))
  212. return;
  213. _storage.RemoveCategories(selected.Select(x => x.GetIdentifier()).ToArray());
  214. RefreshCategoryList();
  215. }
  216. private void tbbutCatApply_Click(object sender, EventArgs e)
  217. {
  218. }
  219. private void tbbutImport_Click(object sender, EventArgs e)
  220. {
  221. var dlg = new dlgImport();
  222. if (dlg.ShowDialog() == DialogResult.OK)
  223. {
  224. ImportProducts(dlg.ImportDir, dlg.UrlPrefix, dlg.ShortDescription, dlg.Description, dlg.UploadDate);
  225. }
  226. RefreshViews();
  227. RefreshTools();
  228. }
  229. #endregion
  230. #region *** Refreshes ***
  231. private void RefreshTools()
  232. {
  233. tsslblProducts.Text = $"Produkty: {_storage.Products.Count(x => !x.IsVariant)}";
  234. tsslblVariants.Text = $"Varianty: {_storage.Products.Count(x => x.IsVariant)}";
  235. }
  236. private void RefreshViews()
  237. {
  238. RefreshProductList();
  239. RefreshCategoryList();
  240. RefreshVariantList();
  241. }
  242. private void RefreshProductList()
  243. {
  244. BlockErrorHandled(() =>
  245. {
  246. lvProducts.SaveSelection();
  247. lvProducts.BindData(_storage.GetProductsView(tbbutProduct.Checked, tbbutVariant.Checked), itemCustomProcessCallback: (lvItem, data) =>
  248. {
  249. if (!data.IsValid)
  250. lvItem.BackColor = Color.IndianRed;
  251. });
  252. lvProducts.RestoreSelection();
  253. });
  254. }
  255. private void RefreshCategoryList()
  256. {
  257. BlockErrorHandled(() =>
  258. {
  259. lvCategories.SaveSelection();
  260. lvCategories.BindData(_storage.Categories);
  261. lvCategories.RestoreSelection();
  262. });
  263. }
  264. private void RefreshVariantList()
  265. {
  266. BlockErrorHandled(() =>
  267. {
  268. lvVariants.SaveSelection();
  269. lvVariants.BindData(_storage.Variants);
  270. lvVariants.RestoreSelection();
  271. });
  272. }
  273. #endregion
  274. #region *** ListView Handlers ***
  275. private void lvProducts_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
  276. {
  277. if (e.Item != null)
  278. {
  279. var product = _storage.GetProductByIdentifier(e.Item.Tag?.ToString());
  280. ShowDetail(product);
  281. _currentDetailProduct = product;
  282. }
  283. }
  284. private void lvVariants_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
  285. {
  286. if (e.Item != null)
  287. {
  288. var variant = _storage.GetVariantByIdentifier(e.Item.Tag?.ToString());
  289. ShowDetail(variant);
  290. _currentDetailVariant = variant;
  291. }
  292. }
  293. private void lvCategories_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
  294. {
  295. if (e.Item != null)
  296. {
  297. var category = _storage.GetCategoryByIdentifier(e.Item.Tag?.ToString());
  298. ShowDetail(category);
  299. _currentDetailCategory = category;
  300. }
  301. }
  302. #endregion
  303. #region *** Operations ***
  304. private void OpenProductFile(string fileName)
  305. {
  306. BlockErrorHandled(() =>
  307. {
  308. tsslblOutput.Text = fileName;
  309. if (!File.Exists(fileName))
  310. return;
  311. _storage.Load(fileName, ",");
  312. RefreshTools();
  313. RefreshViews();
  314. });
  315. }
  316. private void SaveProductFile(string? fileName)
  317. {
  318. BlockErrorHandled(() =>
  319. {
  320. if (fileName == null)
  321. return;
  322. tsslblOutput.Text = fileName;
  323. _storage.Save(fileName, ",");
  324. RefreshTools();
  325. });
  326. }
  327. private void ClearDetail()
  328. {
  329. BlockErrorHandled(() =>
  330. {
  331. tbdetId.Text = string.Empty;
  332. tbdetName.Text = string.Empty;
  333. tbdetSku.Text = string.Empty;
  334. tbdetShortDescription.Text = string.Empty;
  335. tbdetDescription.Text = string.Empty;
  336. cbdetCategories.BeginUpdate();
  337. cbdetCategories.Items.Clear();
  338. foreach (var category in _storage.Categories)
  339. cbdetCategories.Items.Add(category.Name);
  340. cbdetCategories.EndUpdate();
  341. tbdetPrice.Value = 0;
  342. tbdetUri.Text = string.Empty;
  343. cbdetParent.BeginUpdate();
  344. cbdetParent.Items.Clear();
  345. foreach (var product in _storage.GetProductsView(true, false).Select(x => x.Sku).Order())
  346. cbdetParent.Items.Add(product!);
  347. cbdetParent.EndUpdate();
  348. });
  349. }
  350. private void VisibleAllDetail(bool visible)
  351. {
  352. BlockErrorHandled(() =>
  353. {
  354. tbdetId.Visible = visible;
  355. ltbdetId.Visible = visible;
  356. tbdetName.Visible = visible;
  357. ltbdetName.Visible = visible;
  358. tbdetSku.Visible = visible;
  359. ltbdetSku.Visible = visible;
  360. tbdetShortDescription.Visible = visible;
  361. ltbdetShortDescription.Visible = visible;
  362. tbdetDescription.Visible = visible;
  363. ltbdetDescription.Visible = visible;
  364. tbdetPrice.Visible = visible;
  365. ltbdetPrice.Visible = visible;
  366. tbdetUri.Visible = visible;
  367. ltbdetUri.Visible = visible;
  368. cbdetCategories.Visible = visible;
  369. lcbdetCategories.Visible = visible;
  370. cbdetParent.Visible = visible;
  371. lcbdetParent.Visible = visible;
  372. });
  373. }
  374. private void ShowDetail(ProductDto? data)
  375. {
  376. BlockErrorHandled(() =>
  377. {
  378. _detailType = DetailType.Product;
  379. detProduct.Visible = false;
  380. ClearDetail();
  381. if (data == null)
  382. {
  383. detProduct.Visible = true;
  384. return;
  385. }
  386. var isVariant = data.IsVariant;
  387. tblbCaption.Text = isVariant ? "Varianta produktu" : "Produkt";
  388. VisibleAllDetail(true);
  389. if (isVariant)
  390. {
  391. // variant
  392. cbdetCategories.Visible = false;
  393. lcbdetCategories.Visible = false;
  394. }
  395. else
  396. {
  397. // head product
  398. cbdetParent.Visible = false;
  399. lcbdetParent.Visible = false;
  400. tbdetPrice.Visible = false;
  401. ltbdetPrice.Visible = false;
  402. cbdetCategories.SelectedIndex = cbdetCategories.FindStringExact(data.Category);
  403. }
  404. tbdetId.Text = data.Id.ToString();
  405. tbdetName.Text = data.ProductName;
  406. tbdetSku.Text = data.Sku;
  407. tbdetShortDescription.Text = data.ShortDescription;
  408. tbdetDescription.Text = data.Description;
  409. tbdetPrice.Value = data.Price;
  410. tbdetUri.Text = data.Uri;
  411. cbdetParent.SelectedIndex = cbdetParent.FindStringExact(data.ParentName);
  412. detProduct.Visible = true;
  413. });
  414. }
  415. private void ShowDetail(VariantDto? data)
  416. {
  417. BlockErrorHandled(() =>
  418. {
  419. _detailType = DetailType.Variant;
  420. tblbCaption.Text = "Varianta";
  421. detProduct.Visible = false;
  422. ClearDetail();
  423. if (data == null)
  424. {
  425. detProduct.Visible = true;
  426. return;
  427. }
  428. VisibleAllDetail(false);
  429. ltbdetName.Visible = true;
  430. tbdetName.Visible = true;
  431. ltbdetPrice.Visible = true;
  432. tbdetPrice.Visible = true;
  433. tbdetName.Text = data.Name;
  434. tbdetPrice.Value = data.Price;
  435. detProduct.Visible = true;
  436. });
  437. }
  438. private void ShowDetail(CategoryDto? data)
  439. {
  440. BlockErrorHandled(() =>
  441. {
  442. _detailType = DetailType.Category;
  443. tblbCaption.Text = "Kategorie";
  444. detProduct.Visible = false;
  445. ClearDetail();
  446. if (data == null)
  447. {
  448. detProduct.Visible = true;
  449. return;
  450. }
  451. VisibleAllDetail(false);
  452. ltbdetName.Visible = true;
  453. tbdetName.Visible = true;
  454. tbdetName.Text = data.Name;
  455. detProduct.Visible = true;
  456. });
  457. }
  458. private void SaveDetail(ProductDto? data)
  459. {
  460. BlockErrorHandled(() =>
  461. {
  462. if (data == null)
  463. return;
  464. data.ProductName = tbdetName.Text;
  465. if (!string.Equals(data.Sku,tbdetSku.Text,StringComparison.CurrentCultureIgnoreCase)){
  466. if (_storage.Products.Any(x => string.Equals(x.Sku, tbdetSku.Text, StringComparison.CurrentCultureIgnoreCase)))
  467. throw new Exception($"Produkt se zadaným SKU '{tbdetSku.Text}' již existuje!");
  468. if (!data.IsVariant)
  469. {
  470. foreach(ProductDto item in _storage.Products.Where(x=>x.IsVariant && string.Equals(x.ParentName, data.Sku, StringComparison.CurrentCultureIgnoreCase)))
  471. {
  472. item.ParentName = tbdetSku.Text;
  473. }
  474. }
  475. }
  476. data.Sku = tbdetSku.Text;
  477. data.ShortDescription = tbdetShortDescription.Text;
  478. data.Description = tbdetDescription.Text;
  479. data.Price = tbdetPrice.Value;
  480. data.Uri = tbdetUri.Text;
  481. data.ParentName = cbdetParent.SelectedItem?.ToString() ?? string.Empty;
  482. data.Category = cbdetCategories.SelectedItem?.ToString() ?? string.Empty;
  483. _storage.CheckProductVariantValidity();
  484. });
  485. }
  486. private void SaveDetail(VariantDto? data)
  487. {
  488. BlockErrorHandled(() =>
  489. {
  490. if (data == null)
  491. return;
  492. // update products
  493. var productsToUpdate = _storage.Products.Where(x => x.IsVariant && string.Equals(x.VariantName, data.Name, StringComparison.InvariantCultureIgnoreCase));
  494. foreach (var product in productsToUpdate)
  495. {
  496. product.VariantName = tbdetName.Text;
  497. product.Price = tbdetPrice.Value;
  498. }
  499. data.Name = tbdetName.Text;
  500. data.Price = tbdetPrice.Value;
  501. });
  502. }
  503. private void SaveDetail(CategoryDto? data)
  504. {
  505. BlockErrorHandled(() =>
  506. {
  507. if (data == null)
  508. return;
  509. // update products
  510. if (!string.Equals(data.Name, tbdetName.Text, StringComparison.InvariantCultureIgnoreCase))
  511. {
  512. var productsToUpdate = _storage.Products.Where(x => x.IsVariant && string.Equals(x.Category, data.Name, StringComparison.InvariantCultureIgnoreCase));
  513. foreach (var product in productsToUpdate)
  514. {
  515. product.Category = tbdetName.Text;
  516. }
  517. data.Name = tbdetName.Text;
  518. }
  519. });
  520. }
  521. private void AddNewVariant()
  522. {
  523. BlockErrorHandled(() =>
  524. {
  525. var item = _storage.AddNewVariant();
  526. lvVariants.AddItem(item, true);
  527. });
  528. }
  529. private void AddNewCategory()
  530. {
  531. BlockErrorHandled(() =>
  532. {
  533. var item = _storage.AddNewCategory();
  534. lvCategories.AddItem(item, true);
  535. });
  536. }
  537. private void AddNewProduct()
  538. {
  539. BlockErrorHandled(() =>
  540. {
  541. var item = _storage.AddNewProduct();
  542. item.ProductName = _hashGenerator.NewId();
  543. item.Sku = item.ProductName;
  544. lvProducts.AddItem(item, true);
  545. });
  546. }
  547. private void AddNewProductVariant()
  548. {
  549. BlockErrorHandled(() =>
  550. {
  551. var item = _storage.AddNewProductVariant(GetSelectedProduct()?.FirstOrDefault()?.ParentName);
  552. item.ProductName = _hashGenerator.NewId();
  553. item.Sku = item.ProductName;
  554. lvProducts.AddItem(item, true);
  555. });
  556. }
  557. private void CloneProduct(ProductDto item)
  558. {
  559. BlockErrorHandled(() =>
  560. {
  561. var newItem = item.IsVariant ? _storage.AddNewProductVariant(item.ParentName) : _storage.AddNewProduct();
  562. item.CopyTo(newItem);
  563. lvProducts.AddItem(newItem, true);
  564. });
  565. }
  566. private void ApplyProductVariant()
  567. {
  568. BlockErrorHandled(() =>
  569. {
  570. var variants = GetSelectedVariants();
  571. if (variants == null)
  572. return;
  573. var totalCnt = 0;
  574. foreach (var variant in variants)
  575. {
  576. var productsToUpdate = _storage.Products.Where(x => x.IsVariant && string.Equals(x.VariantName, variant.Name, StringComparison.InvariantCultureIgnoreCase));
  577. totalCnt += productsToUpdate.Count();
  578. foreach (var product in productsToUpdate)
  579. {
  580. product.Price = variant.Price;
  581. }
  582. }
  583. MessageBox.Show($"Bylo upraveno {totalCnt} produktů", "Hotovo", MessageBoxButtons.OK, MessageBoxIcon.Information);
  584. });
  585. }
  586. private ProductDto[]? GetSelectedProduct()
  587. {
  588. if (lvProducts.SelectedItems.Count == 0)
  589. return null;
  590. var result = new List<ProductDto>();
  591. BlockErrorHandled(() =>
  592. {
  593. foreach (ListViewItem item in lvProducts.SelectedItems)
  594. {
  595. var product = _storage.GetProductByIdentifier(item.Tag?.ToString());
  596. if (product != null)
  597. result.Add(product);
  598. }
  599. });
  600. return result.ToArray();
  601. }
  602. private VariantDto[]? GetSelectedVariants()
  603. {
  604. if (lvVariants.SelectedItems.Count == 0)
  605. return null;
  606. var result = new List<VariantDto>();
  607. BlockErrorHandled(() =>
  608. {
  609. foreach (ListViewItem item in lvVariants.SelectedItems)
  610. {
  611. var variant = _storage.GetVariantByIdentifier(item.Tag?.ToString());
  612. if (variant != null)
  613. result.Add(variant);
  614. }
  615. });
  616. return result.ToArray();
  617. }
  618. private CategoryDto[]? GetSelectedCategories()
  619. {
  620. if (lvCategories.SelectedItems.Count == 0)
  621. return null;
  622. var result = new List<CategoryDto>();
  623. foreach (ListViewItem item in lvCategories.SelectedItems)
  624. {
  625. var category = _storage.GetCategoryByIdentifier(item.Tag?.ToString());
  626. if (category != null)
  627. result.Add(category);
  628. }
  629. return result.ToArray();
  630. }
  631. private void ImportProducts(string selectedPath, string urlPrefix, string shortDescription, string description, DateTime uploadDate)
  632. {
  633. BlockErrorHandled(() =>
  634. {
  635. if (!Directory.Exists(selectedPath))
  636. throw new Exception($"Složka '{selectedPath}' neexistuje.");
  637. // search for files
  638. var fsrch = new FileSearch(selectedPath, true);
  639. var filesCache = new List<string>();
  640. var files = fsrch.Search(new[] {AppSettings.Default.SourceSearchPattern , "*" });
  641. if (files.Length == 0)
  642. throw new Exception($"Nenalezeny žádné soubory pro zpracování ve složce '{selectedPath}'.");
  643. // construct list of files
  644. foreach (var file in files)
  645. if (!filesCache.Any(x => x == file))
  646. filesCache.Add(file);
  647. var tplParams = new Dictionary<string, string>
  648. {
  649. { "DD", uploadDate.Day.ToString("00") },
  650. { "MM", uploadDate.Month.ToString("00") },
  651. { "YY", uploadDate.Year.ToString().Substring(2,2) },
  652. { "YYYY", uploadDate.Year.ToString() },
  653. { "file", "file" },
  654. { "ext", "ext" },
  655. { "category", "category" },
  656. { "variant", "variant" }
  657. };
  658. foreach (var file in filesCache)
  659. {
  660. var product = new ProductDto();
  661. var pathParts = file.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);
  662. if (pathParts.Length < 3) continue;
  663. var indexLast = pathParts.Length - 1;
  664. var sku = Path.GetFileNameWithoutExtension(pathParts[indexLast]);
  665. var variant = pathParts[indexLast - 1];
  666. var category = pathParts[indexLast - 2];
  667. tplParams["file"] = Path.GetFileNameWithoutExtension(pathParts[indexLast]);
  668. tplParams["ext"] = Path.GetExtension(pathParts[indexLast]);
  669. tplParams["variant"] = variant;
  670. tplParams["category"] = category;
  671. var parentDto = _storage.GetProductByName(Path.GetFileNameWithoutExtension(pathParts[indexLast]));
  672. if (parentDto == null)
  673. {
  674. // product has not parent, create new product
  675. parentDto = _storage.AddNewProduct();
  676. parentDto.ProductName = Path.GetFileNameWithoutExtension(pathParts[indexLast]);
  677. parentDto.Sku = sku + "_" + _hashGenerator.NewId();
  678. parentDto.Category = category;
  679. parentDto.ShortDescription = new ExtendedParametrizedString(shortDescription, tplParams, "{", "}").ToString();
  680. parentDto.Description = new ExtendedParametrizedString(description, tplParams, "{", "}").ToString();
  681. parentDto.Uri = new ExtendedParametrizedString(urlPrefix, tplParams, "{", "}").ToString();
  682. }
  683. product = _storage.AddNewProductVariant(parentDto.Sku);
  684. product.Uri = new ExtendedParametrizedString(urlPrefix, tplParams, "{", "}").ToString();
  685. product.ShortDescription = new ExtendedParametrizedString(shortDescription, tplParams, "{", "}").ToString();
  686. product.Description = new ExtendedParametrizedString(description, tplParams, "{", "}").ToString();
  687. product.ProductName = Path.GetFileNameWithoutExtension(pathParts[indexLast]) + " - " + variant;
  688. product.Sku = sku + "_" + _hashGenerator.NewId();
  689. product.Price = 0;
  690. product.VariantName = variant;
  691. }
  692. _storage.CheckProductVariantValidity();
  693. });
  694. }
  695. private bool ConfirmMessage(string message)
  696. {
  697. return MessageBox.Show(message, "Potvrzení", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes;
  698. }
  699. private void BlockErrorHandled(Action block)
  700. {
  701. try
  702. {
  703. block();
  704. }
  705. catch (Exception ex)
  706. {
  707. // Log("Error: " + ex.Message);
  708. MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  709. RefreshTools();
  710. }
  711. }
  712. #endregion
  713. }
  714. }