def handle(self, text): contact = self.msg.logistics_contact sp = self.msg.logistics_contact.supply_point stock_report = create_stock_report(Reports.REC, sp, text, self.msg.logger_msg, timestamp=self.msg.timestamp) if stock_report.errors: for e in stock_report.errors: if isinstance(e, UnknownCommodityCodeError): self.respond_error(_(config.Messages.INVALID_PRODUCT_CODE) % {"product_code": e}) return self.respond_error(_(config.Messages.DELIVERY_BAD_FORMAT)) return else: expected_products = set(contact.commodities.all()) # define missing as products not seen in the last 7 days # the exclusion prevents newly added products from counting as "seen" start_date = datetime.utcnow() + timedelta(days=-7) seen_products = set(Product.objects.get(pk=product_id) for product_id in \ ProductStock.objects.filter\ (supply_point=sp, last_modified__gte=start_date)\ .exclude(quantity=None)\ .values_list("product", flat=True)) self.respond(_(config.Messages.DELIVERY_CONFIRM), reply_list=','.join(sorted(stock_report.reported_products()))) SupplyPointStatus.objects.create(supply_point=sp, status_type=SupplyPointStatusTypes.DELIVERY_FACILITY, status_value=SupplyPointStatusValues.RECEIVED, status_date=self.msg.timestamp)
def handle(self, text): words = set(t.lower() for t in text.split(" ")) if not words: self.add_tag("Error") return self.help() products = [Product.objects.get(sms_code__iexact=code) for code in words \ if Product.objects.filter(sms_code__iexact=code).exists()] if len(products) != len(words): bad = words - set([p.sms_code.lower() for p in products]) self.respond_error(_(config.Messages.INVALID_PRODUCT_CODE), product_code=" ".join(bad)) return # fake a soh report with the stock level set to 0 for all products fake_report_text = " ".join(["%s 0" % p.sms_code for p in products]) stock_report = create_stock_report(Reports.SOH, self.msg.logistics_contact.supply_point, fake_report_text, self.msg.logger_msg, self.msg.timestamp) kwargs = {'contact_name': self.msg.logistics_contact.name, 'facility_name': self.msg.logistics_contact.supply_point.name, 'product_names': " ".join(sorted(words))} self.respond(_(config.Messages.STOCKOUT_CONFIRM), **kwargs)
def _process_rec(self): stock_report = create_stock_report(Reports.REC, self.hsa.supply_point, self.report_data, self.msg.logger_msg) requests = StockRequest.close_pending_from_receipt_report(stock_report, self.hsa) if stock_report.errors: # TODO: respond better. self.respond(config.Messages.GENERIC_ERROR) else: self.respond(config.Messages.REPORT_RECEIPT_RESPONSE, reporter=self.msg.logistics_contact.name, hsa=self.hsa.name, products=" ".join(stock_report.reported_products()).strip())
def handle(self, text): contact = self.msg.logistics_contact sp = self.msg.logistics_contact.supply_point stock_report = create_stock_report(Reports.LOSS_ADJUST, sp, text, self.msg.logger_msg, timestamp=self.msg.timestamp) if stock_report.errors: self.respond_error(_(config.Messages.LOSS_ADJUST_BAD_FORMAT)) return else: self.respond(_(config.Messages.LOSS_ADJUST_CONFIRM))
def _process_give(self): words = self.report_data.split(" ") # TODO: this is too much copy-paste from the transfer handler if len(words) < 3: return self.help() hsa_id = words[0] remainder = " ".join(words[1:]) hsa = util.get_hsa(hsa_id) if hsa is None: self.respond(config.Messages.UNKNOWN_HSA, hsa_id=hsa_id) else: stock_report = create_stock_report(Reports.GIVE, self.hsa.supply_point, remainder, self.msg.logger_msg) transfers = StockTransfer.create_from_transfer_report(stock_report, hsa.supply_point) send_transfer_responses(self.msg, stock_report, transfers, self.hsa, hsa)
def handle(self, text): words = text.split(" ") # need at least a keyword and 1 product + amount if len(words) < 3: return self.help() hsa_id = words[0] remainder = " ".join(words[1:]) hsa = util.get_hsa(hsa_id) if hsa is None: self.respond(config.Messages.UNKNOWN_HSA, hsa_id=hsa_id) else: stock_report = create_stock_report(Reports.GIVE, self.msg.logistics_contact.supply_point, remainder, self.msg.logger_msg) transfers = StockTransfer.create_from_transfer_report(stock_report, hsa.supply_point) send_transfer_responses(self.msg, stock_report, transfers, self.msg.logistics_contact, hsa)
def handle(self, text): contact = self.msg.logistics_contact sp = self.msg.logistics_contact.supply_point stock_report = create_stock_report(Reports.SOH, sp, text, self.msg.logger_msg, self.msg.timestamp) if stock_report.errors: self.respond_error(_(config.Messages.SOH_BAD_FORMAT)) return else: expected_products = set(contact.commodities.all()) # define missing as products not seen in the last 7 days # the exclusion prevents newly added products from counting as "seen" start_date = datetime.utcnow() + timedelta(days=-7) seen_products = set(Product.objects.get(pk=product_id) for product_id in \ ProductStock.objects.filter\ (supply_point=sp, last_modified__gte=start_date)\ .exclude(quantity=None)\ .values_list("product", flat=True)) # if missing products tell them they still need to report, otherwise send confirmation missing_products = expected_products - seen_products if missing_products: kwargs = {'contact_name': self.msg.contact.name, 'facility_name': sp.name, 'product_list': ' '.join(sorted([p.sms_code for p in missing_products]))} self.respond(_(config.Messages.SOH_PARTIAL_CONFIRM), **kwargs) else: self.respond(_(config.Messages.SOH_CONFIRM), reply_list=','.join(sorted(stock_report.reported_products()))) SupplyPointStatus.objects.create(supply_point=sp, status_type=SupplyPointStatusTypes.SOH_FACILITY, status_value=SupplyPointStatusValues.SUBMITTED, status_date=self.msg.timestamp) # this is an artifact of the response generating the l&a reminder SupplyPointStatus.objects.create(supply_point=sp, status_type=SupplyPointStatusTypes.LOSS_ADJUSTMENT_FACILITY, status_value=SupplyPointStatusValues.REMINDER_SENT, status_date=self.msg.timestamp)
def _process_emergency_soh(self): stock_report = create_stock_report(Reports.EMERGENCY_SOH, self.hsa.supply_point, self.report_data, self.msg.logger_msg) requests = StockRequest.create_from_report(stock_report, self.hsa) if stock_report.errors: # TODO: respond better. self.respond(config.Messages.GENERIC_ERROR) else: if self.msg.logistics_contact.role == ContactRole.objects.get(code=config.Roles.IN_CHARGE): self.respond(config.Messages.REPORT_SOH_RESPONSE, hsa=self.hsa.name, products=", ".join(req.sms_format() for req in requests), hsa_id=self.hsa.supply_point.code) else: assert(self.msg.logistics_contact.role == ContactRole.objects.get(code=config.Roles.HSA)) send_emergency_responses(self.msg, self.hsa, stock_report, requests)
def handle(self, text): """ Check some preconditions, based on shared assumptions of these handlers. Return true if there is a precondition that wasn't met. If all preconditions are met, the variables for facility and name will be set. This method will manage some replies as well. """ # at some point we may want more granular permissions for these # operations, but for now we just share the one self.hsa = self.msg.logistics_contact stock_report = create_stock_report(self.get_report_type(), self.hsa.supply_point, text, self.msg.logger_msg) self.requests = StockRequest.create_from_report(stock_report, self.hsa) self.send_responses(stock_report)
def _process_soh(self): stock_report = create_stock_report(Reports.SOH, self.hsa.supply_point, self.report_data, self.msg.logger_msg) requests = StockRequest.create_from_report(stock_report, self.hsa) if stock_report.errors: # TODO: respond better. self.respond(config.Messages.GENERIC_ERROR) else: if self.msg.logistics_contact.role == ContactRole.objects.get( code=config.Roles.IN_CHARGE): self.respond(config.Messages.REPORT_SOH_RESPONSE, hsa=self.hsa.name, products=", ".join(req.sms_format() for req in requests), hsa_id=self.hsa.supply_point.code) else: assert ( self.msg.logistics_contact.role == ContactRole.objects.get( code=config.Roles.HSA)) send_soh_responses(self.msg, self.hsa, stock_report, requests)
def handle(self, text): contact = self.msg.logistics_contact sp = self.msg.logistics_contact.supply_point stock_report = create_stock_report(Reports.REC, sp, text, self.msg.logger_msg, timestamp=self.msg.timestamp) if stock_report.errors: for e in stock_report.errors: if isinstance(e, UnknownCommodityCodeError): self.respond_error( _(config.Messages.INVALID_PRODUCT_CODE) % {"product_code": e}) return self.respond_error(_(config.Messages.DELIVERY_BAD_FORMAT)) return else: expected_products = set(contact.commodities.all()) # define missing as products not seen in the last 7 days # the exclusion prevents newly added products from counting as "seen" start_date = datetime.utcnow() + timedelta(days=-7) seen_products = set(Product.objects.get(pk=product_id) for product_id in \ ProductStock.objects.filter\ (supply_point=sp, last_modified__gte=start_date)\ .exclude(quantity=None)\ .values_list("product", flat=True)) self.respond(_(config.Messages.DELIVERY_CONFIRM), reply_list=','.join( sorted(stock_report.reported_products()))) SupplyPointStatus.objects.create( supply_point=sp, status_type=SupplyPointStatusTypes.DELIVERY_FACILITY, status_value=SupplyPointStatusValues.RECEIVED, status_date=self.msg.timestamp)