File Coverage

blib/lib/Business/ID/POM.pm
Criterion Covered Total %
statement 14 165 8.4
branch 0 194 0.0
condition n/a
subroutine 5 7 71.4
pod 1 1 100.0
total 20 367 5.4


line stmt bran cond sub pod time code
1             package Business::ID::POM;
2              
3 1     1   382144 use 5.010001;
  1         5  
4 1     1   9 use warnings;
  1         2  
  1         94  
5 1     1   9 use strict;
  1         2  
  1         35  
6 1     1   1988 use Log::ger;
  1         59  
  1         6  
7              
8 1     1   284 use Exporter qw(import);
  1         2  
  1         3100  
9              
10             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
11             our $DATE = '2023-11-03'; # DATE
12             our $DIST = 'Business-ID-POM'; # DIST
13             our $VERSION = '0.006'; # VERSION
14              
15             our @EXPORT_OK = qw(parse_pom_reg_code);
16              
17             our %SPEC;
18              
19             sub _2to4_dig_year {
20 0 0   0     ($_[0] >= 78 ? 1900 : 2000) + $_[0];
21             }
22              
23             $SPEC{parse_pom_reg_code} = {
24             v => 1.1,
25             summary => 'Parse food/drug registration code published by '.
26             'the Indonesian National Agency of Drug and Food Control (POM)',
27             description => <<'_',
28              
29             This routine does not check whether the specified code is actually registered.
30             Use for that.
31              
32             _
33             args => {
34             code => {
35             summary => 'Input POM code to be parsed',
36             schema => 'str*',
37             pos => 0,
38             req => 1,
39             },
40             },
41             examples => [
42             {args=>{code=>'MD240935001200027'}},
43             {args=>{code=>'BPOM RI MD 224510107115'}},
44             {args=>{code=>'DBL9624502804A1'}},
45             {args=>{code=>'NC14191300159'}},
46             {args=>{code=>'POM TR092699241'}},
47             {args=>{code=>'FF182600791'}},
48             {args=>{code=>'SD181353251'}},
49             {args=>{code=>'SI184509731'}},
50             {args=>{code=>'SL091300431'}},
51             ],
52             };
53             sub parse_pom_reg_code {
54 0     0 1   my %args = @_;
55              
56 0 0         my $code = $args{code} or return [400, "Please specify code"];
57 0           my $res = {};
58              
59 0           $code = uc($code);
60 0           $code =~ s/[^0-9A-Z]+//g;
61              
62 0           $code =~ s/^B?POM(RI)?//;
63              
64 0 0         $code =~ /\A([A-Z]+)([0-9A-Z]+)\z/
65             or return [400, "Invalid syntax, code needs to be letters followed by digits/letters"];
66              
67 0           $res->{category_code} = $1;
68 0           $res->{number} = $2;
69              
70 0 0         if ($res->{category_code} =~ /\AM[DL]\z/) {
    0          
    0          
    0          
    0          
    0          
    0          
71              
72 0 0         $res->{category_id} = $res->{category_code} eq 'MD' ? 'Makanan (M), dalam negeri (D)' : 'Makanan (M), impor (L)';
73 0 0         if (length $res->{number} == 12) {
    0          
74 0 0         $res->{number} =~ /\A([0-9])([0-9]{3})([0-9]{2})([0-9]{3})([0-9]{3})\z/
75             or return [400, "MD/ML number needs to be 12-digit number"];
76              
77 0           $res->{food_is_rba} = 0;
78 0           $res->{food_packaging_type_code} = $1;
79 0           $res->{food_type_code} = $2;
80 0           $res->{food_province_code} = $3;
81 0           $res->{food_company_code} = $4;
82 0           $res->{food_company_product_code} = $5;
83 0           $res->{number_id} = "(Kode Kemasan $1) (Jenis Pangan $2) (Kode Provinsi $3) (Kode Perusahaan $5) (Nomor Urut $5)";
84             } elsif (length $res->{number} == 15) {
85 0 0         $res->{number} =~ /\A([0-9]{1})([0-9]{1})([0-9]{2})([0-9]{2})([0-9]{4})([0-9]{5})\z/
86             or return [400, "MD/ML number needs to be 15-digit number"];
87              
88             # this is based on my analysis, can't find official documentation.
89 0           $res->{food_is_rba} = 1;
90 0           $res->{food_risk_code} = $1;
91 0 0         $res->{food_risk_id} = $1 == 0 ? "MR - Menengah Rendah" : $1 == 1 ? "MT - Menengah Tinggi" : "T - Tinggi";
    0          
92 0           $res->{food_packaging_type_code} = $2;
93 0           $res->{food_province_code} = $3;
94 0           $res->{food_type_code} = $4;
95 0           $res->{food_company_product_code} = $5;
96 0           $res->{food_company_code} = $6;
97 0           $res->{number_id} = "(Kode Risiko $1 ($res->{food_risk_id})) (Kode Kemasan $2) (Kode Provinsi $3) (Jenis Pangan $4) (Nomor Urut $5) (Kode Perusahaan $6)";
98             } else {
99 0           return [400, "MD/ML number needs to be 12- or 15-digit number"];
100             }
101             } elsif ($res->{category_code} =~ /\A[DG](.?)(.?)\z/) {
102              
103 0           $res->{drug_category_code} = $1;
104 0           $res->{drug_origin_code} = $2;
105              
106 0 0         $res->{category_id} = $res->{category_code} =~ /\AD/ ? 'Obat merek dagang (D)' : 'Obat generik (G)';
107 0 0         if ($res->{drug_category_code} eq 'B') { $res->{category_id} .= ", bebas (B)" }
  0 0          
    0          
    0          
    0          
108 0           elsif ($res->{drug_category_code} eq 'T') { $res->{category_id} .= ", bebas terbatas (T)" }
109 0           elsif ($res->{drug_category_code} eq 'K') { $res->{category_id} .= ", obat keras (K)" }
110 0           elsif ($res->{drug_category_code} eq 'N') { $res->{category_id} .= ", narkotik (N)" }
111 0           elsif ($res->{drug_category_code} eq 'P') { $res->{category_id} .= ", psikotropik (P)" }
112 0           else { return [400, "Invalid drug category code '$res->{drug_category_code}', valid codes are B/T/K/N/P"] }
113              
114 0 0         if ($res->{drug_origin_code} eq 'L') { $res->{category_id} .= ", lokal (L)" }
  0 0          
    0          
    0          
115 0           elsif ($res->{drug_origin_code} eq 'I') { $res->{category_id} .= ", impor (I)" }
116 0           elsif ($res->{drug_origin_code} eq 'E') { $res->{category_id} .= ", ekspor (E)" }
117 0           elsif ($res->{drug_origin_code} eq 'X') { $res->{category_id} .= ", keperluan khusus (X)" }
118 0           else { return [400, "Invalid drug origin code '$res->{drug_origin_code}', valid codes are L/I/E/X"] }
119              
120 0 0         $res->{number} =~ /\A([0-9]{2})([0-9]{3})([0-9]{3})([0-9]{2})([A-Z])([0-9])\z/
121             or return [400, "Dxx/Gxx number needs to be 12-digit number/letter"];
122              
123 0           $res->{drug_year} = _2to4_dig_year($1);
124 0           $res->{drug_company_code} = $2;
125 0           $res->{drug_company_product_code} = $3;
126 0           $res->{drug_dosage_form_code} = $4;
127 0           $res->{drug_strength_serial} = $5;
128 0           $res->{drug_packaging_serial} = $6;
129 0 0         if ($res->{drug_dosage_form_code} eq '01') { $res->{drug_dosage_form_id} = "kapsul (01)" }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
130 0           elsif ($res->{drug_dosage_form_code} eq '02') { $res->{drug_dosage_form_id} = "kapsul lunak (02)" }
131 0           elsif ($res->{drug_dosage_form_code} eq '04') { $res->{drug_dosage_form_id} = "kaplet (04)" }
132 0           elsif ($res->{drug_dosage_form_code} eq '09') { $res->{drug_dosage_form_id} = "kaplet salut film (09)" }
133 0           elsif ($res->{drug_dosage_form_code} eq '10') { $res->{drug_dosage_form_id} = "tablet (10)" }
134 0           elsif ($res->{drug_dosage_form_code} eq '11') { $res->{drug_dosage_form_id} = "tablet effervescent (11)" }
135 0           elsif ($res->{drug_dosage_form_code} eq '12') { $res->{drug_dosage_form_id} = "tablet hisap (12)" }
136 0           elsif ($res->{drug_dosage_form_code} eq '14') { $res->{drug_dosage_form_id} = "tablet lepas terkontrol (14)" }
137 0           elsif ($res->{drug_dosage_form_code} eq '15') { $res->{drug_dosage_form_id} = "tablet salut enterik (15)" }
138 0           elsif ($res->{drug_dosage_form_code} eq '16') { $res->{drug_dosage_form_id} = "pil (16)" }
139 0           elsif ($res->{drug_dosage_form_code} eq '17') { $res->{drug_dosage_form_id} = "tablet salut selaput (17)" }
140 0           elsif ($res->{drug_dosage_form_code} eq '22') { $res->{drug_dosage_form_id} = "granul (22)" }
141 0           elsif ($res->{drug_dosage_form_code} eq '23') { $res->{drug_dosage_form_id} = "serbuk oral (23)" }
142 0           elsif ($res->{drug_dosage_form_code} eq '24') { $res->{drug_dosage_form_id} = "bedak (24)" }
143 0           elsif ($res->{drug_dosage_form_code} eq '28') { $res->{drug_dosage_form_id} = "gel (28)" }
144 0           elsif ($res->{drug_dosage_form_code} eq '29') { $res->{drug_dosage_form_id} = "krim (29)" }
145 0           elsif ($res->{drug_dosage_form_code} eq '30') { $res->{drug_dosage_form_id} = "salep (30)" }
146 0           elsif ($res->{drug_dosage_form_code} eq '31') { $res->{drug_dosage_form_id} = "salep mata (31)" }
147 0           elsif ($res->{drug_dosage_form_code} eq '32') { $res->{drug_dosage_form_id} = "emulsi (32)" }
148 0           elsif ($res->{drug_dosage_form_code} eq '33') { $res->{drug_dosage_form_id} = "suspensi (33)" }
149 0           elsif ($res->{drug_dosage_form_code} eq '34') { $res->{drug_dosage_form_id} = "elixir (34)" }
150 0           elsif ($res->{drug_dosage_form_code} eq '36') { $res->{drug_dosage_form_id} = "drops (36)" }
151 0           elsif ($res->{drug_dosage_form_code} eq '37') { $res->{drug_dosage_form_id} = "sirup (37)" }
152 0           elsif ($res->{drug_dosage_form_code} eq '38') { $res->{drug_dosage_form_id} = "suspensi kering (38)" }
153 0           elsif ($res->{drug_dosage_form_code} eq '41') { $res->{drug_dosage_form_id} = "lotion/solusio (41)" }
154 0           elsif ($res->{drug_dosage_form_code} eq '43') { $res->{drug_dosage_form_id} = "injeksi (43)" }
155 0           elsif ($res->{drug_dosage_form_code} eq '44') { $res->{drug_dosage_form_id} = "injeksi suspensi kering (44)" }
156 0           elsif ($res->{drug_dosage_form_code} eq '46') { $res->{drug_dosage_form_id} = "tetes mata steril (46)" }
157 0           elsif ($res->{drug_dosage_form_code} eq '47') { $res->{drug_dosage_form_id} = "tetes hidung (47)" }
158 0           elsif ($res->{drug_dosage_form_code} eq '48') { $res->{drug_dosage_form_id} = "tetes telinga (48)" }
159 0           elsif ($res->{drug_dosage_form_code} eq '49') { $res->{drug_dosage_form_id} = "infus (49)" }
160 0           elsif ($res->{drug_dosage_form_code} eq '53') { $res->{drug_dosage_form_id} = "supositoria, ovula (53)" }
161 0           elsif ($res->{drug_dosage_form_code} eq '56') { $res->{drug_dosage_form_id} = "nasal spray (56)" }
162 0           elsif ($res->{drug_dosage_form_code} eq '58') { $res->{drug_dosage_form_id} = "rectal tube (58)" }
163 0           elsif ($res->{drug_dosage_form_code} eq '62') { $res->{drug_dosage_form_id} = "inhalasi (62)" }
164 0           elsif ($res->{drug_dosage_form_code} eq '63') { $res->{drug_dosage_form_id} = "tablet kunyah (63)" }
165 0           elsif ($res->{drug_dosage_form_code} eq '81') { $res->{drug_dosage_form_id} = "tablet dispersi (81)" }
166 0           else { log_warn "Unknown drug dosage form code ($res->{drug_dosage_form_code}), known codes include 01/02/04/10/etc" }
167              
168             } elsif ($res->{category_code} =~ /\AS[DIL]\z/) {
169              
170             $res->{category_id} =
171             $res->{category_code} eq 'SD' ? 'Suplemen kesehatan (S), dalam negeri (D)' :
172 0 0         $res->{category_code} eq 'SI' ? 'Suplemen kesehatan (S), impor (I)' :
    0          
173             'Suplemen kesehatan (S), lisensi (L)';
174              
175 0 0         $res->{number} =~ /\A([0-9]{9})\z/
176             or return [400, "S number needs to be 9-digit number"];
177              
178             } elsif ($res->{category_code} =~ /\AN(.?)\z/) {
179              
180 0           $res->{cosmetic_category_code} = $1;
181 0           $res->{category_id} = "Kosmetik (N)";
182 0 0         if ($res->{cosmetic_category_code} eq 'A') { $res->{category_id} .= ", Asia termasuk lokal (A)" }
  0 0          
    0          
    0          
    0          
183 0           elsif ($res->{cosmetic_category_code} eq 'B') { $res->{category_id} .= ", Australia (B)" }
184 0           elsif ($res->{cosmetic_category_code} eq 'C') { $res->{category_id} .= ", Eropa (C)" }
185 0           elsif ($res->{cosmetic_category_code} eq 'D') { $res->{category_id} .= ", Afrika (D)" }
186 0           elsif ($res->{cosmetic_category_code} eq 'E') { $res->{category_id} .= ", Amerika (E)" }
187 0           else { return [400, "Invalid cosmetic category code ($res->{cosmetic_category_code}), valid code is A-E"] }
188              
189 0 0         $res->{number} =~ /\A([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{5})\z/
190             or return [400, "Nx number needs to be 11-digit number"];
191              
192 0           $res->{cosmetic_country_code} = $1;
193 0           $res->{cosmetic_year} = _2to4_dig_year($2);
194 0           $res->{cosmetic_group_code} = $3;
195 0           $res->{cosmetic_notification_code} = $4;
196              
197             } elsif ($res->{category_code} =~ /\AB?T(.)\z/) {
198              
199 0           $res->{trad_origin} = $1;
200 0 0         $res->{category_id} = $res->{category_code} =~ /\AB/ ? 'Obat traditional berbatasan dengan obat produksi (BT)' : 'Obat traditional (T)';
201 0 0         if ($res->{trad_origin} eq 'R') { $res->{category_id} .= ', dalam negeri (R)' }
  0 0          
    0          
202 0           elsif ($res->{trad_origin} eq 'I') { $res->{category_id} .= ', impor (I)' }
203 0           elsif ($res->{trad_origin} eq 'L') { $res->{category_id} .= ', dalam negeri dengan lisensi (L)' }
204 0           else { return [400, "Invalid traditional medicine origin code ($res->{trad_origin}), valid code is R/I/L"] }
205              
206 0 0         $res->{number} =~ /\A([0-9]{2})([0-9]{1})([0-9]{1})([0-9]{4})([0-9]{1})\z/
207             or return [400, "BTx/Tx number needs to be 9-digit number"];
208              
209 0           $res->{trad_year} = _2to4_dig_year($1);
210 0           $res->{trad_company_type_code} = $2;
211 0           $res->{trad_packaging_code} = $3;
212 0           $res->{trad_company_product_serial} = $4;
213 0           $res->{trad_packaging_volume_code} = $5;
214              
215 0 0         if ($res->{trad_company_type_code} == 1) { $res->{trad_company_type_id} = 'pabrik farmasi' }
  0 0          
    0          
    0          
216 0           elsif ($res->{trad_company_type_code} == 2) { $res->{trad_company_type_id} = 'pabrik jamu' }
217 0           elsif ($res->{trad_company_type_code} == 3) { $res->{trad_company_type_id} = 'perusahaan jamu' }
218 0           elsif ($res->{trad_company_type_code} == 4) { $res->{trad_company_type_id} = 'pabrik luar negeri' } # not documented, i guessed
219             else {
220 0           $res->{trad_company_type_id} = '?';
221 0           log_warn "Unknown traditional medicine company type code ($res->{trad_company_type_code}), known code is 1/2/3/4";
222             }
223              
224 0 0         if ($res->{trad_packaging_code} == 1) { $res->{trad_packaging_id} = 'rajangan' }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
225 0           elsif ($res->{trad_packaging_code} == 2) { $res->{trad_packaging_id} = 'serbuk' }
226 0           elsif ($res->{trad_packaging_code} == 3) { $res->{trad_packaging_id} = 'kapsul' }
227 0           elsif ($res->{trad_packaging_code} == 4) { $res->{trad_packaging_id} = 'pil, granul, boli, pastiles, jenang, tablet/kaplet' }
228 0           elsif ($res->{trad_packaging_code} == 5) { $res->{trad_packaging_id} = 'dodol, majun' }
229 0           elsif ($res->{trad_packaging_code} == 6) { $res->{trad_packaging_id} = 'cairan' }
230 0           elsif ($res->{trad_packaging_code} == 7) { $res->{trad_packaging_id} = 'salep, krim' }
231 0           elsif ($res->{trad_packaging_code} == 8) { $res->{trad_packaging_id} = 'plester, koyo' }
232 0           elsif ($res->{trad_packaging_code} == 9) { $res->{trad_packaging_id} = 'bentuk lain (mis: dupa, ratus, mangir, permen)' }
233              
234 0 0         if ($res->{trad_packaging_volume_code} == 1) { $res->{trad_packaging_volume} = '15ml' }
  0 0          
    0          
235 0           elsif ($res->{trad_packaging_volume_code} == 2) { $res->{trad_packaging_volume} = '30ml' }
236 0           elsif ($res->{trad_packaging_volume_code} == 3) { $res->{trad_packaging_volume} = '45ml' }
237 0           else { log_warn "Unknown traditional medicine package volume code ($res->{trad_packaging_volume_code}), known code is 1/2/3" }
238              
239             } elsif ($res->{category_code} =~ /\AFF\z/) {
240              
241 0           $res->{category_id} = 'Fitofarma (FF)';
242 0 0         $res->{number} =~ /\A([0-9]{9})\z/
243             or return [400, "FF number needs to be 9-digit number"];
244              
245             } elsif ($res->{category_code} =~ /\AHT\z/) {
246              
247 0           $res->{category_id} = 'Herbal terstandar (HT)';
248 0 0         $res->{number} =~ /\A([0-9]{9})\z/
249             or return [400, "HT number needs to be 9-digit number"];
250              
251             } else {
252              
253 0           return [400, "Unknown category code ($res->{category_code}), known category codes include MD/ML/TR/TI/SD/SI/etc"];
254              
255             }
256              
257 0           [200, "OK", $res];
258             }
259              
260             1;
261             # ABSTRACT: Parse food/drug registration code published by the Indonesian National Agency of Drug and Food Control (POM)
262              
263             __END__