Example #1
0
    def trans():
        node_order = get_node_order(order_id)
        if node_order.odoo_sale_order_id:
            update_odoo_quotation(node_order.odoo_sale_order_id, {'state': QuotationState.CANCEL.value})

        node_order.populate(status=NodeOrderStatus.CANCELED, cancel_time=now())
        node_order.put()
Example #2
0
def _inform_support_of_new_node_order(node_order_id):
    node_order = get_node_order(node_order_id)
    cfg = get_config(NAMESPACE)
    iyo_username = get_iyo_username(node_order.app_user)

    subject = 'New Node Order by %s' % node_order.billing_info.name
    body = """Hello,

We just received a new Node order from %(name)s (IYO username %(iyo_username)s) with id %(node_order_id)s.
This order needs to be manually approved since this user has not invested more than %(tokens)s tokens yet via the app.
Check the old purchase agreements to verify if this user can sign up as a hoster and if not, contact him.

Please visit https://tff-backend.appspot.com/orders/%(node_order_id)s to approve or cancel this order.
""" % {
        'name': node_order.billing_info.name,
        'iyo_username': iyo_username,
        'node_order_id': node_order.id,
        'tokens': REQUIRED_TOKEN_COUNT_TO_HOST
    }

    for email in cfg.investor.support_emails:
        mail.send_mail(sender='*****@*****.**',
                       to=email,
                       subject=subject,
                       body=body)
Example #3
0
def _send_node_order_sent_message(node_order_id):
    node_order = get_node_order(node_order_id)
    subject = u'ThreeFold node ready to ship out'
    msg = u'Good news, your ThreeFold node (order id %s) has been prepared for shipment.' \
          u' It will be handed over to our shipping partner soon.' \
          u'\nThanks again for accepting hosting duties and helping to grow the ThreeFold Grid close to the users.' % \
          node_order_id
    send_message_and_email(node_order.app_user, msg, subject)
Example #4
0
def _create_node_order_pdf(node_order_id):
    node_order = get_node_order(node_order_id)
    user_email, app_id = get_app_user_tuple(node_order.app_user)
    logging.debug('Creating Hosting agreement')
    pdf_name = NodeOrder.filename(node_order_id)
    pdf_contents = create_hosting_agreement_pdf(node_order.billing_info.name, node_order.billing_info.address)
    pdf_url = upload_to_gcs(pdf_name, pdf_contents, 'application/pdf')
    deferred.defer(_order_node_iyo_see, node_order.app_user, node_order_id, pdf_url)
    deferred.defer(update_hoster_progress, user_email.email(), app_id, HosterSteps.FLOW_ADDRESS)
Example #5
0
def get_node_order_details(order_id):
    # type: (long) -> NodeOrderDetailsTO
    node_order = get_node_order(order_id)
    if node_order.tos_iyo_see_id:
        iyo_organization_id = get_iyo_organization_id()
        username = get_iyo_username(node_order.app_user)
        see_document = get_see_document(iyo_organization_id, username, node_order.tos_iyo_see_id)
    else:
        see_document = None
    return NodeOrderDetailsTO.from_model(node_order, see_document)
Example #6
0
 def trans():
     order = get_node_order(node_order_id)
     order.tos_iyo_see_id = doc_id
     order.put()
     if create_quotation:
         deferred.defer(_create_quotation,
                        app_user,
                        node_order_id,
                        pdf_url,
                        attachment_name,
                        pdf_size,
                        _transactional=True)
Example #7
0
def put_node_order(order_id, order):
    # type: (long, NodeOrderTO) -> NodeOrder
    order_model = get_node_order(order_id)
    if order_model.status == NodeOrderStatus.CANCELED:
        raise HttpBadRequestException('order_canceled')
    if order.status not in (NodeOrderStatus.CANCELED, NodeOrderStatus.SENT,
                            NodeOrderStatus.APPROVED, NodeOrderStatus.PAID):
        raise HttpBadRequestException('invalid_status')
    # Only support updating the status for now
    if order_model.status != order.status:
        if not _can_change_status(order_model.status, order.status):
            raise HttpBadRequestException(
                'cannot_change_status', {
                    'from': order_model.status,
                    'to': order.status,
                    'allowed_new_statuses': _get_allowed_status(
                        order_model.status)
                })
        order_model.status = order.status
        human_user, app_id = get_app_user_tuple(order_model.app_user)
        if order_model.status == NodeOrderStatus.CANCELED:
            order_model.cancel_time = now()
            if order_model.odoo_sale_order_id:
                deferred.defer(update_odoo_quotation,
                               order_model.odoo_sale_order_id,
                               {'state': QuotationState.CANCEL.value})
            deferred.defer(update_hoster_progress, human_user.email(), app_id,
                           HosterSteps.NODE_POWERED)  # nuke todo list
            deferred.defer(set_hoster_status_in_user_data,
                           order_model.app_user,
                           _countdown=2)
        elif order_model.status == NodeOrderStatus.SENT:
            if not order_model.odoo_sale_order_id or not get_nodes_from_odoo(
                    order_model.odoo_sale_order_id):
                raise HttpBadRequestException(
                    'cannot_mark_sent_no_serial_number_configured_yet',
                    {'sale_order': order_model.odoo_sale_order_id})
            order_model.send_time = now()
            deferred.defer(update_hoster_progress, human_user.email(), app_id,
                           HosterSteps.NODE_SENT)
            deferred.defer(_send_node_order_sent_message, order_id)
        elif order_model.status == NodeOrderStatus.APPROVED:
            deferred.defer(_create_node_order_pdf, order_id)
        elif order_model.status == NodeOrderStatus.PAID:
            deferred.defer(confirm_odoo_quotation,
                           order_model.odoo_sale_order_id)
    else:
        logging.debug('Status was already %s, not doing anything',
                      order_model.status)
    order_model.put()
    return order_model
Example #8
0
def _create_quotation(app_user, order_id, pdf_url, attachment_name):
    order = get_node_order(order_id)
    config = get_config(NAMESPACE)
    assert isinstance(config, TffConfiguration)
    product_id = config.odoo.product_ids.get(order.socket)
    if not product_id:
        logging.warn('Could not find appropriate product for socket %s. Falling back to EU socket.', order.socket)
        product_id = config.odoo.product_ids['EU']
    odoo_sale_order_id, odoo_sale_order_name = create_odoo_quotation(order.billing_info, order.shipping_info,
                                                                     product_id)

    order.odoo_sale_order_id = odoo_sale_order_id
    order.put()

    deferred.defer(_send_order_node_sign_message, app_user, order_id, pdf_url, attachment_name,
                   odoo_sale_order_name)
Example #9
0
def order_node_signed(message_flow_run_id, member, steps, end_id,
                      end_message_flow_id, parent_message_key, tag, result_key,
                      flush_id, flush_message_flow_id, service_identity,
                      user_details, flow_params):
    try:
        user_detail = user_details[0]
        tag_dict = json.loads(tag)
        order = get_node_order(tag_dict['order_id'])

        last_step = steps[-1]
        if last_step.answer_id != FormTO.POSITIVE:
            logging.info('Zero-Node order was canceled')
            deferred.defer(_cancel_quotation, order.id)
            return None

        logging.info('Received signature for Zero-Node order')

        sign_result = last_step.form_result.result.get_value()
        assert isinstance(sign_result, SignWidgetResultTO)
        iyo_username = get_iyo_username(user_detail)
        sign_see_document(iyo_username, order.tos_iyo_see_id, sign_result,
                          user_detail)

        logging.debug('Storing signature in DB')
        order.populate(status=NodeOrderStatus.SIGNED,
                       signature=sign_result.payload_signature,
                       sign_time=now())
        order.put()

        # TODO: send mail to TF support
        deferred.defer(add_user_to_role, user_detail, RogerthatRoles.HOSTERS)
        deferred.defer(update_hoster_progress, user_detail.email,
                       user_detail.app_id, HosterSteps.FLOW_SIGN)
        intercom_tags = get_intercom_tags_for_node_order(order)
        for intercom_tag in intercom_tags:
            deferred.defer(tag_intercom_users, intercom_tag, [iyo_username])

        logging.debug('Sending confirmation message')
        result = FlowCallbackResultTypeTO(
            flow=FLOW_HOSTER_SIGNATURE_RECEIVED,
            tag=None,
            force_language=None,
            flow_params=json.dumps({'orderId': order.human_readable_id}))
        return FlowMemberResultCallbackResultTO(type=TYPE_FLOW, value=result)
    except:
        logging.exception('An unexpected error occurred')
        return create_error_message()
Example #10
0
def _inform_support_of_new_node_order(node_order_id):
    node_order = get_node_order(node_order_id)
    iyo_username = get_iyo_username(node_order.app_user)

    subject = 'New Node Order by %s' % node_order.billing_info.name
    body = """Hello,

We just received a new Node order from %(name)s (IYO username %(iyo_username)s) with id %(node_order_id)s.
This order needs to be manually approved since this user has not invested more than %(tokens)s tokens yet via the app.
Check the old purchase agreements to verify if this user can sign up as a hoster and if not, contact him.

Please visit %(base_url)s/orders/%(node_order_id)s to approve or cancel this order.
""" % {
        'name': node_order.billing_info.name,
        'iyo_username': iyo_username,
        'base_url': get_base_url(),
        'node_order_id': node_order.id,
        'tokens': REQUIRED_TOKEN_COUNT_TO_HOST
    }

    send_emails_to_support(subject, body)
Example #11
0
def api_get_node_order(order_id):
    return NodeOrderDetailTO.from_dict(
        get_node_order(order_id).to_dict(['username']))
Example #12
0
def order_node_signed(status, form_result, answer_id, member, message_key, tag, received_timestamp, acked_timestamp,
                      parent_message_key, result_key, service_identity, user_details):
    """
    Args:
        status (int)
        form_result (FormResultTO)
        answer_id (unicode)
        member (unicode)
        message_key (unicode)
        tag (unicode)
        received_timestamp (int)
        acked_timestamp (int)
        parent_message_key (unicode)
        result_key (unicode)
        service_identity (unicode)
        user_details(list[UserDetailsTO])

    Returns:
        FormAcknowledgedCallbackResultTO
    """
    try:
        user_detail = user_details[0]
        tag_dict = json.loads(tag)
        order = get_node_order(tag_dict['order_id'])

        if answer_id != FormTO.POSITIVE:
            logging.info('Zero-Node order was canceled')
            deferred.defer(_cancel_quotation, order.id)
            return None

        logging.info('Received signature for Zero-Node order')

        sign_result = form_result.result.get_value()
        assert isinstance(sign_result, SignWidgetResultTO)
        payload_signature = sign_result.payload_signature

        iyo_organization_id = get_iyo_organization_id()
        iyo_username = get_iyo_username(user_detail)

        logging.debug('Getting IYO SEE document %s', order.tos_iyo_see_id)
        doc = get_see_document(iyo_organization_id, iyo_username, order.tos_iyo_see_id)
        doc_view = IYOSeeDocumentView(username=doc.username,
                                      globalid=doc.globalid,
                                      uniqueid=doc.uniqueid,
                                      **serialize_complex_value(doc.versions[-1], IYOSeeDocumenVersion, False))
        doc_view.signature = payload_signature
        keystore_label = get_publickey_label(sign_result.public_key.public_key, user_detail)
        if not keystore_label:
            return create_error_message(FormAcknowledgedCallbackResultTO())
        doc_view.keystore_label = keystore_label
        logging.debug('Signing IYO SEE document')
        sign_see_document(iyo_organization_id, iyo_username, doc_view)

        logging.debug('Storing signature in DB')
        order.populate(status=NodeOrderStatus.SIGNED,
                       signature=payload_signature,
                       sign_time=now())
        order.put()

        # TODO: send mail to TF support
        deferred.defer(add_user_to_role, user_detail, RogerthatRoles.HOSTERS)
        deferred.defer(update_hoster_progress, user_detail.email, user_detail.app_id, HosterSteps.FLOW_SIGN)
        intercom_tags = get_intercom_tags_for_node_order(order)
        for intercom_tag in intercom_tags:
            deferred.defer(tag_intercom_users, intercom_tag, [iyo_username])

        logging.debug('Sending confirmation message')
        message = MessageCallbackResultTypeTO()
        message.alert_flags = Message.ALERT_FLAG_VIBRATE
        message.answers = []
        message.branding = get_main_branding_hash()
        message.dismiss_button_ui_flags = 0
        message.flags = Message.FLAG_ALLOW_DISMISS | Message.FLAG_AUTO_LOCK
        message.message = u'Thank you. We successfully received your digital signature.' \
                          u' We have stored a copy of this agreement in your ThreeFold Documents.\n\n' \
                          u'Your order with ID "%s" has been placed successfully.\n' % order.human_readable_id
        message.step_id = u'order_completed'
        message.tag = None

        result = FormAcknowledgedCallbackResultTO()
        result.type = TYPE_MESSAGE
        result.value = message
        return result
    except:
        logging.exception('An unexpected error occurred')
        return create_error_message(FormAcknowledgedCallbackResultTO())
Example #13
0
def api_get_node_order(order_id):
    return NodeOrderTO.from_model(get_node_order(order_id))