Skip to content

Commit

Permalink
Tracking pull request to merge release-1.57.0 to master (#2104)
Browse files Browse the repository at this point in the history
* update Minio to object storage (#2105)

* feat: zeva-2093 - add checkbox (#2097)

* feat: zeva-2093 - add checkbox

* add missing prop type

* Added functionality to download email list with organizations attached for filtering (#2107)

* fix ZEVA 2091: credit application table filter missing some submitted records (#2094)

* fix: adds recommended and checked submissions to the queryset filter if the bceid user searches anything that matches submitted

* chore: cleans up code

* edit logic location

---------

Co-authored-by: tim738745 <tim.chen@gov.bc.ca>

* Removing lock on generated excel sheet to allow for sorting/filtering (#2108)

* fix: zeva-2106 - report history (#2111)

* fix: zeva-2098 - credit applications list date display (#2114)

* roll back minio changes

---------

Co-authored-by: tim738745 <98717409+tim738745@users.noreply.github.com>
Co-authored-by: JulianForeman <71847719+JulianForeman@users.noreply.github.com>
Co-authored-by: Emily <44536222+emi-hi@users.noreply.github.com>
Co-authored-by: tim738745 <tim.chen@gov.bc.ca>
  • Loading branch information
5 people authored Jan 17, 2024
1 parent a248150 commit b370c4e
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 29 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/dev-build.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
## For each release, please update the value of workflow name, branches and PR_NUMBER
## Also update frontend/package.json version

name: Dev Build 1.56.0
name: Dev Build 1.57.0

on:
push:
branches: [ release-1.56.0 ]
branches: [ release-1.57.0 ]
paths:
- frontend/**
- backend/**
Expand All @@ -14,8 +14,8 @@ on:

env:
## The pull request number of the Tracking pull request to merge the release branch to main
PR_NUMBER: 2088
VERSION: 1.56.0
PR_NUMBER: 2104
VERSION: 1.57.0
GIT_URL: https://github.com/bcgov/zeva.git
TOOLS_NAMESPACE: ${{ secrets.OPENSHIFT_NAMESPACE_PLATE }}-tools
DEV_NAMESPACE: ${{ secrets.OPENSHIFT_NAMESPACE_PLATE }}-dev
Expand All @@ -32,7 +32,7 @@ jobs:
call-unit-test:
uses: ./.github/workflows/unit-test-template.yaml
with:
pr-number: 2088
pr-number: 2104

build:

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release-build.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
## For each release, please update the value of workflow name, branches and PR_NUMBER
## Also update frontend/package.json version

name: Release Build 1.56.0
name: Release Build 1.57.0

on:
workflow_dispatch:
workflow_call:

env:
## The pull request number of the Tracking pull request to merge the release branch to main
PR_NUMBER: 2088
VERSION: 1.56.0
PR_NUMBER: 2104
VERSION: 1.57.0
GIT_URL: https://github.com/bcgov/zeva.git
TOOLS_NAMESPACE: ${{ secrets.OPENSHIFT_NAMESPACE_PLATE }}-tools
DEV_NAMESPACE: ${{ secrets.OPENSHIFT_NAMESPACE_PLATE }}-dev
Expand All @@ -27,7 +27,7 @@ jobs:
call-unit-test:
uses: ./.github/workflows/unit-test-template.yaml
with:
pr-number: 2088
pr-number: 2104

build:

Expand Down
17 changes: 12 additions & 5 deletions backend/api/serializers/sales_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,15 @@ class Meta:
class SalesSubmissionBaseListSerializer(
ModelSerializer, EnumSupportSerializerMixin, BaseSerializer
):
submission_history_timestamp = SerializerMethodField()
submission_history = SerializerMethodField()
organization = SerializerMethodField()
totals = SerializerMethodField()
total_warnings = SerializerMethodField()
total_credits = SerializerMethodField()
validation_status = SerializerMethodField()

def get_submission_history(self, obj):
def get_submission_history_timestamp(self, obj):
request = self.context.get('request')

if obj.part_of_model_year_report:
Expand All @@ -101,7 +102,7 @@ def get_submission_history(self, obj):
).first()

if credit_transaction:
return credit_transaction.transaction_timestamp.date()
return credit_transaction.transaction_timestamp

if not request.user.is_government and obj.validation_status in [
SalesSubmissionStatuses.RECOMMEND_REJECTION,
Expand All @@ -117,7 +118,7 @@ def get_submission_history(self, obj):
if history is None:
return None

return history.update_timestamp.date()
return history.update_timestamp

# return the last updated date
history = SalesSubmissionHistory.objects.filter(
Expand All @@ -128,7 +129,13 @@ def get_submission_history(self, obj):
if history is None:
return None

return history.update_timestamp.date()
return history.update_timestamp

def get_submission_history(self, obj):
timestamp = self.get_submission_history_timestamp(obj)
if timestamp:
return timestamp.date()
return None

def get_organization(self, obj):
return {
Expand Down Expand Up @@ -213,7 +220,7 @@ def get_total_credits(self, obj):
class Meta:
model = SalesSubmission
fields = [
'id', 'submission_history', 'organization', 'totals', 'unselected',
'id', 'submission_history_timestamp', 'submission_history', 'organization', 'totals', 'unselected',
'total_warnings', 'total_credits', 'validation_status'
]

Expand Down
56 changes: 56 additions & 0 deletions backend/api/services/bceid_email_spreadsheet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from django.http import HttpResponse
import io
import xlwt
from datetime import datetime
from api.models.user_profile import UserProfile

BOLD = xlwt.easyxf('font: name Times New Roman, bold on;')

def create_bceid_emails_sheet():
sheet_name = 'Active BCeID Emails'

output = io.BytesIO()
workbook = xlwt.Workbook('Emails.xls')
workbook.protect = True

descriptor = {
'version': 2,
'create_time': datetime.utcnow().timestamp(),
'sheets': []
}

worksheet = workbook.add_sheet(sheet_name)
descriptor['sheets'].append({
'index': 1,
'name': sheet_name
})

row = 0

worksheet.write(row, 0, 'Organization', style=BOLD)
worksheet.write(row, 1, 'Email', style=BOLD)

users = UserProfile.objects.filter(is_active=True).exclude(organization__is_government='True').values('organization__name', 'email')

users_list = list(users)

for user in users_list:
row += 1
if user['email'] and user['organization__name']:
worksheet.write(row, 0, user['organization__name'])
worksheet.write(row, 1, user['email'])

org_col = worksheet.col(0)
org_col.width = 256 * 30

email_col = worksheet.col(1)
email_col.width = 256 * 30 # 30 characters for VIN

workbook.save(output)
output.seek(0)

filename = 'active_bceid_users.xls'
response = HttpResponse(output.getvalue(), content_type='application/vnd.ms-excel')
response['Content-Disposition'] = f'attachment; filename="{filename}"'

return response
12 changes: 10 additions & 2 deletions backend/api/viewsets/credit_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def paginated(self, request):
if q_obj:
queryset = queryset.filter(q_obj)
elif id == "status":
queryset = self.filter_by_status(queryset, search_type, search_terms)
queryset = self.filter_by_status(queryset, search_type, search_terms, request.user)
for sort in sorts:
id = sort.get("id")
desc = sort.get("desc")
Expand Down Expand Up @@ -174,7 +174,7 @@ def paginated(self, request):
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

def filter_by_status(self, queryset, search_type, search_terms):
def filter_by_status(self, queryset, search_type, search_terms, user):
mappings = {
"validated": SalesSubmissionStatuses.CHECKED.value,
"issued": SalesSubmissionStatuses.VALIDATED.value,
Expand Down Expand Up @@ -206,6 +206,14 @@ def filter_by_status(self, queryset, search_type, search_terms):
else:
contains_unmapped_search_term = True

if not user.is_government and SalesSubmissionStatuses.SUBMITTED.value in mapped_search_terms:
statuses_to_add = [
SalesSubmissionStatuses.CHECKED.value,
SalesSubmissionStatuses.RECOMMEND_APPROVAL.value,
SalesSubmissionStatuses.RECOMMEND_REJECTION.value
]
mapped_search_terms.extend(statuses_to_add)

final_q = get_search_q_object(
mapped_search_terms,
"exact",
Expand Down
8 changes: 8 additions & 0 deletions backend/api/viewsets/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from api.models.user_profile import UserProfile
from api.permissions.user import UserPermissions
from api.serializers.user import UserSerializer, UserSaveSerializer
from api.services.bceid_email_spreadsheet import create_bceid_emails_sheet
from auditable.views import AuditableMixin


Expand Down Expand Up @@ -42,3 +43,10 @@ def current(self, request):
serializer = self.get_serializer(request.user)

return Response(serializer.data)

@action(detail=False)
def download_active(self, request):

active_bceid_users_excel = create_bceid_emails_sheet()

return active_bceid_users_excel
9 changes: 8 additions & 1 deletion frontend/src/app/components/TextInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'

const TextInput = (props) => {
const {
additionalClasses,
defaultValue,
errorMessage,
handleInputChange,
Expand Down Expand Up @@ -59,8 +60,13 @@ const TextInput = (props) => {
}
}

let className = rowClass
if (additionalClasses) {
className = `${rowClass} ${additionalClasses}`
}

return (
<div className={rowClass}>
<div className={className}>
<label className={labelSize} htmlFor={id}>
{label}
</label>
Expand Down Expand Up @@ -112,6 +118,7 @@ TextInput.defaultProps = {
}

TextInput.propTypes = {
additionalClasses: PropTypes.string,
defaultValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
details: PropTypes.string,
errorMessage: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/app/routes/Users.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ const USERS = {
ME: `${API_BASE_PATH}/current`,
DETAILS: `${API_BASE_PATH}/:id`,
EDIT: `${API_BASE_PATH}/:id/edit`,
ACTIVE: `${API_BASE_PATH}/active`
ACTIVE: `${API_BASE_PATH}/active`,
DOWNLOAD_ACTIVE: `${API_BASE_PATH}/download_active`
}

export default USERS
16 changes: 9 additions & 7 deletions frontend/src/compliance/components/ComplianceHistory.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ const ComplianceHistory = (props) => {
return result
}

const getHistory = (itemHistory, item) => {
const getHistory = (history, item) => {
let itemHistory = history
if (itemHistory) {
const sequentialStatusesToRemove = ['DRAFT', 'SUBMITTED', 'RECOMMENDED', 'RETURNED']
sequentialStatusesToRemove.forEach((status) => {
itemHistory = removeSequentialHistoryItems(itemHistory, status)
})
}
const tempHistory = []
if (itemHistory) {
itemHistory.forEach((obj, i) => {
Expand Down Expand Up @@ -92,12 +99,7 @@ const ComplianceHistory = (props) => {

})
}
let result = tempHistory
const sequentialStatusesToRemove = ['DRAFT', 'SUBMITTED', 'RECOMMENDED']
sequentialStatusesToRemove.forEach((status) => {
result = removeSequentialHistoryItems(result, status)
})
return result
return tempHistory
}
const getTitle = (item) => {
const type = item.isSupplementary ? startedAsSupplemental ? 'Supplementary Report' : 'Reassessment' : 'Model Year Report'
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/credits/components/CreditRequestListTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import history from '../../app/History'
import ROUTES_CREDIT_REQUESTS from '../../app/routes/CreditRequests'
import calculateNumberOfPages from '../../app/utilities/calculateNumberOfPages'
import CustomFilterComponent from '../../app/components/CustomFilterComponent'
import moment from 'moment-timezone'

const CreditRequestListTable = (props) => {
const {
Expand Down Expand Up @@ -55,7 +56,12 @@ const CreditRequestListTable = (props) => {
},
{
id: 'date',
accessor: 'submissionHistory',
accessor: (item) => {
if(item.submissionHistoryTimestamp) {
return moment(item.submissionHistoryTimestamp).format('YYYY-MM-DD')
}
return ''
},
className: 'text-center',
Header: 'Date',
maxWidth: 150,
Expand Down
30 changes: 29 additions & 1 deletion frontend/src/users/components/ActiveUsersListPage.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
import React from 'react'
import PropTypes from 'prop-types'
import Loading from '../../app/components/Loading'
import axios from 'axios'
import ROUTES_USERS from '../../app/routes/Users'
import Button from '../../app/components/Button'

const ActiveUsersListPage = (props) => {
const { activeIdirUsers, activeBceidUsers, loading } = props

const handleDownload = async () => {
try {
const response = await axios.get(ROUTES_USERS.DOWNLOAD_ACTIVE, {responseType: 'blob'})

const url = window.URL.createObjectURL(new Blob([response.data]))
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'Active_BCEID_Users.xls'); // File name for download
document.body.appendChild(link);
link.click();
link.remove();
} catch (error) {
console.error('Error downloading the file: ', error)
}

}

if (loading) {
return <Loading />
}
Expand All @@ -14,7 +34,7 @@ const ActiveUsersListPage = (props) => {
<div className="col-md-8">
<h2>Active Users</h2>
</div>
<div className="mt-3 pt-3">
<div className="mt-3 mb-3 pt-3">
<h4>BCEID Users</h4>
<textarea
rows="11"
Expand All @@ -23,6 +43,14 @@ const ActiveUsersListPage = (props) => {
readOnly
/>
</div>
<Button
buttonType="download"
optionalText="Download List"
optionalClassname="button primary"
action={() => {
handleDownload()
}}
/>
<div className="mt-3 pt-4">
<h4>IDIR Users</h4>
<textarea
Expand Down
Loading

0 comments on commit b370c4e

Please sign in to comment.