def help(self):
     service_delivery_point=self.msg.contact.contactdetail.service_delivery_point
     if service_delivery_point.service_delivery_point_type.name == "DISTRICT":
         self.respond(_("How many R&R forms have you submitted to MSD for group %(group)s? Reply with 'submitted A <number of R&Rs submitted for group A> B <number of R&Rs submitted for group B>...'"))
     elif service_delivery_point.service_delivery_point_type.name == "FACILITY":
         st = ServiceDeliveryPointStatusType.objects.filter(short_name="r_and_r_submitted_facility_to_district")[0:1].get()
         ns = ServiceDeliveryPointStatus(service_delivery_point=service_delivery_point, status_type=st, status_date=datetime.now())
         ns.save()
         kwargs = {'contact_name': self.msg.contact.name,
                   'sdp_name': self.msg.contact.contactdetail.service_delivery_point.name}
         self.respond(_('Thank you %(contact_name)s for submitting your R and R form for %(sdp_name)s'), **kwargs)
         return
 def handle(self, text):
     product_list = self.parse_report(text)
     # flatten
     product_list =  map(str, [item for sublist in product_list for item in sublist])
     #product_list = text.split()
     
     if (len(product_list) == 0) or (len(product_list) > 0 and len(product_list) % 2 != 0):
          self.respond(_("Sorry, invalid format.  The message should be in the format 'soh <product> <amount> <product> <amount>'"))
          return
     else:    
         reported_products = []
         sdp = self.msg.contact.contactdetail.service_delivery_point
         reply_list = []
         while len(product_list) >= 2:
             product_code = sub('\.', '', product_list.pop(0))
             quantity = sub('\.', '', product_list.pop(0))
             if not is_number(quantity):
                 if is_number(product_code):
                     temp = product_code
                     product_code = quantity
                     quantity = temp
                 else:                        
                     self.respond(_("Sorry, invalid format.  The message should be in the format 'soh product amount product amount'"))
                     return
             report_type = ProductReportType.objects.filter(sms_code='soh')[0:1].get()
             try:
                 product = Product.get_product(product_code)   
             except Product.DoesNotExist:
                 self.respond(_("Sorry, invalid product code %(code)s"), code=product_code.upper())
                 return
             reported_products.append(product.sms_code)
             reply_list.append('%s' % (product.sms_code) )
             sdp.report_product_status(product=product,report_type=report_type,quantity=quantity, message=self.msg.logger_msg)
         now = datetime.now()
         all_products = []
         date_check = datetime.now() + relativedelta(days=-7)
         missing_products = Product.objects.filter(Q(activeproduct__service_delivery_point=sdp, activeproduct__is_active=True), 
                                                   ~Q(servicedeliverypointproductreport__report_date__gt=date_check) )
         for dict in missing_products.values('sms_code'):
             all_products.append(dict['sms_code'])
         missing_product_list = list(set(all_products)-set(reported_products))
         if missing_product_list:
             kwargs = {'contact_name': self.msg.contact.name,
                       'facility_name': sdp.name,
                       'product_list': ' '.join(missing_product_list)}
             self.respond(_('Thank you %(contact_name)s for reporting your stock on hand for %(facility_name)s.  Still missing %(product_list)s.'), **kwargs)
         else:    
             self.respond(_('Thank you, you reported you have %(reply_list)s. If incorrect, please resend.'), reply_list=','.join(reply_list))
         self.respond(_("Please send in your adjustments in the format 'la <product> +-<amount> +-<product> +-<amount>...'"))
         st = ServiceDeliveryPointStatusType.objects.filter(short_name="lost_adjusted_reminder_sent_facility")[0:1].get()
         ns = ServiceDeliveryPointStatus(service_delivery_point=sdp, status_type=st, status_date=datetime.now())
         ns.save()
    def handle(self, text):
        if re.match("del", text.strip().lower()):
            self.respond(_("You have reported that you haven't yet received your delivery."))
            st = ServiceDeliveryPointStatusType.objects.filter(short_name="delivery_not_received_facility")[0:1].get()
            ns = ServiceDeliveryPointStatus(
                service_delivery_point=self.msg.contact.contactdetail.service_delivery_point,
                status_type=st,
                status_date=datetime.datetime.now(),
            )
            ns.save()

        elif re.match("sub", text.strip().lower()):
            self.respond(_("You have reported that you haven't yet sent in your R&R."))
            st = ServiceDeliveryPointStatusType.objects.filter(short_name="r_and_r_not_submitted_facility_to_district")[
                0:1
            ].get()
            ns = ServiceDeliveryPointStatus(
                service_delivery_point=self.msg.contact.contactdetail.service_delivery_point,
                status_type=st,
                status_date=datetime.datetime.now(),
            )
            ns.save()
        else:
            self.respond(
                _(
                    'If you haven\'t submitted your R&R, respond "not submitted". If you haven\'t received your delivery, respond "not delivered"'
                )
            )
Example #4
0
    def test_all(self):
        sdp = ServiceDeliveryPoint(name="Test SDP")
        self.assertEqual(sdp.name, "Test SDP")
        sdp.save()

        self.assertFalse(
            sdp.received_reminder_after(
                "r_and_r_reminder_sent_facility",
                datetime(datetime.now().year, datetime.now().month, 1) - timedelta(seconds=1),
            )
        )

        # create a reminder
        st = ServiceDeliveryPointStatusType.objects.filter(short_name="r_and_r_reminder_sent_facility")[0:1].get()
        ns = ServiceDeliveryPointStatus(service_delivery_point=sdp, status_type=st, status_date=datetime.now())
        ns.save()

        # check reminder
        self.assertTrue(
            sdp.received_reminder_after(
                "r_and_r_reminder_sent_facility",
                datetime(datetime.now().year, datetime.now().month, 1) - timedelta(seconds=1),
            )
        )
    def handle(self, text):
        service_delivery_point=self.msg.contact.contactdetail.service_delivery_point
        if service_delivery_point.service_delivery_point_type.name == "DISTRICT":
            st = ServiceDeliveryPointStatusType.objects.filter(short_name="r_and_r_submitted_district_to_msd")[0:1].get()
            ns = ServiceDeliveryPointStatus(service_delivery_point=service_delivery_point, status_type=st, status_date=datetime.now())
            ns.save()
            
            delivery_groups_list = text.split()
            if len(delivery_groups_list) > 0 and len(delivery_groups_list) % 2 != 0:
                 self.respond(_("Sorry, invalid format.  The message should be in the format 'submitted A <quantity  of R&R forms for group A> B <quantity  of R&R forms for group B>...'"))
                 return
            else:    
                sdp = self.msg.contact.contactdetail.service_delivery_point
                while len(delivery_groups_list) >= 2:
                    quantity = delivery_groups_list.pop(0)
                    delivery_group_name = delivery_groups_list.pop(0)
                    if not is_number(quantity):
                        if is_number(delivery_group_name):
                            temp = delivery_group_name
                            delivery_group_name = quantity
                            quantity = temp
                        else:                        
                            self.respond(_("Sorry, invalid format.  The message should be in the format 'submitted A <quantity  of R&R forms for group A> B <quantity  of R&R forms for group B>...'"))
                            return
                                        
                    try:
                        delivery_group = DeliveryGroup.objects.filter(name__iexact=delivery_group_name)[0:1].get()   
                    except DeliveryGroup.DoesNotExist:
                        kwargs = {'delivery_group_name': delivery_group_name.upper()}
                        self.respond(_("Sorry, invalid Delivery Group %(delivery_group_name)s. Please try again"), **kwargs)
                        return
                    if float(quantity) > service_delivery_point.child_sdps().filter(delivery_group__name__iexact=delivery_group_name).count():
                        kwargs = {'quantity': quantity,
                                  'delivery_group_name': delivery_group_name.upper()}
                        self.respond(_("You reported %(quantity)s forms submitted for group %(delivery_group_name)s, which is more than the number of facilities in group %(delivery_group_name)s. Please try again."), **kwargs)
                        return

                    sdp.report_delivery_group_status(delivery_group=delivery_group,quantity=quantity, message=self.msg.logger_msg)
            kwargs = {'contact_name': self.msg.contact.name,
                      'sdp_name': self.msg.contact.contactdetail.service_delivery_point.name}
            self.respond(_('Thank you %(contact_name)s for reporting your R&R form submissions for %(sdp_name)s'), **kwargs)
            self._send_randr_alert_to_facilities(service_delivery_point)
            return
        elif service_delivery_point.service_delivery_point_type.name == "FACILITY":
            st = ServiceDeliveryPointStatusType.objects.filter(short_name="r_and_r_submitted_facility_to_district")[0:1].get()
            ns = ServiceDeliveryPointStatus(service_delivery_point=service_delivery_point, status_type=st, status_date=datetime.now())
            ns.save()
            kwargs = {'contact_name': self.msg.contact.name,
                      'sdp_name': self.msg.contact.contactdetail.service_delivery_point.name}
            self.respond(_('Thank you %(contact_name)s for submitting your R and R form for %(sdp_name)s'), **kwargs)
            return
        else:
            self.respond(_("Sorry, you need to register."))
 def help(self):
     service_delivery_point=self.msg.contact.contactdetail.service_delivery_point
     if service_delivery_point.service_delivery_point_type.name == "DISTRICT":
         st = ServiceDeliveryPointStatusType.objects.filter(short_name="delivery_received_district")[0:1].get()
         ns = ServiceDeliveryPointStatus(service_delivery_point=service_delivery_point, status_type=st, status_date=datetime.now())
         ns.save()
         kwargs={'contact_name': self.msg.contact.name,
                 'facility_name': service_delivery_point.name}
         self.respond(_('Thank you %(contact_name)s for reporting your delivery for %(facility_name)s'), **kwargs)
         self._send_delivery_alert_to_facilities(service_delivery_point)
     elif service_delivery_point.service_delivery_point_type.name == "FACILITY":
         st = ServiceDeliveryPointStatusType.objects.filter(short_name="delivery_received_facility")[0:1].get()
         ns = ServiceDeliveryPointStatus(service_delivery_point=service_delivery_point, status_type=st, status_date=datetime.now())
         ns.save()
         self.respond(_("To record a delivery, respond with \"delivered product amount product amount...\""))
 def handle(self, text):
     sub_command = text.strip().lower()
     if re.match("hap", sub_command) or re.match("no", sub_command):
         self.respond(_('You have reported that you have not yet received supervision this month.'))
         st = ServiceDeliveryPointStatusType.objects.filter(short_name="supervision_not_received_facility")[0:1].get()
         print st
         ns = ServiceDeliveryPointStatus(service_delivery_point=self.msg.contact.contactdetail.service_delivery_point, status_type=st, status_date=datetime.datetime.now())
         ns.save()            
     elif re.match("ndi", sub_command) or re.match("yes", sub_command):
         self.respond(_('Thank you for reporting that you have received supervision this month.'))
         st = ServiceDeliveryPointStatusType.objects.filter(short_name="supervision_received_facility")[0:1].get()
         print st
         ns = ServiceDeliveryPointStatus(service_delivery_point=self.msg.contact.contactdetail.service_delivery_point, status_type=st, status_date=datetime.datetime.now())
         ns.save()
     else:
         self.help()
 def handle(self, text):
     service_delivery_point=self.msg.contact.contactdetail.service_delivery_point
     if service_delivery_point.service_delivery_point_type.name == "DISTRICT":
         st = ServiceDeliveryPointStatusType.objects.filter(short_name="delivery_received_district")[0:1].get()
         ns = ServiceDeliveryPointStatus(service_delivery_point=service_delivery_point, status_type=st, status_date=datetime.now())
         ns.save()
         kwargs={'contact_name': self.msg.contact.name,
                 'facility_name': service_delivery_point.name}
         self.respond(_('Thank you %(contact_name)s for reporting your delivery for %(facility_name)s'), **kwargs)
         self._send_delivery_alert_to_facilities(service_delivery_point)
     elif service_delivery_point.service_delivery_point_type.name == "FACILITY":
         product_list = text.split()
         if len(product_list) > 0 and len(product_list) % 2 != 0:
              self.respond(_("Sorry, invalid format.  The message should be in the format 'delivered product amount product amount'"))
              return
         else:
             reply_list = []
             while len(product_list) >= 2:
                 product_code = product_list.pop(0)
                 quantity = product_list.pop(0)
                 if not is_number(quantity):
                     if is_number(product_code):
                         temp = product_code
                         product_code = quantity
                         quantity = temp
                     else:                        
                         self.respond(_("Sorry, invalid format.  The message should be in the format 'delivered product amount product amount'"))
                         return
                 
                 report_type = ProductReportType.objects.filter(sms_code='dlvd')[0:1].get()
                 try:
                     product = Product.get_product(product_code)      
                 except Product.DoesNotExist:
                     self.respond(_('Sorry, invalid product code %(code)s'), code=product_code)
                     return
                 reply_list.append('%s %s' % (product.sms_code, quantity) )
                 service_delivery_point.report_product_status(product=product,report_type=report_type,quantity=quantity, message=self.msg.logger_msg)
             
             st = ServiceDeliveryPointStatusType.objects.filter(short_name="delivery_quantities_reported")[0:1].get()
             ns = ServiceDeliveryPointStatus(service_delivery_point=service_delivery_point, status_type=st, status_date=datetime.now())
             ns.save()
             self.respond(_('Thank you, you reported a delivery of %(reply_list)s. If incorrect, please resend.'), reply_list=','.join(reply_list))             
    def handle(self, text):
        result = text.lower().split()
        command = result.pop(0)
        msd_code = result.pop(0)
        extra = ''
        while len(result) > 0:
            extra = extra + ' ' + result.pop(0)
            
        if command != 'send_inquiry_message':
            try:
                sdp = ServiceDeliveryPoint.objects.get(msd_code=msd_code.upper())
            except:
                self.respond("Invalid msd code %s" % msd_code)
                return
            contact_details_to_remind = ContactDetail.objects.filter(service_delivery_point=sdp)

        if command in ['la']:
            for contact_detail in contact_details_to_remind:
                default_connection = contact_detail.default_connection
                if default_connection:
                    m = OutgoingMessage(default_connection, _("Please send in your adjustments in the format 'la <product> +-<amount> +-<product> +-<amount>...'"))
                    m.send() 
                    st = ServiceDeliveryPointStatusType.objects.filter(short_name="lost_adjusted_reminder_sent_facility")[0:1].get()
                    ns = ServiceDeliveryPointStatus(service_delivery_point=contact_detail.service_delivery_point, status_type=st, status_date=datetime.now())
                    ns.save()
            self.respond("Sent")
        if command in ['fw']:
            for contact_detail in contact_details_to_remind:
                default_connection = contact_detail.default_connection
                if default_connection:
                    m = OutgoingMessage(default_connection, _(extra))
                    m.send() 
            self.respond("Sent '%s'" % _(extra))
        if command in ['supervision']:
            for contact_detail in contact_details_to_remind:
                default_connection = contact_detail.default_connection
                if default_connection:
                    m = OutgoingMessage(default_connection, _("Have you received supervision this month? Please reply 'supervision yes' or 'supervision no'"))
                    m.send() 
                    st = ServiceDeliveryPointStatusType.objects.filter(short_name="supervision_reminder_sent_facility")[0:1].get()
                    ns = ServiceDeliveryPointStatus(service_delivery_point=contact_detail.service_delivery_point, status_type=st, status_date=datetime.now())
                    ns.save()
            self.respond("Sent")
        if command in ['soh','hmk']:
            for contact_detail in contact_details_to_remind:
                default_connection = contact_detail.default_connection
                if default_connection:
                    m = OutgoingMessage(default_connection, _("Please send in your stock on hand information in the format 'soh <product> <amount> <product> <amount>...'"))
                    m.send() 
                    st = ServiceDeliveryPointStatusType.objects.filter(short_name="soh_reminder_sent_facility")[0:1].get()
                    ns = ServiceDeliveryPointStatus(service_delivery_point=contact_detail.service_delivery_point, status_type=st, status_date=datetime.now())
                    ns.save()
            self.respond("Sent")
        elif command in ['si']:
            product = Product.objects.get(product_code=addl_parameter)
            if not product:
                self.respond("Invalid product code %s" % addl_parameter)
                return
            if sdp.service_delivery_point_type.name == "FACILITY":
                contact_details_to_remind = ContactDetail.objects.filter(service_delivery_point=sdp)                
                for contact_detail in contact_details_to_remind:
                    default_connection = contact_detail.default_connection
                    if default_connection:
                        m = OutgoingMessage(default_connection, _("How much %s (msd code %s) do you have in stock?  Please respond 'si %s <amount>'" % (product.name, addl_parameter, addl_parameter) ))
                        m.send() 
                self.respond("Sent")
            else:
                self.respond("Can only initiate product inquiry for a single facility via SMS - %s is a %s" % (sdp.name, sdp.service_delivery_point_type.name) )
                return
                
        elif command in ['send_inquiry_message']:
            product = Product.objects.get(product_code=addl_parameter)
            if not product:
                self.respond("Invalid product code %s" % addl_parameter)
                return
            try:
                sdp = ServiceDeliveryPoint.objects.get(id=msd_code)
            except:
                self.respond("Invalid ID %s" % msd_code)
                return
            
            if sdp.service_delivery_point_type.name == "FACILITY":
                contact_details_to_remind = ContactDetail.objects.filter(service_delivery_point=sdp)                
                for contact_detail in contact_details_to_remind:
                    default_connection = contact_detail.default_connection
                    if default_connection:
                        m = OutgoingMessage(default_connection, _("How much %s (msd code %s) do you have in stock?  Please respond 'si %s <amount>'" % (product.name, addl_parameter, addl_parameter) ))
                        m.send() 
            elif sdp.service_delivery_point_type.name == "DISTRICT":
                for facility_sdp in sdp.child_sdps():
                    contact_details_to_remind = ContactDetail.objects.filter(service_delivery_point=facility_sdp)                
                    for contact_detail in contact_details_to_remind:
                        default_connection = contact_detail.default_connection
                        if default_connection:
                            m = OutgoingMessage(default_connection, _("How much %s (msd code %s) do you have in stock?  Please respond 'si %s <amount>'" % (product.name, addl_parameter, addl_parameter) ))
                            m.send() 
            elif sdp.service_delivery_point_type.name == "REGION":
                for district_sdp in sdp.child_sdps():
                    for facility_sdp in district_sdp.child_sdps:
                        contact_details_to_remind = ContactDetail.objects.filter(service_delivery_point=facility_sdp)                
                        for contact_detail in contact_details_to_remind:
                            default_connection = contact_detail.default_connection
                            if default_connection:
                                m = OutgoingMessage(default_connection, _("How much %s (msd code %s) do you have in stock?  Please respond 'si %s <amount>'" % (product.name, addl_parameter, addl_parameter) ))
                                m.send()

        elif command in ['randr']:
            for contact_detail in contact_details_to_remind:
                default_connection = contact_detail.default_connection
                if default_connection:
                    if sdp.service_delivery_point_type.name == "DISTRICT":
                        m = OutgoingMessage(default_connection, _("How many R&R forms have you submitted to MSD? Reply with 'submitted A <number of R&Rs submitted for group A> B <number of R&Rs submitted for group B>'"))
                        m.send() 
                    elif sdp.service_delivery_point_type.name == "FACILITY":
                        m = OutgoingMessage(default_connection, _("Have you sent in your R&R form yet for this quarter? Please reply \"submitted\" or \"not submitted\""))
                        m.send() 
                        st = ServiceDeliveryPointStatusType.objects.filter(short_name="r_and_r_reminder_sent_facility")[0:1].get()
                        ns = ServiceDeliveryPointStatus(service_delivery_point=contact_detail.service_delivery_point, status_type=st, status_date=datetime.now())
                        ns.save()        
            self.respond("Sent")
        elif command in ['delivery']:
            for contact_detail in contact_details_to_remind:
                default_connection = contact_detail.default_connection
                if default_connection:
                    if contact_detail.service_delivery_point.service_delivery_point_type.name == "FACILITY":
                        m = OutgoingMessage(default_connection, _("Did you receive your delivery yet? Please reply 'delivered <product> <amount> <product> <amount>...'"))
                        m.send() 
                        st = ServiceDeliveryPointStatusType.objects.filter(short_name="delivery_received_reminder_sent_facility")[0:1].get()
                        ns = ServiceDeliveryPointStatus(service_delivery_point=contact_detail.service_delivery_point, status_type=st, status_date=datetime.now())
                        ns.save()
                    elif contact_detail.service_delivery_point.service_delivery_point_type.name == "DISTRICT": 
                        m = OutgoingMessage(default_connection, _("Did you receive your delivery yet? Please reply 'delivered' or 'not delivered'"))
                        m.send() 
                        st = ServiceDeliveryPointStatusType.objects.filter(short_name="r_and_r_reminder_sent_district")[0:1].get()
                        ns = ServiceDeliveryPointStatus(service_delivery_point=contact_detail.service_delivery_point, status_type=st, status_date=datetime.now())
                        ns.save()
                    else:
                        self.respond("Sorry there was a problem with your service delivery point setup. Please check via the admin.")
            self.respond("Sent")
        elif command in ['latedelivery']:
            for contact_detail in contact_details_to_remind:
                default_connection = contact_detail.default_connection
                if default_connection:
                    service_delivery_point = contact_detail.service_delivery_point
                    kwargs = {"group_name": current_delivering_group(), 
                              "group_total": service_delivery_point.child_sdps().filter(delivery_group__name=current_delivering_group()).count(), 
                              "not_responded_count": service_delivery_point.child_sdps_not_responded_delivery_this_month(), 
                              "not_received_count": service_delivery_point.child_sdps_not_received_delivery_this_month()}
                    m = OutgoingMessage(default_connection, 
                                        _("Facility deliveries for group %(group_name)s (out of %(group_total)d): %(not_responded_count)d haven't responded and %(not_received_count)d have reported not receiving. See ilsgateway.com"),
                                        **kwargs) 
                    m.send()         
            self.respond("Sent")
                        
def _send_reminders(router,
                    reminder_name,
                    monthday,
                    byhour,
                    byminute,                    
                    additional_reminders_to_send,
                    default_query=ServiceDeliveryPoint.objects.all(),
                    bysetpos=-1,
                    send_initial=True,
                    message_kwargs={}):
    
    now = _get_current_time()
        
    additional_reminders_to_send_count = len(additional_reminders_to_send)
    sdp_status_type = ServiceDeliveryPointStatusType.objects.filter(short_name=reminder_name)[0:1].get()
    
    #create a date rule (for business day logic) - last weekday prior to monthday
    if monthday:
        rr1 = rrule(MONTHLY, 
                    interval=1, 
                    dtstart=now + relativedelta(months=-2), 
                    until=  now + relativedelta(months=+2), 
                    byweekday=(MO,TU,WE,TH,FR), 
                    byhour=byhour, 
                    bysetpos=bysetpos,
                    byminute=byminute,
                    bysecond=0,
                    bymonthday=(monthday-2, monthday-1, monthday))
    else:
        #Date rule for business days prior to the end of the month - can't use a monthday or we crash
        rr1 = rrule(MONTHLY, 
                    interval=1, 
                    dtstart=now + relativedelta(months=-2), 
                    until=  now + relativedelta(months=+2), 
                    byweekday=(MO,TU,WE,TH,FR), 
                    byhour=byhour, 
                    bysetpos=bysetpos,
                    byminute=byminute,
                    bysecond=0)
        
    start_time = rr1.before(now)
    end_time = rr1.after(now)
    

    # query for sdps with no reminders sent 
    q_no_reminders = default_query.exclude(servicedeliverypointstatus__status_date__range=(start_time, end_time),
                                           servicedeliverypointstatus__status_type=sdp_status_type) 
    
    # query for sdps with reminders sent: annotate to count the number of reminders sent
    q_reminders = default_query.filter(servicedeliverypointstatus__status_date__range=(start_time, end_time),
                                        servicedeliverypointstatus__status_type=sdp_status_type) \
                                        .annotate(last_status_date=Max('servicedeliverypointstatus__status_date'),
                                                  status_count=Count('servicedeliverypointstatus'))
    # add 1 to the count to include the initial reminder
    q_reminders = q_reminders.filter(status_count__lt=additional_reminders_to_send_count+1)
            
    #logging.debug("No reminder sent query: %s, count %d" % (q_no_reminders, len(q_no_reminders)))
    #logging.debug("Reminders already sent query: %s, count %d" % (q_reminders, len(q_reminders)))
    logging.debug("Sending Reminders for %s:" % reminder_name)
    logging.debug("  Reminder start window: %s" % start_time)
    logging.debug("  Reminder end window: %s" % end_time)
    if send_initial:
        logging.debug("  Sending initial reminders:")
        for sdp in q_no_reminders:
            contact_details_to_remind = sdp.contacts('primary')
            sent = False
            for contact_detail in contact_details_to_remind:
                default_connection = contact_detail.default_connection
                if default_connection:
                    m = get_message(contact_detail, reminder_name, **message_kwargs)
                    if m:
                        logging.debug("    sdp %s (delivery group: %s) hasn't yet received their %s reminder, contact detail %s" % (sdp, 
                                                                                                                                sdp.delivery_group, 
                                                                                                                                reminder_name, 
                                                                                                                                contact_detail))
                        m.send()
                        sent = True
            if sent:
                ns = ServiceDeliveryPointStatus(service_delivery_point=contact_detail.service_delivery_point, 
                                                status_type=sdp_status_type, 
                                                status_date=_get_current_time())
                ns.save()
    
    logging.debug("  Sending followup reminders:")
    for sdp in q_reminders:
        next_reminder = additional_reminders_to_send[sdp.status_count-1]
        #TODO: Do we want a check to see whether the reminder has gone out already today (if the server was down, or some other reason?)
        # relativedelta reset to midnight is to count dates that might have an original reminder time later than the reminder time - otherwise we would lose a business day
        # also account for the count + 1, because we include the first day of the reminder cycle in the count - but we want ADDITIONAL days
        rr2 = rrule(DAILY, 
            dtstart=start_time + relativedelta(hour=0, minute=0, second=0, microsecond=0), 
            count=next_reminder['additional_business_days']+1,
            byhour=next_reminder['hour'],
            byminute=next_reminder['minute'],
            bysecond=0,
            byweekday=(MO,TU,WE,TH,FR))            
        next_reminder_date = list(rr2).pop()
        #logging.debug("    Reminder RRUle: %s" % list(rr2))
        logging.debug("    Last status date: %s" % sdp.last_status_date)
        if now > next_reminder_date:
            contact_details_to_remind = sdp.contacts('primary')
            sent = False
            for contact_detail in contact_details_to_remind:
                default_connection = contact_detail.default_connection
                if default_connection:
                    logging.debug("      %s %s" % (contact_detail, default_connection))
                    m = get_message(contact_detail, reminder_name, **message_kwargs)
                    if m:
                        m.send()
                        sent = True           
            if sent:
                ns = ServiceDeliveryPointStatus(service_delivery_point=contact_detail.service_delivery_point, 
                                                status_type=sdp_status_type, 
                                                status_date=_get_current_time())
                ns.save()     
                logging.debug("    SDP %s (delivery group %s) has already received %d %s reminders and is past reminder date %s for %s, sending reminder to the following contacts" % ( \
                         sdp, 
                         sdp.delivery_group, 
                         sdp.status_count,
                         reminder_name,
                         next_reminder_date, 
                         reminder_name))
        else:
            logging.debug("    SDP %s (delivery group %s) has already received %d %s reminders, next one is set for %s" % ( \
                         sdp, 
                         sdp.delivery_group, 
                         sdp.status_count,
                         reminder_name,
                         next_reminder_date))

    logging.info("%s (%s) sent to all PRIMARY contacts" % (sdp_status_type.name, sdp_status_type.short_name))
 def handle(self, text):
     self.respond(_('You have reported that you haven\'t yet sent in your R&R.'))
     st = ServiceDeliveryPointStatusType.objects.filter(short_name="r_and_r_not_submitted_facility_to_district")[0:1].get()
     ns = ServiceDeliveryPointStatus(service_delivery_point=self.msg.contact.contactdetail.service_delivery_point, status_type=st, status_date=datetime.datetime.now())
     ns.save()
 def handle(self, text):
     self.respond(_('You have reported that you haven\'t yet received your delivery.'))
     st = ServiceDeliveryPointStatusType.objects.filter(short_name="delivery_not_received_facility")[0:1].get()
     ns = ServiceDeliveryPointStatus(service_delivery_point=self.msg.contact.contactdetail.service_delivery_point, status_type=st, status_date=datetime.datetime.now())
     ns.save()