Exemple #1
0
 def setUp(self):
     vendor_code = self.intervention.agreement.partner.vendor_number
     self.fr_1 = FundsReservationHeaderFactory(intervention=None,
                                               currency="USD",
                                               vendor_code=vendor_code)
     self.fr_2 = FundsReservationHeaderFactory(intervention=None,
                                               currency="USD",
                                               vendor_code=vendor_code)
     self.fr_3 = FundsReservationHeaderFactory(intervention=None,
                                               currency="RON")
Exemple #2
0
 def test_attachment(self):
     """If Total actual amount > 100,000 need attachment with
     type Final Partnership Review
     """
     file_type = self.file_parnership_file_type
     InterventionAttachmentFactory(
         intervention=self.intervention,
         type=file_type
     )
     frs = FundsReservationHeaderFactory(
         intervention=self.intervention,
         total_amt=0.00,
         total_amt_local=120000.00,
         actual_amt_local=120000.00,
         actual_amt=0,
         outstanding_amt_local=0.00,
         outstanding_amt=0.00,
         intervention_amt=0.00,
     )
     self.assertTrue(transition_to_closed(self.intervention))
     self.expected["total_actual_amt"] = 120000.00
     self.expected["total_frs_amt"] = 120000.00
     self.expected["earliest_start_date"] = frs.start_date
     self.expected["latest_end_date"] = frs.end_date
     self.assertFundamentals(self.intervention.total_frs)
    def test_attachment_invalid(self):
        """If Total actual amount > 100,000 need attachment with
        type Final Partnership Review
        """
        frs = FundsReservationHeaderFactory(
            intervention=self.intervention,
            total_amt=0.00,
            total_amt_local=120000.00,
            actual_amt_local=120000.00,
            actual_amt=120000.00,
            outstanding_amt_local=0.00,
            outstanding_amt=0.00,
            intervention_amt=0.00,
        )

        with self.assertRaisesRegexp(
                TransitionError,
                'Total amount transferred greater than 100,000 and no '
                'Final Partnership Review was attached'):
            transition_to_closed(self.intervention)
        self.expected["total_actual_amt"] = 120000.00
        self.expected["total_actual_amt_usd"] = 120000.00
        self.expected["total_frs_amt"] = 120000.00
        self.expected["earliest_start_date"] = frs.start_date
        self.expected["latest_end_date"] = frs.end_date
        self.assertFundamentals(self.intervention.total_frs)
Exemple #4
0
 def test_donors_many_filter(self):
     """Check that filtering on multiple donors returns expected result"""
     donor_1 = DonorFactory()
     donor_2 = DonorFactory()
     grant_number_1 = "G123"
     grant_number_2 = "G124"
     GrantFactory(
         donor=donor_1,
         name=grant_number_1,
     )
     GrantFactory(
         donor=donor_2,
         name=grant_number_2,
     )
     FundsReservationItemFactory(fund_reservation=self.fr_1,
                                 grant_number=grant_number_1)
     FundsReservationItemFactory(fund_reservation=self.fr_2,
                                 grant_number=grant_number_2)
     FundsReservationHeaderFactory()
     data = {
         "values": ",".join([self.fr_1.fr_number, self.fr_2.fr_number]),
         "donors": ",".join([str(donor_1.pk),
                             str(donor_2.pk)]),
     }
     status_code, result = self.run_request(data)
     self.assertEqual(status_code, status.HTTP_200_OK)
     self.assertEqual(len(result['frs']), 2)
Exemple #5
0
    def test_api_partners_retreive_same_fr_amounts(self):
        self.intervention.status = Intervention.ACTIVE
        self.intervention.save()
        fr_header_1 = FundsReservationHeaderFactory(
            intervention=self.intervention,
            total_amt=Decimal("300.00"),
            actual_amt=Decimal("250.00"),
            outstanding_amt=Decimal("200.00"),
            total_amt_local=Decimal("100.00"),
            actual_amt_local=Decimal("50.00"),
            outstanding_amt_local=Decimal("20.00"),
            intervention_amt=Decimal("10.00"),
        )
        fr_header_2 = FundsReservationHeaderFactory(
            intervention=self.intervention,
            total_amt=Decimal("300.00"),
            actual_amt=Decimal("250.00"),
            outstanding_amt=Decimal("200.00"),
            total_amt_local=Decimal("100.00"),
            actual_amt_local=Decimal("50.00"),
            outstanding_amt_local=Decimal("20.00"),
            intervention_amt=Decimal("10.00"),
        )

        response = self.forced_auth_req(
            'get',
            reverse('partners_api:partner-detail', args=[self.partner.pk]),
            user=self.unicef_staff,
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(
            Decimal(response.data["interventions"][0]["actual_amount"]),
            Decimal(fr_header_1.actual_amt_local +
                    fr_header_2.actual_amt_local))
        self.assertEqual(
            Decimal(response.data["interventions"][0]["frs_total_frs_amt"]),
            Decimal(fr_header_1.total_amt_local + fr_header_2.total_amt_local))
        self.assertEqual(
            Decimal(response.data["interventions"][0]
                    ["frs_total_intervention_amt"]),
            Decimal(fr_header_1.intervention_amt +
                    fr_header_2.intervention_amt))
        self.assertEqual(
            Decimal(response.data["interventions"][0]
                    ["frs_total_outstanding_amt"]),
            Decimal(fr_header_1.outstanding_amt_local +
                    fr_header_2.outstanding_amt_local))
 def test_dates(self):
     """Ensure earliest and latest dates set correctly"""
     FundsReservationHeaderFactory(
         intervention=self.intervention,
         fr_number=1,
         total_amt=0.00,
         total_amt_local=100.00,
         start_date=datetime.date(2001, 1, 1),
         end_date=datetime.date(2001, 2, 1),
         actual_amt=0.00,
         actual_amt_local=100.00,
         intervention_amt=0.00,
         outstanding_amt_local=0.00,
         outstanding_amt=0.00,
     )
     FundsReservationHeaderFactory(
         intervention=self.intervention,
         fr_number=2,
         total_amt=0.00,
         total_amt_local=100.00,
         start_date=datetime.date(2000, 1, 1),
         end_date=datetime.date(2000, 2, 1),
         actual_amt=0.00,
         actual_amt_local=100.00,
         intervention_amt=0.00,
         outstanding_amt_local=0.00,
         outstanding_amt=0.00,
     )
     FundsReservationHeaderFactory(
         intervention=self.intervention,
         fr_number=3,
         total_amt=0.00,
         total_amt_local=100.00,
         start_date=datetime.date(2002, 1, 1),
         end_date=datetime.date(2002, 2, 1),
         actual_amt_local=100.00,
         actual_amt=0.00,
         intervention_amt=0.00,
         outstanding_amt_local=0.00,
         outstanding_amt=0.00,
     )
     self.assertTrue(transition_to_closed(self.intervention))
     self.expected["earliest_start_date"] = datetime.date(2000, 1, 1)
     self.expected["latest_end_date"] = datetime.date(2002, 2, 1)
     self.expected["total_actual_amt"] = 300.00
     self.expected["total_frs_amt"] = 300.00
     self.assertFundamentals(self.intervention.total_frs)
Exemple #7
0
    def test_api_partners_retreive_actual_fr_amounts(self):
        self.intervention.status = Intervention.ACTIVE
        self.intervention.save()
        fr_header_1 = FundsReservationHeaderFactory(
            intervention=self.intervention)
        fr_header_2 = FundsReservationHeaderFactory(
            intervention=self.intervention)

        response = self.forced_auth_req(
            'get',
            reverse('partners_api:partner-detail', args=[self.partner.pk]),
            user=self.unicef_staff,
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(
            Decimal(response.data["interventions"][0]["actual_amount"]),
            Decimal(fr_header_1.actual_amt_local +
                    fr_header_2.actual_amt_local))
Exemple #8
0
 def test_send_not_signed(self):
     intervention = InterventionFactory(
         status=Intervention.DRAFT,
         start=datetime.date.today() - datetime.timedelta(days=2),
     )
     FundsReservationHeaderFactory(intervention=intervention)
     mock_send = Mock()
     with patch(self.send_path, mock_send):
         utils.send_intervention_past_start_notification()
     self.assertEqual(mock_send.call_count, 0)
Exemple #9
0
 def test_task(self):
     send_path = "etools.applications.partners.utils.send_notification_with_template"
     intervention = InterventionFactory(
         status=Intervention.SIGNED,
         start=datetime.date.today() - datetime.timedelta(days=2),
     )
     FundsReservationHeaderFactory(intervention=intervention)
     mock_send = Mock()
     with patch(send_path, mock_send):
         call_command("send_intervention_past_start_notification")
     self.assertEqual(mock_send.call_count, 1)
 def test_total_amounts_valid(self):
     """Total amounts must equal and total outstanding must be zero"""
     frs = FundsReservationHeaderFactory(intervention=self.intervention,
                                         total_amt=0.00,
                                         total_amt_local=10.00,
                                         intervention_amt=0.00,
                                         actual_amt=0.00,
                                         actual_amt_local=10.00,
                                         outstanding_amt=0.00,
                                         outstanding_amt_local=0.00)
     self.assertTrue(transition_to_closed(self.intervention))
     self.expected["total_frs_amt"] = 10.00
     self.expected["total_actual_amt"] = 10.00
     self.expected["earliest_start_date"] = frs.start_date
     self.expected["latest_end_date"] = frs.end_date
     self.assertFundamentals(self.intervention.total_frs)
Exemple #11
0
 def test_update(self):
     user = UserFactory()
     intervention = InterventionFactory()
     obj_dict = utils.create_dict_with_relations(intervention)
     fr = FundsReservationHeaderFactory(intervention=intervention)
     activity = utils.create_snapshot(intervention, obj_dict, user)
     self.assertEqual(activity.target, intervention)
     self.assertEqual(activity.action, activity.UPDATE)
     self.assertEqual(activity.by_user, user)
     self.assertEqual(activity.data["title"], intervention.title)
     self.assertEqual(activity.change, {
         "frs": {
             "before": [],
             "after": [fr.pk]
         }
     })
Exemple #12
0
 def test_get_fail_with_intervention_id(self):
     other_intervention = InterventionFactory()
     fth_value = 'im a bad value'
     FundsReservationHeaderFactory(fr_number=fth_value,
                                   intervention=other_intervention,
                                   currency="USD")
     data = {
         'values': ','.join([fth_value, self.fr_1.fr_number]),
         'intervention': self.intervention.pk
     }
     status_code, result = self.run_request(data)
     self.assertEqual(status_code, status.HTTP_400_BAD_REQUEST)
     self.assertEqual(
         result['error'],
         'FR #{} is already being used by PD/SSFA ref [{}]'.format(
             fth_value, other_intervention))
 def test_total_frs_amount(self):
     """Ensure total_frs_amt set correctly"""
     frs = FundsReservationHeaderFactory(
         intervention=self.intervention,
         total_amt=0.00,
         total_amt_local=100.00,
         actual_amt=0.00,
         actual_amt_local=100.00,
         intervention_amt=0.00,
         outstanding_amt=0.00,
         outstanding_amt_local=0.00,
     )
     self.assertTrue(transition_to_closed(self.intervention))
     self.expected["total_frs_amt"] = 100.00
     self.expected["total_actual_amt"] = 100.00
     self.expected["earliest_start_date"] = frs.start_date
     self.expected["latest_end_date"] = frs.end_date
     self.assertFundamentals(self.intervention.total_frs)
 def test_total_amounts_not_equal(self):
     """Total amounts must equal and total outstanding must be zero"""
     frs = FundsReservationHeaderFactory(intervention=self.intervention,
                                         total_amt=0.00,
                                         total_amt_local=0.00,
                                         intervention_amt=10.00,
                                         actual_amt_local=20.00,
                                         actual_amt=0.00,
                                         outstanding_amt_local=0.00,
                                         outstanding_amt=0.00)
     with self.assertRaisesRegexp(
             TransitionError,
             'Total FR amount needs to equal total actual amount, and '
             'Total Outstanding DCTs need to equal to 0'):
         transition_to_closed(self.intervention)
     self.expected["total_intervention_amt"] = 10.00
     self.expected["total_actual_amt"] = 20.00
     self.expected["earliest_start_date"] = frs.start_date
     self.expected["latest_end_date"] = frs.end_date
     self.assertFundamentals(self.intervention.total_frs)
Exemple #15
0
 def setUp(self):
     self.data = {
         "VENDOR_CODE": "Code123",
         "FR_NUMBER": "123",
         "FR_DOC_DATE": "14-Jan-15",
         "FR_TYPE": "Type",
         "CURRENCY": "USD",
         "FR_DOCUMENT_TEXT": "Random Text",
         "FR_START_DATE": "13-Jan-15",
         "FR_END_DATE": "20-Dec-15",
         "LINE_ITEM": "987",
         "WBS_ELEMENT": "WBS",
         "GRANT_NBR": "456",
         "FUND": "Fund",
         "OVERALL_AMOUNT": "20.00",
         "OVERALL_AMOUNT_DC": "5.00",
         "FR_LINE_ITEM_TEXT": "Line item text",
         "DUE_DATE": "18-May-15",
         "FR_OVERALL_AMOUNT": "15.00",
         "CURRENT_FR_AMOUNT": "17.00",
         "ACTUAL_CASH_TRANSFER": "18.00",
         "OUTSTANDING_DCT": "19.00",
         "ACTUAL_CASH_TRANSFER_DC": "13.00",
         "OUTSTANDING_DCT_DC": "14.00",
         "MULTI_CURR_FLAG": "N"
     }
     self.expected_headers = {
         "vendor_code": "Code123",
         "fr_number": "123",
         "document_date": datetime.date(2015, 1, 14),
         "fr_type": "Type",
         "currency": "USD",
         "document_text": "Random Text",
         "start_date": datetime.date(2015, 1, 13),
         "end_date": datetime.date(2015, 12, 20),
         "total_amt": "15.00",
         "intervention_amt": "17.00",
         "actual_amt": "18.00",
         "actual_amt_local": "13.00",
         "outstanding_amt": "19.00",
         "outstanding_amt_local": "14.00",
         "multi_curr_flag": False
     }
     self.expected_line_item = {
         "line_item": "987",
         "fr_number": "123",
         "donor": None,
         "donor_code": None,
         "wbs": "WBS",
         "grant_number": "456",
         "fund": "Fund",
         "overall_amount": "20.00",
         "overall_amount_dc": "5.00",
         "due_date": datetime.date(2015, 5, 18),
         "line_item_text": "Line item text",
         "fr_ref_number": "123-987"
     }
     self.fund_item = FundsReservationItemFactory(
         fr_ref_number="123-987",
         line_item=self.data["LINE_ITEM"],
         wbs=self.data["WBS_ELEMENT"],
         grant_number=self.data["GRANT_NBR"],
         fund=self.data["FUND"],
         overall_amount=self.data["OVERALL_AMOUNT"],
         overall_amount_dc=self.data["OVERALL_AMOUNT_DC"],
         due_date=datetime.date(2015, 5, 18),
         line_item_text=self.data["FR_LINE_ITEM_TEXT"],
     )
     self.fund_header = FundsReservationHeaderFactory(
         vendor_code=self.data["VENDOR_CODE"],
         fr_number=self.data["FR_NUMBER"],
         document_date=datetime.date(2015, 1, 14),
         fr_type=self.data["FR_TYPE"],
         currency=self.data["CURRENCY"],
         document_text=self.data["FR_DOCUMENT_TEXT"],
         intervention_amt=self.data["CURRENT_FR_AMOUNT"],
         total_amt=self.data["FR_OVERALL_AMOUNT"],
         actual_amt=self.data["ACTUAL_CASH_TRANSFER"],
         outstanding_amt=self.data["OUTSTANDING_DCT"],
         outstanding_amt_local=self.data["OUTSTANDING_DCT_DC"],
         start_date=datetime.date(2015, 1, 13),
         end_date=datetime.date(2015, 12, 20),
     )
     self.adapter = adapter.FundReservationsSynchronizer(self.country)
Exemple #16
0
    def test_make_intervention_status_automatic_transitions_with_valid_interventions(
            self, MockInterventionValid, mock_db_connection, mock_logger):
        '''Exercise _make_intervention_status_automatic_transitions() when all interventions are valid'''
        # Make some interventions that are active that ended yesterday. (The task looks for such interventions.)
        end_date = datetime.date.today() - datetime.timedelta(days=1)
        # Interventions sort by oldest last, so I make sure my list here is ordered in the same way as they'll be
        # pulled out of the database.
        interventions = [
            InterventionFactory(status=Intervention.ACTIVE,
                                end=end_date,
                                created=_make_past_datetime(i))
            for i in range(3)
        ]

        # Make an intervention with some associated funds reservation headers that the task should find.
        intervention = InterventionFactory(status=Intervention.ENDED)
        for i in range(3):
            FundsReservationHeaderFactory(intervention=intervention,
                                          outstanding_amt=Decimal(0.00),
                                          intervention_amt=_make_decimal(i),
                                          actual_amt=_make_decimal(i),
                                          total_amt=_make_decimal(i))
        interventions.append(intervention)

        # Create a few items that should be ignored. If they're not ignored, this test will fail.
        # Ignored because of end date
        InterventionFactory(status=Intervention.ACTIVE,
                            end=datetime.date.today() +
                            datetime.timedelta(days=2))
        # Ignored because of status
        InterventionFactory(status=Intervention.IMPLEMENTED, end=end_date)
        # Ignored because funds total outstanding != 0
        intervention = InterventionFactory(status=Intervention.ENDED,
                                           end=end_date)
        for i in range(3):
            FundsReservationHeaderFactory(intervention=intervention,
                                          outstanding_amt=Decimal(i),
                                          intervention_amt=_make_decimal(i),
                                          actual_amt=_make_decimal(i),
                                          total_amt=_make_decimal(i))

        # Ignored because funds totals don't match
        intervention = InterventionFactory(status=Intervention.ENDED,
                                           end=end_date)
        for i in range(3):
            FundsReservationHeaderFactory(intervention=intervention,
                                          outstanding_amt=Decimal(0.00),
                                          intervention_amt=_make_decimal(i),
                                          actual_amt=_make_decimal(i + 1),
                                          total_amt=_make_decimal(i))

        # Mock InterventionValid() to always return True.
        mock_validator = mock.Mock(spec=['is_valid'])
        mock_validator.is_valid = True
        MockInterventionValid.return_value = mock_validator

        # I'm done mocking, it's time to call the function.
        etools.applications.partners.tasks._make_intervention_status_automatic_transitions(
            self.country_name)

        expected_call_args = [((intervention_, ), {
            'user': self.admin_user,
            'disable_rigid_check': True
        }) for intervention_ in interventions]
        self._assertCalls(MockInterventionValid, expected_call_args)

        # Verify logged messages.
        expected_call_args = [
            (('Starting intervention auto status transition for country {}'.
              format(self.country_name), ), {}),
            (('Total interventions 4', ), {}),
            (('Transitioned interventions 0 ', ), {})
        ]
        self._assertCalls(mock_logger.info, expected_call_args)

        expected_call_args = [
            (('Bad interventions 0', ), {}),
            (('Bad interventions ids: ', ), {}),
        ]
        self._assertCalls(mock_logger.error, expected_call_args)
Exemple #17
0
    def test_make_intervention_status_automatic_transitions_with_mixed_interventions(
            self, MockInterventionValid, mock_db_connection, mock_logger):
        '''Exercise _make_intervention_status_automatic_transitions() when only some interventions are valid, but
        not all of them.
        '''
        # Make some interventions that are active that ended yesterday. (The task looks for such interventions.)
        end_date = datetime.date.today() - datetime.timedelta(days=1)
        # Interventions sort by oldest last, so I make sure my list here is ordered in the same way as they'll be
        # pulled out of the database.
        interventions = [
            InterventionFactory(status=Intervention.ACTIVE,
                                end=end_date,
                                created=_make_past_datetime(i))
            for i in range(3)
        ]

        # Make an intervention with some associated funds reservation headers that the task should find.
        intervention = InterventionFactory(status=Intervention.ENDED)
        for i in range(3):
            FundsReservationHeaderFactory(intervention=intervention,
                                          outstanding_amt=Decimal(0.00),
                                          intervention_amt=_make_decimal(i),
                                          actual_amt=_make_decimal(i),
                                          total_amt=_make_decimal(i))
        interventions.append(intervention)

        # Create a few items that should be ignored. If they're not ignored, this test will fail.
        # Ignored because of end date
        InterventionFactory(status=Intervention.ACTIVE,
                            end=datetime.date.today() +
                            datetime.timedelta(days=2))
        # Ignored because of status
        InterventionFactory(status=Intervention.IMPLEMENTED, end=end_date)
        # Ignored because funds total outstanding != 0
        intervention = InterventionFactory(status=Intervention.ENDED,
                                           end=end_date)
        for i in range(3):
            FundsReservationHeaderFactory(intervention=intervention,
                                          outstanding_amt=Decimal(i),
                                          intervention_amt=_make_decimal(i),
                                          actual_amt=_make_decimal(i),
                                          total_amt=_make_decimal(i))
        # Ignored because funds totals don't match
        intervention = InterventionFactory(status=Intervention.ENDED,
                                           end=end_date)
        for i in range(3):
            FundsReservationHeaderFactory(intervention=intervention,
                                          outstanding_amt=Decimal(0.00),
                                          intervention_amt=_make_decimal(i),
                                          actual_amt=_make_decimal(i + 1),
                                          total_amt=_make_decimal(i))

        def mock_intervention_valid_class_side_effect(*args, **kwargs):
            '''Side effect for my mock InterventionValid() that gets called each time my mock InterventionValid() class
            is instantiated. It gives me the opportunity to modify one of the agreements passed.
            '''
            if args and hasattr(args[0], 'id'):
                if args[0].id == interventions[1].id:
                    # We'll pretend the second intervention made a status transition
                    args[0].status = Intervention.CLOSED
                    args[0].save()
            # else:
            # This is a test failure; we always expect (mock) InterventionValid to be called (instantiated) with
            # an agreement passed as the first arg. However the args with which InterventionValid is called are
            # explicitly checked in this test so we don't need to react here.

            return mock.DEFAULT

        # (Mock) InterventionValid() returns a (mock) validator; set up is_valid to return False for the first
        # intervention and True for the others.
        mock_validator = mock.Mock(spec=['is_valid'], name='mock_validator')
        type(mock_validator).is_valid = mock.PropertyMock(
            side_effect=[False, True, True, True])

        MockInterventionValid.side_effect = mock_intervention_valid_class_side_effect
        MockInterventionValid.return_value = mock_validator

        # I'm done mocking, it's time to call the function.
        etools.applications.partners.tasks._make_intervention_status_automatic_transitions(
            self.country_name)

        expected_call_args = [((intervention_, ), {
            'user': self.admin_user,
            'disable_rigid_check': True
        }) for intervention_ in interventions]
        self._assertCalls(MockInterventionValid, expected_call_args)

        # Verify logged messages.
        expected_call_args = [
            (('Starting intervention auto status transition for country {}'.
              format(self.country_name), ), {}),
            (('Total interventions 4', ), {}),
            (('Transitioned interventions 1 ', ), {})
        ]
        self._assertCalls(mock_logger.info, expected_call_args)

        expected_call_args = [
            (('Bad interventions 1', ), {}),
            (('Bad interventions ids: {}'.format(interventions[0].id), ), {}),
        ]
        self._assertCalls(mock_logger.error, expected_call_args)
Exemple #18
0
 def setUp(self):
     super().setUp()
     self.unicef_staff = UserFactory(is_staff=True)
     self.frs = FundsReservationHeaderFactory()
     self.item = FundsReservationItemFactory(fund_reservation=self.frs)
Exemple #19
0
 def setUpTestData(cls):
     cls.unicef_staff = UserFactory(is_staff=True)
     cls.frs = FundsReservationHeaderFactory()
Exemple #20
0
 def setUpTestData(cls):
     cls.fr_header = FundsReservationHeaderFactory(fr_number='23')
Exemple #21
0
 def test_relation(self):
     intervention = InterventionFactory()
     fr = FundsReservationHeaderFactory(intervention=intervention)
     obj_dict = utils.create_dict_with_relations(intervention)
     self.assertEqual(obj_dict["frs"], [fr.pk])
Exemple #22
0
    def test_notify_of_ended_interventions_with_some_interventions(
            self, mock_notification_model, mock_db_connection, mock_logger):
        '''Exercise _notify_of_ended_interventions_with_mismatched_frs() when it has some interventions to work on'''
        # Create some interventions to work with. Interventions sort by oldest last, so I make sure my list here is
        # ordered in the same way as they'll be pulled out of the database.
        interventions = [
            InterventionFactory(status=Intervention.ENDED,
                                created=_make_past_datetime(i))
            for i in range(3)
        ]

        # Add mismatched funds values to each intervention.
        for intervention in interventions:
            for i in range(3):
                FundsReservationHeaderFactory(
                    intervention=intervention,
                    actual_amt_local=_make_decimal(i + 1),
                    total_amt_local=_make_decimal(i))

        # Create a few items that should be ignored. If they're not ignored, this test will fail.
        # Should be ignored because of status even though FRS values are mismatched
        intervention = InterventionFactory(status=Intervention.DRAFT)
        for i in range(3):
            FundsReservationHeaderFactory(intervention=intervention,
                                          actual_amt_local=_make_decimal(i +
                                                                         1),
                                          total_amt_local=_make_decimal(i))

        # Should be ignored because FRS values are not mismatched
        intervention = InterventionFactory(status=Intervention.ENDED)
        for i in range(3):
            FundsReservationHeaderFactory(intervention=intervention,
                                          actual_amt_local=_make_decimal(i),
                                          total_amt_local=_make_decimal(i))

        # Mock Notifications.objects.create() to return a Mock. In order to *truly* mimic create(), my
        # mock_notification_objects.create() should return a new (mock) object every time, but the lazy way or
        # returning the same object is good enough and still allows me to count calls to .send_notification().
        mock_notification = mock.Mock(
            spec=['send_notification', 'save', 'full_clean'])
        mock_notification_model.return_value = mock_notification

        # I'm done mocking, it's time to call the function.
        etools.applications.partners.tasks._notify_of_ended_interventions_with_mismatched_frs(
            self.country_name)

        # Verify that Notification.objects.create() was called as expected.
        expected_call_args = [((), {
            'method_type':
            mock_notification_model.TYPE_EMAIL,
            'sender':
            intervention_,
            'recipients': [],
            'cc': [],
            'from_address':
            '',
            'template_name':
            'partners/partnership/ended/frs/outstanding',
            'template_data':
            etools.applications.partners.tasks.get_intervention_context(
                intervention_),
        }) for intervention_ in interventions]
        self._assertCalls(mock_notification_model, expected_call_args)

        # Verify that each created notification object had send_notification() called.
        expected_call_args = [((), {})] * len(interventions)
        self._assertCalls(mock_notification.send_notification,
                          expected_call_args)
Exemple #23
0
def setup_intervention_test_data(test_case,
                                 include_results_and_indicators=False):
    today = datetime.date.today()
    test_case.unicef_staff = UserFactory(is_staff=True)
    test_case.partnership_manager_user = UserFactory(is_staff=True)
    test_case.partnership_manager_user.groups.add(GroupFactory())
    test_case.partner = PartnerFactory(name='Partner 1', vendor_number="VP1")
    test_case.partner1 = PartnerFactory(name='Partner 2')
    test_case.agreement = AgreementFactory(
        partner=test_case.partner, signed_by_unicef_date=datetime.date.today())

    test_case.active_agreement = AgreementFactory(
        partner=test_case.partner1,
        status='active',
        signed_by_unicef_date=datetime.date.today(),
        signed_by_partner_date=datetime.date.today())

    test_case.intervention = InterventionFactory(agreement=test_case.agreement,
                                                 title='Intervention 1')
    test_case.intervention_2 = InterventionFactory(
        agreement=test_case.agreement,
        title='Intervention 2',
        document_type=Intervention.PD,
    )
    test_case.active_intervention = InterventionFactory(
        agreement=test_case.active_agreement,
        title='Active Intervention',
        document_type=Intervention.PD,
        start=today - datetime.timedelta(days=1),
        end=today + datetime.timedelta(days=90),
        status='active',
        signed_by_unicef_date=today - datetime.timedelta(days=1),
        signed_by_partner_date=today - datetime.timedelta(days=1),
        unicef_signatory=test_case.unicef_staff,
        partner_authorized_officer_signatory=test_case.partner1.staff_members.
        all().first())

    test_case.result_type = ResultType.objects.get_or_create(
        name=ResultType.OUTPUT)[0]
    test_case.result = ResultFactory(result_type=test_case.result_type)

    test_case.partnership_budget = InterventionBudget.objects.create(
        intervention=test_case.intervention,
        unicef_cash=10,
        unicef_cash_local=100,
        partner_contribution=20,
        partner_contribution_local=200,
        in_kind_amount_local=10,
    )

    # set up two frs not connected to any interventions
    test_case.fr_1 = FundsReservationHeaderFactory(intervention=None,
                                                   currency='USD')
    test_case.fr_2 = FundsReservationHeaderFactory(intervention=None,
                                                   currency='USD')

    if include_results_and_indicators:
        # setup additional inicator/results
        test_case.result = ResultFactory(name='A Result')
        test_case.result_link = InterventionResultLink.objects.create(
            intervention=test_case.active_intervention,
            cp_output=test_case.result)
        test_case.lower_result = LowerResult.objects.create(
            result_link=test_case.result_link, name='Lower Result 1')
        test_case.indicator_blueprint = IndicatorBlueprint.objects.create(
            title='The Blueprint')
        test_case.applied_indicator = AppliedIndicator.objects.create(
            indicator=test_case.indicator_blueprint,
            lower_result=test_case.lower_result,
        )
        test_case.applied_indicator.locations.add(
            LocationFactory(name='A Location',
                            gateway=GatewayTypeFactory(name='A Gateway'),
                            p_code='a-p-code'))
        test_case.disaggregation = test_case.applied_indicator.disaggregation.create(
            name='A Disaggregation')

    test_case.file_type_attachment = AttachmentFileTypeFactory(
        code="partners_intervention_attachment")
    test_case.file_type_prc = AttachmentFileTypeFactory(
        code="partners_intervention_prc_review")
    test_case.file_type_pd = AttachmentFileTypeFactory(
        code="partners_intervention_signed_pd")