Skip to content

Commit

Permalink
Tracking pull request to merge release-1.27.0 to main (#713)
Browse files Browse the repository at this point in the history
* initial update for 1.27.0

* update tracking pr number

* update cleanup cron

* itvr 620 feat: Driver's License Verification  (#715)

* feat: adds backend validation for drivers licences, must be 7-8 characters and if 7 characters must start with 0 or 3.

* feat: adds drivers licence validation to frontend

* feat: 698 - extend rebate expiry (#716)

* feat: 698 - extend rebate expiry

* update migration

* fix: 717 - fix typo (#718)

---------

Co-authored-by: Emily <[email protected]>
Co-authored-by: tim738745 <[email protected]>
  • Loading branch information
3 people authored Jun 11, 2024
1 parent 9e3eeed commit 3d3e01d
Show file tree
Hide file tree
Showing 20 changed files with 274 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dev-cicd.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## For each release, the value of workflow name, branches and PR_NUMBER need to be adjusted accordingly

name: ITVR Dev release-1.26.0
name: ITVR Dev release-1.27.0

on:
pull_request:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release-build.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
name: ITVR release-1.26.0
name: ITVR release-1.27.0

on:
workflow_dispatch:
inputs:
pull_request:
description: "Tracking pull request number"
required: true
default: 703
default: 713
release_branch:
description: "The name of the release branch"
required: true
default: release-1.26.0
default: release-1.27.0

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ chart/itvr/charts/itvr-minio/charts/
cron.log
.pipeline/package-lock.json
*.tgz
docker-compose-dev.yml
docker-compose-dev.yml
*.sql
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ You can view Django Restframework's browseable api here: `http://localhost:8000/

Use a created superuser to login and view the api.

### postgres
To get into postgres in terminal
docker-compose exec db psql -U postgres itvr


#### MinIO

You can view the contents of the bucket in MinIO by visiting `http://localhost:9001/login`. Use env variables `MINIO_ROOT_USER` and `MINIO_ROOT_PASSWORD` to login to the console. Default values are found in `minio.env`
Expand Down
97 changes: 95 additions & 2 deletions django/api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
CancellableGoElectricRebateApplication,
DriverLicenceEditableGoElectricRebateApplication,
ChangeRedeemedGoElectricRebateApplication,
ExpiredGoElectricRebateApplication,
)
from .models.household_member import HouseholdMember
from .models.go_electric_rebate import GoElectricRebate
Expand All @@ -15,11 +16,18 @@
from . import messages_custom
from django.db.models import Q
from django.db import transaction
from api.services.ncda import delete_rebate, update_rebate
from api.services.ncda import (
delete_rebate,
update_rebate,
get_rebate_by_drivers_licence,
notify,
)
from django_q.tasks import async_task
from api.services.go_electric_rebate_application import (
equivalent_drivers_licence_number_found,
)
from api.model_forms.extend_expired_application import ExtendExpiryForm
from datetime import date, timedelta


class ITVRModelAdmin(admin.ModelAdmin):
Expand Down Expand Up @@ -440,7 +448,7 @@ def edit_drivers_licence(self, request, object_id, form_url, extra_context):


@admin.register(ChangeRedeemedGoElectricRebateApplication)
class ChangeRedeemedGoElectricRebateApplication(ITVRModelAdmin):
class ChangeRedeemedGoElectricRebateApplicationAdmin(ITVRModelAdmin):
search_fields = ["drivers_licence", "id", "status", "last_name"]
exclude = (
"sin",
Expand Down Expand Up @@ -497,3 +505,88 @@ def response_change(self, request, obj):
if ncda_id is not None:
update_rebate(ncda_id, {"Status": "Not-Redeemed"})
return ret


@admin.register(ExpiredGoElectricRebateApplication)
class ExpiredGoElectricRebateApplicationAdmin(ITVRModelAdmin):
form = ExtendExpiryForm
search_fields = ["drivers_licence", "id", "last_name"]
exclude = (
"sin",
"doc1",
"doc2",
"user",
"spouse_email",
"status",
"address",
"city",
"postal_code",
"application_type",
"doc1_tag",
"doc2_tag",
"consent_personal",
"consent_tax",
"reason_for_decline",
)
readonly_fields = (
"id",
"last_name",
"first_name",
"middle_names",
"status",
"email",
"user_is_bcsc",
"drivers_licence",
"date_of_birth",
"tax_year",
"is_legacy",
"confirmation_email_success",
"spouse_email_success",
"created",
"approved_on",
"not_approved_on",
)

def get_queryset(self, request):
return GoElectricRebateApplication.objects.filter(
status=GoElectricRebateApplication.Status.EXPIRED
)

def response_change(self, request, obj):
ret = super().response_change(request, obj)
if "extend_expiry_date" in request.POST:
drivers_licence = obj.drivers_licence
rebate_exists = GoElectricRebate.objects.filter(
drivers_licence=drivers_licence
).exists()
if rebate_exists is False:
ncda_rebate = get_rebate_by_drivers_licence(drivers_licence, ["Title"])
if ncda_rebate is None:
obj.status = GoElectricRebateApplication.Status.APPROVED
obj.save(update_fields=["status"])
rebate_amount = request.POST.get("rebate_amount")
last_name = obj.last_name
expiry_date = date.today() + timedelta(days=30)
ncda_data = notify(
drivers_licence,
last_name,
expiry_date.strftime("%m/%d/%Y"),
rebate_amount,
obj.id,
)
ncda_id = ncda_data["d"]["ID"]
rebate = GoElectricRebate(
application=obj,
drivers_licence=drivers_licence,
last_name=last_name,
expiry_date=expiry_date,
rebate_max_amount=rebate_amount,
redeemed=False,
ncda_id=ncda_id,
)
rebate.save()
else:
raise Exception("There exists an associated NCDA rebate!")
else:
raise Exception("There exists an associated Go Elecric Rebate!")
return ret
2 changes: 1 addition & 1 deletion django/api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# for each income tested maximum rebate ($4000, $2000, $1000), there are different rebate levels for certain ZEV types and lease terms
class FOUR_THOUSAND_REBATE(Enum):
ZEV_MAX = 4000
ZEV_MID = 2688
ZEV_MID = 2668
ZEV_MIN = 1332
PHEV_MAX = 2000
PHEV_MID = 1334
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 4.0.9 on 2024-05-29 22:39

import api.validators
import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0019_changeredeemedgoelectricrebateapplication'),
]

operations = [
migrations.AlterField(
model_name='goelectricrebateapplication',
name='drivers_licence',
field=models.CharField(max_length=8, validators=[django.core.validators.MinLengthValidator(7), api.validators.validate_drivers_licence]),
),
]
25 changes: 25 additions & 0 deletions django/api/migrations/0021_expiredgoelectricrebateapplication.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.0.9 on 2024-06-03 17:31

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('api', '0020_alter_goelectricrebateapplication_drivers_licence'),
]

operations = [
migrations.CreateModel(
name='ExpiredGoElectricRebateApplication',
fields=[
],
options={
'ordering': ['-modified'],
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('api.goelectricrebateapplication',),
),
]
17 changes: 17 additions & 0 deletions django/api/model_forms/extend_expired_application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django import forms
from api.models.go_electric_rebate_application import ExpiredGoElectricRebateApplication
from api.constants import ONE_THOUSAND_REBATE, TWO_THOUSAND_REBATE, FOUR_THOUSAND_REBATE


class ExtendExpiryForm(forms.ModelForm):
rebate_amount = forms.ChoiceField(
choices=[
(ONE_THOUSAND_REBATE.ZEV_MAX.value, ONE_THOUSAND_REBATE.ZEV_MAX.value),
(TWO_THOUSAND_REBATE.ZEV_MAX.value, TWO_THOUSAND_REBATE.ZEV_MAX.value),
(FOUR_THOUSAND_REBATE.ZEV_MAX.value, FOUR_THOUSAND_REBATE.ZEV_MAX.value),
]
)

class Meta:
model = ExpiredGoElectricRebateApplication
fields = "__all__"
13 changes: 12 additions & 1 deletion django/api/models/go_electric_rebate_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
validate_consent,
validate_file_size,
validate_file_safe,
validate_drivers_licence,
)
from django_extensions.db.models import TimeStampedModel
from django.utils.translation import gettext_lazy as _
Expand Down Expand Up @@ -89,7 +90,7 @@ class Status(TextChoices):
city = CharField(max_length=250, unique=False, null=True)
postal_code = CharField(max_length=6, unique=False, blank=True, null=True)
drivers_licence = CharField(
max_length=8, unique=False, validators=[MinLengthValidator(7)]
max_length=8, unique=False, validators=[MinLengthValidator(7), validate_drivers_licence]
)
date_of_birth = DateField(validators=[validate_driving_age], null=True)
tax_year = IntegerField(null=True)
Expand Down Expand Up @@ -279,6 +280,7 @@ class Meta:
def admin_label(cls):
return "Edit DL#'s"


class ChangeRedeemedGoElectricRebateApplication(GoElectricRebateApplication):
class Meta:
proxy = True
Expand All @@ -288,3 +290,12 @@ class Meta:
def admin_label(cls):
return "Change Redeemed Status"


class ExpiredGoElectricRebateApplication(GoElectricRebateApplication):
class Meta:
proxy = True
ordering = ["-modified"]

@classproperty
def admin_label(cls):
return "Extend Expiry Dates"
25 changes: 21 additions & 4 deletions django/api/services/ncda.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ def delete_rebate(ncda_id):
ncda_rs.raise_for_status()


def get_rebate(ncda_id, fields):
def get_rebates(filter, fields):
api_endpoint = settings.NCDA_SHAREPOINT_URL
access_token = get_ncda_service_token()

Expand All @@ -260,11 +260,12 @@ def get_rebate(ncda_id, fields):

url = api_endpoint + "/lists/getbytitle('ITVREligibility')/items"

select_fields = ",".join(fields)
payload = {
"$select": select_fields,
"$filter": "(Id eq %s)" % ncda_id,
"$filter": filter,
}
if fields:
payload["$select"] = ",".join(fields)

ncda_rs = requests.get(url, headers=headers, params=payload, verify=True)
ncda_rs.raise_for_status()
data = ncda_rs.json()
Expand All @@ -273,6 +274,22 @@ def get_rebate(ncda_id, fields):
return items


def get_rebate_by_id(ncda_id, fields=[]):
filter = "(Id eq %s)" % ncda_id
rebates = get_rebates(filter, fields)
if len(rebates) >= 1:
return rebates[0]
return None


def get_rebate_by_drivers_licence(drivers_licence, fields=[]):
filter = "(Title eq '%s')" % drivers_licence
rebates = get_rebates(filter, fields)
if len(rebates) >= 1:
return rebates[0]
return None


def update_rebate(ncda_id, updated_fields):
api_endpoint = settings.NCDA_SHAREPOINT_URL
access_token = get_ncda_service_token()
Expand Down
6 changes: 3 additions & 3 deletions django/api/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from api.services.ncda import (
notify,
get_rebates_redeemed_since,
get_rebate,
get_rebate_by_id,
delete_rebate,
)
from api.constants import (
Expand Down Expand Up @@ -559,8 +559,8 @@ def expire_expired_applications(max_number_of_rebates=50, days_offset=15):
@transaction.atomic
def expire_rebate(rebate):
ncda_id = rebate.ncda_id
ncda_rebates = get_rebate(ncda_id, ["Status"])
if len(ncda_rebates) == 1 and ncda_rebates[0]["Status"] == "Not-Redeemed":
ncda_rebate = get_rebate_by_id(ncda_id, ["Status"])
if ncda_rebate is not None and ncda_rebate["Status"] == "Not-Redeemed":
application = rebate.application
if application:
application.status = GoElectricRebateApplication.Status.EXPIRED
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{% extends "admin/api/change_form.html" %} {% load i18n admin_urls jazzmin %} {%
get_jazzmin_ui_tweaks as jazzmin_ui %}

{% block itvr_subheader %}{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% extends "admin/api/change_list.html" %}
{% load i18n admin_urls static admin_list jazzmin %} {%

{% block content_title %} Extend Expiry Dates {% endblock %}
{% block itvr_subtitle %} Extend Expiry Dates {% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{% extends "admin/submit_line.html" %}
{% load i18n admin_urls jazzmin %}
{% get_jazzmin_ui_tweaks as jazzmin_ui %}
{% load static %}
{% block submit-row %}
<!-- <script src="{% static 'edit_dl_handler.js' %}"></script> -->
<div class="card card-primary card-outline">
<div class="card-header">
<h3 class="card-title">
<em class="fas fa-edit"></em>
{% trans 'Actions' %}
</h3>
</div>
<div class="card-body">
<div class="form-group">
<input
type="submit"
class="btn {{ jazzmin_ui.button_classes.danger }} form-control"
value="Extend Expiry Date By 30 Days From Today"
name="extend_expiry_date"
id="extend_expiry_date"
/>
</div>
</div>
</div>
{% endblock %}
Loading

0 comments on commit 3d3e01d

Please sign in to comment.