WorkAreaApiController.cs 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599
  1. using GreenPipes.Filters;
  2. using LAPS_XMLQC_Service.App_Data;
  3. using LAPS_XMLQC_Service.Models;
  4. using LAPS_XMLQC_Service.Services;
  5. using MassTransit.Initializers.Variables;
  6. using Microsoft.AspNetCore.Authorization;
  7. using Microsoft.AspNetCore.Mvc;
  8. using Microsoft.CodeAnalysis;
  9. using Microsoft.Extensions.Configuration;
  10. using Microsoft.IdentityModel.Logging;
  11. using Newtonsoft.Json;
  12. using Newtonsoft.Json.Linq;
  13. using Npgsql;
  14. using RabbitMQ.Client.Framing.Impl;
  15. using RabbitMQ.Client.Impl;
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Data;
  19. using System.Diagnostics;
  20. using System.Globalization;
  21. using System.IO;
  22. using System.Linq;
  23. using System.Net.Http;
  24. using System.Net.NetworkInformation;
  25. using System.Reflection.Metadata;
  26. using System.Security.Cryptography;
  27. using System.Security.Principal;
  28. using System.Threading.Tasks;
  29. using System.Transactions;
  30. using System.Xml.Linq;
  31. using static MassTransit.Logging.LogCategoryName;
  32. namespace LAPS_XMLQC_Service.Controllers.WorkArea
  33. {
  34. [Route("api/[controller]")]
  35. [ApiController]
  36. public class WorkAreaApiController : ControllerBase
  37. {
  38. private readonly FileSearchService _fileSearchService;
  39. private readonly IWorkAreaService oWorkAreaService;
  40. private readonly CommonRepository oCommonRepository;
  41. private readonly GrantFolderPermission oGrantFolderPermission;
  42. private readonly string _connectionString;
  43. //public WorkAreaApiController(IConfiguration configuration)
  44. //{
  45. // _connectionString = configuration.GetConnectionString("DbConnection");
  46. //}
  47. public WorkAreaApiController(FileSearchService fileSearchService, IWorkAreaService workAreaService, CommonRepository commonRepository, GrantFolderPermission grantFolderPermission, IConfiguration configuration)
  48. {
  49. _fileSearchService = fileSearchService;
  50. oWorkAreaService = workAreaService;
  51. oCommonRepository = commonRepository;
  52. oGrantFolderPermission = grantFolderPermission;
  53. _connectionString = configuration.GetConnectionString("DbConnection");
  54. }
  55. [Authorize]
  56. [HttpGet("GetServerPath")]
  57. public ActionResult<string> GetServerPath(string tranid)
  58. {
  59. string serverpath = oWorkAreaService.GetServerPath(tranid, false, "serverinfo");
  60. if (!string.IsNullOrEmpty(serverpath))
  61. serverpath = System.IO.Path.Combine(serverpath, "IN");
  62. else
  63. serverpath = string.Empty;
  64. return Ok(serverpath);
  65. }
  66. // [Authorize]
  67. [HttpGet("XmlReviewQC")]
  68. public async Task<IActionResult> XmlReviewQC(string tranid, long jobid, long lotid, bool islot)
  69. {
  70. string xmlserverpath = string.Empty;
  71. string serverpath = string.Empty;
  72. string serverinpath = string.Empty;
  73. long transactionid = 0;
  74. var results = new List<MatchedResult>();
  75. // oGrantFolderPermission.FolderPermission("", "", "", jobid.ToString());
  76. //{
  77. try
  78. {
  79. using (var connection = new NpgsqlConnection(_connectionString))
  80. {
  81. await connection.OpenAsync();
  82. Console.WriteLine("Database connection opened.");
  83. using (var command = new NpgsqlCommand(
  84. "SELECT lt.transactionid, lt.batchid " +
  85. "FROM tbljobmaster jm " +
  86. "JOIN tbljobworkflowdefinition jwm ON jwm.jobid = jm.jobid " +
  87. "JOIN tbllottransaction lt ON jwm.jobworkflowid = lt.jobworkflowid " +
  88. "WHERE jm.jobid = @jobid AND jwm.stagename_alias = 'PDF Analysis' " +
  89. "ORDER BY lt.createdon DESC LIMIT 1;",
  90. connection))
  91. {
  92. command.Parameters.AddWithValue("@jobid", jobid);
  93. // execute reader or scalar here
  94. // command.Parameters.AddWithValue("@lotid", lotid);
  95. Console.WriteLine($"Executing SQL with jobid: {jobid}, lotid: {lotid}");
  96. using (var reader = await command.ExecuteReaderAsync())
  97. {
  98. if (await reader.ReadAsync()) // Use ReadAsync instead of Read
  99. {
  100. transactionid = reader.GetInt64(0); // Read as long instead of string
  101. Console.WriteLine("Transaction ID found: " + transactionid);
  102. }
  103. else
  104. {
  105. Console.WriteLine("No data found for the given jobid and lotid.");
  106. }
  107. }
  108. }
  109. }
  110. if (islot == false)
  111. {
  112. // Use async database operation
  113. if (transactionid != 0)
  114. {
  115. serverpath = oWorkAreaService.GetServerPath(transactionid.ToString(), false, "serverinfo");
  116. Console.WriteLine("Server path retrieved: " + serverpath);
  117. }
  118. else
  119. {
  120. Console.WriteLine("Transaction ID is empty, unable to retrieve server path.");
  121. }
  122. }
  123. else
  124. {
  125. serverpath = oWorkAreaService.GetServerPath(transactionid.ToString(), false, "serverinfo");
  126. }
  127. serverinpath = Path.Combine(serverpath, "IN");
  128. Console.WriteLine("Server IN Path: " + serverinpath);
  129. if (!string.IsNullOrEmpty(serverinpath))
  130. {
  131. oGrantFolderPermission.FolderPermission_vlex(serverinpath, "", "", "", jobid.ToString());
  132. var identity = oGrantFolderPermission.GetImpartunate()?.AllowAccesstoServer();
  133. WindowsIdentity.RunImpersonated(identity.AccessToken, () =>
  134. {
  135. WindowsIdentity useri = WindowsIdentity.GetCurrent();
  136. });
  137. // Offload file system search to another thread asynchronously using Task.Run
  138. //var filePaths = await Task.Run(() => Directory.GetFiles(serverinpath, "*.pdf", SearchOption.AllDirectories));
  139. //results = filePaths.Select(path => new MatchedResult
  140. //{
  141. // FilePath = path
  142. //}).ToList();
  143. var filePaths = await Task.Run(() =>
  144. Directory.GetFiles(serverinpath, "*.pdf", SearchOption.AllDirectories)
  145. .Where(f => !f.EndsWith("_High.pdf", StringComparison.OrdinalIgnoreCase))
  146. );
  147. results = filePaths.Select(path => new MatchedResult
  148. {
  149. FilePath = path
  150. }).ToList();
  151. // var filePaths = await Task.Run(() =>
  152. //Directory.GetFiles(serverinpath, "*.pdf", SearchOption.AllDirectories)
  153. // .Where(f => !f.EndsWith("_High.pdf", StringComparison.OrdinalIgnoreCase))
  154. // .ToArray());
  155. Console.WriteLine($"Found {results.Count} files.");
  156. NetworkShareUtility.DisconnectFromShare(serverinpath);
  157. }
  158. return Ok(results);
  159. }
  160. catch (Exception ex)
  161. {
  162. Console.WriteLine($"Running as: {Environment.UserDomainName}\\{Environment.UserName}");
  163. Console.WriteLine("An error occurred: " + ex.Message);
  164. return StatusCode(500, "Internal Server Error: " + string.Concat(ex.Message, Environment.UserName, Environment.UserDomainName));
  165. }
  166. // }
  167. }
  168. //public async Task<IActionResult> XmlReviewQC(string tranid, long jobid, long lotid, bool islot)
  169. //{
  170. // string xmlserverpath = string.Empty;
  171. // string serverpath = string.Empty;
  172. // string serverinpath = string.Empty;
  173. // long transactionid = 0; // Use long instead of string for bigint column
  174. // var results = new List<MatchedResult>();
  175. // try
  176. // {
  177. // if (islot == false)
  178. // {
  179. // // Open database connection and fetch transaction id
  180. // using (var connection = new NpgsqlConnection(_connectionString))
  181. // {
  182. // connection.Open();
  183. // Console.WriteLine("Database connection opened.");
  184. // using (var command = new NpgsqlCommand(
  185. // "SELECT lt.transactionid FROM tbljobmaster jm " +
  186. // "JOIN tbllotmaster lm ON jm.jobid = lm.jobid " +
  187. // "JOIN tbllottransaction lt ON lm.lotid = lt.lotid " +
  188. // "WHERE jm.jobid = @jobid AND lm.lotid = @lotid ORDER BY jm.createdon desc LIMIT 1", connection))
  189. // {
  190. // // Pass the jobid and lotid as long (Int64)
  191. // command.Parameters.AddWithValue("@jobid", jobid);
  192. // command.Parameters.AddWithValue("@lotid", lotid);
  193. // using (var reader = command.ExecuteReader())
  194. // {
  195. // if (reader.Read())
  196. // {
  197. // transactionid = reader.GetInt64(0); // Read as long instead of string
  198. // Console.WriteLine("Transaction ID found: " + transactionid);
  199. // }
  200. // else
  201. // {
  202. // Console.WriteLine("No data found for the given jobid and lotid.");
  203. // }
  204. // }
  205. // }
  206. // }
  207. // // Check if transactionid is found before proceeding
  208. // if (transactionid != 0)
  209. // {
  210. // // Retrieve server path based on the transaction id
  211. // serverpath = oWorkAreaService.GetServerPath(transactionid.ToString(), false, "serverinfo");
  212. // Console.WriteLine("Server path retrieved successfully.");
  213. // }
  214. // else
  215. // {
  216. // Console.WriteLine("Transaction ID is empty, unable to retrieve server path.");
  217. // }
  218. // }
  219. // else
  220. // {
  221. // // If islot is true, use the provided tranid
  222. // serverpath = oWorkAreaService.GetServerPath(tranid, false, "serverinfo");
  223. // }
  224. // // Construct the path for the "IN" folder
  225. // serverinpath = Path.Combine(serverpath, "IN");
  226. // // Optional permission logic (if applicable)
  227. // // oGrantFolderPermission.FolderPermission("", "", "", jobid);
  228. // // Perform file search if serverpath is valid
  229. // if (!string.IsNullOrEmpty(serverinpath))
  230. // {
  231. // var filePaths = Directory.GetFiles(serverinpath, "*.pdf", SearchOption.AllDirectories);
  232. // results = filePaths.Select(path => new MatchedResult
  233. // {
  234. // FilePath = path // Adjust the property name as per your class
  235. // }).ToList();
  236. // }
  237. // // Return the results as a response
  238. // return Ok(results);
  239. // }
  240. // catch (Exception ex)
  241. // {
  242. // // Log the error and return an internal server error status code
  243. // Console.WriteLine("An error occurred: " + ex.Message);
  244. // return StatusCode(500, "Internal Server Error: " + ex.Message);
  245. // }
  246. //}
  247. // [Authorize]
  248. //[HttpGet("PreviewPdf")]
  249. //public IActionResult PreviewPdf([FromQuery] string path)
  250. //{
  251. // if (string.IsNullOrWhiteSpace(path) || !System.IO.File.Exists(path))
  252. // return NotFound();
  253. // var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
  254. // return File(stream, "application/pdf");
  255. //}
  256. //public async Task<IActionResult> PreviewPdf([FromQuery] string path)
  257. //{
  258. // if (string.IsNullOrWhiteSpace(path))
  259. // return BadRequest("Missing PDF path.");
  260. // // Serve local file
  261. // if (System.IO.File.Exists(path))
  262. // {
  263. // try
  264. // {
  265. // var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
  266. // return File(stream, "application/pdf");
  267. // }
  268. // catch (Exception ex)
  269. // {
  270. // Console.WriteLine($"Local file error: {ex.Message}");
  271. // return StatusCode(500, "Error reading local file.");
  272. // }
  273. // }
  274. // // Try remote download if not a local path
  275. // if (Uri.TryCreate(path, UriKind.Absolute, out Uri? uriResult) && uriResult.Scheme.StartsWith("http"))
  276. // {
  277. // try
  278. // {
  279. // using var httpClient = new HttpClient();
  280. // var response = await httpClient.GetAsync(path);
  281. // if (!response.IsSuccessStatusCode)
  282. // return StatusCode((int)response.StatusCode, "Unable to fetch PDF from URL.");
  283. // var stream = await response.Content.ReadAsStreamAsync();
  284. // return File(stream, "application/pdf");
  285. // }
  286. // catch (Exception ex)
  287. // {
  288. // Console.WriteLine($"Remote fetch error: {ex.Message}");
  289. // return StatusCode(500, "Error fetching remote PDF.");
  290. // }
  291. // }
  292. // return BadRequest("Invalid path or URL.");
  293. //}
  294. [HttpGet("PreviewPdf")]
  295. public async Task<IActionResult> PreviewPdf([FromQuery] string path)
  296. {
  297. if (string.IsNullOrWhiteSpace(path))
  298. return BadRequest("Missing PDF path.");
  299. // Local file case
  300. if (System.IO.File.Exists(path))
  301. {
  302. try
  303. {
  304. var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
  305. var fileName = Path.GetFileName(path);
  306. Response.Headers["Content-Disposition"] = $"inline; filename=\"{fileName}\"";
  307. Response.Headers["Content-Type"] = "application/pdf";
  308. Response.Headers["X-Content-Type-Options"] = "nosniff";
  309. Response.Headers.Remove("X-Frame-Options"); // Optional: allow iframe embedding
  310. return File(stream, "application/pdf");
  311. }
  312. catch (Exception ex)
  313. {
  314. Console.WriteLine($"Local file error: {ex.Message}");
  315. return StatusCode(500, "Error reading local file.");
  316. }
  317. }
  318. // Remote file case
  319. if (Uri.TryCreate(path, UriKind.Absolute, out Uri? uriResult) && uriResult.Scheme.StartsWith("http"))
  320. {
  321. try
  322. {
  323. using var httpClient = new HttpClient();
  324. var response = await httpClient.GetAsync(path);
  325. if (!response.IsSuccessStatusCode)
  326. return StatusCode((int)response.StatusCode, "Unable to fetch PDF from URL.");
  327. var stream = await response.Content.ReadAsStreamAsync();
  328. var fileName = Path.GetFileName(uriResult.LocalPath);
  329. Response.Headers["Content-Disposition"] = $"inline; filename=\"{fileName}\"";
  330. Response.Headers["Content-Type"] = "application/pdf";
  331. Response.Headers["X-Content-Type-Options"] = "nosniff";
  332. Response.Headers.Remove("X-Frame-Options");
  333. return File(stream, "application/pdf");
  334. }
  335. catch (Exception ex)
  336. {
  337. Console.WriteLine($"Remote fetch error: {ex.Message}");
  338. return StatusCode(500, "Error fetching remote PDF.");
  339. }
  340. }
  341. return BadRequest("Invalid path or URL.");
  342. }
  343. //public async Task<IActionResult> PreviewPdf([FromQuery] string path)
  344. //{
  345. // if (!Uri.TryCreate(path, UriKind.Absolute, out Uri? uriResult))
  346. // return BadRequest("Invalid URL.");
  347. // // Create a temporary file
  348. // var tempFile = Path.Combine(Path.GetTempPath(), Path.GetFileName(uriResult.LocalPath));
  349. // using (var httpClient = new HttpClient())
  350. // using (var response = await httpClient.GetAsync(path, HttpCompletionOption.ResponseHeadersRead))
  351. // {
  352. // if (!response.IsSuccessStatusCode)
  353. // return StatusCode((int)response.StatusCode, "Unable to fetch remote PDF.");
  354. // using (var fs = new FileStream(tempFile, FileMode.Create, FileAccess.Write))
  355. // {
  356. // await response.Content.CopyToAsync(fs);
  357. // }
  358. // }
  359. // // Serve the file with range support
  360. // return PhysicalFile(tempFile, "application/pdf", Path.GetFileName(tempFile), enableRangeProcessing: true);
  361. //}
  362. //public async Task<IActionResult> PreviewPdf([FromQuery] string path)
  363. //{
  364. // if (string.IsNullOrWhiteSpace(path))
  365. // return BadRequest("Missing PDF path.");
  366. // // Local file case
  367. // if (System.IO.File.Exists(path))
  368. // {
  369. // try
  370. // {
  371. // var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
  372. // var fileName = Path.GetFileName(path);
  373. // Response.Headers["Content-Disposition"] = $"inline; filename=\"{fileName}\"";
  374. // Response.Headers["Content-Type"] = "application/pdf";
  375. // Response.Headers["X-Content-Type-Options"] = "nosniff";
  376. // Response.Headers.Remove("X-Frame-Options"); // Optional: allow iframe embedding
  377. // return File(stream, "application/pdf");
  378. // }
  379. // catch (Exception ex)
  380. // {
  381. // Console.WriteLine($"Local file error: {ex.Message}");
  382. // return StatusCode(500, "Error reading local file.");
  383. // }
  384. // }
  385. // // Remote file case
  386. // if (Uri.TryCreate(path, UriKind.Absolute, out Uri? uriResult) && uriResult.Scheme.StartsWith("http"))
  387. // {
  388. // try
  389. // {
  390. // using var httpClient = new HttpClient();
  391. // var response = await httpClient.GetAsync(path);
  392. // if (!response.IsSuccessStatusCode)
  393. // return StatusCode((int)response.StatusCode, "Unable to fetch PDF from URL.");
  394. // var stream = await response.Content.ReadAsStreamAsync();
  395. // var fileName = Path.GetFileName(uriResult.LocalPath);
  396. // Response.Headers["Content-Disposition"] = $"inline; filename=\"{fileName}\"";
  397. // Response.Headers["Content-Type"] = "application/pdf";
  398. // Response.Headers["X-Content-Type-Options"] = "nosniff";
  399. // Response.Headers.Remove("X-Frame-Options");
  400. // return File(stream, "application/pdf");
  401. // }
  402. // catch (Exception ex)
  403. // {
  404. // Console.WriteLine($"Remote fetch error: {ex.Message}");
  405. // return StatusCode(500, "Error fetching remote PDF.");
  406. // }
  407. // }
  408. // return BadRequest("Invalid path or URL.");
  409. //}
  410. //[HttpGet("PreviewPdf")]
  411. //public IActionResult PreviewPdf([FromQuery] string path)
  412. //{
  413. // if (string.IsNullOrEmpty(path))
  414. // return BadRequest("Path is required.");
  415. // var baseFolder = @"\\172.20.254.139\files_internal_laps\ROOT_UAT\LNBPM\150\2547";
  416. // // Normalize and validate the requested path
  417. // var fullPath = Path.GetFullPath(path);
  418. // //if (!fullPath.StartsWith(baseFolder, StringComparison.OrdinalIgnoreCase))
  419. // //{
  420. // // return BadRequest("Invalid path.");
  421. // //}
  422. // if (!System.IO.File.Exists(fullPath))
  423. // {
  424. // return NotFound();
  425. // }
  426. // var fileBytes = System.IO.File.ReadAllBytes(fullPath);
  427. // var fileName = Path.GetFileName(fullPath);
  428. // return File(fileBytes, "application/pdf", fileName);
  429. //}
  430. // [Authorize]
  431. [HttpGet("GetLotTitles")]
  432. public IActionResult GetLotTitles(long jobid)
  433. {
  434. var titles = new List<LotTitleDto>();
  435. string imgTitle = null;
  436. using (var connection = new NpgsqlConnection(_connectionString))
  437. {
  438. connection.Open();
  439. using (var command = new NpgsqlCommand(
  440. "SELECT lm.title, lm.lotid, tlp.mainpagerange, tlp.supplementrypagerange, lm.totalunits " +
  441. "FROM tbljobmaster jm " +
  442. "JOIN tbllotmaster lm ON jm.jobid = lm.jobid " +
  443. "JOIN tbllotpagedetails tlp ON lm.lotid = tlp.lotid " +
  444. "WHERE jm.jobid = @jobid order by lm.lotid", connection))
  445. {
  446. command.Parameters.AddWithValue("@jobid", jobid);
  447. using (var reader = command.ExecuteReader())
  448. {
  449. while (reader.Read())
  450. {
  451. var title = reader.IsDBNull(0) ? null : reader.GetString(0); // Handle null for title (string)
  452. var lotid = reader.IsDBNull(1) ? 0 : reader.GetInt32(1); // Handle null for lotid (int)
  453. var mainpagerange = reader.IsDBNull(2) ? string.Empty : reader.GetString(2); // Handle null for mainpagerange (string)
  454. var supplementrypagerange = reader.IsDBNull(3) ? string.Empty : reader.GetString(3); // Handle null for supplementrypagerange (string)
  455. var totalunits = reader.IsDBNull(4) ? 0 : reader.GetInt32(4); // Handle null for totalunits (int)
  456. // Determine if the title ends with '-img'
  457. imgTitle = !string.IsNullOrEmpty(title) && title.EndsWith("-img", StringComparison.OrdinalIgnoreCase) ? "1" : "0";
  458. // Add all the fields to the LotTitleDto object
  459. var lotTitleDto = new LotTitleDto
  460. {
  461. Title = title ?? string.Empty, // Default to empty if null
  462. lotid = lotid,
  463. mainpagerange = mainpagerange, // Assuming it's a string, not converting to ToString()
  464. supplementrypagerange = supplementrypagerange, // Same here
  465. ImgTitle = imgTitle,
  466. DefaultDocType = 1 // Assuming DefaultDocType is always 1
  467. };
  468. titles.Add(lotTitleDto);
  469. }
  470. }
  471. }
  472. }
  473. // Log the data to inspect it (if you're debugging)
  474. Console.WriteLine($"Returned Titles: {titles.Count} rows");
  475. foreach (var title in titles)
  476. {
  477. Console.WriteLine($"Title: {title.Title}, Lotid: {title.lotid}, ImgTitle: {title.ImgTitle}");
  478. }
  479. return Ok(titles); // Return the list of titles
  480. }
  481. //public IActionResult GetLotTitles(long jobid)
  482. //{
  483. // var titles = new List<LotTitleDto>();
  484. // using (var connection = new NpgsqlConnection(_connectionString))
  485. // {
  486. // connection.Open();
  487. // using (var command = new NpgsqlCommand(
  488. // "SELECT lm.title,lm.lotid, lm.totalunits " +
  489. // "FROM tbljobmaster jm " +
  490. // "JOIN tbllotmaster lm ON jm.jobid = lm.jobid " +
  491. // "WHERE jm.jobid = @jobid", connection))
  492. // {
  493. // command.Parameters.AddWithValue("@jobid", jobid); // Now jobid is long
  494. // using (var reader = command.ExecuteReader())
  495. // {
  496. // while (reader.Read())
  497. // {
  498. // titles.Add(new LotTitleDto
  499. // {
  500. // Title = reader.GetString(0),
  501. // lotid = reader.GetInt32(1),
  502. // TotalUnits = reader.GetInt32(2)
  503. // });
  504. // }
  505. // }
  506. // }
  507. // }
  508. // return Ok(titles);
  509. //}
  510. [Authorize]
  511. [HttpPost("usrstagemove")]
  512. public IActionResult usrstagemove([FromBody] lottraninfo data)
  513. {
  514. try
  515. {
  516. var _list = oWorkAreaService.usrstagemove(data);
  517. return Ok(_list);
  518. }
  519. catch (Exception ex)
  520. {
  521. return BadRequest(new { message = ex.Message });
  522. }
  523. }
  524. [Authorize]
  525. [HttpPost("getJobDetails")]
  526. public IActionResult getJobDetails([FromBody] object data)
  527. {
  528. var _list = oWorkAreaService.getJobDetails(data);
  529. return Ok(_list);
  530. }
  531. // [Authorize]
  532. [HttpGet("GetAllFilesForDownload")]
  533. public List<FileDetails> GetAllFilesForDownload(int jobid, int tranid)
  534. {
  535. List<FileDetails> AllFiles = new List<FileDetails>();
  536. oGrantFolderPermission.FolderPermission("", "", "", tranid.ToString());
  537. string serverpath = oWorkAreaService.GetServerPath(tranid.ToString(), false, "serverinfo");
  538. serverpath = Path.Combine(serverpath, "IN");
  539. var filetype = oWorkAreaService.getFileTypeInput(tranid.ToString());
  540. var jsonList = new List<string>();
  541. string[] inputfiles;
  542. //if (filetype != null)
  543. //{
  544. // var i_filetype = JsonConvert.DeserializeObject<object>(filetype.ToString());
  545. // JArray a_filetype = JArray.Parse(i_filetype.ToString());
  546. // foreach (var a in a_filetype)
  547. // {
  548. // JObject obj_filetype = JObject.Parse(a.ToString());
  549. // jsonList.Add(obj_filetype["filetype"].ToString().ToLower());
  550. // }
  551. //}
  552. if (jsonList.Count() == 1 && jsonList[0].ToString().Contains(".*"))
  553. {
  554. inputfiles = Directory.GetFiles(serverpath, "*.*", SearchOption.AllDirectories).ToArray();
  555. }
  556. else
  557. {
  558. inputfiles = Directory.GetFiles(serverpath, "*.*", SearchOption.TopDirectoryOnly).Where(x => jsonList.Contains(Path.GetExtension(x.ToString()).ToLower())).ToArray();
  559. if (inputfiles.Length == 0)
  560. {
  561. inputfiles = Directory.GetFiles(serverpath, "*.*", SearchOption.AllDirectories).ToArray();
  562. }
  563. }
  564. foreach (var item in inputfiles)
  565. {
  566. FileDetails filedetails = new FileDetails();
  567. filedetails.FileName = Path.GetFileName(item);
  568. filedetails.FilePath = item;
  569. AllFiles.Add(filedetails);
  570. }
  571. return AllFiles;
  572. }
  573. // [Authorize]
  574. [HttpGet("GetAllOutputFiles")]
  575. public List<FileDetails> GetAllOutputFiles(int jobid, int tranid)
  576. {
  577. List<FileDetails> AllFiles = new List<FileDetails>();
  578. oGrantFolderPermission.FolderPermission("", "", "", tranid.ToString());
  579. string serverpath = oWorkAreaService.GetServerPath(tranid.ToString(), false, "serverinfo");
  580. serverpath = Path.Combine(serverpath, "OUT");
  581. string[] outputfiles = null;
  582. if (Directory.Exists(serverpath))
  583. {
  584. outputfiles = Directory.GetFiles(serverpath, "*.*", SearchOption.AllDirectories);
  585. }
  586. else
  587. {
  588. AllFiles = null;
  589. }
  590. if (outputfiles.Length == 0)
  591. {
  592. outputfiles = Directory.GetFiles(serverpath, "*.*", SearchOption.AllDirectories);
  593. }
  594. foreach (var item in outputfiles)
  595. {
  596. FileDetails filedetails = new FileDetails();
  597. filedetails.FileName = Path.GetFileName(item);
  598. filedetails.FilePath = item;
  599. AllFiles.Add(filedetails);
  600. }
  601. return AllFiles;
  602. }
  603. //[Authorize]
  604. [HttpPost("DownloadSingleFile")]
  605. public IActionResult DownloadSingleFile([FromBody] filedownload fileData)
  606. {
  607. try
  608. {
  609. string filePath = fileData.path;
  610. string tranid = fileData.jobid.ToString();
  611. // 1️⃣ Validate file path
  612. if (string.IsNullOrWhiteSpace(filePath))
  613. return BadRequest("File path is required.");
  614. // 2️⃣ Grant folder permission using your existing method
  615. oGrantFolderPermission.FolderPermission("", "", "", tranid);
  616. // 3️⃣ Check if file exists
  617. if (!System.IO.File.Exists(filePath))
  618. return NotFound("File not found on server.");
  619. // 4️⃣ Open file as stream for large-file support
  620. var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
  621. // 5️⃣ Detect MIME type
  622. string contentType = "application/octet-stream";
  623. var provider = new Microsoft.AspNetCore.StaticFiles.FileExtensionContentTypeProvider();
  624. provider.TryGetContentType(filePath, out contentType);
  625. string fileName = Path.GetFileName(filePath);
  626. // 6️⃣ Return file as FileStreamResult
  627. return File(stream, contentType, fileName);
  628. }
  629. catch (Exception ex)
  630. {
  631. // 7️⃣ Log the error
  632. var data_input = new
  633. {
  634. errormessage = "Error: " + ex.Message,
  635. createdby = 0,
  636. controller = "UploaderApi: Downloader"
  637. };
  638. // oCommonRepository.addlog(data_input, "errorlog");
  639. return StatusCode(500, "An error occurred while downloading the file: " + ex.Message);
  640. }
  641. }
  642. // [Authorize]
  643. [HttpPost("DownloadInOutFiles")]
  644. public IActionResult DownloadInOutFiles(filedownload fileData)
  645. {
  646. try
  647. {
  648. string jobid = fileData.jobid.ToString();
  649. string tranid = fileData.tranid.ToString();
  650. string pdid = fileData.pdid.ToString();
  651. string option = fileData.option.ToString();
  652. string jobtitle = fileData.jobtitle.ToString();
  653. string serverpath;
  654. serverpath = oWorkAreaService.GetServerPath(tranid, false, "serverinfo");
  655. serverpath = Path.Combine(serverpath, option);
  656. string zipname = string.Empty;
  657. if (option.IndexOf("IN") != -1 || option.IndexOf("OUT") != -1)
  658. {
  659. zipname = jobtitle + "_" + tranid + "_" + option + ".zip";
  660. }
  661. else
  662. {
  663. zipname = jobtitle + "_" + tranid + ".zip";
  664. }
  665. string[] inputfiles = Directory.GetFiles(serverpath, "*.*", SearchOption.TopDirectoryOnly).ToArray();
  666. byte[] fileBytes = null;
  667. using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
  668. {
  669. using (System.IO.Compression.ZipArchive zip = new System.IO.Compression.ZipArchive(memoryStream, System.IO.Compression.ZipArchiveMode.Create, true))
  670. {
  671. foreach (string f in inputfiles)
  672. {
  673. // add the item name to the zip
  674. System.IO.Compression.ZipArchiveEntry zipItem = zip.CreateEntry(Path.GetFileName(f) + "." + Path.GetExtension(f));
  675. // add the item bytes to the zip entry by opening the original file and copying the bytes
  676. using (System.IO.MemoryStream originalFileMemoryStream = new System.IO.MemoryStream(System.IO.File.ReadAllBytes(f)))
  677. {
  678. using (System.IO.Stream entryStream = zipItem.Open())
  679. {
  680. originalFileMemoryStream.CopyTo(entryStream);
  681. }
  682. }
  683. }
  684. }
  685. fileBytes = memoryStream.ToArray();
  686. return Ok(new { File = fileBytes });
  687. // return Ok(new { File = File(fileBytes, "application/zip", zipname) });
  688. }
  689. }
  690. catch (Exception ex)
  691. {
  692. var data_input = new
  693. {
  694. errormessage = "Error: " + ex.Message,
  695. createdby = 0,
  696. controller = "UploaderApi: Downloader"
  697. };
  698. // oCommonRepository.addlog(data_input, "errorlog");
  699. return BadRequest(new { message = "File notfound" });
  700. }
  701. }
  702. // [Authorize]
  703. [HttpPost("DownloadSingleOutFile")]
  704. public IActionResult DownloadSingleOutFile(filedownload fileData)
  705. {
  706. try
  707. {
  708. string type = fileData.type.ToString();
  709. string path = fileData.path.ToString();
  710. string jobid = fileData.jobid.ToString();
  711. byte[] fileBytes = null;
  712. oGrantFolderPermission.FolderPermission_vlex("", "", "", jobid.ToString());
  713. fileBytes = System.IO.File.ReadAllBytes(path);
  714. string fileName = Path.GetFileName(path);
  715. return Ok(new { File = fileBytes });
  716. }
  717. catch (Exception ex)
  718. {
  719. var data_input = new
  720. {
  721. errormessage = "Error: " + ex.Message,
  722. createdby = 0,
  723. controller = "UploaderApi: Downloader"
  724. };
  725. //oCommonRepository.addlog(data_input, "errorlog");
  726. throw;
  727. }
  728. }
  729. // [Authorize]
  730. [HttpPost("RemoveIOFiles")]
  731. public object RemoveIOFiles(filedownload fileData)
  732. {
  733. string path = fileData.path.ToString();
  734. string jobid = fileData.jobid.ToString();
  735. try
  736. {
  737. oGrantFolderPermission.FolderPermission("", "", "", jobid.ToString());
  738. System.IO.File.Delete(path);
  739. var json = new { result = true, filename = Path.GetFileName(path) };
  740. return json;
  741. }
  742. catch (Exception ex)
  743. {
  744. var data_input = new
  745. {
  746. errormessage = "Error: " + ex.Message,
  747. createdby = 0,
  748. controller = "UploaderApi: Downloader"
  749. };
  750. // oCommonRepository.addlog(data_input, "errorlog");
  751. var json = new { result = false, filename = Path.GetFileName(path) };
  752. return json;
  753. }
  754. }
  755. // [Authorize]
  756. [HttpGet("GetAllOutFilesForDownload")]
  757. public List<FileDetails> GetAllOutFilesForDownload(int jobid, int tranid)
  758. {
  759. List<FileDetails> AllFiles = new List<FileDetails>();
  760. string serverpath = oWorkAreaService.GetServerPath(tranid.ToString(), false, "serverinfo");
  761. serverpath = Path.Combine(serverpath, "OUT");
  762. var filetype = oWorkAreaService.getFileTypeOutput(tranid.ToString());
  763. var jsonList = new List<string>();
  764. if (filetype != null)
  765. {
  766. var i_filetype = JsonConvert.DeserializeObject<object>(filetype.ToString());
  767. JArray a_filetype = JArray.Parse(i_filetype.ToString());
  768. foreach (var a in a_filetype)
  769. {
  770. JObject obj_filetype = JObject.Parse(a.ToString());
  771. jsonList.Add(obj_filetype["filetype"].ToString().ToLower());
  772. }
  773. }
  774. string[] inputfiles = Directory.GetFiles(serverpath, "*.*", SearchOption.TopDirectoryOnly)
  775. .Where(x => jsonList.Contains(Path.GetExtension(x.ToString()).ToLower())).ToArray();
  776. if (inputfiles.Length == 0)
  777. {
  778. inputfiles = Directory.GetFiles(serverpath, "*.*", SearchOption.AllDirectories)
  779. .Where(x => jsonList.Contains(Path.GetExtension(x.ToString()).ToLower())).ToArray();
  780. }
  781. foreach (var item in inputfiles)
  782. {
  783. FileDetails filedetails = new FileDetails();
  784. filedetails.FileName = Path.GetFileName(item);
  785. filedetails.FilePath = item;
  786. AllFiles.Add(filedetails);
  787. }
  788. return AllFiles;
  789. }
  790. [Authorize]
  791. [HttpPost("InsertPageDetails")]
  792. public async Task<IActionResult> InsertPageDetails([FromBody] PageDetailDto dto)
  793. {
  794. // If you expect file uploads, use IFormFile
  795. // If you're sending a file as part of FormData
  796. // public IFormFile File { get; set; }
  797. await using var conn = new NpgsqlConnection(_connectionString);
  798. await conn.OpenAsync();
  799. try
  800. {
  801. using (var cmd = new NpgsqlCommand("SELECT upsert_lotpagedetails(@jobid, @lotid, @maincount, @doctype,@updatedby ,@mode)", conn))
  802. {
  803. cmd.Parameters.AddWithValue("jobid", dto.JobId);
  804. cmd.Parameters.AddWithValue("lotid", dto.LotId);
  805. cmd.Parameters.AddWithValue("maincount", dto.MainPage);
  806. // cmd.Parameters.AddWithValue("supplementcount", dto.SupplementPage);
  807. cmd.Parameters.AddWithValue("doctype", dto.DocType);
  808. cmd.Parameters.AddWithValue("updatedby", dto.UpdatedBy);
  809. cmd.Parameters.AddWithValue("mode", dto.Mode); // Add this to match the new SP signature
  810. // Add this to match the new SP signature
  811. // Execute and get the returned lotid
  812. var result = cmd.ExecuteScalar();
  813. int returnedLotId = result != null ? Convert.ToInt32(result) : 0;
  814. return Ok(new { InsertedLotId = result });
  815. }
  816. }
  817. catch (Exception Ex)
  818. {
  819. throw;
  820. }
  821. }
  822. [HttpGet("getreporterkey")]
  823. public IActionResult GetReporterKey(int jobid, string jobtitle)
  824. {
  825. if (string.IsNullOrWhiteSpace(jobtitle))
  826. return BadRequest(new { message = "Job title is required." });
  827. try
  828. {
  829. // Extract reporter key (everything before "__")
  830. int secondUnderscore = jobtitle.IndexOf("_", jobtitle.IndexOf("_") + 1);
  831. string reporterKey = secondUnderscore != -1
  832. ? jobtitle.Substring(0, secondUnderscore + 1)
  833. : jobtitle;
  834. // 🔹 if it ends with "__", trim one underscore
  835. if (reporterKey.EndsWith("__"))
  836. reporterKey = reporterKey.TrimEnd('_') + "_";
  837. int? reporterId = null;
  838. using (var conn = new NpgsqlConnection(_connectionString))
  839. {
  840. conn.Open();
  841. using (var cmd = new NpgsqlCommand(@"
  842. SELECT reporterid
  843. FROM tblvlexreporterkey
  844. WHERE reporter_key = @rkey
  845. LIMIT 1;", conn))
  846. {
  847. cmd.Parameters.AddWithValue("@rkey", reporterKey);
  848. var result = cmd.ExecuteScalar();
  849. if (result != null && result != DBNull.Value)
  850. reporterId = Convert.ToInt32(result);
  851. }
  852. }
  853. if (!reporterId.HasValue)
  854. return NotFound(new { message = $"No reporter found for key '{reporterKey}'." });
  855. return Ok(new { reporterId = reporterId.Value });
  856. }
  857. catch (Exception ex)
  858. {
  859. return StatusCode(500, new { error = "An error occurred while fetching reporter key.", details = ex.Message });
  860. }
  861. }
  862. [Authorize]
  863. [HttpGet("getxmlfile")]
  864. public IActionResult getxmlfile(string tranid, string lotid, string userid)
  865. {
  866. if (string.IsNullOrWhiteSpace(tranid))
  867. return BadRequest("tranid is required.");
  868. oGrantFolderPermission.FolderPermission("", "", "", tranid.ToString());
  869. // Validate lotid before using it in query
  870. if (!long.TryParse(lotid, out long lotIdNumeric))
  871. return BadRequest("Invalid lotid format. It must be a numeric value.");
  872. // Validate and convert userid to int
  873. if (!int.TryParse(userid, out int userIdNumeric))
  874. return BadRequest("Invalid userid format. It must be an integer.");
  875. using var conn = new NpgsqlConnection(_connectionString);
  876. conn.OpenAsync();
  877. string serverpath = oWorkAreaService.GetServerPath(tranid, false, "serverinfo");
  878. serverpath = Path.Combine(serverpath, "OUT");
  879. // 1. Locate file
  880. string filePath = Path.Combine(serverpath, "pageinfo.xml");
  881. if (!System.IO.File.Exists(filePath))
  882. return NotFound("File not found for given tranid.");
  883. try
  884. {
  885. // 2. Read XML
  886. string xmlContent = System.IO.File.ReadAllText(filePath);
  887. var doc = XDocument.Parse(xmlContent);
  888. var files = doc.Descendants("file");
  889. foreach (var file in files)
  890. {
  891. string fileName = file.Attribute("name")?.Value ?? "unknown";
  892. string main = file.Element("main")?.Value ?? "";
  893. string supp = file.Element("supp")?.Value ?? "";
  894. using (var cmd = new NpgsqlCommand("UPDATE tbllotpagedetails SET supplementrypagerange=@supprange, mainpagerange=@mainrange, updatedby=@updatedby, updatedon=NOW() WHERE lotid=@lotid", conn))
  895. {
  896. cmd.Parameters.AddWithValue("supprange", supp);
  897. cmd.Parameters.AddWithValue("mainrange", main);
  898. cmd.Parameters.AddWithValue("updatedby", userIdNumeric); // Convert userid to int
  899. cmd.Parameters.AddWithValue("lotid", lotIdNumeric);
  900. // Execute the update
  901. var result = cmd.ExecuteScalar();
  902. int returnedLotId = result != null ? Convert.ToInt32(result) : 0;
  903. }
  904. }
  905. return Ok("XML processed and values saved to database.");
  906. }
  907. catch (Exception ex)
  908. {
  909. return StatusCode(500, $"Error processing XML: {ex.Message}");
  910. }
  911. }
  912. [HttpPost("SaveLots")]
  913. public IActionResult SaveLots([FromBody] List<LotDto> lots)
  914. {
  915. if (lots == null || lots.Count == 0)
  916. return BadRequest("No lots provided.");
  917. int jobId = lots[0].jobid;
  918. long ocrtranid = 0;
  919. int lastTransactionId = 0;
  920. bool firstLotUpdated = false;
  921. string serverPathIn = string.Empty;
  922. int batchId = 0;
  923. long nextTransactionId = 0;
  924. try
  925. {
  926. using (var conn = new NpgsqlConnection(_connectionString))
  927. {
  928. conn.Open();
  929. // 1️⃣ Get last transaction ID for PDF Analysis
  930. using (var command = new NpgsqlCommand(@"
  931. SELECT lt.transactionid, lt.batchid
  932. FROM tbljobmaster jm
  933. JOIN tbljobworkflowdefinition jwm ON jwm.jobid = jm.jobid
  934. JOIN tbllottransaction lt ON jwm.jobworkflowid = lt.jobworkflowid
  935. WHERE jm.jobid = @jobid AND jwm.stagename_alias = 'PDF Analysis'
  936. ORDER BY lt.createdon DESC
  937. LIMIT 1", conn))
  938. {
  939. command.Parameters.AddWithValue("@jobid", jobId);
  940. using (var reader = command.ExecuteReader())
  941. {
  942. if (reader.Read())
  943. {
  944. lastTransactionId = reader.GetInt32(0);
  945. batchId = reader.GetInt32(1);
  946. }
  947. }
  948. }
  949. string pdfAnalysisServerPath = oWorkAreaService.GetServerPath(lastTransactionId.ToString(), false, "serverinfo");
  950. // 🔹 Collect ALL split files from all lots
  951. List<string> allSplitFiles = new List<string>();
  952. // 2️⃣ Process each lot
  953. foreach (var lot in lots)
  954. {
  955. int lotId = 0;
  956. Guid lotKey = Guid.NewGuid();
  957. int latestSequence = -1;
  958. // 🔹 Check existing lots
  959. int latestLotId = 0;
  960. Guid latestLotKey = Guid.Empty;
  961. using (var cmdCheck = new NpgsqlCommand(@"
  962. SELECT lotid, sequence, lotkey
  963. FROM tbllotmaster
  964. WHERE jobid = @jobid
  965. ORDER BY sequence DESC
  966. LIMIT 1;", conn))
  967. {
  968. cmdCheck.Parameters.AddWithValue("@jobid", jobId);
  969. using (var reader = cmdCheck.ExecuteReader())
  970. {
  971. if (reader.Read())
  972. {
  973. latestLotId = reader.GetInt32(0);
  974. latestSequence = reader.GetInt32(1);
  975. latestLotKey = reader.GetGuid(2);
  976. }
  977. }
  978. }
  979. using (var tran = conn.BeginTransaction())
  980. {
  981. if (latestLotId > 0 && !firstLotUpdated)
  982. {
  983. // ✅ Update the first lot only once
  984. firstLotUpdated = true;
  985. lotId = latestLotId;
  986. lotKey = latestLotKey;
  987. using (var cmdUpdate = new NpgsqlCommand(@"
  988. UPDATE tbllotmaster
  989. SET title = @title, filename = @filename, updatedon = @updatedon
  990. WHERE jobid = @jobid AND lotid = @lotid;", conn, tran))
  991. {
  992. string lotNameTitle = $"{lot.Volume} {lot.Edition} {lot.Printpage}";
  993. cmdUpdate.Parameters.AddWithValue("@title", lotNameTitle);
  994. cmdUpdate.Parameters.AddWithValue("@filename", lotNameTitle + ".pdf");
  995. cmdUpdate.Parameters.AddWithValue("@updatedon", DateTime.Now);
  996. cmdUpdate.Parameters.AddWithValue("@jobid", jobId);
  997. cmdUpdate.Parameters.AddWithValue("@lotid", lotId);
  998. cmdUpdate.ExecuteNonQuery();
  999. }
  1000. }
  1001. else
  1002. {
  1003. // ✅ Insert new lot
  1004. int nextSequence = (latestSequence >= 0 ? latestSequence + 1 : 0);
  1005. lotKey = Guid.NewGuid();
  1006. using (var cmdInsertLot = new NpgsqlCommand("insert_lot_details", conn, tran))
  1007. {
  1008. cmdInsertLot.CommandType = CommandType.StoredProcedure;
  1009. cmdInsertLot.Parameters.AddWithValue("p_jobid", jobId);
  1010. string lotNameTitle = $"{lot.Volume} {lot.Edition} {lot.Printpage}";
  1011. cmdInsertLot.Parameters.AddWithValue("p_title", lotNameTitle);
  1012. cmdInsertLot.Parameters.AddWithValue("p_sequence", nextSequence);
  1013. cmdInsertLot.Parameters.AddWithValue("p_lotkey", lotKey);
  1014. cmdInsertLot.Parameters.AddWithValue("p_filename", lotNameTitle + ".pdf");
  1015. lotId = Convert.ToInt32(cmdInsertLot.ExecuteScalar());
  1016. }
  1017. }
  1018. // ✅ Insert transaction (common for both update/insert)
  1019. nextTransactionId = InsertLotTransaction(conn, tran, lotId, lotKey);
  1020. using (var cmdUpdate = new NpgsqlCommand(@"
  1021. UPDATE tbllottransaction
  1022. SET lotstatus = @lotstatus, pickedby = @pickedby
  1023. WHERE transactionid = @transactionid;", conn, tran))
  1024. {
  1025. cmdUpdate.Parameters.AddWithValue("@lotstatus", "C");
  1026. cmdUpdate.Parameters.AddWithValue("@pickedby", 0);
  1027. cmdUpdate.Parameters.AddWithValue("@transactionid", nextTransactionId);
  1028. cmdUpdate.ExecuteNonQuery();
  1029. }
  1030. tran.Commit();
  1031. }
  1032. // 3️⃣ Create server paths
  1033. string serverPath = oWorkAreaService.GetServerPath(nextTransactionId.ToString(), false, "serverinfo")
  1034. ?? throw new Exception("Server path not found");
  1035. if (!Directory.Exists(serverPath)) Directory.CreateDirectory(serverPath);
  1036. oGrantFolderPermission.FolderPermission_vlex(serverPath, "", "", "", jobId.ToString());
  1037. WindowsIdentity newId = oGrantFolderPermission.GetImpartunate().AllowAccesstoServer();
  1038. WindowsIdentity.RunImpersonated(newId.AccessToken, () =>
  1039. {
  1040. WindowsIdentity useri = WindowsIdentity.GetCurrent();
  1041. });
  1042. serverPathIn = Path.Combine(serverPath, "IN");
  1043. string serverPathOut = Path.Combine(serverPath, "OUT");
  1044. string pdfAnalysisServerPathIn = Path.Combine(pdfAnalysisServerPath ?? throw new Exception("PDF Analysis path not found"), "IN");
  1045. Directory.CreateDirectory(serverPathIn);
  1046. Directory.CreateDirectory(serverPathOut);
  1047. Appsettings High_appset = new Appsettings();
  1048. //var pdfFiles = Directory.GetFiles(pdfAnalysisServerPathIn, "*.pdf");
  1049. var pdfFiles = Directory.GetFiles(pdfAnalysisServerPathIn, "*.pdf", SearchOption.TopDirectoryOnly)
  1050. .Where(f => Path.GetFileName(f)
  1051. .EndsWith("_High"+ ".pdf", StringComparison.OrdinalIgnoreCase))
  1052. .ToArray();
  1053. if (pdfFiles.Length == 0)
  1054. throw new FileNotFoundException("No PDF files found in PDF Analysis path.");
  1055. string pdfFile = pdfFiles[0];
  1056. // 4️⃣ Run splitter
  1057. RunSplitterExe(serverPathIn, pdfFile, lot.Range, jobId.ToString());
  1058. // 🔹 Collect split files
  1059. string splitterOutputFolder = Path.Combine(serverPathIn, "splitter_files");
  1060. if (!Directory.Exists(splitterOutputFolder))
  1061. throw new DirectoryNotFoundException("Splitter output folder not found: " + splitterOutputFolder);
  1062. var splitFiles = Directory.GetFiles(splitterOutputFolder, "*.pdf");
  1063. if (splitFiles.Length == 0)
  1064. throw new FileNotFoundException("No split PDF files found in splitter output folder.");
  1065. // 🔹 Rename split files with lot prefix
  1066. foreach (var file in splitFiles)
  1067. {
  1068. string fileNameOnly = Path.GetFileName(file);
  1069. string newFileName = $"{lot.Volume} {lot.Edition} {lot.Printpage}";
  1070. newFileName= string.Concat(newFileName, ".pdf");
  1071. string newFilePath = Path.Combine(splitterOutputFolder, newFileName);
  1072. if (System.IO.File.Exists(newFilePath))
  1073. System.IO.File.Delete(newFilePath);
  1074. System.IO.File.Move(file, newFilePath);
  1075. }
  1076. // 🔹 Add renamed files to list for OCR
  1077. allSplitFiles.AddRange(Directory.GetFiles(splitterOutputFolder, "*.pdf"));
  1078. // 5️⃣ Insert Vlex Report
  1079. long reportId = InsertVlexReport(conn, jobId,
  1080. lotId, lot.Report, lot.Volume, lot.Edition, lot.Issue, lot.Printpage,
  1081. lot.createadby, 1);
  1082. }
  1083. // 🔹 OCR Transaction only once after all lots
  1084. using (var tran = conn.BeginTransaction())
  1085. {
  1086. ocrtranid = InsertLotTransactionocr(conn, tran, batchId);
  1087. tran.Commit();
  1088. }
  1089. // 🔹 Create OCR paths
  1090. string serverocrPath = oWorkAreaService.GetServerPath(ocrtranid.ToString(), false, "serverinfo")
  1091. ?? throw new Exception("OCR server path not found");
  1092. string serverocrPathIn = Path.Combine(serverocrPath, "IN");
  1093. string serverocrPathOut = Path.Combine(serverocrPath, "OUT");
  1094. Directory.CreateDirectory(serverocrPathIn);
  1095. Directory.CreateDirectory(serverocrPathOut);
  1096. // 🔹 Move ALL renamed split files into OCR IN folder
  1097. foreach (var splitFile in allSplitFiles)
  1098. {
  1099. string destinationFilePath = Path.Combine(serverocrPathIn, Path.GetFileName(splitFile));
  1100. if (System.IO.File.Exists(destinationFilePath))
  1101. System.IO.File.Delete(destinationFilePath);
  1102. System.IO.File.Move(splitFile, destinationFilePath);
  1103. }
  1104. return Ok(new { message = "Lots saved/updated with transactions successfully!", lastTransactionId });
  1105. }
  1106. }
  1107. catch (Exception ex)
  1108. {
  1109. return StatusCode(500, new { error = ex.Message });
  1110. }
  1111. }
  1112. private long InsertLotTransaction(NpgsqlConnection conn, NpgsqlTransaction tran, int lotId, Guid lotkey)
  1113. {
  1114. int jobWorkflowId = 0;
  1115. long transactionId = 0;
  1116. // Get the workflow ID
  1117. using (var cmdWF = new NpgsqlCommand(@"
  1118. SELECT jwm.jobworkflowid
  1119. FROM tbllotmaster lm
  1120. LEFT JOIN tbljobworkflowdefinition jwm
  1121. ON jwm.jobid = lm.jobid
  1122. WHERE lm.lotid = @lotid AND jwm.stagename_alias='PDF Splitting'", conn, tran))
  1123. {
  1124. cmdWF.Parameters.AddWithValue("@lotid", lotId);
  1125. var result = cmdWF.ExecuteScalar();
  1126. if (result != null && result != DBNull.Value)
  1127. jobWorkflowId = Convert.ToInt32(result);
  1128. }
  1129. if (jobWorkflowId > 0)
  1130. {
  1131. using (var cmdTran = new NpgsqlCommand("insert_lot_transaction_details", conn, tran))
  1132. {
  1133. cmdTran.CommandType = CommandType.StoredProcedure;
  1134. cmdTran.Parameters.AddWithValue("p_jobworkflowid", jobWorkflowId);
  1135. cmdTran.Parameters.AddWithValue("p_lotid", lotId);
  1136. cmdTran.Parameters.AddWithValue("p_lotkey", lotkey);
  1137. // ✅ ExecuteScalar will return the inserted transaction ID
  1138. var result = cmdTran.ExecuteScalar();
  1139. if (result != null && result != DBNull.Value)
  1140. transactionId = Convert.ToInt64(result);
  1141. }
  1142. }
  1143. return transactionId;
  1144. }
  1145. private long InsertLotTransactionocr(NpgsqlConnection conn, NpgsqlTransaction tran, int lotId)
  1146. {
  1147. int jobWorkflowId = 0;
  1148. long transactionId = 0;
  1149. // Get the workflow ID
  1150. using (var cmdWF = new NpgsqlCommand(@"
  1151. SELECT jwm.jobworkflowid
  1152. FROM tbllotbatch lm
  1153. LEFT JOIN tbljobworkflowdefinition jwm
  1154. ON jwm.jobid = lm.jobid
  1155. WHERE lm.batchid = @lotid AND jwm.stagename_alias='OCR Conversion'", conn, tran))
  1156. {
  1157. cmdWF.Parameters.AddWithValue("@lotid", lotId);
  1158. var result = cmdWF.ExecuteScalar();
  1159. if (result != null && result != DBNull.Value)
  1160. jobWorkflowId = Convert.ToInt32(result);
  1161. }
  1162. if (jobWorkflowId > 0)
  1163. {
  1164. using (var cmdTran = new NpgsqlCommand("insert_lot_transaction_details_batch_only", conn, tran))
  1165. {
  1166. cmdTran.CommandType = CommandType.StoredProcedure;
  1167. cmdTran.Parameters.AddWithValue("p_jobworkflowid", jobWorkflowId);
  1168. cmdTran.Parameters.AddWithValue("p_batchid", lotId);
  1169. // cmdTran.Parameters.AddWithValue("p_lotkey", lotkey);
  1170. // ✅ ExecuteScalar will return the inserted transaction ID
  1171. var result = cmdTran.ExecuteScalar();
  1172. if (result != null && result != DBNull.Value)
  1173. transactionId = Convert.ToInt64(result);
  1174. }
  1175. }
  1176. return transactionId;
  1177. }
  1178. private void RunSplitterExe(string serverPathIn, string pdfAnalysisServerPathIn, string range, string jobId)
  1179. {
  1180. try
  1181. {
  1182. // 📌 Read exe path from appsettings.json
  1183. // string exePath = @"";
  1184. oGrantFolderPermission.FolderPermission_vlex(serverPathIn, "", "", "", jobId.ToString());
  1185. var exePath = Path.Combine(AppContext.BaseDirectory, "Tools", "Vlex_LAPS_PDF_Spiltter.exe");
  1186. //var exePath = @"D:\pdfanalysis_vlex\Service\bin\Debug\netcoreapp3.1\Tools\Vlex_LAPS_PDF_Spiltter.exe";
  1187. // if (string.IsNullOrEmpty(exePath) || !File.Exists(exePath))
  1188. // throw new FileNotFoundException("Splitter EXE path not found in configuration or file missing.", exePath);
  1189. // 🔒 Apply folder permission before running EXE
  1190. //oGrantFolderPermission.FolderPermission("", "", "", jobId);
  1191. // Arguments: input folder, PDF Analysis folder, range
  1192. var arguments = $"\"{serverPathIn},{pdfAnalysisServerPathIn},{range}\"";
  1193. var processInfo = new ProcessStartInfo
  1194. {
  1195. FileName = exePath,
  1196. Arguments = arguments,
  1197. CreateNoWindow = true,
  1198. UseShellExecute = false,
  1199. RedirectStandardOutput = true,
  1200. RedirectStandardError = true
  1201. };
  1202. using (var process = new Process { StartInfo = processInfo })
  1203. {
  1204. process.Start();
  1205. string output = process.StandardOutput.ReadToEnd();
  1206. string error = process.StandardError.ReadToEnd();
  1207. process.WaitForExit();
  1208. if (process.ExitCode != 0)
  1209. {
  1210. throw new Exception($"Splitter EXE failed. Error: {error}. Output: {output}");
  1211. }
  1212. }
  1213. }
  1214. catch (Exception ex)
  1215. {
  1216. throw new Exception(
  1217. $"Failed to run splitter EXE for paths '{serverPathIn}' and '{pdfAnalysisServerPathIn}': {ex.Message}",
  1218. ex
  1219. );
  1220. }
  1221. }
  1222. private long InsertVlexReport(
  1223. NpgsqlConnection conn,
  1224. long jobId,
  1225. long lotId,
  1226. string report,
  1227. string volume,
  1228. string edition,
  1229. string issue,
  1230. string printpage,
  1231. long createdBy,
  1232. int active)
  1233. {
  1234. using (var cmd = new NpgsqlCommand("spvlexreport_insert", conn))
  1235. {
  1236. cmd.CommandType = CommandType.StoredProcedure;
  1237. cmd.Parameters.AddWithValue("p_jobid", jobId);
  1238. cmd.Parameters.AddWithValue("p_lotid", lotId);
  1239. cmd.Parameters.AddWithValue("p_report", (object?)report ?? DBNull.Value);
  1240. cmd.Parameters.AddWithValue("p_volume", (object?)volume ?? DBNull.Value);
  1241. cmd.Parameters.AddWithValue("p_edition", (object?)edition ?? DBNull.Value);
  1242. cmd.Parameters.AddWithValue("p_issue", (object?)issue ?? DBNull.Value);
  1243. cmd.Parameters.AddWithValue("p_printpage", (object?)printpage ?? DBNull.Value);
  1244. cmd.Parameters.AddWithValue("p_createdby", createdBy);
  1245. cmd.Parameters.AddWithValue("p_active", active);
  1246. object result = cmd.ExecuteScalar();
  1247. return result != null && result != DBNull.Value ? Convert.ToInt64(result) : 0;
  1248. }
  1249. }
  1250. public class MatchedResult
  1251. {
  1252. public string FilePath { get; set; }
  1253. // Add other properties if needed
  1254. }
  1255. //public class LotTitleDto
  1256. //{
  1257. // public string Title { get; set; }
  1258. // public int TotalUnits { get; set; }
  1259. // public int lotid { get; set; }
  1260. //}
  1261. public class PageDetailDto
  1262. {
  1263. public int JobId { get; set; }
  1264. public int LotId { get; set; }
  1265. public string MainPage { get; set; }
  1266. // public string SupplementPage { get; set; }
  1267. public int DocType { get; set; }
  1268. public int UpdatedBy { get; set; }
  1269. public string? Mode { get; set; }
  1270. }
  1271. public class LotTitleDto
  1272. {
  1273. public string Title { get; set; }
  1274. public int lotid { get; set; }
  1275. //public int TotalUnits { get; set; }
  1276. public string mainpagerange { get; set; }
  1277. public string supplementrypagerange { get; set; }
  1278. public string ImgTitle { get; set; } // optional, for image title if found
  1279. public int DefaultDocType { get; set; } = 1; // assuming 1 is main
  1280. }
  1281. public class LotDto
  1282. {
  1283. public string Report { get; set; }
  1284. public string Volume { get; set; }
  1285. public string Edition { get; set; }
  1286. public string Issue { get; set; }
  1287. public string Range { get; set; }
  1288. public string Printpage { get; set; }
  1289. public string LotName { get; set; } // concatenated in Angular
  1290. public int jobid { get; set; }
  1291. public int? LotId { get; set; }
  1292. public int createadby { get; set; }
  1293. }
  1294. }
  1295. }