def make_home_pages(self): """Make standard home pages for docs, developer docs, api and models from templates""" # make dev home page with open(os.path.join(self.docs_path, "index.html"), "w") as home: home.write(frappe.render_template("templates/autodoc/docs_home.html", self.app_context)) # make dev home page with open(os.path.join(self.path, "index.html"), "w") as home: home.write(frappe.render_template("templates/autodoc/dev_home.html", self.app_context)) # make folders self.models_base_path = os.path.join(self.path, "models") self.make_folder(self.models_base_path, template = "templates/autodoc/models_home.html") self.api_base_path = os.path.join(self.path, "api") self.make_folder(self.api_base_path, template = "templates/autodoc/api_home.html") # make /user user_path = os.path.join(self.docs_path, "user") if not os.path.exists(user_path): os.makedirs(user_path) # make /assets/img img_path = os.path.join(self.docs_path, "assets", "img") if not os.path.exists(img_path): os.makedirs(img_path)
def build_user_docs(self): """Build templates for user docs pages, if missing.""" #user_docs_path = os.path.join(self.docs_path, "user") # license with open(os.path.join(self.app_path, "..", "license.txt"), "r") as license_file: self.app_context["license_text"] = markdown(license_file.read()) html = frappe.render_template("templates/autodoc/license.html", context = self.app_context) with open(os.path.join(self.docs_path, "license.html"), "w") as license_file: license_file.write(html.encode("utf-8")) # contents shutil.copy(os.path.join(frappe.get_app_path("frappe", "templates", "autodoc", "contents.html")), os.path.join(self.docs_path, "contents.html")) shutil.copy(os.path.join(frappe.get_app_path("frappe", "templates", "autodoc", "contents.py")), os.path.join(self.docs_path, "contents.py")) # install html = frappe.render_template("templates/autodoc/install.md", context = self.app_context) with open(os.path.join(self.docs_path, "install.md"), "w") as f: f.write(html) self.update_index_txt(self.docs_path)
def build_page(path): if not getattr(frappe.local, "path", None): frappe.local.path = path context = get_context(path) if context.title and "{{" in context.title: title_template = context.pop('title') context.title = frappe.render_template(title_template, context) if context.source: html = frappe.render_template(context.source, context) elif context.template: html = frappe.get_template(context.template).render(context) if '{index}' in html: html = html.replace('{index}', get_toc(context.route)) if '{next}' in html: html = html.replace('{next}', get_next_link(context.route)) # html = frappe.get_template(context.base_template_path).render(context) if can_cache(context.no_cache): page_cache = frappe.cache().hget("website_page", path) or {} page_cache[frappe.local.lang] = html frappe.cache().hset("website_page", path, page_cache) return html
def update_cart(item_code, qty, with_items=False): quotation = _get_cart_quotation() qty = flt(qty) if qty == 0: quotation.set("items", quotation.get("items", {"item_code": ["!=", item_code]})) else: quotation_items = quotation.get("items", {"item_code": item_code}) if not quotation_items: quotation.append("items", { "doctype": "Quotation Item", "item_code": item_code, "qty": qty }) else: quotation_items[0].qty = qty apply_cart_settings(quotation=quotation) quotation.flags.ignore_permissions = True quotation.save() set_cart_count(quotation) if with_items: context = get_cart_quotation(quotation) return { "items": frappe.render_template("templates/includes/cart/cart_items.html", context), "taxes": frappe.render_template("templates/includes/order/order_taxes.html", context), } else: return quotation.name
def create_submit_log(self, submitted_ss, not_submitted_ss, jv_name): log = '' if not submitted_ss and not not_submitted_ss: log = "No salary slip found to submit for the above selected criteria" if submitted_ss: log = frappe.render_template("templates/includes/salary_slip_log.html", dict(ss_list=submitted_ss, keys=sorted(submitted_ss[0].keys()), title=_('Submitted Salary Slips'))) if jv_name: log += "<b>" + _("Accural Journal Entry Submitted") + "</b>\ %s" % '<br>''<a href="#Form/Journal Entry/{0}">{0}</a>'.format(jv_name) if not_submitted_ss: log += frappe.render_template("templates/includes/salary_slip_log.html", dict(ss_list=not_submitted_ss, keys=sorted(not_submitted_ss[0].keys()), title=_('Not Submitted Salary Slips'))) log += """ Possible reasons: <br>\ 1. Net pay is less than 0 <br> 2. Company Email Address specified in employee master is not valid. <br> """ return log
def weekly_digest(): new_jobs = frappe.db.sql("""select job_title, page_name, job_detail, company_name from `tabFrappe Job` where datediff(curdate(), creation) < 7""", as_dict=True) if not new_jobs: return recipients = frappe.db.sql_list("""select distinct owner from `tabFrappe Partner` where name != 'Administrator'""") template = """ <h3>New Jobs Listed on Frappe.io</h3> <table style="width: 100%" cellspacing="0" border="1px" cellpadding="2px"> <tbody> {% for j in jobs %} <tr> <td style="width: 50%"> <a href="https://frappe.io/community/jobs/{{ j.page_name }}"> {{ j.job_title }}</a> <br><span style="color: #888">{{ j.company_name }}</span> </td> <td> {{ j.job_detail[:300] }}{{ "..." if j.job_detail|length > 300 else "" }} </td> </tr> {% endfor %} </tbody> </table> """ print frappe.render_template(template, {"jobs": new_jobs}) frappe.sendmail(recipients = recipients, subject="New Jobs This Week on Frappe.io", message = frappe.render_template(template, {"jobs": new_jobs}), bulk=True)
def generate_message_preview(reference_dt, reference_doc, message=None, subject=None): doc = frappe.get_doc(reference_dt, reference_doc) subject_preview = _("Please add a subject to your email") msg_preview = frappe.render_template(message, {'doc': doc}) if subject: subject_preview = frappe.render_template(subject, {'doc': doc}) return {'message': msg_preview, 'subject': subject_preview}
def get_email_template(template_name, doc): '''Returns the processed HTML of a email template with the given doc''' if isinstance(doc, string_types): doc = json.loads(doc) email_template = frappe.get_doc("Email Template", template_name) return {"subject" : frappe.render_template(email_template.subject, doc), "message" : frappe.render_template(email_template.response, doc)}
def get_sms_text(doc): sms_text = {} doc = frappe.get_doc("Lab Test",doc) #doc = json.loads(doc) context = {"doc": doc, "alert": doc, "comments": None} emailed = frappe.db.get_value("Healthcare Settings", None, "sms_emailed") sms_text['emailed'] = frappe.render_template(emailed, context) printed = frappe.db.get_value("Healthcare Settings", None, "sms_printed") sms_text['printed'] = frappe.render_template(printed, context) return sms_text
def get_feedback_request_details(reference_doctype, reference_name, trigger="Manual", request=None): if not frappe.db.get_value(reference_doctype, reference_name): # reference document is either deleted or renamed return elif not trigger and not request and not frappe.db.get_value("Feedback Trigger", { "document_type": reference_doctype }): return elif not trigger and request: trigger = frappe.db.get_value("Feedback Request", request, "feedback_trigger") else: trigger = frappe.db.get_value("Feedback Trigger", { "document_type": reference_doctype }) if not trigger: return feedback_trigger = frappe.get_doc("Feedback Trigger", trigger) doc = frappe.get_doc(reference_doctype, reference_name) context = get_context(doc) recipients = doc.get(feedback_trigger.email_fieldname, None) if feedback_trigger.check_communication: communications = frappe.get_all("Communication", filters={ "reference_doctype": reference_doctype, "reference_name": reference_name, "communication_type": "Communication", "sent_or_received": "Sent" }, fields=["name"]) if len(communications) < 1: frappe.msgprint(_("At least one reply is mandatory before requesting feedback")) return None if recipients and (not feedback_trigger.condition or \ frappe.safe_eval(feedback_trigger.condition, None, context)): subject = feedback_trigger.subject context.update({ "feedback_trigger": feedback_trigger }) if "{" in subject: subject = frappe.render_template(feedback_trigger.subject, context) feedback_request_message = frappe.render_template(feedback_trigger.message, context) return { "subject": subject, "recipients": recipients, "reference_name":doc.name, "reference_doctype":doc.doctype, "message": feedback_request_message, } else: frappe.msgprint(_("Feedback conditions do not match")) return None
def evaluate_alert(doc, alert, event): if isinstance(alert, basestring): alert = frappe.get_doc("Email Alert", alert) context = {"doc": doc, "nowdate": nowdate} if alert.condition: if not eval(alert.condition, context): return if event=="Value Change" and not doc.is_new(): if doc.get(alert.value_changed) == frappe.db.get_value(doc.doctype, doc.name, alert.value_changed): return # value not changed for recipient in alert.recipients: recipients = [] if recipient.condition: if not eval(recipient.condition, context): continue if recipient.email_by_document_field: if validate_email_add(doc.get(recipient.email_by_document_field)): recipients.append(doc.get(recipient.email_by_document_field)) # else: # print "invalid email" if recipient.cc: recipient.cc = recipient.cc.replace(",", "\n") recipients = recipients + recipient.cc.split("\n") if not recipients: return subject = alert.subject if event != "Value Change" and not doc.is_new(): # reload the doc for the latest values & comments, # except for validate type event. doc = frappe.get_doc(doc.doctype, doc.name) context = {"doc": doc, "alert": alert, "comments": None} if doc.get("_comments"): context["comments"] = json.loads(doc.get("_comments")) if "{" in subject: subject = frappe.render_template(alert.subject, context) frappe.sendmail(recipients=recipients, subject=subject, message= frappe.render_template(alert.message, context), bulk=True, reference_doctype = doc.doctype, reference_name = doc.name, attachments = [frappe.attach_print(doc.doctype, doc.name)] if alert.attach_print else None)
def update_cart(item_code, qty, with_items=False): quotation = _get_cart_quotation() empty_card = False qty = flt(qty) if qty == 0: quotation_items = quotation.get("items", {"item_code": ["!=", item_code]}) if quotation_items: quotation.set("items", quotation_items) else: empty_card = True else: quotation_items = quotation.get("items", {"item_code": item_code}) if not quotation_items: quotation.append("items", { "doctype": "Quotation Item", "item_code": item_code, "qty": qty }) else: quotation_items[0].qty = qty apply_cart_settings(quotation=quotation) quotation.flags.ignore_permissions = True quotation.payment_schedule = [] if not empty_card: quotation.save() else: quotation.delete() quotation = None set_cart_count(quotation) context = get_cart_quotation(quotation) if cint(with_items): return { "items": frappe.render_template("templates/includes/cart/cart_items.html", context), "taxes": frappe.render_template("templates/includes/order/order_taxes.html", context), } else: return { 'name': quotation.name, 'shopping_cart_menu': get_shopping_cart_menu(context) }
def get_summary_message(self): '''Return summary of replies as HTML''' settings = frappe.get_doc('Daily Work Summary Settings') replies = frappe.get_all('Communication', fields=['content', 'text_content', 'sender'], filters=dict(reference_doctype=self.doctype, reference_name=self.name, communication_type='Communication', sent_or_received='Received'), order_by='creation asc') did_not_reply = self.email_sent_to.split() for d in replies: d.sender_name = frappe.db.get_value("Employee", {"user_id": d.sender}, "employee_name") or d.sender if d.sender in did_not_reply: did_not_reply.remove(d.sender) if d.text_content: d.content = markdown(EmailReplyParser.parse_reply(d.text_content)) did_not_reply = [(frappe.db.get_value("Employee", {"user_id": email}, "employee_name") or email) for email in did_not_reply] return frappe.render_template(self.get_summary_template(), dict(replies=replies, original_message=settings.message, title=_('Daily Work Summary for {0}'.format(formatdate(self.creation))), did_not_reply= ', '.join(did_not_reply) or '', did_not_reply_title = _('No replies from')))
def get_search_results(text, start=0, as_html=False): results = web_search(text, start, limit=21) out = frappe._dict() if len(results) == 21: out.has_more = 1 results = results[:20] for d in results: d.content = html2text(d.content) index = d.content.lower().index(text.lower()) d.content = d.content[:index] + '<b>' + d.content[index:][:len(text)] + '</b>' + d.content[index + len(text):] if index < 40: start = 0 prefix = '' else: start = index - 40 prefix = '...' suffix = '' if (index + len(text) + 47) < len(d.content): suffix = '...' d.preview = prefix + d.content[start:start + len(text) + 87] + suffix out.results = results if as_html: out.results = frappe.render_template('templates/includes/search_result.html', out) return out
def view_result(self): # abc = frappe.render_template("templates/includes/cart/view_result.html",{"context":"aa","aa":"aaaa"}) water_content = frappe.db.get_value("Water Content Test",{"sample_id":self.sample_id, "result_status":"Accept", "test_type" : "Sample"},"avg(final_result)") if water_content: water_content = '%.2f'%water_content dl_dga = frappe.db.sql("""select * from `tabDissolved Gas Analysis` where sample_id = '{0}' and result_status = 'Accept' and test_type = 'Sample'""".format(self.sample_id), as_dict=1) dga_test_result = {} # print "/n/ndl",dl_dga if len(dl_dga)>0: dga_test_result = dl_dga[0] # print "/n/n/ndga",dl_dga abc = frappe.render_template("sample_register/sample_register/doctype/job_card_creation/view_result_with_dga.html",{"water_content":water_content,"dga_test_result":dga_test_result}, is_path=True) else: abc = frappe.render_template("sample_register/sample_register/doctype/job_card_creation/view_result.html",{"water_content":water_content,"dga_test_result":dga_test_result}, is_path=True) frappe.msgprint(abc)
def get_standard_reply(template_name, doc): '''Returns the processed HTML of a standard reply with the given doc''' if isinstance(doc, basestring): doc = json.loads(doc) standard_reply = frappe.get_doc("Standard Reply", template_name) return frappe.render_template(standard_reply.response, doc)
def build_page(path): if not getattr(frappe.local, "path", None): frappe.local.path = path context = get_context(path) if context.source: html = frappe.render_template(context.source, context) elif context.template: if path.endswith('min.js'): html = frappe.get_jloader().get_source(frappe.get_jenv(), context.template)[0] else: html = frappe.get_template(context.template).render(context) if '{index}' in html: html = html.replace('{index}', get_toc(context.route)) if '{next}' in html: html = html.replace('{next}', get_next_link(context.route)) # html = frappe.get_template(context.base_template_path).render(context) if can_cache(context.no_cache): page_cache = frappe.cache().hget("website_page", path) or {} page_cache[frappe.local.lang] = html frappe.cache().hset("website_page", path, page_cache) return html
def write_modules(self, basepath, folders, files): module_folder = os.path.join(self.api_base_path, os.path.relpath(basepath, self.app_path)) self.make_folder(module_folder) for f in files: if f.endswith(".py"): full_module_name = os.path.relpath(os.path.join(basepath, f), self.app_path)[:-3].replace("/", ".") module_name = full_module_name.replace(".__init__", "") module_doc_path = os.path.join(module_folder, self.app + "." + module_name + ".html") self.make_folder(basepath) if not os.path.exists(module_doc_path): print "Writing " + module_doc_path with open(module_doc_path, "w") as f: context = {"name": self.app + "." + module_name} context.update(self.app_context) context['full_module_name'] = self.app + '.' + full_module_name f.write(frappe.render_template("templates/autodoc/pymodule.html", context).encode('utf-8')) self.update_index_txt(module_folder)
def send_feedback_request(reference_doctype, reference_name, trigger="Manual", details=None, is_manual=False): """ send feedback alert """ if is_feedback_request_already_sent(reference_doctype, reference_name, is_manual=is_manual): frappe.msgprint(_("Feedback Request is already sent to user")) return None details = json.loads(details) if details else \ get_feedback_request_details(reference_doctype, reference_name, trigger=trigger) if not details: return None feedback_request, url = get_feedback_request_url(reference_doctype, reference_name, details.get("recipients"), trigger) feedback_msg = frappe.render_template("templates/emails/feedback_request_url.html", { "url": url }) # appending feedback url to message body message = "{message}{feedback_msg}".format( message=details.get("message"), feedback_msg=feedback_msg ) details.update({ "message": message, "header": [details.get('subject'), 'blue'] }) if details: frappe.sendmail(**details) frappe.db.set_value("Feedback Request", feedback_request, "is_sent", 1)
def get_task_html(project, start=0, item_status=None): return frappe.render_template("erpnext/templates/includes/projects/project_tasks.html", {"doc": { "name": project, "project_name": project, "tasks": get_tasks(project, start, item_status=item_status)} }, is_path=True)
def update_cart_address(address_fieldname, address_name): quotation = _get_cart_quotation() address_display = get_address_display(frappe.get_doc("Address", address_name).as_dict()) if address_fieldname == "shipping_address_name": quotation.shipping_address_name = address_name quotation.shipping_address = address_display if not quotation.customer_address: address_fieldname == "customer_address" if address_fieldname == "customer_address": quotation.customer_address = address_name quotation.address_display = address_display apply_cart_settings(quotation=quotation) quotation.flags.ignore_permissions = True quotation.save() context = get_cart_quotation(quotation) return { "taxes": frappe.render_template("templates/includes/order/order_taxes.html", context), }
def get_itemised_tax_breakup_html(doc): if not doc.taxes: return frappe.flags.company = doc.company # get headers tax_accounts = [] for tax in doc.taxes: if getattr(tax, "category", None) and tax.category=="Valuation": continue if tax.description not in tax_accounts: tax_accounts.append(tax.description) headers = get_itemised_tax_breakup_header(doc.doctype + " Item", tax_accounts) # get tax breakup data itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(doc) get_rounded_tax_amount(itemised_tax, doc.precision("tax_amount", "taxes")) update_itemised_tax_data(doc) frappe.flags.company = None return frappe.render_template( "templates/includes/itemised_tax_breakup.html", dict( headers=headers, itemised_tax=itemised_tax, itemised_taxable_amount=itemised_taxable_amount, tax_accounts=tax_accounts, conversion_rate=doc.conversion_rate, currency=doc.currency ) )
def get_msg_html(self): """Build email digest content""" frappe.flags.ignore_account_permission = True from erpnext.setup.doctype.email_digest.quotes import get_random_quote context = frappe._dict() context.update(self.__dict__) self.set_title(context) self.set_style(context) self.set_accounting_cards(context) context.events = self.get_calendar_events() context.todo_list = self.get_todo_list() context.notifications = self.get_notifications() # quote = get_random_quote() context.quote = {"text": self.custom_message, "author": "AMLS"} if not (context.events or context.todo_list or context.notifications or context.cards): return None frappe.flags.ignore_account_permission = False # style return frappe.render_template("erpnext/setup/doctype/email_digest/templates/default.html", context, is_path=True)
def get_terms_and_conditions(template_name, doc): if isinstance(doc, string_types): doc = json.loads(doc) terms_and_conditions = frappe.get_doc("Terms and Conditions", template_name) if terms_and_conditions.terms: return frappe.render_template(terms_and_conditions.terms, doc)
def send(self, doc): '''Build recipients and send email alert''' context = get_context(doc) for recipient in self.recipients: recipients = [] if recipient.condition: if not eval(recipient.condition, context): continue if recipient.email_by_document_field: if validate_email_add(doc.get(recipient.email_by_document_field)): recipients.append(doc.get(recipient.email_by_document_field)) # else: # print "invalid email" if recipient.cc: recipient.cc = recipient.cc.replace(",", "\n") recipients = recipients + recipient.cc.split("\n") #For sending emails to specified role if recipient.email_by_role: emails = get_emails_from_role(recipient.email_by_role) for email in emails: recipients = recipients + email.split("\n") if not recipients: return subject = self.subject context = {"doc": doc, "alert": self, "comments": None} if self.is_standard: self.load_standard_properties(context) if doc.get("_comments"): context["comments"] = json.loads(doc.get("_comments")) if "{" in subject: subject = frappe.render_template(self.subject, context) frappe.sendmail(recipients=recipients, subject=subject, message= frappe.render_template(self.message, context), reference_doctype = doc.doctype, reference_name = doc.name, attachments = [frappe.attach_print(doc.doctype, doc.name)] if self.attach_print else None)
def preview_report_card(doc): doc = frappe._dict(json.loads(doc)) doc.students = [doc.student] if not (doc.student_name and doc.student_batch): program_enrollment = frappe.get_all("Program Enrollment", fields=["student_batch_name", "student_name"], filters={"student": doc.student, "docstatus": ('!=', 2), "academic_year": doc.academic_year}) if program_enrollment: doc.batch = program_enrollment[0].student_batch_name doc.student_name = program_enrollment[0].student_name # get the assessment result of the selected student values = get_formatted_result(doc, get_course=True, get_all_assessment_groups=doc.include_all_assessment) assessment_result = values.get("assessment_result").get(doc.student) courses = values.get("course_dict") course_criteria = get_courses_criteria(courses) # get the assessment group as per the user selection if doc.include_all_assessment: assessment_groups = get_child_assessment_groups(doc.assessment_group) else: assessment_groups = [doc.assessment_group] # get the attendance of the student for that peroid of time. doc.attendance = get_attendance_count(doc.students[0], doc.academic_year, doc.academic_term) template = "erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html" base_template_path = "frappe/www/printview.html" from frappe.www.printview import get_letter_head letterhead = get_letter_head(frappe._dict({"letter_head": doc.letterhead}), not doc.add_letterhead) html = frappe.render_template(template, { "doc": doc, "assessment_result": assessment_result, "courses": courses, "assessment_groups": assessment_groups, "course_criteria": course_criteria, "letterhead": letterhead.content, "add_letterhead": doc.add_letterhead if doc.add_letterhead else 0 }) final_template = frappe.render_template(base_template_path, {"body": html, "title": "Report Card"}) frappe.response.filename = "Report Card " + doc.students[0] + ".pdf" frappe.response.filecontent = get_pdf(final_template) frappe.response.type = "download"
def prepare_and_attach_invoice(doc, replace=False): progressive_name, progressive_number = get_progressive_name_and_number(doc, replace) invoice = prepare_invoice(doc, progressive_number) invoice_xml = frappe.render_template('erpnext/regional/italy/e-invoice.xml', context={"doc": invoice}, is_path=True) invoice_xml = invoice_xml.replace("&", "&") xml_filename = progressive_name + ".xml" return save_file(xml_filename, invoice_xml, dt=doc.doctype, dn=doc.name, is_private=True)
def create_log(self, ss_list): if not ss_list: log = "<p>" + _("No employee for the above selected criteria OR salary slip already created") + "</p>" else: log = frappe.render_template("templates/includes/salary_slip_log.html", dict(ss_list=ss_list, keys=sorted(ss_list[0].keys()), title=_('Created Salary Slips'))) return log
def get_shipping_address(company): filters = {"company": company, "is_your_company_address":1} fieldname = ["name", "address_line1", "address_line2", "city", "state", "country"] address_as_dict = frappe.db.get_value("Address", filters=filters, fieldname=fieldname, as_dict=True) if address_as_dict: name, address_template = get_address_templates(address_as_dict) return address_as_dict.get("name"), frappe.render_template(address_template, address_as_dict)
def get_message(self): """return message with payment gateway link""" context = { "doc": frappe.get_doc(self.reference_doctype, self.reference_name), "payment_url": self.payment_url } return frappe.render_template(self.message, context)
def get_shipping_address(company): filters = {"company": company, "is_your_company_address": 1} fieldname = [ "name", "address_line1", "address_line2", "city", "state", "country" ] address_as_dict = frappe.db.get_value("Address", filters=filters, fieldname=fieldname, as_dict=True) if address_as_dict: name, address_template = get_address_templates(address_as_dict) return address_as_dict.get("name"), frappe.render_template( address_template, address_as_dict)
def get_address_display(address_dict): if not address_dict: return if not isinstance(address_dict, dict): address_dict = frappe.db.get_value( "Address", address_dict, "*", as_dict=True, cache=True) or {} name, template = get_address_templates(address_dict) try: return frappe.render_template(template, address_dict) except TemplateSyntaxError: frappe.throw( _("There is an error in your Address Template {0}").format(name))
def send_notification(self, new_doc): """Notify concerned people about recurring document generation""" subject = self.subject or '' message = self.message or '' if not self.subject: subject = _("New {0}: {1}").format(new_doc.doctype, new_doc.name) elif "{" in self.subject: subject = frappe.render_template(self.subject, {'doc': new_doc}) if not self.message: message = _("Please find attached {0}: {1}").format(new_doc.doctype, new_doc.name) elif "{" in self.message: message = frappe.render_template(self.message, {'doc': new_doc}) print_format = self.print_format or 'Standard' attachments = [frappe.attach_print(new_doc.doctype, new_doc.name, file_name=new_doc.name, print_format=print_format)] recipients = self.recipients.split('\n') make(doctype=new_doc.doctype, name=new_doc.name, recipients=recipients, subject=subject, content=message, attachments=attachments, send_email=1)
def send_mail(entry, email_campaign): recipient_list = [] if email_campaign.email_campaign_for == "Email Group": for member in frappe.db.get_list( "Email Group Member", filters={"email_group": email_campaign.get("recipient")}, fields=["email"]): recipient_list.append(member["email"]) else: recipient_list.append( frappe.db.get_value(email_campaign.email_campaign_for, email_campaign.get("recipient"), "email_id")) email_template = frappe.get_doc("Email Template", entry.get("email_template")) sender = frappe.db.get_value("User", email_campaign.get("sender"), "email") context = { "doc": frappe.get_doc(email_campaign.email_campaign_for, email_campaign.recipient) } # send mail and link communication to document comm = make( doctype="Email Campaign", name=email_campaign.name, subject=frappe.render_template(email_template.get("subject"), context), content=frappe.render_template(email_template.get("response"), context), sender=sender, recipients=recipient_list, communication_medium="Email", sent_or_received="Sent", send_email=True, email_template=email_template.name, ) return comm
def get_dummy_message(doc): return frappe.render_template( """{% if doc.contact_person -%} <p>Dear {{ doc.contact_person }},</p> {%- else %}<p>Hello,</p>{% endif %} <p>{{ _("Requesting payment against {0} {1} for amount {2}").format(doc.doctype, doc.name, doc.get_formatted("grand_total")) }}</p> <a href="{{ payment_url }}">{{ _("Make Payment") }}</a> <p>{{ _("If you have any questions, please get back to us.") }}</p> <p>{{ _("Thank you for your business!") }}</p> """, dict(doc=doc, payment_url='{{ payment_url }}'))
def create_system_notification(self, doc, context): subject = self.subject if "{" in subject: subject = frappe.render_template(self.subject, context) attachments = self.get_attachment(doc) recipients, cc, bcc = self.get_list_of_recipients(doc, context) users = recipients + cc + bcc if not users: return notification_doc = { 'type': 'Alert', 'document_type': doc.doctype, 'document_name': doc.name, 'subject': subject, 'from_user': doc.modified_by or doc.owner, 'email_content': frappe.render_template(self.message, context), 'attached_file': attachments and json.dumps(attachments[0]) } enqueue_create_notification(users, notification_doc)
def send_message(doc, message): patient_mobile = frappe.db.get_value("Patient", doc.patient, "mobile") if patient_mobile: context = {"doc": doc, "alert": doc, "comments": None} if doc.get("_comments"): context["comments"] = json.loads(doc.get("_comments")) # jinja to string convertion happens here message = frappe.render_template(message, context) number = [patient_mobile] try: send_sms(number, message) except Exception as e: frappe.msgprint(_("SMS not sent, please check SMS Settings"), alert=True)
def build_user_docs(self): """Build templates for user docs pages, if missing.""" #user_docs_path = os.path.join(self.docs_path, "user") # license with open(os.path.join(self.app_path, "..", "license.txt"), "r") as license_file: self.app_context["license_text"] = markdown(license_file.read()) html = frappe.render_template("templates/autodoc/license.html", context=self.app_context) with open(os.path.join(self.docs_path, "license.html"), "w") as license_file: license_file.write(html.encode("utf-8")) # contents shutil.copy( os.path.join( frappe.get_app_path("frappe", "templates", "autodoc", "contents.html")), os.path.join(self.docs_path, "contents.html")) shutil.copy( os.path.join( frappe.get_app_path("frappe", "templates", "autodoc", "contents.py")), os.path.join(self.docs_path, "contents.py")) # install html = frappe.render_template("templates/autodoc/install.md", context=self.app_context) with open(os.path.join(self.docs_path, "install.md"), "w") as f: f.write(html) self.update_index_txt(self.docs_path)
def send_registration_sms(doc): if (frappe.db.get_value("Healthcare Settings", None, "reg_sms") == '1'): if doc.mobile: context = {"doc": doc, "alert": doc, "comments": None} if doc.get("_comments"): context["comments"] = json.loads(doc.get("_comments")) messages = frappe.db.get_value("Healthcare Settings", None, "reg_msg") messages = frappe.render_template(messages, context) number = [doc.mobile] send_sms(number, messages) else: frappe.msgprint(doc.name + " Has no mobile number to send registration SMS", alert=True)
def prepare_and_attach_invoice(doc): progressive_name, progressive_number = get_progressive_name_and_number(doc) invoice = prepare_invoice(doc, progressive_number) invoice_xml = frappe.render_template( 'erpnext/regional/italy/e-invoice.xml', context={"doc": invoice}, is_path=True) xml_filename = progressive_name + ".xml" save_file(xml_filename, invoice_xml, dt=doc.doctype, dn=doc.name, is_private=True)
def get_awc_gateway_form(context={}): """This is the Gateway Selector embed form used by awc to embed itself on the cart's frontend""" context.update({ "source": "templates/includes/integrations/gateway_selector/embed.html", "submit_source": "templates/includes/integrations/gateway_selector/submit.html" }) print(context) context = _dict(context) build_embed_context(context) return { "form": frappe.render_template(context.source, context), "context": context, "submit": frappe.render_template(context.submit_source, context), "styles": context["gateway_styles"], "scripts": context["gateway_scripts"], "js_api_factory": "frappe.integration_service.gateway_selector_gateway" }
def add_custom_context_and_script(self, context): '''Update context from module if standard and append script''' if self.web_form_module: new_context = self.web_form_module.get_context(context) if new_context: context.update(new_context) js_path = os.path.join(os.path.dirname(self.web_form_module.__file__), scrub(self.name) + '.js') if os.path.exists(js_path): context.script = frappe.render_template(open(js_path, 'r').read(), context) css_path = os.path.join(os.path.dirname(self.web_form_module.__file__), scrub(self.name) + '.css') if os.path.exists(css_path): context.style = open(css_path, 'r').read()
def send_an_email(self, doc, context): from email.utils import formataddr subject = self.subject if "{" in subject: subject = frappe.render_template(self.subject, context) attachments = self.get_attachment(doc) recipients, cc, bcc = self.get_list_of_recipients(doc, context) sender = None if self.sender and self.sender_email: sender = formataddr((self.sender, self.sender_email)) frappe.sendmail( recipients=recipients, subject=subject, sender=sender, cc=cc, bcc=bcc, message=frappe.render_template(self.message, context), reference_doctype=doc.doctype, reference_name=doc.name, attachments=attachments, print_letterhead=((attachments and attachments[0].get('print_letterhead')) or False))
def send_email_notification(mr_list): """ Notify user about auto creation of indent""" email_list = frappe.db.sql_list("""select distinct r.parent from tabUserRole r, tabUser p where p.name = r.parent and p.enabled = 1 and p.docstatus < 2 and r.role in ('Purchase Manager','Stock Manager') and p.name not in ('Administrator', 'All', 'Guest')""") msg = frappe.render_template("templates/emails/reorder_item.html", { "mr_list": mr_list }) frappe.sendmail(recipients=email_list, subject=_('Auto Material Requests Generated'), message = msg)
def after_insert(self): replies = frappe.db.count("Discussion Reply", {"topic": self.topic}) topic_info = frappe.get_all("Discussion Topic", {"name": self.topic}, [ "reference_doctype", "reference_docname", "name", "title", "owner", "creation" ]) template = frappe.render_template( "frappe/templates/discussions/reply_card.html", { "reply": self, "topic": { "name": self.topic }, "loop": { "index": replies }, "single_thread": True if not topic_info[0].title else False }) sidebar = frappe.render_template( "frappe/templates/discussions/sidebar.html", {"topic": topic_info[0]}) new_topic_template = frappe.render_template( "frappe/templates/discussions/reply_section.html", {"topic": topic_info[0]}) frappe.publish_realtime(event="publish_message", message={ "template": template, "topic_info": topic_info[0], "sidebar": sidebar, "new_topic_template": new_topic_template }, after_commit=True)
def get_html_table(self, columns=None, data=None): date_time = global_date_format(now()) + ' ' + format_time(now()) report_doctype = frappe.db.get_value('Report', self.report, 'ref_doctype') return frappe.render_template('frappe/templates/emails/auto_email_report.html', { 'title': self.name, 'description': self.description, 'date_time': date_time, 'columns': columns, 'data': data, 'report_url': get_url_to_report(self.report, self.report_type, report_doctype), 'report_name': self.report, 'edit_report_settings': get_link_to_form('Auto Email Report', self.name) })
def get_contract_template(template_name, doc): if isinstance(doc, string_types): doc = json.loads(doc) contract_template = frappe.get_doc("Contract Template", template_name) contract_terms = None if contract_template.contract_terms: contract_terms = frappe.render_template( contract_template.contract_terms, doc) return { 'contract_template': contract_template, 'contract_terms': contract_terms }
def send_membership_creation_renewal_email(self,notification_name,args): if frappe.db.exists('Notification',notification_name): alert = frappe.get_doc('Notification',notification_name) if alert.enabled==1: doc=frappe.get_doc(self.doctype,self.name) context = get_context(doc) context = {"doc": doc, "alert": alert, "comments": None} from email.utils import formataddr subject = alert.subject if "{" in subject: subject = frappe.render_template(alert.subject, context) attachments = alert.get_attachment(doc) recipients, cc, bcc = alert.get_list_of_recipients(doc, context) if not (recipients or cc or bcc): return sender = None if alert.sender and alert.sender_email: sender = formataddr((alert.sender, alert.sender_email)) msg=frappe.render_template(alert.message,context) if args !=None: msg=frappe.render_template(msg, args) frappe.sendmail(recipients = recipients, subject = subject, sender = sender, cc = cc, bcc = bcc, message = msg, reference_doctype = doc.doctype, reference_name = doc.name, attachments = attachments, expose_recipients="header", print_letterhead = ((attachments and attachments[0].get('print_letterhead')) or False))
def get_care_symbol_html(bemusterung): # prepare query sql_query = """SELECT `tabPflegesymbol`.`titel` AS `title`, `tabPflegesymbol`.`image` AS `url` FROM `tabItem Pflegesymbol` LEFT JOIN `tabPflegesymbol` ON `tabItem Pflegesymbol`.`pflegesymbol` = `tabPflegesymbol`.`name` WHERE `tabItem Pflegesymbol`.`parenttype` = "Bemusterung" AND `tabItem Pflegesymbol`.`parent` = "{bemusterung}";""".format( bemusterung=bemusterung) # collect data data = {'symbols': frappe.db.sql(sql_query, as_dict=True)} # render data html = frappe.render_template('hoh/hoh/doctype/angebot/care_symbols.html', data) return html
def get_embed_form(self, context={}): context.update({ "source": "templates/includes/integrations/authorizenet/embed.html" }) context = _dict(context) self.get_embed_context(context) return { "form": frappe.render_template(context.source, context), "style_url": "/assets/css/authorizenet_embed.css", "script_url": "/assets/js/authorizenet_embed.js" }
def send_message(doc, message): patient_mobile = frappe.db.get_value('Patient', doc.patient, 'mobile') if patient_mobile: context = {'doc': doc, 'alert': doc, 'comments': None} if doc.get('_comments'): context['comments'] = json.loads(doc.get('_comments')) # jinja to string convertion happens here message = frappe.render_template(message, context) number = [patient_mobile] try: send_sms(number, message) except Exception as e: frappe.msgprint(_('SMS not sent, please check SMS Settings'), alert=True)
def do_assignment(self, doc): # clear existing assignment, to reassign assign_to.clear(doc.get('doctype'), doc.get('name')) user = self.get_user() assign_to.add( dict(assign_to=user, doctype=doc.get('doctype'), name=doc.get('name'), description=frappe.render_template(self.description, doc), assignment_rule=self.name)) # set for reference in round robin self.db_set('last_user', user)
def get_print_output(self, data: dict) -> str: """ Returns the print output of EditorJS content using the print_format defined. :param data: The dictionary of values to be inserted into the template """ context = frappe._dict(data) # Logic for handling file urls if self.type == 'image': # Print nothing if url is undefined if context.file is None or context.file.get("url") is None: return "" file_url = context.file.get("url") if 'https://' in file_url or 'http://' in file_url: context.file_url = file_url else: context.file_url = get_url() + file_url context.update(frappe._dict(site_url=get_url())) elif self.type == 'expandable': body = "" for item in context.get('body'): body += get_editor_template(item.get("type")).get_print_output( item.get("data")) context.update(frappe._dict(body=body)) elif self.type == 'Math': output = "" error = "" process = subprocess.Popen([ 'echo', '-n', " " + context.get("text").replace('\\\\', '\\') + " " ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) try: output = subprocess.check_output(('katex', '--display-mode'), stdin=process.stdout, stderr=subprocess.STDOUT) except Exception as e: frappe.log_error(frappe.as_json(e)) error = str(e) process.wait() context.update( frappe._dict(rendered_katex=error if not output else output. decode('utf-8'))) return frappe.render_template(self.print_format, context=context)
def authorize(**kwargs): success_url = "/api/method/frappe.integrations.oauth2.approve?" + encode_params( sanitize_kwargs(kwargs)) failure_url = frappe.form_dict["redirect_uri"] + "?error=access_denied" if frappe.session.user == 'Guest': #Force login, redirect to preauth again. frappe.local.response["type"] = "redirect" frappe.local.response["location"] = "/login?" + encode_params( {'redirect-to': frappe.request.url}) else: try: r = frappe.request scopes, frappe.flags.oauth_credentials = get_oauth_server( ).validate_authorization_request(r.url, r.method, r.get_data(), r.headers) skip_auth = frappe.db.get_value( "OAuth Client", frappe.flags.oauth_credentials['client_id'], "skip_authorization") unrevoked_tokens = frappe.get_all("OAuth Bearer Token", filters={"status": "Active"}) if skip_auth or (get_oauth_settings().skip_authorization == "Auto" and unrevoked_tokens): frappe.local.response["type"] = "redirect" frappe.local.response["location"] = success_url else: #Show Allow/Deny screen. response_html_params = frappe._dict({ "client_id": frappe.db.get_value("OAuth Client", kwargs['client_id'], "app_name"), "success_url": success_url, "failure_url": failure_url, "details": scopes }) resp_html = frappe.render_template( "templates/includes/oauth_confirmation.html", response_html_params) frappe.respond_as_web_page("Confirm Access", resp_html) except FatalClientError as e: return e except OAuth2Error as e: return e
def get(doctype, txt=None, limit_start=0, **kwargs): """Returns processed HTML page for a standard listing.""" limit_start = cint(limit_start) limit_page_length = 20 next_start = limit_start + limit_page_length filters = prepare_filters(kwargs) meta = frappe.get_meta(doctype) list_context = get_list_context(frappe._dict(), doctype) if list_context.filters: filters.update(list_context.filters) _get_list = list_context.get_list or get_list raw_result = _get_list(doctype=doctype, txt=txt, filters=filters, limit_start=limit_start, limit_page_length=limit_page_length) if not raw_result: return {"result": []} show_more = (_get_list(doctype=doctype, txt=txt, filters=filters, limit_start=next_start, limit_page_length=1) and True or False) if txt: list_context.default_subtitle = _('Filtered by "{0}"').format(txt) result = [] row_template = list_context.row_template or "templates/includes/list/row_template.html" for doc in raw_result: doc.doctype = doctype new_context = frappe._dict(doc=doc, meta=meta) if not frappe.flags.in_test: new_context["pathname"] = frappe.local.request.path.strip("/ ") new_context.update(list_context) set_route(new_context) rendered_row = frappe.render_template(row_template, new_context, is_path=True) result.append(rendered_row) return {"result": result, "show_more": show_more, "next_start": next_start}
def subscribe(email, email_group=_("Website")): """API endpoint to subscribe an email to a particular email group. Triggers a confirmation email. """ # build subscription confirmation URL api_endpoint = frappe.utils.get_url( "/api/method/frappe.email.doctype.newsletter.newsletter.confirm_subscription" ) signed_params = get_signed_params({ "email": email, "email_group": email_group }) confirm_subscription_url = f"{api_endpoint}?{signed_params}" # fetch custom template if available email_confirmation_template = frappe.db.get_value( "Email Group", email_group, "confirmation_email_template") # build email and send if email_confirmation_template: args = { "email": email, "confirmation_url": confirm_subscription_url, "email_group": email_group } email_template = frappe.get_doc("Email Template", email_confirmation_template) email_subject = email_template.subject content = frappe.render_template(email_template.response, args) else: email_subject = _("Confirm Your Email") translatable_content = ( _("Thank you for your interest in subscribing to our updates"), _("Please verify your Email Address"), confirm_subscription_url, _("Click here to verify"), ) content = """ <p>{0}. {1}.</p> <p><a href="{2}">{3}</a></p> """.format(*translatable_content) frappe.sendmail( email, subject=email_subject, content=content, now=True, )
def cancel_production_order(sales_order_name): settings = frappe.get_doc("Trumpf Settings") target_path = settings.physical_path order_codes = [] so = frappe.get_doc("Sales Order", sales_order_name) for i in sales_order.items: order_codes.append("{0}/{1}".format(sales_order_name, i.idx)) data = { 'order_codes': order_codes } content = frappe.render_template('kuchelmeister/trumpf/cancel_production_order.html', data) file = codecs.open("{path}DelProdOrderImp{sales_order}.xml".format(path=target_path, sales_order=sales_order_name), "w", "utf-8") file.write(content) file.close() return
def write_model_file(self, basepath, module, doctype): model_path = os.path.join(self.models_base_path, module, doctype + ".html") if not os.path.exists(model_path): model_json_path = os.path.join(basepath, doctype + ".json") if os.path.exists(model_json_path): with open(model_json_path, "r") as j: doctype_real_name = json.loads(j.read()).get("name") print "Writing " + model_path with open(model_path, "w") as f: context = {"doctype": doctype_real_name} context.update(self.app_context) f.write(frappe.render_template("templates/autodoc/doctype.html", context).encode("utf-8"))
def get_address_display(address_dict): if not address_dict: return if not isinstance(address_dict, dict): address_dict = frappe.db.get_value("Address", address_dict, "*", as_dict=True) or {} template = frappe.db.get_value("Address Template", \ {"country": address_dict.get("country")}, "template") if not template: template = frappe.db.get_value("Address Template", \ {"is_default": 1}, "template") if not template: frappe.throw(_("No default Address Template found. Please create a new one from Setup > Printing and Branding > Address Template.")) return frappe.render_template(template, address_dict)
def send_registration_sms(doc): if frappe.db.get_single_value('Healthcare Settings', 'send_registration_msg'): if doc.mobile: context = {'doc': doc, 'alert': doc, 'comments': None} if doc.get('_comments'): context['comments'] = json.loads(doc.get('_comments')) messages = frappe.db.get_single_value('Healthcare Settings', 'registration_msg') messages = frappe.render_template(messages, context) number = [doc.mobile] send_sms(number, messages) else: frappe.msgprint(doc.name + ' has no mobile number to send registration SMS', alert=True)