Nessuna descrizione

Utility.cs 58KB

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