示例#1
0
class IntIDMixin(object):
    id = db.IntField(primary_key=True)
    created_at = db.DateTimeField(default=datetime.now)
    updated_at = db.DateTimeField()

    def _generate_id(self):
        last_obj = self.__class__.objects.only('id').order_by('-id').first()
        self.id = last_obj.id + 1 if last_obj else 1

    def save(self, *args, **kwargs):
        if not self.id:
            self._generate_id()
        if not self.created_at:
            self.created_at = datetime.now()
        self.updated_at = datetime.now()
        super(IntIDMixin, self).save(*args, **kwargs)
示例#2
0
class Order(db.Document):
    apishop_id = db.StringField(required=True)
    offers = db.ListField(db.EmbeddedDocumentField('OrderOffer'), default=[])
    ordered_at = db.DateTimeField()
    userinfo = db.DictField(default={})
    delivery_info = db.DictField(default={})
    comment = db.StringField()

    @property
    def get_delivery(self):
        return dict(price=self.delivery_info.get('delivery_price'),
                    total=self.delivery_info.get('order_sum')) \
            if self.delivery_info.get('delivery_price', None) is not None else None

    @property
    def get_total(self):
        return sum([offer.price * offer.quantity for offer in self.offers])

    def get_relevant_offers(self, max_items=4):
        offer_ids_not_to = [item.offer.id for item in self.offers]
        offer_ids = Offer.objects(available=True, id__nin=offer_ids_not_to).distinct('id')

        length = len(offer_ids)
        if length:
            try:
                ids = random.sample(offer_ids, max_items)
            except ValueError:
                ids = random.sample(offer_ids, length)

        return Offer.objects(id__in=ids)

    def get_timer(self):
        timer = self.ordered_at + timedelta(minutes=5) - timedelta(seconds=20)
        if timer < datetime.now():
            return False
        return timer.strftime('%Y/%m/%d %H:%M:%S')

    def add_offer(self, offer, quantity=1, variant=None):
        o = OrderOffer(offer=offer,
                       price=offer.get_price(),
                       oldprice=offer.get_oldprice or 0.0,
                       quantity=quantity,
                       variant=variant)
        self.update(push__offers=o)
        self.reload()

    def populate_offers(self, sended_offers):

        if not isinstance(sended_offers, (list, tuple)):
            sended_offers = [sended_offers]

        for sended_offer in sended_offers:
            offer = Offer.objects(articul=sended_offer.get('articul')).first()
            if offer:
                self.offers.append(OrderOffer(offer=offer,
                                              price=offer.get_price(),
                                              oldprice=offer.get_oldprice or 0.0,
                                              quantity=sended_offer.get('quantity', 1),
                                              variant=sended_offer.get('variant', None)))
示例#3
0
class BaseModel(db.Document):
    id = db.IntField(primary_key=True)
    create_at = db.DateTimeField(default=datetime.now)
    update_at = db.DateTimeField()

    meta = {'allow_inheritance': True, 'abstract': True, 'strict': False}

    @classmethod
    def get(cls, id):
        coll_name = cls._meta['collection']
        key = OBJ_KEY.format(coll_name=coll_name, id=id)
        rs = cache.get(key)
        if rs:
            return cls.from_json(
                rs)  # Converts json data to an unsaved document instance
        rs = cls.objects.get(id=id)
        cache.set(key, rs.to_json())  # Convert this document to JSON.
        return rs

    @classmethod
    def get_multi(cls, ids):
        return [cls.get(i) for i in ids if i]

    @classmethod
    def get_or_create(cls, **kwargs):
        try:
            return cls.objects.get(id=kwargs['id'])
        except DoesNotExist:
            kwargs.update({'update_at': datetime.now()})
            model = cls(**kwargs)
            model.save()
            return model

    @classmethod
    def get_sample_ids(cls, size):
        samples = list(cls.objects.aggregate({'$sample': {'size': size}}))
        return [s['_id'] for s in samples]
示例#4
0
class ApishopConfig(TempDBMixin, db.Document):
    login = db.StringField(max_length=50, required=True)
    shop_id = db.IntField(required=True)
    yml_file = db.StringField(max_length=255)
    task = db.DictField(default={'id': None, 'name': None})
    updated_at = db.DateTimeField()

    _password = db.StringField(required=True)

    def __unicode__(self):
        return self.login

    @classmethod
    def get_config(cls):
        return cls.objects.first()

    @property
    def password(self):
        return decode_string(self._password)

    @password.setter
    def password(self, value):
        self._password = encode_string(value)

    def set_task(self, task):
        self.update(set__task=dict(id=task.task_id, name=task.task_name))

    def set_updated_at(self):
        self.update(set__updated_at=datetime.datetime.now())

    @property
    def is_yml_exists(self):
        if self.yml_file:
            return check_file_exists(self.yml_file, relative=True)
        return False

    @property
    def task_is_ready(self):
        if self.task.get('id'):
            return celery.AsyncResult(self.task.get('id')).ready()
        return True

    def delete(self, *args, **kwargs):
        delete_file_by_path(self.yml_file, relative=True)
        ApishopCategory.objects.delete()
        ApishopOffer.objects.delete()
        super(ApishopConfig, self).delete(*args, **kwargs)
示例#5
0
class User(db.Document, UserMixin):
    email = db.StringField(max_length=255, unique=True)
    password = db.StringField(max_length=255, required=True)
    name = db.StringField(max_length=255)
    active = db.BooleanField(default=True)
    roles = db.ListField(db.ReferenceField(Role), default=[])
    registered_at = db.DateTimeField()

    def __unicode__(self):
        return 'User %s' % self.email

    @property
    def is_admin(self):
        return self.has_role('admin')

    def save(self, *args, **kwargs):
        self.registered_at = datetime.now()
        super(User, self).save(*args, **kwargs)
示例#6
0
class ApishopPriceChange(TempDBMixin, db.Document):
    oid = db.IntField()
    name = db.StringField()
    old_price = db.FloatField()
    new_price = db.FloatField()
    date = db.DateTimeField(default=datetime.datetime.now)

    meta = {'ordering': ['-date']}

    @classmethod
    def create_or_update(cls, **kwargs):
        oid = kwargs.pop('oid')

        obj = cls.objects(oid=oid)
        if len(obj) >= 1:
            for o in obj:
                o.delete()

        obj = cls(**kwargs)
        obj.save()
        return obj
示例#7
0
class Subscriber(IntIDMixin, db.Document):
    name = db.StringField(max_length=200, required=True)
    email = db.StringField(max_length=200, required=True)

    subscribed_at = db.DateTimeField(default=datetime.now())
    is_active = db.BooleanField(default=True)

    def __unicode__(self):
        return '<Subscriber {}: {}>'.format(self.id, self.email)

    def mark_subscribed(self):
        userinfo = session.get('userinfo', None)
        if not userinfo:
            session['userinfo'] = dict(fullname=self.name, email=self.email)
        else:
            if 'fullname' not in userinfo:
                userinfo['fullname'] = self.name
            if 'email' not in userinfo:
                userinfo['email'] = self.email

        session['is_subscribed'] = True
示例#8
0
class Review(db.Document):
    offer = db.ReferenceField('Offer')
    fullname = db.StringField(max_length=200)
    email = db.StringField(max_length=200)
    text = db.StringField()
    rating = db.IntField(default=0)
    is_moderated = db.BooleanField(default=False)
    is_viewed = db.BooleanField(default=False)
    created_at = db.DateTimeField(default=datetime.now)

    meta = {
        'ordering': ['-created_at']
    }

    def toggle_moderate(self):
        self.update(set__is_moderated=not self.is_moderated)
        self.reload()

    def set_viewed(self):
        if not self.is_viewed:
            self.update(set__is_viewed=True)
            self.reload()
示例#9
0
class Region(db.Document):
    id = db.IntField(primary_key=True)
    name = db.StringField(max_length=400)
    popularity = db.IntField(default=0)
    deliveries = db.ListField(db.EmbeddedDocumentField('RegionDelivery'),
                              default=[])

    updated_at = db.DateTimeField()

    meta = {
        'ordering': ['-popularity', '+id'],
        'indexes': ['name']
    }

    def __unicode__(self):
        return self.name

    def __str__(self):
        return u'%s(%s)' % (self.__class__.__name__, self.id)

    def int_popularity(self):
        popularity = (self.popularity or 0) + 1
        try:
            self.update(set__popularity=popularity)
        except db.OperationError:
            self.popularity = popularity
            self.save()

    def update_deliveries(self, methods):
        now = datetime.now()
        try:
            self.update(set__deliveries=methods, set__updated_at=now)
        except db.OperationError:
            self.deliveries = methods
            self.updated_at = now
            self.save()

    def get_delivery_prices(self, result, aid=None):
        d_methods = {str(d.id): {'id': d.id,
                                 'method': d.name} for d in DeliveryMethod.objects()}
        if not aid:
            aids = Offer.objects(available=True).distinct('aid')
            aid = random.choice(aids)

        methods = []

        if len(result):
            deliveries = result[0].deliveries
            for delivery in deliveries:
                d = d_methods.get(delivery.id, None)
                if d:
                    prices = []
                    for payment in delivery.payments:
                        price = payment.sum
                        if price is not None and price > 0 and price not in prices:
                            prices.append(price)

                    if len(prices):
                        price = min(prices)
                        d['price'] = price
                        methods.append(RegionDelivery(**d))
        return methods
示例#10
0
class OfferSpecial(db.Document):
    is_active = db.BooleanField(default=False)
    type = db.StringField(choices=(('real', u'Понизить цену'), ('fake', u'Повысить цену')), default='real', verbose_name=u'Тип акции')
    price_type = db.StringField(choices=(('percent', u'На проценты'), ('new', u'На сумму')), default='percent')
    price_value = db.IntField(required=True)
    timer_type = db.StringField(choices=(('date', u'До даты'), ('time', u'По времени')), default='date')
    timer_settings = db.DictField(required=True)

    created_at = db.DateTimeField()
    prices = db.EmbeddedDocumentField('OfferPrices')

    def __unicode__(self):
        return str(self.id)

    @classmethod
    def create_or_update(cls, offer, form):
        special = offer.get_special or cls()

        form.populate_obj(special)

        special.populate_price(offer)
        special.set_created_at()
        special.save()

        offer.update(set__special=special)

        return special

    def create_from_self(self):
        offer = Offer.objects(special=self).first()
        if offer:
            data = deepcopy(self._data)
            data.pop('id')
            data.pop('prices')

            new = self.__class__(**data)

            return new

    def set_created_at(self):
        self.is_active = True
        self.created_at = datetime.now()

    def populate_price(self, offer):
        if self.type == 'real':

            if not self.prices:
                self.prices = offer.price

            if self.price_type == 'percent':
                new_price = self.prices.ru * (1 - float(self.price_value) / 100)

            elif self.price_type == 'new':
                new_price = self.prices.ru - self.price_value

            offer.update(set__price__ru=new_price)
            offer.reload()

        else:

            if not self.prices:
                self.prices = offer.price

            if self.price_type == 'percent':
                new_price = self.prices.ru * (1 + float(self.price_value) / 100)

            elif self.price_type == 'new':
                new_price = self.prices.ru + self.price_value

            self.prices.ru = new_price

    def get_timer(self):

        if self.timer_type == 'date':
            date = datetime.strptime(self.timer_settings.get('timer_date'), "%d/%m/%Y").date()
            return date + timedelta(days=1)

        elif self.timer_type == 'time':
            now = datetime.now()
            delta = now - self.created_at
            days_step = int(self.timer_settings.get('timer_days', 1))

            if self.timer_settings.get('timer_repeat') == 'on' and delta.days > days_step:
                full = delta.days - (delta.days % days_step) + days_step
                new_delta = timedelta(days=full)
            else:
                new_delta = timedelta(days=days_step)

            return (self.created_at + new_delta + timedelta(days=1)).date()

    @property
    def timer(self):
        return self.get_timer().strftime('%Y/%m/%d')

    @cached_property
    def is_over(self):
        now = datetime.now()
        is_over = now.date() >= self.get_timer()
        if is_over:
            offer = Offer.objects(special=self).first()
            if offer:
                self.remove(offer)
            else:
                self.update(set__is_active=False)
        return is_over

    def remove(self, offer):
        atomic = dict(set__special=None)
        if self.type == 'real':
            atomic['set__price'] = self.prices

        offer.update(**atomic)

        self.delete()