示例#1
0
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))
示例#2
0
    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)
示例#3
0
 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))
示例#4
0
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)
示例#5
0
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)
示例#6
0
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]
示例#7
0
    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)