feat (generate-file): control letter done
This commit is contained in:
@@ -3,6 +3,9 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<style>
|
<style>
|
||||||
|
body {
|
||||||
|
padding: 10px 30px;
|
||||||
|
}
|
||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse
|
border-collapse: collapse
|
||||||
@@ -18,6 +21,12 @@
|
|||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
margin-bottom: 0rem;
|
margin-bottom: 0rem;
|
||||||
}
|
}
|
||||||
|
td {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
@page {
|
||||||
|
size: 148mm 210mm;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@@ -25,7 +34,7 @@
|
|||||||
<table style="margin-top: 1rem;">
|
<table style="margin-top: 1rem;">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<img src="logo-1.png" alt="logo" style="height: 70px" />
|
<img src="logo-1.png" alt="logo" style="height: 70px; margin-bottom: 20px;" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>
|
<div>
|
||||||
@@ -35,15 +44,10 @@
|
|||||||
RSUD dr. Saiful Anwar
|
RSUD dr. Saiful Anwar
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td style="text-align: right;">
|
||||||
<div>
|
No. : {{ .Number }}
|
||||||
No. : {{ .Number }}
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td style="height: 0.5rem;"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div>
|
<div>
|
||||||
@@ -65,46 +69,50 @@
|
|||||||
Mohon Pemeriksaan dan Penanganan Lebih Lanjut:
|
Mohon Pemeriksaan dan Penanganan Lebih Lanjut:
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<table style="margin-top: 1rem;">
|
<table style="margin-top: 1rem;">
|
||||||
<tr>
|
<tr>
|
||||||
<td style="width: 9rem;">
|
<td style="width: 9rem;">
|
||||||
No.Kartu
|
No.Kartu
|
||||||
</td>
|
</td>
|
||||||
|
<td style="width: 10px;">:</td>
|
||||||
<td>
|
<td>
|
||||||
: {{ .CardNumber }}
|
{{ .CardNumber }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Nama Peserta
|
Nama Peserta
|
||||||
</td>
|
</td>
|
||||||
|
<td>: </td>
|
||||||
<td>
|
<td>
|
||||||
: {{ .Name }}
|
{{ .Name }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Tgl.Lahir
|
Tgl.Lahir
|
||||||
</td>
|
</td>
|
||||||
|
<td>: </td>
|
||||||
<td>
|
<td>
|
||||||
: {{ .BirthDate }}
|
{{ .BirthDate }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Diagnosa
|
Diagnosa
|
||||||
</td>
|
</td>
|
||||||
|
<td>: </td>
|
||||||
<td>
|
<td>
|
||||||
: {{ .Diagnose }}
|
{{ .Diagnose }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Rencana Kontrol
|
Rencana Kontrol
|
||||||
</td>
|
</td>
|
||||||
|
<td>: </td>
|
||||||
<td>
|
<td>
|
||||||
: {{ .PlanDate }}
|
{{ .PlanDate }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -112,19 +120,26 @@
|
|||||||
<div style="margin: 1rem 0;">
|
<div style="margin: 1rem 0;">
|
||||||
Demikian atas bantuannya, diucapkan banyak terima kasih.
|
Demikian atas bantuannya, diucapkan banyak terima kasih.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<td style="width: 15rem;">
|
|
||||||
Mengetahui, DPJP : {{ .ResponsibleDoctor_Name }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<div style="margin-top: 6rem;">
|
<table style="width:100%">
|
||||||
Tgl. Cetak : {{ .PrintDate }}
|
<tbody>
|
||||||
</div>
|
<tr>
|
||||||
|
<td style="width:20%"></td>
|
||||||
|
<td></td>
|
||||||
|
<td style="width:20%; text-align: center;">Mengetahui:</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="height:100px"></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Tgl. Cetak: {{ .PrintDate }}</td>
|
||||||
|
<td></td>
|
||||||
|
<td style="text-align: center;">{{ .ResponsibleDoctor_Name }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
<div style="height: 3rem;"></div>
|
<div style="height: 3rem;"></div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import (
|
|||||||
|
|
||||||
dg "github.com/karincake/apem/db-gorm-pg"
|
dg "github.com/karincake/apem/db-gorm-pg"
|
||||||
d "github.com/karincake/dodol"
|
d "github.com/karincake/dodol"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
erc "simrs-vx/internal/domain/references/common"
|
erc "simrs-vx/internal/domain/references/common"
|
||||||
ere "simrs-vx/internal/domain/references/encounter"
|
ere "simrs-vx/internal/domain/references/encounter"
|
||||||
@@ -36,128 +37,137 @@ func Generate(input GenerateDto) (*d.Data, error) {
|
|||||||
// Start log
|
// Start log
|
||||||
pl.SetLogInfo(&event, input, "started", "create")
|
pl.SetLogInfo(&event, input, "started", "create")
|
||||||
|
|
||||||
switch input.Type_Code {
|
err := dg.I.Transaction(func(tx *gorm.DB) error {
|
||||||
// general-consent
|
switch input.Type_Code {
|
||||||
case ere.DTCGC:
|
// general-consent
|
||||||
// get value from general consent by ref_id
|
case ere.DTCGC:
|
||||||
gc, err := ugc.ReadDetailData(egc.ReadDetailDto{Id: uint(*pc.StringToUint64(*input.Ref_Id))}, &event)
|
// get value from general consent by ref_id
|
||||||
if err != nil {
|
gc, err := ugc.ReadDetailData(egc.ReadDetailDto{Id: uint(*pc.StringToUint64(*input.Ref_Id))}, &event)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if gc.FileUrl != nil {
|
|
||||||
if err := removeFile(string(input.EntityType_Code), *gc.FileUrl); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// map template data
|
|
||||||
templateData := GeneralConsentPDF{}
|
|
||||||
if gc.Value != nil {
|
|
||||||
err := json.Unmarshal([]byte(*gc.Value), &templateData)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
event.ErrInfo = pl.ErrorInfo{
|
return err
|
||||||
Code: "data-unmarshal-fail",
|
}
|
||||||
Detail: err.Error(),
|
|
||||||
Raw: err,
|
if gc.FileUrl != nil {
|
||||||
|
if err := removeFile(string(input.EntityType_Code), *gc.FileUrl); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return nil, errors.New("no value in this general consent")
|
|
||||||
}
|
|
||||||
|
|
||||||
input.FormatType = erc.DFTCPDF
|
// map template data
|
||||||
input.TemplateName = TDNGC
|
templateData := GeneralConsentPDF{}
|
||||||
input.Encounter_Id = gc.Encounter_Id
|
if gc.Value != nil {
|
||||||
templateData.Date = pu.FormatIndonesianDate(gc.CreatedAt)
|
err := json.Unmarshal([]byte(*gc.Value), &templateData)
|
||||||
|
if err != nil {
|
||||||
// generate file
|
event.ErrInfo = pl.ErrorInfo{
|
||||||
urlPub, err := generateFile(input, templateData)
|
Code: "data-unmarshal-fail",
|
||||||
if err != nil {
|
Detail: err.Error(),
|
||||||
return nil, err
|
Raw: err,
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
gc.FileUrl = &urlPub
|
}
|
||||||
if err := dg.I.Save(&gc).Error; err != nil {
|
} else {
|
||||||
return nil, err
|
return errors.New("no value in this general consent")
|
||||||
}
|
|
||||||
|
|
||||||
response = ResponseDto{
|
|
||||||
FileUrl: urlPub,
|
|
||||||
}
|
|
||||||
|
|
||||||
// control-letter
|
|
||||||
case ere.DTCVSCL:
|
|
||||||
// get value from control letter by ref_id
|
|
||||||
cl, err := uvscl.ReadDetailData(evscl.ReadDetailDto{Number: input.Ref_Id}, &event)
|
|
||||||
if err != nil {
|
|
||||||
if !pu.IsDataNotFoundError(err) {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if cl != nil && cl.FileUrl != nil {
|
input.FormatType = erc.DFTCPDF
|
||||||
if err := removeFile(string(input.EntityType_Code), *cl.FileUrl); err != nil {
|
input.TemplateName = TDNGC
|
||||||
return nil, err
|
input.Encounter_Id = gc.Encounter_Id
|
||||||
}
|
templateData.Date = pu.FormatIndonesianDate(gc.CreatedAt)
|
||||||
}
|
|
||||||
|
|
||||||
// map template data
|
// generate file
|
||||||
clData := VclaimControlLetter{}
|
urlPub, err := generateFile(input, templateData)
|
||||||
if input.Data != nil {
|
|
||||||
err := json.Unmarshal([]byte(*input.Data), &clData)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
event.ErrInfo = pl.ErrorInfo{
|
return err
|
||||||
Code: "data-unmarshal-fail",
|
}
|
||||||
Detail: err.Error(),
|
|
||||||
Raw: err,
|
gc.FileUrl = &urlPub
|
||||||
|
if err := dg.I.Save(&gc).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
response = ResponseDto{
|
||||||
|
FileUrl: urlPub,
|
||||||
|
}
|
||||||
|
|
||||||
|
// control-letter
|
||||||
|
case ere.DTCVSCL:
|
||||||
|
// get value from control letter by ref_id
|
||||||
|
cl, err := uvscl.ReadDetailData(evscl.ReadDetailDto{Number: input.Ref_Id}, &event)
|
||||||
|
if err != nil {
|
||||||
|
if !pu.IsDataNotFoundError(err) {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, errors.New("there is no data to be used")
|
|
||||||
}
|
|
||||||
|
|
||||||
if cl == nil {
|
|
||||||
createCL := evscl.CreateDto{
|
|
||||||
VclaimSep_Number: &clData.VclaimSep.Number,
|
|
||||||
Number: &clData.Number,
|
|
||||||
Value: input.Data,
|
|
||||||
}
|
|
||||||
if cl, err = uvscl.CreateData(createCL, &event); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
if cl != nil && cl.FileUrl != nil {
|
||||||
// get encounter id by vclaim sep number
|
if err := removeFile(string(input.EntityType_Code), *cl.FileUrl); err != nil {
|
||||||
vs, err := uvs.ReadDetailData(evs.ReadDetailDto{Number: &clData.VclaimSep.Number}, &event)
|
return err
|
||||||
if err != nil {
|
}
|
||||||
return nil, err
|
}
|
||||||
|
|
||||||
|
// map template data
|
||||||
|
clData := VclaimControlLetter{}
|
||||||
|
if input.Data != nil {
|
||||||
|
err := json.Unmarshal([]byte(*input.Data), &clData)
|
||||||
|
if err != nil {
|
||||||
|
event.ErrInfo = pl.ErrorInfo{
|
||||||
|
Code: "data-unmarshal-fail",
|
||||||
|
Detail: err.Error(),
|
||||||
|
Raw: err,
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return errors.New("there is no data to be used")
|
||||||
|
}
|
||||||
|
|
||||||
|
if cl == nil {
|
||||||
|
createCL := evscl.CreateDto{
|
||||||
|
VclaimSep_Number: &clData.VclaimSep.Number,
|
||||||
|
Number: &clData.Number,
|
||||||
|
Value: input.Data,
|
||||||
|
}
|
||||||
|
if cl, err = uvscl.CreateData(createCL, &event, tx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// get encounter id by vclaim sep number
|
||||||
|
vs, err := uvs.ReadDetailData(evs.ReadDetailDto{Number: &clData.VclaimSep.Number}, &event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
input.FormatType = erc.DFTCPDF
|
||||||
|
input.TemplateName = TDNCL
|
||||||
|
input.Encounter_Id = vs.Encounter_Id
|
||||||
|
input.UseA5Lanscape = true
|
||||||
|
|
||||||
|
templateData := clData.generateTemplateData()
|
||||||
|
// generate file
|
||||||
|
urlPub, err := generateFile(input, templateData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cl.FileUrl = &urlPub
|
||||||
|
if err := tx.Save(&cl).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
response = ResponseDto{
|
||||||
|
FileUrl: urlPub,
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return errors.New("invalid type code")
|
||||||
}
|
}
|
||||||
|
|
||||||
input.FormatType = erc.DFTCPDF
|
return nil
|
||||||
input.TemplateName = TDNCL
|
})
|
||||||
input.Encounter_Id = vs.Encounter_Id
|
|
||||||
|
|
||||||
templateData := clData.generateTemplateData()
|
if err != nil {
|
||||||
// generate file
|
return nil, err
|
||||||
urlPub, err := generateFile(input, templateData)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cl.FileUrl = &urlPub
|
|
||||||
if err := dg.I.Save(&cl).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
response = ResponseDto{
|
|
||||||
FileUrl: urlPub,
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil, errors.New("invalid type code")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &d.Data{
|
return &d.Data{
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ func generateFile(input GenerateDto, templateData any) (string, error) {
|
|||||||
switch input.FormatType {
|
switch input.FormatType {
|
||||||
case erc.DFTCPDF:
|
case erc.DFTCPDF:
|
||||||
if err := generatePDF(GeneratePDFdto{
|
if err := generatePDF(GeneratePDFdto{
|
||||||
TemplatePath: templatePath,
|
TemplatePath: templatePath,
|
||||||
TemplateData: templateData,
|
TemplateData: templateData,
|
||||||
PdfPath: fPath,
|
PdfPath: fPath,
|
||||||
|
UseA5Lanscape: input.UseA5Lanscape,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -73,7 +74,7 @@ func generatePDF(input GeneratePDFdto) error {
|
|||||||
// parse template data into html template
|
// parse template data into html template
|
||||||
r := pp.NewRequestPdf("")
|
r := pp.NewRequestPdf("")
|
||||||
if err := r.ParseTemplate(input.TemplatePath, input.TemplateData); err == nil {
|
if err := r.ParseTemplate(input.TemplatePath, input.TemplateData); err == nil {
|
||||||
_, err := r.GenerateByCommand(input.PdfPath, input.TemplatePath)
|
_, err := r.GenerateByCommand(input.PdfPath, input.TemplatePath, input.UseA5Lanscape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("generate pdf by command error : " + err.Error())
|
return errors.New("generate pdf by command error : " + err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ type GenerateDto struct {
|
|||||||
FormatType erc.DocFormatTypeCode `json:"formatType"`
|
FormatType erc.DocFormatTypeCode `json:"formatType"`
|
||||||
TemplateName TemplateDocsName `json:"-"`
|
TemplateName TemplateDocsName `json:"-"`
|
||||||
Encounter_Id *uint `json:"-"`
|
Encounter_Id *uint `json:"-"`
|
||||||
|
UseA5Lanscape bool `json:"-"`
|
||||||
|
|
||||||
Data *string `json:"data"`
|
Data *string `json:"data"`
|
||||||
}
|
}
|
||||||
@@ -46,7 +47,6 @@ type GenerateDto struct {
|
|||||||
type VclaimControlLetter struct {
|
type VclaimControlLetter struct {
|
||||||
Number string `json:"noSuratKontrol"`
|
Number string `json:"noSuratKontrol"`
|
||||||
PlannedControlDate string `json:"tglRencanaKontrol"`
|
PlannedControlDate string `json:"tglRencanaKontrol"`
|
||||||
IssuedDate string `json:"tglTerbit"`
|
|
||||||
Doctor_Name string `json:"namaDokter"`
|
Doctor_Name string `json:"namaDokter"`
|
||||||
DstUnit_Name string `json:"namaPoliTujuan"`
|
DstUnit_Name string `json:"namaPoliTujuan"`
|
||||||
ResponsibleDoctor_Name string `json:"namaDokterPembuat"`
|
ResponsibleDoctor_Name string `json:"namaDokterPembuat"`
|
||||||
@@ -67,9 +67,10 @@ type VclaimMember struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GeneratePDFdto struct {
|
type GeneratePDFdto struct {
|
||||||
TemplatePath string
|
TemplatePath string
|
||||||
TemplateData any
|
TemplateData any
|
||||||
PdfPath string
|
PdfPath string
|
||||||
|
UseA5Lanscape bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseDto struct {
|
type ResponseDto struct {
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ func (r *RequestPdf) ParseTemplate(templatePath string, data interface{}) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RequestPdf) GenerateByCommand(pdfPath string, templatePath string) (bool, error) {
|
func (r *RequestPdf) GenerateByCommand(pdfPath string, templatePath string, useA5Lanscape bool) (bool, error) {
|
||||||
// wkhtmltopdf -L 0 -R 0 -B 0 -s Legal --enable-local-file-access resultAntigen2.html out.pdf
|
|
||||||
t := time.Now().Unix()
|
t := time.Now().Unix()
|
||||||
|
var cmd *exec.Cmd
|
||||||
|
|
||||||
if _, err := os.Stat("cloneTemplate/"); os.IsNotExist(err) {
|
if _, err := os.Stat("cloneTemplate/"); os.IsNotExist(err) {
|
||||||
errDir := os.Mkdir("cloneTemplate/", 0777)
|
errDir := os.Mkdir("cloneTemplate/", 0777)
|
||||||
@@ -63,7 +63,20 @@ func (r *RequestPdf) GenerateByCommand(pdfPath string, templatePath string) (boo
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command("wkhtmltopdf", "--enable-local-file-access", "-L", "0", "-R", "0", "-B", "0", "-s", "A4", "cloneTemplate/"+htmlName, pdfPath)
|
if !useA5Lanscape {
|
||||||
|
cmd = exec.Command("wkhtmltopdf", "--enable-local-file-access", "-L", "0", "-R", "0", "-B", "0", "-s", "A4", "cloneTemplate/"+htmlName, pdfPath)
|
||||||
|
} else {
|
||||||
|
cmd = exec.Command("wkhtmltopdf",
|
||||||
|
"--enable-local-file-access",
|
||||||
|
"-L", "0", // left margin
|
||||||
|
"-R", "0", // right margin
|
||||||
|
"-B", "0", // bottom margin
|
||||||
|
"-T", "0", // top margin
|
||||||
|
"-s", "A5", // page size A5
|
||||||
|
"-O", "Landscape", // landscape mode
|
||||||
|
"cloneTemplate/"+htmlName,
|
||||||
|
pdfPath)
|
||||||
|
}
|
||||||
|
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|||||||
Reference in New Issue
Block a user