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
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
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
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()
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)
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'Заказ успешно подтвержден')
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)
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'Заказ успешно выдан!')
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)
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'Заказ успешно отменен!')
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
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)
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)
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()
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
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
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
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')
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 })
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
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
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
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)
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)
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
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()
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'Логин занят')
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()
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")
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)
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 })
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