def _handle(order_id): from methods.orders.change import do_load order = Order.order_by_id(order_id) logging.info('searching for move, number %s, id %s', order.number, order.order_id) try: customer = order.customer.get() company = CompanyNew.get_by_iiko_id(order.venue_id) orders = get_orders(company, date.today(), date.today()) for iiko_order in orders['deliveryOrders']: if iiko_order['number'] == order.number \ and iiko_order['customer']['phone'][-10:] == customer.phone[-10:] \ and Order.parse_status(iiko_order['status']) != Order.CANCELED: logging.info("found move: %s" % iiko_order['orderId']) logging.info(iiko_order) order.order_id = iiko_order['orderId'] do_load(order, order.order_id, order.venue_id, iiko_order) break else: if order.payment_type == PaymentType.CARD: message = u"№ заказа: %s<br/>" \ u"Сумма: %s<br/>" \ u"Клиент: %s %s<br/>" \ u"ID платежа: %s" % (order.number, order.initial_sum, customer.phone, customer.name, order.alfa_order_id) mandrill.send_email( "*****@*****.**", ["*****@*****.**"], ["*****@*****.**", "*****@*****.**"], u"[ОЭ] Отмена заказа с безналичной оплатой", message) send_order_status_push(order) except Exception as e: send_error("order", "OE move checker: exception on %s" % order.number, repr(e))
def get(self): now = datetime.datetime.now() delta = datetime.timedelta(minutes=MINUTES_INTERVAL) orders = Order.query(Order.status == Order.CREATING, Order.created <= now - delta).fetch() if orders: infos = [] for order in orders: info = [("id", order.order_id), ("payment type", order.payment_type), ("payment id", order.alfa_order_id)] to_delete = False iiko_order = order_info1(order.order_id, order.venue_id) if 'httpStatusCode' not in iiko_order: info.append(('found', True)) order.load_from_object(iiko_order) else: if order.payment_type == PaymentType.CARD: try: company = CompanyNew.get_by_iiko_id(order.venue_id) delivery_terminal = DeliveryTerminal.get_by_id(order.delivery_terminal_id) \ if order.delivery_terminal_id else None # check payment status status = alfa_bank.check_extended_status( company, delivery_terminal, order.alfa_order_id)["alfa_response"] info.append(("status check result", status)) # if status check was successful: if str(status.get("errorCode", '0')) == '0': # money already deposited -- do not delete if status['orderStatus'] == 2: info.append(("ERROR", "deposited")) # money approved -- reverse elif status['orderStatus'] == 1: reverse_result = alfa_bank.get_back_blocked_sum( company, delivery_terminal, order.alfa_order_id) info.append( ("reverse result", reverse_result)) if str(reverse_result.get( 'errorCode', '0')) == '0': to_delete = True # any other status is OK to delete else: to_delete = True except Exception as e: info.append(("exception", repr(e))) else: to_delete = True if to_delete: order.key.delete() info.append(("deleted", True)) infos.append(info) mail_body = "Orders with creating status\n" mail_body += "List of orders:\n" + \ "\n\n".join("\n".join("%s: %s" % t for t in info) for info in infos) admin.send_error("order", "Orders crashed while creating", mail_body)
def deactivate(self, company): from methods.parse_com import send_order_screen_push from methods.iiko.customer import get_customer_by_phone, create_or_update_customer recipient = self.recipient.get() iiko_customer = get_customer_by_phone(company, recipient.phone) if 'httpStatusCode' in iiko_customer: iiko_customer = {'phone': recipient.phone, 'balance': 0} iiko_customer['balance'] += company.invitation_settings.recipient_value create_or_update_customer(company, iiko_customer) sender = self.sender.get() iiko_customer = get_customer_by_phone(company, sender.phone) if 'httpStatusCode' in iiko_customer: iiko_customer = {'phone': sender.phone, 'balance': 0} iiko_customer['balance'] += company.invitation_settings.sender_value create_or_update_customer(company, iiko_customer) self.status = self.DONE self.put() send_order_screen_push( Order.query( Order.customer == self.recipient).order(-Order.date).get(), u'Вам начислены бонусы: %s! Спасибо, что заказываете у нас!' % company.invitation_settings.recipient_value, head=company.app_title) send_order_screen_push( Order.query( Order.customer == self.sender).order(-Order.date).get(), u'Вам начислены бонусы за приглашенного друга: %s!' % company.invitation_settings.sender_value, head=company.app_title) send_error( 'share', 'Invitation success', "Sender: %s, recipient: %s" % (sender.phone, recipient.phone))
def send_sms(from_, to, text): data = { 'apikey': SMSPILOT_API_KEY, 'send': [{ 'from': from_, 'to': phone, 'text': text } for phone in to] } response = urlfetch.fetch("http://smspilot.ru/api2.php", payload=json.dumps(data), method='POST', headers={ 'Content-Type': 'application/json' }).content logging.info(response) result = json.loads(response) success = "send" in result for message in result.get("send", []): if message["status"] != "0": success = False if not success: admin.send_error("sms", "SMS failure", response) return success, json.loads(response)
def _request(path, params): url = '%s%s' % (BASE_URL, path) response = urlfetch.fetch(url, method='POST', payload=urllib.urlencode(params), deadline=10) if response.status_code >= 400: body = "\n".join( (str(response.status_code), url, str(params), response.content)) logging.error(body) send_error('auto', 'Error in automation request', body)
def handle_500(request, response, exception): body = """URL: %s User-Agent: %s Exception: %s Logs: https://appengine.google.com/logs?app_id=s~%s&severity_level_override=0&severity_level=3""" \ % (request.url, request.headers['User-Agent'], exception, _APP_ID) if isinstance(exception, DeadlineExceededError) and ":9900/" in exception.message: send_error("iiko", "iiko deadline", body) else: send_error("server", "Error 500", body) exc_info = sys.exc_info() raise exc_info[0], exc_info[1], exc_info[2]
def post(self, delivery_terminal_id): logging.info(self.request.POST) custom_data = None try: custom_data = json.loads(self.request.get('custom_data')) except ValueError: pass bonus_sum = self.request.get('bonus_sum') bonus_sum = float(bonus_sum) if bonus_sum else 0.0 discount_sum = self.request.get('discount_sum') discount_sum = float(discount_sum) if discount_sum else 0.0 customer_id = self.request.get('customer_id') or self.request.get( 'customerId') address = self.request.get('address') comment = self.request.get('comment') binding_id = self.request.get('binding_id') alpha_client_id = self.request.get('alpha_client_id') source = self.request.get('source') delivery_terminal = DeliveryTerminal.get_by_id(delivery_terminal_id) if delivery_terminal: org_id = delivery_terminal.iiko_organization_id else: org_id = delivery_terminal_id company = CompanyNew.get_by_iiko_id(org_id) if not delivery_terminal: delivery_terminal = DeliveryTerminal.get_any(company.iiko_org_id) delivery_terminal_id = delivery_terminal.key.id() response_delivery_terminal_id = delivery_terminal_id customer = get_resto_customer(company, customer_id) set_customer_info(company, customer, self.request.get('name').strip(), self.request.headers, filter_phone(self.request.get('phone')), custom_data) update_customer_id(company, customer) self.order = order = iiko.Order() order.order_id = self.request.get('id') or str(uuid.uuid4()) if source == AUTO_APP_SOURCE: if not company.auto_token: send_error( "order", u"Компания %s не настроена для работы с автоматизацией" % company.app_title, "") return self.send_error( u"Неизвестная системная ошибка, попробуйте позже") order.source = source order.date = datetime.datetime.utcfromtimestamp( int(self.request.get('date'))) order.payment_type = self.request.get('paymentType') str_date = self.request.get('str_date') if str_date: parsed_str_date = parse_str_date(str_date) if parsed_str_date: order.date = parsed_str_date - datetime.timedelta( seconds=company.get_timezone_offset()) else: logging.warning("Failed to parse str_date: %s", str_date) order.date = datetime.datetime.now() + datetime.timedelta( hours=1) if order.date < datetime.datetime.utcnow() and \ ('/2.0 ' in self.request.user_agent or '/2.0.1' in self.request.user_agent): logging.info('new date(str): %s' % order.date) order.date += datetime.timedelta(hours=12) logging.info("ios v2.0 fuckup, adding 12h: %s", order.date) send_confirmation_sms = False if company.iiko_org_id in (CompanyNew.EMPATIKA, CompanyNew.ORANGE_EXPRESS): confirm_by_phone = self.request.get("confirm_by_phone") if confirm_by_phone == "1": comment = u"Клиент просит перезвонить. " + comment elif confirm_by_phone == "0": comment = u"Клиенту будет отправлено СМС-подтверждение. " + comment send_confirmation_sms = True else: pass # old version order.delivery_terminal_id = delivery_terminal_id order.venue_id = company.iiko_org_id gifts = json.loads( self.request.get('gifts')) if self.request.get('gifts') else [] order.customer = customer.key items = prepare_items(company, json.loads(self.request.get('items'))) order.items = items order.initial_sum = order.sum = calc_sum(items, company.iiko_org_id) logging.info("calculated sum: %s, app sum: %s", order.sum, self.request.get('sum')) if company.iiko_org_id in (CompanyNew.DIMASH, CompanyNew.CHAIHANA_LOUNGE): if 'Android' in self.request.user_agent: comment = u"Заказ с Android. " + comment else: comment = u"Заказ с iOS. " + comment is_repeated_order = None if company.iiko_org_id in _FIRST_ORDER_COMMENTS: comment_first, comment_repeated = _FIRST_ORDER_COMMENTS[ company.iiko_org_id] is_repeated_order = orders_exist_for_phone(customer.phone) comment = (comment_repeated if is_repeated_order else comment_first) + comment order.comment = comment delivery_type = self.request.get_range('deliveryType') order.is_delivery = delivery_type == DeliveryType.DELIVERY if order.is_delivery: if not address: self.abort(400) try: order.address = json.loads(address) prepare_address(order) except Exception as e: logging.exception(e) self.abort(400) order.delivery_type = None for company_delivery_type in company.delivery_types: company_delivery_type = company_delivery_type.get() if company_delivery_type.delivery_id == delivery_type: order.delivery_type = company_delivery_type if order.venue_id == CompanyNew.KUKSU: kuksu_delivery.check_and_add_delivery(company, order) # this resets order.delivery_terminal_id if it is delivery (not takeout) order_dict = prepare_order(order, customer, order.payment_type) if delivery_terminal_id != order.delivery_terminal_id: delivery_terminal_id = order.delivery_terminal_id delivery_terminal = DeliveryTerminal.get_by_id(delivery_terminal_id) \ if delivery_terminal_id else None validation_result = validate_order(company, delivery_terminal, order, customer) if not validation_result['valid']: return self.send_error(validation_result['errors'][0]) pre_check_result = pre_check_order(company, order_dict) if 'code' in pre_check_result: logging.warning('iiko pre check failed') msg = pre_check_result["description"] or pre_check_result["message"] send_error("iiko", "iiko pre check failed", msg) self.abort(400) order.discount_sum = 0.0 order.bonus_sum = 0.0 if company.is_iiko_system: create_or_update_customer(company, {'phone': customer.phone}) success = set_discounts_bonuses_gifts(order, order_dict, discount_sum, bonus_sum, gifts) if not success: self.abort(409) order.sum -= order.bonus_sum + order.discount_sum elif company.iiko_org_id == CompanyNew.CHAIHANA_LOUNGE: assert is_repeated_order is not None if is_repeated_order: order.discount_sum = 0.05 * order.sum else: order.discount_sum = 0.25 * order.sum if order.payment_type == PaymentType.COURIER_CARD: for payment in order_dict['order']['paymentItems']: if payment['paymentType']['code'] == 'CARD': payment['sum'] -= order.discount_sum if order.payment_type == PaymentType.CASH and not order.is_delivery: payments_list = order_dict['order']['paymentItems'] for payment in payments_list: if payment['paymentType']['code'] == 'CASH': payments_list.remove(payment) break # pay after pre check if order.payment_type == PaymentType.CARD: binding_id = check_binding_id(company, alpha_client_id, binding_id) success, result = create_payment(company, delivery_terminal, order, alpha_client_id) if not success: self.send_error(result) return order.alfa_order_id = result order.put() success, result = perform_payment(company, delivery_terminal, order, order_dict, order.alfa_order_id, binding_id) if not success: self.send_error(u"Не удалось произвести оплату. " + result) return result = place_order(company, order_dict) if 'code' in result.keys(): logging.error('iiko failure') if order.payment_type == PaymentType.CARD: # return money return_result = get_back_blocked_sum(company, delivery_terminal, order.alfa_order_id) logging.info('return') logging.info(return_result) msg = result["description"] or result["message"] send_error("iiko", "iiko place order failed", msg) self.response.set_status(400) return self.render_json(result) customer.customer_id = result['customerId'] customer.put() order.customer = customer.key client_info_id = self.request.get_range('user_data_id') if client_info_id: client_info = ClientInfo.get_by_id(client_info_id) if client_info and client_info.customer != customer.key: client_info.customer = customer.key client_info.put() order.order_id = result['orderId'] order.number = result['number'] order.set_status(result['status']) order.created_in_iiko = parse_iiko_time(result['createdTime'], company) order.put() try: send_order_email(order, customer, company) except DownloadError: logging.warning('mandrill is not responsed') if send_confirmation_sms: countdown = random.randint(120, 420) # make it realistic deferred.defer(send_confirmation, order.key, _countdown=countdown) response_items = order.items if company.iiko_org_id == CompanyNew.COFFEE_CITY: response_items = json.loads(json.dumps(order.items)) for item in response_items: fix_modifiers_by_own.remove_modifiers_from_item(item) resp = { 'customer_id': customer.customer_id, 'order': { 'order_id': order.order_id, 'resto_id': order.key.id(), 'status': order.status, 'items': response_items, 'sum': order.sum, 'payments': order_dict['order']['paymentItems'], # it was added 'number': order.number, 'venue_id': response_delivery_terminal_id, 'address': order.address, 'date': int(self.request.get('date')), }, 'error': False, 'error_code': 0, } logging.info(resp) delete_iiko_customer_from_memcache(company.iiko_org_id, customer.phone) self.render_json(resp)