class VoucherUpdate(jsonobject.JsonObject): voucher_id = jsonobject.StringProperty(required=True) payment_status = jsonobject.StringProperty(required=True, choices=['success', 'failure']) payment_amount = jsonobject.DecimalProperty(required=False) failure_description = jsonobject.StringProperty(required=False) case_type = CASE_TYPE_VOUCHER @property def case_id(self): return self.voucher_id @property def properties(self): if self.payment_status == 'success': return { 'state': 'paid', 'amount_fulfilled': self.payment_amount, 'date_fulfilled': datetime.datetime.utcnow().date().isoformat(), } else: return { 'state': 'rejected', 'reason_rejected': self.failure_description, 'date_rejected': datetime.datetime.utcnow().date().isoformat(), }
class StockLedgerValueWrapper(jsonobject.JsonObject): """ Wrapper class to abstract StockState and the equivalent model coming out of Elasticsearch """ domain = jsonobject.StringProperty() case_id = jsonobject.StringProperty() section_id = jsonobject.StringProperty() entry_id = jsonobject.StringProperty() balance = jsonobject.DecimalProperty() # todo: should this be an int? last_modified = jsonobject.DateTimeProperty() last_modified_form_id = jsonobject.StringProperty() daily_consumption = jsonobject.FloatProperty() location_id = jsonobject.StringProperty() _sql_product = None _sql_location = None def __init__(self, _obj=None, sql_product=None, sql_location=None, *args, **kwargs): self._sql_product = sql_product self._sql_location = sql_location super(StockLedgerValueWrapper, self).__init__(_obj, *args, **kwargs) @property def sql_product(self): if self.entry_id and not self._sql_product: try: self._sql_product = SQLProduct.objects.get(domain=self.domain, product_id=self.entry_id) except ObjectDoesNotExist: # todo: cache this result so multiple failing calls don't keep hitting the DB return None return self._sql_product @property def sql_location(self): if self.location_id and not self._sql_location: try: self._sql_location = SQLLocation.objects.get(domain=self.domain, location_id=self.location_id) except ObjectDoesNotExist: # todo: cache this result so multiple failing calls don't keep hitting the DB return None return self._sql_location @classmethod def from_stock_state(cls, stock_state): return cls( case_id=stock_state.case_id, section_id=stock_state.section_id, entry_id=stock_state.product_id, balance=stock_state.stock_on_hand, last_modified=stock_state.last_modified_date, last_modified_form_id=stock_state.last_modified_form_id, daily_consumption=stock_state.daily_consumption, location_id=stock_state.location_id, sql_location=stock_state.sql_location, sql_product=stock_state.sql_product, )
class PaymentUpdate(jsonobject.JsonObject): id = jsonobject.StringProperty(required=True) status = jsonobject.StringProperty(required=True, choices=[SUCCESS, FAILURE]) amount = jsonobject.DecimalProperty(required=False) paymentDate = FlexibleDateTimeProperty(required=True) comments = jsonobject.StringProperty(required=False) failureDescription = jsonobject.StringProperty(required=False) paymentMode = jsonobject.StringProperty(required=False) checkNumber = jsonobject.StringProperty(required=False) bankName = jsonobject.StringProperty(required=False) @property def case_id(self): return self.id
class StockLedgerValueWrapper(jsonobject.JsonObject): """ Wrapper class to abstract StockState and the equivalent model coming out of Elasticsearch """ domain = jsonobject.StringProperty() case_id = jsonobject.StringProperty() section_id = jsonobject.StringProperty() entry_id = jsonobject.StringProperty() balance = jsonobject.DecimalProperty() # todo: should this be an int? last_modified = jsonobject.DateTimeProperty() last_modified_form_id = jsonobject.StringProperty() daily_consumption = jsonobject.FloatProperty() location_id = jsonobject.StringProperty() @property @quickcache(['self.domain', 'self.entry_id']) def sql_product(self): try: return SQLProduct.objects.get(domain=self.domain, product_id=self.entry_id) except ObjectDoesNotExist: return None @property @quickcache(['self.domain', 'self.location_id']) def sql_location(self): try: return ( SQLLocation.objects .prefetch_related('location_type') .get(domain=self.domain, location_id=self.location_id) ) except ObjectDoesNotExist: return None @classmethod def from_stock_state(cls, stock_state): return cls( case_id=stock_state.case_id, section_id=stock_state.section_id, entry_id=stock_state.product_id, balance=stock_state.stock_on_hand, last_modified=stock_state.last_modified_date, last_modified_form_id=stock_state.last_modified_form_id, daily_consumption=stock_state.daily_consumption, location_id=stock_state.location_id, sql_location=stock_state.sql_location, sql_product=stock_state.sql_product, )
class IncentiveUpdate(jsonobject.JsonObject): beneficiary_id = jsonobject.StringProperty(required=True) episode_id = jsonobject.StringProperty(required=True) payment_status = jsonobject.StringProperty(required=True, choices=['success', 'failure']) payment_amount = jsonobject.DecimalProperty(required=False) failure_description = jsonobject.StringProperty(required=False) bets_parent_event_id = jsonobject.StringProperty(required=False, choices=BETS_EVENT_IDS) case_type = CASE_TYPE_EPISODE @property def case_id(self): return self.episode_id @property def properties(self): status_key = 'tb_incentive_{}_status'.format(self.bets_parent_event_id) if self.payment_status == 'success': amount_key = 'tb_incentive_{}_amount'.format( self.bets_parent_event_id) date_key = 'tb_incentive_{}_payment_date'.format( self.bets_parent_event_id) return { status_key: 'paid', amount_key: self.payment_amount, date_key: datetime.datetime.utcnow().date().isoformat(), } else: date_key = 'tb_incentive_{}_rejection_date'.format( self.bets_parent_event_id) reason_key = 'tb_incentive_{}_rejection_reason'.format( self.bets_parent_event_id) return { status_key: 'rejected', date_key: datetime.datetime.utcnow().date().isoformat(), reason_key: self.failure_description, }
class StockTransactionHelper(jsonobject.JsonObject): """ Helper class for transactions """ product_id = jsonobject.StringProperty() action = jsonobject.StringProperty() subaction = jsonobject.StringProperty() domain = jsonobject.StringProperty() quantity = jsonobject.DecimalProperty() # todo: this field is never populated during normal form submissions, only on SMS submissions location_id = jsonobject.StringProperty() timestamp = jsonobject.DateTimeProperty() case_id = jsonobject.StringProperty() section_id = jsonobject.StringProperty() @property def ledger_reference(self): return UniqueLedgerReference( case_id=self.case_id, section_id=self.section_id, entry_id=self.product_id ) @property def relative_quantity(self): """ Gets the quantity of this transaction as a positive or negative number depending on the action/context """ if self.action == const.StockActions.CONSUMPTION: return -self.quantity else: return self.quantity def action_config(self, commtrack_config): action = CommtrackActionConfig(action=self.action, subaction=self.subaction) for a in commtrack_config.all_actions: if a.name == action.name: return a return None @property def date(self): if self.timestamp: return dateparse.json_format_datetime(self.timestamp) def to_xml(self, E=None, **kwargs): if not E: E = XML() return E.entry( id=self.product_id, quantity=str(self.quantity if self.action != StockActions.STOCKOUT else 0), ) @property def category(self): return 'stock' def fragment(self): """ A short string representation of this to be used in sms correspondence """ if self.quantity is not None: quant = self.quantity else: quant = '' # FIXME product fetch here is inefficient return '%s%s' % (Product.get(self.product_id).code.lower(), quant) def __repr__(self): return '{action} ({subaction}): {quantity} (loc: {location_id}, product: {product_id})'.format( action=self.action, subaction=self.subaction, quantity=self.quantity, location_id=self.location_id, product_id=self.product_id, )