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()
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)
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)
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)
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)
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)
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
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)
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()
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)
def api_get_node_order(order_id): return NodeOrderDetailTO.from_dict( get_node_order(order_id).to_dict(['username']))
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())
def api_get_node_order(order_id): return NodeOrderTO.from_model(get_node_order(order_id))