Skip to content

Commit

Permalink
Bugs/WP-789: Extension Edit Modal (#382)
Browse files Browse the repository at this point in the history
* WP-789:Extension Edit Modal fixes

* New api is only for admin users

* Remove print

* handle "None" for expiration date
  • Loading branch information
chandra-tacc authored Dec 4, 2024
1 parent 9828bc1 commit 3cdd1a6
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 122 deletions.
16 changes: 6 additions & 10 deletions apcd_cms/src/apps/admin_extension/views.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,30 @@
from django.http import HttpResponseRedirect, HttpResponse, JsonResponse
from django.core.paginator import Paginator, EmptyPage
from django.http import HttpResponseRedirect, JsonResponse
from django.views.generic.base import TemplateView
from django.views import View
from django.template import loader
from apps.utils.apcd_database import get_all_extensions, update_extension
from apps.utils.apcd_database import get_all_extensions, update_extension
from apps.utils.apcd_groups import is_apcd_admin
from apps.utils.utils import table_filter
from apps.utils.utils import title_case
from apps.components.paginator.paginator import paginator
from dateutil import parser
from datetime import date as datetimeDate
from datetime import datetime
import logging
import json

logger = logging.getLogger(__name__)


class AdminExtensionsTable(TemplateView):

template_name = 'list_admin_extension.html'

def get(self, request, *args, **kwargs):
extension_content = get_all_extensions()

#context = self.get_context_data(extension_content, *args,**kwargs)
#template = loader.get_template(self.template_name)
#return HttpResponse(template.render(context, request))
context = self.get_extensions_list_json(extension_content, *args, **kwargs)
return JsonResponse({'response': context})

def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated or not is_apcd_admin(request.user):
if not request.user.is_authenticated or not is_apcd_admin(request.user):
return HttpResponseRedirect('/')
return super(AdminExtensionsTable, self).dispatch(request, *args, **kwargs)

Expand Down Expand Up @@ -131,13 +125,15 @@ def _set_extension(self, ext):
'notes': ext[17] if ext[17] else "None",
}


# function converts int value in the format YYYYMM to a string with abbreviated month and year
def _get_applicable_data_period(value):
try:
return datetime.strptime(str(value), '%Y%m').strftime('%b. %Y')
except:
return None


class UpdateExtensionsView(View):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated or not is_apcd_admin(request.user):
Expand Down
6 changes: 3 additions & 3 deletions apcd_cms/src/apps/common_api/urls.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from django.urls import path
from apps.common_api.views import EntitiesView, cdlsView
from . import views
from apps.common_api.views import EntitiesView, cdlsView, DataPeriodsView

app_name = 'common_api'
urlpatterns = [
path('entities/', EntitiesView.as_view(), name='entities_api'),
path('cdls/', cdlsView.as_view(), name='cdls_api'),
path('cdls/<str:file_type>', cdlsView.as_view(), name='cdls_api')
path('cdls/<str:file_type>', cdlsView.as_view(), name='cdls_api'),
path('data_periods/', DataPeriodsView.as_view(), name='dataperiods_api')
]
68 changes: 46 additions & 22 deletions apcd_cms/src/apps/common_api/views.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.template import loader
from django.http import HttpResponseRedirect, JsonResponse, Http404
from django.views.generic import TemplateView
from apps.utils import apcd_database
from apps.utils.apcd_groups import has_apcd_group
from apps.utils.apcd_groups import has_apcd_group, is_apcd_admin
from apps.utils.utils import title_case
from datetime import datetime
import logging
import json

logger = logging.getLogger(__name__)


class EntitiesView(TemplateView):
def get(self, request, *args, **kwargs):
submitters = apcd_database.get_submitter_info(request.user.username)
Expand All @@ -27,12 +26,6 @@ def dispatch(self, request, *args, **kwargs):
def get_submitter_info_json(self, submitters):
context = {}

def _get_applicable_data_period(value):
try:
return datetime.strptime(str(value), '%Y%m').strftime('%Y-%m')
except Exception:
return None

def _set_submitter(sub, data_periods):
return {
"submitter_id": sub[0],
Expand All @@ -46,23 +39,18 @@ def _set_submitter(sub, data_periods):
context["submitters"] = []

for submitter in submitters:
data_periods = []
submitter_id = submitter[0]
applicable_data_periods = apcd_database.get_applicable_data_periods(submitter[0])
for data_period_tuple in applicable_data_periods:
for data_period in data_period_tuple:
data_period = _get_applicable_data_period(data_period)
expected_dates = apcd_database.get_current_exp_date(submitter_id=submitter_id, applicable_data_period=data_period.replace('-', ''))
data_periods.append({
'data_period': data_period,
'expected_date': expected_dates[0][0] if expected_dates else ''
})
data_periods = sorted(data_periods, key=lambda x: x['data_period'], reverse=True)
data_periods = _getApplicableDataPeriods(submitter[0])
context["submitters"].append(_set_submitter(submitter, data_periods))

return context


class cdlsView(TemplateView):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated or not has_apcd_group(request.user):
return HttpResponseRedirect('/')
return super(cdlsView, self).dispatch(request, *args, **kwargs)

def get(self, request, *args, **kwargs):
file_type = kwargs.get('file_type')

Expand All @@ -81,3 +69,39 @@ def _set_cdls(cdl):
cdls_response.append(_set_cdls(cdl))

return JsonResponse({"cdls": cdls_response})


class DataPeriodsView(TemplateView):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated or not is_apcd_admin(request.user):
return HttpResponseRedirect('/')
return super(DataPeriodsView, self).dispatch(request, *args, **kwargs)

def get(self, request, *args, **kwargs):
submitter_id = request.GET.get('submitter_id', None)
if submitter_id is None:
raise Http404("Submitter Id not provided")
applicable_data_periods = _getApplicableDataPeriods(submitter_id)

return JsonResponse({'response': {"data_periods": applicable_data_periods}})


def _getApplicableDataPeriods(submitter_id):
def _get_applicable_data_period(value):
try:
return datetime.strptime(str(value), '%Y%m').strftime('%Y-%m')
except Exception:
return None

data_periods = []
applicable_data_periods = apcd_database.get_applicable_data_periods(submitter_id)
for data_period_tuple in applicable_data_periods:
for data_period in data_period_tuple:
data_period = _get_applicable_data_period(data_period)
expected_dates = apcd_database.get_current_exp_date(submitter_id=submitter_id, applicable_data_period=data_period.replace('-', ''))
data_periods.append({
'data_period': data_period,
'expected_date': expected_dates[0][0] if expected_dates else ''
})
data_periods = sorted(data_periods, key=lambda x: x['data_period'], reverse=True)
return data_periods
91 changes: 38 additions & 53 deletions apcd_cms/src/apps/utils/apcd_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -1070,70 +1070,55 @@ def create_extension(form, extension, sub_data):
if conn is not None:
conn.close()


def update_extension(form):
cur = None
conn = None
try:
conn = psycopg.connect(
host=APCD_DB['host'],
dbname=APCD_DB['database'],
user=APCD_DB['user'],
password=APCD_DB['password'],
port=APCD_DB['port'],
sslmode='require'
)
cur = conn.cursor()
operation = """UPDATE extensions
SET
updated_at= %s,"""

set_values = []
# to set column names for query to the correct DB name
columns = {
'applicable_data_period': 'applicable_data_period',
'status': 'status',
'outcome': 'outcome',
'approved_expiration_date': 'approved_expiration_date'
}
# To make sure fields are not blank.
# If they aren't, add column to update set operation
for field, column_name in columns.items():
value = form.get(field)
if value not in (None, ""):
set_values.append(f"{column_name} = %s")

# to allow notes to be cleared, need to move notes out of the loop that ignores none
operation += ", ".join(set_values) + ", notes = %s WHERE extension_id = %s"
## add last update time to all extension updates
values = [
datetime.now(),
]

for field, column_name in columns.items():
value = form.get(field)
print(value)
if value not in (None, ""):
# to make sure applicable data period field is an int to insert to DB
if column_name == 'applicable_data_period':
values.append(int(value.replace('-', '')))
# else server side clean values
else:
values.append(_clean_value(value))

# to allow notes to be cleared, need to move notes out of the loop that ignores none
values.append(_clean_value(form['notes']))
## to make sure extension id is last in query to match with WHERE statement
values.append(_clean_value(form['extension_id']))

cur.execute(operation, values)
conn.commit()
with db_connect() as conn:
cur = conn.cursor()
query = "UPDATE extensions SET updated_at = %s"
values = [datetime.now()] # Timestamp for updated_at

# Map form fields to DB columns
columns = {
'applicable_data_period': 'applicable_data_period',
'status': 'status',
'outcome': 'outcome',
'approved_expiration_date': 'approved_expiration_date'
}

# Build the SET clause dynamically
set_clauses = []
for field, column_name in columns.items():
value = form.get(field)
if value not in (None, "", "None"):
set_clauses.append(f"{column_name} = %s")
if column_name == 'applicable_data_period':
values.append(int(value.replace('-', '')))
elif column_name == 'approved_expiration_date':
# Convert to None if the value is 'None' (string)
values.append(None if value == 'None' else _clean_value(value))
else:
values.append(_clean_value(value))

# Include 'notes' field, allowing it to be cleared
set_clauses.append("notes = %s")
values.append(_clean_value(form.get('notes', "")))

query += ", " + ", ".join(set_clauses) + " WHERE extension_id = %s"
values.append(_clean_value(form['extension_id']))

cur.execute(query, values)
conn.commit()
except Exception as error:
logger.error(error)
return error
finally:
if cur is not None:
cur.close()


def get_submitter_info(user):
cur = None
conn = None
Expand Down
Loading

0 comments on commit 3cdd1a6

Please sign in to comment.