コード例 #1
0
class XFormPhoneMetadata(jsonobject.JsonObject):
    """
    Metadata of an xform, from a meta block structured like:

        <Meta>
            <timeStart />
            <timeEnd />
            <instanceID />
            <userID />
            <deviceID />
            <username />

            <!-- CommCare extension -->
            <appVersion />
            <location />
        </Meta>

    See spec: https://bitbucket.org/javarosa/javarosa/wiki/OpenRosaMetaDataSchema

    username is not part of the spec but included for convenience
    """

    timeStart = jsonobject.DateTimeProperty()
    timeEnd = jsonobject.DateTimeProperty()
    instanceID = jsonobject.StringProperty()
    userID = jsonobject.StringProperty()
    deviceID = jsonobject.StringProperty()
    username = jsonobject.StringProperty()
    appVersion = jsonobject.StringProperty()
    location = GeoPointProperty()
コード例 #2
0
class TestFormMetadata(jsonobject.JsonObject):
    domain = jsonobject.StringProperty(required=False)
    xmlns = jsonobject.StringProperty(default='http://openrosa.org/formdesigner/form-processor')
    app_id = jsonobject.StringProperty(default='123')
    form_name = jsonobject.StringProperty(default='New Form')
    device_id = jsonobject.StringProperty(default='DEV IL')
    user_id = jsonobject.StringProperty(default='cruella_deville')
    username = jsonobject.StringProperty(default='eve')
    time_end = jsonobject.DateTimeProperty(default=datetime(2013, 4, 19, 16, 52, 2))
    time_start = jsonobject.DateTimeProperty(default=datetime(2013, 4, 19, 16, 53, 2))
    # Set this property to fake the submission time
    received_on = jsonobject.DateTimeProperty(default=datetime.utcnow)
コード例 #3
0
ファイル: interface.py プロジェクト: mekete/commcare-hq
class ChangeMeta(jsonobject.JsonObject):
    """
    Metadata about a change. If available, this will be set on Change.metadata.

    This is only used in kafka-based pillows.
    """
    _allow_dynamic_properties = False

    document_id = DefaultProperty(required=True)

    # Only relevant for Couch documents
    document_rev = jsonobject.StringProperty()

    # 'couch' or 'sql'
    data_source_type = jsonobject.StringProperty(required=True)

    # couch database name or one of data sources listed in corehq.apps.change_feed.data_sources
    data_source_name = jsonobject.StringProperty(required=True)

    # doc_type property of doc or else the topic name
    document_type = DefaultProperty()

    document_subtype = jsonobject.StringProperty()
    domain = jsonobject.StringProperty()
    is_deletion = jsonobject.BooleanProperty()
    publish_timestamp = jsonobject.DateTimeProperty(default=datetime.utcnow)

    # track of retry attempts
    attempts = jsonobject.IntegerProperty(default=0)
コード例 #4
0
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,
        )
コード例 #5
0
class StockReportHelper(jsonobject.JsonObject):
    """
    Intermediate class for dealing with stock XML
    """

    domain = jsonobject.StringProperty()
    form_id = jsonobject.StringProperty()
    timestamp = jsonobject.DateTimeProperty()
    tag = jsonobject.StringProperty()
    transactions = jsonobject.ListProperty(lambda: StockTransactionHelper)
    server_date = jsonobject.DateTimeProperty()
    deprecated = jsonobject.BooleanProperty()

    @property
    def report_type(self):
        # this is for callers to be able to use a less confusing name
        return self.tag

    @classmethod
    def make_from_form(cls, form, timestamp, tag, transactions):
        deprecated = form.is_deprecated
        return cls(
            domain=form.domain,
            form_id=form.form_id if not deprecated else form.orig_id,
            timestamp=timestamp,
            tag=tag,
            transactions=transactions,
            server_date=form.received_on,
            deprecated=deprecated,
        )

    def validate(self):
        """
        Validates this object as best we can and raises Exceptions if we find anything invalid .
        """
        if any(transaction_helper.product_id in ('', None)
               for transaction_helper in self.transactions):
            raise MissingProductId(
                _('Product IDs must be set for all ledger updates!'))
コード例 #6
0
ファイル: forms.py プロジェクト: soitun/commcare-hq
class XFormPhoneMetadata(jsonobject.JsonObject):
    """
    Metadata of an xform, from a meta block structured like:

        <Meta>
            <timeStart />
            <timeEnd />
            <instanceID />
            <userID />
            <deviceID />
            <username />

            <!-- CommCare extension -->
            <appVersion />
            <location />
        </Meta>

    See spec: https://bitbucket.org/javarosa/javarosa/wiki/OpenRosaMetaDataSchema

    username is not part of the spec but included for convenience
    """

    timeStart = jsonobject.DateTimeProperty()
    timeEnd = jsonobject.DateTimeProperty()
    instanceID = jsonobject.StringProperty()
    userID = jsonobject.StringProperty()
    deviceID = jsonobject.StringProperty()
    username = jsonobject.StringProperty()
    appVersion = jsonobject.StringProperty()
    location = GeoPointProperty()

    @property
    def commcare_version(self):
        from corehq.apps.receiverwrapper.util import get_commcare_version_from_appversion_text
        from distutils.version import LooseVersion
        version_text = get_commcare_version_from_appversion_text(self.appVersion)
        if version_text:
            return LooseVersion(version_text)
コード例 #7
0
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,
        )
コード例 #8
0
class ChangeMeta(jsonobject.JsonObject):
    """
    Metadata about a change. If available, this will be set on Change.metadata.

    This is only used in kafka-based pillows.
    """
    document_id = DefaultProperty(required=True)
    document_rev = jsonobject.StringProperty()  # Only relevant for Couch documents
    data_source_type = jsonobject.StringProperty(required=True)
    data_source_name = jsonobject.StringProperty(required=True)
    document_type = DefaultProperty()
    document_subtype = jsonobject.StringProperty()
    domain = jsonobject.StringProperty()
    is_deletion = jsonobject.BooleanProperty()
    publish_timestamp = jsonobject.DateTimeProperty(default=datetime.utcnow)
    _allow_dynamic_properties = False
コード例 #9
0
ファイル: helpers.py プロジェクト: ye-man/commcare-hq
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,
        )