diff --git a/.github/workflows/release_report.yaml b/.github/workflows/release_report.yaml new file mode 100644 index 00000000..39bdf8c0 --- /dev/null +++ b/.github/workflows/release_report.yaml @@ -0,0 +1,87 @@ +name: release-dev +run-name: release-dev ${{ github.actor }} +on: + # push: + # tags: + # - 'v[0-9]+.[0-9]+.[0-9]+' + # tags-ignore: + # - '2.*' + # Allow run workflow manually from Action tab + workflow_dispatch: +env: + REGISTRY: docker.frappet.com + IMAGE_NAME: ehr/bma-ehr-report-v2-service + DEPLOY_HOST: frappet.com + COMPOSE_PATH: /home/frappet/docker/bma-ehr-report-v2 + TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0 + +jobs: + # act workflow_dispatch -W .github/workflows/release_report.yaml --input IMAGE_VER=test-v6.1 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd + release-dev: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + # skip Set up QEMU because it fail on act and container + - name: Gen Version + id: gen_ver + run: | + if [[ $GITHUB_REF == 'refs/tags/'* ]]; then + IMAGE_VER='${GITHUB_REF/refs\/tags\//}' + else + IMAGE_VER=${{ github.event.inputs.IMAGE_VER }} + fi + if [[ $IMAGE_VER == '' ]]; then + IMAGE_VER='test-vBeta' + fi + echo '::set-output name=image_ver::'$IMAGE_VER + - name: Test Version + run: | + echo $GITHUB_REF + echo ${{ steps.gen_ver.outputs.image_ver }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Login in to registry + uses: docker/login-action@v2 + with: + registry: ${{env.REGISTRY}} + username: ${{secrets.DOCKER_USER}} + password: ${{secrets.DOCKER_PASS}} + - name: Build and load local docker image + uses: docker/build-push-action@v3 + with: + context: . + platforms: linux/amd64 + file: BMA.EHR.Command.Service/Dockerfile + push: true + tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest + + - name: Reload docker compose + uses: appleboy/ssh-action@v0.1.8 + with: + host: ${{env.DEPLOY_HOST}} + username: frappet + password: ${{ secrets.SSH_PASSWORD }} + port: 22 + script: | + cd "${{env.COMPOSE_PATH}}" + docker-compose pull + docker-compose up -d + echo "${{ steps.gen_ver.outputs.image_ver }}"> success + - uses: snow-actions/line-notify@v1.1.0 + if: success() + with: + access_token: ${{ env.TOKEN_LINE }} + message: | + -Success✅✅✅ + Image: ${{env.IMAGE_NAME}} + Version: ${{ github.event.inputs.IMAGE_VER }} + By: ${{secrets.DOCKER_USER}} + - uses: snow-actions/line-notify@v1.1.0 + if: failure() + with: + access_token: ${{ env.TOKEN_LINE }} + message: | + -Failure❌❌❌ + Image: ${{env.IMAGE_NAME}} + Version: ${{ github.event.inputs.IMAGE_VER }} + By: ${{secrets.DOCKER_USER}} diff --git a/BMA.EHR.Application/ApplicationServicesRegistration.cs b/BMA.EHR.Application/ApplicationServicesRegistration.cs index 502acb37..fefe5d9e 100644 --- a/BMA.EHR.Application/ApplicationServicesRegistration.cs +++ b/BMA.EHR.Application/ApplicationServicesRegistration.cs @@ -23,6 +23,7 @@ namespace BMA.EHR.Application services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); return services; } diff --git a/BMA.EHR.Application/Repositories/Commands/CommandReportRepository.cs b/BMA.EHR.Application/Repositories/Commands/CommandReportRepository.cs new file mode 100644 index 00000000..a956fec8 --- /dev/null +++ b/BMA.EHR.Application/Repositories/Commands/CommandReportRepository.cs @@ -0,0 +1,92 @@ +using BMA.EHR.Application.Common.Interfaces; +using BMA.EHR.Domain.Models.Commands.Core; +using BMA.EHR.Domain.Shared; +using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BMA.EHR.Application.Repositories.Commands +{ + public class CommandReportRepository : GenericRepository + { + #region " Fields " + + private readonly IApplicationDBContext _dbContext; + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly OrganizationCommonRepository _organizationCommonRepository; + private readonly UserProfileRepository _userProfileRepository; + + #endregion + + #region " Constructor and Destuctor " + + public CommandReportRepository(IApplicationDBContext dbContext, + IHttpContextAccessor httpContextAccessor, + OrganizationCommonRepository organizationCommonRepository, + UserProfileRepository userProfileRepository) : base(dbContext, httpContextAccessor) + { + _dbContext = dbContext; + _httpContextAccessor = httpContextAccessor; + _organizationCommonRepository = organizationCommonRepository; + _userProfileRepository = userProfileRepository; + } + + #endregion + + #region " Properties " + + protected Guid UserOrganizationId + { + get + { + if (UserId != null || UserId != "") + return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!)); + else + return Guid.Empty; + } + } + + #endregion + + #region " Methods " + + public async Task> GetCommandType01AttachmentAsync(Guid id) + { + try + { + var raw_data = await _dbContext.Set() + .Include(c => c.Command) + .Where(c => c.Command.Id == id) + .ToListAsync(); + if (raw_data == null) + { + throw new Exception(GlobalMessages.CommandNotFound); + } + + var ret = new List(); + + foreach (var c in raw_data) + { + ret.Add(new + { + FullName = $"{c.Prefix}{c.FirstName} {c.LastName}", + PositionName = "" + }); + } + + return ret; + } + catch + { + throw; + } + } + + #endregion + } +} diff --git a/BMA.EHR.Report.Service/Controllers/CommandReportController.cs b/BMA.EHR.Report.Service/Controllers/CommandReportController.cs index 06f71c46..458cac2b 100644 --- a/BMA.EHR.Report.Service/Controllers/CommandReportController.cs +++ b/BMA.EHR.Report.Service/Controllers/CommandReportController.cs @@ -9,6 +9,8 @@ using Swashbuckle.AspNetCore.Annotations; using static System.Runtime.InteropServices.JavaScript.JSType; using Telerik.Reporting; using Telerik.Reporting.Processing; +using Microsoft.IdentityModel.Protocols.OpenIdConnect; +using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; namespace BMA.EHR.Report.Service.Controllers { @@ -25,6 +27,7 @@ namespace BMA.EHR.Report.Service.Controllers private readonly CommandRepository _repository; private readonly IWebHostEnvironment _hostingEnvironment; private readonly IConfiguration _configuration; + private readonly CommandReportRepository _commandReportRepository; #endregion @@ -32,11 +35,13 @@ namespace BMA.EHR.Report.Service.Controllers public CommandReportController(CommandRepository repository, IWebHostEnvironment hostingEnvironment, - IConfiguration configuration) + IConfiguration configuration, + CommandReportRepository commandReportRepository) { _repository = repository; _hostingEnvironment = hostingEnvironment; _configuration = configuration; + _commandReportRepository = commandReportRepository; } #endregion @@ -45,7 +50,7 @@ namespace BMA.EHR.Report.Service.Controllers #region " Private " - private async Task GenerateCommandReportType01(Guid commandId, string exportType) + private async Task GenerateCommandReportType01_Cover(Guid commandId, string exportType) { try { @@ -101,11 +106,74 @@ namespace BMA.EHR.Report.Service.Controllers } } + private async Task GenerateCommandReportType01_Attachment(Guid commandId, string exportType) + { + try + { + var command = await _repository.GetByIdAsync(commandId); + if (command == null) + { + throw new Exception(GlobalMessages.CommandNotFound); + } + + var data = await _commandReportRepository.GetCommandType01AttachmentAsync(commandId); + + var rptFile = Path.Combine(_hostingEnvironment.ContentRootPath, "Reports", $"01-คำสั่งบรรจุและแต่งตั้งผู้สอบแข่งขันได้-2.trdp"); + + ReportPackager reportPackager = new ReportPackager(); + Telerik.Reporting.Report? report = null; + using (var sourceStream = System.IO.File.OpenRead(rptFile)) + { + report = (Telerik.Reporting.Report)reportPackager.UnpackageDocument(sourceStream); + } + + var tblData = (Telerik.Reporting.Table)report.Items["detailSection1"].Items["tblData"]; + + tblData.DataSource = data; + + report.ReportParameters["IssuerOrganizationName"].Value = command.IssuerOrganizationName; + report.ReportParameters["CommandNo"].Value = command.CommandNo; + report.ReportParameters["CommandYear"].Value = command.CommandYear.ToInteger().ToThaiYear().ToString(); + report.ReportParameters["CommandExecuteDate"].Value = command.CommandExcecuteDate == null ? "" : command.CommandExcecuteDate.Value.ToThaiFullDate3(); + + System.Collections.Hashtable deviceInfo = new System.Collections.Hashtable(); + + InstanceReportSource instanceReportSource = new InstanceReportSource() + { + ReportDocument = report + }; + + + ReportProcessor reportProcessor = new ReportProcessor(_configuration); + RenderingResult result = reportProcessor.RenderReport(exportType, instanceReportSource, deviceInfo); + + var content = result.DocumentBytes; + + return content; + } + catch + { + throw; + } + } + #endregion - [HttpGet("{exportType}/{id}")] + /// + /// รายงานหน้าคำสั่ง + /// + /// Record Id ของคำสั่ง + /// pdf, docx หรือ xlsx + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("cover/{exportType}/{id}")] [AllowAnonymous] - public async Task> GetCommandReport(Guid id, string exportType) + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetCommandCoverReportAsync(Guid id, string exportType = "pdf") { try { @@ -113,8 +181,73 @@ namespace BMA.EHR.Report.Service.Controllers if (cmd == null) throw new Exception(GlobalMessages.CommandNotFound); - var contentData = await GenerateCommandReportType01(id, exportType); - return File(contentData, "application/pdf", $"command-{cmd.CommandNo}-{cmd.CommandYear.ToInteger().ToThaiYear()}.pdf"); + var mimeType = ""; + switch (exportType.Trim().ToLower()) + { + case "pdf": mimeType = "application/pdf"; break; + case "docx": mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; break; + case "xlsx": mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; break; + } + + switch (cmd.CommandType.CommandCode.Trim().ToUpper()) + { + case "C-PM-01": + case "C-PM-02": + case "C-PM-03": + { + var contentData = await GenerateCommandReportType01_Cover(id, exportType); + return File(contentData, mimeType, $"command-{cmd.CommandNo}-{cmd.CommandYear.ToInteger().ToThaiYear()}.{exportType.Trim().ToLower()}"); + } + default: throw new Exception(GlobalMessages.MethodForCommandTypeNotImplement); + } + } + catch + { + throw; + } + } + + /// + /// รายงานเอกสารแนบท้าย + /// + /// Record Id ของคำสั่ง + /// pdf, docx หรือ xlsx + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("attachment/{exportType}/{id}")] + [AllowAnonymous] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetCommandAttachmentReportAsync(Guid id, string exportType = "pdf") + { + try + { + var cmd = await _repository.GetByIdAsync(id); + if (cmd == null) + throw new Exception(GlobalMessages.CommandNotFound); + + var mimeType = ""; + switch (exportType.Trim().ToLower()) + { + case "pdf": mimeType = "application/pdf"; break; + case "docx": mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; break; + case "xlsx": mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; break; + } + + switch (cmd.CommandType.CommandCode.Trim().ToUpper()) + { + case "C-PM-01": + case "C-PM-02": + case "C-PM-03": + { + var contentData = await GenerateCommandReportType01_Attachment(id, exportType); + return File(contentData, mimeType, $"command-attachment-{cmd.CommandNo}-{cmd.CommandYear.ToInteger().ToThaiYear()}.{exportType.Trim().ToLower()}"); + } + default: throw new Exception(GlobalMessages.MethodForCommandTypeNotImplement); + } } catch { diff --git a/BMA.EHR.Report.Service/Reports/01-คำสั่งบรรจุและแต่งตั้งผู้สอบแข่งขันได้-2.trdp b/BMA.EHR.Report.Service/Reports/01-คำสั่งบรรจุและแต่งตั้งผู้สอบแข่งขันได้-2.trdp index 5807ce32..575b3c56 100644 Binary files a/BMA.EHR.Report.Service/Reports/01-คำสั่งบรรจุและแต่งตั้งผู้สอบแข่งขันได้-2.trdp and b/BMA.EHR.Report.Service/Reports/01-คำสั่งบรรจุและแต่งตั้งผู้สอบแข่งขันได้-2.trdp differ