Fakultas Ilmu Komputer UI
Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ppl-fasilkom-ui
2020
PPL-C
PPTI-Mobile Apps Monitoring Wabah Tuberkolosis
Neza-Backend
Commits
aa078106
Commit
aa078106
authored
Jun 04, 2020
by
Jonathan Christopher Jakub
Browse files
Implement CSV field formatter
parent
52aeffdc
Changes
7
Hide whitespace changes
Inline
Side-by-side
apps/commons/permissions.py
View file @
aa078106
...
...
@@ -6,6 +6,10 @@ from django.core.exceptions import ObjectDoesNotExist
class
IsAuthenticated
(
BasePermission
):
def
has_permission
(
self
,
request
,
view
):
user
=
request
.
user
if
not
hasattr
(
user
,
"account"
):
return
False
return
(
user
.
is_authenticated
and
user
.
account
.
is_active
...
...
apps/commons/tests/test_permissions.py
View file @
aa078106
...
...
@@ -19,6 +19,7 @@ class IsAuthenticatedPermissionTest(APITestCase):
cls
.
user_1
=
UserFactory
(
username
=
"user_1"
,
password
=
"justpass"
)
cls
.
user_2
=
UserFactory
(
username
=
"user_2"
,
password
=
"justpass"
)
cls
.
user_3
=
UserFactory
(
username
=
"user_3"
,
password
=
"justpass"
)
cls
.
user_4
=
UserFactory
(
username
=
"user_4"
,
password
=
"justpass"
)
cls
.
account_1
=
AccountFactory
(
admin
=
True
,
...
...
@@ -32,7 +33,7 @@ class IsAuthenticatedPermissionTest(APITestCase):
is_active
=
False
,
is_verified
=
True
)
cls
.
account_
2
=
AccountFactory
(
cls
.
account_
3
=
AccountFactory
(
admin
=
False
,
user
=
cls
.
user_3
,
is_active
=
True
,
...
...
@@ -62,6 +63,12 @@ class IsAuthenticatedPermissionTest(APITestCase):
request
.
user
=
self
.
user_3
self
.
assertFalse
(
self
.
permission
.
has_permission
(
request
,
None
))
def
test_has_permission_false_for_anonymous_user
(
self
):
self
.
client
=
APIClient
()
request
=
self
.
client
.
get
(
"/"
).
wsgi_request
request
.
user
=
self
.
user_4
self
.
assertFalse
(
self
.
permission
.
has_permission
(
request
,
None
))
class
CreateOnlyPermissionTest
(
APITestCase
):
@
classmethod
...
...
apps/exportables/constants.py
View file @
aa078106
...
...
@@ -34,3 +34,39 @@ UNDETERMINED = "undetermined"
# Total
TOTAL
=
"total_count"
# CSV Fields
INVESTIGATION_CASE_RENDERER_FIELDS
=
[
"case_subject__name"
,
"case_subject__address"
,
"case_subject__age"
,
"case_subject__is_male"
,
"case_subject__district"
,
"case_subject__sub_district"
,
"case_relation"
,
"reference_case__case_subject__name"
,
"outcome"
,
"medical_symptoms"
,
"risk_factors"
,
"medical_facility_reference"
,
"created_at"
,
"author__name"
,
]
INVESTIGATION_CASE_HEADER_FIELDS
=
[
"nama"
,
"alamat"
,
"usia"
,
"jenis_kelamin"
,
"kabupaten"
,
"kecamatan"
,
"jenis_kontak"
,
"subyek_kasus_acuan"
,
"hasil_pemeriksaan"
,
"gejala_medis"
,
"faktor_risiko"
,
"rujukan_fasilitas_kesehatan"
,
"tanggal_pencatatan"
,
"kader_pencatat"
,
]
apps/exportables/renderers.py
View file @
aa078106
from
rest_framework_csv.renderers
import
CSVRenderer
INVESTIGATION_CASE_RENDERER_FIELDS
=
[
"id"
,
"case_subject__age"
,
"case_subject__is_male"
,
"case_subject__district"
,
"outcome"
,
"is_positive"
,
"case_relation"
,
"medical_symptoms"
,
"risk_factors"
,
"is_referral_needed"
,
"medical_facility_reference"
,
"created_at"
,
"author__name"
,
]
from
apps.exportables.constants
import
INVESTIGATION_CASE_HEADER_FIELDS
class
InvestigationCaseCSVRenderer
(
CSVRenderer
):
header
=
INVESTIGATION_CASE_
RENDER
ER_FIELDS
header
=
INVESTIGATION_CASE_
HEAD
ER_FIELDS
apps/exportables/tests/test_units/test_exportables.py
View file @
aa078106
...
...
@@ -2,13 +2,22 @@ import json
import
csv
import
io
from
rest_framework
import
status
from
rest_framework.test
import
APITestCase
from
rest_framework.authtoken.models
import
Token
from
rest_framework.test
import
APITestCase
,
APIClient
from
apps.constants
import
HEADER_PREFIX
from
apps.accounts.tests.factories.accounts
import
AccountFactory
,
UserFactory
from
apps.cases.models
import
CaseSubject
from
apps.cases.tests.factories.case_subjects
import
CaseSubjectFactory
from
apps.cases.tests.factories.cases
import
InvestigationCaseFactory
from
apps.exportables.renderers
import
INVESTIGATION_CASE_RENDERER_FIELDS
from
apps.exportables.constants
import
(
INVESTIGATION_CASE_HEADER_FIELDS
,
INVESTIGATION_CASE_RENDERER_FIELDS
,
)
def
init_data
():
...
...
@@ -57,8 +66,15 @@ def init_data():
class
ExportableViewTest
(
APITestCase
):
@
classmethod
def
setUpTestData
(
cls
):
cls
.
user
=
UserFactory
(
username
=
"user"
,
password
=
"justpass"
)
cls
.
admin
=
AccountFactory
(
admin
=
True
,
user
=
cls
.
user
)
cls
.
token
,
_
=
Token
.
objects
.
get_or_create
(
user
=
cls
.
user
)
init_data
()
def
setUp
(
self
):
self
.
client
=
APIClient
(
HTTP_AUTHORIZATION
=
HEADER_PREFIX
+
self
.
token
.
key
)
def
test_exportable_data_return_values
(
self
):
url
=
"/exportables/"
response
=
self
.
client
.
get
(
url
)
...
...
@@ -189,9 +205,16 @@ class ExportableViewTest(APITestCase):
class
ExportInvestigationCaseViewTest
(
APITestCase
):
@
classmethod
def
setUpTestData
(
cls
):
cls
.
user
=
UserFactory
(
username
=
"user"
,
password
=
"justpass"
)
cls
.
admin
=
AccountFactory
(
admin
=
True
,
user
=
cls
.
user
)
cls
.
token
,
_
=
Token
.
objects
.
get_or_create
(
user
=
cls
.
user
)
cls
.
BASE_URL
=
"/exportables/investigation-cases-csv/"
init_data
()
def
setUp
(
self
):
self
.
client
=
APIClient
(
HTTP_AUTHORIZATION
=
HEADER_PREFIX
+
self
.
token
.
key
)
def
export_csv_test_util
(
self
,
filter
):
url
=
self
.
BASE_URL
+
filter
response
=
self
.
client
.
get
(
url
)
...
...
@@ -207,7 +230,7 @@ class ExportInvestigationCaseViewTest(APITestCase):
body
=
list
(
reader
)
headers
=
body
.
pop
(
0
)
self
.
assertEqual
(
headers
,
INVESTIGATION_CASE_
RENDER
ER_FIELDS
)
self
.
assertEqual
(
headers
,
INVESTIGATION_CASE_
HEAD
ER_FIELDS
)
return
body
def
wrong_query_param_test_util
(
self
,
filter
):
...
...
apps/exportables/utils.py
View file @
aa078106
import
json
import
time
from
django.utils
import
timezone
from
apps.exportables.constants
import
(
DISTRICT
,
DISTRICTS
,
...
...
@@ -6,10 +10,15 @@ from apps.exportables.constants import (
NEGATIVE
,
POSITIVE
,
TOTAL
,
UNDETERMINED
UNDETERMINED
,
INVESTIGATION_CASE_HEADER_FIELDS
,
INVESTIGATION_CASE_RENDERER_FIELDS
,
)
# CASE STATISTIC COUNTS
def
generate_initial_counts
():
return
{
POSITIVE
:
0
,
...
...
@@ -43,3 +52,40 @@ def map_sex_value(sex):
if
sex
:
return
MALE
return
FEMALE
# CSV EXPORTS
def
format_custom_csv_rows
(
cases_csv_rows
):
formatted_rows
=
[]
FIELDS_LENGTH
=
len
(
INVESTIGATION_CASE_RENDERER_FIELDS
)
for
row
in
cases_csv_rows
:
formatted_row
=
{}
for
field_name_index
in
range
(
FIELDS_LENGTH
):
original_field_name
=
INVESTIGATION_CASE_RENDERER_FIELDS
[
field_name_index
]
target_field_name
=
INVESTIGATION_CASE_HEADER_FIELDS
[
field_name_index
]
formatted_row
[
target_field_name
]
=
row
[
original_field_name
]
value
=
formatted_row
[
"jenis_kelamin"
]
formatted_row
[
"jenis_kelamin"
]
=
"Laki-laki"
if
value
else
"Perempuan"
value
=
json
.
loads
(
formatted_row
[
"gejala_medis"
])
selected_values
=
[
key
for
key
in
value
.
keys
()
if
value
[
key
]]
formatted_row
[
"gejala_medis"
]
=
"; "
.
join
(
selected_values
)
value
=
json
.
loads
(
formatted_row
[
"faktor_risiko"
])
selected_values
=
[
key
for
key
in
value
.
keys
()
if
value
[
key
]]
formatted_row
[
"faktor_risiko"
]
=
"; "
.
join
(
selected_values
)
value
=
formatted_row
[
"tanggal_pencatatan"
]
formatted_row
[
"tanggal_pencatatan"
]
=
timezone
.
localtime
(
value
)
formatted_rows
.
append
(
formatted_row
)
return
formatted_rows
apps/exportables/views.py
View file @
aa078106
...
...
@@ -9,6 +9,7 @@ from apps.cases.models import (
CaseSubject
,
InvestigationCase
,
)
from
apps.commons.permissions
import
IsAuthenticated
from
apps.exportables.constants
import
(
AGE
,
DISTRICT
,
...
...
@@ -19,31 +20,32 @@ from apps.exportables.constants import (
POSITIVE
,
SEX
,
TOTAL
,
UNDETERMINED
UNDETERMINED
,
INVESTIGATION_CASE_RENDERER_FIELDS
,
)
from
apps.exportables.utils
import
(
format_custom_csv_rows
,
generate_initial_counts
,
generate_initial_group_counts
,
map_outcome_value
,
map_sex_value
,
)
from
apps.exportables.renderers
import
(
InvestigationCaseCSVRenderer
,
INVESTIGATION_CASE_RENDERER_FIELDS
,
)
from
apps.exportables.renderers
import
InvestigationCaseCSVRenderer
class
CaseCountsView
(
APIView
):
permission_classes
=
(
IsAuthenticated
,)
def
get
(
self
,
request
,
format
=
None
):
case_subjects
=
CaseSubject
.
objects
.
all
()
investigation_cases
=
(
InvestigationCase
.
objects
.
values
(
"case_subject"
)
.
annotate
(
latest_investigation_case
=
Max
(
"created_at"
))
.
order_by
()
.
values
(
"case_subject__id"
,
"is_positive"
)
)
investigation_cases
=
(
InvestigationCase
.
objects
.
values
(
"case_subject"
)
.
annotate
(
latest_investigation_case
=
Max
(
"created_at"
))
.
order_by
()
.
values
(
"case_subject__id"
,
"is_positive"
)
)
outcomes
=
{}
...
...
@@ -91,6 +93,7 @@ class CaseCountsView(APIView):
class
ExportInvestigationCaseView
(
APIView
):
permission_classes
=
(
IsAuthenticated
,)
renderer_classes
=
(
InvestigationCaseCSVRenderer
,)
def
get
(
self
,
request
,
format
=
None
):
...
...
@@ -127,9 +130,14 @@ class ExportInvestigationCaseView(APIView):
cases
.
prefetch_related
(
"case_subject"
,
"reference_case"
,
"author"
).
values
(
*
INVESTIGATION_CASE_RENDERER_FIELDS
))
"author"
).
values
(
*
INVESTIGATION_CASE_RENDERER_FIELDS
)
)
formatted_data
=
format_custom_csv_rows
(
data
)
filename
=
"cases-{}.csv"
.
format
(
timezone
.
localtime
(
timezone
.
now
()))
headers
=
{
"Content-Disposition"
:
'attachment; filename="{}"'
.
format
(
filename
)}
return
Response
(
data
,
headers
=
headers
)
return
Response
(
formatted_
data
,
headers
=
headers
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment