Nav apraksta

Utility.cs 58KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.IO;
  7. using System.Net;
  8. using System.Management;
  9. using Newtonsoft.Json;
  10. using Newtonsoft.Json.Serialization;
  11. using Microsoft.Win32;
  12. using System.Security.Cryptography;
  13. using System.Data.SQLite;
  14. using System.Windows.Forms;
  15. using System.Globalization;
  16. using System.Threading;
  17. using System.Data.Common;
  18. namespace BulkPrinting
  19. {
  20. public class Utility
  21. {
  22. public static string GetHDDSerial()
  23. {
  24. ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
  25. string result;
  26. ManagementObjectCollection.ManagementObjectEnumerator enumerator = null;
  27. try
  28. {
  29. enumerator = managementObjectSearcher.Get().GetEnumerator();
  30. while (enumerator.MoveNext())
  31. {
  32. string text = ((ManagementObject)enumerator.Current)["SerialNumber"].ToString();
  33. text = text.Replace(" ", "").Replace(".", "");
  34. if (text != "")
  35. {
  36. result = text;
  37. return result.Length > 15 ? result.Substring(result.Length - 15, 15) : result;
  38. }
  39. }
  40. }
  41. finally
  42. {
  43. if (enumerator != null)
  44. {
  45. ((IDisposable)enumerator).Dispose();
  46. }
  47. }
  48. result = "SERIAL ERROR";
  49. return result.Length > 15 ? result.Substring(result.Length - 15, 15) : result;
  50. }
  51. public static bool Login(LoginData UserLoginData, bool Offline, bool RememberMe) {
  52. string MaxDBPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Configuration.MaxDataPathName);
  53. string PostData = JsonConvert.SerializeObject(UserLoginData);
  54. byte[] data = Encoding.ASCII.GetBytes(PostData);
  55. HttpWebRequest request = WebRequest.Create("https://" + Configuration.ServerDN + ":" + Configuration.ServerPort + "/api/login") as HttpWebRequest;
  56. request.ServerCertificateValidationCallback = delegate { return true; };
  57. request.Method = "POST";
  58. request.ContentType = "application/json";
  59. request.ContentLength = data.Length;
  60. request.Accept = "application/json";
  61. try
  62. {
  63. using (var stream = request.GetRequestStream())
  64. {
  65. stream.Write(data, 0, data.Length);
  66. }
  67. string responseString;
  68. using (var response = (HttpWebResponse)request.GetResponse())
  69. {
  70. responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
  71. }
  72. Globals.SessionData = JsonConvert.DeserializeObject<OKResponse>(responseString);
  73. if (RememberMe == true)
  74. {
  75. SaveSetting("Username", UserLoginData.Username);
  76. SaveSetting("UserID", UserLoginData.UserId.ToString());
  77. }
  78. else {
  79. SaveSetting("Username", "");
  80. SaveSetting("UserID", "");
  81. }
  82. SaveSetting("VendorID", UserLoginData.VendorId.ToString());
  83. Globals.SessionEncryptedDatabasePassword = Globals.SessionData.Credentials.Payload.EncryptedDatabasePassword;
  84. Globals.SessionSalt = Globals.SessionData.Credentials.Salt;
  85. Globals.SessionIterations = Globals.SessionData.Credentials.Iterations;
  86. return true;
  87. }
  88. catch (WebException) {
  89. return false;
  90. }
  91. }
  92. public static bool RESTRequest<R>(ref R Result, string RESTPath)
  93. {
  94. return RESTRequest<bool?, R>(null, ref Result, RESTPath);
  95. }
  96. public static bool RESTRequest<T, R>(T POSTData, ref R Result, string RESTPath) {
  97. string MaxDBPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Configuration.MaxDataPathName);
  98. HttpWebRequest request = WebRequest.Create("https://" + Configuration.ServerDN + ":" + Configuration.ServerPort + RESTPath) as HttpWebRequest;
  99. request.ServerCertificateValidationCallback = delegate { return true; };
  100. request.Headers.Add("Authorization", "Bearer " + Globals.SessionData.AccessToken);
  101. request.ContentType = "application/json";
  102. request.Accept = "application/json";
  103. try
  104. {
  105. if (POSTData != null)
  106. {
  107. string PostData = JsonConvert.SerializeObject(POSTData);
  108. byte[] data = Encoding.ASCII.GetBytes(PostData);
  109. request.ContentLength = data.Length;
  110. request.Method = "POST";
  111. using (var stream = request.GetRequestStream())
  112. {
  113. stream.Write(data, 0, data.Length);
  114. }
  115. }
  116. else {
  117. request.Method = "GET";
  118. }
  119. string responseString;
  120. using (var response = (HttpWebResponse)request.GetResponse())
  121. {
  122. responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
  123. }
  124. Result = JsonConvert.DeserializeObject<R>(responseString);
  125. return true;
  126. }
  127. catch (WebException)
  128. {
  129. return false;
  130. }
  131. }
  132. /*
  133. private static bool RegSave(string Key, string Value)
  134. {
  135. bool Result;
  136. try
  137. {
  138. RegistryKey MaxRegistry = Registry.CurrentUser.OpenSubKey("Software\\M@X\\BulkPrint");
  139. Registry.SetValue(MaxRegistry.Name, Key, Value);
  140. Registry.CurrentUser.Close();
  141. Result = true;
  142. }
  143. catch (Exception)
  144. {
  145. Result = false;
  146. }
  147. return Result;
  148. }
  149. public static string RegFetch(string Key)
  150. {
  151. string Result;
  152. try
  153. {
  154. RegistryKey MaxRegistry = Registry.CurrentUser.OpenSubKey("Software\\M@X\\BulkPrint");
  155. Result = Registry.GetValue(MaxRegistry.Name, Key, "").ToString();
  156. Registry.CurrentUser.Close();
  157. }
  158. catch (Exception)
  159. {
  160. Result = "";
  161. }
  162. return Result;
  163. }
  164. */
  165. private static bool SaveSetting(string Key, string Value)
  166. {
  167. SavedSettings StoredValues = LoadSavedSettings();
  168. switch (Key)
  169. {
  170. case "Username":
  171. StoredValues.Username = Value;
  172. break;
  173. case "UserID":
  174. if (Value == "")
  175. StoredValues.UserId = 0;
  176. else
  177. StoredValues.UserId = int.Parse(Value);
  178. break;
  179. case "VendorID":
  180. if (Value == "")
  181. StoredValues.VendorId = 0;
  182. else
  183. StoredValues.VendorId = int.Parse(Value);
  184. break;
  185. default:
  186. return false;
  187. }
  188. string MaxAppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Configuration.MaxDataPathName);
  189. string MaxSettingsFilePath = Path.Combine(MaxAppDataPath, "maxsettings.dat");
  190. File.WriteAllText(MaxSettingsFilePath, JsonConvert.SerializeObject(StoredValues));
  191. return true;
  192. }
  193. public static string LoadSetting(string Key)
  194. {
  195. SavedSettings StoredValues = LoadSavedSettings();
  196. string ReturnVal = "";
  197. switch (Key)
  198. {
  199. case "Username":
  200. ReturnVal = StoredValues.Username;
  201. break;
  202. case "UserID":
  203. ReturnVal = StoredValues.UserId.ToString();
  204. break;
  205. case "VendorID":
  206. ReturnVal = StoredValues.VendorId.ToString();
  207. break;
  208. default:
  209. return "";
  210. }
  211. if (ReturnVal == "0")
  212. return "";
  213. return ReturnVal;
  214. }
  215. private static SavedSettings LoadSavedSettings() {
  216. string MaxAppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Configuration.MaxDataPathName);
  217. string MaxSettingsFilePath = Path.Combine(MaxAppDataPath, "maxsettings.dat");
  218. SavedSettings StoredValues = new SavedSettings();
  219. if (!Directory.Exists(MaxAppDataPath))
  220. {
  221. Directory.CreateDirectory(MaxAppDataPath);
  222. }
  223. if (File.Exists(MaxSettingsFilePath)) {
  224. StoredValues = JsonConvert.DeserializeObject<SavedSettings>(File.ReadAllText(MaxSettingsFilePath));
  225. }
  226. else {
  227. File.WriteAllText(MaxSettingsFilePath, JsonConvert.SerializeObject(StoredValues));
  228. }
  229. return StoredValues;
  230. }
  231. public static byte[] Transform(ICryptoTransform transform, byte[] input)
  232. {
  233. using (var memoryStream = new MemoryStream())
  234. using (var cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
  235. {
  236. cryptoStream.Write(input, 0, input.Length);
  237. cryptoStream.FlushFinalBlock();
  238. return memoryStream.ToArray();
  239. }
  240. }
  241. public static byte[] AesDecryptBytes(byte[] cipherText, byte[] key)
  242. {
  243. using (var aes = Aes.Create())
  244. using (var decryptor = aes.CreateDecryptor(key, new byte[16]))
  245. {
  246. return Transform(decryptor, cipherText);
  247. }
  248. }
  249. public static string AesDecryptString(byte[] cipherText, byte[] key)
  250. {
  251. return Encoding.ASCII.GetString(AesDecryptBytes(cipherText, key));
  252. }
  253. public static string TripleDESDecrypt(string cipherText, TripleDES des)
  254. {
  255. using (var decryptor = des.CreateDecryptor(des.Key, des.IV))
  256. {
  257. return Encoding.UTF8.GetString(Transform(decryptor, Convert.FromBase64String(cipherText)));
  258. }
  259. }
  260. public static string TripleDESDecrypt(string cipherText, byte[] key)
  261. {
  262. using (var des = TripleDES.Create())
  263. {
  264. des.Key = key;
  265. des.IV = new byte[8];
  266. return TripleDESDecrypt(cipherText, des);
  267. }
  268. }
  269. public static Batch GetBatch(int BatchId) {
  270. Batch RequestedBatch = new Batch();
  271. bool OrderResult = Utility.RESTRequest<Batch>(ref RequestedBatch, String.Format("/api/batches/{0}", BatchId));
  272. return RequestedBatch;
  273. }
  274. public static string GetNextInternalReference()
  275. {
  276. InternalReferenceResponse InternalReferenceRequest = new InternalReferenceResponse();
  277. bool OrderResult = Utility.RESTRequest<InternalReferenceResponse>(ref InternalReferenceRequest, "/api/vendors/nextinternalref");
  278. return InternalReferenceRequest.InternalReference;
  279. }
  280. public static void DownloadBatch(Batch BatchItem)
  281. {
  282. if (BatchItem == null) {
  283. return;
  284. }
  285. Batch BatchRefresh = GetBatch(BatchItem.Id);
  286. string Sql = "DELETE FROM Batch WHERE Id=@id";
  287. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  288. Command.Parameters.Add(new SQLiteParameter("@id", BatchItem.Id));
  289. Command.ExecuteNonQuery();
  290. Sql = "INSERT INTO Batch (Id,OrderDate,OrderGuid,OrderReference,NetworkId,NetworkName,ProductId,ProductDescription ,VoucherType,FaceValue,DiscountPercentage,RequestedQuantity,DeliveredQuantity,Cost,ReadyForDownload,InternalReference)" +
  291. "VALUES (@a,@b,@c,@d,@e,@f,@g,@h,@i,@j,@k,@l,@m,@n,@o,@p)";
  292. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  293. Command.Parameters.Add(new SQLiteParameter("@a", BatchRefresh.Id));
  294. Command.Parameters.Add(new SQLiteParameter("@b", BatchRefresh.OrderDate));
  295. Command.Parameters.Add(new SQLiteParameter("@c", BatchRefresh.OrderGuid));
  296. Command.Parameters.Add(new SQLiteParameter("@d", BatchRefresh.OrderReference));
  297. Command.Parameters.Add(new SQLiteParameter("@e", BatchRefresh.NetworkId));
  298. Command.Parameters.Add(new SQLiteParameter("@f", BatchRefresh.NetworkName));
  299. Command.Parameters.Add(new SQLiteParameter("@g", BatchRefresh.ProductId));
  300. Command.Parameters.Add(new SQLiteParameter("@h", BatchRefresh.ProductDescription));
  301. Command.Parameters.Add(new SQLiteParameter("@i", BatchRefresh.VoucherType));
  302. Command.Parameters.Add(new SQLiteParameter("@j", BatchRefresh.FaceValue));
  303. Command.Parameters.Add(new SQLiteParameter("@k", BatchRefresh.DiscountPercentage));
  304. Command.Parameters.Add(new SQLiteParameter("@l", BatchRefresh.RequestedQuantity));
  305. Command.Parameters.Add(new SQLiteParameter("@m", BatchRefresh.DeliveredQuantity));
  306. Command.Parameters.Add(new SQLiteParameter("@n", BatchRefresh.Cost));
  307. Command.Parameters.Add(new SQLiteParameter("@o", BatchRefresh.ReadyForDownload));
  308. Command.Parameters.Add(new SQLiteParameter("@p", BatchRefresh.InternalReference));
  309. Command.ExecuteNonQuery();
  310. if (BatchRefresh.ReadyForDownload == true)
  311. {
  312. DownloadVouchers(BatchItem);
  313. }
  314. }
  315. public static void DownloadVouchers(Batch BatchItem, int PageNumber = 1) {
  316. string Sql;
  317. SQLiteCommand Command;
  318. Page<Voucher> VoucherBatch = new Page<Voucher>();
  319. bool BatchResult = Utility.RESTRequest<Page<Voucher>>(ref VoucherBatch, String.Format("/api/batches/{0}/vouchers/?page={1}&pageSize=1000", BatchItem.Id,PageNumber));
  320. if (PageNumber == 1) //Execute on first pass only
  321. {
  322. Sql = "DELETE FROM Voucher WHERE BatchId=@id";
  323. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  324. Command.Parameters.Add(new SQLiteParameter("@id", BatchItem.Id));
  325. Command.ExecuteNonQuery();
  326. }
  327. using (var Trans = Globals.DBConnection.BeginTransaction())
  328. {
  329. foreach (var VoucherItem in VoucherBatch.Items)
  330. {
  331. Sql = "INSERT INTO Voucher (Id,SequenceNumber,ExpiryDate,Serial,EncryptedPIN,BatchId)" +
  332. "VALUES (@id,@sequence_number,@expiry_date,@serial,@encrypted_pin,@batch_id)";
  333. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  334. Command.Parameters.Add(new SQLiteParameter("@id", VoucherItem.Id));
  335. Command.Parameters.Add(new SQLiteParameter("@sequence_number", VoucherItem.SequenceNumber));
  336. Command.Parameters.Add(new SQLiteParameter("@expiry_date", VoucherItem.ExpiryDate.Date));
  337. Command.Parameters.Add(new SQLiteParameter("@serial", VoucherItem.Serial));
  338. Command.Parameters.Add(new SQLiteParameter("@encrypted_pin", VoucherItem.EncryptedPIN));
  339. Command.Parameters.Add(new SQLiteParameter("@batch_id", BatchItem.Id));
  340. Command.ExecuteNonQuery();
  341. }
  342. Trans.Commit();
  343. }
  344. if (VoucherBatch.PageNumber < VoucherBatch.NumPages) {
  345. DownloadVouchers(BatchItem, PageNumber + 1);
  346. }
  347. }
  348. public static void SyncAllBatches(int PageNumber = 1)
  349. {
  350. string Sql;
  351. Page<Batch> BatchList = new Page<Batch>();
  352. bool BatchResult = Utility.RESTRequest<Page<Batch>>(ref BatchList, String.Format("/api/batches/?page={0}", PageNumber));
  353. foreach (var BatchItem in BatchList.Items)
  354. {
  355. Sql = "SELECT COUNT(*) FROM Voucher WHERE BatchId=@id";
  356. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  357. Command.Parameters.Add(new SQLiteParameter("@id", BatchItem.Id));
  358. int Count = Convert.ToInt32(Command.ExecuteScalar());
  359. if (BatchItem.ReadyForDownload==false || Count == 0 || Count < BatchItem.RequestedQuantity)
  360. {
  361. DownloadBatch(BatchItem);
  362. }
  363. }
  364. if (BatchList.PageNumber < BatchList.NumPages) {
  365. SyncAllBatches(PageNumber + 1);
  366. }
  367. }
  368. public static void PrintVouchers(int BatchId, int StartSeqNo, int EndSeqNo)
  369. {
  370. int VoucherCount = 0;
  371. int RowCount = 0;
  372. int PageCount = (int) Math.Ceiling(((decimal)StartSeqNo)/20);
  373. int TotalCount = 0;
  374. string SerialNumberTrimmed;
  375. bool IsReprint;
  376. var PrinterInitString = new StringBuilder();
  377. PrinterInitString.Append(Printer.INITIALISE_PRINTER).Append(Printer.EMPHASISE_ON).Append(Printer.UNIDIRECTIONAL_OFF).Append(Printer.CHARPITCHELITE);
  378. int initJobID = Globals.MaxPrinter.Open("Printer_Init");
  379. if (initJobID == 0) return;
  380. Globals.MaxPrinter.Print(PrinterInitString.ToString());
  381. Globals.MaxPrinter.Close();
  382. List<EventLog> LogEvents = new List<EventLog>();
  383. IList<PrintVoucher> VoucherRow = new List<PrintVoucher>();
  384. SQLiteCommand Command = new SQLiteCommand("SELECT DISTINCT v.Id,v.SequenceNumber,v.Serial,v.EncryptedPIN,v.BatchId,b.ProductDescription,l.VoucherId From Voucher v LEFT JOIN Batch b on v.BatchId = b.Id LEFT JOIN Logs l ON v.Id = l.VoucherId AND l.EventType = @eventtype WHERE v.BatchId=@batch_id AND v.SequenceNumber BETWEEN @seqstartno AND @seqendno ORDER BY v.SequenceNumber", Globals.DBConnection);
  385. Command.Parameters.Add(new SQLiteParameter("@batch_id", BatchId));
  386. Command.Parameters.Add(new SQLiteParameter("@eventtype", VendorEvent.VendorEventType.PrintVoucher));
  387. Command.Parameters.Add(new SQLiteParameter("@seqstartno", StartSeqNo));
  388. Command.Parameters.Add(new SQLiteParameter("@seqendno", EndSeqNo));
  389. using (SQLiteDataReader read = Command.ExecuteReader())
  390. {
  391. while (read.Read())
  392. {
  393. VoucherCount++;
  394. PrintVoucher IndividualVoucher = new PrintVoucher();
  395. IndividualVoucher.SequenceNumber = (int)read["SequenceNumber"];
  396. IndividualVoucher.BatchId = (int)read["BatchId"];
  397. IndividualVoucher.Serial = (string)read["Serial"];
  398. IndividualVoucher.VoucherId = (int)read["Id"];
  399. IndividualVoucher.Description = (string)read["ProductDescription"];
  400. IsReprint = !read.IsDBNull(6);
  401. if (IsReprint)
  402. {
  403. IndividualVoucher.Description = "*" + IndividualVoucher.Description;
  404. }
  405. IndividualVoucher.DecryptedPIN = Utility.TripleDESDecrypt((string)read["EncryptedPIN"], Globals.SessionVoucherKey);
  406. VoucherRow.Add(IndividualVoucher);
  407. if (VoucherCount >= 5 || TotalCount == (EndSeqNo - StartSeqNo))
  408. {
  409. RowCount++;
  410. string PrintRow = "\r\n\n\n ";
  411. for (int Column = 0; Column < VoucherRow.Count(); Column++)
  412. {
  413. IndividualVoucher = VoucherRow[Column];
  414. PrintRow += (Column == 2 ? " " : "") + (" " + IndividualVoucher.DecryptedPIN).PadRight(30, ' ');
  415. }
  416. PrintRow = PrintRow.TrimEnd() + "\r\n\n ";
  417. for (int Column = 0; Column < VoucherRow.Count(); Column++)
  418. {
  419. IndividualVoucher = VoucherRow[Column];
  420. SerialNumberTrimmed = IndividualVoucher.Serial;
  421. if (SerialNumberTrimmed.Length > 24)
  422. {
  423. SerialNumberTrimmed = SerialNumberTrimmed.Substring(0, 24);
  424. }
  425. PrintRow += (Column == 2 ? " " : "") + SerialNumberTrimmed.PadRight(30, ' ');
  426. }
  427. PrintRow = PrintRow.TrimEnd() + "\r\n ";
  428. for (int Column = 0; Column < VoucherRow.Count(); Column++)
  429. {
  430. IndividualVoucher = VoucherRow[Column];
  431. int CurrentPage = (int)Math.Ceiling(((decimal)IndividualVoucher.SequenceNumber) / 20);
  432. PrintRow += (Column == 2 ? " " : "") + String.Format("{0}/{1}/{2}", IndividualVoucher.BatchId, IndividualVoucher.SequenceNumber, PageCount).PadRight(30, ' ');
  433. }
  434. PrintRow = PrintRow.TrimEnd() + "\r\n ";
  435. for (int Column = 0; Column < VoucherRow.Count(); Column++)
  436. {
  437. IndividualVoucher = VoucherRow[Column];
  438. PrintRow += (Column == 2 ? " " : "") + IndividualVoucher.Description.PadRight(30, ' ');
  439. }
  440. PrintRow = PrintRow.TrimEnd() + "\r\n\n\n\n\n\n\n\n\n\n\n";
  441. int JobID = Globals.MaxPrinter.Open("Vouchers");
  442. if (JobID == 0) return;
  443. Globals.MaxPrinter.Print(PrintRow);
  444. Globals.MaxPrinter.Close();
  445. foreach (PrintVoucher PrintedVoucher in VoucherRow)
  446. {
  447. var ExportEvent = new EventLog();
  448. ExportEvent.EventType = VendorEvent.VendorEventType.PrintVoucher;
  449. ExportEvent.VoucherId = PrintedVoucher.VoucherId;
  450. ExportEvent.Retry = IsReprint;
  451. LogEvents.Add(ExportEvent);
  452. }
  453. VoucherRow = new List<PrintVoucher>();
  454. VoucherCount = 0;
  455. if (RowCount >= 4)
  456. {
  457. //Globals.MaxPrinter.NewPage();
  458. PageCount++;
  459. RowCount = 0;
  460. //Globals.MaxPrinter.GetJobInfo(JobID);
  461. }
  462. }
  463. TotalCount++;
  464. }
  465. }
  466. Utility.LogBulkEvents(LogEvents);
  467. }
  468. public enum UserPermissions {
  469. CanPrintOnline,
  470. CanReprintOnline,
  471. CanPrintOffline,
  472. CanReprintOffline,
  473. BulkExport,
  474. BulkOrder,
  475. BulkViewPins,
  476. BulkReExport
  477. }
  478. public static bool CheckUserAccess(UserPermissions Permission) {
  479. if (Globals.SessionData.Credentials.Payload.User.Level == (int)UserLevel.Administrator) {
  480. return true;
  481. }
  482. switch (Permission) {
  483. case UserPermissions.CanPrintOnline:
  484. return Globals.SessionData.Credentials.Payload.User.CanPrintOnline;
  485. case UserPermissions.CanReprintOnline:
  486. return Globals.SessionData.Credentials.Payload.User.CanReprintOnline;
  487. case UserPermissions.CanPrintOffline:
  488. return Globals.SessionData.Credentials.Payload.User.CanPrintOffline;
  489. case UserPermissions.CanReprintOffline:
  490. return Globals.SessionData.Credentials.Payload.User.CanReprintOffline;
  491. case UserPermissions.BulkViewPins:
  492. return Globals.SessionData.Credentials.Payload.User.BulkViewPins;
  493. case UserPermissions.BulkOrder:
  494. return Globals.SessionData.Credentials.Payload.User.BulkOrder;
  495. case UserPermissions.BulkExport:
  496. return Globals.SessionData.Credentials.Payload.User.BulkExport;
  497. case UserPermissions.BulkReExport:
  498. return Globals.SessionData.Credentials.Payload.User.BulkReExport;
  499. default:
  500. return false;
  501. }
  502. }
  503. public static void Logout() {
  504. if (Globals.SessionData != null)
  505. {
  506. string Sql = "DELETE FROM SessionData"; //Destroy stored session data
  507. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  508. Command.ExecuteNonQuery();
  509. string SessionDataJson = JsonConvert.SerializeObject(Globals.SessionData);
  510. Sql = "INSERT INTO SessionData (Key,Value) VALUES (@key,@value)";
  511. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  512. Command.Parameters.Add(new SQLiteParameter("@key", "SessionDataJson"));
  513. Command.Parameters.Add(new SQLiteParameter("@value", SessionDataJson));
  514. Command.ExecuteNonQuery();
  515. Utility.LogEvent(VendorEvent.VendorEventType.Logout);
  516. while (Globals.LogSyncRunning || Globals.LogSyncThread.IsAlive)
  517. {
  518. Globals.LogSyncThread.Join();
  519. }
  520. Globals.DBConnection.Close();
  521. Globals.SessionData = null;
  522. Globals.SessionDatabasePassword = null;
  523. Globals.SessionVoucherKey = null;
  524. Globals.SessionMode = SessionModes.Invalid;
  525. Globals.ProductCatalogue = null;
  526. Globals.MaxPrinter.Close();
  527. UserLoginForm LoginForm = (UserLoginForm)Application.OpenForms["UserLoginForm"];
  528. LoginForm.Show();
  529. }
  530. }
  531. public static int GetLastSyncedLogID() {
  532. VendorEventsMetaData MetaData = new VendorEventsMetaData();
  533. bool MetaDataResult = Utility.RESTRequest<VendorEventsMetaData>(ref MetaData, "/api/vendorevents/meta");
  534. if (MetaData.LastVendorEventRemoteId == null) {
  535. return 0;
  536. }
  537. return (int)MetaData.LastVendorEventRemoteId;
  538. }
  539. public static bool SyncLogs()
  540. {
  541. Globals.LogSyncRunning = true;
  542. bool ReSyncLogs = true;
  543. while (ReSyncLogs)
  544. {
  545. ReSyncLogs = false;
  546. int LastSyncedLogID = GetLastSyncedLogID();
  547. string Sql = "SELECT MAX(Id) FROM Logs";
  548. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  549. var result = Command.ExecuteScalar()?.ToString() ?? "0";
  550. if (string.IsNullOrWhiteSpace(result)) result = "0";
  551. int LastRecordedLogId = int.Parse(result.ToString());
  552. if (LastRecordedLogId > LastSyncedLogID)
  553. { //If local logs are newer than server logs
  554. List<RemoteVendorEvent> EventList = new List<RemoteVendorEvent>();
  555. RemoteVendorEvent NextEvent;
  556. RemoteVendorEventResponse LastVendorEventIdSynced;
  557. int Counter = 0;
  558. Command = new SQLiteCommand("Select Id,UserId,VoucherId,EventDate,EventType From Logs WHERE Id > @id", Globals.DBConnection);
  559. Command.Parameters.Add(new SQLiteParameter("@id", LastSyncedLogID));
  560. using (SQLiteDataReader read = Command.ExecuteReader())
  561. {
  562. while (read.Read())
  563. {
  564. Counter += 1;
  565. NextEvent = new RemoteVendorEvent();
  566. NextEvent.Id = read.GetInt32(0);
  567. NextEvent.UserId = read.GetInt32(1);
  568. if (read.IsDBNull(2) == true)
  569. {
  570. NextEvent.VoucherId = null;
  571. }
  572. else
  573. {
  574. NextEvent.VoucherId = read.GetInt32(2);
  575. }
  576. NextEvent.EventDate = (DateTime)read.GetDateTime(3);
  577. NextEvent.EventType = (VendorEvent.VendorEventType)Enum.Parse(typeof(VendorEvent.VendorEventType), read.GetValue(4).ToString());
  578. NextEvent.VendorId = Globals.SessionData.Credentials.Payload.Vendor.id;
  579. EventList.Add(NextEvent);
  580. if (Counter == 1000)
  581. { //Send logs in pages of 1000
  582. LastVendorEventIdSynced = new RemoteVendorEventResponse();
  583. bool EventPostResult = Utility.RESTRequest<List<RemoteVendorEvent>, RemoteVendorEventResponse>(EventList, ref LastVendorEventIdSynced, "/api/vendorevents/");
  584. Counter = 0;
  585. EventList = new List<RemoteVendorEvent>();
  586. }
  587. }
  588. if (Counter > 0)
  589. { //Left over logs not synced in a 100 item page
  590. LastVendorEventIdSynced = new RemoteVendorEventResponse();
  591. bool EventPostResult = Utility.RESTRequest<List<RemoteVendorEvent>, RemoteVendorEventResponse>(EventList, ref LastVendorEventIdSynced, "/api/vendorevents/");
  592. }
  593. }
  594. }
  595. else if (LastSyncedLogID > LastRecordedLogId)
  596. { //Server logs are newer than local logs, indicating loss of local database - resync entire table
  597. Sql = "DELETE FROM Logs";
  598. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  599. Command.ExecuteNonQuery();
  600. Page<VendorEvent> EventPage;
  601. int TotalPages = 1;
  602. for (int PageNumber = 1; PageNumber <= TotalPages; PageNumber++)
  603. {
  604. EventPage = new Page<VendorEvent>();
  605. bool EventGetResult = Utility.RESTRequest<Page<VendorEvent>>(ref EventPage, String.Format("/api/vendorevents/?page={0}&pagesize=1000", PageNumber));
  606. if (TotalPages == 1)
  607. { //Number of pages is sent with first page, so update on the fly
  608. TotalPages = EventPage.NumPages;
  609. }
  610. using (var Trans = Globals.DBConnection.BeginTransaction())
  611. {
  612. foreach (VendorEvent Event in EventPage.Items)
  613. {
  614. if (Event.RemoteId != null) //Only interested in downloading locally generated logs
  615. {
  616. Sql = "INSERT INTO Logs (Id, UserId, VoucherId, EventDate, EventType, Retry) VALUES (@id, @userid, @voucherid, @eventdate, @eventtype, @retry)";
  617. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  618. Command.Parameters.Add(new SQLiteParameter("@id", Event.RemoteId));
  619. Command.Parameters.Add(new SQLiteParameter("@userid", Event.UserId));
  620. Command.Parameters.Add(new SQLiteParameter("@voucherid", Event.VoucherId));
  621. Command.Parameters.Add(new SQLiteParameter("@eventdate", Event.EventDate.UtcDateTime));
  622. Command.Parameters.Add(new SQLiteParameter("@eventtype", Event.EventType));
  623. Command.Parameters.Add(new SQLiteParameter("@retry", Event.Retry));
  624. Command.ExecuteNonQuery();
  625. }
  626. }
  627. Trans.Commit();
  628. }
  629. }
  630. }
  631. if (Globals.LogSyncWaiting)
  632. {
  633. Globals.LogSyncWaiting = false;
  634. ReSyncLogs = true;
  635. }
  636. }
  637. Globals.LogSyncRunning = false;
  638. return true;
  639. }
  640. public static void LogBulkEvents(List<EventLog> EventLogs)
  641. {
  642. string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  643. using (var Trans = Globals.DBConnection.BeginTransaction())
  644. {
  645. foreach (var EventLog in EventLogs)
  646. {
  647. using (SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection))
  648. {
  649. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  650. Command.Parameters.Add(new SQLiteParameter("@voucherid", EventLog.VoucherId));
  651. Command.Parameters.Add(new SQLiteParameter("@eventdate", DateTime.UtcNow));
  652. Command.Parameters.Add(new SQLiteParameter("@eventtype", EventLog.EventType));
  653. Command.Parameters.Add(new SQLiteParameter("@retry", EventLog.Retry));
  654. Command.ExecuteNonQuery();
  655. }
  656. }
  657. Trans.Commit();
  658. }
  659. //string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  660. //SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  661. if (Globals.SessionMode == SessionModes.Online)
  662. {
  663. //if (Globals.LogSyncTask != null && Globals.LogSyncTask.Status == TaskStatus.Running)
  664. if (Globals.LogSyncRunning)
  665. {
  666. Globals.LogSyncWaiting = true;
  667. return;
  668. }
  669. Globals.LogSyncThread = new Thread(() => SyncLogs());
  670. Globals.LogSyncThread.Start();
  671. //var Result = await Task.Run(() => SyncLogs()).ConfigureAwait(false);
  672. }
  673. }
  674. public static void LogEvent(VendorEvent.VendorEventType EventType, int? VoucherId = null, bool Retry = false)
  675. {
  676. string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  677. using (SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection))
  678. {
  679. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  680. Command.Parameters.Add(new SQLiteParameter("@voucherid", VoucherId));
  681. Command.Parameters.Add(new SQLiteParameter("@eventdate", DateTime.UtcNow));
  682. Command.Parameters.Add(new SQLiteParameter("@eventtype", EventType));
  683. Command.Parameters.Add(new SQLiteParameter("@retry", Retry));
  684. Command.ExecuteNonQuery();
  685. }
  686. //string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  687. //SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  688. if (Globals.SessionMode == SessionModes.Online)
  689. {
  690. //if (Globals.LogSyncTask != null && Globals.LogSyncTask.Status == TaskStatus.Running)
  691. if (Globals.LogSyncRunning)
  692. {
  693. Globals.LogSyncWaiting = true;
  694. return;
  695. }
  696. Globals.LogSyncThread = new Thread(() => SyncLogs());
  697. Globals.LogSyncThread.Start();
  698. //var Result = await Task.Run(() => SyncLogs()).ConfigureAwait(false);
  699. }
  700. }
  701. private static void SaveCurrentUserUsage() {
  702. string Sql = "DELETE FROM AccessControlTracking WHERE UserID = @userid";
  703. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  704. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  705. Command.ExecuteNonQuery();
  706. Sql = "INSERT INTO AccessControlTracking (UserID, Date, Permission, CurrentUsage) Values" +
  707. "(@userid, datetime('now'), 'OfflinePrint', @offlineprintvalue)," +
  708. "(@userid, datetime('now'), 'OfflineReprint', @offlinereprintvalue)," +
  709. "(@userid, datetime('now'), 'OnlinePrint', @onlineprintvalue)," +
  710. "(@userid, datetime('now'), 'OnlineReprint', @onlinereprintvalue)," +
  711. "(@userid, datetime('now'), 'BulkOrder', @bulkorder)," +
  712. "(@userid, datetime('now'), 'BulkExport', @bulkexport)";
  713. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  714. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  715. Command.Parameters.Add(new SQLiteParameter("@offlineprintvalue", Globals.UserCurrentUsage.OfflinePrintValue));
  716. Command.Parameters.Add(new SQLiteParameter("@offlinereprintvalue", Globals.UserCurrentUsage.OfflineReprintValue));
  717. Command.Parameters.Add(new SQLiteParameter("@onlineprintvalue", Globals.UserCurrentUsage.OnlinePrintValue));
  718. Command.Parameters.Add(new SQLiteParameter("@onlinereprintvalue", Globals.UserCurrentUsage.OnlineReprintValue));
  719. Command.Parameters.Add(new SQLiteParameter("@bulkorder", Globals.UserCurrentUsage.BulkOrderValue));
  720. Command.Parameters.Add(new SQLiteParameter("@bulkexport", Globals.UserCurrentUsage.BulkExportValue));
  721. Command.ExecuteNonQuery();
  722. }
  723. public static void AddUserUsage(UserLimits.UserLimitTypes UserLimitType, decimal Value) {
  724. DateTime ServerDate = Globals.SessionData.Credentials.Payload.Date;
  725. DateTime Today = DateTime.Now;
  726. if (ServerDate.Date != Today.Date) //prevent system time tampering
  727. {
  728. MessageBox.Show("Date mismatch detected. Logging out.", "Server Date Mismatch", MessageBoxButtons.OK, MessageBoxIcon.Error);
  729. Logout();
  730. return;
  731. }
  732. switch (UserLimitType) {
  733. case UserLimits.UserLimitTypes.OfflinePrint:
  734. Globals.UserCurrentUsage.OfflinePrintValue += Value;
  735. break;
  736. case UserLimits.UserLimitTypes.OfflineReprint:
  737. Globals.UserCurrentUsage.OfflineReprintValue += Value;
  738. break;
  739. case UserLimits.UserLimitTypes.OnlinePrint:
  740. Globals.UserCurrentUsage.OnlinePrintValue += Value;
  741. break;
  742. case UserLimits.UserLimitTypes.OnlineReprint:
  743. Globals.UserCurrentUsage.OnlineReprintValue += Value;
  744. break;
  745. case UserLimits.UserLimitTypes.BulkExport:
  746. Globals.UserCurrentUsage.BulkExportValue += Value;
  747. break;
  748. case UserLimits.UserLimitTypes.BulkOrder:
  749. Globals.UserCurrentUsage.BulkOrderValue += Value;
  750. break;
  751. }
  752. //Immediately write to db to avoid cheating
  753. SaveCurrentUserUsage();
  754. }
  755. public static Boolean IsValueWithinRemainingUserLimit(UserLimits.UserLimitTypes UserLimitType, decimal Value) {
  756. decimal RemainingUserLimit = CheckRemainingUserLimit(UserLimitType);
  757. if (RemainingUserLimit == -1 || RemainingUserLimit >= Value) {
  758. return true;
  759. }
  760. return false;
  761. }
  762. public static decimal CheckRemainingUserLimit(UserLimits.UserLimitTypes UserLimitType) {
  763. if (Globals.SessionData.Credentials.Payload.User.Level == (int)UserLevel.Administrator)
  764. {
  765. return -1; //Signifies unlimited
  766. }
  767. switch (UserLimitType)
  768. {
  769. case UserLimits.UserLimitTypes.OfflinePrint:
  770. if (Globals.SessionData.Credentials.Payload.User.CanPrintOffline)
  771. {
  772. if (Globals.SessionData.Credentials.Payload.User.OfflinePrintValue > 0) //Unlimited from server is signified by 0, but remaining limit at 0 means limit reached, so change unlimited to -1 for internal use
  773. {
  774. return Globals.SessionData.Credentials.Payload.User.OfflinePrintValue - Globals.UserCurrentUsage.OfflinePrintValue;
  775. }
  776. else
  777. {
  778. return -1; //Signifies unlimited
  779. }
  780. }
  781. else
  782. {
  783. return 0;
  784. }
  785. case UserLimits.UserLimitTypes.OfflineReprint:
  786. if (Globals.SessionData.Credentials.Payload.User.CanReprintOffline)
  787. {
  788. if (Globals.SessionData.Credentials.Payload.User.OfflineReprintValue > 0) //Unlimited from server is signified by 0, but remaining limit at 0 means limit reached, so change unlimited to -1 for internal use
  789. {
  790. return Globals.SessionData.Credentials.Payload.User.OfflineReprintValue - Globals.UserCurrentUsage.OfflineReprintValue;
  791. }
  792. else
  793. {
  794. return -1; //Signifies unlimited
  795. }
  796. }
  797. else
  798. {
  799. return 0;
  800. }
  801. case UserLimits.UserLimitTypes.OnlinePrint:
  802. if (Globals.SessionData.Credentials.Payload.User.CanPrintOnline)
  803. {
  804. if (Globals.SessionData.Credentials.Payload.User.OnlinePrintValue > 0) //Unlimited from server is signified by 0, but remaining limit at 0 means limit reached, so change unlimited to -1 for internal use
  805. {
  806. return Globals.SessionData.Credentials.Payload.User.OnlinePrintValue - Globals.UserCurrentUsage.OnlinePrintValue;
  807. }
  808. else
  809. {
  810. return -1; //Signifies unlimited
  811. }
  812. }
  813. else
  814. {
  815. return 0;
  816. }
  817. case UserLimits.UserLimitTypes.OnlineReprint:
  818. if (Globals.SessionData.Credentials.Payload.User.CanReprintOnline)
  819. {
  820. if (Globals.SessionData.Credentials.Payload.User.OnlineReprintValue > 0) //Unlimited from server is signified by 0, but remaining limit at 0 means limit reached, so change unlimited to -1 for internal use
  821. {
  822. return Globals.SessionData.Credentials.Payload.User.OnlineReprintValue - Globals.UserCurrentUsage.OnlineReprintValue;
  823. }
  824. else
  825. {
  826. return -1; //Signifies unlimited
  827. }
  828. }
  829. else
  830. {
  831. return 0;
  832. }
  833. case UserLimits.UserLimitTypes.BulkExport:
  834. if (Globals.SessionData.Credentials.Payload.User.BulkExport)
  835. {
  836. if (Globals.SessionData.Credentials.Payload.User.BulkExportMaxValue > 0) //Unlimited from server is signified by 0, but remaining limit at 0 means limit reached, so change unlimited to -1 for internal use
  837. {
  838. return Globals.SessionData.Credentials.Payload.User.BulkExportMaxValue - Globals.UserCurrentUsage.BulkExportValue;
  839. }
  840. else
  841. {
  842. return -1; //Signifies unlimited
  843. }
  844. }
  845. else
  846. {
  847. return 0;
  848. }
  849. case UserLimits.UserLimitTypes.BulkOrder:
  850. if (Globals.SessionData.Credentials.Payload.User.BulkOrder)
  851. {
  852. if (Globals.SessionData.Credentials.Payload.User.BulkOrderMaxValue > 0) //Unlimited from server is signified by 0, but remaining limit at 0 means limit reached, so change unlimited to -1 for internal use
  853. {
  854. return Globals.SessionData.Credentials.Payload.User.BulkOrderMaxValue - Globals.UserCurrentUsage.BulkOrderValue;
  855. }
  856. else
  857. {
  858. return -1; //Signifies unlimited
  859. }
  860. }
  861. else
  862. {
  863. return 0;
  864. }
  865. }
  866. return 0;
  867. }
  868. private static int GetVoucherPrintCountFromLogs(int VoucherId)
  869. {
  870. string Sql = "SELECT COUNT(*) FROM Logs WHERE VoucherId=@voucherid AND EventType=@eventtype";
  871. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  872. Command.Parameters.Add(new SQLiteParameter("@voucherid", VoucherId));
  873. Command.Parameters.Add(new SQLiteParameter("@eventtype", (int)VendorEvent.VendorEventType.PrintVoucher));
  874. return int.Parse(Command.ExecuteScalar().ToString());
  875. }
  876. private static DateTime GetVoucherFirstPrintDateFromLogs(int VoucherId)
  877. {
  878. string Sql = "SELECT MIN(EventDate) FROM Logs WHERE VoucherId=@voucherid AND EventType=@eventtype";
  879. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  880. Command.Parameters.Add(new SQLiteParameter("@voucherid", VoucherId));
  881. Command.Parameters.Add(new SQLiteParameter("@eventtype", (int)VendorEvent.VendorEventType.PrintVoucher));
  882. return (DateTime)Command.ExecuteScalar();
  883. }
  884. private static decimal GetVoucherFaceValue(int VoucherId)
  885. {
  886. string Sql = "SELECT b.FaceValue FROM Voucher v LEFT JOIN Batch b on v.BatchId = b.Id WHERE v.Id=@voucherid";
  887. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  888. Command.Parameters.Add(new SQLiteParameter("@voucherid", VoucherId));
  889. return (decimal)Command.ExecuteScalar();
  890. }
  891. private static UserLimits CalculateUsageFromLogs() {
  892. UserLimits CalculateUsage = new UserLimits();
  893. CalculateUsage.OfflinePrintValue = 0;
  894. CalculateUsage.OfflineReprintValue = 0;
  895. CalculateUsage.OnlinePrintValue = 0;
  896. CalculateUsage.OnlineReprintValue = 0;
  897. var CurrentDate = DateTime.Today.Date;
  898. CultureInfo IVC = CultureInfo.InvariantCulture;
  899. string Sql = "SELECT VoucherId FROM Logs WHERE UserId=@userid AND EventDate BETWEEN @eventdatea AND @eventdateb AND EventType=@eventtype";
  900. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  901. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  902. Command.Parameters.Add(new SQLiteParameter("@eventdatea", CurrentDate.ToString("yyyy-MM-dd 00:00:00", IVC)));
  903. Command.Parameters.Add(new SQLiteParameter("@eventdateb", CurrentDate.ToString("yyyy-MM-dd 23:59:59", IVC)));
  904. Command.Parameters.Add(new SQLiteParameter("@eventtype", (int)VendorEvent.VendorEventType.PrintVoucher));
  905. int VoucherId;
  906. decimal VoucherFaceValue;
  907. using (SQLiteDataReader read = Command.ExecuteReader())
  908. {
  909. while (read.Read())
  910. {
  911. VoucherId = read.GetInt32(0);
  912. VoucherFaceValue = GetVoucherFaceValue(VoucherId);
  913. //Don't distinguish between online and offline usage for log recalculations
  914. CalculateUsage.OfflinePrintValue += VoucherFaceValue;
  915. CalculateUsage.OnlinePrintValue += VoucherFaceValue;
  916. if (GetVoucherPrintCountFromLogs(VoucherId) > 1) { //For reprinted vouchers just assume all prints were reprints - log recalculations should be stricter to prevent cheating
  917. CalculateUsage.OfflineReprintValue += VoucherFaceValue;
  918. CalculateUsage.OnlineReprintValue += VoucherFaceValue;
  919. }
  920. }
  921. }
  922. return CalculateUsage;
  923. }
  924. public static void InitialiseUserLimits()
  925. {
  926. Globals.UserCurrentUsage = new UserLimits();
  927. UserLimits CurrentUserLimits = new UserLimits();
  928. string Sql = "SELECT COUNT(*) FROM AccessControlTracking WHERE UserID = @userid";
  929. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  930. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  931. int Result = int.Parse(Command.ExecuteScalar().ToString());
  932. Sql = "SELECT Date FROM AccessControlTracking WHERE UserID = @userid";
  933. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  934. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  935. object ResultDate = Command.ExecuteScalar();
  936. bool DatePassed = false;
  937. if (ResultDate != null) {
  938. DateTime DateResult = DateTime.Parse(Command.ExecuteScalar().ToString());
  939. if (DateResult.Date < Globals.SessionData.Credentials.Payload.Date.Date) {
  940. DatePassed = true;
  941. }
  942. }
  943. if (DatePassed)
  944. { //Fresh day since last db write or data missing - fetch usage from logs incase of tampering
  945. Globals.UserCurrentUsage = CalculateUsageFromLogs();
  946. SaveCurrentUserUsage(); //Immediately write calculated usage to DB
  947. }
  948. else
  949. {
  950. if (Result == 6)
  951. {
  952. Sql = "SELECT UserID, Permission, CurrentUsage FROM AccessControlTracking WHERE UserID = @userid";
  953. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  954. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  955. using (SQLiteDataReader read = Command.ExecuteReader())
  956. {
  957. while (read.Read())
  958. {
  959. switch (read["Permission"])
  960. {
  961. case "OfflinePrint":
  962. Globals.UserCurrentUsage.OfflinePrintValue = (decimal)read["CurrentUsage"];
  963. break;
  964. case "OfflineReprint":
  965. Globals.UserCurrentUsage.OfflineReprintValue = (decimal)read["CurrentUsage"];
  966. break;
  967. case "OnlinePrint":
  968. Globals.UserCurrentUsage.OnlinePrintValue = (decimal)read["CurrentUsage"];
  969. break;
  970. case "OnlineReprint":
  971. Globals.UserCurrentUsage.OnlineReprintValue = (decimal)read["CurrentUsage"];
  972. break;
  973. case "BulkOrder":
  974. Globals.UserCurrentUsage.BulkOrderValue = (decimal)read["CurrentUsage"];
  975. break;
  976. case "BulkExport":
  977. Globals.UserCurrentUsage.BulkExportValue = (decimal)read["CurrentUsage"];
  978. break;
  979. }
  980. }
  981. }
  982. }
  983. else
  984. {
  985. Globals.UserCurrentUsage = CalculateUsageFromLogs();
  986. SaveCurrentUserUsage(); //Immediately write calculated usage to DB
  987. }
  988. }
  989. }
  990. public static int GetNumberOfUnprintedVouchersInRange(int StartSeqNo, int EndSeqNo, int BatchId) {
  991. int UnprintedVouchers = 0;
  992. int VoucherId;
  993. string Sql;
  994. SQLiteCommand Command;
  995. for (int SeqNo = StartSeqNo; SeqNo <= EndSeqNo; SeqNo++)
  996. {
  997. Sql = "SELECT Id FROM Voucher WHERE SequenceNumber=@sequencenumber AND BatchId=@batchid";
  998. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  999. Command.Parameters.Add(new SQLiteParameter("@sequencenumber", SeqNo));
  1000. Command.Parameters.Add(new SQLiteParameter("@batchid", BatchId));
  1001. VoucherId = int.Parse(Command.ExecuteScalar().ToString());
  1002. int NumPrintedVouchers = GetVoucherPrintCountFromLogs(VoucherId);
  1003. if (NumPrintedVouchers == 0) {
  1004. UnprintedVouchers++;
  1005. }
  1006. }
  1007. return UnprintedVouchers;
  1008. }
  1009. public class BulkLogger : IDisposable
  1010. {
  1011. SQLiteTransaction transaction;
  1012. SQLiteCommand logCommand;
  1013. public BulkLogger()
  1014. {
  1015. transaction = Globals.DBConnection.BeginTransaction();
  1016. string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  1017. logCommand = new SQLiteCommand(Sql, Globals.DBConnection);
  1018. logCommand.Transaction = transaction;
  1019. }
  1020. public void LogEvent(VendorEvent.VendorEventType EventType, int? VoucherId = null, bool Retry = false)
  1021. {
  1022. var Command = logCommand;
  1023. if (Command.Parameters.Count == 0)
  1024. {
  1025. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  1026. Command.Parameters.Add(new SQLiteParameter("@voucherid", VoucherId));
  1027. Command.Parameters.Add(new SQLiteParameter("@eventdate", DateTime.UtcNow));
  1028. Command.Parameters.Add(new SQLiteParameter("@eventtype", EventType));
  1029. Command.Parameters.Add(new SQLiteParameter("@retry", Retry));
  1030. }
  1031. else
  1032. {
  1033. Command.Parameters[1].Value = VoucherId;
  1034. Command.Parameters[2].Value = DateTime.UtcNow;
  1035. Command.Parameters[3].Value = EventType;
  1036. Command.Parameters[4].Value = Retry;
  1037. }
  1038. Command.ExecuteNonQuery();
  1039. }
  1040. private void SyncLogs()
  1041. {
  1042. //string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  1043. //SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  1044. if (Globals.SessionMode == SessionModes.Online)
  1045. {
  1046. //if (Globals.LogSyncTask != null && Globals.LogSyncTask.Status == TaskStatus.Running)
  1047. if (Globals.LogSyncRunning)
  1048. {
  1049. Globals.LogSyncWaiting = true;
  1050. return;
  1051. }
  1052. Globals.LogSyncThread = new Thread(() => SyncLogs());
  1053. Globals.LogSyncThread.Start();
  1054. //var Result = await Task.Run(() => SyncLogs()).ConfigureAwait(false);
  1055. }
  1056. }
  1057. #region IDisposable Support
  1058. private bool disposedValue = false; // To detect redundant calls
  1059. protected virtual void Dispose(bool disposing)
  1060. {
  1061. if (!disposedValue)
  1062. {
  1063. if (disposing)
  1064. {
  1065. transaction.Commit();
  1066. logCommand.Dispose();
  1067. SyncLogs();
  1068. }
  1069. // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
  1070. // TODO: set large fields to null.
  1071. disposedValue = true;
  1072. }
  1073. }
  1074. // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
  1075. // ~BulkLogger() {
  1076. // // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
  1077. // Dispose(false);
  1078. // }
  1079. // This code added to correctly implement the disposable pattern.
  1080. public void Dispose()
  1081. {
  1082. // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
  1083. Dispose(true);
  1084. // TODO: uncomment the following line if the finalizer is overridden above.
  1085. // GC.SuppressFinalize(this);
  1086. }
  1087. #endregion
  1088. }
  1089. }
  1090. }