Add selected non-PBS medicines
This commit is contained in:
parent
cd33823cc7
commit
eddbdfcccf
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
rm html/database.db
|
rm html/database.db
|
||||||
sqlite3 database.db '.dump meta pbs_item pbs_mp pbs_mp_brand_name pbs_mpp pbs_item_restriction pbs_restriction pbs_restriction_criteria pbs_criteria pbs_criteria_parameter' | sqlite3 html/database.db
|
sqlite3 database.db '.dump meta pbs_item pbs_mp mp_brand_name pbs_mpp pbs_item_restriction pbs_restriction pbs_restriction_criteria pbs_criteria pbs_criteria_parameter non_pbs_tpp' | sqlite3 html/database.db
|
||||||
|
@ -25,10 +25,11 @@ con.row_factory = sqlite3.Row
|
|||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
|
|
||||||
# Init schema
|
# Init schema
|
||||||
cur.execute('DROP TABLE IF EXISTS pbs_mp_brand_name')
|
cur.execute('DROP TABLE IF EXISTS mp_brand_name')
|
||||||
cur.execute('CREATE TABLE pbs_mp_brand_name (id INTEGER PRIMARY KEY AUTOINCREMENT, mp_code STRING, brand_name STRING)')
|
cur.execute('CREATE TABLE mp_brand_name (id INTEGER PRIMARY KEY AUTOINCREMENT, mp_preferred_term TEXT, brand_name TEXT)')
|
||||||
|
|
||||||
cur.execute('SELECT * FROM pbs_tpp LEFT JOIN (SELECT code, mp_code FROM pbs_mpp) AS pbs_mpp ON pbs_tpp.mpp_code = pbs_mpp.code LEFT JOIN (SELECT code, preferred_term as mp_preferred_term FROM pbs_mp) AS pbs_mp ON pbs_mpp.mp_code = pbs_mp.code')
|
# Get PBS brand names
|
||||||
|
cur.execute('SELECT brand_name, mp_preferred_term FROM pbs_tpp LEFT JOIN (SELECT code, mp_code FROM pbs_mpp) AS pbs_mpp ON pbs_tpp.mpp_code = pbs_mpp.code LEFT JOIN (SELECT code, preferred_term as mp_preferred_term FROM pbs_mp) AS pbs_mp ON pbs_mpp.mp_code = pbs_mp.code')
|
||||||
|
|
||||||
brand_names = {}
|
brand_names = {}
|
||||||
for tpp in cur.fetchall():
|
for tpp in cur.fetchall():
|
||||||
@ -53,21 +54,31 @@ for tpp in cur.fetchall():
|
|||||||
# OK!
|
# OK!
|
||||||
brand_name = ' '.join(words)
|
brand_name = ' '.join(words)
|
||||||
|
|
||||||
if tpp['mp_code'] not in brand_names:
|
if tpp['mp_preferred_term'] not in brand_names:
|
||||||
brand_names[tpp['mp_code']] = set()
|
brand_names[tpp['mp_preferred_term']] = set()
|
||||||
|
|
||||||
brand_names[tpp['mp_code']].add(brand_name)
|
brand_names[tpp['mp_preferred_term']].add(brand_name)
|
||||||
|
|
||||||
|
# Get non-PBS brand names
|
||||||
|
cur.execute('SELECT * FROM non_pbs_tpp')
|
||||||
|
for tpp in cur.fetchall():
|
||||||
|
# This is manually curated so no need for cleaning
|
||||||
|
|
||||||
|
if tpp['mp_preferred_term'] not in brand_names:
|
||||||
|
brand_names[tpp['mp_preferred_term']] = set()
|
||||||
|
|
||||||
|
brand_names[tpp['mp_preferred_term']].add(tpp['brand_name'])
|
||||||
|
|
||||||
# Reduce names with unambiguous prefixes
|
# Reduce names with unambiguous prefixes
|
||||||
for mp_code in sorted(brand_names.keys()):
|
for mp_preferred_term in sorted(brand_names.keys()):
|
||||||
for brand_name in list(brand_names[mp_code]):
|
for brand_name in list(brand_names[mp_preferred_term]):
|
||||||
# Can we reduce the length of the name?
|
# Can we reduce the length of the name?
|
||||||
words = brand_name.split()
|
words = brand_name.split()
|
||||||
|
|
||||||
for i in range(1, len(words)):
|
for i in range(1, len(words)):
|
||||||
short_name = ' '.join(words[0:i])
|
short_name = ' '.join(words[0:i])
|
||||||
|
|
||||||
if any(b.startswith(short_name) for m in brand_names.keys() if m != mp_code for b in brand_names[m]):
|
if any(b.startswith(short_name) for m in brand_names.keys() if m != mp_preferred_term for b in brand_names[m]):
|
||||||
# Conflict
|
# Conflict
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -76,14 +87,14 @@ for mp_code in sorted(brand_names.keys()):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Can shorten
|
# Can shorten
|
||||||
if brand_name in brand_names[mp_code]:
|
if brand_name in brand_names[mp_preferred_term]:
|
||||||
brand_names[mp_code].remove(brand_name)
|
brand_names[mp_preferred_term].remove(brand_name)
|
||||||
brand_names[mp_code].add(short_name)
|
brand_names[mp_preferred_term].add(short_name)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Add to database
|
# Add to database
|
||||||
for mp_code in sorted(brand_names.keys()):
|
for mp_preferred_term in sorted(brand_names.keys()):
|
||||||
for brand_name in sorted(list(brand_names[mp_code])):
|
for brand_name in sorted(list(brand_names[mp_preferred_term])):
|
||||||
cur.execute('INSERT INTO pbs_mp_brand_name (mp_code, brand_name) VALUES (?, ?)', (mp_code, brand_name))
|
cur.execute('INSERT INTO mp_brand_name (mp_preferred_term, brand_name) VALUES (?, ?)', (mp_preferred_term, brand_name))
|
||||||
|
|
||||||
con.commit()
|
con.commit()
|
@ -2,5 +2,6 @@
|
|||||||
|
|
||||||
./import_pbs_xml.py || exit 1
|
./import_pbs_xml.py || exit 1
|
||||||
./render_pbs_criteria.py || exit 1
|
./render_pbs_criteria.py || exit 1
|
||||||
./find_pbs_brand_names.py || exit 1
|
./import_non_pbs.py || exit 1
|
||||||
|
./find_brand_names.py || exit 1
|
||||||
./export_db.sh
|
./export_db.sh
|
||||||
|
@ -97,11 +97,11 @@
|
|||||||
document.getElementById('pbs-date').innerText = {'01': 'January', '02': 'February', '03': 'March', '04': 'April', '05': 'May', '06': 'June', '07': 'July', '08': 'August', '09': 'September', '10': 'October', '11': 'November', '12': 'December'}[pbs_date_bits[1]] + ' ' + pbs_date_bits[0];
|
document.getElementById('pbs-date').innerText = {'01': 'January', '02': 'February', '03': 'March', '04': 'April', '05': 'May', '06': 'June', '07': 'July', '08': 'August', '09': 'September', '10': 'October', '11': 'November', '12': 'December'}[pbs_date_bits[1]] + ' ' + pbs_date_bits[0];
|
||||||
|
|
||||||
// Initialise search bar
|
// Initialise search bar
|
||||||
const mp_preferred_terms = execAsScalars(db.prepare('SELECT preferred_term FROM pbs_mp ORDER BY LOWER(preferred_term)'));
|
const mp_preferred_terms = execAsScalars(db.prepare('SELECT * FROM (SELECT preferred_term FROM pbs_mp UNION SELECT mp_preferred_term AS preferred_term FROM non_pbs_tpp) ORDER BY LOWER(preferred_term)'));
|
||||||
let data = mp_preferred_terms.map(mp_preferred_term => ({'label': mp_preferred_term, 'preview': mp_preferred_term, 'value': mp_preferred_term}));
|
let data = mp_preferred_terms.map(mp_preferred_term => ({'label': mp_preferred_term, 'preview': mp_preferred_term, 'value': mp_preferred_term}));
|
||||||
|
|
||||||
const tpp_brand_names = execAsObjects(db.prepare('SELECT * FROM pbs_mp_brand_name LEFT JOIN pbs_mp ON pbs_mp_brand_name.mp_code = pbs_mp.code ORDER BY LOWER(brand_name)'));
|
const tpp_brand_names = execAsObjects(db.prepare('SELECT * FROM mp_brand_name ORDER BY LOWER(brand_name)'));
|
||||||
data = data.concat(tpp_brand_names.map(tpp_brand_name => ({'label': tpp_brand_name['brand_name'], 'preview': tpp_brand_name['brand_name'] + ' <span class="text-muted">(' + tpp_brand_name['preferred_term'] + ')</span>', 'value': tpp_brand_name['preferred_term']})));
|
data = data.concat(tpp_brand_names.map(tpp_brand_name => ({'label': tpp_brand_name['brand_name'], 'preview': tpp_brand_name['brand_name'] + ' <span class="text-muted">(' + tpp_brand_name['mp_preferred_term'] + ')</span>', 'value': tpp_brand_name['mp_preferred_term']})));
|
||||||
|
|
||||||
const autocomplete = new Autocomplete(document.getElementById('search-input'), {
|
const autocomplete = new Autocomplete(document.getElementById('search-input'), {
|
||||||
data: data,
|
data: data,
|
||||||
@ -120,7 +120,15 @@
|
|||||||
document.getElementById('search-input').value = item.value;
|
document.getElementById('search-input').value = item.value;
|
||||||
|
|
||||||
// Find matching PBS items
|
// Find matching PBS items
|
||||||
let stmt = db.prepare('SELECT * FROM pbs_item LEFT JOIN (SELECT code AS mpp_code, preferred_term AS mpp_preferred_term, mp_code FROM pbs_mpp) AS pbs_mpp ON pbs_item.mpp_code = pbs_mpp.mpp_code LEFT JOIN (SELECT code AS mp_code, preferred_term AS mp_preferred_term FROM pbs_mp) AS pbs_mp ON pbs_mpp.mp_code = pbs_mp.mp_code WHERE LOWER(mp_preferred_term) = ?');
|
let stmt = db.prepare(
|
||||||
|
'SELECT * FROM (' +
|
||||||
|
' SELECT code, mp_preferred_term, mpp_preferred_term, benefit_type, maximum_prescribable_units, number_repeats, program FROM pbs_item' +
|
||||||
|
' LEFT JOIN (SELECT code AS mpp_code, preferred_term AS mpp_preferred_term, mp_code FROM pbs_mpp) AS pbs_mpp ON pbs_item.mpp_code = pbs_mpp.mpp_code' +
|
||||||
|
' LEFT JOIN (SELECT code AS mp_code, preferred_term AS mp_preferred_term FROM pbs_mp) AS pbs_mp ON pbs_mpp.mp_code = pbs_mp.mp_code' +
|
||||||
|
' UNION SELECT DISTINCT NULL AS code, mp_preferred_term, mpp_preferred_term, "unrestricted" AS benefit_type, NULL AS maximum_prescribable_units, NULL AS number_repeats, "NA" AS program FROM non_pbs_tpp' +
|
||||||
|
' )' +
|
||||||
|
' WHERE LOWER(mp_preferred_term) = ?'
|
||||||
|
);
|
||||||
stmt.bind([item.value.toLowerCase()]);
|
stmt.bind([item.value.toLowerCase()]);
|
||||||
const items = execAsObjects(stmt);
|
const items = execAsObjects(stmt);
|
||||||
|
|
||||||
@ -136,7 +144,11 @@
|
|||||||
const restrictions = execAsObjects(stmt);
|
const restrictions = execAsObjects(stmt);
|
||||||
|
|
||||||
const tr = document.createElement('tr');
|
const tr = document.createElement('tr');
|
||||||
let td = document.createElement('td'); td.innerHTML = '<a href="https://www.pbs.gov.au/medicine/item/' + item['code'] + '" target="_blank">' + item['code'] + '</a>'; tr.appendChild(td);
|
let td = document.createElement('td');
|
||||||
|
if (item['code']) {
|
||||||
|
td.innerHTML = '<a href="https://www.pbs.gov.au/medicine/item/' + item['code'] + '" target="_blank">' + item['code'] + '</a>';
|
||||||
|
}
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
td = document.createElement('td');
|
td = document.createElement('td');
|
||||||
let div = document.createElement('div'); div.innerText = item['mpp_preferred_term']; td.appendChild(div);
|
let div = document.createElement('div'); div.innerText = item['mpp_preferred_term']; td.appendChild(div);
|
||||||
@ -174,8 +186,17 @@
|
|||||||
td = document.createElement('td'); td.innerText = item['maximum_prescribable_units']; tr.appendChild(td);
|
td = document.createElement('td'); td.innerText = item['maximum_prescribable_units']; tr.appendChild(td);
|
||||||
td = document.createElement('td'); td.innerText = item['number_repeats']; tr.appendChild(td);
|
td = document.createElement('td'); td.innerText = item['number_repeats']; tr.appendChild(td);
|
||||||
|
|
||||||
|
if (item['program'] !== 'GE') {
|
||||||
|
td = document.createElement('td');
|
||||||
if (item['program'] === 'R1') {
|
if (item['program'] === 'R1') {
|
||||||
td = document.createElement('td'); td.innerHTML = '<a href="https://www.pbs.gov.au/medicine/item/' + item['code'] + '" target="_blank">RPBS</a>'; tr.appendChild(td);
|
td.innerHTML = '<a href="https://www.pbs.gov.au/medicine/item/' + item['code'] + '" target="_blank">RPBS</a>';
|
||||||
|
} else if (item['program'] === 'NA') {
|
||||||
|
td.innerHTML = 'Non-PBS';
|
||||||
|
} else {
|
||||||
|
alert('Unknown program: ' + item['program']);
|
||||||
|
throw 'Unknown program: ' + item['program'];
|
||||||
|
}
|
||||||
|
tr.appendChild(td);
|
||||||
tr.classList.add('table-secondary');
|
tr.classList.add('table-secondary');
|
||||||
} else if (item['benefit_type'] === 'unrestricted') {
|
} else if (item['benefit_type'] === 'unrestricted') {
|
||||||
td = document.createElement('td'); tr.appendChild(td);
|
td = document.createElement('td'); tr.appendChild(td);
|
||||||
|
35
import_non_pbs.py
Executable file
35
import_non_pbs.py
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright © 2023 Lee Yingtong Li (RunasSudo)
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
# Open database
|
||||||
|
con = sqlite3.connect('database.db')
|
||||||
|
cur = con.cursor()
|
||||||
|
|
||||||
|
# Init schema
|
||||||
|
cur.execute('DROP TABLE IF EXISTS non_pbs_tpp')
|
||||||
|
cur.execute('CREATE TABLE non_pbs_tpp (mp_preferred_term TEXT, mpp_preferred_term TEXT, brand_name TEXT)')
|
||||||
|
|
||||||
|
with open('non_pbs.csv', 'r', newline='') as f:
|
||||||
|
reader = csv.DictReader(f)
|
||||||
|
|
||||||
|
for tpp in reader:
|
||||||
|
if not tpp['Hide']:
|
||||||
|
cur.execute('INSERT INTO non_pbs_tpp (mp_preferred_term, mpp_preferred_term, brand_name) VALUES (?, ?, ?)', (tpp['MP'], tpp['MPP'], tpp['TPP']))
|
||||||
|
|
||||||
|
con.commit()
|
27
non_pbs.csv
Normal file
27
non_pbs.csv
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
MP,MPP,TPP,Source,Accessed,Hide
|
||||||
|
colecalciferol,"colecalciferol 25 microgram (1000 units) tablet, 60",OsteVit-D One-A-Day,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=74470001_2,2023-02-24,
|
||||||
|
colecalciferol,"colecalciferol 25 microgram (1000 units) tablet, 250",OsteVit-D One-A-Day,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=74470001_2,2023-02-24,Hide
|
||||||
|
colecalciferol,"colecalciferol 25 microgram (1000 units) capsule, 60",Caltrate Vitamin D Daily,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=2930001_2,2023-02-24,
|
||||||
|
colecalciferol,"colecalciferol 25 microgram (1000 units) capsule, 60",Ostelin,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=21920001_2,2023-02-24,
|
||||||
|
colecalciferol,"colecalciferol 25 microgram (1000 units) capsule, 130",Ostelin,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=21920001_2,2023-02-24,Hide
|
||||||
|
colecalciferol,"colecalciferol 25 microgram (1000 units) capsule, 250",Ostelin,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=21920001_2,2023-02-24,Hide
|
||||||
|
calcium + colecalciferol,"calcium 600 mg + colecalciferol 12.5 microgram (500 units) tablet, 60",Caltrate Bone Health,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/endocrine-drugs/drugs-affecting-bone/other-drugs-affecting-bone/calcium,2023-02-24,
|
||||||
|
calcium + colecalciferol,"calcium 600 mg + colecalciferol 12.5 microgram (500 units) tablet, 100",Caltrate Bone Health,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/endocrine-drugs/drugs-affecting-bone/other-drugs-affecting-bone/calcium,2023-02-24,Hide
|
||||||
|
calcium + colecalciferol,"calcium 600 mg + colecalciferol 12.5 microgram (500 units) tablet, 120",Caltrate Bone Health,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/endocrine-drugs/drugs-affecting-bone/other-drugs-affecting-bone/calcium,2023-02-24,Hide
|
||||||
|
calcium + colecalciferol,"calcium 600 mg + colecalciferol 12.5 microgram (500 units) tablet, 60",Cal-600 + D,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/endocrine-drugs/drugs-affecting-bone/other-drugs-affecting-bone/calcium,2023-02-24,
|
||||||
|
calcium + colecalciferol,"calcium 600 mg + colecalciferol 12.5 microgram (500 units) tablet, 100",Cal-600 + D,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/endocrine-drugs/drugs-affecting-bone/other-drugs-affecting-bone/calcium,2023-02-24,Hide
|
||||||
|
calcium + colecalciferol,"calcium 600 mg + colecalciferol 12.5 microgram (500 units) tablet, 60",Ostelin Calcium & Vitamin D3,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/endocrine-drugs/drugs-affecting-bone/other-drugs-affecting-bone/calcium,2023-02-24,
|
||||||
|
calcium + colecalciferol,"calcium 600 mg + colecalciferol 12.5 microgram (500 units) tablet, 130",Ostelin Calcium & Vitamin D3,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/endocrine-drugs/drugs-affecting-bone/other-drugs-affecting-bone/calcium,2023-02-24,Hide
|
||||||
|
calcium + colecalciferol,"calcium 600 mg + colecalciferol 12.5 microgram (500 units) tablet, 250",Ostelin Calcium & Vitamin D3,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/endocrine-drugs/drugs-affecting-bone/other-drugs-affecting-bone/calcium,2023-02-24,Hide
|
||||||
|
calcium + colecalciferol,"calcium 600 mg + colecalciferol 12.5 microgram (500 units) chewable tablet, 60",Ostelin Calcium & Vitamin D3,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/endocrine-drugs/drugs-affecting-bone/other-drugs-affecting-bone/calcium,2023-02-24,Hide
|
||||||
|
ferrous sulfate + folic acid,"ferrous sulfate 270 mg (iron 87.4 mg) + folic acid 300 microgram capsule, 30",Fefol,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=2850001_2,2023-02-24,
|
||||||
|
ferrous sulfate + folic acid,"ferrous sulfate 270 mg (iron 87.4 mg) + folic acid 300 microgram capsule, 60",Fefol,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=2850001_2,2023-02-24,Hide
|
||||||
|
ferrous fumarate + ascorbic acid,"ferrous fumarate 304 mg (iron 100 mg) + ascorbic acid 20 mg capsule, 30",Ferropods,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=135900001_2,2023-02-24,
|
||||||
|
ferrous sulfate,"ferrous sulfate 325 mg (iron 105 mg) tablet, 30",Ferro-grad,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=2870001_2,2023-02-24,
|
||||||
|
ferrous sulfate + ascorbic acid,"ferrous sulfate 325 mg (iron 105 mg) + ascorbic acid 500 mg tablet, 30",Ferro-grad C,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=48460001_2,2023-02-24,
|
||||||
|
ferrous sulfate + folic acid,"ferrous sulfate 250 mg (iron 80 mg) + folic acid 300 microgram tablet, 30",Ferro-grad F,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=2900001_2,2023-02-24,
|
||||||
|
iron polymaltose,"iron (as polymaltose) 100 mg tablet, 30",Maltofer,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=6800001_2,2023-02-24,
|
||||||
|
sodium chloride,"sodium chloride 600 mg tablet, 100",Saltabs,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=130430001_2,2023-02-24,
|
||||||
|
sodium chloride,"sodium chloride 600 mg tablet, 100",Toppin,https://www.mimsonline.com.au.acs.hcn.com.au/Search/AbbrPI.aspx?ID=21820001_2,2023-02-24,
|
||||||
|
zinc sulfate,"zinc (as sulfate) 50 mg capsule, 100",Zincaps,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/blood-electrolytes/tables/oral-electrolytes-table,2023-02-24,
|
||||||
|
tapentadol,"tapentadol 50 mg tablet, 20",Palexia IR,https://amhonline.amh.net.au.acs.hcn.com.au/chapters/analgesics/drugs-pain-relief/opioid-analgesics/tapentadol,2023-02-24,
|
|
Loading…
Reference in New Issue
Block a user