def notify_employee(self): employee = dataent.get_doc("Employee", self.employee) if not employee.user_id: return parent_doc = dataent.get_doc('Leave Application', self.name) args = parent_doc.as_dict() template = dataent.db.get_single_value( 'HR Settings', 'leave_status_notification_template') if not template: dataent.msgprint( _("Please set default template for Leave Status Notification in HR Settings." )) return email_template = dataent.get_doc("Email Template", template) message = dataent.render_template(email_template.response, args) self.notify({ # for post in messages "message": message, "message_to": employee.user_id, # for email "subject": email_template.subject, "notify": "employee" })
def update_cart_address(address_fieldname, address_name): quotation = _get_cart_quotation() address_display = get_address_display(dataent.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": dataent.render_template("templates/includes/order/order_taxes.html", context), }
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.path, "index.html"), "w") as home: home.write( dataent.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 get_timesheet_html(project, start=0): return dataent.render_template( "epaas/templates/includes/projects/project_timesheets.html", {"doc": { "timesheets": get_timesheets(project, start) }}, is_path=True)
def build_page(path): if not getattr(dataent.local, "path", None): dataent.local.path = path context = get_context(path) if context.source: html = dataent.render_template(context.source, context) elif context.template: if path.endswith('min.js'): html = dataent.get_jloader().get_source(dataent.get_jenv(), context.template)[0] else: html = dataent.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 = dataent.get_template(context.base_template_path).render(context) if can_cache(context.no_cache): page_cache = dataent.cache().hget("website_page", path) or {} page_cache[dataent.local.lang] = html dataent.cache().hset("website_page", path, page_cache) return html
def get_search_results(text, start=0, as_html=False): results = web_search(text, start, limit=21) out = dataent._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 = dataent.render_template( 'templates/includes/search_result.html', out) return out
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, "wb") as f: context = {"name": self.app + "." + module_name} context.update(self.app_context) context[ 'full_module_name'] = self.app + '.' + full_module_name f.write( dataent.render_template( "templates/autodoc/pymodule.html", context).encode('utf-8')) self.update_index_txt(module_folder)
def get_payment_reconciliation_details(self): currency = get_company_currency(self) return dataent.render_template( "epaas/selling/doctype/pos_closing_voucher/closing_voucher_details.html", { "data": self, "currency": currency })
def get_terms_and_conditions(template_name, doc): if isinstance(doc, string_types): doc = json.loads(doc) terms_and_conditions = dataent.get_doc("Terms and Conditions", template_name) if terms_and_conditions.terms: return dataent.render_template(terms_and_conditions.terms, doc)
def get_task_html(project, start=0, item_status=None): return dataent.render_template( "epaas/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 get_common_email_args(doc): doctype = doc.get('doctype') docname = doc.get('name') email_template = get_email_template(doc) if email_template: subject = dataent.render_template(email_template.subject, vars(doc)) response = dataent.render_template(email_template.response, vars(doc)) else: subject = _('Workflow Action') response = _('{0}: {1}'.format(doctype, docname)) common_args = { 'template': 'workflow_action', 'attachments': [dataent.attach_print(doctype, docname, file_name=docname)], 'subject': subject, 'message': response } return common_args
def notify_customers(delivery_trip): delivery_trip = dataent.get_doc("Delivery Trip", delivery_trip) context = delivery_trip.as_dict() if delivery_trip.driver: context.update( dataent.db.get_value("Driver", delivery_trip.driver, "cell_number", as_dict=1)) email_recipients = [] for stop in delivery_trip.delivery_stops: contact_info = dataent.db.get_value( "Contact", stop.contact, ["first_name", "last_name", "email_id"], as_dict=1) context.update({"items": []}) if stop.delivery_note: items = dataent.get_all("Delivery Note Item", filters={ "parent": stop.delivery_note, "docstatus": 1 }, fields=["*"]) context.update({"items": items}) if contact_info and contact_info.email_id: context.update(stop.as_dict()) context.update(contact_info) dispatch_template_name = dataent.db.get_single_value( "Delivery Settings", "dispatch_template") dispatch_template = dataent.get_doc("Email Template", dispatch_template_name) dataent.sendmail(recipients=contact_info.email_id, subject=dispatch_template.subject, message=dataent.render_template( dispatch_template.response, context), attachments=get_attachments(stop)) stop.db_set("email_sent_to", contact_info.email_id) email_recipients.append(contact_info.email_id) if email_recipients: dataent.msgprint( _("Email sent to {0}").format(", ".join(email_recipients))) delivery_trip.db_set("email_notification_sent", True) else: dataent.msgprint(_("No contacts with email IDs found."))
def load_assets(self): from dataent.modules import get_module_path, scrub import os self.script = '' page_name = scrub(self.name) path = os.path.join(get_module_path(self.module), 'page', page_name) # script fpath = os.path.join(path, page_name + '.js') if os.path.exists(fpath): with open(fpath, 'r') as f: self.script = render_include(f.read()) # css fpath = os.path.join(path, page_name + '.css') if os.path.exists(fpath): with open(fpath, 'r') as f: self.style = safe_decode(f.read()) # html as js template for fname in os.listdir(path): if fname.endswith(".html"): with open(os.path.join(path, fname), 'r') as f: template = f.read() if "<!-- jinja -->" in template: context = dataent._dict({}) try: out = dataent.get_attr("{app}.{module}.page.{page}.{page}.get_context".format( app = dataent.local.module_app[scrub(self.module)], module = scrub(self.module), page = page_name ))(context) if out: context = out except (AttributeError, ImportError): pass template = dataent.render_template(template, context) self.script = html_to_js_template(fname, template) + self.script # flag for not caching this page self._dynamic_page = True if dataent.lang != 'en': from dataent.translate import get_lang_js self.script += get_lang_js("page", self.name) for path in get_code_files_via_hooks("page_js", self.name): js = get_js(path) if js: self.script += "\n\n" + js
def get_message(self): """return message with payment gateway link""" context = { "doc": dataent.get_doc(self.reference_doctype, self.reference_name), "payment_url": self.payment_url } if self.message: return dataent.render_template(self.message, context)
def send_message(doc, message): patient = dataent.get_doc("Patient", doc.patient) 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 = dataent.render_template(message, context) number = [patient.mobile] send_sms(number, message)
def get_list_of_recipients(self, doc, context): recipients = [] cc = [] bcc = [] for recipient in self.recipients: if recipient.condition: if not dataent.safe_eval(recipient.condition, None, context): continue if recipient.email_by_document_field: email_ids_value = doc.get(recipient.email_by_document_field) if validate_email_add(email_ids_value): email_ids = email_ids_value.replace(",", "\n") recipients = recipients + email_ids.split("\n") # else: # print "invalid email" if recipient.cc and "{" in recipient.cc: recipient.cc = dataent.render_template(recipient.cc, context) if recipient.cc: recipient.cc = recipient.cc.replace(",", "\n") cc = cc + recipient.cc.split("\n") if recipient.bcc and "{" in recipient.bcc: recipient.bcc = dataent.render_template(recipient.bcc, context) if recipient.bcc: recipient.bcc = recipient.bcc.replace(",", "\n") bcc = bcc + recipient.bcc.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 and not cc and not bcc: return None, None, None return list(set(recipients)), list(set(cc)), list(set(bcc))
def get(doctype, txt=None, limit_start=0, limit=20, pathname=None, **kwargs): """Returns processed HTML page for a standard listing.""" limit_start = cint(limit_start) raw_result = get_list_data(doctype, txt, limit_start, limit=limit + 1, **kwargs) show_more = len(raw_result) > limit if show_more: raw_result = raw_result[:-1] meta = dataent.get_meta(doctype) list_context = dataent.flags.list_context if not raw_result: return {"result": []} 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" list_view_fields = [df for df in meta.fields if df.in_list_view][:4] for doc in raw_result: doc.doctype = doctype new_context = dataent._dict(doc=doc, meta=meta, list_view_fields=list_view_fields) if not list_context.get_list and not isinstance( new_context.doc, Document): new_context.doc = dataent.get_doc(doc.doctype, doc.name) new_context.update(new_context.doc.as_dict()) if not dataent.flags.in_test: pathname = pathname or dataent.local.request.path new_context["pathname"] = pathname.strip("/ ") new_context.update(list_context) set_route(new_context) rendered_row = dataent.render_template(row_template, new_context, is_path=True) result.append(rendered_row) from dataent.utils.response import json_handler return { "raw_result": json.dumps(raw_result, default=json_handler), "result": result, "show_more": show_more, "next_start": limit_start + limit, }
def send_an_email(self, doc, context): from email.utils import formataddr subject = self.subject if "{" in subject: subject = dataent.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)) dataent.sendmail(recipients = recipients, subject = subject, sender = sender, cc = cc, bcc = bcc, message = dataent.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 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 = dataent.render_template("templates/autodoc/license.html", context=self.app_context) with open(os.path.join(self.docs_path, "license.html"), "wb") as license_file: license_file.write(html.encode("utf-8")) # contents shutil.copy( os.path.join( dataent.get_app_path("dataent", "templates", "autodoc", "contents.html")), os.path.join(self.docs_path, "contents.html")) shutil.copy( os.path.join( dataent.get_app_path("dataent", "templates", "autodoc", "contents.py")), os.path.join(self.docs_path, "contents.py")) # install html = dataent.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 get_address_display(address_dict): if not address_dict: return if not isinstance(address_dict, dict): address_dict = dataent.db.get_value( "Address", address_dict, "*", as_dict=True, cache=True) or {} name, template = get_address_templates(address_dict) try: return dataent.render_template(template, address_dict) except TemplateSyntaxError: dataent.throw( _("There is an error in your Address Template {0}").format(name))
def send_email_notification(mr_list): """ Notify user about auto creation of indent""" email_list = dataent.db.sql_list("""select distinct r.parent from `tabHas Role` 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 = dataent.render_template("templates/emails/reorder_item.html", { "mr_list": mr_list }) dataent.sendmail(recipients=email_list, subject=_('Auto Material Requests Generated'), message = msg)
def get_dummy_message(doc): return dataent.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 send_registration_sms(doc): if (dataent.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 = dataent.db.get_value("Healthcare Settings", None, "reg_msg") messages = dataent.render_template(messages, context) number = [doc.mobile] send_sms(number, messages) else: dataent.msgprint(doc.name + " Has no mobile number to send registration SMS", alert=True)
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 = dataent.render_template('epaas/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 prepare_header_footer(soup): options = {} head = soup.find("head").contents styles = soup.find_all("style") bootstrap = dataent.read_file( os.path.join(dataent.local.sites_path, "assets/dataent/css/bootstrap.css")) fontawesome = dataent.read_file( os.path.join(dataent.local.sites_path, "assets/dataent/css/font-awesome.css")) # extract header and footer for html_id in ("header-html", "footer-html"): content = soup.find(id=html_id) if content: # there could be multiple instances of header-html/footer-html for tag in soup.find_all(id=html_id): tag.extract() toggle_visible_pdf(content) html = dataent.render_template( "templates/print_formats/pdf_header_footer.html", { "head": head, "styles": styles, "content": content, "html_id": html_id, "bootstrap": bootstrap, "fontawesome": fontawesome }) # create temp file fname = os.path.join( "/tmp", "dataent-pdf-{0}.html".format(dataent.generate_hash())) with open(fname, "wb") as f: f.write(html.encode("utf-8")) # {"header-html": "/tmp/dataent-pdf-random.html"} options[html_id] = fname else: if html_id == "header-html": options["margin-top"] = "15mm" elif html_id == "footer-html": options["margin-bottom"] = "15mm" return options
def authorize(*args, **kwargs): #Fetch provider URL from settings oauth_settings = get_oauth_settings() params = get_urlparams_from_kwargs(kwargs) request_url = urlparse(dataent.request.url) success_url = request_url.scheme + "://" + request_url.netloc + "/api/method/dataent.integrations.oauth2.approve?" + params failure_url = dataent.form_dict["redirect_uri"] + "?error=access_denied" if dataent.session['user']=='Guest': #Force login, redirect to preauth again. dataent.local.response["type"] = "redirect" dataent.local.response["location"] = "/login?redirect-to=/api/method/dataent.integrations.oauth2.authorize?" + quote(params.replace("+"," ")) elif dataent.session['user']!='Guest': try: r = dataent.request uri = url_fix(r.url) http_method = r.method body = r.get_data() headers = r.headers scopes, dataent.flags.oauth_credentials = get_oauth_server().validate_authorization_request(uri, http_method, body, headers) skip_auth = dataent.db.get_value("OAuth Client", dataent.flags.oauth_credentials['client_id'], "skip_authorization") unrevoked_tokens = dataent.get_all("OAuth Bearer Token", filters={"status":"Active"}) if skip_auth or (oauth_settings["skip_authorization"] == "Auto" and len(unrevoked_tokens)): dataent.local.response["type"] = "redirect" dataent.local.response["location"] = success_url else: #Show Allow/Deny screen. response_html_params = dataent._dict({ "client_id": dataent.db.get_value("OAuth Client", kwargs['client_id'], "app_name"), "success_url": success_url, "failure_url": failure_url, "details": scopes }) resp_html = dataent.render_template("templates/includes/oauth_confirmation.html", response_html_params) dataent.respond_as_web_page("Confirm Access", resp_html) except FatalClientError as e: return e except OAuth2Error as e: return e
def get_shipping_address(company, address=None): filters = [["Dynamic Link", "link_doctype", "=", "Company"], ["Dynamic Link", "link_name", "=", company], ["Address", "is_your_company_address", "=", 1]] fields = ["*"] if address and dataent.db.get_value('Dynamic Link', { 'parent': address, 'link_name': company }): filters.append(["Address", "name", "=", address]) address = dataent.get_all("Address", filters=filters, fields=fields) or {} if address: address_as_dict = address[0] name, address_template = get_address_templates(address_as_dict) return address_as_dict.get("name"), dataent.render_template( address_template, address_as_dict)
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, "wb") as f: context = {"doctype": doctype_real_name} context.update(self.app_context) f.write( dataent.render_template( "templates/autodoc/doctype.html", context).encode("utf-8"))
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 = dataent.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 get_msg_html(self): """Build email digest content""" dataent.flags.ignore_account_permission = True from epaas.setup.doctype.email_digest.quotes import get_random_quote context = dataent._dict() context.update(self.__dict__) self.set_title(context) self.set_style(context) self.set_accounting_cards(context) if self.get("calendar_events"): context.events, context.event_count = self.get_calendar_events() if self.get("todo_list"): context.todo_list = self.get_todo_list() context.todo_count = self.get_todo_count() if self.get("notifications"): context.notifications = self.get_notifications() if self.get("issue"): context.issue_list = self.get_issue_list() context.issue_count = self.get_issue_count() if self.get("project"): context.project_list = self.get_project_list() context.project_count = self.get_project_count() quote = get_random_quote() context.quote = {"text": quote[0], "author": quote[1]} if not (context.events or context.todo_list or context.notifications or context.cards): return None dataent.flags.ignore_account_permission = False # style return dataent.render_template( "epaas/setup/doctype/email_digest/templates/default.html", context, is_path=True)