def sync_transactions(bank, bank_account): last_sync_date = dataent.db.get_value("Bank Account", bank_account, "last_integration_date") if last_sync_date: start_date = formatdate(last_sync_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 = [] if transactions: for transaction in transactions: result.append(new_bank_transaction(transaction)) dataent.db.set_value("Bank Account", bank_account, "last_integration_date", getdate(end_date)) return result except Exception: dataent.log_error(dataent.get_traceback(), _("Plaid transactions sync error"))
def get_express_checkout_details(token): try: doc = dataent.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": dataent.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=dataent.ValidationError.http_status_code) return doc = dataent.get_doc("Integration Request", token) update_integration_request_status(token, { "payerid": response.get("PAYERID")[0], "payer_email": response.get("EMAIL")[0] }, "Authorized", doc=doc) dataent.local.response["type"] = "redirect" dataent.local.response["location"] = get_redirect_uri(doc, token, response.get("PAYERID")[0]) except Exception: dataent.log_error(dataent.get_traceback())
def publish_selected_items(items_to_publish): items_to_publish = json.loads(items_to_publish) if not len(items_to_publish): dataent.throw(_('No items to publish')) for item in items_to_publish: item_code = item.get('item_code') dataent.db.set_value('Item', item_code, 'publish_in_hub', 1) dataent.get_doc({ 'doctype': 'Hub Tracked Item', 'item_code': item_code, 'hub_category': item.get('hub_category'), 'image_list': item.get('image_list') }).insert(ignore_if_duplicate=True) items = map_fields(items_to_publish) try: item_sync_preprocess(len(items)) convert_relative_image_urls_to_absolute(items) # TODO: Publish Progress connection = get_hub_connection() connection.insert_many(items) item_sync_postprocess() except Exception as e: dataent.log_error(message=e, title='Hub Sync Error')
def mark_email_as_seen(name=None): try: if name and dataent.db.exists( "Communication", name) and not dataent.db.get_value( "Communication", name, "read_by_recipient"): dataent.db.set_value("Communication", name, "read_by_recipient", 1) dataent.db.set_value("Communication", name, "delivery_status", "Read") dataent.db.set_value("Communication", name, "read_by_recipient_on", get_datetime()) dataent.db.commit() except Exception: dataent.log_error(dataent.get_traceback()) finally: # Return image as response under all circumstances from PIL import Image import io im = Image.new('RGBA', (1, 1)) im.putdata([(255, 255, 255, 0)]) buffered_obj = io.BytesIO() im.save(buffered_obj, format="PNG") dataent.response["type"] = 'binary' dataent.response["filename"] = "imaginary_pixel.png" dataent.response["filecontent"] = buffered_obj.getvalue()
def create_bank_entries(columns, data, bank_account): header_map = get_header_mapping(columns, bank_account) success = 0 errors = 0 for d in json.loads(data): if all(item is None for item in d) is True: continue fields = {} for key, value in iteritems(header_map): fields.update({key: d[int(value) - 1]}) try: bank_transaction = dataent.get_doc({"doctype": "Bank Transaction"}) bank_transaction.update(fields) bank_transaction.date = getdate(parse_date(bank_transaction.date)) bank_transaction.bank_account = bank_account bank_transaction.insert() bank_transaction.submit() success += 1 except Exception: dataent.log_error(dataent.get_traceback()) errors += 1 return {"success": success, "errors": errors}
def run_background(prepared_report): instance = dataent.get_doc("Prepared Report", prepared_report) report = dataent.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 = dataent.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 = dataent.utils.now() instance.save(ignore_permissions=True) except Exception: dataent.log_error(dataent.get_traceback()) instance = dataent.get_doc("Prepared Report", prepared_report) instance.status = "Error" instance.error_message = dataent.get_traceback() instance.save(ignore_permissions=True) dataent.publish_realtime('report_generated', { "report_name": instance.report_name, "name": instance.name }, user=dataent.session.user)
def create_mandate(data): data = dataent._dict(data) dataent.logger().debug(data) mandate = data.get('mandate') if dataent.db.exists("GoCardless Mandate", mandate): return else: reference_doc = dataent.db.get_value( data.get('reference_doctype'), data.get('reference_docname'), ["reference_doctype", "reference_name"], as_dict=1) epaas_customer = dataent.db.get_value(reference_doc.reference_doctype, reference_doc.reference_name, ["customer_name"], as_dict=1) try: dataent.get_doc({ "doctype": "GoCardless Mandate", "mandate": mandate, "customer": epaas_customer.customer_name, "gocardless_customer": data.get('customer') }).insert(ignore_permissions=True) except Exception: dataent.log_error(dataent.get_traceback())
def finalize_request(self): redirect_to = self.data.get('redirect_to') or None redirect_message = self.data.get('redirect_message') or None status = self.integration_request.status 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 = dataent.get_doc(self.data.reference_doctype, self.data.reference_docname).run_method("on_payment_authorized", self.flags.status_changed_to) except Exception: dataent.log_error(dataent.get_traceback()) if custom_redirect_to: redirect_to = custom_redirect_to redirect_url = 'payment-success' if self.redirect_url: redirect_url = self.redirect_url redirect_to = None 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_subscription_on_stripe(stripe_settings): items = [] for payment_plan in stripe_settings.payment_plans: plan = dataent.db.get_value("Subscription Plan", payment_plan.plan, "payment_plan_id") items.append({"plan": plan, "quantity": payment_plan.qty}) try: customer = stripe.Customer.create( description=stripe_settings.data.payer_name, email=stripe_settings.data.payer_email, source=stripe_settings.data.stripe_token_id) subscription = stripe.Subscription.create(customer=customer, items=items) if subscription.status == "active": stripe_settings.integration_request.db_set('status', 'Completed', update_modified=False) stripe_settings.flags.status_changed_to = "Completed" else: stripe_settings.integration_request.db_set('status', 'Failed', update_modified=False) dataent.log_error('Subscription N°: ' + subscription.id, 'Stripe Payment not completed') except Exception: stripe_settings.integration_request.db_set('status', 'Failed', update_modified=False) dataent.log_error(dataent.get_traceback()) return stripe_settings.finalize_request()
def order(*args, **kwargs): try: _order(*args, **kwargs) except Exception: error_message = dataent.get_traceback()+"\n\n Request Data: \n"+json.loads(dataent.request.data).__str__() dataent.log_error(error_message, "WooCommerce Error") raise
def create_stripe_subscription(gateway_controller, data): stripe_settings = dataent.get_doc("Stripe Settings", gateway_controller) stripe_settings.data = dataent._dict(data) stripe.api_key = stripe_settings.get_password(fieldname="secret_key", raise_exception=False) stripe.default_http_client = stripe.http_client.RequestsClient() try: stripe_settings.integration_request = create_request_log( stripe_settings.data, "Host", "Stripe") stripe_settings.payment_plans = dataent.get_doc( "Payment Request", stripe_settings.data.reference_docname).subscription_plans return create_subscription_on_stripe(stripe_settings) except Exception: dataent.log_error(dataent.get_traceback()) return { "redirect_to": dataent.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 upload_file_to_dropbox(filename, folder, dropbox_client): """upload files with chunk of 15 mb to reduce session append calls""" if not os.path.exists(filename): return 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".format(path=path) error += dataent.get_traceback() dataent.log_error(error) else: raise
def confirm_payment(token): try: custom_redirect_to = None data, params, url = get_paypal_and_transaction_details(token) params.update({ "METHOD": "DoExpressCheckoutPayment", "PAYERID": data.get("payerid"), "TOKEN": token, "PAYMENTREQUEST_0_PAYMENTACTION": "SALE", "PAYMENTREQUEST_0_AMT": data.get("amount"), "PAYMENTREQUEST_0_CURRENCYCODE": data.get("currency").upper() }) response = make_post_request(url, data=params) if response.get("ACK")[0] == "Success": update_integration_request_status(token, { "transaction_id": response.get("PAYMENTINFO_0_TRANSACTIONID")[0], "correlation_id": response.get("CORRELATIONID")[0] }, "Completed") if data.get("reference_doctype") and data.get("reference_docname"): custom_redirect_to = dataent.get_doc(data.get("reference_doctype"), data.get("reference_docname")).run_method("on_payment_authorized", "Completed") dataent.db.commit() redirect_url = '/integrations/payment-success?doctype={0}&docname={1}'.format(data.get("reference_doctype"), data.get("reference_docname")) else: redirect_url = "/integrations/payment-failed" setup_redirect(data, redirect_url, custom_redirect_to) except Exception: dataent.log_error(dataent.get_traceback())
def get_transactions(self, start_date, end_date, account_id=None): try: self.auth() if account_id: account_ids = [account_id] response = self.client.Transactions.get( self.access_token, start_date=start_date, end_date=end_date, account_ids=account_ids) else: response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date) transactions = response['transactions'] while len(transactions) < response['total_transactions']: response = self.client.Transactions.get( self.access_token, start_date=start_date, end_date=end_date, offset=len(transactions)) transactions.extend(response['transactions']) return transactions except Exception: dataent.log_error(dataent.get_traceback(), _("Plaid transactions sync error"))
def auth(self): try: self.client.Auth.get(self.access_token) print("Authentication successful.....") except ItemError as e: if e.code == 'ITEM_LOGIN_REQUIRED': pass else: pass except APIError as e: if e.code == 'PLANNED_MAINTENANCE': pass else: pass except requests.Timeout: pass except Exception as e: print(e) dataent.log_error(dataent.get_traceback(), _("Plaid authentication error")) dataent.msgprint({ "title": _("Authentication Failed"), "message": e, "raise_exception": 1, "indicator": 'red' })
def sync(): try: gcalendar_settings = dataent.get_doc('GCalendar Settings') if gcalendar_settings.enable == 1: gcalendar_settings.sync() except Exception: dataent.log_error(dataent.get_traceback())
def create_recurring_profile(token, payerid): try: custom_redirect_to = None updating = False data, params, url = get_paypal_and_transaction_details(token) addons = data.get("addons") subscription_details = data.get("subscription_details") if data.get('subscription_id') and addons: updating = True manage_recurring_payment_profile_status(data['subscription_id'], 'Cancel', params, url) params.update({ "METHOD": "CreateRecurringPaymentsProfile", "PAYERID": payerid, "TOKEN": token, "DESC": data.get("description"), "BILLINGPERIOD": subscription_details.get("billing_period"), "BILLINGFREQUENCY": subscription_details.get("billing_frequency"), "AMT": data.get("amount") if data.get("subscription_amount") == data.get("amount") else data.get("subscription_amount"), "CURRENCYCODE": data.get("currency").upper(), "INITAMT": data.get("upfront_amount") }) status_changed_to = 'Completed' if data.get("starting_immediately") or updating else 'Verified' starts_at = get_datetime(subscription_details.get("start_date")) or dataent.utils.now_datetime() starts_at = starts_at.replace(tzinfo=pytz.timezone(dataent.utils.get_time_zone())).astimezone(pytz.utc) #"PROFILESTARTDATE": datetime.utcfromtimestamp(get_timestamp(starts_at)).isoformat() params.update({ "PROFILESTARTDATE": starts_at.isoformat() }) response = make_post_request(url, data=params) if response.get("ACK")[0] == "Success": update_integration_request_status(token, { "profile_id": response.get("PROFILEID")[0], }, "Completed") if data.get("reference_doctype") and data.get("reference_docname"): data['subscription_id'] = response.get("PROFILEID")[0] dataent.flags.data = data custom_redirect_to = dataent.get_doc(data.get("reference_doctype"), data.get("reference_docname")).run_method("on_payment_authorized", status_changed_to) dataent.db.commit() redirect_url = '/integrations/payment-success?doctype={0}&docname={1}'.format(data.get("reference_doctype"), data.get("reference_docname")) else: redirect_url = "/integrations/payment-failed" setup_redirect(data, redirect_url, custom_redirect_to) except Exception: dataent.log_error(dataent.get_traceback())
def get_access_token(self, public_token): if public_token is None: dataent.log_error(_("Public token is missing for this bank"), _("Plaid public token error")) response = self.client.Item.public_token.exchange(public_token) access_token = response['access_token'] return access_token
def accept(key, sender, reference_doctype, reference_name, feedback, rating, fullname): """ save the feedback in communication """ if not reference_doctype and not reference_name or \ not dataent.db.get_value(reference_doctype, reference_name): dataent.throw(_("Invalid Reference")) if not rating: dataent.throw(_("Please add a rating")) if not is_valid_feedback_request(key): dataent.throw(_("Expired link")) try: feedback_request = dataent.db.get_value("Feedback Request", {"key": key}) communication = dataent.get_doc({ "rating": rating, "status": "Closed", "content": feedback or "", "doctype": "Communication", "sender": sender or "Guest", "sent_or_received": "Received", "communication_type": "Feedback", "reference_name": reference_name, "sender_full_name": fullname or "", "feedback_request": feedback_request, "reference_doctype": reference_doctype, "subject": "Feedback for {0} {1}".format(reference_doctype, reference_name), }).insert(ignore_permissions=True) doc = dataent.get_doc("Feedback Request", feedback_request) doc.is_feedback_submitted = 1 doc.rating = rating doc.reference_communication = communication.name doc.save(ignore_permissions=True) return True except Exception: dataent.log_error() dataent.throw(_("Cannot submit feedback, please try again later"))
def setup_app_type(): try: shopify_settings = dataent.get_doc("Shopify Settings") shopify_settings.app_type = 'Private' shopify_settings.update_price_in_epaas_price_list = 0 if getattr( shopify_settings, 'push_prices_to_shopify', None) else 1 shopify_settings.flags.ignore_mandatory = True shopify_settings.ignore_permissions = True shopify_settings.save() except Exception: dataent.db.set_value("Shopify Settings", None, "enable_shopify", 0) dataent.log_error(dataent.get_traceback())
def check_mandate(data, reference_doctype, reference_docname): data = json.loads(data) client = gocardless_initialization(reference_docname) payer = dataent.get_doc("Customer", data["payer_name"]) if payer.customer_type == "Individual" and payer.customer_primary_contact is not None: primary_contact = dataent.get_doc("Contact", payer.customer_primary_contact) prefilled_customer = { "company_name": payer.name, "given_name": primary_contact.first_name, } if primary_contact.last_name is not None: prefilled_customer.update( {"family_name": primary_contact.last_name}) if primary_contact.email_id is not None: prefilled_customer.update({"email": primary_contact.email_id}) else: prefilled_customer.update({"email": dataent.session.user}) else: prefilled_customer = { "company_name": payer.name, "email": dataent.session.user } success_url = get_url( "./integrations/gocardless_confirmation?reference_doctype=" + reference_doctype + "&reference_docname=" + reference_docname) try: redirect_flow = client.redirect_flows.create( params={ "description": _("Pay {0} {1}".format(data['amount'], data['currency'])), "session_token": dataent.session.user, "success_redirect_url": success_url, "prefilled_customer": prefilled_customer }) return {"redirect_to": redirect_flow.redirect_url} except Exception as e: dataent.log_error(e, "GoCardless Payment Error") return {"redirect_to": '/integrations/payment-failed'}
def submit_invoice(si_doc, name, doc, name_list): try: si_doc.insert() si_doc.submit() dataent.db.commit() name_list.append(name) except Exception as e: if dataent.message_log: dataent.message_log.pop() dataent.db.rollback() dataent.log_error(dataent.get_traceback()) name_list = save_invoice(doc, name, name_list) return name_list
def process(data): """ Checks a `Subscription` and updates it status as necessary """ if data: try: subscription = dataent.get_doc('Subscription', data['name']) subscription.process() dataent.db.commit() except dataent.ValidationError: dataent.db.rollback() dataent.db.begin() dataent.log_error(dataent.get_traceback()) dataent.db.commit()
def get_redirect_url(): if not dataent.conf.dropbox_broker_site: dataent.conf.dropbox_broker_site = 'https://dropbox.epaas.xyz' url = "{0}/api/method/dropbox_epaas_broker.www.setup_dropbox.get_authotize_url".format(dataent.conf.dropbox_broker_site) try: response = make_post_request(url, data={"site": get_url()}) if response.get("message"): return response["message"] except Exception: dataent.log_error() dataent.throw( _("Something went wrong while generating dropbox access token. Please check error log for more details.") )
def _log_error(self, execption, data=""): import json, traceback traceback.print_exc() dataent.log_error(title="QuickBooks Migration Error", message="\n".join([ "Data", json.dumps(data, sort_keys=True, indent=4, separators=(',', ': ') ), "Exception", traceback.format_exc() ]) )
def get_prepared_report_result(report, filters, dn="", user=None): latest_report_data = {} doc = None if dn: # Get specified dn doc = dataent.get_doc("Prepared Report", dn) else: # Only look for completed prepared reports with given filters. doc_list = dataent.get_all("Prepared Report", filters={ "status": "Completed", "filters": json.dumps(filters), "owner": user, "report_name": report.report_name }) if doc_list: # Get latest doc = dataent.get_doc("Prepared Report", doc_list[0]) if doc: try: # Prepared Report data is stored in a GZip compressed JSON file attached_file_name = dataent.db.get_value( "File", { "attached_to_doctype": doc.doctype, "attached_to_name": doc.name }, "name") compressed_content = get_file(attached_file_name)[1] uncompressed_content = gzip_decompress(compressed_content) data = json.loads(uncompressed_content) if data: columns = json.loads(doc.columns) if doc.columns else data[0] for column in columns: if isinstance(column, dict): column["label"] = _(column["label"]) latest_report_data = {"columns": columns, "result": data} except Exception: dataent.log_error(dataent.get_traceback()) dataent.delete_doc("Prepared Report", doc.name) dataent.db.commit() doc = None latest_report_data.update({"prepared_report": True, "doc": doc}) return latest_report_data
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) if charge.captured == True: self.integration_request.db_set('status', 'Completed', update_modified=False) self.flags.status_changed_to = "Completed" else: dataent.log_error(charge.failure_message, 'Stripe Payment not completed') except Exception: dataent.log_error(dataent.get_traceback()) return self.finalize_request()
def reset_enabled_scheduler_events(login_manager): if login_manager.info.user_type == "System User": try: if dataent.db.get_global('enabled_scheduler_events'): # clear restricted events, someone logged in! dataent.db.set_global('enabled_scheduler_events', None) except pymysql.InternalError as e: if e.args[0] == ER.LOCK_WAIT_TIMEOUT: dataent.log_error(dataent.get_traceback(), "Error in reset_enabled_scheduler_events") else: raise else: is_dormant = dataent.conf.get('dormant') if is_dormant: update_site_config('dormant', 'None')
def ipn_handler(): try: data = dataent.local.form_dict validate_ipn_request(data) data.update({ "payment_gateway": "PayPal" }) doc = dataent.get_doc({ "data": json.dumps(dataent.local.form_dict), "doctype": "Integration Request", "integration_type": "Subscription Notification", "status": "Queued" }).insert(ignore_permissions=True) dataent.db.commit() dataent.enqueue(method='dataent.integrations.doctype.paypal_settings.paypal_settings.handle_subscription_notification', queue='long', timeout=600, is_async=True, **{"doctype": "Integration Request", "docname": doc.name}) except dataent.InvalidStatusError: pass except Exception as e: dataent.log(dataent.log_error(title=e))
def create_request(self, data): import stripe self.data = dataent._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: dataent.log_error(dataent.get_traceback()) return{ "redirect_to": dataent.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 }