Exemplo n.º 1
0
def send_notifications(xform, cases):
    # TODO: fix circular imports
    from corehq.apps.commtrack.requisitions import get_notification_recipients
    from corehq.apps.commtrack.requisitions import get_notification_message

    # for now the only notifications are for requisitions that were touched.
    # todo: if we wanted to include previously requested items we could do so
    # by either polling for other open requisitions here, or by ensuring that
    # they get touched by the commtrack case processing.
    requisitions = [RequisitionCase.wrap(case._doc) for case in cases if case.type == const.REQUISITION_CASE_TYPE]

    if requisitions:
        by_status = defaultdict(list)
        for r in requisitions:
            by_status[r.requisition_status].append(r)

        req_config = CommtrackConfig.for_domain(requisitions[0].domain).requisition_config
        # since each state transition might trigger a different person to be notified
        for s, reqs in by_status.items():
            next_action = req_config.get_next_action(RequisitionStatus.to_action_type(s))

            if next_action:
                # we could make this even more customizable by specifying it per requisition
                # but that would get even messier in terms of constructing the messages
                # so we'll just compose one message per status type now, and then send
                # it to everyone who should be notified.
                to_notify = filter(
                    create_unique_filter(lambda u: u._id),
                    itertools.chain(*(get_notification_recipients(next_action, r) for r in reqs)),
                )

                msg = get_notification_message(next_action, reqs)
                for u in to_notify:
                    phone = u.get_verified_number()
                    if phone:
                        send_sms_to_verified_number(phone, msg)
Exemplo n.º 2
0
    def test_create_fulfill_and_receive_requisition(self):
        amounts = [(p._id, 50.0 + float(i*10)) for i, p in enumerate(self.products)]

        # ----------------
        # Create a request
        # ----------------

        self.submit_xml_form(create_requisition_xml(amounts))
        req_cases = list(get_cases_in_domain(self.domain.name, type=const.REQUISITION_CASE_TYPE))
        self.assertEqual(1, len(req_cases))
        req = RequisitionCase.get(req_cases[0]._id)
        [index] = req.indices

        self.assertEqual(req.requisition_status, 'requested')
        self.assertEqual(const.SUPPLY_POINT_CASE_TYPE, index.referenced_type)
        self.assertEqual(self.sp._id, index.referenced_id)
        self.assertEqual('parent_id', index.identifier)
        # TODO: these types of tests probably belong elsewhere
        self.assertEqual(req.get_next_action().keyword, 'fulfill')
        self.assertEqual(req.get_location()._id, self.sp.location._id)
        self.assertEqual(len(RequisitionCase.open_for_location(
            self.domain.name,
            self.sp.location._id
        )), 1)
        self.assertEqual(
            get_notification_message(
                req.get_next_action(),
                [req]
            ),
            self.expected_notification_message(req, amounts)
        )

        for product, amt in amounts:
            self.check_stock_models(req, product, amt, 0, 'ct-requested')

        # ----------------
        # Mark it fulfilled
        # -----------------

        self.submit_xml_form(create_fulfillment_xml(req, amounts))

        req = RequisitionCase.get(req._id)

        self.assertEqual(req.requisition_status, 'fulfilled')
        self.assertEqual(req.get_next_action().keyword, 'rec')
        self.assertEqual(
            get_notification_message(
                req.get_next_action(),
                [req]
            ),
            self.expected_notification_message(req, amounts)
        )

        for product, amt in amounts:
            # we are expecting two separate blocks to have come with the same
            # values
            self.check_stock_models(req, product, amt, amt, 'stock')
            self.check_stock_models(req, product, amt, 0, 'ct-fulfilled')

        # ----------------
        # Mark it received
        # ----------------

        self.submit_xml_form(create_received_xml(req, amounts))

        req = RequisitionCase.get(req._id)

        self.assertEqual(req.requisition_status, 'received')
        self.assertIsNone(req.get_next_action())
        self.assertEqual(len(RequisitionCase.open_for_location(
            self.domain.name,
            self.sp.location._id
        )), 0)

        for product, amt in amounts:
            self.check_stock_models(req, product, 0, -amt, 'stock')
            self.check_stock_models(self.sp, product, amt, amt, 'stock')
Exemplo n.º 3
0
    def test_create_fulfill_and_receive_requisition(self):
        amounts = [(p._id, 50.0 + float(i * 10))
                   for i, p in enumerate(self.products)]

        # ----------------
        # Create a request
        # ----------------

        self.submit_xml_form(create_requisition_xml(amounts))
        req_cases = list(
            get_cases_in_domain(self.domain.name,
                                type=const.REQUISITION_CASE_TYPE))
        self.assertEqual(1, len(req_cases))
        req = RequisitionCase.get(req_cases[0]._id)
        [index] = req.indices

        self.assertEqual(req.requisition_status, 'requested')
        self.assertEqual(const.SUPPLY_POINT_CASE_TYPE, index.referenced_type)
        self.assertEqual(self.sp._id, index.referenced_id)
        self.assertEqual('parent_id', index.identifier)
        # TODO: these types of tests probably belong elsewhere
        self.assertEqual(req.get_next_action().keyword, 'fulfill')
        self.assertEqual(req.get_location()._id, self.sp.location._id)
        self.assertEqual(
            len(
                RequisitionCase.open_for_location(self.domain.name,
                                                  self.sp.location._id)), 1)
        self.assertEqual(
            get_notification_message(req.get_next_action(), [req]),
            self.expected_notification_message(req, amounts))

        for product, amt in amounts:
            self.check_stock_models(req, product, amt, 0, 'ct-requested')

        # ----------------
        # Mark it fulfilled
        # -----------------

        self.submit_xml_form(create_fulfillment_xml(req, amounts))

        req = RequisitionCase.get(req._id)

        self.assertEqual(req.requisition_status, 'fulfilled')
        self.assertEqual(req.get_next_action().keyword, 'rec')
        self.assertEqual(
            get_notification_message(req.get_next_action(), [req]),
            self.expected_notification_message(req, amounts))

        for product, amt in amounts:
            # we are expecting two separate blocks to have come with the same
            # values
            self.check_stock_models(req, product, amt, amt, 'stock')
            self.check_stock_models(req, product, amt, 0, 'ct-fulfilled')

        # ----------------
        # Mark it received
        # ----------------

        self.submit_xml_form(create_received_xml(req, amounts))

        req = RequisitionCase.get(req._id)

        self.assertEqual(req.requisition_status, 'received')
        self.assertIsNone(req.get_next_action())
        self.assertEqual(
            len(
                RequisitionCase.open_for_location(self.domain.name,
                                                  self.sp.location._id)), 0)

        for product, amt in amounts:
            self.check_stock_models(req, product, 0, -amt, 'stock')
            self.check_stock_models(self.sp, product, amt, amt, 'stock')
Exemplo n.º 4
0
        for s, reqs in by_status.items():
            next_action = req_config.get_next_action(
                RequisitionStatus.to_action_type(s))

            if next_action:
                # we could make this even more customizable by specifying it per requisition
                # but that would get even messier in terms of constructing the messages
                # so we'll just compose one message per status type now, and then send
                # it to everyone who should be notified.
                to_notify = filter(
                    create_unique_filter(lambda u: u._id),
                    itertools.chain(
                        *(get_notification_recipients(next_action, r)
                          for r in reqs)))

                msg = get_notification_message(next_action, reqs)
                for u in to_notify:
                    phone = u.get_verified_number()
                    if phone:
                        send_sms_to_verified_number(phone, msg)


def raise_events(xform, cases):
    requisition_cases = [
        RequisitionCase.wrap(c._doc) for c in cases
        if c.type == const.REQUISITION_CASE_TYPE
    ]
    if requisition_cases and requisition_cases[
            0].requisition_status == RequisitionStatus.APPROVED:
        requisition_approved.send(sender=None, requisitions=requisition_cases)
    if requisition_cases and requisition_cases[