From 374319e504ab21d58183dc389aa0b49fd03daf69 Mon Sep 17 00:00:00 2001 From: robertavram Date: Sun, 5 Mar 2017 18:44:30 -0500 Subject: [PATCH 01/10] Fix travel --- .../scripts/migrate_trips_to_travel.py | 5 ++--- EquiTrack/partners/models.py | 20 ++++--------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/EquiTrack/EquiTrack/scripts/migrate_trips_to_travel.py b/EquiTrack/EquiTrack/scripts/migrate_trips_to_travel.py index e602e93b79..6e104452f0 100644 --- a/EquiTrack/EquiTrack/scripts/migrate_trips_to_travel.py +++ b/EquiTrack/EquiTrack/scripts/migrate_trips_to_travel.py @@ -338,12 +338,11 @@ def migrate_trips(country): def migrate_trips_all_countries(): - for country in Country.objects.all(): + for country in Country.objects.order_by('name').all(): if country.name in ["Global"]: continue - print("Migrating trips for: '%s'" % country.name) - migrate_trips(country.name) + migrate_trips(country) def migrate_trips_for(country_name): diff --git a/EquiTrack/partners/models.py b/EquiTrack/partners/models.py index df295fc24a..1c1d9b55b5 100644 --- a/EquiTrack/partners/models.py +++ b/EquiTrack/partners/models.py @@ -8,7 +8,7 @@ from django.contrib.auth.models import User, Group from django.contrib.postgres.fields import JSONField, ArrayField from django.db import models, connection, transaction -from django.db.models import Q, Sum +from django.db.models import Q, Sum, F from django.db.models.signals import post_save, pre_delete from django.utils.translation import ugettext as _ from django.utils.functional import cached_property @@ -635,12 +635,11 @@ def programmatic_visits(cls, partner, update_one=False): if update_one: pv += 1 else: - travelers = Travel.objects.filter(status__in=[Travel.COMPLETED]).values_list('traveler', flat=True) pv = TravelActivity.objects.filter( travel_type=TravelType.PROGRAMME_MONITORING, + travels__traveler=F('primary_traveler'), travels__status__in=[Travel.COMPLETED], partner=partner, - primary_traveler__in=travelers ).count() or 0 partner.hact_values['programmatic_visits'] = pv @@ -655,12 +654,11 @@ def spot_checks(cls, partner, update_one=False): if update_one: sc += 1 else: - travelers = Travel.objects.filter(status__in=[Travel.COMPLETED]).values_list('traveler', flat=True) sc = TravelActivity.objects.filter( travel_type=TravelType.SPOT_CHECK, + travels__traveler=F('primary_traveler'), travels__status__in=[Travel.COMPLETED], partner=partner, - primary_traveler__in=travelers ).count() or 0 partner.hact_values['spot_checks'] = sc @@ -668,18 +666,8 @@ def spot_checks(cls, partner, update_one=False): @classmethod def follow_up_flags(cls, partner, action_point=None): - follow_ups = len([ - action for trip in partner.trips - for action in trip.actionpoint_set.filter( - completed_date__isnull=True - ) - if action.follow_up - ]) - if action_point and action_point.completed_date is None and action_point.follow_up: - follow_ups += 1 - partner.hact_values['follow_up_flags'] = follow_ups - partner.save() + pass @classmethod def create_user(cls, sender, instance, created, **kwargs): From 10163ee8aa0a60db3a8faaae3e933b86a529bd96 Mon Sep 17 00:00:00 2001 From: ntrncic Date: Sun, 5 Mar 2017 19:53:26 -0500 Subject: [PATCH 02/10] followup flags --- EquiTrack/partners/models.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EquiTrack/partners/models.py b/EquiTrack/partners/models.py index 1c1d9b55b5..0b644d73c1 100644 --- a/EquiTrack/partners/models.py +++ b/EquiTrack/partners/models.py @@ -665,9 +665,9 @@ def spot_checks(cls, partner, update_one=False): partner.save() @classmethod - def follow_up_flags(cls, partner, action_point=None): - - pass + def follow_up_flags(cls, partner, update_one=False): + partner.hact_values['follow_up_flags'] = 0 + partner.save() @classmethod def create_user(cls, sender, instance, created, **kwargs): From 6bf2673da1c9dcc1d5118f7c985aa48001c7fbf3 Mon Sep 17 00:00:00 2001 From: ntrncic Date: Mon, 6 Mar 2017 11:21:42 -0500 Subject: [PATCH 03/10] interventions export fix --- EquiTrack/partners/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EquiTrack/partners/models.py b/EquiTrack/partners/models.py index df295fc24a..f7e92008f9 100644 --- a/EquiTrack/partners/models.py +++ b/EquiTrack/partners/models.py @@ -1398,7 +1398,7 @@ def __unicode__(self): def days_from_submission_to_signed(self): if not self.submission_date: return u'Not Submitted' - if not self.signed_by_unicef_date or self.signed_by_partner_date: + if not self.signed_by_unicef_date or not self.signed_by_partner_date: return u'Not fully signed' signed_date = max([self.signed_by_partner_date, self.signed_by_unicef_date]) return relativedelta(signed_date - self.submission_date).days @@ -1407,7 +1407,7 @@ def days_from_submission_to_signed(self): def days_from_review_to_signed(self): if not self.review_date_prc: return u'Not Reviewed' - if not self.signed_by_unicef_date or self.signed_by_partner_date: + if not self.signed_by_unicef_date or not self.signed_by_partner_date: return u'Not fully signed' signed_date = max([self.signed_by_partner_date, self.signed_by_unicef_date]) return relativedelta(signed_date - self.review_date_prc).days From 6c7b22b95ec7068f44544b459330b3211cf94e5b Mon Sep 17 00:00:00 2001 From: ntrncic Date: Mon, 6 Mar 2017 12:24:12 -0500 Subject: [PATCH 04/10] cso type sync fixed --- EquiTrack/vision/adapters/partner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EquiTrack/vision/adapters/partner.py b/EquiTrack/vision/adapters/partner.py index 9a6dabaa2d..4adba304fb 100644 --- a/EquiTrack/vision/adapters/partner.py +++ b/EquiTrack/vision/adapters/partner.py @@ -17,8 +17,8 @@ } cso_type_mapping = { - "International NGO ": u'International', - "National NGO ": u'National', + "International NGO": u'International', + "National NGO": u'National', "Community based organization": u'Community Based Organization', "Academic Institution": u'Academic Institution' } From 217bba0bcdc8e01ccb7246e284a8eb21bf9f581a Mon Sep 17 00:00:00 2001 From: Zoltan Ilcsik Date: Mon, 6 Mar 2017 20:11:33 +0100 Subject: [PATCH 05/10] Fix trips dashboard no section error --- EquiTrack/t2f/tests/test_travel_list.py | 31 ++++++++++++++++++++++++- EquiTrack/t2f/views/dashboard.py | 5 ++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/EquiTrack/t2f/tests/test_travel_list.py b/EquiTrack/t2f/tests/test_travel_list.py index 2ce811652b..d60a1fd501 100644 --- a/EquiTrack/t2f/tests/test_travel_list.py +++ b/EquiTrack/t2f/tests/test_travel_list.py @@ -48,7 +48,7 @@ def test_list_view(self): self.assertKeysIn(expected_keys, travel_data) def test_dashboard_travels_list_view(self): - with self.assertNumQueries(12): + with self.assertNumQueries(10): response = self.forced_auth_req( 'get', reverse( @@ -70,6 +70,35 @@ def test_dashboard_travels_list_view(self): self.assertEqual(len(response_json['travels_by_section']), 1) self.assertEqual(response_json['planned'], 1) + def test_dashboard_travels_list_view_no_section(self): + travel = TravelFactory(reference_number=make_travel_reference_number(), + traveler=self.traveler, + supervisor=self.unicef_staff, + section=None) + + with self.assertNumQueries(10): + response = self.forced_auth_req( + 'get', + reverse( + 't2f:travels:list:dashboard', + kwargs={ + "year": travel.start_date.year, + "month": '{month:02d}'.format(month=travel.start_date.month), + } + ), + user=self.unicef_staff, + data={"office_id": travel.office.id} + ) + + response_json = json.loads(response.rendered_content) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + expected_keys = ['travels_by_section', 'completed', 'planned', 'approved'] + self.assertKeysIn(expected_keys, response_json) + self.assertEqual(response_json['travels_by_section'][0]['section_name'], 'no_section_selected') + self.assertEqual(len(response_json['travels_by_section']), 1) + self.assertEqual(response_json['planned'], 1) + def test_dashboard_action_points_list_view(self): with self.assertNumQueries(8): response = self.forced_auth_req( diff --git a/EquiTrack/t2f/views/dashboard.py b/EquiTrack/t2f/views/dashboard.py index 3fa7856b0c..e78cb0f428 100644 --- a/EquiTrack/t2f/views/dashboard.py +++ b/EquiTrack/t2f/views/dashboard.py @@ -36,9 +36,10 @@ def list(self, request, year, month, **kwargs): planned = travels.filter(status=Travel.PLANNED).count() approved = travels.filter(status=Travel.APPROVED).count() completed = travels.filter(status=Travel.COMPLETED).count() + section = travels.first().section section_trips = { - "section_id": travels.first().section.id, - "section_name": travels.first().section.name, + "section_id": section.id if section else None, + "section_name": section.name if section else "no_section_selected", "planned_travels": planned, "approved_travels": approved, "completed_travels": completed, From 120bb5cd41d30d9b7148b51cc54a8b11e54a70db Mon Sep 17 00:00:00 2001 From: Zoltan Ilcsik Date: Mon, 6 Mar 2017 20:18:43 +0100 Subject: [PATCH 06/10] Fix trips dashboard no section, action points view --- EquiTrack/t2f/tests/test_travel_list.py | 4 ++-- EquiTrack/t2f/views/dashboard.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/EquiTrack/t2f/tests/test_travel_list.py b/EquiTrack/t2f/tests/test_travel_list.py index d60a1fd501..3e2a1799f4 100644 --- a/EquiTrack/t2f/tests/test_travel_list.py +++ b/EquiTrack/t2f/tests/test_travel_list.py @@ -100,7 +100,7 @@ def test_dashboard_travels_list_view_no_section(self): self.assertEqual(response_json['planned'], 1) def test_dashboard_action_points_list_view(self): - with self.assertNumQueries(8): + with self.assertNumQueries(6): response = self.forced_auth_req( 'get', reverse('t2f:action_points:dashboard'), @@ -117,7 +117,7 @@ def test_dashboard_action_points_list_view(self): self.assertEqual(response_json['action_points_by_section'][0]['total_action_points'], 1) def test_dashboard_action_points_list_view_no_office(self): - with self.assertNumQueries(8): + with self.assertNumQueries(6): response = self.forced_auth_req( 'get', reverse('t2f:action_points:dashboard'), diff --git a/EquiTrack/t2f/views/dashboard.py b/EquiTrack/t2f/views/dashboard.py index e78cb0f428..a18d28cd6f 100644 --- a/EquiTrack/t2f/views/dashboard.py +++ b/EquiTrack/t2f/views/dashboard.py @@ -70,9 +70,10 @@ def list(self, request, **kwargs): action_points = ActionPoint.objects.filter(travel__in=travels) total = action_points.count() completed = action_points.filter(status=Travel.COMPLETED).count() + section = travels.first().section section_action_points = { - "section_id": travels.first().section.id, - "section_name": travels.first().section.name, + "section_id": section.id if section else None, + "section_name": section.name if section else "no_section_selected", "total_action_points": total, "completed_action_points": completed, } From 6155f887c52d78e5a9b14d311d38a3043b572212 Mon Sep 17 00:00:00 2001 From: ntrncic Date: Mon, 6 Mar 2017 15:04:50 -0500 Subject: [PATCH 07/10] signed by unicef fix --- EquiTrack/partners/views/v2.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/EquiTrack/partners/views/v2.py b/EquiTrack/partners/views/v2.py index 9e1fb74f2f..62cc32e45c 100644 --- a/EquiTrack/partners/views/v2.py +++ b/EquiTrack/partners/views/v2.py @@ -203,7 +203,11 @@ def get(self, request): """ Return All dropdown values used for Agreements form """ - signed_by_unicef = list(models.User.objects.filter(groups__name__in=['Senior Management Team']).values('id', 'first_name', 'last_name', 'email')) + signed_by_unicef = list(models.User.objects.filter(groups__name__in=['Senior Management Team'], + profile__country=request.tenant).values('id', + 'first_name', + 'last_name', + 'email')) hrps = list(ResultStructure.objects.values()) current_country_programme = CountryProgramme.current() cp_outputs = list(Result.objects.filter(result_type__name=ResultType.OUTPUT, wbs__isnull=False, From b96e9f5529e23966706eef6162465f293f09d9df Mon Sep 17 00:00:00 2001 From: ntrncic Date: Mon, 6 Mar 2017 15:49:11 -0500 Subject: [PATCH 08/10] fix pca pdf dead link --- EquiTrack/templates/partners/pca_pdf.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EquiTrack/templates/partners/pca_pdf.html b/EquiTrack/templates/partners/pca_pdf.html index dd6824e049..5a1677b995 100644 --- a/EquiTrack/templates/partners/pca_pdf.html +++ b/EquiTrack/templates/partners/pca_pdf.html @@ -1060,10 +1060,10 @@ supplies and equipment transferred by UNICEF to IP: (a) are not used to provide support to individuals or entities associated with terrorism; (b) are not transferred by the IP to any individual or entity on the UN Security Council Committee Consolidated List available at - http://www.un.org/sc/committees/consolidated_list.shtml; and (c) are not used, in the case of money, - for the purpose of any payment to persons or entities, or for any import of goods, if such payment - or import is prohibited by a decision of the United Nations Security Council taken under Chapter VII - of the Charter of the United Nations. + https://www.un.org/sc/suborg/en/sanctions/un-sc-consolidated-list; and (c) are not used, in the case + of money, for the purpose of any payment to persons or entities, or for any import of goods, if such + payment or import is prohibited by a decision of the United Nations Security Council taken under + Chapter VII of the Charter of the United Nations. From 8c9a0615ebcfa89b46727732f75ab96c3ec7ec31 Mon Sep 17 00:00:00 2001 From: Zoltan Ilcsik Date: Mon, 6 Mar 2017 22:07:11 +0100 Subject: [PATCH 09/10] Rename no section selected name --- EquiTrack/t2f/tests/test_travel_list.py | 2 +- EquiTrack/t2f/views/dashboard.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/EquiTrack/t2f/tests/test_travel_list.py b/EquiTrack/t2f/tests/test_travel_list.py index 3e2a1799f4..7187e7971e 100644 --- a/EquiTrack/t2f/tests/test_travel_list.py +++ b/EquiTrack/t2f/tests/test_travel_list.py @@ -95,7 +95,7 @@ def test_dashboard_travels_list_view_no_section(self): self.assertEqual(response.status_code, status.HTTP_200_OK) expected_keys = ['travels_by_section', 'completed', 'planned', 'approved'] self.assertKeysIn(expected_keys, response_json) - self.assertEqual(response_json['travels_by_section'][0]['section_name'], 'no_section_selected') + self.assertEqual(response_json['travels_by_section'][0]['section_name'], 'No Section selected') self.assertEqual(len(response_json['travels_by_section']), 1) self.assertEqual(response_json['planned'], 1) diff --git a/EquiTrack/t2f/views/dashboard.py b/EquiTrack/t2f/views/dashboard.py index a18d28cd6f..7df4f6e2ed 100644 --- a/EquiTrack/t2f/views/dashboard.py +++ b/EquiTrack/t2f/views/dashboard.py @@ -39,7 +39,7 @@ def list(self, request, year, month, **kwargs): section = travels.first().section section_trips = { "section_id": section.id if section else None, - "section_name": section.name if section else "no_section_selected", + "section_name": section.name if section else "No Section selected", "planned_travels": planned, "approved_travels": approved, "completed_travels": completed, @@ -73,7 +73,7 @@ def list(self, request, **kwargs): section = travels.first().section section_action_points = { "section_id": section.id if section else None, - "section_name": section.name if section else "no_section_selected", + "section_name": section.name if section else "No Section selected", "total_action_points": total, "completed_action_points": completed, } From 8215dbdff781d56967b98d4ff76711d44284c1cf Mon Sep 17 00:00:00 2001 From: robertavram Date: Mon, 6 Mar 2017 16:20:38 -0500 Subject: [PATCH 10/10] Fix sync --- EquiTrack/vision/adapters/publics_adapter.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/EquiTrack/vision/adapters/publics_adapter.py b/EquiTrack/vision/adapters/publics_adapter.py index b42551bc02..c1a901cb9a 100644 --- a/EquiTrack/vision/adapters/publics_adapter.py +++ b/EquiTrack/vision/adapters/publics_adapter.py @@ -86,6 +86,7 @@ def _convert_records(self, records): def _save_records(self, records): records = records['ROWSET']['ROW'] + records = self._filter_records(records) processed = 0 for row in records: @@ -101,6 +102,10 @@ def _save_records(self, records): travel_agent = TravelAgent(code=vendor_code) log.debug('Travel agent created with code %s', vendor_code) + travel_expense_type, _ = TravelExpenseType.objects.get_or_create(vendor_number=vendor_code, + defaults={'title': name}) + + travel_agent.expense_type = travel_expense_type travel_agent.name = name travel_agent.city = city @@ -124,8 +129,6 @@ def _save_records(self, records): travel_agent.save() log.info('Travel agent %s saved.', travel_agent.name) - TravelExpenseType.objects.get_or_create(vendor_number=vendor_code, is_travel_agent=True, - defaults={'title': name}) return processed