Files
satusehat-worker/internal/master/kfa/mapper.go
T

169 lines
4.7 KiB
Go

package kfa
import (
"encoding/json"
"strconv"
"strings"
"time"
)
func MapKfaDetailToEntity(detail KfaDetailResult) (*KfaProduct, []KfaProductActiveIngredient, []KfaProductPackaging) {
now := time.Now()
var displayName *string
// Attempt to extract display_name safely if product template exists
templateB := toJsonb(detail.ProductTemplate)
if templateB != nil {
var tpl struct {
DisplayName string `json:"display_name"`
}
if err := json.Unmarshal(templateB, &tpl); err == nil && tpl.DisplayName != "" {
displayName = &tpl.DisplayName
}
}
if displayName == nil {
displayName = &detail.Name
}
product := &KfaProduct{
KfaCode: detail.KfaCode,
Name: detail.Name,
DisplayName: displayName,
TradeName: detail.NamaDagang,
State: detail.State,
IsGeneric: detail.Generik,
DosageForm: toJsonb(detail.DosageForm),
FarmalkesType: toJsonb(detail.FarmalkesType),
Route: toJsonb(detail.RutePemberian),
ControlledDrug: toJsonb(detail.ControlledDrug),
Uom: toJsonb(detail.Uom),
FixPrice: detail.FixPrice,
HetPrice: detail.HetPrice,
DosePerUnit: detail.DosePerUnit,
NetWeight: detail.NetWeight,
NetWeightUom: detail.NetWeightUomName,
Volume: detail.Volume,
VolumeUom: detail.VolumeUomName,
ScoreTkdn: detail.ScoreTkdn,
ScoreTkdnBmp: detail.ScoreTkdnBmp,
ScoreBmp: detail.ScoreBmp,
Rxterm: detail.Rxterm,
Manufacturer: detail.Manufacturer,
Registrar: detail.Registrar,
Nie: detail.Nie,
Hscode: detail.FarmalkesHscode,
LkppCode: detail.KodeLkpp,
IsLkppActive: detail.TayangLkpp,
Description: detail.Description,
Indication: detail.Indication,
SideEffect: detail.SideEffect,
Warning: detail.Warning,
Image: detail.Image,
DrugClassification: detail.KlasifikasiIzin,
ManufacturingOrigin: detail.ProduksiBuatan,
AtcInfo: buildAtcInfo(detail),
Fornas: toJsonb(detail.Fornas),
DosageUsage: toJsonb(detail.DosageUsage),
Tags: toJsonb(detail.Tags),
IdentifierIds: toJsonb(detail.IdentifierIds),
ProductTemplate: templateB,
Replacement: toJsonb(detail.Replacement),
Ucum: toJsonb(detail.Ucum),
CreatedAt: now,
UpdatedAt: parseTime(detail.UpdatedAt, now),
Active: &detail.Active,
}
var ingredients []KfaProductActiveIngredient
for _, ing := range detail.ActiveIngredients {
val, unit := parseStrength(ing.KekuatanZatAktif)
ingredients = append(ingredients, KfaProductActiveIngredient{
ProductKfaCode: product.KfaCode,
ProductDisplay: product.Name,
SubstanceCode: ing.KfaCode,
SubstanceName: ing.ZatAktif,
StrengthValue: val,
StrengthUnit: unit,
StrengthText: ing.KekuatanZatAktif,
State: ing.State,
CreatedAt: now,
UpdatedAt: parseTime(ing.UpdatedAt, now),
Active: &ing.Active,
})
}
var packagings []KfaProductPackaging
for _, pkg := range detail.PackagingIds {
active := true
packagings = append(packagings, KfaProductPackaging{
ProductKfaCode: product.KfaCode,
ProductDisplay: product.Name,
Code: pkg.KfaCode,
Name: pkg.Name,
Quantity: pkg.Qty,
Unit: pkg.UomId,
Price: pkg.PackPrice,
State: "valid",
CreatedAt: now,
UpdatedAt: now,
Active: &active,
})
}
return product, ingredients, packagings
}
func toJsonb(v interface{}) json.RawMessage {
if v == nil {
return nil
}
b, err := json.Marshal(v)
if err != nil || string(b) == "null" {
return nil
}
return b
}
func buildAtcInfo(d KfaDetailResult) json.RawMessage {
m := map[string]interface{}{
"atc_ddd": d.AtcDdd,
"atc_l1": d.AtcL1,
"atc_l2": d.AtcL2,
"atc_l3": d.AtcL3,
"atc_l4": d.AtcL4,
"atc_l5": d.AtcL5,
}
return toJsonb(m)
}
func parseStrength(text string) (*float64, string) {
text = strings.TrimSpace(text)
if text == "" {
return nil, ""
}
parts := strings.Split(text, " ")
if len(parts) == 0 {
return nil, ""
}
val, err := strconv.ParseFloat(parts[0], 64)
if err != nil {
return nil, text
}
var unit string
if len(parts) > 1 {
unit = strings.Join(parts[1:], " ")
}
return &val, unit
}
func parseTime(t *string, defaultTime time.Time) time.Time {
if t == nil || *t == "" {
return defaultTime
}
parsed, err := time.Parse("2006-01-02 15:04:05", *t)
if err != nil {
return defaultTime
}
return parsed
}