示例#1
0
class ApplicationSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Application
        load_instance = True
        ordered = True
        include_relationships = True

    status = EnumField(ApplicationStatus)
    applicant = ma.Nested('AccountSchema', only=('full_name', 'email'))
    feedback = ma.Nested('FeedbackSchema', exclude=('time', ))
    reports = ma.Nested('VolunteeringReportSchema', many=True)
    telegram_username = ma.Str(data_key='telegram')
示例#2
0
class NotificationSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Notification
        load_instance = True
        include_relationships = True

    type = EnumField(NotificationType)
    payload = ma.Nested(PayloadSchema)
示例#3
0
class StockChangeSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = StockChange
        load_instance = True
        ordered = True
        include_fk = True
        include_relationships = True

    status = EnumField(StockChangeStatus)
    variety = ma.Nested(VarietySchema, exclude=('stock_changes', ))
    account = ma.Nested('AccountSchema', only=('email', 'full_name'))
    product = ma.Nested('ProductSchema', only=('id', 'name', 'type'))

    @pre_dump
    def get_product(self, stock_change, **_kwargs):
        stock_change.product = Product.query.get(
            stock_change.variety.product_id)
        return stock_change
示例#4
0
class ApplicationActivitySchema(ma.SQLAlchemyAutoSchema):
    '''An intermediate schema for VolunteeringReportSchema to get the activity name.'''
    class Meta:
        model = Application
        load_instance = True
        fields = ('activity', )
        include_relationships = True

    activity = ma.Nested('ActivityProjectSchema')
示例#5
0
class ActivityProjectSchema(ma.SQLAlchemyAutoSchema):
    '''An intermediate schema for VolunteeringReportSchema to get the project name.'''
    class Meta:
        model = Application
        load_instance = True
        fields = ('project', 'name')
        include_relationships = True

    project = ma.Nested('ProjectSchema', only=('name', 'id'))
示例#6
0
class VolunteeringReportSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = VolunteeringReport
        load_instance = True
        ordered = True
        include_fk = True
        include_relationships = True

    reporter_email = ma.Str(dump_only=True)
    application_id = ma.Int(dump_only=True)
    application = ma.Nested('ApplicationActivitySchema',
                            data_key='application_on')
    rating = ma.Int(validate=validate.Range(min=1, max=5))
示例#7
0
class ProjectSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Project
        load_instance = True
        ordered = True
        include_relationships = True

    name = ma.Str(allow_none=True,
                  validate=validate.Length(max=128),
                  error_messages={
                      'validator_failed':
                      'The name must be below 128 characters.'
                  })
    creator = ma.Nested('AccountSchema', only=('full_name', 'email'))
    image_id = ma.Int(allow_none=True)
    review_status = EnumField(ReviewStatus)
    lifetime_stage = EnumField(LifetimeStage)
    activities = ma.Nested('ActivitySchema', many=True)
    moderators = ma.Nested('AccountSchema',
                           only=('full_name', 'email'),
                           many=True)
    start_date = ma.DateTime()
    end_date = ma.DateTime()
示例#8
0
class ProductSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Product
        load_instance = True
        ordered = True
        include_relationships = True

    varieties = ma.Nested('VarietySchema',
                          many=True,
                          validate=validate.Length(min=1))
    name = ma.Str(validate=validate.Length(min=1, max=128))
    type = ma.Str(validate=validate.Length(min=1, max=128), allow_none=True)
    description = ma.Str(validate=validate.Length(max=1024))
    price = ma.Int(validate=validate.Range(min=1))
示例#9
0
class PayloadSchema(ma.Schema):
    project = ma.Nested('ProjectSchema',
                        only=('id', 'name', 'review_status', 'lifetime_stage',
                              'image_id'))
    activity = ma.Nested('ActivitySchema',
                         only=('id', 'name', 'internal', 'reward_rate'))
    product = ma.Nested('ProductSchema', only=('id', 'name', 'type', 'price'))
    variety = ma.Nested('VarietySchema',
                        only=('id', 'size', 'color', 'images'))
    account = ma.Nested('AccountSchema', only=('email', 'full_name'))
    application = ma.Nested('ApplicationSchema',
                            only=('id', 'status', 'actual_hours'))
    stock_change = ma.Nested('StockChangeSchema',
                             only=('id', 'amount', 'status'))
    transaction = ma.Nested('TransactionSchema', only=('id', 'change'))
    message = ma.Str()

    @pre_dump
    def fill_data(self, data, **_kwargs):
        if 'project_id' in data:
            data['project'] = Project.query.get(data.pop('project_id'))
        if 'activity_id' in data:
            data['activity'] = Activity.query.get(data.pop('activity_id'))
        if 'product_id' in data:
            data['product'] = Product.query.get(data.pop('product_id'))
        if 'variety_id' in data:
            data['variety'] = Variety.query.get(data.pop('variety_id'))
        if 'account_email' in data:
            data['account'] = Account.query.get(data.pop('account_email'))
        if 'application_id' in data:
            data['application'] = Application.query.get(
                data.pop('application_id'))
        if 'stock_change_id' in data:
            data['stock_change'] = StockChange.query.get(
                data.pop('stock_change_id'))
        if 'transaction_id' in data:
            data['transaction'] = Transaction.query.get(
                data.pop('transaction_id'))
        return data
示例#10
0
class VarietySchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Variety
        load_instance = True
        ordered = True
        include_fk = True
        include_relationships = True

    @pre_load
    def create_stock_change(self, data, **_kwargs):
        """Convert the integer `amount` property into a stock change."""
        if 'stock_changes' in data:
            raise ValidationError(
                'The stock changes are not to be specified explicitly.')

        if self.context.get('update', False):
            return data

        if 'amount' not in data:
            raise ValidationError('The amount for a variety is not specified.')

        amount = data.pop('amount')
        data['stock_changes'] = [{
            'amount': amount,
            'account_email': self.context['user'].email,
            'status': 'carried_out',
        }]
        return data

    @pre_load
    def normalize_color(self, data, **_kwargs):
        """Normalize the color value."""
        if 'color' not in data:
            if self.context.get('update', False):
                return data
            raise ValidationError('The color must be specified.')

        if data['color'] is None:
            return data

        if data['color'].startswith('#'):
            data['color'] = data['color'][1:].upper()

        if len(data['color']) != 6:
            raise ValidationError(
                f'The color value is {len(data["color"])} characters long, 6 expected.'
            )

        return data

    @pre_load
    def enumerate_images(self, data, **_kwargs):
        """Convert the array of URL strings to an array of image objects with order."""
        if self.context.get('update', False):
            if 'images' in data:
                data['images'] = [{
                    'order': idx,
                    'image_id': id
                } for (idx, id) in enumerate(data['images'], start=1)]
        else:
            try:
                data['images'] = [{
                    'order': idx,
                    'image_id': id
                } for (idx, id) in enumerate(data['images'], start=1)]
            except KeyError:
                raise ValidationError('Images must be specified.')
        return data

    @post_dump
    def format_color(self, data, **_kwargs):
        """Add a '#' to the color value."""
        if data['color'] is not None:
            data['color'] = '#' + data['color']
        return data

    @post_dump
    def flatten_images(self, data, **_kwargs):
        """Convert an array of image objects with order into a flat array of URL strings."""
        if 'images' not in data:
            return data

        data['images'] = [
            image["image_id"]
            for image in sorted(data['images'], key=lambda x: x['order'])
        ]
        return data

    images = ma.Nested('ProductImageSchema', many=True)
    stock_changes = ma.Nested('StockChangeSchema', many=True)
    amount = ma.Int(dump_only=True)
    purchases = ma.Int(dump_only=True)