Няма описание

Utility.cs 57KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  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 = 1;
  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", 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. PrintRow += (Column == 2 ? " " : "") + String.Format("{0}/{1}/{2}", IndividualVoucher.BatchId, IndividualVoucher.SequenceNumber, PageCount).PadRight(30, ' ');
  432. }
  433. PrintRow = PrintRow.TrimEnd() + "\r\n ";
  434. for (int Column = 0; Column < VoucherRow.Count(); Column++)
  435. {
  436. IndividualVoucher = VoucherRow[Column];
  437. PrintRow += (Column == 2 ? " " : "") + IndividualVoucher.Description.PadRight(30, ' ');
  438. }
  439. PrintRow = PrintRow.TrimEnd() + "\r\n\n\n\n\n\n\n\n\n\n\n";
  440. int JobID = Globals.MaxPrinter.Open("Vouchers");
  441. if (JobID == 0) return;
  442. Globals.MaxPrinter.Print(PrintRow);
  443. Globals.MaxPrinter.Close();
  444. foreach (PrintVoucher PrintedVoucher in VoucherRow)
  445. {
  446. var ExportEvent = new EventLog();
  447. ExportEvent.EventType = VendorEvent.VendorEventType.PrintVoucher;
  448. ExportEvent.VoucherId = PrintedVoucher.VoucherId;
  449. ExportEvent.Retry = IsReprint;
  450. LogEvents.Add(ExportEvent);
  451. }
  452. VoucherRow = new List<PrintVoucher>();
  453. VoucherCount = 0;
  454. if (RowCount >= 4)
  455. {
  456. //Globals.MaxPrinter.NewPage();
  457. PageCount++;
  458. RowCount = 0;
  459. //Globals.MaxPrinter.GetJobInfo(JobID);
  460. }
  461. }
  462. TotalCount++;
  463. }
  464. }
  465. Utility.LogBulkEvents(LogEvents);
  466. }
  467. public enum UserPermissions {
  468. CanPrintOnline,
  469. CanReprintOnline,
  470. CanPrintOffline,
  471. CanReprintOffline,
  472. BulkExport,
  473. BulkOrder,
  474. BulkViewPins,
  475. BulkReExport
  476. }
  477. public static bool CheckUserAccess(UserPermissions Permission) {
  478. if (Globals.SessionData.Credentials.Payload.User.Level == (int)UserLevel.Administrator) {
  479. return true;
  480. }
  481. switch (Permission) {
  482. case UserPermissions.CanPrintOnline:
  483. return Globals.SessionData.Credentials.Payload.User.CanPrintOnline;
  484. case UserPermissions.CanReprintOnline:
  485. return Globals.SessionData.Credentials.Payload.User.CanReprintOnline;
  486. case UserPermissions.CanPrintOffline:
  487. return Globals.SessionData.Credentials.Payload.User.CanPrintOffline;
  488. case UserPermissions.CanReprintOffline:
  489. return Globals.SessionData.Credentials.Payload.User.CanReprintOffline;
  490. case UserPermissions.BulkViewPins:
  491. return Globals.SessionData.Credentials.Payload.User.BulkViewPins;
  492. case UserPermissions.BulkOrder:
  493. return Globals.SessionData.Credentials.Payload.User.BulkOrder;
  494. case UserPermissions.BulkExport:
  495. return Globals.SessionData.Credentials.Payload.User.BulkExport;
  496. case UserPermissions.BulkReExport:
  497. return Globals.SessionData.Credentials.Payload.User.BulkReExport;
  498. default:
  499. return false;
  500. }
  501. }
  502. public static void Logout() {
  503. if (Globals.SessionData != null)
  504. {
  505. string Sql = "DELETE FROM SessionData"; //Destroy stored session data
  506. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  507. Command.ExecuteNonQuery();
  508. string SessionDataJson = JsonConvert.SerializeObject(Globals.SessionData);
  509. Sql = "INSERT INTO SessionData (Key,Value) VALUES (@key,@value)";
  510. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  511. Command.Parameters.Add(new SQLiteParameter("@key", "SessionDataJson"));
  512. Command.Parameters.Add(new SQLiteParameter("@value", SessionDataJson));
  513. Command.ExecuteNonQuery();
  514. Utility.LogEvent(VendorEvent.VendorEventType.Logout);
  515. while (Globals.LogSyncRunning || Globals.LogSyncThread.IsAlive)
  516. {
  517. Globals.LogSyncThread.Join();
  518. }
  519. Globals.DBConnection.Close();
  520. Globals.SessionData = null;
  521. Globals.SessionDatabasePassword = null;
  522. Globals.SessionVoucherKey = null;
  523. Globals.SessionMode = SessionModes.Invalid;
  524. Globals.ProductCatalogue = null;
  525. Globals.MaxPrinter.Close();
  526. UserLoginForm LoginForm = (UserLoginForm)Application.OpenForms["UserLoginForm"];
  527. LoginForm.Show();
  528. }
  529. }
  530. public static int GetLastSyncedLogID() {
  531. VendorEventsMetaData MetaData = new VendorEventsMetaData();
  532. bool MetaDataResult = Utility.RESTRequest<VendorEventsMetaData>(ref MetaData, "/api/vendorevents/meta");
  533. if (MetaData.LastVendorEventRemoteId == null) {
  534. return 0;
  535. }
  536. return (int)MetaData.LastVendorEventRemoteId;
  537. }
  538. public static bool SyncLogs()
  539. {
  540. Globals.LogSyncRunning = true;
  541. bool ReSyncLogs = true;
  542. while (ReSyncLogs)
  543. {
  544. ReSyncLogs = false;
  545. int LastSyncedLogID = GetLastSyncedLogID();
  546. string Sql = "SELECT MAX(Id) FROM Logs";
  547. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  548. var result = Command.ExecuteScalar()?.ToString() ?? "0";
  549. if (string.IsNullOrWhiteSpace(result)) result = "0";
  550. int LastRecordedLogId = int.Parse(result.ToString());
  551. if (LastRecordedLogId > LastSyncedLogID)
  552. { //If local logs are newer than server logs
  553. List<RemoteVendorEvent> EventList = new List<RemoteVendorEvent>();
  554. RemoteVendorEvent NextEvent;
  555. RemoteVendorEventResponse LastVendorEventIdSynced;
  556. int Counter = 0;
  557. Command = new SQLiteCommand("Select Id,UserId,VoucherId,EventDate,EventType From Logs WHERE Id > @id", Globals.DBConnection);
  558. Command.Parameters.Add(new SQLiteParameter("@id", LastSyncedLogID));
  559. using (SQLiteDataReader read = Command.ExecuteReader())
  560. {
  561. while (read.Read())
  562. {
  563. Counter += 1;
  564. NextEvent = new RemoteVendorEvent();
  565. NextEvent.Id = read.GetInt32(0);
  566. NextEvent.UserId = read.GetInt32(1);
  567. if (read.IsDBNull(2) == true)
  568. {
  569. NextEvent.VoucherId = null;
  570. }
  571. else
  572. {
  573. NextEvent.VoucherId = read.GetInt32(2);
  574. }
  575. NextEvent.EventDate = (DateTime)read.GetDateTime(3);
  576. NextEvent.EventType = (VendorEvent.VendorEventType)Enum.Parse(typeof(VendorEvent.VendorEventType), read.GetValue(4).ToString());
  577. NextEvent.VendorId = Globals.SessionData.Credentials.Payload.Vendor.id;
  578. EventList.Add(NextEvent);
  579. if (Counter == 1000)
  580. { //Send logs in pages of 1000
  581. LastVendorEventIdSynced = new RemoteVendorEventResponse();
  582. bool EventPostResult = Utility.RESTRequest<List<RemoteVendorEvent>, RemoteVendorEventResponse>(EventList, ref LastVendorEventIdSynced, "/api/vendorevents/");
  583. Counter = 0;
  584. EventList = new List<RemoteVendorEvent>();
  585. }
  586. }
  587. if (Counter > 0)
  588. { //Left over logs not synced in a 100 item page
  589. LastVendorEventIdSynced = new RemoteVendorEventResponse();
  590. bool EventPostResult = Utility.RESTRequest<List<RemoteVendorEvent>, RemoteVendorEventResponse>(EventList, ref LastVendorEventIdSynced, "/api/vendorevents/");
  591. }
  592. }
  593. }
  594. else if (LastSyncedLogID > LastRecordedLogId)
  595. { //Server logs are newer than local logs, indicating loss of local database - resync entire table
  596. Sql = "DELETE FROM Logs";
  597. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  598. Command.ExecuteNonQuery();
  599. Page<VendorEvent> EventPage;
  600. int TotalPages = 1;
  601. for (int PageNumber = 1; PageNumber <= TotalPages; PageNumber++)
  602. {
  603. EventPage = new Page<VendorEvent>();
  604. bool EventGetResult = Utility.RESTRequest<Page<VendorEvent>>(ref EventPage, String.Format("/api/vendorevents/?page={0}&pagesize=1000", PageNumber));
  605. if (TotalPages == 1)
  606. { //Number of pages is sent with first page, so update on the fly
  607. TotalPages = EventPage.NumPages;
  608. }
  609. using (var Trans = Globals.DBConnection.BeginTransaction())
  610. {
  611. foreach (VendorEvent Event in EventPage.Items)
  612. {
  613. if (Event.RemoteId != null) //Only interested in downloading locally generated logs
  614. {
  615. Sql = "INSERT INTO Logs (Id, UserId, VoucherId, EventDate, EventType, Retry) VALUES (@id, @userid, @voucherid, @eventdate, @eventtype, @retry)";
  616. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  617. Command.Parameters.Add(new SQLiteParameter("@id", Event.RemoteId));
  618. Command.Parameters.Add(new SQLiteParameter("@userid", Event.UserId));
  619. Command.Parameters.Add(new SQLiteParameter("@voucherid", Event.VoucherId));
  620. Command.Parameters.Add(new SQLiteParameter("@eventdate", Event.EventDate.UtcDateTime));
  621. Command.Parameters.Add(new SQLiteParameter("@eventtype", Event.EventType));
  622. Command.Parameters.Add(new SQLiteParameter("@retry", Event.Retry));
  623. Command.ExecuteNonQuery();
  624. }
  625. }
  626. Trans.Commit();
  627. }
  628. }
  629. }
  630. if (Globals.LogSyncWaiting)
  631. {
  632. Globals.LogSyncWaiting = false;
  633. ReSyncLogs = true;
  634. }
  635. }
  636. Globals.LogSyncRunning = false;
  637. return true;
  638. }
  639. public static void LogBulkEvents(List<EventLog> EventLogs)
  640. {
  641. string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  642. using (var Trans = Globals.DBConnection.BeginTransaction())
  643. {
  644. foreach (var EventLog in EventLogs)
  645. {
  646. using (SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection))
  647. {
  648. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  649. Command.Parameters.Add(new SQLiteParameter("@voucherid", EventLog.VoucherId));
  650. Command.Parameters.Add(new SQLiteParameter("@eventdate", DateTime.UtcNow));
  651. Command.Parameters.Add(new SQLiteParameter("@eventtype", EventLog.EventType));
  652. Command.Parameters.Add(new SQLiteParameter("@retry", EventLog.Retry));
  653. Command.ExecuteNonQuery();
  654. }
  655. }
  656. Trans.Commit();
  657. }
  658. //string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  659. //SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  660. if (Globals.SessionMode == SessionModes.Online)
  661. {
  662. //if (Globals.LogSyncTask != null && Globals.LogSyncTask.Status == TaskStatus.Running)
  663. if (Globals.LogSyncRunning)
  664. {
  665. Globals.LogSyncWaiting = true;
  666. return;
  667. }
  668. Globals.LogSyncThread = new Thread(() => SyncLogs());
  669. Globals.LogSyncThread.Start();
  670. //var Result = await Task.Run(() => SyncLogs()).ConfigureAwait(false);
  671. }
  672. }
  673. public static void LogEvent(VendorEvent.VendorEventType EventType, int? VoucherId = null, bool Retry = false)
  674. {
  675. string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  676. using (SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection))
  677. {
  678. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  679. Command.Parameters.Add(new SQLiteParameter("@voucherid", VoucherId));
  680. Command.Parameters.Add(new SQLiteParameter("@eventdate", DateTime.UtcNow));
  681. Command.Parameters.Add(new SQLiteParameter("@eventtype", EventType));
  682. Command.Parameters.Add(new SQLiteParameter("@retry", Retry));
  683. Command.ExecuteNonQuery();
  684. }
  685. //string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  686. //SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  687. if (Globals.SessionMode == SessionModes.Online)
  688. {
  689. //if (Globals.LogSyncTask != null && Globals.LogSyncTask.Status == TaskStatus.Running)
  690. if (Globals.LogSyncRunning)
  691. {
  692. Globals.LogSyncWaiting = true;
  693. return;
  694. }
  695. Globals.LogSyncThread = new Thread(() => SyncLogs());
  696. Globals.LogSyncThread.Start();
  697. //var Result = await Task.Run(() => SyncLogs()).ConfigureAwait(false);
  698. }
  699. }
  700. private static void SaveCurrentUserUsage() {
  701. string Sql = "DELETE FROM AccessControlTracking WHERE UserID = @userid";
  702. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  703. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  704. Command.ExecuteNonQuery();
  705. Sql = "INSERT INTO AccessControlTracking (UserID, Date, Permission, CurrentUsage) Values" +
  706. "(@userid, datetime('now'), 'OfflinePrint', @offlineprintvalue)," +
  707. "(@userid, datetime('now'), 'OfflineReprint', @offlinereprintvalue)," +
  708. "(@userid, datetime('now'), 'OnlinePrint', @onlineprintvalue)," +
  709. "(@userid, datetime('now'), 'OnlineReprint', @onlinereprintvalue)," +
  710. "(@userid, datetime('now'), 'BulkOrder', @bulkorder)," +
  711. "(@userid, datetime('now'), 'BulkExport', @bulkexport)";
  712. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  713. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  714. Command.Parameters.Add(new SQLiteParameter("@offlineprintvalue", Globals.UserCurrentUsage.OfflinePrintValue));
  715. Command.Parameters.Add(new SQLiteParameter("@offlinereprintvalue", Globals.UserCurrentUsage.OfflineReprintValue));
  716. Command.Parameters.Add(new SQLiteParameter("@onlineprintvalue", Globals.UserCurrentUsage.OnlinePrintValue));
  717. Command.Parameters.Add(new SQLiteParameter("@onlinereprintvalue", Globals.UserCurrentUsage.OnlineReprintValue));
  718. Command.Parameters.Add(new SQLiteParameter("@bulkorder", Globals.UserCurrentUsage.BulkOrderValue));
  719. Command.Parameters.Add(new SQLiteParameter("@bulkexport", Globals.UserCurrentUsage.BulkExportValue));
  720. Command.ExecuteNonQuery();
  721. }
  722. public static void AddUserUsage(UserLimits.UserLimitTypes UserLimitType, decimal Value) {
  723. DateTime ServerDate = Globals.SessionData.Credentials.Payload.Date;
  724. DateTime Today = DateTime.Now;
  725. if (ServerDate.Date != Today.Date) //prevent system time tampering
  726. {
  727. MessageBox.Show("Date mismatch detected. Logging out.", "Server Date Mismatch", MessageBoxButtons.OK, MessageBoxIcon.Error);
  728. Logout();
  729. return;
  730. }
  731. switch (UserLimitType) {
  732. case UserLimits.UserLimitTypes.OfflinePrint:
  733. Globals.UserCurrentUsage.OfflinePrintValue += Value;
  734. break;
  735. case UserLimits.UserLimitTypes.OfflineReprint:
  736. Globals.UserCurrentUsage.OfflineReprintValue += Value;
  737. break;
  738. case UserLimits.UserLimitTypes.OnlinePrint:
  739. Globals.UserCurrentUsage.OnlinePrintValue += Value;
  740. break;
  741. case UserLimits.UserLimitTypes.OnlineReprint:
  742. Globals.UserCurrentUsage.OnlineReprintValue += Value;
  743. break;
  744. case UserLimits.UserLimitTypes.BulkExport:
  745. Globals.UserCurrentUsage.BulkExportValue += Value;
  746. break;
  747. case UserLimits.UserLimitTypes.BulkOrder:
  748. Globals.UserCurrentUsage.BulkOrderValue += Value;
  749. break;
  750. }
  751. //Immediately write to db to avoid cheating
  752. SaveCurrentUserUsage();
  753. }
  754. public static Boolean IsValueWithinRemainingUserLimit(UserLimits.UserLimitTypes UserLimitType, decimal Value) {
  755. decimal RemainingUserLimit = CheckRemainingUserLimit(UserLimitType);
  756. if (RemainingUserLimit == -1 || RemainingUserLimit >= Value) {
  757. return true;
  758. }
  759. return false;
  760. }
  761. public static decimal CheckRemainingUserLimit(UserLimits.UserLimitTypes UserLimitType) {
  762. if (Globals.SessionData.Credentials.Payload.User.Level == (int)UserLevel.Administrator)
  763. {
  764. return -1; //Signifies unlimited
  765. }
  766. switch (UserLimitType)
  767. {
  768. case UserLimits.UserLimitTypes.OfflinePrint:
  769. if (Globals.SessionData.Credentials.Payload.User.CanPrintOffline)
  770. {
  771. 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
  772. {
  773. return Globals.SessionData.Credentials.Payload.User.OfflinePrintValue - Globals.UserCurrentUsage.OfflinePrintValue;
  774. }
  775. else
  776. {
  777. return -1; //Signifies unlimited
  778. }
  779. }
  780. else
  781. {
  782. return 0;
  783. }
  784. case UserLimits.UserLimitTypes.OfflineReprint:
  785. if (Globals.SessionData.Credentials.Payload.User.CanReprintOffline)
  786. {
  787. 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
  788. {
  789. return Globals.SessionData.Credentials.Payload.User.OfflineReprintValue - Globals.UserCurrentUsage.OfflineReprintValue;
  790. }
  791. else
  792. {
  793. return -1; //Signifies unlimited
  794. }
  795. }
  796. else
  797. {
  798. return 0;
  799. }
  800. case UserLimits.UserLimitTypes.OnlinePrint:
  801. if (Globals.SessionData.Credentials.Payload.User.CanPrintOnline)
  802. {
  803. 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
  804. {
  805. return Globals.SessionData.Credentials.Payload.User.OnlinePrintValue - Globals.UserCurrentUsage.OnlinePrintValue;
  806. }
  807. else
  808. {
  809. return -1; //Signifies unlimited
  810. }
  811. }
  812. else
  813. {
  814. return 0;
  815. }
  816. case UserLimits.UserLimitTypes.OnlineReprint:
  817. if (Globals.SessionData.Credentials.Payload.User.CanReprintOnline)
  818. {
  819. 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
  820. {
  821. return Globals.SessionData.Credentials.Payload.User.OnlineReprintValue - Globals.UserCurrentUsage.OnlineReprintValue;
  822. }
  823. else
  824. {
  825. return -1; //Signifies unlimited
  826. }
  827. }
  828. else
  829. {
  830. return 0;
  831. }
  832. case UserLimits.UserLimitTypes.BulkExport:
  833. if (Globals.SessionData.Credentials.Payload.User.BulkExport)
  834. {
  835. 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
  836. {
  837. return Globals.SessionData.Credentials.Payload.User.BulkExportMaxValue - Globals.UserCurrentUsage.BulkExportValue;
  838. }
  839. else
  840. {
  841. return -1; //Signifies unlimited
  842. }
  843. }
  844. else
  845. {
  846. return 0;
  847. }
  848. case UserLimits.UserLimitTypes.BulkOrder:
  849. if (Globals.SessionData.Credentials.Payload.User.BulkOrder)
  850. {
  851. 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
  852. {
  853. return Globals.SessionData.Credentials.Payload.User.BulkOrderMaxValue - Globals.UserCurrentUsage.BulkOrderValue;
  854. }
  855. else
  856. {
  857. return -1; //Signifies unlimited
  858. }
  859. }
  860. else
  861. {
  862. return 0;
  863. }
  864. }
  865. return 0;
  866. }
  867. private static int GetVoucherPrintCountFromLogs(int VoucherId)
  868. {
  869. string Sql = "SELECT COUNT(*) FROM Logs WHERE VoucherId=@voucherid AND EventType=@eventtype";
  870. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  871. Command.Parameters.Add(new SQLiteParameter("@voucherid", VoucherId));
  872. Command.Parameters.Add(new SQLiteParameter("@eventtype", (int)VendorEvent.VendorEventType.PrintVoucher));
  873. return int.Parse(Command.ExecuteScalar().ToString());
  874. }
  875. private static DateTime GetVoucherFirstPrintDateFromLogs(int VoucherId)
  876. {
  877. string Sql = "SELECT MIN(EventDate) FROM Logs WHERE VoucherId=@voucherid AND EventType=@eventtype";
  878. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  879. Command.Parameters.Add(new SQLiteParameter("@voucherid", VoucherId));
  880. Command.Parameters.Add(new SQLiteParameter("@eventtype", (int)VendorEvent.VendorEventType.PrintVoucher));
  881. return (DateTime)Command.ExecuteScalar();
  882. }
  883. private static decimal GetVoucherFaceValue(int VoucherId)
  884. {
  885. string Sql = "SELECT b.FaceValue FROM Voucher v LEFT JOIN Batch b on v.BatchId = b.Id WHERE v.Id=@voucherid";
  886. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  887. Command.Parameters.Add(new SQLiteParameter("@voucherid", VoucherId));
  888. return (decimal)Command.ExecuteScalar();
  889. }
  890. private static UserLimits CalculateUsageFromLogs() {
  891. UserLimits CalculateUsage = new UserLimits();
  892. CalculateUsage.OfflinePrintValue = 0;
  893. CalculateUsage.OfflineReprintValue = 0;
  894. CalculateUsage.OnlinePrintValue = 0;
  895. CalculateUsage.OnlineReprintValue = 0;
  896. var CurrentDate = DateTime.Today.Date;
  897. CultureInfo IVC = CultureInfo.InvariantCulture;
  898. string Sql = "SELECT VoucherId FROM Logs WHERE UserId=@userid AND EventDate BETWEEN @eventdatea AND @eventdateb AND EventType=@eventtype";
  899. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  900. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  901. Command.Parameters.Add(new SQLiteParameter("@eventdatea", CurrentDate.ToString("yyyy-MM-dd 00:00:00", IVC)));
  902. Command.Parameters.Add(new SQLiteParameter("@eventdateb", CurrentDate.ToString("yyyy-MM-dd 23:59:59", IVC)));
  903. Command.Parameters.Add(new SQLiteParameter("@eventtype", (int)VendorEvent.VendorEventType.PrintVoucher));
  904. int VoucherId;
  905. decimal VoucherFaceValue;
  906. using (SQLiteDataReader read = Command.ExecuteReader())
  907. {
  908. while (read.Read())
  909. {
  910. VoucherId = read.GetInt32(0);
  911. VoucherFaceValue = GetVoucherFaceValue(VoucherId);
  912. //Don't distinguish between online and offline usage for log recalculations
  913. CalculateUsage.OfflinePrintValue += VoucherFaceValue;
  914. CalculateUsage.OnlinePrintValue += VoucherFaceValue;
  915. if (GetVoucherPrintCountFromLogs(VoucherId) > 1) { //For reprinted vouchers just assume all prints were reprints - log recalculations should be stricter to prevent cheating
  916. CalculateUsage.OfflineReprintValue += VoucherFaceValue;
  917. CalculateUsage.OnlineReprintValue += VoucherFaceValue;
  918. }
  919. }
  920. }
  921. return CalculateUsage;
  922. }
  923. public static void InitialiseUserLimits()
  924. {
  925. Globals.UserCurrentUsage = new UserLimits();
  926. UserLimits CurrentUserLimits = new UserLimits();
  927. string Sql = "SELECT COUNT(*) FROM AccessControlTracking WHERE UserID = @userid";
  928. SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  929. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  930. int Result = int.Parse(Command.ExecuteScalar().ToString());
  931. Sql = "SELECT Date FROM AccessControlTracking WHERE UserID = @userid";
  932. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  933. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  934. object ResultDate = Command.ExecuteScalar();
  935. bool DatePassed = false;
  936. if (ResultDate != null) {
  937. DateTime DateResult = DateTime.Parse(Command.ExecuteScalar().ToString());
  938. if (DateResult.Date < Globals.SessionData.Credentials.Payload.Date.Date) {
  939. DatePassed = true;
  940. }
  941. }
  942. if (DatePassed)
  943. { //Fresh day since last db write or data missing - fetch usage from logs incase of tampering
  944. Globals.UserCurrentUsage = CalculateUsageFromLogs();
  945. SaveCurrentUserUsage(); //Immediately write calculated usage to DB
  946. }
  947. else
  948. {
  949. if (Result == 6)
  950. {
  951. Sql = "SELECT UserID, Permission, CurrentUsage FROM AccessControlTracking WHERE UserID = @userid";
  952. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  953. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  954. using (SQLiteDataReader read = Command.ExecuteReader())
  955. {
  956. while (read.Read())
  957. {
  958. switch (read["Permission"])
  959. {
  960. case "OfflinePrint":
  961. Globals.UserCurrentUsage.OfflinePrintValue = (decimal)read["CurrentUsage"];
  962. break;
  963. case "OfflineReprint":
  964. Globals.UserCurrentUsage.OfflineReprintValue = (decimal)read["CurrentUsage"];
  965. break;
  966. case "OnlinePrint":
  967. Globals.UserCurrentUsage.OnlinePrintValue = (decimal)read["CurrentUsage"];
  968. break;
  969. case "OnlineReprint":
  970. Globals.UserCurrentUsage.OnlineReprintValue = (decimal)read["CurrentUsage"];
  971. break;
  972. case "BulkOrder":
  973. Globals.UserCurrentUsage.BulkOrderValue = (decimal)read["CurrentUsage"];
  974. break;
  975. case "BulkExport":
  976. Globals.UserCurrentUsage.BulkExportValue = (decimal)read["CurrentUsage"];
  977. break;
  978. }
  979. }
  980. }
  981. }
  982. else
  983. {
  984. Globals.UserCurrentUsage = CalculateUsageFromLogs();
  985. SaveCurrentUserUsage(); //Immediately write calculated usage to DB
  986. }
  987. }
  988. }
  989. public static int GetNumberOfUnprintedVouchersInRange(int StartSeqNo, int EndSeqNo, int BatchId) {
  990. int UnprintedVouchers = 0;
  991. int VoucherId;
  992. string Sql;
  993. SQLiteCommand Command;
  994. for (int SeqNo = StartSeqNo; SeqNo <= EndSeqNo; SeqNo++)
  995. {
  996. Sql = "SELECT Id FROM Voucher WHERE SequenceNumber=@sequencenumber AND BatchId=@batchid";
  997. Command = new SQLiteCommand(Sql, Globals.DBConnection);
  998. Command.Parameters.Add(new SQLiteParameter("@sequencenumber", SeqNo));
  999. Command.Parameters.Add(new SQLiteParameter("@batchid", BatchId));
  1000. VoucherId = int.Parse(Command.ExecuteScalar().ToString());
  1001. int NumPrintedVouchers = GetVoucherPrintCountFromLogs(VoucherId);
  1002. if (NumPrintedVouchers == 0) {
  1003. UnprintedVouchers++;
  1004. }
  1005. }
  1006. return UnprintedVouchers;
  1007. }
  1008. public class BulkLogger : IDisposable
  1009. {
  1010. SQLiteTransaction transaction;
  1011. SQLiteCommand logCommand;
  1012. public BulkLogger()
  1013. {
  1014. transaction = Globals.DBConnection.BeginTransaction();
  1015. string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  1016. logCommand = new SQLiteCommand(Sql, Globals.DBConnection);
  1017. logCommand.Transaction = transaction;
  1018. }
  1019. public void LogEvent(VendorEvent.VendorEventType EventType, int? VoucherId = null, bool Retry = false)
  1020. {
  1021. var Command = logCommand;
  1022. if (Command.Parameters.Count == 0)
  1023. {
  1024. Command.Parameters.Add(new SQLiteParameter("@userid", Globals.SessionData.Credentials.Payload.User.Id));
  1025. Command.Parameters.Add(new SQLiteParameter("@voucherid", VoucherId));
  1026. Command.Parameters.Add(new SQLiteParameter("@eventdate", DateTime.UtcNow));
  1027. Command.Parameters.Add(new SQLiteParameter("@eventtype", EventType));
  1028. Command.Parameters.Add(new SQLiteParameter("@retry", Retry));
  1029. }
  1030. else
  1031. {
  1032. Command.Parameters[1].Value = VoucherId;
  1033. Command.Parameters[2].Value = DateTime.UtcNow;
  1034. Command.Parameters[3].Value = EventType;
  1035. Command.Parameters[4].Value = Retry;
  1036. }
  1037. Command.ExecuteNonQuery();
  1038. }
  1039. private void SyncLogs()
  1040. {
  1041. //string Sql = "INSERT INTO Logs (UserId, VoucherId, EventDate, EventType, Retry) VALUES (@userid, @voucherid, @eventdate, @eventtype, @retry)";
  1042. //SQLiteCommand Command = new SQLiteCommand(Sql, Globals.DBConnection);
  1043. if (Globals.SessionMode == SessionModes.Online)
  1044. {
  1045. //if (Globals.LogSyncTask != null && Globals.LogSyncTask.Status == TaskStatus.Running)
  1046. if (Globals.LogSyncRunning)
  1047. {
  1048. Globals.LogSyncWaiting = true;
  1049. return;
  1050. }
  1051. Globals.LogSyncThread = new Thread(() => SyncLogs());
  1052. Globals.LogSyncThread.Start();
  1053. //var Result = await Task.Run(() => SyncLogs()).ConfigureAwait(false);
  1054. }
  1055. }
  1056. #region IDisposable Support
  1057. private bool disposedValue = false; // To detect redundant calls
  1058. protected virtual void Dispose(bool disposing)
  1059. {
  1060. if (!disposedValue)
  1061. {
  1062. if (disposing)
  1063. {
  1064. transaction.Commit();
  1065. logCommand.Dispose();
  1066. SyncLogs();
  1067. }
  1068. // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
  1069. // TODO: set large fields to null.
  1070. disposedValue = true;
  1071. }
  1072. }
  1073. // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
  1074. // ~BulkLogger() {
  1075. // // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
  1076. // Dispose(false);
  1077. // }
  1078. // This code added to correctly implement the disposable pattern.
  1079. public void Dispose()
  1080. {
  1081. // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
  1082. Dispose(true);
  1083. // TODO: uncomment the following line if the finalizer is overridden above.
  1084. // GC.SuppressFinalize(this);
  1085. }
  1086. #endregion
  1087. }
  1088. }
  1089. }