def repost_si(si_failed_list): si_list = get_affected_sales_invoice() if si_list: print "-"*40 print "Reposting Sales Invoice" for si in si_list: if si.docstatus == 0: continue print si.name try: si_doc = frappe.get_doc("Sales Invoice", si.name) si_doc.docstatus = 2 si_doc.update_stock_ledger() frappe.db.sql("""delete from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s""", si.name) frappe.db.sql("update `tabSales Invoice Item` set target_warehouse='' where parent=%s", si.name) si_doc = frappe.get_doc("Sales Invoice", si.name) si_doc.docstatus = 1 si_doc.update_stock_ledger() si_doc.make_gl_entries() frappe.db.commit() except Exception: si_failed_list.append(si.name) frappe.local.stockledger_exceptions = None print frappe.get_traceback() frappe.db.rollback() frappe.db.sql("update `tabSales Invoice Item` set target_warehouse='' where docstatus=0")
def repost_dn(dn_failed_list): dn_list = get_affected_delivery_notes() if dn_list: print "-"*40 print "Reposting Delivery Notes" for dn in dn_list: if dn.docstatus == 0: continue print dn.name try: dn_doc = frappe.get_doc("Delivery Note", dn.name) dn_doc.docstatus = 2 dn_doc.update_prevdoc_status() dn_doc.update_stock_ledger() dn_doc.cancel_packing_slips() frappe.db.sql("""delete from `tabGL Entry` where voucher_type='Delivery Note' and voucher_no=%s""", dn.name) frappe.db.sql("update `tabDelivery Note Item` set target_warehouse='' where parent=%s", dn.name) dn_doc = frappe.get_doc("Delivery Note", dn.name) dn_doc.docstatus = 1 dn_doc.on_submit() frappe.db.commit() except Exception: dn_failed_list.append(dn.name) frappe.local.stockledger_exceptions = None print frappe.get_traceback() frappe.db.rollback() frappe.db.sql("update `tabDelivery Note Item` set target_warehouse='' where docstatus=0")
def pack(target, sources, no_compress): from cStringIO import StringIO outtype, outtxt = target.split(".")[-1], '' jsm = JavascriptMinify() for f in sources: suffix = None if ':' in f: f, suffix = f.split(':') if not os.path.exists(f) or os.path.isdir(f): continue timestamps[f] = os.path.getmtime(f) try: with open(f, 'r') as sourcefile: data = unicode(sourcefile.read(), 'utf-8', errors='ignore') if outtype=="js" and (not no_compress) and suffix!="concat" and (".min." not in f): tmpin, tmpout = StringIO(data.encode('utf-8')), StringIO() jsm.minify(tmpin, tmpout) outtxt += unicode(tmpout.getvalue() or '', 'utf-8').strip('\n') + ';' else: outtxt += ('\n/*\n *\t%s\n */' % f) outtxt += '\n' + data + '\n' except Exception, e: print "--Error in:" + f + "--" print frappe.get_traceback()
def repost_all_stock_vouchers(): warehouses_with_account = frappe.db.sql_list("""select warehouse from tabAccount where ifnull(account_type, '') = 'Stock' and (warehouse is not null and warehouse != '') and is_group=0""") vouchers = frappe.db.sql("""select distinct voucher_type, voucher_no from `tabStock Ledger Entry` sle where voucher_type != "Serial No" and sle.warehouse in (%s) order by posting_date, posting_time, name""" % ', '.join(['%s']*len(warehouses_with_account)), tuple(warehouses_with_account)) rejected = [] i = 0 for voucher_type, voucher_no in vouchers: i+=1 print i, "/", len(vouchers), voucher_type, voucher_no try: for dt in ["Stock Ledger Entry", "GL Entry"]: frappe.db.sql("""delete from `tab%s` where voucher_type=%s and voucher_no=%s"""% (dt, '%s', '%s'), (voucher_type, voucher_no)) doc = frappe.get_doc(voucher_type, voucher_no) if voucher_type=="Stock Entry" and doc.purpose in ["Manufacture", "Repack"]: doc.calculate_rate_and_amount(force=1) elif voucher_type=="Purchase Receipt" and doc.is_subcontracted == "Yes": doc.validate() doc.update_stock_ledger() doc.make_gl_entries(repost_future_gle=False) frappe.db.commit() except Exception, e: print frappe.get_traceback() rejected.append([voucher_type, voucher_no]) frappe.db.rollback()
def import_csv(context, path, only_insert=False, submit_after_import=False, ignore_encoding_errors=False): "Import CSV using data import tool" from frappe.core.page.data_import_tool import importer from frappe.utils.csvutils import read_csv_content site = get_site(context) with open(path, "r") as csvfile: content = read_csv_content(csvfile.read()) frappe.init(site=site) frappe.connect() try: importer.upload( content, submit_after_import=submit_after_import, ignore_encoding_errors=ignore_encoding_errors, overwrite=not only_insert, via_console=True, ) frappe.db.commit() except Exception: print frappe.get_traceback() frappe.destroy()
def import_json(file, defaults): with open(file, 'r') as f: data = json.loads(f.read()) could_not_create = [] try: for i, d in enumerate(data): try: import_doc(d, defaults) frappe.db.commit() except Exception, e: frappe.db.rollback() could_not_create.append(d) if 'Item Code is mandatory' in cstr(e): pass else: print frappe.get_traceback() finally: print '-'*80 print file print frappe.as_json(could_not_create)
def get_user_profile(data): request_data = json.loads(data) putil.validate_for_user_id_exists(request_data.get("user_id")) try: user_data = frappe.db.sql(""" SELECT ifnull(first_name, "") AS first_name, ifnull(last_name, "") AS last_name, ifnull(user_image,"") AS profile_photo, ifnull(user_id,"") AS user_id, ifnull(email, "") AS email, ifnull(mobile_no, "") AS mobile_number, ifnull(state, "") AS state, ifnull(city,"") AS city, ifnull(address, "") AS address, ifnull(area, "") AS area, ifnull(pincode, "") AS pincode, ifnull(birth_date, "") AS dob, ifnull(lattitude,"") AS geo_location_lat, ifnull(longitude,"") AS geo_location_lon FROM `tabUser` WHERE user_id = '{0}' """.format(request_data.get("user_id")),as_dict=True) user_data = user_data[0] if user_data.get("profile_photo"): user_data["profile_photo"] = frappe.request.host_url + user_data.get("profile_photo") user_data["city"] = frappe.db.get_value("City",user_data["city"],"city_name") or "" user_data["location"] = frappe.db.get_value("Area",user_data["area"],"area") or "" user_data["dob"] = datetime.datetime.strftime(getdate(user_data["dob"]), "%d-%m-%Y") if user_data["dob"] else "" user_data.pop("area",None) return {"operation":"Search", "message":"Profile Found", "data":user_data, "user_id":request_data.get("user_id")} except Exception,e: print frappe.get_traceback() raise e raise GetUserProfileOperationFailed("User Profile Operation failed")
def run_background(prepared_report): instance = frappe.get_doc("Prepared Report", prepared_report) report = frappe.get_doc("Report", instance.ref_report_doctype) try: report.custom_columns = [] if report.report_type == 'Custom Report': custom_report_doc = report reference_report = custom_report_doc.reference_report report = frappe.get_doc("Report", reference_report) report.custom_columns = custom_report_doc.json result = generate_report_result(report, filters=instance.filters, user=instance.owner) create_json_gz_file(result['result'], 'Prepared Report', instance.name) instance.status = "Completed" instance.columns = json.dumps(result["columns"]) instance.report_end_time = frappe.utils.now() instance.save() except Exception: frappe.log_error(frappe.get_traceback()) instance = frappe.get_doc("Prepared Report", prepared_report) instance.status = "Error" instance.error_message = frappe.get_traceback() instance.save() frappe.publish_realtime( 'report_generated', {"report_name": instance.report_name, "name": instance.name}, user=frappe.session.user )
def create_lead_from_userid(request_data, email, response): user_data = frappe.db.get_value("User", {"email":email}, '*',as_dict=True) try: lead_name = frappe.db.get_value("Lead",{"email_id":email},"name") if create_show_property_contact_entry(user_data, response): if not lead_name: lead = frappe.new_doc("Lead") lead.lead_name = user_data.get("first_name") lead.email_id = user_data.get("email") lead.lead_from = "Propshikari" lead.mobile_no = user_data.get("mobile_no") lead.state = user_data.get("state") lead.city = user_data.get("city") lead.location = user_data.get("location") lead.save(ignore_permissions=True) lead_name = lead.name address_nm = create_lead_address_from_user_data(user_data, lead_name) address_nm = frappe.db.get_value("Address", {"is_primary_address":1, "lead":lead_name},"name") if not frappe.db.get_value("Enquiry", {"lead":lead_name}, "name"): create_enquiry(user_data, lead_name, address_nm, response) elif not frappe.db.sql(""" select e.name from `tabEnquiry` e , `tabProperty Details` pd where pd.parent = e.name and pd.property_id = '{0}' and e.lead = '{1}' """.format(response.get("property_id"), lead_name)): update_enquiry(lead_name, response) except Exception,e: print "lead & Enquiry creation Error" print response.get("property_id") print frappe.get_traceback()
def share_property_to_agents(request_data): if request_data: email = putil.validate_for_user_id_exists(request_data.get("user_id")) user_name = frappe.db.get_value("User", {"user_id":request_data.get("user_id")}, ["first_name", "last_name"],as_dict=True) putil.validate_property_data(request_data, ["comments", "email_id"]) try: property_ids_list = { comment.get("property_id"):[comment.get("comment",""),comment.get("prop_through", ""),comment.get("doc_available", "")] for comment in request_data.get("comments") if comment.get("property_id")} search_query = { "query":{ "ids":{ "values":property_ids_list.keys() } }} es = ElasticSearchController() response_data, total_records = es.search_document(["property"], search_query, request_data.get("page_number",1), request_data.get("records_per_page",40)) if response_data: for response in response_data: response["comments"] = property_ids_list.get(response.get("property_id"),"")[0] response["property_through"] = property_ids_list.get(response.get("property_id"),"")[1] response["doc_available"] = property_ids_list.get(response.get("property_id"),"")[2] make_shared_doc_entry(response,email,request_data.get("email_id")) args = { "title":"Property Shared by {0}".format(email) , "property_data":response_data ,"first_name":user_name.get("first_name"), "last_name":user_name.get("last_name")} send_email(request_data.get("email_id"), "Propshikari properties shared with you", "/templates/share_agents_property.html", args) return { "operation":"Share", "message":"Property Shared Successfully"} else: raise DoesNotExistError("Property Id does not exists in elastic search") except frappe.OutgoingEmailError: raise OutgoingEmailError("Email can not be sent,Outgoing email error") except elasticsearch.TransportError: raise DoesNotExistError("Property Id does not exists") except elasticsearch.ElasticsearchException,e: raise ElasticSearchException(e.error) except Exception,e: print frappe.get_traceback() raise OperationFailed("Share Property Operation Failed")
def execute(): if not frappe.db.get_single_value("Accounts Settings", "auto_accounting_for_stock"): return frappe.reload_doctype("Account") warehouses = frappe.db.sql_list("""select name from tabAccount where account_type = 'Stock' and is_group = 0 and (warehouse is null or warehouse = '')""") if warehouses: warehouses = set_warehouse_for_stock_account(warehouses) stock_vouchers = frappe.db.sql("""select distinct sle.voucher_type, sle.voucher_no from `tabStock Ledger Entry` sle where sle.warehouse in (%s) and creation > '2016-05-01' and not exists(select name from `tabGL Entry` where account=sle.warehouse and voucher_type=sle.voucher_type and voucher_no=sle.voucher_no) order by sle.posting_date""" % ', '.join(['%s']*len(warehouses)), tuple(warehouses)) rejected = [] for voucher_type, voucher_no in stock_vouchers: try: frappe.db.sql("""delete from `tabGL Entry` where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no)) voucher = frappe.get_doc(voucher_type, voucher_no) voucher.make_gl_entries() frappe.db.commit() except Exception, e: print frappe.get_traceback() rejected.append([voucher_type, voucher_no]) frappe.db.rollback() print rejected
def import_csv(context, path, only_insert=False, submit_after_import=False, ignore_encoding_errors=False, no_email=True): "Import CSV using data import tool" from frappe.core.page.data_import_tool import importer from frappe.utils.csvutils import read_csv_content site = get_site(context) if not os.path.exists(path): path = os.path.join('..', path) if not os.path.exists(path): print 'Invalid path {0}'.format(path) sys.exit(1) with open(path, 'r') as csvfile: content = read_csv_content(csvfile.read()) frappe.init(site=site) frappe.connect() try: importer.upload(content, submit_after_import=submit_after_import, no_email=no_email, ignore_encoding_errors=ignore_encoding_errors, overwrite=not only_insert, via_console=True) frappe.db.commit() except Exception: print frappe.get_traceback() frappe.destroy()
def execute(): from frappe.core.doctype.file.file import make_home_folder if not frappe.db.exists("DocType", "File"): frappe.rename_doc("DocType", "File Data", "File") frappe.reload_doctype("File") if not frappe.db.exists("File", {"is_home_folder": 1}): make_home_folder() # make missing folders and set parent folder for file in frappe.get_all("File", filters={"is_folder": 0}): file = frappe.get_doc("File", file.name) file.flags.ignore_folder_validate = True file.flags.ignore_file_validate = True file.flags.ignore_duplicate_entry_error = True file.flags.ignore_links = True file.set_folder_name() try: file.save() except: print frappe.get_traceback() raise from frappe.utils.nestedset import rebuild_tree rebuild_tree("File", "folder") # reset file size for folder in frappe.db.sql("""select name from tabFile f1 where is_folder = 1 and (select count(*) from tabFile f2 where f2.folder = f1.name and f2.is_folder = 1) = 0"""): folder = frappe.get_doc("File", folder[0]) folder.save()
def receive(self, test_mails=None): """Called by scheduler to receive emails from this EMail account using POP3/IMAP.""" if self.enable_incoming: exceptions = [] if frappe.local.flags.in_test: incoming_mails = test_mails else: email_server = self.get_server(in_receive=True) if not email_server: return try: incoming_mails = email_server.get_messages() except Exception as e: frappe.db.sql("update `tabEmail Account` set no_remaining = NULL where name = %s",(self.name), auto_commit=1) incoming_mails = [] for msg in incoming_mails: try: communication = self.insert_communication(msg) #self.notify_update() except SentEmailInInbox as e: frappe.db.rollback() if self.use_imap: self.handle_bad_emails(email_server, msg[1], msg[0], "sent email in inbox") except Exception as e: frappe.db.rollback() log('email_account.receive') if self.use_imap: self.handle_bad_emails(email_server, msg[1], msg[0], frappe.get_traceback()) exceptions.append(frappe.get_traceback()) else: frappe.db.commit() attachments = [d.file_name for d in communication._attachments] if communication.message_id and not communication.timeline_hide: first = frappe.db.get_value("Communication", {"message_id": communication.message_id},["name"],order_by="creation",as_dict=1) if first: if first.name != communication.name: frappe.db.sql("""update tabCommunication set timeline_hide =%s where name = %s""",(first.name,communication.name),auto_commit=1) if self.no_remaining == '0' and not frappe.local.flags.in_test: if communication.reference_doctype : if not communication.timeline_hide and not communication.unread_notification_sent: communication.notify(attachments=attachments, fetched_from_email_account=True) #notify if user is linked to account if len(incoming_mails)>0 and not frappe.local.flags.in_test: frappe.publish_realtime('new_email', {"account":self.email_account_name, "account_name": self.name, "number":len(incoming_mails)}) if exceptions: raise Exception, frappe.as_json(exceptions)
def authorize_payment(self): """ An authorization is performed when user’s payment details are successfully authenticated by the bank. The money is deducted from the customer’s account, but will not be transferred to the merchant’s account until it is explicitly captured by merchant. """ data = json.loads(self.integration_request.data) settings = self.get_settings(data) try: resp = make_get_request("https://api.razorpay.com/v1/payments/{0}" .format(self.data.razorpay_payment_id), auth=(settings.api_key, settings.api_secret)) if resp.get("status") == "authorized": self.integration_request.update_status(data, 'Authorized') self.flags.status_changed_to = "Authorized" else: frappe.log_error(str(resp), 'Razorpay Payment not authorized') except: frappe.log_error(frappe.get_traceback()) # failed pass status = frappe.flags.integration_request.status_code redirect_to = data.get('notes', {}).get('redirect_to') or None redirect_message = data.get('notes', {}).get('redirect_message') or None if self.flags.status_changed_to == "Authorized": if self.data.reference_doctype and self.data.reference_docname: custom_redirect_to = None try: custom_redirect_to = frappe.get_doc(self.data.reference_doctype, self.data.reference_docname).run_method("on_payment_authorized", self.flags.status_changed_to) except Exception: frappe.log_error(frappe.get_traceback()) if custom_redirect_to: redirect_to = custom_redirect_to redirect_url = 'payment-success' else: redirect_url = 'payment-failed' if redirect_to: redirect_url += '?' + urlencode({'redirect_to': redirect_to}) if redirect_message: redirect_url += '&' + urlencode({'redirect_message': redirect_message}) return { "redirect_to": redirect_url, "status": status }
def create_charge_on_stripe(self): headers = {"Authorization": "Bearer {0}".format(self.get_password(fieldname="secret_key", raise_exception=False))} data = { "amount": cint(flt(self.data.amount)*100), "currency": self.data.currency, "source": self.data.stripe_token_id, "description": self.data.description } redirect_to = self.data.get('redirect_to') or None redirect_message = self.data.get('redirect_message') or None try: resp = make_post_request(url="https://api.stripe.com/v1/charges", headers=headers, data=data) if resp.get("captured") == True: self.integration_request.db_set('status', 'Completed', update_modified=False) self.flags.status_changed_to = "Completed" else: frappe.log_error(str(resp), 'Stripe Payment not completed') except: frappe.log_error(frappe.get_traceback()) # failed pass status = frappe.flags.integration_request.status_code if self.flags.status_changed_to == "Completed": if self.data.reference_doctype and self.data.reference_docname: custom_redirect_to = None try: custom_redirect_to = frappe.get_doc(self.data.reference_doctype, self.data.reference_docname).run_method("on_payment_authorized", self.flags.status_changed_to) except Exception: frappe.log_error(frappe.get_traceback()) if custom_redirect_to: redirect_to = custom_redirect_to redirect_url = 'payment-success' else: redirect_url = 'payment-failed' if redirect_to: redirect_url += '?' + urlencode({'redirect_to': redirect_to}) if redirect_message: redirect_url += '&' + urlencode({'redirect_message': redirect_message}) return { "redirect_to": redirect_url, "status": status }
def execute(): frappe.reload_doc("utilities", "doctype", "address_template") if not frappe.db.sql("select name from `tabAddress Template`"): try: d = frappe.new_doc("Address Template") d.update({"country":frappe.db.get_default("country") or frappe.db.get_value("Global Defaults", "Global Defaults", "country")}) d.insert() except: print frappe.get_traceback()
def enqueue_events_for_all_sites(): '''Loop through sites and enqueue events that are not already queued''' with frappe.init_site(): jobs_per_site = get_jobs() sites = get_sites() for site in sites: try: enqueue_events_for_site(site=site, queued_jobs=jobs_per_site[site]) except: # it should try to enqueue other sites print frappe.get_traceback()
def create_snapshot(): snapshot_repo = frappe.get_hooks("snapshot_repo", app_name="propshikari")[0] snapshot_name = get_datetime().strftime("%Y%m%d_%H%M%S") es = ElasticSearchController() print now() try: response = es.create_snapshot(snapshot_repo, snapshot_name) if not response.get("state") == "SUCCESS": send_email(["*****@*****.**"], "Propshikari Elastic Backup Operation Error", "/templates/elastic_backup_notification.html", {"error_log":response}) return response except Exception,e: print "Elastic Backup Operation Failed" print frappe.get_traceback() print "Error Occured : ",e send_email(["*****@*****.**", "*****@*****.**"], "Propshikari Elastic Backup Operation Error", "/templates/elastic_backup_notification.html", {"error_log":frappe.get_traceback()})
def upload(): if not frappe.has_permission("BRS Entries", "create"): raise frappe.PermissionError from frappe.utils.csvutils import read_csv_content_from_uploaded_file from frappe.modules import scrub rows = read_csv_content_from_uploaded_file() rows = filter(lambda x: x and any(x), rows) if not rows: msg = [_("Please select a csv file")] return {"messages": msg, "error": msg} #Columns located at 4th row columns = [scrub(f) for f in rows[2]] ret = [] error = False from frappe.utils.csvutils import check_record, import_doc for i, row in enumerate(rows[3:]): if not row: continue row_idx = i + 3 d = frappe._dict(zip(columns, row)) d["doctype"] = "BRS Entries" try: check_record(d) ret.append(import_doc(d, "BRS Entries", 1, row_idx, submit=True)) except Exception, e: error = True ret.append('Error for row (#%d) %s : %s' % (row_idx, len(row)>1 and row[1] or "", cstr(e))) frappe.errprint(frappe.get_traceback())
def new_bank_transaction(transaction): result = [] bank_account = frappe.db.get_value("Bank Account", dict(integration_id=transaction["account_id"])) if float(transaction["amount"]) >= 0: debit = float(transaction["amount"]) credit = 0 else: debit = 0 credit = abs(float(transaction["amount"])) status = "Pending" if transaction["pending"] == "True" else "Settled" if not frappe.db.exists("Bank Transaction", dict(transaction_id=transaction["transaction_id"])): try: new_transaction = frappe.get_doc({ "doctype": "Bank Transaction", "date": getdate(transaction["date"]), "status": status, "bank_account": bank_account, "debit": debit, "credit": credit, "currency": transaction["iso_currency_code"], "description": transaction["name"] }) new_transaction.insert() new_transaction.submit() result.append(new_transaction.name) except Exception: frappe.throw(frappe.get_traceback()) return result
def setup_complete(args): """Calls hooks for `setup_wizard_complete`, sets home page as `desktop` and clears cache. If wizard breaks, calls `setup_wizard_exception` hook""" args = process_args(args) try: if args.language and args.language != "english": set_default_language(args.language) frappe.clear_cache() # update system settings update_system_settings(args) for method in frappe.get_hooks("setup_wizard_complete"): frappe.get_attr(method)(args) # frappe.db.set_default('desktop:home_page', 'desktop') frappe.db.set_default('desktop:home_page', 'dashboard') frappe.db.commit() frappe.clear_cache() except: if args: traceback = frappe.get_traceback() for hook in frappe.get_hooks("setup_wizard_exception"): frappe.get_attr(hook)(traceback, args) raise else: for hook in frappe.get_hooks("setup_wizard_success"): frappe.get_attr(hook)(args)
def upload_from_folder(path, dropbox_folder, dropbox_client, did_not_upload, error_log): if not os.path.exists(path): return try: response = dropbox_client.files_list_folder(dropbox_folder) except dropbox.exceptions.ApiError as e: # folder not found if isinstance(e.error, dropbox.files.ListFolderError): response = frappe._dict({"entries": []}) else: raise for filename in os.listdir(path): filename = cstr(filename) if filename in ignore_list: continue found = False filepath = os.path.join(path, filename) for file_metadata in response.entries: if (os.path.basename(filepath) == file_metadata.name and os.stat(encode(filepath)).st_size == int(file_metadata.size)): found = True break if not found: try: upload_file_to_dropbox(filepath, dropbox_folder, dropbox_client) except Exception: did_not_upload.append(filename) error_log.append(frappe.get_traceback())
def send_newsletter(site, newsletter, event): # hack! pass event="bulk_long" to queue in longjob queue try: frappe.connect(site=site) doc = frappe.get_doc("Newsletter", newsletter) doc.send_bulk() except: frappe.db.rollback() task_logger.error(site) task_logger.error(frappe.get_traceback()) # wasn't able to send emails :( doc.db_set("email_sent", 0) frappe.db.commit() log("send_newsletter") raise else: frappe.db.commit() finally: frappe.destroy()
def receive(self, test_mails=None): """Called by scheduler to receive emails from this EMail account using POP3.""" if self.enable_incoming: if frappe.local.flags.in_test: incoming_mails = test_mails else: pop3 = self.get_pop3() incoming_mails = pop3.get_messages() exceptions = [] for raw in incoming_mails: try: communication = self.insert_communication(raw) except SentEmailInInbox: frappe.db.rollback() except Exception: frappe.db.rollback() exceptions.append(frappe.get_traceback()) else: frappe.db.commit() attachments = [d.file_name for d in communication._attachments] communication.notify(attachments=attachments, fetched_from_email_account=True) if exceptions: raise Exception, frappe.as_json(exceptions)
def handle_exception(e): http_status_code = getattr(e, "http_status_code", 500) if (http_status_code==500 and isinstance(e, MySQLdb.OperationalError) and e.args[0] in (1205, 1213)): # 1205 = lock wait timeout # 1213 = deadlock # code 409 represents conflict http_status_code = 508 if frappe.local.is_ajax or 'application/json' in frappe.local.request.headers.get('Accept', ''): response = frappe.utils.response.report_error(http_status_code) else: traceback = "<pre>"+frappe.get_traceback()+"</pre>" if frappe.local.flags.disable_traceback: traceback = "" frappe.respond_as_web_page("Server Error", traceback, http_status_code=http_status_code) response = frappe.website.render.render("message", http_status_code=http_status_code) if e.__class__ == frappe.AuthenticationError: if hasattr(frappe.local, "login_manager"): frappe.local.login_manager.clear_cookies() if http_status_code >= 500: frappe.logger().error('Request Error', exc_info=True) make_error_snapshot(e) return response
def get_express_checkout_details(token): try: doc = frappe.get_doc("PayPal Settings") doc.setup_sandbox_env(token) params, url = doc.get_paypal_params_and_url() params.update({ "METHOD": "GetExpressCheckoutDetails", "TOKEN": token }) response = make_post_request(url, data=params) if response.get("ACK")[0] != "Success": frappe.respond_as_web_page(_("Something went wrong"), _("Looks like something went wrong during the transaction. Since we haven't confirmed the payment, Paypal will automatically refund you this amount. If it doesn't, please send us an email and mention the Correlation ID: {0}.").format(response.get("CORRELATIONID", [None])[0]), indicator_color='red', http_status_code=frappe.ValidationError.http_status_code) return update_integration_request_status(token, { "payerid": response.get("PAYERID")[0], "payer_email": response.get("EMAIL")[0] }, "Authorized") frappe.local.response["type"] = "redirect" frappe.local.response["location"] = get_url( \ "/api/method/frappe.integrations.doctype.paypal_settings.paypal_settings.confirm_payment?token={0}".format(token)) except Exception: frappe.log_error(frappe.get_traceback())
def run_async_task(self, site=None, user=None, cmd=None, form_dict=None, hijack_std=False): ret = {} frappe.init(site) frappe.connect() frappe.local.task_id = self.request.id if hijack_std: original_stdout, original_stderr = sys.stdout, sys.stderr sys.stdout, sys.stderr = get_std_streams(self.request.id) frappe.local.stdout, frappe.local.stderr = sys.stdout, sys.stderr try: set_task_status(self.request.id, "Running") frappe.db.commit() frappe.set_user(user) # sleep(60) frappe.local.form_dict = frappe._dict(form_dict) execute_cmd(cmd, from_async=True) ret = frappe.local.response except Exception, e: frappe.db.rollback() ret = frappe.local.response http_status_code = getattr(e, "http_status_code", 500) ret['status_code'] = http_status_code frappe.errprint(frappe.get_traceback()) frappe.utils.response.make_logs() set_task_status(self.request.id, "Error", response=ret) task_logger.error('Exception in running {}: {}'.format(cmd, ret['exc']))
def capture_payment(is_sandbox=False, sanbox_response=None): """ Verifies the purchase as complete by the merchant. After capture, the amount is transferred to the merchant within T+3 days where T is the day on which payment is captured. Note: Attempting to capture a payment whose status is not authorized will produce an error. """ controller = frappe.get_doc("Razorpay Settings") for doc in frappe.get_all("Integration Request", filters={"status": "Authorized", "integration_request_service": "Razorpay"}, fields=["name", "data"]): try: if is_sandbox: resp = sanbox_response else: data = json.loads(doc.data) settings = controller.get_settings(data) resp = make_post_request("https://api.razorpay.com/v1/payments/{0}/capture".format(data.get("razorpay_payment_id")), auth=(settings.api_key, settings.api_secret), data={"amount": data.get("amount")}) if resp.get("status") == "captured": frappe.db.set_value("Integration Request", doc.name, "status", "Completed") except Exception: doc = frappe.get_doc("Integration Request", doc.name) doc.status = "Failed" doc.error = frappe.get_traceback() frappe.log_error(doc.error, '{0} Failed'.format(doc.name))
def execute_patch(patchmodule, method=None, methodargs=None): """execute the patch""" success = False block_user(True) frappe.db.begin() try: log( "Executing {patch} in {site} ({db})".format( patch=patchmodule or str(methodargs), site=frappe.local.site, db=frappe.db.cur_db_name ) ) if patchmodule: if patchmodule.startswith("execute:"): exec patchmodule.split("execute:")[1] in globals() else: frappe.get_attr(patchmodule + ".execute")() update_patch_log(patchmodule) elif method: method(**methodargs) frappe.db.commit() success = True except Exception, e: frappe.db.rollback() tb = frappe.get_traceback() log(tb)
def create_charge_on_stripe(self): import stripe try: charge = stripe.Charge.create( amount=cint(flt(self.data.amount) * 100), currency=self.data.currency, source=self.data.stripe_token_id, description=self.data.description, receipt_email=self.data.payer_email, ) if charge.captured == True: self.integration_request.db_set("status", "Completed", update_modified=False) self.flags.status_changed_to = "Completed" else: frappe.log_error(charge.failure_message, "Stripe Payment not completed") except Exception: frappe.log_error(frappe.get_traceback()) return self.finalize_request()
def attach_print(mail, parent_doc, print_html, print_format): name = parent_doc.name if parent_doc else "attachment" if (not print_html) and parent_doc and print_format: print_html = frappe.get_print_format(parent_doc.doctype, parent_doc.name, print_format) print_settings = frappe.db.get_singles_dict("Print Settings") send_print_as_pdf = cint(print_settings.send_print_as_pdf) if send_print_as_pdf: try: mail.add_pdf_attachment( name.replace(' ', '').replace('/', '-') + '.pdf', print_html) except Exception: frappe.msgprint(_("Error generating PDF, attachment sent as HTML")) frappe.errprint(frappe.get_traceback()) send_print_as_pdf = 0 if not send_print_as_pdf: print_html = scrub_urls(print_html) mail.add_attachment( name.replace(' ', '').replace('/', '-') + '.html', print_html, 'text/html')
def send_password_notification(self, new_password): try: if self.flags.in_insert: if self.name not in STANDARD_USERS: if new_password: # new password given, no email required _update_password( user=self.name, pwd=new_password, logout_all_sessions=self.logout_all_sessions) if not self.flags.no_welcome_mail and self.send_welcome_email: self.send_welcome_mail_to_user() self.flags.email_sent = 1 if frappe.session.user != 'Guest': msgprint(_("Welcome email sent")) return else: self.email_new_password(new_password) except frappe.OutgoingEmailError: print(frappe.get_traceback()) pass # email server not set, don't send email
def receive(self, test_mails=None): """Called by scheduler to receive emails from this EMail account using POP3.""" if self.enable_incoming: if frappe.local.flags.in_test: incoming_mails = test_mails else: pop3 = self.get_pop3() incoming_mails = pop3.get_messages() exceptions = [] for raw in incoming_mails: try: self.insert_communication(raw) except Exception: frappe.db.rollback() exceptions.append(frappe.get_traceback()) else: frappe.db.commit() if exceptions: raise Exception, frappe.as_json(exceptions)
def handle_event(*args, **kwargs): ''' Set the webhook URL in GitHub to point to this method: https://[hostname]/api/method/deployer.deployer.doctype.deployer_instance.deploy_handler.handle_event content_type: application/json add the webhook secret to common_site_config.json as: { "deployer_secret": "your-secret-key" } ensure that the secret key is the same as the one provided to GitHub ''' r = frappe.request try: authenticate_request(r) payload = json.dumps(json.loads(r.get_data())) d = deploy(payload) return '', 200 except Exception as e: frappe.log_error(frappe.get_traceback(), 'Deployer Instance') return '', 500
def add_institution(token, response): response = json.loads(response) plaid = PlaidConnector() access_token = plaid.get_access_token(token) if not frappe.db.exists("Bank", response["institution"]["name"]): try: bank = frappe.get_doc({ "doctype": "Bank", "bank_name": response["institution"]["name"], "plaid_access_token": access_token }) bank.insert() except Exception: frappe.throw(frappe.get_traceback()) else: bank = frappe.get_doc("Bank", response["institution"]["name"]) bank.plaid_access_token = access_token bank.save() return bank
def create_request(self, data): import stripe self.data = frappe._dict(data) stripe.api_key = self.get_password(fieldname="secret_key", raise_exception=False) stripe.default_http_client = stripe.http_client.RequestsClient() try: self.integration_request = create_request_log( self.data, "Host", "Stripe") return self.create_charge_on_stripe() except Exception: frappe.log_error(frappe.get_traceback()) return { "redirect_to": frappe.redirect_to_message( _('Server Error'), _("It seems that there is an issue with the server's stripe configuration. In case of failure, the amount will get refunded to your account." )), "status": 401 }
def get_desktop_page(page): """Applies permissions, customizations and returns the configruration for a page on desk. Args: page (string): page name Returns: dict: dictionary of cards, charts and shortcuts to be displayed on website """ try: wspace = Workspace(page) wspace.build_workspace() return { "charts": wspace.charts, "shortcuts": wspace.shortcuts, "cards": wspace.cards, "onboarding": wspace.onboarding, "allow_customization": not wspace.doc.disable_user_customization, } except DoesNotExistError: frappe.log_error(frappe.get_traceback()) return {}
def creates_qb_accounts_heads_to_erp_chart_of_accounts(): quickbooks_settings = frappe.get_doc("Quickbooks Settings", "Quickbooks Settings") Company_abbr = frappe.db.get_value( "Company", {"name": quickbooks_settings.select_company}, "abbr") for root_type, account_names in quickbooks_accounts_head( quickbooks_settings).items(): for account_name in account_names: if not frappe.db.get_value( "Account", { "quickbooks_account_id": "Quickbooks_catagory", "name": account_name + " - qb - " + Company_abbr }, "name"): try: qb_category_type = frappe.new_doc("Account") qb_category_type.quickbooks_account_id = "Quickbooks_catagory" qb_category_type.account_name = account_name + " - " + "qb" qb_category_type.is_group = True qb_category_type.parent_account = root_type.split( ",")[1].strip() + " - " + Company_abbr qb_category_type.root_type = root_type.split(",")[0] qb_category_type.company = quickbooks_settings.select_company qb_category_type.flags.ignore_mandatory = True qb_category_type.insert() frappe.db.commit() except Exception, e: if e.args[0] and e.args[0].startswith("402"): raise e else: make_quickbooks_log( title=e.message, status="Error", method= "creates_qb_accounts_heads_to_erp_chart_of_accounts", message=frappe.get_traceback(), request_data=account_names, exception=True)
def upload_file_to_dropbox(filename, folder, dropbox_client): """upload files with chunk of 15 mb to reduce session append calls""" create_folder_if_not_exists(folder, dropbox_client) chunk_size = 15 * 1024 * 1024 file_size = os.path.getsize(encode(filename)) mode = (dropbox.files.WriteMode.overwrite) f = open(encode(filename), 'rb') path = "{0}/{1}".format(folder, os.path.basename(filename)) try: if file_size <= chunk_size: dropbox_client.files_upload(f.read(), path, mode) else: upload_session_start_result = dropbox_client.files_upload_session_start( f.read(chunk_size)) cursor = dropbox.files.UploadSessionCursor( session_id=upload_session_start_result.session_id, offset=f.tell()) commit = dropbox.files.CommitInfo(path=path, mode=mode) while f.tell() < file_size: if ((file_size - f.tell()) <= chunk_size): dropbox_client.files_upload_session_finish( f.read(chunk_size), cursor, commit) else: dropbox_client.files_upload_session_append( f.read(chunk_size), cursor.session_id, cursor.offset) cursor.offset = f.tell() except dropbox.exceptions.ApiError as e: if isinstance(e.error, dropbox.files.UploadError): error = "File Path: {path}\n".foramt(path=path) error += frappe.get_traceback() frappe.log_error(error) else: raise
def process_message(msg_value, name=None): logger = get_module_logger() consumer_conf = frappe.get_cached_doc("Spine Consumer Config", "Spine Consumer Config") # Send the received message for processing on the background queue for async execution using redis # queue. This ensures that current event loop thread remains available for more incoming requests. msg_value = preprocess_msg(msg_value) handlers_to_enqueue = filter_handlers_for_event(msg_value, consumer_conf) # if not handlers_to_enqueue or len(handlers_to_enqueue) == 0: # # Submit a default logging handler to ensure event is logged for analysis # handlers_to_enqueue = ["spine.spine_adapter.kafka_client.kafka_async_consumer.log_doctype_event"] # provision for retrying. # To Enable, capture the retry payload sent from handler function to set status of message and value for next retry. retry = [] last_error = None if handlers_to_enqueue and len(handlers_to_enqueue) > 0: # Process only if there are any handlers available. If not, do not commit. for handler in handlers_to_enqueue: logger.info("Loading {} handler".format(handler)) func = frappe.get_attr(handler) try: func(msg_value) process_success = True except Exception as exc: last_error = frappe.log_error(title="Consumer Message Handler {} Error".format(handler), message={ 'traceback': frappe.get_traceback(), 'message_id': name, }) ## Retry array if found in the error payload then consumer would like to override the Spine retry timeline. retry = ((exc.args and exc.args[0]) or {}).get('error', {}).get('retry') frappe.db.rollback() else: # No handlers defined. Consider this as success scenario. process_success = True logger.info("No handlers defined for doctype in the message - {}".format(msg_value.get("Header"))) return process_success, retry, last_error
def execute_bloomtrace_integration_request(): frappe_client = get_bloomtrace_client() if not frappe_client: return pending_requests = frappe.get_all("Integration Request", filters={ "status": ["IN", ["Queued", "Failed"]], "reference_doctype": "Harvest", "integration_request_service": "BloomTrace" }, order_by="creation ASC", limit=50) for request in pending_requests: integration_request = frappe.get_doc("Integration Request", request.name) harvest = frappe.get_doc("Harvest", integration_request.reference_docname) bloomtrace_harvest = frappe_client.get_doc( "Harvest", filters={"harvest": integration_request.reference_docname}) try: if not bloomtrace_harvest: insert_harvest(harvest, frappe_client) else: update_harvest(harvest, frappe_client) integration_request.error = "" integration_request.status = "Completed" integration_request.save(ignore_permissions=True) except Exception as e: integration_request.error = cstr(frappe.get_traceback()) integration_request.status = "Failed" integration_request.save(ignore_permissions=True)
def upload(): if not frappe.has_permission("Attendance", "create"): raise frappe.PermissionError from frappe.utils.csvutils import read_csv_content_from_uploaded_file from frappe.modules import scrub rows = read_csv_content_from_uploaded_file() rows = filter(lambda x: x and any(x), rows) if not rows: msg = [_("Please select a csv file")] return {"messages": msg, "error": msg} columns = [scrub(f) for f in rows[4]] columns[0] = "name" columns[3] = "att_date" ret = [] error = False from frappe.utils.csvutils import check_record, import_doc for i, row in enumerate(rows[5:]): if not row: continue row_idx = i + 5 d = frappe._dict(zip(columns, row)) d["doctype"] = "Attendance" if d.name: d["docstatus"] = frappe.db.get_value("Attendance", d.name, "docstatus") try: check_record(d) ret.append(import_doc(d, "Attendance", 1, row_idx, submit=True)) except Exception, e: error = True ret.append('Error for row (#%d) %s : %s' % (row_idx, len(row) > 1 and row[1] or "", cstr(e))) frappe.errprint(frappe.get_traceback())
def capture_payment(is_sandbox=False, sanbox_response=None): """ Verifies the purchase as complete by the merchant. After capture, the amount is transferred to the merchant within T+3 days where T is the day on which payment is captured. Note: Attempting to capture a payment whose status is not authorized will produce an error. """ controller = frappe.get_doc("Razorpay Settings") for doc in frappe.get_all("Integration Request", filters={ "status": "Authorized", "integration_request_service": "Razorpay" }, fields=["name", "data"]): try: if is_sandbox: resp = sanbox_response else: data = json.loads(doc.data) resp = controller.post_request( "https://api.razorpay.com/v1/payments/{0}/capture".format( data.get("razorpay_payment_id")), auth=(controller.api_key, controller.get_password("api_secret")), data={"amount": data.get("amount")}) if resp.get("status") == "captured": frappe.db.set_value("Integration Request", doc.name, "status", "Completed") except Exception: doc = frappe.get_doc("Integration Request", doc.name) doc.status = "Failed" doc.error = frappe.get_traceback() frappe.log_error(doc.error, '{0} Failed'.format(doc.name))
def evaluate_alert(doc, alert, event): from jinja2 import TemplateError try: if isinstance(alert, string_types): alert = frappe.get_doc("Notification", alert) context = get_context(doc) if alert.condition: if not frappe.safe_eval(alert.condition, None, context): return if event=="Value Change" and not doc.is_new(): try: db_value = frappe.db.get_value(doc.doctype, doc.name, alert.value_changed) except pymysql.InternalError as e: if e.args[0]== ER.BAD_FIELD_ERROR: alert.db_set('enabled', 0) frappe.log_error('Notification {0} has been disabled due to missing field'.format(alert.name)) return db_value = parse_val(db_value) if (doc.get(alert.value_changed) == db_value) or \ (not db_value and not doc.get(alert.value_changed)): return # value not changed 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) alert.send(doc) except TemplateError: frappe.throw(_("Error while evaluating Notification {0}. Please fix your template.").format(alert)) except Exception as e: frappe.log_error(message=frappe.get_traceback(), title=str(e)) frappe.throw(_("Error in Notification"))
def cancel_lrpt_doc(self): for item in self.lrpt_items: if item.reference_doctype == "Therapy Plan": cancel_tharapy_plan_doc(self.patient, item.reference_docname) frappe.db.set_value("Therapy Plan Detail", item.child_name, "is_cancelled", 1) else: if not item.reference_docname: frappe.db.set_value("Lab Prescription", item.child_name, "is_cancelled", 1) frappe.db.set_value("Radiology Procedure Prescription", item.child_name, "is_cancelled", 1) frappe.db.set_value("Procedure Prescription", item.child_name, "is_cancelled", 1) continue doc = frappe.get_doc(item.reference_doctype, item.reference_docname) if doc.docstatus < 2: try: apply_workflow(doc, "Not Serviced") if doc.meta.get_field("status"): doc.status = "Not Serviced" doc.save(ignore_permissions=True) doc.reload() if ( doc.workflow_state == "Not Serviced" or doc.workflow_state == "Submitted but Not Serviced" ): frappe.db.set_value("Lab Prescription", item.child_name, "is_cancelled", 1) frappe.db.set_value("Radiology Procedure Prescription", item.child_name, "is_cancelled", 1) frappe.db.set_value("Procedure Prescription", item.child_name, "is_cancelled", 1) except Exception: traceback = frappe.get_traceback() frappe.log_error(traceback) return self.name
def get_device(device_id): payment_types = [] if device_id: try: device_record = frappe.get_doc("Device", device_id) if device_record: for idx, i in enumerate(device_record.mop): payment_type = i.__dict__ payment_types.append({ "mop": payment_type['payment_type'], "mop_arabic": payment_type['arabic_translation'], }) except: tailpos_settings_payment = frappe.get_single("Tail Settings") for idx, i in enumerate(tailpos_settings_payment.mop): payment_type = i.__dict__ payment_types.append({ "mop": payment_type['payment_type'], "mop_arabic": payment_type['arabic_translation'], }) frappe.log_error(frappe.get_traceback()) else: tailpos_settings_payment = frappe.get_single("Tail Settings") for idx, i in enumerate(tailpos_settings_payment.mop): payment_type = i.__dict__ payment_types.append({ "mop": payment_type['payment_type'], "mop_arabic": payment_type['arabic_translation'], }) return {"tableNames": "Device", "paymentTypes": payment_types}
def evaluate_alert(doc, alert, event): from jinja2 import TemplateError try: if isinstance(alert, string_types): alert = frappe.get_doc("Notification", alert) context = get_context(doc) if alert.condition: if not frappe.safe_eval(alert.condition, None, context): return if event=="Value Change" and not doc.is_new(): if not frappe.db.has_column(doc.doctype, alert.value_changed): alert.db_set('enabled', 0) frappe.log_error('Notification {0} has been disabled due to missing field'.format(alert.name)) return doc_before_save = doc.get_doc_before_save() field_value_before_save = doc_before_save.get(alert.value_changed) if doc_before_save else None field_value_before_save = parse_val(field_value_before_save) if (doc.get(alert.value_changed) == field_value_before_save): # value not changed return if event != "Value Change" and not doc.is_new(): # reload the doc for the latest values & comments, # except for validate type event. doc.reload() alert.send(doc) except TemplateError: frappe.throw(_("Error while evaluating Notification {0}. Please fix your template.").format(alert)) except Exception as e: error_log = frappe.log_error(message=frappe.get_traceback(), title=str(e)) frappe.throw(_("Error in Notification: {}").format( frappe.utils.get_link_to_form('Error Log', error_log.name)))
def sync_quickbooks_resources(): quickbooks_settings = frappe.get_doc("Quickbooks Settings") make_quickbooks_log(title="Sync Job Queued", status="Queued", method=frappe.local.form_dict.cmd, message="Sync Job Queued") if quickbooks_settings.enable_quickbooks_online: try: if quickbooks_settings.quickbooks_to_erpnext: validate_quickbooks_settings(quickbooks_settings) sync_from_quickbooks_to_erp(quickbooks_settings) if quickbooks_settings.erpnext_to_quickbooks: sync_from_erp_to_quickbooks(quickbooks_settings) make_quickbooks_log(title="Sync Completed", status="Success", method=frappe.local.form_dict.cmd, message="Updated {customers} customer(s)") except Exception, e: # if e.args[0]: # make_quickbooks_log( # title="QuickBooks has suspended your account", # status="Error", # method="sync_quickbooks_resources", # message=_("""QuickBooks has suspended your account till you complete the payment. We have disabled ERPNext Quickbooks Sync. Please enable it once your complete the payment at Quickbooks Online."""), # exception=True) # disable_quickbooks_sync_on_exception() # else: make_quickbooks_log(title="sync has terminated", status="Error", method="sync_quickbooks_resources", message=frappe.get_traceback(), exception=True)
def get_context(context): if (frappe.session.user == "Guest" or frappe.db.get_value("User", frappe.session.user, "user_type")=="Website User"): frappe.throw(_("You are not permitted to access this page."), frappe.PermissionError) hooks = frappe.get_hooks() try: boot = frappe.sessions.get() except Exception as e: boot = frappe._dict(status='failed', error = str(e)) print(frappe.get_traceback()) # this needs commit csrf_token = frappe.sessions.get_csrf_token() frappe.db.commit() boot_json = frappe.as_json(boot) # remove script tags from boot boot_json = re.sub("\<script\>[^<]*\</script\>", "", boot_json) context.update({ "no_cache": 1, "build_version": get_build_version(), "include_js": hooks["app_include_js"], "include_css": hooks["app_include_css"], "sounds": hooks["sounds"], "boot": boot if context.get("for_mobile") else boot_json, "csrf_token": csrf_token, "background_image": (boot.status != 'failed' and (boot.user.background_image or boot.default_background_image) or None), "google_analytics_id": frappe.conf.get("google_analytics_id"), "mixpanel_id": frappe.conf.get("mixpanel_id") }) return context
def get_contacts(email_strings): email_addrs = [] for email_string in email_strings: if email_string: for email in email_string.split(","): parsed_email = parseaddr(email)[1] if parsed_email: email_addrs.append(parsed_email) contacts = [] for email in email_addrs: email = get_email_without_link(email) contact_name = get_contact_name(email) if not contact_name and email: email_parts = email.split("@") first_name = frappe.unscrub(email_parts[0]) try: contact_name = '{0}-{1}'.format(first_name, email_parts[1]) if first_name == 'Contact' else first_name contact = frappe.get_doc({ "doctype": "Contact", "first_name": contact_name, "name": contact_name }) contact.add_email(email_id=email, is_primary=True) contact.insert(ignore_permissions=True) contact_name = contact.name except Exception: traceback = frappe.get_traceback() frappe.log_error(traceback) if contact_name: contacts.append(contact_name) return contacts
def upload_from_folder(path, dropbox_folder, dropbox_client, did_not_upload, error_log): import dropbox.rest if not os.path.exists(path): return try: response = dropbox_client.metadata(dropbox_folder) except dropbox.rest.ErrorResponse as e: # folder not found if e.status == 404: response = {"contents": []} else: raise for filename in os.listdir(path): filename = cstr(filename) if filename in ignore_list: continue found = False filepath = os.path.join(path, filename) for file_metadata in response["contents"]: if (os.path.basename(filepath) == os.path.basename(file_metadata["path"]) and os.stat(encode(filepath)).st_size == int(file_metadata["bytes"])): found = True break if not found: try: dropbox_client = upload_file_to_dropbox(filepath, dropbox_folder, dropbox_client) except Exception: did_not_upload.append(filename) error_log.append(frappe.get_traceback()) return dropbox_client
def upload_from_folder(path, dropbox_folder, dropbox_client, did_not_upload, error_log): if not os.path.exists(path): return try: response = dropbox_client.files_list_folder(dropbox_folder) except dropbox.exceptions.ApiError as e: # folder not found if isinstance(e.error, dropbox.files.ListFolderError): response = frappe._dict({"entries": []}) else: raise for root, directory, files in os.walk(path): for filename in files: filename = cstr(filename) filepath = os.path.join(root, filename) if filename in ignore_list: continue found = False for file_metadata in response.entries: if (os.path.basename(filepath) == file_metadata.name and os.stat(encode(filepath)).st_size == int( file_metadata.size)): found = True break if not found: try: upload_file_to_dropbox(filepath, dropbox_folder, dropbox_client) except Exception: did_not_upload.append(filepath) error_log.append(frappe.get_traceback())
def create_journal_entry(qb_journal_entry, quickbooks_journal_entry_list=[]): """ store JournalEntry data in ERPNEXT """ journal = None qb_journal_entry_id = '' if qb_journal_entry.get('Id'): qb_journal_entry_id = "JE" + qb_journal_entry.get('Id') try: if not frappe.db.get_value( "Journal Entry", {"quickbooks_journal_entry_id": qb_journal_entry_id}, "name"): journal = frappe.new_doc("Journal Entry") journal.quickbooks_journal_entry_id = qb_journal_entry_id journal.voucher_type = _("Journal Entry") journal.naming_series = "JE-Quickbooks-" journal.posting_date = qb_journal_entry.get('TxnDate') get_journal_entry_account(journal, qb_journal_entry) journal.cheque_no = "dummy check" journal.cheque_date = qb_journal_entry.get('TxnDate') journal.flags.ignore_mandatory = True journal.save() journal.submit() frappe.db.commit() quickbooks_journal_entry_list.append( journal.quickbooks_journal_entry_id) except Exception, e: if e.args[0] and e.args[0].startswith("402"): raise e else: make_quickbooks_log(title=e.message, status="Error", method="create_journal_entry", message=frappe.get_traceback(), request_data=qb_journal_entry, exception=True)
def update_item_stock(item_code, woocommerce_settings, bin=None): item = frappe.get_doc("Item", item_code) if item.sync_qty_with_woocommerce: if not bin: bin = get_bin(item_code, woocommerce_settings.warehouse) if not item.woocommerce_product_id and not item.variant_of: sync_item_with_woocommerce(item, woocommerce_settings.price_list, woocommerce_settings.warehouse) if item.sync_with_woocommerce and item.woocommerce_product_id and woocommerce_settings.warehouse == bin.warehouse: if item.variant_of: item_data, resource = get_product_update_dict_and_resource( frappe.get_value("Item", item.variant_of, "woocommerce_product_id"), item.woocommerce_variant_id, is_variant=True, actual_qty=bin.actual_qty) else: item_data, resource = get_product_update_dict_and_resource( item.woocommerce_product_id, item.woocommerce_variant_id, actual_qty=bin.actual_qty) try: put_request(resource, item_data) except requests.exceptions.HTTPError, e: if e.args[0] and e.args[0].startswith("404"): make_woocommerce_log(title=e.message, status="Error", method="sync_woocommerce_items", message=frappe.get_traceback(), request_data=item_data, exception=True) disable_woocommerce_sync_for_item(item) else: raise e
def receive(self, test_mails=None): """Called by scheduler to receive emails from this EMail account using POP3/IMAP.""" if self.enable_incoming: if frappe.local.flags.in_test: incoming_mails = test_mails else: email_server = self.get_server(in_receive=True) if not email_server: return incoming_mails = email_server.get_messages() exceptions = [] for raw in incoming_mails: try: communication = self.insert_communication(raw) except SentEmailInInbox: frappe.db.rollback() except Exception: frappe.db.rollback() log('email_account.receive') exceptions.append(frappe.get_traceback()) else: frappe.db.commit() attachments = [ d.file_name for d in communication._attachments ] # TODO fix bug where it sends emails to 'Adminsitrator' during testing communication.notify(attachments=attachments, fetched_from_email_account=True) if exceptions: raise Exception, frappe.as_json(exceptions)
def adjust_entries(payment_against_credit_note): try: for entries in payment_against_credit_note: payments, credit_notes = {}, [] for line in entries['Line']: payment_dict = get_credit_note_dict(entries, line) if line.get('LinkedTxn')[0].get('TxnType') == "Invoice": payments[payment_dict.get("qb_si_id")] = payment_dict payments[payment_dict.get("qb_si_id")]["credit_notes"] = [] else: credit_notes.append(payment_dict) for row in payments: payments[row]["credit_notes"].extend(credit_notes) if payments: adjust_je_against_cn(payments) except Exception, e: make_quickbooks_log(title=e.message, status="Error", method="adjust_entries", message=frappe.get_traceback(), request_data=payment_against_credit_note, exception=True)
def run_async_task(self, site=None, user=None, cmd=None, form_dict=None, hijack_std=False): ret = {} frappe.init(site) frappe.connect() frappe.local.task_id = self.request.id if hijack_std: original_stdout, original_stderr = sys.stdout, sys.stderr sys.stdout, sys.stderr = get_std_streams(self.request.id) frappe.local.stdout, frappe.local.stderr = sys.stdout, sys.stderr try: set_task_status(self.request.id, "Running") frappe.db.commit() frappe.set_user(user) # sleep(60) frappe.local.form_dict = frappe._dict(form_dict) execute_cmd(cmd, from_async=True) ret = frappe.local.response except Exception, e: frappe.db.rollback() ret = frappe.local.response http_status_code = getattr(e, "http_status_code", 500) ret['status_code'] = http_status_code frappe.errprint(frappe.get_traceback()) frappe.utils.response.make_logs() set_task_status(self.request.id, "Error", response=ret) task_logger.error('Exception in running {}: {}'.format( cmd, ret['exc']))
def validate_link(): """validate link when updated by user""" import frappe import frappe.utils value, options, fetch = frappe.form_dict.get('value'), frappe.form_dict.get('options'), frappe.form_dict.get('fetch') # no options, don't validate if not options or options=='null' or options=='undefined': frappe.response['message'] = 'Ok' return valid_value = frappe.db.get_all(options, filters=dict(name=value), as_list=1, limit=1) if valid_value: valid_value = valid_value[0][0] # get fetch values if fetch: # escape with "`" fetch = ", ".join(("`{0}`".format(f.strip()) for f in fetch.split(","))) fetch_value = None try: fetch_value = frappe.db.sql("select %s from `tab%s` where name=%s" % (fetch, options, '%s'), (value,))[0] except Exception as e: error_message = str(e).split("Unknown column '") fieldname = None if len(error_message)<=1 else error_message[1].split("'")[0] frappe.msgprint(_("Wrong fieldname <b>{0}</b> in add_fetch configuration of custom client script").format(fieldname)) frappe.errprint(frappe.get_traceback()) if fetch_value: frappe.response['fetch_values'] = [frappe.utils.parse_val(c) for c in fetch_value] frappe.response['valid_value'] = valid_value frappe.response['message'] = 'Ok'
def sync_transactions(bank, bank_account): ''' Sync transactions based on the last integration date as the start date, after sync is completed add the transaction date of the oldest transaction as the last integration date ''' last_transaction_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date") if last_transaction_date: start_date = formatdate(last_transaction_date, "YYYY-MM-dd") else: start_date = formatdate(add_months(today(), -12), "YYYY-MM-dd") end_date = formatdate(today(), "YYYY-MM-dd") try: transactions = get_transactions(bank=bank, bank_account=bank_account, start_date=start_date, end_date=end_date) result = [] for transaction in reversed(transactions): result += new_bank_transaction(transaction) if result: last_transaction_date = frappe.db.get_value( 'Bank Transaction', result.pop(), 'date') frappe.logger().info( "Plaid added {} new Bank Transactions from '{}' between {} and {}" .format(len(result), bank_account, start_date, end_date)) frappe.db.set_value("Bank Account", bank_account, "last_integration_date", last_transaction_date) except Exception: frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))