def cancel_orders_with_sold_out_products(self): """ After selling a product online or adding a customer to a product, check whether products aren't sold out. If a product is sold out, check for open orders containing the sold out product and cancel them. """ from os_order import Order from os_workshop_product import WorkshopProduct db = current.db products = self.get_products() for product in products: wsp = WorkshopProduct(product.id) if wsp.is_sold_out(): # Cancel all unpaid orders with this product left = [ db.customers_orders.on( db.customers_orders_items.customers_orders_id == db.customers_orders.id) ] query = ((db.customers_orders.Status == 'awaiting_payment') | (db.customers_orders.Status == 'received')) & \ (db.customers_orders_items.workshops_products_id == product.id) sold_out_rows = db(query).select(db.customers_orders_items.ALL, db.customers_orders.ALL, left=left) for sold_out_row in sold_out_rows: order = Order(sold_out_row.customers_orders.id) order.set_status_cancelled()
def render_sys_notification(self, sys_notification, title='', subject='', description='', comments='', customers_orders_id=None, invoices_id=None, invoices_payments_id=None, workshops_products_customers_id=None): """ Render notification email :param sys_notifications_id: db.sys_notifications.id :param title: Email title :param subject: Email subject :param description: Email description :param comments: Email comments :param customers_orders_id: db.customers_orders.id :param invoices_id: db.invoices.id :param invoices_payments_id: db.invoices_payments.id :param workshops_products_customers_id: db.workshops_products_customers.id :return: html message for sys_notification """ from gluon.template import render T = current.T db = current.db request = current.request DATETIME_FORMAT = current.DATETIME_FORMAT logo = self._render_email_template_get_logo() if sys_notification == 'order_created': from os_order import Order order = Order(customers_orders_id) notification = db.sys_notifications(Notification='order_created') # title title = notification.NotificationTitle # description au = db.auth_user() description = DIV( T('A new order has been received:'), BR(), BR(), TABLE( TR( TD(B(T('Order'))), TD( A( '#', order.order.id, _href=URL('orders', 'edit', vars={'coID': order.order.id}, scheme=True, host=True), ))), TR(TD(B(T('Order status'))), TD(order.order.Status)), TR(TD(B(T('Order date'))), TD(order.order.DateCreated)), TR( TD(B(T('Customer'))), TD( A(order.get_customer_name(), _href=URL('customers', 'edit', args=order.order.auth_customer_id, scheme=True, host=True))), ), TR( TD(B(T('CustomerID'))), TD(order.order.auth_customer_id), ))) # content template_content = notification.NotificationTemplate content = self._render_email_template_order( template_content, customers_orders_id) # Check for order message if order.order.CustomerNote: comments = DIV( T("The customer provided the following message with the order:" ), BR(), BR(), XML(order.order.CustomerNote.replace('\n', '<br>'))) context = dict(logo=logo, title=title, description=description, content=content, comments=comments, footer='', request=request) template_name = 'default.html' template_path = os.path.join(request.folder, 'views', 'templates', 'email') template = os.path.join(template_path, template_name) message = render(filename=template, path=template_path, context=context) return message
def render_email_template(self, email_template, title='', subject='', description='', comments='', template_content=None, auth_user_id=None, customers_orders_id=None, invoices_id=None, invoices_payments_id=None, classes_otc_id=None, classes_otc_sub_avail_id=None, workshops_products_customers_id=None, return_html=False): """ Renders default email template uses the render function from gluon.template instead of response.render response throws a RestrictedError when run from the scheduler or shell... and we do want scheduled emails to be rendered :) """ # from gluon.template import parse_template from gluon.template import render db = current.db T = current.T DATETIME_FORMAT = current.DATETIME_FORMAT error = False error_msg = '' request = current.request logo = self._render_email_template_get_logo() template_name = 'default.html' template_path = os.path.join(request.folder, 'views', 'templates', 'email') # Get template if template_content is None: # Get email template from db template_content = self.get_email_template(email_template) # Render template if email_template == 'order_received': subject = T('Order received') # do some pre-processing to show the correct order info content = self._render_email_template_order( template_content, customers_orders_id) # Check for order message from os_order import Order order = Order(customers_orders_id) if order.order.CustomerNote: comments = DIV( T("We received the following message with your order:"), BR(), BR(), XML(order.order.CustomerNote.replace('\n', '<br>'))) elif email_template == 'order_delivered': subject = T('Order delivered') # do some pre-processing to show the correct order info content = self._render_email_template_order( template_content, customers_orders_id) elif email_template == 'payment_recurring_failed': subject = T('Recurring payment failed') content = self._render_email_template_payment_recurring_failed( template_content) elif email_template == 'teacher_sub_requests_daily_summary': result = self._render_email_template_teacher_sub_requests_daily_summary( template_content, auth_user_id) title = T("Daily summary - open classes") description = result['description'] content = result['content'] error = result['error'] error_msg = result['error_msg'] elif email_template == 'teacher_sub_request_open_reminder': result = self._render_email_template_teacher_sub_request_open_reminder( template_content, classes_otc_id) title = T("A friendly reminder") description = result['description'] content = result['content'] error = result['error'] error_msg = result['error_msg'] elif email_template == 'teacher_sub_offer_declined': result = self._render_email_template_teacher_sub_offer( template_content, classes_otc_sub_avail_id) title = T("Substitute offer declined") description = result['description'] content = result['content'] elif email_template == 'teacher_sub_offer_accepted': result = self._render_email_template_teacher_sub_offer( template_content, classes_otc_sub_avail_id) title = T("Thank you for teaching this class") description = result['description'] content = result['content'] elif email_template == 'workshops_info_mail': wspc = db.workshops_products_customers( workshops_products_customers_id) wsp = db.workshops_products(wspc.workshops_products_id) ws = db.workshops(wsp.workshops_id) subject = ws.Name title = ws.Name result = self._render_email_workshops_info_mail(wspc, wsp, ws) content = result['content'] description = result['description'] elif (email_template == 'sys_verify_email' or email_template == 'sys_reset_password'): template_name = 'default_simple.html' content = XML(template_content) subject = subject else: template_name = 'default.html' content = XML(template_content) subject = subject footer = XML(self.get_email_template('sys_email_footer')) template = os.path.join(template_path, template_name) context = dict(logo=logo, title=title, description=description, content=content, comments=comments, footer=footer, request=request) html_message = render(filename=template, path=template_path, context=context) if return_html: return dict(html_message=html_message, error=error, error_msg=error_msg) else: msgID = db.messages.insert(msg_content=html_message, msg_subject=subject) return msgID
def _render_email_template_order(self, template_content, customers_orders_id): """ :param customers_orders_id: :return: mail body for order_received & order_delivered """ def get_row(value_left, value_right, first=False, total=False): border = '' font_weight = '' if first: border = "border-top: 1px dashed #aaaaaa;" if total: border = "border-top: 1px solid #eaeaea; border-bottom: 1px dashed #aaaaaa;" font_weight = "font-weight:bold;" tr = TR( TD( TABLE( TR( TD( TABLE( TR( TD( TABLE( TR( TD( value_left, # left column _align="left", _style= "font-family: Arial, sans-serif; color: #333333; font-size: 16px; " + font_weight)), _cellpadding="0", _cellspacing="0", _border="0", _width="100%"), _style="padding: 0 0 10px 0;")), _cellpadding="0", _cellspacing="0", _border="0", _width="47%", _style="width:67%;", _align="left"), TABLE( TR( TD( TABLE( TR( TD( value_right, # right column _align="right", _style= "font-family: Arial, sans-serif; color: #333333; font-size: 16px; " + font_weight)), _cellpadding="0", _cellspacing="0", _border="0", _width="100%"), _style="padding: 0 0 10px 0;")), _cellpadding="0", _cellspacing="0", _border="0", _width="47%", _style="width:33%;", _align="right"), _valign="top", _class="mobile-wrapper")), _cellspacing="0", _cellpadding="0", _border="0", _width="100%"), _style="padding: 10px 0 0 0; " + border)) return tr from os_order import Order T = current.T DATETIME_FORMAT = current.DATETIME_FORMAT represent_float_as_amount = current.globalenv[ 'represent_float_as_amount'] order = Order(customers_orders_id) item_rows = order.get_order_items_rows() order_items = TABLE(_border="0", _cellspacing="0", _cellpadding="0", _width="100%", _style="max-width: 500px;", _class="responsive-table") for i, row in enumerate(item_rows): repr_row = list(item_rows[i:i + 1].render())[0] first = False if i == 0: first = True tr = get_row(SPAN(row.ProductName, ' ', row.Description), repr_row.TotalPriceVAT, first) order_items.append(tr) # add total row amounts = order.get_amounts() total_row = get_row(T('Total'), represent_float_as_amount(amounts.TotalPriceVAT), total=True) order_items.append(total_row) # TODO: Add to manual & button on page available variables; return XML( template_content.format( order_id=order.order.id, order_date=order.order.DateCreated.strftime(DATETIME_FORMAT), order_status=order.order.Status, order_items=order_items, link_profile_orders=URL('profile', 'orders', scheme=True, host=True), link_profile_invoices=URL('profile', 'invoices', scheme=True, host=True)))
def render_email_template(self, email_template, title='', subject='', description='', comments='', template_content=None, customers_orders_id=None, invoices_id=None, invoices_payments_id=None, workshops_products_customers_id=None, return_html=False): """ Renders default email template uses the render function from gluon.template instead of response.render response throws a RestrictedError when run from the scheduler or shell... and we do want scheduled emails to be rendered :) """ # from gluon.template import parse_template from gluon.template import render db = current.db T = current.T DATETIME_FORMAT = current.DATETIME_FORMAT get_sys_property = current.globalenv['get_sys_property'] request = current.request logo = self._render_email_template_get_logo() template_name = 'default.html' template_path = os.path.join(request.folder, 'views', 'templates', 'email') if template_content is None: # Get email template from settings template_content = get_sys_property(email_template) if email_template == 'email_template_order_received': subject = T('Order received') # do some pre-processing to show the correct order info content = self._render_email_template_order( template_content, customers_orders_id) # Check for order message from os_order import Order order = Order(customers_orders_id) if order.order.CustomerNote: comments = DIV( T("We received the following message with your order:"), BR(), BR(), XML(order.order.CustomerNote.replace('\n', '<br>'))) elif email_template == 'email_template_order_delivered': subject = T('Order delivered') # do some pre-processing to show the correct order info content = self._render_email_template_order( template_content, customers_orders_id) elif email_template == 'email_template_payment_recurring_failed': subject = T('Recurring payment failed') content = self._render_email_template_payment_recurring_failed( template_content) elif email_template == 'workshops_info_mail': wspc = db.workshops_products_customers( workshops_products_customers_id) wsp = db.workshops_products(wspc.workshops_products_id) ws = db.workshops(wsp.workshops_id) subject = ws.Name title = ws.Name result = self._render_email_workshops_info_mail(wspc, wsp, ws) content = result['content'] description = result['description'] elif (email_template == 'email_template_sys_verify_email' or email_template == 'email_template_sys_reset_password'): template_name = 'default_simple.html' content = XML(template_content) subject = subject else: template_name = 'default.html' content = XML(template_content) subject = subject footer = XML(get_sys_property('email_template_sys_footer')) template = os.path.join(template_path, template_name) context = dict(logo=logo, title=title, description=description, content=content, comments=comments, footer=footer, request=request) message = render(filename=template, path=template_path, context=context) if return_html: return message else: msgID = db.messages.insert(msg_content=message, msg_subject=subject) return msgID