class HttpTemplate(Template): _kind = 63 _use_rule_engine = False message_reciever = orm.SuperStringProperty('1', required=True, indexed=False) message_subject = orm.SuperStringProperty('2', required=True, indexed=False) message_body = orm.SuperTextProperty('3', required=True) def run(self, **kwargs): callbacks = [] template_values = {'entity': kwargs['caller_entity']} data = { 'action_id': 'send_http', 'action_model': '61', 'recipient': self.message_reciever, 'body': render_template(self.message_body, template_values), 'subject': render_template(self.message_subject, template_values), 'caller_entity': kwargs['caller_entity'].key.urlsafe() } callbacks.append(('send', data)) return callbacks
class MailTemplate(Template): _kind = 58 _use_rule_engine = False message_reciever = orm.SuperKeyProperty( '1', kind='60', required=True, indexed=False) # All users that have this role. message_subject = orm.SuperStringProperty('2', required=True, indexed=False) message_body = orm.SuperTextProperty('3', required=True) def run(self, **kwargs): callbacks = [] DomainUser = kwargs['models']['8'] domain_users = DomainUser.query( DomainUser.roles == self.message_reciever, namespace=self.message_reciever.namespace()).fetch() recievers = orm.get_multi_clean([ orm.Key('0', long(reciever.key.id())) for reciever in domain_users ]) template_values = {'entity': kwargs['caller_entity']} data = { 'action_id': 'send_mail', 'action_model': '61', 'recipient': [reciever._primary_email for reciever in recievers], 'body': render_template(self.message_body, template_values), 'subject': render_template(self.message_subject, template_values), 'caller_entity': kwargs['caller_entity'].key.urlsafe() } recipients_per_task = int( math.ceil(len(data['recipient']) / settings.RECIPIENTS_PER_TASK)) data_copy = data.copy() del data_copy['recipient'] for i in xrange(0, recipients_per_task + 1): recipients = data['recipient'][settings.RECIPIENTS_PER_TASK * i:settings.RECIPIENTS_PER_TASK * (i + 1)] if recipients: new_data = data_copy.copy() new_data['recipient'] = recipients callbacks.append(('send', new_data)) return callbacks
class CustomTemplate(Template): _kind = 59 _use_rule_engine = False message_recievers = orm.SuperPickleProperty('1', required=True, indexed=False) message_subject = orm.SuperStringProperty('2', required=True, indexed=False) message_body = orm.SuperTextProperty('3', required=True) outlet = orm.SuperStringProperty('4', required=True, default='send_mail', indexed=False) def run(self, **kwargs): callbacks = [] template_values = {'entity': kwargs['caller_entity']} data = { 'action_id': self.outlet, 'action_model': '61', 'recipient': self.message_recievers(kwargs['caller_entity'], kwargs['caller_user']), 'body': render_template(self.message_body, template_values), 'subject': render_template(self.message_subject, template_values), 'caller_entity': kwargs['caller_entity'].key.urlsafe() } callbacks.append(('send', data)) return callbacks
def run(self, context): if not isinstance(self.cfg, dict): self.cfg = {} documents = [] index_name = self.cfg.get('index', None) catalog_fields = { 'namespace_entity.name': orm.SuperStringProperty(search_document_field_name='seller_name'), 'namespace_entity.logo.value.serving_url': orm.SuperStringProperty(search_document_field_name='seller_logo'), 'cover.value.serving_url': orm.SuperStringProperty(search_document_field_name='cover') } # name='seller_feedback', value=context._catalog.namespace_entity.feedback product_fields = { 'parent_entity.name': orm.SuperStringProperty(search_document_field_name='catalog_name'), 'namespace_entity.name': orm.SuperStringProperty(search_document_field_name='seller_name'), 'namespace_entity.logo.value.serving_url': orm.SuperStringProperty(search_document_field_name='seller_logo'), '_product_category.value.parent_record': orm.SuperKeyProperty( kind='17', search_document_field_name='product_category_parent_record'), '_product_category.value.name': orm.SuperStringProperty( search_document_field_name='product_category_name'), '_product_category.value.complete_name': orm.SuperTextProperty( search_document_field_name='product_category_complete_name') } context._catalog._images.read({'config': {'cursor': -1}}) product_keys = [] for image in context._catalog._images.value: product_keys.extend([ pricetag.product._urlsafe for pricetag in image.pricetags.value ]) context._catalog._products.read({ '_product_category': {}, 'config': { 'keys': product_keys } }) products = context._catalog._products.value context._catalog._images = [] write_index = True if not len(products): # write_index = False @todo We shall not allow indexing of catalogs without products attached! pass for product in products: if product._product_category.value.state != 'indexable': write_index = False break results = None if write_index: documents.extend( [context._catalog.get_search_document(catalog_fields)]) documents.extend([ product.get_search_document(product_fields) for product in products ]) context._catalog._write_custom_indexes = {} context._catalog._write_custom_indexes[index_name] = documents context._catalog._products = []
class Notification(orm.BaseExpando): _kind = 61 name = orm.SuperStringProperty('1', required=True) action = orm.SuperKeyProperty('2', kind='56', required=True) condition = orm.SuperStringProperty('3', required=True, indexed=False) active = orm.SuperBooleanProperty('4', required=True, default=True) templates = orm.SuperPickleProperty('5', required=True, indexed=False, compressed=False) _default_indexed = False _virtual_fields = {'_records': orm.SuperRecordProperty('61')} _global_role = GlobalRole(permissions=[ orm.ActionPermission( '61', [ orm.Action.build_key('61', 'prepare'), orm.Action.build_key('61', 'create'), orm.Action.build_key('61', 'read'), orm.Action.build_key('61', 'update'), orm.Action.build_key('61', 'delete'), orm.Action.build_key('61', 'search') ], False, 'entity._original.namespace_entity._original.state != "active"'), orm.ActionPermission('61', [ orm.Action.build_key('61', 'initiate'), orm.Action.build_key('61', 'send_mail'), orm.Action.build_key('61', 'send_http') ], False, 'True'), orm.ActionPermission( '61', [ orm.Action.build_key('61', 'initiate'), orm.Action.build_key('61', 'send_mail'), orm.Action.build_key('61', 'send_http') ], True, 'entity._original.namespace_entity._original.state == "active" and user._is_taskqueue' ), orm.FieldPermission( '61', ['name', 'action', 'condition', 'active', 'templates', '_records'], False, False, 'entity._original.namespace_entity._original.state != "active"') ]) _actions = [ orm.Action(key=orm.Action.build_key('61', 'prepare'), arguments={ 'domain': orm.SuperKeyProperty(kind='6', required=True) }, _plugin_groups=[ orm.PluginGroup(plugins=[ Context(), Read(), RulePrepare(), RuleExec(), Set(cfg={'d': { 'output.entity': '_notification' }}) ]) ]), orm.Action( key=orm.Action.build_key('61', 'create'), arguments={ 'domain': orm.SuperKeyProperty(kind='6', required=True), 'name': orm.SuperStringProperty(required=True), 'action': orm.SuperVirtualKeyProperty(required=True, kind='56'), 'condition': orm.SuperTextProperty(required=True), 'active': orm.SuperBooleanProperty(), 'templates': orm.SuperMultiLocalStructuredProperty(('58', '63'), repeated=True) }, _plugin_groups=[ orm.PluginGroup(plugins=[ Context(), Read(), Set( cfg={ 'd': { '_notification.name': 'input.name', '_notification.action': 'input.action', '_notification.condition': 'input.condition', '_notification.active': 'input.active', '_notification.templates': 'input.templates' } }), RulePrepare(), RuleExec() ]), orm.PluginGroup( transactional=True, plugins=[ Write(), Set(cfg={'d': { 'output.entity': '_notification' }}), CallbackNotify(), CallbackExec() ]) ]), orm.Action(key=orm.Action.build_key('61', 'read'), arguments={ 'key': orm.SuperKeyProperty(kind='61', required=True), 'read_arguments': orm.SuperJsonProperty() }, _plugin_groups=[ orm.PluginGroup(plugins=[ Context(), Read(), RulePrepare(), RuleExec(), Set(cfg={'d': { 'output.entity': '_notification' }}) ]) ]), orm.Action( key=orm.Action.build_key('61', 'update'), arguments={ 'key': orm.SuperKeyProperty(required=True, kind='61'), 'name': orm.SuperStringProperty(required=True), 'action': orm.SuperVirtualKeyProperty(required=True, kind='56'), 'condition': orm.SuperTextProperty(required=True), 'active': orm.SuperBooleanProperty(), 'templates': orm.SuperMultiLocalStructuredProperty(('58', '63'), repeated=True), 'read_arguments': orm.SuperJsonProperty() }, _plugin_groups=[ orm.PluginGroup(plugins=[ Context(), Read(), Set( cfg={ 'd': { '_notification.name': 'input.name', '_notification.action': 'input.action', '_notification.condition': 'input.condition', '_notification.active': 'input.active', '_notification.templates': 'input.templates' } }), RulePrepare(), RuleExec() ]), orm.PluginGroup( transactional=True, plugins=[ Write(), Set(cfg={'d': { 'output.entity': '_notification' }}), CallbackNotify(), CallbackExec() ]) ]), orm.Action( key=orm.Action.build_key('61', 'delete'), arguments={'key': orm.SuperKeyProperty(required=True, kind='61')}, _plugin_groups=[ orm.PluginGroup( plugins=[Context( ), Read(), RulePrepare(), RuleExec()]), orm.PluginGroup( transactional=True, plugins=[ Delete(), Set(cfg={'d': { 'output.entity': '_notification' }}), CallbackNotify(), CallbackExec() ]) ]), orm.Action(key=orm.Action.build_key('61', 'search'), arguments={ 'domain': orm.SuperKeyProperty(kind='6', required=True), 'search': orm.SuperSearchProperty( default={ 'filters': [], 'orders': [{ 'field': 'name', 'operator': 'asc' }] }, cfg={ 'search_arguments': { 'kind': '61', 'options': { 'limit': settings.SEARCH_PAGE } }, 'filters': { 'name': orm.SuperStringProperty(), 'action': orm.SuperVirtualKeyProperty(kind='56'), 'active': orm.SuperBooleanProperty() }, 'indexes': [{ 'orders': [('name', ['asc', 'desc'])] }, { 'filters': [('name', ['==', '!='])], 'orders': [('name', ['asc', 'desc'])] }, { 'filters': [('action', ['==', '!='])], 'orders': [('name', ['asc', 'desc'])] }, { 'filters': [('active', ['=='])], 'orders': [('name', ['asc', 'desc'])] }, { 'filters': [('active', ['==']), ('name', ['==', '!='])], 'orders': [('name', ['asc', 'desc'])] }, { 'filters': [('active', ['==']), ('action', ['==', '!='])], 'orders': [('name', ['asc', 'desc'])] }, { 'filters': [('active', ['==']), ('name', ['==', '!=']), ('action', ['==', '!='])], 'orders': [('name', ['asc', 'desc'])] }] }) }, _plugin_groups=[ orm.PluginGroup(plugins=[ Context(), Read(), RulePrepare(), RuleExec(), Search(), RulePrepare(cfg={'path': '_entities'}), Set( cfg={ 'd': { 'output.entities': '_entities', 'output.cursor': '_cursor', 'output.more': '_more' } }) ]) ]), orm.Action( key=orm.Action.build_key('61', 'initiate'), arguments={ 'caller_entity': orm.SuperKeyProperty(required=True), 'caller_user': orm.SuperKeyProperty(required=True, kind='0'), 'caller_action': orm.SuperVirtualKeyProperty(required=True) }, _plugin_groups=[ orm.PluginGroup(plugins=[ Context(), Set(cfg={ 'd': { '_caller_entity': 'input.caller_entity.entity' } }), Read(cfg={'namespace': '_caller_entity.key_namespace'}), RulePrepare(), RuleExec(), NotificationInitiate(), CallbackExec() ]) ]), orm.Action( key=orm.Action.build_key('61', 'send_mail'), arguments={ 'recipient': orm.SuperStringProperty(repeated=True), 'subject': orm.SuperTextProperty(required=True), 'body': orm.SuperTextProperty(required=True), 'caller_entity': orm.SuperKeyProperty(required=True) }, _plugin_groups=[ orm.PluginGroup(plugins=[ Context(), Set(cfg={ 'd': { '_caller_entity': 'input.caller_entity.entity' } }), Read(cfg={'namespace': '_caller_entity.key_namespace'}), RulePrepare(), RuleExec(), NotificationMailSend(cfg={'sender': settings.NOTIFY_EMAIL}) ]) ]), orm.Action( key=orm.Action.build_key('61', 'send_http'), arguments={ 'recipient': orm.SuperStringProperty(required=True), 'subject': orm.SuperTextProperty(required=True), 'body': orm.SuperTextProperty(required=True), 'caller_entity': orm.SuperKeyProperty(required=True) }, _plugin_groups=[ orm.PluginGroup(plugins=[ Context(), Set(cfg={ 'd': { '_caller_entity': 'input.caller_entity.entity' } }), Read(cfg={'namespace': '_caller_entity.key_namespace'}), RulePrepare(), RuleExec(), NotificationHttpSend() ]) ]) ]
class Journal(orm.BaseExpando): _kind = 49 created = orm.SuperDateTimeProperty('1', required=True, auto_now_add=True) updated = orm.SuperDateTimeProperty('2', required=True, auto_now=True) name = orm.SuperStringProperty('3', required=True) state = orm.SuperStringProperty('4', required=True, default='draft', choices=['draft', 'active', 'decommissioned']) entry_fields = orm.SuperPickleProperty('5', required=True, indexed=False, compressed=False) line_fields = orm.SuperPickleProperty('6', required=True, indexed=False, compressed=False) _default_indexed = False _virtual_fields = { '_records': orm.SuperRecordProperty('49'), '_code': orm.SuperComputedProperty(lambda self: self.key_id_str), '_transaction_actions': orm.SuperRemoteStructuredProperty(Action, repeated=True), '_transaction_plugin_groups': orm.SuperRemoteStructuredProperty(PluginGroup, repeated=True) } _global_role = GlobalRole( permissions=[ orm.ActionPermission('49', [orm.Action.build_key('49', 'prepare'), orm.Action.build_key('49', 'create'), orm.Action.build_key('49', 'read'), orm.Action.build_key('49', 'update'), orm.Action.build_key('49', 'delete'), orm.Action.build_key('49', 'search'), orm.Action.build_key('49', 'activate'), orm.Action.build_key('49', 'decommission')], False, 'entity._original.namespace_entity._original.state != "active"'), orm.ActionPermission('49', [orm.Action.build_key('49', 'delete')], False, 'entity._original.state != "draft"'), orm.ActionPermission('49', [orm.Action.build_key('49', 'activate')], False, 'entity._original.state == "active"'), orm.ActionPermission('49', [orm.Action.build_key('49', 'decommission')], False, 'entity._is_system or entity._original.state != "active"'), orm.FieldPermission('49', ['created', 'updated', 'state'], False, None, 'True'), orm.FieldPermission('49', ['created', 'updated', 'name', 'state', 'entry_fields', 'line_fields', '_records', '_code', '_transaction_actions', '_transaction_plugin_groups'], False, False, 'entity._original.namespace_entity._original.state != "active"'), orm.FieldPermission('49', ['created', 'updated', 'name', 'state', 'entry_fields', 'line_fields', '_records', '_code'], False, None, 'entity._original.state != "draft"'), orm.FieldPermission('49', ['_transaction_actions', '_transaction_plugin_groups.name', '_transaction_plugin_groups.subscriptions', '_transaction_plugin_groups.active', '_transaction_plugin_groups.sequence', '_transaction_plugin_groups.transactional'], False, None, 'entity._is_system'), orm.FieldPermission('49', ['_transaction_plugin_groups.plugins'], False, None, 'entity._is_system and entity._original._transaction_plugin_groups.name != "User Plugins"'), # @todo Missing index between _transaction_plugin_groups and name! orm.FieldPermission('49', ['state'], True, None, '(action.key_id_str == "activate" and entity.state == "active") or (action.key_id_str == "decommission" and entity.state == "decommissioned")') ] ) _actions = [ orm.Action( key=orm.Action.build_key('49', 'prepare'), arguments={ 'domain': orm.SuperKeyProperty(kind='6', required=True) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(), RuleExec(), Set(cfg={'d': {'output.entity': '_journal'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('49', 'create'), arguments={ 'domain': orm.SuperKeyProperty(kind='6', required=True), '_code': orm.SuperStringProperty(required=True, max_size=64), # Regarding max_size, take a look at the transaction.JournalUpdateRead() plugin! 'name': orm.SuperStringProperty(required=True), 'entry_fields': orm.SuperPropertyStorageProperty(required=True, cfg=JOURNAL_FIELDS), 'line_fields': orm.SuperPropertyStorageProperty(required=True, cfg=JOURNAL_FIELDS) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), Set(cfg={'s': {'_journal.state': 'draft'}, 'd': {'_journal.name': 'input.name', '_journal.entry_fields': 'input.entry_fields', '_journal.line_fields': 'input.line_fields'}}), RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(), Set(cfg={'d': {'output.entity': '_journal'}}), CallbackNotify(), CallbackExec() ] ) ] ), orm.Action( key=orm.Action.build_key('49', 'read'), arguments={ 'key': orm.SuperKeyProperty(kind='49', required=True), 'read_arguments': orm.SuperJsonProperty() }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(), RuleExec(), Set(cfg={'d': {'output.entity': '_journal'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('49', 'update'), arguments={ 'key': orm.SuperKeyProperty(kind='49', required=True), 'name': orm.SuperStringProperty(required=True), 'entry_fields': orm.SuperPropertyStorageProperty(required=True, cfg=JOURNAL_FIELDS), 'line_fields': orm.SuperPropertyStorageProperty(required=True, cfg=JOURNAL_FIELDS), '_transaction_actions': orm.SuperLocalStructuredProperty(Action, repeated=True), '_transaction_plugin_groups': orm.SuperLocalStructuredProperty(PluginGroup, repeated=True) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), Set(cfg={'d': {'_journal.name': 'input.name', '_journal.entry_fields': 'input.entry_fields', '_journal.line_fields': 'input.line_fields', '_journal._transaction_actions': 'input._transaction_actions', '_journal._transaction_plugin_groups': 'input._transaction_plugin_groups'}}), RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(), Set(cfg={'d': {'output.entity': '_journal'}}), CallbackNotify(), CallbackExec() ] ) ] ), orm.Action( key=orm.Action.build_key('49', 'delete'), arguments={ 'key': orm.SuperKeyProperty(kind='49', required=True) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Delete(), Set(cfg={'d': {'output.entity': '_journal'}}), CallbackNotify(), CallbackExec() ] ) ] ), orm.Action( key=orm.Action.build_key('49', 'search'), arguments={ 'domain': orm.SuperKeyProperty(kind='6', required=True), 'search': orm.SuperSearchProperty( default={'filters': [], 'orders': [{'field': 'name', 'operator': 'asc'}]}, cfg={ 'search_arguments': {'kind': '49', 'options': {'limit': settings.SEARCH_PAGE}}, 'filters': {'name': orm.SuperStringProperty(), 'state': orm.SuperStringProperty(choices=[])}, 'indexes': [{'orders': [('name', ['asc', 'desc'])]}, {'orders': [('state', ['asc', 'desc'])]}, {'filters': [('name', ['==', '!='])], 'orders': [('name', ['asc', 'desc'])]}, {'filters': [('state', ['==', '!='])], 'orders': [('name', ['asc', 'desc'])]}, {'filters': [('state', ['==', '!=']), ('name', ['==', '!='])], 'orders': [('name', ['asc', 'desc'])]}] } ) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(), RuleExec(), Search(), RulePrepare(cfg={'path': '_entities'}), Set(cfg={'d': {'output.entities': '_entities', 'output.cursor': '_cursor', 'output.more': '_more'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('49', 'activate'), arguments={ 'key': orm.SuperKeyProperty(kind='49', required=True), 'message': orm.SuperTextProperty(required=True) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), Set(cfg={'s': {'_journal.state': 'active'}}), RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(cfg={'dra': {'message': 'input.message'}}), CallbackNotify(), CallbackExec() ] ), orm.PluginGroup( plugins=[ RulePrepare(), Set(cfg={'d': {'output.entity': '_journal'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('49', 'decommission'), arguments={ 'key': orm.SuperKeyProperty(kind='49', required=True), 'message': orm.SuperTextProperty(required=True) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), Set(cfg={'s': {'_journal.state': 'decommissioned'}}), RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(cfg={'dra': {'message': 'input.message'}}), CallbackNotify(), CallbackExec() ] ), orm.PluginGroup( plugins=[ RulePrepare(), Set(cfg={'d': {'output.entity': '_journal'}}) ] ) ] ) ] @classmethod def prepare_key(cls, input, **kwargs): code = input.get('_code') return cls.build_key(code, namespace=kwargs.get('namespace')) # @todo Possible prefix? @property def _is_system(self): return self.key_id_str.startswith('system_')
class Category(orm.BaseExpando): _kind = 47 created = orm.SuperDateTimeProperty('1', required=True, auto_now_add=True) updated = orm.SuperDateTimeProperty('2', required=True, auto_now=True) parent_record = orm.SuperKeyProperty('3', kind='47') name = orm.SuperStringProperty('4', required=True) complete_name = orm.SuperTextProperty('5', required=True) active = orm.SuperBooleanProperty('6', required=True, default=True) _default_indexed = False ###################################################### # Primitive example of real time balance calculator! # ###################################################### @classmethod def _get_children(cls, parent_records, children): entities = [] for parent_record in parent_records: entities.extend(cls.query(cls.parent_record == parent_record).fetch(keys_only=True)) if len(entities): children.extend(entities) cls._get_children(entities, children) @classmethod def _get_balance(cls, category): debit = 0 credit = 0 lines = Line.query(Line.categories.IN(category._children_records)).fetch() for line in lines: debit += line.debit credit += line.credit return (debit, credit, (debit - credit)) @classmethod def _post_get_hook(cls, key, future): # @todo Missing super extension! entity = future.get_result() if entity is not None and entity.key: entity._children_records = [entity.key] entity._get_children([entity.key], entity._children_records) entity._debit, entity._credit, entity._balance = entity._get_balance(entity) ################### # End of example! # ################### _expando_fields = { 'description': orm.SuperTextProperty('7'), 'balances': orm.SuperLocalStructuredProperty(CategoryBalance, '8', repeated=True) } _virtual_fields = { '_records': orm.SuperRecordProperty('47'), '_code': orm.SuperComputedProperty(lambda self: self.key_id_str) #'_debit': orm.SuperComputedProperty(lambda self: self._debit), #'_credit': orm.SuperComputedProperty(lambda self: self._credit), #'_balance': orm.SuperComputedProperty(lambda self: self._balance), } _global_role = GlobalRole( permissions=[ orm.ActionPermission('47', [orm.Action.build_key('47', 'prepare'), orm.Action.build_key('47', 'create'), orm.Action.build_key('47', 'read'), orm.Action.build_key('47', 'update'), orm.Action.build_key('47', 'delete'), orm.Action.build_key('47', 'search')], False, 'entity._original.namespace_entity._original.state != "active"'), orm.ActionPermission('47', [orm.Action.build_key('47', 'create'), orm.Action.build_key('47', 'update'), orm.Action.build_key('47', 'delete')], False, 'entity._is_system'), orm.ActionPermission('47', [orm.Action.build_key('47', 'delete')], False, 'entity._is_used'), orm.FieldPermission('47', ['created', 'updated'], False, None, 'True'), orm.FieldPermission('47', ['created', 'updated', 'parent_record', 'name', 'complete_name', 'active', 'description', 'balances', '_records', '_code'], False, False, 'entity._original.namespace_entity._original.state != "active"'), orm.FieldPermission('47', ['created', 'updated', 'parent_record', 'name', 'complete_name', 'active', 'description', 'balances', '_records', '_code'], False, None, 'entity._is_system') ] ) _actions = [ orm.Action( key=orm.Action.build_key('47', 'prepare'), arguments={ 'domain': orm.SuperKeyProperty(kind='6', required=True) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(), RuleExec(), Set(cfg={'d': {'output.entity': '_category'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('47', 'create'), arguments={ 'domain': orm.SuperKeyProperty(kind='6', required=True), '_code': orm.SuperStringProperty(required=True, max_size=64), # Regarding max_size, take a look at the transaction.CategoryUpdateRead() plugin! 'parent_record': orm.SuperKeyProperty(kind='47'), 'name': orm.SuperStringProperty(required=True), 'active': orm.SuperBooleanProperty(required=True, default=True), 'description': orm.SuperTextProperty() }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), CategoryUpdateSet(), # @todo Unless we decide to implement that complete_name handling property, this will stay. RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(), Set(cfg={'d': {'output.entity': '_category'}}), CallbackNotify(), CallbackExec() ] ) ] ), orm.Action( key=orm.Action.build_key('47', 'read'), arguments={ 'key': orm.SuperKeyProperty(kind='47', required=True), 'read_arguments': orm.SuperJsonProperty() }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(), RuleExec(), Set(cfg={'d': {'output.entity': '_category'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('47', 'update'), arguments={ 'key': orm.SuperKeyProperty(kind='47', required=True), 'parent_record': orm.SuperKeyProperty(kind='47'), 'name': orm.SuperStringProperty(required=True), 'active': orm.SuperBooleanProperty(required=True, default=True), 'description': orm.SuperTextProperty() }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), CategoryUpdateSet(), # @todo Unless we decide to implement that complete_name handling property, this will stay. RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(), Set(cfg={'d': {'output.entity': '_category'}}), CallbackNotify(), CallbackExec() ] ) ] ), orm.Action( key=orm.Action.build_key('47', 'delete'), arguments={ 'key': orm.SuperKeyProperty(kind='47', required=True) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Delete(), Set(cfg={'d': {'output.entity': '_category'}}), CallbackNotify(), CallbackExec() ] ) ] ), orm.Action( key=orm.Action.build_key('47', 'search'), arguments={ 'domain': orm.SuperKeyProperty(kind='6', required=True), 'search': orm.SuperSearchProperty( default={'filters': [{'field': 'active', 'value': True, 'operator': '=='}], 'orders': [{'field': 'name', 'operator': 'asc'}]}, cfg={ 'search_by_keys': True, 'search_arguments': {'kind': '47', 'options': {'limit': settings.SEARCH_PAGE}}, 'filters': {'name': orm.SuperStringProperty(), 'active': orm.SuperBooleanProperty()}, 'indexes': [{'orders': [('name', ['asc', 'desc'])]}, {'orders': [('created', ['asc', 'desc'])]}, {'orders': [('updated', ['asc', 'desc'])]}, {'orders': [('active', ['asc', 'desc'])]}, {'filters': [('name', ['==', '!='])], 'orders': [('name', ['asc', 'desc'])]}, {'filters': [('active', ['=='])], 'orders': [('name', ['asc', 'desc'])]}, {'filters': [('active', ['==']), ('name', ['==', '!='])], 'orders': [('name', ['asc', 'desc'])]}] } ) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(), RuleExec(), Search(), RulePrepare(cfg={'path': '_entities'}), Set(cfg={'d': {'output.entities': '_entities', 'output.cursor': '_cursor', 'output.more': '_more'}}) ] ) ] ) ] @classmethod def prepare_key(cls, input, **kwargs): code = input.get('_code') return cls.build_key(code, namespace=kwargs.get('namespace')) # @todo Possible prefix? @property def _is_system(self): return self.key_id_str.startswith('system_') @property def _is_used(self): if self.key.id() is None: return False category = self.query(self.__class__.parent_record == self.key).get() line = Line.query(Line.categories == self.key).get() return (category is not None) or (line is not None)
@authors: Edis Sehalic ([email protected]), Elvin Kosova ([email protected]) ''' from google.appengine.ext.ndb.google_imports import entity_pb from app import orm, settings from app.models import uom from app.models.base import * from app.plugins.base import * from app.plugins.transaction import * defaults1 = () defaults2 = ('required',) JOURNAL_FIELDS = ((orm.SuperStringProperty(), defaults1, defaults2), (orm.SuperTextProperty(), defaults1, defaults2), (orm.SuperIntegerProperty(), defaults1, defaults2), (orm.SuperFloatProperty(), defaults1, defaults2), (orm.SuperDecimalProperty(), defaults1, defaults2), (orm.SuperBooleanProperty(), defaults1, defaults2), (orm.SuperJsonProperty(), defaults1, defaults2), (orm.SuperKeyProperty(), defaults1, defaults2), (orm.SuperDateTimeProperty(), defaults1, defaults2)) class Action(orm.Action): _kind = 84 _use_rule_engine = False arguments = orm.SuperPropertyStorageProperty('2', required=True, default={}, compressed=False, cfg=JOURNAL_FIELDS) @classmethod
class Domain(orm.BaseExpando): _kind = 6 _use_memcache = True created = orm.SuperDateTimeProperty('1', required=True, auto_now_add=True) updated = orm.SuperDateTimeProperty('2', required=True, auto_now=True) name = orm.SuperStringProperty('3', required=True) primary_contact = orm.SuperKeyProperty('4', kind='8', indexed=False) # This field is required, and is handeled in update action via argument! state = orm.SuperStringProperty('5', required=True, choices=['active', 'suspended', 'su_suspended']) logo = SuperImageLocalStructuredProperty(Image, '6', required=True) _default_indexed = False _virtual_fields = { '_primary_contact_email': orm.SuperReferenceProperty(target_field='primary_contact', format_callback=lambda self, value: value._primary_email), '_records': orm.SuperRecordProperty('6') } _global_role = GlobalRole( permissions=[ orm.ActionPermission('6', [orm.Action.build_key('6', 'prepare'), orm.Action.build_key('6', 'create')], True, 'not user._is_guest'), orm.ActionPermission('6', orm.Action.build_key('6', 'update'), False, 'entity._original.state != "active"'), orm.ActionPermission('6', orm.Action.build_key('6', 'suspend'), False, 'entity._original.state != "active"'), orm.ActionPermission('6', orm.Action.build_key('6', 'activate'), False, 'entity._original.state == "active" or entity._original.state == "su_suspended"'), orm.FieldPermission('6', ['created', 'updated', 'state'], False, None, 'True'), orm.FieldPermission('6', ['name', 'primary_contact', 'logo', '_records', '_primary_contact_email'], False, None, 'entity._original.state != "active"'), orm.FieldPermission('6', ['state'], True, None, '(action.key_id_str == "activate" and entity.state == "active") or (action.key_id_str == "suspend" and entity.state == "suspended")'), # Domain is unit of administration, hence root admins need control over it! # Root admins can always: read domain; search for domains (exclusively); # read domain history; perform sudo operations (exclusively); log messages; read _records.note field (exclusively). orm.ActionPermission('6', [orm.Action.build_key('6', 'read'), orm.Action.build_key('6', 'search'), orm.Action.build_key('6', 'sudo'), orm.Action.build_key('6', 'log_message')], True, 'user._root_admin'), orm.ActionPermission('6', [orm.Action.build_key('6', 'search'), orm.Action.build_key('6', 'sudo')], False, 'not user._root_admin'), orm.FieldPermission('6', ['created', 'updated', 'name', 'primary_contact', 'state', 'logo', '_records', '_primary_contact_email'], None, True, 'user._root_admin'), orm.FieldPermission('6', ['_records.note'], True, True, 'user._root_admin'), orm.FieldPermission('6', ['_records.note'], False, False, 'not user._root_admin'), orm.FieldPermission('6', ['state'], True, None, '(action.key_id_str == "sudo") and user._root_admin and (entity.state == "active" or entity.state == "su_suspended")'), orm.FieldPermission('6', ['created', 'updated', 'name', 'state', 'logo'], None, True, 'entity._original.state == "active"') ] ) _actions = [ orm.Action( key=orm.Action.build_key('6', 'prepare'), arguments={ 'upload_url': orm.SuperStringProperty() }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(cfg={'skip_user_roles': True}), RuleExec(), BlobURL(cfg={'bucket': settings.BUCKET_PATH}), Set(cfg={'d': {'output.entity': '_domain', 'output.upload_url': '_blob_url'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('6', 'create'), arguments={ 'name': orm.SuperStringProperty(required=True), 'logo': SuperImageLocalStructuredProperty(Image, required=True, process_config={'measure': False, 'transform': True, 'width': 240, 'height': 100, 'crop_to_fit': True}) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(cfg={'skip_user_roles': True}), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ DomainCreateWrite(), Set(cfg={'d': {'output.entity': '_domain'}}), CallbackExec(cfg=[('callback', {'action_id': 'install', 'action_model': '57'}, {'key': '_config.key_urlsafe'})]) ] ) ] ), orm.Action( key=orm.Action.build_key('6', 'read'), arguments={ 'key': orm.SuperKeyProperty(kind='6', required=True), 'read_arguments': orm.SuperJsonProperty() }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(), RuleExec(), Set(cfg={'d': {'output.entity': '_domain'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('6', 'update'), arguments={ 'key': orm.SuperKeyProperty(kind='6', required=True), 'name': orm.SuperStringProperty(required=True), 'primary_contact': orm.SuperKeyProperty(required=True, kind='8', validator=primary_contact_validator), 'logo': SuperImageLocalStructuredProperty(Image, process_config={'measure': False, 'transform': True, 'width': 240, 'height': 100, 'crop_to_fit': True}), 'read_arguments': orm.SuperJsonProperty() }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), Set(cfg={'d': {'_domain.name': 'input.name', '_domain.primary_contact': 'input.primary_contact', '_domain.logo': 'input.logo'}}), RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(), Set(cfg={'d': {'output.entity': '_domain'}}), CallbackNotify(), CallbackExec() ] ) ] ), orm.Action( key=orm.Action.build_key('6', 'search'), arguments={ 'search': orm.SuperSearchProperty( default={'filters': [], 'orders': [{'field': 'created', 'operator': 'desc'}]}, cfg={ 'search_arguments': {'kind': '6', 'options': {'limit': settings.SEARCH_PAGE}}, 'filters': {'name': orm.SuperStringProperty(), 'state': orm.SuperStringProperty()}, 'indexes': [{'orders': [('name', ['asc', 'desc'])]}, {'orders': [('created', ['asc', 'desc'])]}, {'orders': [('updated', ['asc', 'desc'])]}, {'filters': [('name', ['==', '!='])], 'orders': [('created', ['asc', 'desc'])]}, {'filters': [('state', ['==', '!='])], 'orders': [('created', ['asc', 'desc'])]}] } ) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(cfg={'skip_user_roles': True}), RuleExec(), Search(), RulePrepare(cfg={'path': '_entities', 'skip_user_roles': True}), Set(cfg={'d': {'output.entities': '_entities', 'output.cursor': '_cursor', 'output.more': '_more'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('6', 'suspend'), arguments={ 'key': orm.SuperKeyProperty(kind='6', required=True), 'message': orm.SuperTextProperty(required=True) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), Set(cfg={'s': {'_domain.state': 'suspended'}}), RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(cfg={'dra': {'message': 'input.message'}}), CallbackNotify(), CallbackExec() ] ), orm.PluginGroup( plugins=[ RulePrepare(), Set(cfg={'d': {'output.entity': '_domain'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('6', 'activate'), arguments={ 'key': orm.SuperKeyProperty(kind='6', required=True), 'message': orm.SuperTextProperty(required=True) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), Set(cfg={'s': {'_domain.state': 'active'}}), RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(cfg={'dra': {'message': 'input.message'}}), CallbackNotify(), CallbackExec() ] ), orm.PluginGroup( plugins=[ RulePrepare(), Set(cfg={'d': {'output.entity': '_domain'}}) ] ) ] ), orm.Action( key=orm.Action.build_key('6', 'sudo'), arguments={ 'key': orm.SuperKeyProperty(kind='6', required=True), 'state': orm.SuperStringProperty(required=True, choices=['active', 'suspended', 'su_suspended']), 'message': orm.SuperTextProperty(required=True), 'note': orm.SuperTextProperty() }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), Set(cfg={'d': {'_domain.state': 'input.state'}}), RulePrepare(cfg={'skip_user_roles': True}), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(cfg={'dra': {'message': 'input.message', 'note': 'input.note'}}), RulePrepare(cfg={'skip_user_roles': True}), Set(cfg={'d': {'output.entity': '_domain'}}), CallbackNotify(), CallbackExec() ] ) ] ), orm.Action( key=orm.Action.build_key('6', 'log_message'), arguments={ 'key': orm.SuperKeyProperty(kind='6', required=True), 'message': orm.SuperTextProperty(required=True), 'note': orm.SuperTextProperty() }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(), RuleExec() ] ), orm.PluginGroup( transactional=True, plugins=[ Write(cfg={'dra': {'message': 'input.message', 'note': 'input.note'}}), Set(cfg={'d': {'output.entity': '_domain'}}), CallbackNotify(), CallbackExec() ] ) ] ) ] @property def key_namespace(self): return self.key.urlsafe() @property def namespace_entity(self): return self
class CountrySubdivision(orm.BaseModel): _kind = 16 _use_record_engine = False _use_cache = True _use_memcache = True parent_record = orm.SuperKeyProperty('1', kind='16', indexed=False) code = orm.SuperStringProperty('2', required=True, indexed=False) name = orm.SuperStringProperty('3', required=True) complete_name = orm.SuperTextProperty('4', required=True) type = orm.SuperStringProperty('5', required=True, indexed=False) active = orm.SuperBooleanProperty('6', required=True, default=True) _global_role = GlobalRole( permissions=[ orm.ActionPermission('16', [orm.Action.build_key('16', 'search')], True, 'not user._is_guest'), orm.FieldPermission('16', ['parent_record', 'code', 'name', 'complete_name', 'type', 'active'], False, True, 'True'), orm.FieldPermission('16', ['parent_record', 'code', 'name', 'complete_name', 'type', 'active'], True, True, 'user._root_admin or user._is_taskqueue') ] ) _actions = [ orm.Action( key=orm.Action.build_key('16', 'search'), arguments={ 'search': orm.SuperSearchProperty( default={'filters': [{'field': 'active', 'value': True, 'operator': '=='}], 'orders': [{'field': 'name', 'operator': 'asc'}]}, cfg={ 'ancestor_kind': '15', 'search_by_keys': True, 'search_arguments': {'kind': '16', 'options': {'limit': settings.SEARCH_PAGE}}, 'filters': {'name': orm.SuperStringProperty(value_filters=[lambda p, s: s.capitalize()]), 'active': orm.SuperBooleanProperty(choices=[True])}, 'indexes': [{'filters': [('active', ['=='])], 'orders': [('name', ['asc', 'desc'])]}, {'ancestor': True, 'filters': [('active', ['=='])], 'orders': [('name', ['asc', 'desc'])]}, {'filters': [('active', ['==']), ('name', ['==', '!=', 'contains'])], 'orders': [('name', ['asc', 'desc'])]}, {'ancestor': True, 'filters': [('active', ['==']), ('name', ['==', '!=', 'contains'])], 'orders': [('name', ['asc', 'desc'])]}] } ) }, _plugin_groups=[ orm.PluginGroup( plugins=[ Context(), Read(), RulePrepare(cfg={'skip_user_roles': True}), RuleExec(), Search(), RulePrepare(cfg={'path': '_entities', 'skip_user_roles': True}), Set(cfg={'d': {'output.entities': '_entities', 'output.cursor': '_cursor', 'output.more': '_more'}}) ] ) ] ) ]
def execute_create_order_journal(self): config_input = self.config.next_operation_input domain_key = config_input.get('domain_key') namespace = domain_key.urlsafe() models = self.context.models Journal = models['49'] Action = models['84'] PluginGroup = models['85'] CartInit = models['99'] PayPalPayment = models['108'] LinesInit = models['100'] AddressRule = models['107'] ProductToLine = models['101'] ProductSubtotalCalculate = models['104'] TaxSubtotalCalculate = models['110'] OrderTotalCalculate = models['105'] RulePrepare = models['93'] TransactionWrite = models['114'] CallbackNotify = models['115'] CallbackExec = models['97'] Unit = models['19'] entity = Journal(namespace=namespace, id='system_sales_order') entity.name = 'Sales Order Journal' entity.state = 'active' # this two need to be ordered Dictionaries because using unordered dict will cause # weird behaviour on user interface (e.g. on each refresh different order of properties entity.entry_fields = { 'company_address': orm.SuperLocalStructuredProperty('68', '7', required=True), 'party': orm.SuperKeyProperty('8', kind='0', required=True, indexed=False), # @todo buyer_reference ?? 'billing_address_reference': orm.SuperKeyProperty('9', kind='9', required=True, indexed=False), 'shipping_address_reference': orm.SuperKeyProperty('10', kind='9', required=True, indexed=False), 'billing_address': orm.SuperLocalStructuredProperty('68', '11', required=True), 'shipping_address': orm.SuperLocalStructuredProperty('68', '12', required=True), 'currency': orm.SuperLocalStructuredProperty('19', '13', required=True), 'untaxed_amount': orm.SuperDecimalProperty('14', required=True, indexed=False), 'tax_amount': orm.SuperDecimalProperty('15', required=True, indexed=False), 'total_amount': orm.SuperDecimalProperty('16', required=True, indexed=False), 'paypal_reciever_email': orm.SuperStringProperty('17', required=True, indexed=False), 'paypal_business': orm.SuperStringProperty('18', required=True, indexed=False) } entity.line_fields = { 'description': orm.SuperTextProperty('6', required=True), 'product_reference': orm.SuperKeyProperty('7', kind='38', required=True, indexed=False), 'product_variant_signature': orm.SuperJsonProperty('8', required=True), 'product_category_complete_name': orm.SuperTextProperty('9', required=True), 'product_category_reference': orm.SuperKeyProperty('10', kind='17', required=True, indexed=False), 'code': orm.SuperStringProperty('11', required=True, indexed=False), 'unit_price': orm.SuperDecimalProperty('12', required=True, indexed=False), 'product_uom': orm.SuperLocalStructuredProperty('19', '13', required=True), 'quantity': orm.SuperDecimalProperty('14', required=True, indexed=False), 'discount': orm.SuperDecimalProperty('15', required=True, indexed=False), 'taxes': orm.SuperLocalStructuredProperty('116', '16', required=True), 'subtotal': orm.SuperDecimalProperty('17', required=True, indexed=False), 'discount_subtotal': orm.SuperDecimalProperty('18', required=True, indexed=False) } entity._use_rule_engine = False entity.write() entity._transaction_actions = [ Action(key=Action.build_key('add_to_cart', parent=entity.key), name='Add to Cart', active=True, arguments={ 'domain': orm.SuperKeyProperty(kind='6', required=True), 'product': orm.SuperKeyProperty(kind='38', required=True), 'variant_signature': orm.SuperJsonProperty() }) # Other actions: update, checkout, cancel, pay, timeout, complete, message ] entity._transaction_plugin_groups = [ PluginGroup(name='Entry Init', active=True, sequence=0, transactional=False, subscriptions=[ Action.build_key('add_to_cart', parent=entity.key) ], plugins=[CartInit()]), PluginGroup(name='Payment Services Configuration', active=True, sequence=1, transactional=False, subscriptions=[ Action.build_key('add_to_cart', parent=entity.key) ], plugins=[ PayPalPayment( currency=Unit.build_key('usd'), reciever_email='*****@*****.**', business='*****@*****.**') ]), PluginGroup(name='Entry Lines Init', active=True, sequence=2, transactional=False, subscriptions=[ Action.build_key('add_to_cart', parent=entity.key) ], plugins=[LinesInit()]), PluginGroup(name='Address Exclusions, Taxes, Carriers...', active=True, sequence=3, transactional=False, subscriptions=[ Action.build_key('add_to_cart', parent=entity.key) ], plugins=[]), PluginGroup( name='Calculating Algorithms', active=True, sequence=4, transactional=False, subscriptions=[ Action.build_key('add_to_cart', parent=entity.key) ], plugins=[ AddressRule( exclusion=False, address_type='billing' ), # @todo For now we setup default address rules for both, billing & shipping addresses. AddressRule( exclusion=False, address_type='shipping' ), # @todo For now we setup default address rules for both, billing & shipping addresses. ProductToLine(), ProductSubtotalCalculate(), TaxSubtotalCalculate(), OrderTotalCalculate() ]), PluginGroup(name='Commit Transaction Plugins', active=True, sequence=5, transactional=True, subscriptions=[ Action.build_key('add_to_cart', parent=entity.key) ], plugins=[ RulePrepare(cfg={'path': '_group._entries'}), TransactionWrite(), CallbackNotify(), CallbackExec() ]), ] entity.write({ 'agent': self.context.user.key, 'action': self.context.action.key }) self.config.next_operation = 'complete' self.config.next_operation_input = {'domain_key': domain_key} self.config.write()