Exemple #1
0
class Project(Model, AuditableRepository, Service):
    name = Property(str, required=True, validators=[NotEmpty()])
    tasks = Property(list, sub_type=Task)
    created = Property(datetime, required=True, generator=date_now_generator)

    def __init__(self, **kwargs):
        Model.init_model(self, **kwargs)
Exemple #2
0
class Group(Model, MongoRepository):
    id = Property(str, required=True, generator=create_uuid_generator('U'))
    name = Property(str,
                    required=True,
                    validators=[NotEmpty, Regexp('[A-Za-z0-9-_]')],
                    index=UniqueIndex)
    users = Property(list, sub_type=User)
Exemple #3
0
class Order(Model, MongoRepository):
    id = Property(str, generator=create_uuid_generator('O'))
    payment_method = Property(Payment, required=True)
    products = Property(list, sub_type=Product, required=True)
    order_date = Property(datetime, required=True, generator=date_now_generator)
    delivery_address = Property(Address, required=True)
    inventory_client = get_client_proxy('inventory')
    payment_client = get_client_proxy('payments')
    shipping_client = get_client_proxy('shipping')

    @classmethod
    def before_post(cls, *args, **kwargs):
        order: Order = kwargs.get('model')
        order.finalise_and_validate()
        status_code, rsp_dict = Order.inventory_client.reservations.post(Reservation(order_id=order.id, products=order.products))
        order.update(reservation_id=rsp_dict.get('result'))

    @classmethod
    def after_post(cls, *args, **kwargs):
        order: Order = kwargs.get('model')
        amount = sum([p.price.amount for p in order.products])
        auth_req = AuthorisationRequest(payment_method=order.payment_method, amount=amount)
        auth_req.external_reference = order.id
        status_code, rsp_dict = Order.payment_client.wrap('/payments/authorize').post(auth_req)
        print(f'<authorisation response> {rsp_dict}')
        if status_code not in [200, 201]:
            code, canceled_reservation = Order.inventory_client.wrap(f'/reservations/{order.reservation_id}/cancel').patch()
            if code not in [200, 201]:
                config.app_engine.logger.warn('reservation was not successful.')
            raise Exception('It is not aurhorised')
        else:
            code, result = Order.shipping_client.shippings.post(
                Shipping(reservation_id=order.reservation_id, delivery_address=order.delivery_address))
            print(f':: {result.tracking_id}')
Exemple #4
0
class ExampleClass(Model):
    just_numbers = Property(str,
                            required=True,
                            validators=[Regexp('^[0-9]+$')])
    future_field = Property(datetime, validators=[Future])
    email = Property(str, validators=Email)
    distance = Property(int, validators=[Min(10), Max(15)])
    numbers = Property(list, validators=Unique)
Exemple #5
0
class Portfolio(Model, MongoRepository):
    id = Property(str, required=True, generator=create_uuid_generator('P'))
    name = Property(str,
                    required=True,
                    validators=[NotEmpty, Regexp('[A-Za-z0-9-_]')],
                    index=UniqueIndex)
    stocks = Property(list, sub_type=Stock, validators=NotEmpty)
    owner = Property(User, required=False)
Exemple #6
0
class Order(Model):
    id = Property(str, generator=create_uuid_generator('O'))
    payment_method = Property(Payment, required=True)
    products = Property(list, sub_type=Product, required=True)
    order_date = Property(datetime,
                          required=True,
                          generator=date_now_generator)
    delivery_address = Property(Address, required=True)
Exemple #7
0
class User(Model, AuditableRepository, Service):
    id = Property(str, required=True, generator=uuid_generator('U'))
    name = Property(str, required=True, validators=[NotEmpty])
    email = Property(str, required=True, validators=[Email, NotEmpty])
    password = Property(str,
                        required=True,
                        validators=[NotEmpty],
                        converter=content_hasher(rounds=10),
                        omit=True)
    roles = Property(list, sub_type=str, default_value=['Login'])
Exemple #8
0
class Reservation(Model, MongoRepository):
    id = Property(str, generator=create_uuid_generator('R'))
    order_id = Property(str, required=True)
    order_date = Property(datetime,
                          required=True,
                          generator=date_now_generator)
    products = Property(list,
                        sub_type=Product,
                        required=True,
                        validators=NotEmpty())
    state = Property(ReservationState,
                     required=True,
                     default_value=ReservationState.RESERVED)
Exemple #9
0
class User(Model, MongoRepository, Service, IdentityMixin):
    id = Property(str, required=True, generator=create_uuid_generator('U'))
    name = Property(str,
                    required=True,
                    validators=[NotEmpty, Regexp('[A-Za-z0-9-_]')],
                    index=UniqueIndex)
    password = Property(str,
                        required=True,
                        validators=[NotEmpty],
                        converter=content_hasher(rounds=10),
                        omit=True)
    description = Property(str, index=TextIndex)
    roles = Property(list, sub_type=str)
    created = Property(datetime,
                       required=True,
                       validators=[Past],
                       generator=date_now_generator)
    last_login = Property(datetime, marshaller=TimestampMarshaller)
    sequence = Property(int, index=Index)

    @link(rel='change_password',
          http_method='POST',
          require=[CurrentSubject(), Role('admin')])
    def change_p(self, current_password, new_password):
        if not pbkdf2_sha256.verify(current_password, self.password):
            raise ServiceException(403, _('Current password is not correct'))
        else:
            self.password = new_password
            self.save()
        return _('Password changed')

    @link(require=Anonymous())
    def get_description(self):
        return self.description
Exemple #10
0
class Stock(Model):
    code = Property(str,
                    required=True,
                    validators=[NotEmpty,
                                Regexp('[A-Za-z0-9-_]'),
                                Max(4)],
                    index=UniqueIndex)
    open = Property(float, required=True, validators=[Min(0)])
    updated = Property(datetime,
                       required=True,
                       validators=[Past],
                       generator=date_now_generator)
    history = Property(list, sub_type=int)
    sequence = Property(int, validators=[Min(1), Max(100)])
Exemple #11
0
class Reservation(Model, MongoRepository, Service):
    id = Property(str, generator=create_uuid_generator('R'))
    order_id = Property(str, required=True)
    order_date = Property(datetime,
                          required=True,
                          generator=date_now_generator)
    products = Property(list, sub_type=Product, required=True)
    state = Property(ReservationState,
                     required=True,
                     default_value=ReservationState.RESERVED)

    @classmethod
    def before_post(self, *args, **kwargs):
        print('aaaa')
Exemple #12
0
class Payment(Model):
    method = Property(PaymentMethod, required=True)
    customer_id = Property(str, required=True, validators=[NotEmpty])
    customer_secret = Property(str, required=True, validators=[NotEmpty])

    def validate(self):
        if self.method in (PaymentMethod.MASTER, PaymentMethod.VISA):
            if len(self.customer_id) < 16 or len(self.customer_secret) < 3:
                raise ValidationException(
                    'The card number must be 16 character long and the CVC 3.',
                    self, 'payment_method')
        elif self.method in (PaymentMethod.PAYPAL, PaymentMethod.DIRECT_DEBIT):
            if len(self.customer_id) < 22:
                raise ValidationException(
                    'The IBAN must be at least 22 character long.', self,
                    'payment_method')
Exemple #13
0
class Order(Model, MongoRepository, Service):
    id = Property(str, generator=create_uuid_generator('O'))
    products = Property(list, sub_type=Product, required=True)
    order_date = Property(datetime,
                          required=True,
                          generator=date_now_generator)

    @classmethod
    def before_post(cls, *args, **kwargs):
        print(request.args)
        print(request.headers)
        client = HttpClientServiceProxy('http://127.0.0.1:5000/')
        order = kwargs['document']
        status, rsp_dict = client.reservation.post(
            Reservation(order_id=order.get('_id'),
                        products=order.get('products')))
        print(f'status: {status} -> {rsp_dict}')
Exemple #14
0
class Address(Model):
    first_name = Property(str, required=True, validators=[NotEmpty])
    last_name = Property(str, required=True, validators=[NotEmpty])
    city = Property(str, required=True, validators=[NotEmpty])
    street = Property(str, required=True, validators=[NotEmpty])
    country = Property(str, required=True, validators=[NotEmpty])
    postal_code = Property(str, required=True, validators=[NotEmpty])
Exemple #15
0
class User(Model, MongoRepository, Service):
    id = Property(str)
    name = Property(str, required=True, index=UniqueIndex)
    email = Property(str, validators=[Email], index=UniqueIndex)
    password = Property(str,
                        validators=[Regexp('(?=.{8,})')],
                        converter=content_hasher(),
                        omit=True)
    roles = Property(list, sub_type=str, default_value=['Login'])

    @link(http_method='POST', require=[CurrentSubject(), Role('admin')])
    def change_password(self, current_password, new_password):
        if not pbkdf2_sha256.verify(current_password, self.password):
            raise ServiceException(403, _('Current password is not correct'))
        else:
            self.password = new_password
            self.save()
        return _('Password changed')

    @link(require=Anonymous())
    def get_description(self):
        return self.description
Exemple #16
0
class Task(Model, AuditableRepository):
    id = Property(str, required=True, generator=create_uuid_generator('U'))
    name = Property(str, required=True, validators=[NotEmpty])
    description = Property(str, required=True, validators=[NotEmpty])
    completed = Property(bool, required=True, default_value=False)
    created = Property(datetime, required=True, generator=date_now_generator)
    closed_date = Property(datetime, validators=[Past])
    priority = Property(Priority, required=True, default_value=Priority.MEDIUM)

    def __init__(self, **kwargs):
        Model.init_model(self, **kwargs)

    def complete(self):
        self.completed = True
        self.closed_date = datetime.now()
Exemple #17
0
class User(Model, MongoRepository, Service):
    id = Property(str, required=True, generator=uuid_generator('U'))
    name = Property(str,
                    required=True,
                    validators=[NotEmpty, Regexp('[A-Za-z0-9-_]')])
    password = Property(str, required=True, validators=[NotEmpty])
    description = Property(str)
    roles = Property(list, sub_type=str)
    created = Property(datetime,
                       required=True,
                       validators=[Past],
                       generator=date_now_generator)
Exemple #18
0
class Task(Model, AuditableRepository, Service):
    id = Property(str, required=True, generator=uuid_generator('T'))
    name = Property(str, required=True, validators=[NotEmpty])
    description = Property(str)
    tags = Property(list, sub_type=str)
    completed = Property(bool, required=True, default_value=False)
    closed_date = Property(datetime, validators=[Past])

    def __init__(self, **kwargs):
        Model.init_model(self, **kwargs)

    def complete(self):
        """
        Mark the task complete and set the completion date to now;
        """
        self.completed = True
        self.closed_date = datetime.now()
class Shipping(Model):
    reservation_id = Property(str, required=True, validators=NotEmpty)
    order_date = Property(datetime,
                          required=True,
                          generator=date_now_generator)
    delivery_address = Property(Address, required=True)
Exemple #20
0
class Stock(Model, MongoRepository):
    id = Property(str, generator=create_uuid_generator('S'))
    product = Property(Product, required=True)
    stock = Property(int, required=True, default_value=0)
Exemple #21
0
class Product(Model, MongoRepository):
    id = Property(str, generator=create_uuid_generator('P'))
    name = Property(str, required=True)
    description = Property(str)
    size = Property(ProductSize, required=True)
    price = Property(Money, required=True)
Exemple #22
0
class Reservation(Model, MongoRepository):
    id = Property(str, generator=create_uuid_generator('R'))
    order_id = Property(str, required=True)
    order_date = Property(datetime, required=True, generator=date_now_generator)
    products = Property(list, sub_type=Product, required=True, validators=NotEmpty())
    state = Property(ReservationState, required=True, default_value=ReservationState.RESERVED)
    stocks = Property(dict, sub_type=dict)
    tracking_id = Property(str)

    def group_products_by_code(self):
        products_by_code = dict()
        for product in self.products:
            size_and_quantity = products_by_code.get(product.code, {product.size.name: 0})
            size_and_quantity[product.size.name] = size_and_quantity.get(product.size.name, 0) + 1
            products_by_code[product.code] = size_and_quantity
        return products_by_code

    @classmethod
    def before_post(cls, *args, **kwargs):
        # method called before the reservation id is sent
        for pcode, size_and_quantity in kwargs['model'].group_products_by_code().items():
            for psize, quantity in size_and_quantity.items():
                # todo: what if there are multiple stock items with the same product code
                query = Stock.where(
                    (Stock.product.code == pcode) & (Stock.product.size == psize) & (Stock.available >= quantity))
                reserved_stock = query.find_one_and_update(available=Stock.available - quantity,
                                                           reserved=Stock.reserved + quantity)
                if not reserved_stock:
                    raise ReservationException(f"There's no stock available for code: {pcode} and size: {psize}.")
                if hasattr(kwargs['model'], 'stocks') and kwargs['model'].stocks is not None:
                    size_and_qty = kwargs['model'].stocks.get(pcode, {psize: {'qty': quantity}})
                    if psize not in size_and_qty:
                        size_and_qty[psize] = {'qty': quantity}
                else:
                    size_and_qty = {psize: {'qty': quantity}}
                    kwargs['model'].stocks = {}
                size_and_qty[psize]['stock'] = reserved_stock.id
                kwargs['model'].stocks[pcode] = size_and_qty

    @classmethod
    def after_post(cls, *args, **kwargs):
        reservation: Reservation = kwargs.get('model')
        print(f'reservation id: {reservation.id}')

    @action(method='PATCH', require=[Role('user')])
    def commit(self):
        self.state = ReservationState.COMMITTED
        self.save()
        return self

    @action(method='PATCH', require=[Role('user')])
    def execute(self, tracking_id):
        self.state = ReservationState.EXECUTED
        self.tracking_id = tracking_id
        self.save()
        for pcode, sizes in self.stocks.items():
            for size, quantity_and_stock in sizes.items():
                stock_id = quantity_and_stock.get('stock')
                query = Stock.where(Stock.id == stock_id)
                modified_count = query.update_one(reserved=Stock.reserved - quantity_and_stock.get('qty'))
                if modified_count != 1:
                    config.app_engine.logger.warn(f'quantities were not reduced for stock: {stock_id}')
        return self

    @action(method='PATCH', require=[Role('user')])
    def cancel(self):
        error = False
        for pcode, sizes in self.stocks.items():
            for size, quantity_and_stock in sizes.items():
                stock_id = quantity_and_stock.get('stock')
                query = Stock.where(Stock.id == stock_id)
                qty = quantity_and_stock.get('qty')
                modified_count = query.update_one(reserved=Stock.reserved - qty, available=Stock.available + qty)
                if modified_count != 1:
                    error = True
                    config.app_engine.logger.warn(f'quantities were not reduced for stock: {stock_id}')
        if not error:
            self.state = ReservationState.CANCELLED
            self.save()
        return self
Exemple #23
0
class ExampleClass(Model):
    just_numbers = Property(str,
                            required=True,
                            validators=[Regexp('^[0-9]+$')])
    future_field = Property(datetime, validators=[Future])
Exemple #24
0
class Application(Model, MongoRepository):
    id = Property(str, required=True, generator=create_uuid_generator())
    application_date = Property(date,
                                required=True,
                                marshaller=MongoDateTimeMarshaller)
Exemple #25
0
class AuthorisationRequest(Model):
    payment_method = Property(PaymentMethod, required=True)
    amount = Property(Money, required=True)
    external_reference = Property(str, required=True, validators=NotEmpty)
Exemple #26
0
class StockInventory(Model, MongoRepository):
    id = Property(str, generator=create_uuid_generator('S'))
    product = Property(Product, required=True)
    available = Property(int, required=True, default_value=0)
    reserved = Property(int, required=True, default_value=0)
Exemple #27
0
class Product(Model):
    code = Property(str, required=True, validators=[NotEmpty])
    name = Property(str, required=True)
    description = Property(str)
    size = Property(ProductSize, required=True)
    price = Property(Money, required=True)