예제 #1
0
def fuckup_ios_delivery_types(delivery_types):
    RESTRICTION = {
        'meatme': [DELIVERY],
        'sushimarket': [DELIVERY],
        'nasushi': [DELIVERY],
        'perchiniribaris': [SELF, IN_CAFE],
        'perchiniribarislublino': [SELF, IN_CAFE],
        'burgerhouse': [SELF, IN_CAFE],
        'tykano': [SELF, IN_CAFE],
        'magnolia': [SELF, IN_CAFE],
        'chikarabar': [SELF, IN_CAFE],
        'sushivesla': [DELIVERY],
        'pastadeli': [SELF, IN_CAFE]
    }
    user = get_temporary_user()
    if not is_ios_user() or user.get(VERSION) != 2 or RESTRICTION.get(
            namespace_manager.get_namespace()) == None:
        return delivery_types
    send_error = False
    for delivery_type in delivery_types[:]:
        if int(delivery_type['id']) in RESTRICTION.get(
                namespace_manager.get_namespace()):
            delivery_types.remove(delivery_type)
            send_error = True
    if send_error:
        logging.warning('Cut delivery types: %s' % delivery_types)
        admins.send_error(
            'ios_fuckup', 'Catch Version 2 with 2 delivery types',
            str({
                'user_agent': user.get(USER_AGENT),
                'delivery_types': delivery_types,
                'version': user.get(VERSION),
                'namespace': namespace_manager.get_namespace()
            }))
    return delivery_types
예제 #2
0
 def dict(self):
     result = memcache.get(
         'gift_items_%s_%s' %
         (namespace_manager.get_namespace(), self.key.id()))
     if not result:
         item = self.item.get()
         result = item.dict()
         result['id'] = str(self.key.id())
         result.update({'points': self.points})
         for modifier in result['group_modifiers']:
             choice_dicts = modifier['choices']
             for choice_dict in choice_dicts[:]:
                 if int(choice_dict['id']
                        ) in self.additional_group_choice_restrictions:
                     choice_dict['price'] = 0
                     modifier['choices'] = [choice_dict]
                     break
         for modifier in result['single_modifiers'][:]:
             if modifier['price'] > 0:
                 result['single_modifiers'].remove(modifier)
         if self.additional_group_choice_restrictions:
             result['title'] = u'%s %s' % (item.title, u','.join([
                 GroupModifier.get_modifier_by_choice(
                     choice).get_choice_by_id(choice).title
                 for choice in self.additional_group_choice_restrictions
             ]))
         memcache.set('gift_items_%s_%s' %
                      (namespace_manager.get_namespace(), self.key.id()),
                      result,
                      time=24 * 3600)
     return result
예제 #3
0
def get_clients():
    namespace = namespace_manager.get_namespace()
    namespace_manager.set_namespace('')  # query global clients
    result = Client.query(Client.namespace_created == namespace).fetch()
    namespace_manager.set_namespace(namespace)
    result.extend(Client.query().fetch())
    return result
예제 #4
0
 def dispatch(self):
     if self.user:
         logging.info(self.user)
         namespace_manager.set_namespace(self.user.namespace)
     else:
         namespace_manager.set_namespace('')
     logging.debug('namespace=%s' % namespace_manager.get_namespace())
     super(UserApiHandler, self).dispatch()
예제 #5
0
def send_demo_sms(client):
    text = u'Поздравляем! На Вашу почту поступил тестовый заказ. Хотите боевой?\nhttp://rbcn.mobi/'
    try:
        send_sms([client.tel], text, company_footer=False)
    except Exception as e:
        error_text = str(e)
        error_text += u' В демо компании "%s" (%s).' % (config.APP_NAME, namespace_manager.get_namespace())
        send_error('sms_error', 'Send sms', error_text)
예제 #6
0
 def get(self):
     email_key = self.request.get('key')
     if not email_key:
         self.abort(403)
     order = Order.query(Order.email_key_confirm == email_key).get()
     if not order:
         return self.response.write(u'Невозможно подтвердить заказ')
     confirm_order(order, namespace_manager.get_namespace())
     self.response.write(u'Заказ успешно подтвержден')
예제 #7
0
 def get(self):
     namespace = namespace_manager.get_namespace()
     host = u'http://%s.%s.%s.appspot.com' % (namespace, CURRENT_VERSION, CURRENT_APP_ID)
     values = {
         'licence_url': u'%s/docs/licence_agreement.html' % host,
         'payment_rules_url': u'%s/docs/payment_rules.html' % host,
         'paypal_privacy_policy_url': u'%s/docs/paypal_privacy_policy.html' % host,
         'paypal_user_agreement_url': u'%s/docs/paypal_user_agreement.html' % host,
     }
     self.render('/docs/legal_list.html', legals=LegalInfo.query().fetch(), **values)
예제 #8
0
 def get(self):
     email_key = self.request.get('key')
     if not email_key:
         self.abort(403)
     order = Order.query(Order.email_key_done == email_key).get()
     if not order:
         return self.response.write(
             u'Невозможно выдать заказ. Возможно, он отменен.')
     done_order(order, namespace_manager.get_namespace())
     self.response.write(u'Заказ успешно выдан!')
예제 #9
0
def done_order(order, namespace, with_push=True):
    total_cash_back = 0
    point_sum = 0
    if config.WALLET_ENABLED:
        total_cash_back = order.activate_cash_back()
    if config.GIFT_ENABLED:
        point_sum = order.activate_gift_points()

    for share_gift in order.shared_gift_details:
        share_gift.gift.get().deactivate()

    for performing in order.promo_code_performings:
        performing = performing.get()
        promo_code = performing.promo_code.get()
        if not promo_code.persist:
            performing.close()

    if order.subscription_details:
        subscription = order.subscription_details.subscription.get()
        subscription.finalize_payment_if_needed()

    order.status = READY_ORDER
    order.email_key_done = None
    order.email_key_cancel = None
    order.email_key_postpone = None
    order.email_key_confirm = None
    order.actual_delivery_time = datetime.utcnow()

    client_key = Client.get(order.client_id).key
    shared_promo = SharedPromo.query(
        SharedPromo.recipient == client_key,
        SharedPromo.status == SharedPromo.READY).get()
    if shared_promo:
        shared_promo.deactivate(namespace_manager.get_namespace())

    if order.has_card_payment:
        legal = Venue.get(order.venue_id).legal.get()
        alfa_bank.deposit(legal.alfa_login, legal.alfa_password,
                          order.payment_id, 0)  # TODO check success
    elif order.has_paypal_payment:
        paypal.capture(order.payment_id,
                       order.total_sum - order.wallet_payment)

    order.put()

    if with_push:
        text = u"Заказ №%s выдан." % order.number
        if point_sum:
            text += u" Начислены баллы в размере %s." % point_sum
        if total_cash_back:
            text += u" Начислены бонусы на Ваш счет в размере %s." % (
                total_cash_back / 100.0)
        OrderPush(text, order, namespace).send(silent=True)
        if order.version >= 4:
            send_review_push(order)
예제 #10
0
 def get(self):
     email_key = self.request.get('key')
     if not email_key:
         self.abort(403)
     order = Order.query(Order.email_key_cancel == email_key).get()
     if not order:
         return self.response.write(
             u'Невозможно отменить заказ. Возможно, он выдан.')
     cancel_order(order, CANCELED_BY_BARISTA_ORDER,
                  namespace_manager.get_namespace())
     self.response.write(u'Заказ успешно отменен!')
예제 #11
0
def update_namespace(namespace):
    init_namespace = None

    if CURRENT_APP_ID == PRODUCTION_APP_ID:
        if not config:
            logging.debug('namespace=%s' % namespace_manager.get_namespace())
            return False, init_namespace
        logging.debug('initial namespace=%s' %
                      namespace_manager.get_namespace())
        if namespace:
            proxy_company = AutomationCompany.query(
                AutomationCompany.namespace == namespace).get()
            if proxy_company:
                init_namespace = namespace_manager.get_namespace()
                namespace_manager.set_namespace(namespace)
    elif CURRENT_APP_ID == DEMO_APP_ID:
        if not namespace_manager.get_namespace():
            namespace_manager.set_namespace(namespace)

    logging.debug('namespace=%s' % namespace_manager.get_namespace())
    return True, init_namespace
예제 #12
0
 def get(self):
     email_key = self.request.get('key')
     if not email_key:
         self.abort(403)
     order = Order.query(Order.email_key_postpone == email_key).get()
     if not order:
         return self.response.write(
             u'Невозможно перенести заказ. Возможно, он выдан, отменен или уже был перенесен.'
         )
     postpone_order(order, POSTPONE_MINUTES,
                    namespace_manager.get_namespace())
     self.response.write(u'Заказ был успешно перенесен на %s минут' %
                         POSTPONE_MINUTES)
예제 #13
0
    def get(self):
        namespace = namespace_manager.get_namespace()
        namespace_manager.set_namespace('')
        users = CompanyUser.query(CompanyUser.namespace == namespace).fetch()
        for user in users:
            user.rights_str = ''
            for right in CompanyUser.ALL_RIGHTS_BITS:
                if user.has_rights((right,)):
                    user.rights_str += MAP_RIGHTS[right] + ', '

        public_hostname = "demo.rbcn.mobi" if CURRENT_APP_ID == DEMO_APP_ID else "auto.rbcn.mobi"
        login_url = "http://%s/company/login" % public_hostname
        self.render('/user/list.html', users=users, login_url=login_url)
예제 #14
0
  def _GetNamespace(self, namespace):
    """Get namespace name.

    Args:
      namespace: Namespace provided in request arguments.

    Returns:
      If namespace is None, returns the name of the current global namespace. If
      namespace is not None, returns namespace.
    """
    if namespace is not None:
      return namespace
    return namespace_manager.get_namespace()
    def _GetNamespace(self, namespace):
        """Get namespace name.

    Args:
      namespace: Namespace provided in request arguments.

    Returns:
      If namespace is None, returns the name of the current global namespace. If
      namespace is not None, returns namespace.
    """
        if namespace is not None:
            return namespace
        return namespace_manager.get_namespace()
예제 #16
0
def check_restrictions(venue, item_dicts, gift_dicts, order_gift_dicts,
                       delivery_type, delivery_time):
    def check(item_dicts):
        description = None
        delivery_items = []
        delivery_categories = []
        for delivery in venue.delivery_types:
            if delivery.delivery_type == delivery_type:
                delivery_items = delivery.item_restrictions
                delivery_categories = delivery.category_restrictions
        for item_dict in item_dicts:
            item = item_dict['item']
            if item.time_restriction and delivery_time <= datetime.utcnow(
            ) + timedelta(minutes=item.time_restriction):
                return u'Чтобы заказать "%s" выберите время %s больше текущего времени' % (
                    item.title, _parse_time(item.time_restriction * 60))
            if venue.key in item.restrictions:
                if delivery_type == DELIVERY:
                    description = u'При заказе на доставку нет %s.' % item.title
                else:
                    description = u'В "%s" нет %s. Выберите другое заведение.' % (
                        venue.title, item.title)
                item_dict['errors'].append(description)
                substitute = _get_substitute(item, delivery_type, venue)
                if substitute:
                    item_dict['substitutes'].append(substitute)
                    if item_dict.get('gift_obj'):
                        del item_dict['substitutes']
                        description = None
            if item.key in delivery_items:
                description = u'Невозможно выбрать "%s" для типа "%s"' % (
                    item.title, DELIVERY_MAP[delivery_type])
            if item.category in delivery_categories:
                description = u'Невозможно выбрать продукт из категории "%s" для типа "%s"' % (
                    item.category.get().title, DELIVERY_MAP[delivery_type])
        return description

    items_description = check(item_dicts)
    if items_description:
        return False, items_description
    gifts_description = check(gift_dicts)
    if gifts_description:
        return False, gifts_description
    order_gifts_description = check(order_gift_dicts)
    if order_gifts_description:
        if namespace_manager.get_namespace() == 'sushimarket':
            return True, None
        else:
            return False, order_gifts_description
    else:
        return True, None
예제 #17
0
    def handle(self):
        mapreduce_id = self.request.get("mapreduce_id")
        if not mapreduce_id:
            raise BadStatusParameterError("'mapreduce_id' was invalid")
        job = model.MapreduceState.get_by_key_name(mapreduce_id)
        if job is None:
            raise KeyError("Could not find job with ID:%r in namespace:%s" %
                           (mapreduce_id, namespace_manager.get_namespace()))

        self.json_response.update(job.mapreduce_spec.to_json())
        self.json_response.update(job.counters_map.to_json())
        self.json_response.update({
            "active":
            job.active,
            "active_shards":
            job.active_shards,
            "start_timestamp_ms":
            int(time.mktime(job.start_time.utctimetuple()) * 1000),
            "updated_timestamp_ms":
            int(time.mktime(job.last_poll_time.utctimetuple()) * 1000),
            "chart_url":
            job.chart_url,
            "chart_width":
            job.chart_width,
        })
        self.json_response["result_status"] = job.result_status

        all_shards = []
        for shard in model.ShardState.find_all_by_mapreduce_state(job):
            out = {
                "active":
                shard.active,
                "result_status":
                shard.result_status,
                "shard_number":
                shard.shard_number,
                "shard_id":
                shard.shard_id,
                "updated_timestamp_ms":
                int(time.mktime(shard.update_time.utctimetuple()) * 1000),
                "shard_description":
                shard.shard_description,
                "last_work_item":
                shard.last_work_item,
            }
            out.update(shard.counters_map.to_json())
            all_shards.append(out)
        all_shards.sort(key=lambda x: x["shard_number"])
        self.json_response["shards"] = all_shards
예제 #18
0
    def _send_push(self):
        from models.config.config import config

        logging.debug(
            "data:{}, dev_type: {}, parsekey: {}, parserest: {}".format(
                self.data, self.device_type, config.PARSE_APP_API_KEY,
                config.PARSE_REST_API_KEY))
        if not self.data or self.device_type not in DEVICE_CHOICES or not config.PARSE_APP_API_KEY or not config.PARSE_REST_API_KEY:
            logging.warning(
                u'Невозможно послать уведомление, data=%s, device_type=%s' %
                (self.data, self.device_type))
            return
        payload = {
            'channels':
            self.channels,
            'type':
            DEVICE_TYPE_MAP[self.device_type],
            'expiry':
            timestamp(datetime.datetime.utcnow() +
                      datetime.timedelta(days=365)),
            'data':
            self.data,
        }
        headers = {
            'Content-Type': 'application/json',
            'X-Parse-Application-Id': config.PARSE_APP_API_KEY,
            'X-Parse-REST-API-Key': config.PARSE_REST_API_KEY
        }
        logging.debug(headers)
        try:
            result = json.loads(
                urlfetch.fetch('https://api.parse.com/1/push',
                               payload=json.dumps(payload),
                               method='POST',
                               headers=headers,
                               validate_certificate=False,
                               deadline=10).content)
            logging.info(result)

            if result and (result.get('code') or result.get('error')):
                text = u'Namespace = %s\nCode = %s, Error = %s' % (
                    namespace_manager.get_namespace(), result.get('code'),
                    result.get('error'))
                send_error('push', u'Ошибка Parse', text)
        except Exception as e:
            text = str(e)
            send_error('push', u'Parse упал', text)
            result = None
        return result
예제 #19
0
 def post(self):
     rights = []
     for right in CompanyUser.ALL_RIGHTS_BITS:
         confirmed = self.request.get(str(right))
         if confirmed:
             rights.append(right)
     login = self.request.get('login')
     values = {
         'namespace': namespace_manager.get_namespace(),
         'login': login,
         'password_raw': self.request.get('password'),
         'rights': CompanyUser.make_mask(rights),
     }
     namespace_manager.set_namespace('')
     success, user = CompanyUser.create_user(login, **values)
     self.redirect('/company/user/list')
예제 #20
0
 def post(self):
     order_id = int(self.request.get('order_id'))
     order = Order.get_by_id(order_id)
     if not order:
         self.abort(400)
     elif order.status != NEW_ORDER:
         self.response.status_int = 412
         self.render_json({
             'error': 1,
             'description': u'Заказ уже выдан или отменен'
         })
     else:
         now = datetime.utcnow()
         if now - order.date_created < timedelta(seconds=config.CANCEL_ALLOWED_WITHIN) or \
                 order.delivery_time - now > timedelta(minutes=config.CANCEL_ALLOWED_BEFORE):
             success = cancel_order(order, CANCELED_BY_CLIENT_ORDER,
                                    namespace_manager.get_namespace())
             if success:
                 reason_id = self.request.get('reason_id')
                 if reason_id:
                     reason_id = int(reason_id)
                     if reason_id in CONFUSED_CHOICES:
                         order.cancel_reason = reason_id
                     if reason_id == CONFUSED_OTHER:
                         order.cancel_reason_text = self.request.get(
                             'reason_text')
                     order.put()
                 self.render_json({'error': 0, 'order_id': order.key.id()})
                 logging.info(u'заказ %d отменен' % order_id)
             else:
                 self.response.status_int = 422
                 self.render_json({
                     'error':
                     1,
                     'description':
                     u'При отмене возникла ошибка'  # todo: change this text
                 })
         else:
             self.response.status_int = 412
             self.render_json({
                 'error':
                 1,
                 'description':
                 u'Отмена заказа невозможна, так как до его исполнения осталось менее %s минут.'
                 % config.CANCEL_ALLOWED_BEFORE
             })
예제 #21
0
 def get_venues_by_company(self, company, location=None):
     from methods import location as location_methods
     from models import Venue
     init_namespace = namespace_manager.get_namespace()
     venues = []
     namespace_manager.set_namespace(company.namespace)
     for venue in Venue.query(Venue.active == True).fetch():
         if venue.address.city == self.city:
             venue.company_id = company.key.id
             venues.append(venue)
             if location:
                 venue.distance = location_methods.distance(
                     location, venue.coordinates)
     if location:
         venues = sorted(venues, key=lambda venue: venue.distance)
     namespace_manager.set_namespace(init_namespace)
     return venues
예제 #22
0
def _refresh_client_info(request,
                         response,
                         android_id,
                         device_phone,
                         client_id=None,
                         city_id=None):
    def refresh(client):
        client.user_agent = request.headers["User-Agent"]
        if 'iOS' in client.user_agent:
            client.device_type = IOS_DEVICE
        elif 'Android' in client.user_agent:
            client.device_type = ANDROID_DEVICE
        if android_id:
            client.android_id = android_id
        if device_phone and not client.tel:
            client.tel = device_phone
        if client.city and client.city.id() == city_id:
            response['show_cities'] = False
        else:
            response['show_cities'] = True
        if city_id:
            save_city(client, city_id)
        client.put()
        client.save_session()

    current_namespace = namespace_manager.get_namespace()
    client = None
    if client_id:
        if request.init_namespace:
            namespace_manager.set_namespace(request.init_namespace)
        client = Client.get(client_id)
    if not client:
        client = Client.create()
        client_id = client.key.id()
    refresh(client)
    if request.init_namespace and not Client.is_id_global(client_id):
        namespace_manager.set_namespace(request.init_namespace)
        for company in AutomationCompany.query(
                AutomationCompany.status == STATUS_AVAILABLE).fetch():
            namespace_manager.set_namespace(company.namespace)
            other_client = Client.get(client_id)
            if not other_client:
                other_client = Client.create(client_id)
            refresh(other_client)
    namespace_manager.set_namespace(current_namespace)
    return client
예제 #23
0
  def handle(self):
    mapreduce_id = self.request.get("mapreduce_id")
    if not mapreduce_id:
      raise BadStatusParameterError("'mapreduce_id' was invalid")
    job = model.MapreduceState.get_by_key_name(mapreduce_id)
    if job is None:
      raise KeyError("Could not find job with ID:%r in namespace:%s" %
                     (mapreduce_id, namespace_manager.get_namespace()))

    self.json_response.update(job.mapreduce_spec.to_json())
    self.json_response.update(job.counters_map.to_json())
    self.json_response.update({

        "active": job.active,
        "active_shards": job.active_shards,
        "start_timestamp_ms":
            int(time.mktime(job.start_time.utctimetuple()) * 1000),
        "updated_timestamp_ms":
            int(time.mktime(job.last_poll_time.utctimetuple()) * 1000),


        "chart_url": job.chart_url,
        "chart_width": job.chart_width,
    })
    self.json_response["result_status"] = job.result_status

    all_shards = []
    for shard in model.ShardState.find_all_by_mapreduce_state(job):
      out = {
          "active": shard.active,
          "result_status": shard.result_status,
          "shard_number": shard.shard_number,
          "shard_id": shard.shard_id,
          "updated_timestamp_ms":
              int(time.mktime(shard.update_time.utctimetuple()) * 1000),
          "shard_description": shard.shard_description,
          "last_work_item": shard.last_work_item,
      }
      out.update(shard.counters_map.to_json())
      all_shards.append(out)
    all_shards.sort(key=lambda x: x["shard_number"])
    self.json_response["shards"] = all_shards
예제 #24
0
파일: __init__.py 프로젝트: AmirS2/tipfy
def run_in_namespace(namespace, function, *args, **kwargs):
    """Executes a function in a given namespace, then returns back to the
    current namescape.

    :param namespace:
        Name of the namespace to run the function.
    :param function:
        Function to be executed in the given namespace.
    :param args:
        Arguments to be passed to the function.
    :param kwargs:
        Keyword arguments to be passed to the function.
    """
    current_namespace = namespace_manager.get_namespace()
    try:
        namespace_manager.set_namespace(namespace)
        return function(*args, **kwargs)
    finally:
        # Restore previous namespace.
        namespace_manager.set_namespace(current_namespace)
예제 #25
0
def run_in_namespace(namespace, function, *args, **kwargs):
    """Executes a function in a given namespace, then returns back to the
    current namescape.

    :param namespace:
        Name of the namespace to run the function.
    :param function:
        Function to be executed in the given namespace.
    :param args:
        Arguments to be passed to the function.
    :param kwargs:
        Keyword arguments to be passed to the function.
    """
    current_namespace = namespace_manager.get_namespace()
    try:
        namespace_manager.set_namespace(namespace)
        return function(*args, **kwargs)
    finally:
        # Restore previous namespace.
        namespace_manager.set_namespace(current_namespace)
예제 #26
0
 def get_items(self, city, available_venues=None):
     from models import MenuItem
     init_namespace = namespace_manager.get_namespace()
     items = []
     for company in AutomationCompany.query(
             AutomationCompany.status == STATUS_AVAILABLE).fetch():
         venues = city.get_venues_by_company(company)
         namespace_manager.set_namespace(company.namespace)
         for item in MenuItem.query(
                 MenuItem.status == STATUS_AVAILABLE).fetch():
             item.venues = []
             for venue in venues:
                 if venue.key in item.restrictions:
                     continue
                 if available_venues and venue not in available_venues:
                     continue
                 if self.compare(item):
                     item.venues.append(venue)
                     items.append(item)
     namespace_manager.set_namespace(init_namespace)
     return items
예제 #27
0
 def post(self):
     login, password, password2 = \
         self.request.get("email").strip().lower(), \
         self.request.get("password"), self.request.get("password2")
     venue_id = self.request.get_range("venue_id", default=-1)
     venue_ids = {v.key.id(): v.key for v in self.venues}
     error = None
     if not login:
         error = u"Не введен логин"
     elif not password:
         error = u"Не введен пароль"
     elif password != password2:
         error = u"Пароли не совпадают"
     elif venue_id and venue_id not in venue_ids:
         error = u"Неправильно выбрана кофейня"
     else:
         company_namespace = namespace_manager.get_namespace()
         venue_key = venue_ids.get(venue_id, None)
         values = {
             'login': login,
             'namespace': company_namespace,
             'venue': venue_key,
             'password_raw': password
         }
         namespace_manager.set_namespace('')
         success, user = Admin.create_user(login, **values)
         if success:
             namespace_manager.set_namespace(company_namespace)
             success, user = Admin.create_user(login, **values)
             if success:
                 logging.info(user)
         else:
             error = u"Пользователь с этим email уже зарегистрирован"
     if error:
         self.render('/barista/signup.html',
                     email=login,
                     error=error,
                     venue_id=venue_id)
     else:
         self.success()
예제 #28
0
 def post(self, admin_id):
     admin_id = int(admin_id)
     admin = Admin.get_by_id(admin_id)
     if not admin:
         self.abort(500)
     company_namespace = namespace_manager.get_namespace()
     namespace_manager.set_namespace('')
     login = admin.login
     admin = Admin.query(Admin.login == login).get()
     if not admin:
         self.abort(500)
     login = self.request.get('login').strip().lower()
     values = {
         'login': login,
         'venue': admin.venue,
         'namespace': admin.namespace,
         'deposit_history': admin.deposit_history
     }
     success, info = Admin.create_user(login, **values)
     if success:
         info.password = admin.password
         info.put()
         admin.delete_auth_ids()
         admin.key.delete()
         namespace_manager.set_namespace(company_namespace)
         admin = Admin.get_by_id(admin_id)
         if not admin:
             self.abort(500)
         success, info = Admin.create_user(login, **values)
         if success:
             info.password = admin.password
             info.put()
             admin.delete_auth_ids()
             admin.key.delete()
         self.redirect_to('barista_main')
     else:
         self.render('/barista/change_login.html',
                     admin=admin,
                     error=u'Логин занят')
예제 #29
0
def apply_module(module, all_clients):
    if not module or not module.status:
        return

    clients, texts = get_clients_and_texts_by_module_logic(module, all_clients)

    for client, text in izip(clients, texts):

        if should_sms(module, client):
            deferred.defer(send_sms, [client.tel], text)
            ClientSmsSending(client=client.key, sms_type=module.type).put()

        if should_push(module):
            push = SimplePush(text=module.text,
                              header=module.header,
                              full_text=text,
                              client=client,
                              namespace=namespace_manager.get_namespace(),
                              should_popup=True,
                              push_id=module.type)

            deferred.defer(push.send)
            ClientPushSending(client=client.key, type=module.type).put()
예제 #30
0
    def get(self):
        venues = Venue.fetch_venues()
        for venue in venues:
            admin = Admin.query(Admin.venue == venue.key).get()
            if admin:
                continue

            ru = u'абвгдеёжзийклмнопрстуфхцчшщъыьэюя'
            en = u'abvgdeegziyklmnoprstufhzcss_y_eua'
            trans_dict = dict(zip(ru, en))

            login_rus = [
                c for c in venue.title.lower()
                if 'a' <= c <= 'z' or u'а' <= c <= u'я'
            ]
            login_en = ''.join(trans_dict.get(c, c) for c in login_rus)

            company_namespace = namespace_manager.get_namespace()

            auth_id = login_en
            values = {
                'login': login_en,
                'venue': venue.key,
                'namespace': company_namespace,
                'password_raw': '0000'
            }
            namespace_manager.set_namespace('')
            success, info = Admin.create_user(auth_id, **values)
            namespace_manager.set_namespace(company_namespace)
            if success:
                success, info = Admin.create_user(auth_id, **values)
                if success:
                    logging.info(info)
            if not success:
                self.abort(500)
        self.redirect_to("barista_main")
예제 #31
0
def _get_filename(model_name, id, uniq):
    tmstmp = timestamp(datetime.utcnow())
    return '/%s/%s/%s/%s/%s/%s' % (_BUCKET, namespace_manager.get_namespace(),
                                   model_name, id, uniq, tmstmp)
예제 #32
0
    def post(self):
        if config.COMPANY_STATUS == COMPANY_REMOVED:
            return self.render_error(
                u'К сожалению, компания больше не принимает заказы через мобильное приложение'
            )
        elif config.COMPANY_STATUS == COMPANY_PREVIEW:
            return self.render_error(
                u'К сожалению, компания пока не принимает заказы через мобильное приложение'
            )

        order_json = json.loads(self.request.get('order'))

        order_id, self.cache_key = get_order_id(order_json)
        if not order_id:
            self.abort(409)
        self.order = Order(id=order_id,
                           unified_app_namespace=self.request.init_namespace)
        self.order.version = int(self.request.headers.get('Version', 0))
        self.order.number = order_id

        success = check_items_and_gifts(order_json)
        if not success:
            return self.render_error(u'Выберите что-нибудь')

        self.order.delivery_type = int(order_json.get('delivery_type'))

        venue = None
        delivery_zone = None
        address_json = order_json.get('address')
        if self.order.delivery_type in [SELF, IN_CAFE, PICKUP]:
            venue_id = order_json.get('venue_id')
            if not venue_id:
                return self.render_error(
                    u"Произошла ошибка. Попробуйте заново выбрать точку.")
            venue = Venue.get(venue_id)
            if not venue:
                return self.render_error(u"Кофейня не найдена")
        elif self.order.delivery_type in [DELIVERY]:
            if address_json:
                address_json = validate_address(address_json)
                venue, delivery_zone = get_venue_and_zone_by_address(
                    address_json)
        if delivery_zone:
            self.order.delivery_zone = delivery_zone.key
        self.order.venue_id = str(venue.key.id())

        if address_json:
            set_address_obj(address_json, self.order)

        coordinates = order_json.get('coordinates')
        if coordinates:
            self.order.coordinates = GeoPt(coordinates)

        self.order.comment = order_json['comment']
        self.order.device_type = order_json.get('device_type', IOS_DEVICE)

        if config.SMS_CONFIRMATION_MODULE and config.SMS_CONFIRMATION_MODULE.status == STATUS_AVAILABLE:
            confirm_by_sms = order_json.get('confirm_by_sms')
            if confirm_by_sms:
                self.order.comment = u"Клиенту нужно отправить СМС-подтверждение. " + self.order.comment
            else:
                self.order.comment = u"Клиент просит перезвонить. " + self.order.comment


        self.order.delivery_slot_id = int(order_json.get('delivery_slot_id')) \
            if order_json.get('delivery_slot_id') else None
        if self.order.delivery_slot_id > 0:
            delivery_slot = DeliverySlot.get_by_id(self.order.delivery_slot_id)
            if not delivery_slot:
                return self.render_error(u'Неправильный формат времени')
        else:
            delivery_slot = None

        delivery_time_minutes = order_json.get(
            'delivery_time')  # used for old versions todo: remove
        if delivery_time_minutes:  # used for old versions todo: remove
            delivery_time_minutes = int(
                delivery_time_minutes)  # used for old versions todo: remove
        delivery_time_picker = order_json.get('time_picker_value')

        self.order.delivery_time = get_delivery_time(delivery_time_picker,
                                                     venue, delivery_slot,
                                                     delivery_time_minutes)
        if not self.order.delivery_time:
            return self.render_error(u'Неправильный формат времени')

        self.order.total_sum = float(order_json.get("total_sum"))
        self.order.delivery_sum = int(order_json.get('delivery_sum', 0))

        client = set_client_info(order_json.get('client'),
                                 self.request.headers)
        if not client:
            return self.render_error(
                u'Неудачная попытка авторизации. Попробуйте позже')
        self.order.client_id = client.key.id()
        self.order.user_agent = self.request.headers["User-Agent"]

        self.order.payment_type_id = order_json['payment']['type_id']
        payment_type = PaymentType.get(self.order.payment_type_id)
        if payment_type.status == STATUS_UNAVAILABLE:
            return self.render_error(u"Выбранный способ оплаты недоступен.")

        self.order.wallet_payment = order_json['payment'].get(
            'wallet_payment', 0)

        # todo: it can be checked in validation
        extra_fields = order_json.get('extra_order_field', {})
        if not extra_fields:
            try:
                extra_fields = json.loads(
                    self.request.get('extra_order_field'))
            except:
                pass
        num_people = order_json.get('num_people')
        cash_change = order_json.get('cash_change')
        set_extra_order_info(self.order, extra_fields, num_people, cash_change)

        if check_after_error(order_json, client):
            return self.render_error(
                u"Этот заказ уже зарегистрирован в системе, проверьте историю заказов."
            )

        conf = config
        if conf.ORDER_MESSAGE_MODULE:
            message = conf.ORDER_MESSAGE_MODULE.get_message(self.order)
        else:
            message = u'Заказ отправлен'

        if config.APP_KIND == RESTO_APP:
            success, response = resto_place_order(
                client, venue, self.order, order_json['payment'],
                order_json['items'], order_json.get('order_gifts', []),
                order_json.get('cancelled_order_gifts', []))
            if success:
                response['message'] = message
                send_client_sms_task(self.order,
                                     namespace_manager.get_namespace())
                return self.render_json(response)
            else:
                return self.render_error(response['description'])

        if config.APP_KIND == DOUBLEB_APP:
            success, response = doubleb_place_order(self.order, client, venue,
                                                    order_json['items'],
                                                    order_json['payment'])
            if success:
                response['message'] = message
                send_client_sms_task(self.order,
                                     namespace_manager.get_namespace())
                return self.render_json(response)
            else:
                return self.render_error(response['description'])

        items = order_json['items']
        gifts = order_json.get('gifts', [])

        # todo убрать через ~2 месяца - в июне
        items, gifts = fuckup_move_items_to_gifts(items, gifts)

        # it is need, because item_id and gift_id are swapping
        gifts_copy = copy.deepcopy(gifts)

        validation_result = validate_order(
            client, items, gifts, order_json.get('order_gifts', []),
            order_json.get('cancelled_order_gifts', []), order_json['payment'],
            venue, address_json, self.order.delivery_time, delivery_slot,
            self.order.delivery_type, delivery_zone, True)

        success, error = after_validation_check(validation_result, self.order)
        if not success:
            return self.render_error(error)

        if self.order.delivery_sum:
            self.order.total_sum += self.order.delivery_sum

        self.order.item_details = validation_result["details"]

        self.order.order_gift_details = validation_result["order_gift_details"]

        self.order.shared_gift_details = validation_result[
            'share_gift_details']

        self.order.promos = [
            ndb.Key('Promo', promo['id'])
            for promo in validation_result["promos"]
        ]
        self.order.delivery_time_str = validation_result['delivery_time']

        self.order.status = CREATING_ORDER
        self.order.put()

        payment_amount = int(
            (self.order.total_sum - self.order.wallet_payment) * 100)

        if self.order.payment_type_id == CARD_PAYMENT_TYPE and payment_amount > 0:
            success, error = card_payment_performing(order_json['payment'],
                                                     payment_amount,
                                                     self.order)
            if not success:
                return self.render_error(error)
        elif self.order.payment_type_id == PAYPAL_PAYMENT_TYPE and payment_amount > 0:
            success, error = paypal_payment_performing(order_json['payment'],
                                                       payment_amount,
                                                       self.order, client)
            if not success:
                return self.render_json(error)

        subscription = get_subscription(client)
        if subscription:
            amount = get_amount_of_subscription_items(items)
        else:
            amount = 0
        if subscription and amount:
            success = subscription.deduct(amount)
            if success:
                self.order.subscription_details = SubscriptionDetails(
                    subscription=subscription.key, amount=amount)
            else:
                return self.render_json(
                    u'Не удалось произвести покупку по абонементу')

        if self.order.wallet_payment > 0:
            empatika_wallet.pay(client.key.id(), self.order.key.id(),
                                int(self.order.wallet_payment * 100))

        gift_details = []

        for gift_detail in validation_result['gift_details']:
            gift_item = gift_detail.gift.get()
            activation_dict = empatika_promos.activate_promo(
                client.key.id(), gift_item.promo_id, 1)
            gift_detail.activation_id = activation_dict['activation']['id']
            gift_details.append(gift_detail)
        self.order.gift_details = gift_details

        for shared_gift_detail in self.order.shared_gift_details:
            gift = shared_gift_detail.gift.get()
            gift.put_in_order()

        # use only gifts_copy, not response_json.get('gifts', [])
        # it is used for creating db for promos
        validate_order(client, items, gifts_copy,
                       order_json.get('order_gifts', []),
                       order_json.get('cancelled_order_gifts',
                                      []), order_json['payment'], venue,
                       address_json, self.order.delivery_time, delivery_slot,
                       self.order.delivery_type, delivery_zone, False,
                       self.order)

        self.order.status = NEW_ORDER
        self.order.put()

        send_venue_sms(venue, self.order)
        send_venue_email(venue,
                         self.order,
                         self.request.host_url,
                         self.jinja2,
                         format_type=config.ORDER_EMAIL_FORMAT_TYPE)
        if config.SUSHINSON_EMAIL_MODULE and config.SUSHINSON_EMAIL_MODULE.status == STATUS_AVAILABLE:
            config.SUSHINSON_EMAIL_MODULE.send(self.order, self.jinja2)
        send_client_sms_task(self.order, namespace_manager.get_namespace())
        if CURRENT_APP_ID == DEMO_APP_ID:
            send_demo_sms(client)
        if config.BITRIX_EXT_API_MODULE and config.BITRIX_EXT_API_MODULE.status == STATUS_AVAILABLE:
            taskqueue.add(url=self.uri_for('bitrix_export_task'),
                          params={'order_id': order_id})

        self.response.status_int = 201

        self.render_json({
            'order_id':
            self.order.key.id(),
            'number':
            self.order.number,
            'delivery_time':
            validation_result['delivery_time'],
            'delivery_slot_name':
            validation_result['delivery_slot_name'],
            'show_share':
            need_to_show_share_invitation(client),
            'message':
            message
        })
예제 #33
0
def _perform_registration(request):
    response = {}

    try:
        client_id = request.get_range('client_id') or int(
            request.headers.get('Client-Id') or 0)
    except ValueError:
        client_id = 0
    android_id = request.get('android_id')
    device_phone = request.get('device_phone')
    location = get_location(request.get("ll"))

    city_id = None
    if location:
        candidates = get_cities_by_coordinates(location.lat, location.lon)
        if candidates:
            city_id = ProxyCity.get_city_id(candidates[0]['address']['city'])
            if city_id:
                response['location_city_id'] = str(city_id)

    client = None
    client_existed = False
    if client_id:
        client = Client.get(client_id)
    elif android_id:
        client = Client.find_by_android_id(android_id)
        if client:
            client_id = client.key.id()
    if client:
        client_existed = True
    else:
        client_id = None

    client = _refresh_client_info(request,
                                  response,
                                  android_id,
                                  device_phone,
                                  client_id,
                                  city_id=city_id)

    response['client_id'] = client.key.id()
    client_name = client.name or ''
    if client.surname:
        client_name += ' ' + client.surname
    response['client_name'] = client_name
    response['client_email'] = client.email or ''

    share_data = request.get('share_data')

    if share_data:
        share_data = json.loads(share_data)
        share_id = share_data.get('share_id')
        if share_id:
            share = Share.get_by_id(int(share_id))
            response["share_type"] = share.share_type
            if share.share_type == INVITATION:
                if not client_existed or \
                        (not Order.query(Order.client_id == client_id).get() and client.key.id() != share.sender.id()):
                    promo = SharedPromo.query(
                        SharedPromo.recipient == client.key).get()
                    if not promo:
                        SharedPromo(sender=share.sender,
                                    recipient=client.key,
                                    share_id=share.key.id()).put()
            elif share.share_type == GIFT:
                if share.status == Share.ACTIVE:
                    gift = SharedGift.query(
                        SharedGift.share_id == share.key.id()).get()
                    if gift.status == SharedGift.READY:
                        gift.perform(client, namespace_manager.get_namespace())
                    response['branch_name'] = share_data.get('name')
                    response['branch_phone'] = share_data.get('phone')
    return response, client