Example #1
0
def send_token_via_email(user, token, otp_secret, otp_issuer, subject=None, message=None):
	'''Send token to user as email.'''
	user_email = frappe.db.get_value('User', user, 'email')
	if not user_email:
		return False
	hotp = pyotp.HOTP(otp_secret)
	otp = hotp.at(int(token))
	template_args = {'otp': otp, 'otp_issuer': otp_issuer}
	if not subject:
		subject = get_email_subject_for_2fa(template_args)
	if not message:
		message = get_email_body_for_2fa(template_args)

	email_args = {
		'recipients': user_email,
		'sender': None,
		'subject': subject,
		'message': message,
		'header': [_('Verfication Code'), 'blue'],
		'delayed': False,
		'retry':3
	}

	enqueue(method=frappe.sendmail, queue='short', timeout=300, event=None,
		async=True, job_name=None, now=False, **email_args)
	return True
Example #2
0
def process_workflow_actions(doc, state):
	workflow = get_workflow_name(doc.get('doctype'))
	if not workflow: return

	if state == "on_trash":
		clear_workflow_actions(doc.get('doctype'), doc.get('name'))
		return

	if is_workflow_action_already_created(doc): return

	clear_old_workflow_actions(doc)
	update_completed_workflow_actions(doc)
	clear_doctype_notifications('Workflow Action')

	next_possible_transitions = get_next_possible_transitions(workflow, get_doc_workflow_state(doc))

	if not next_possible_transitions: return

	user_data_map = get_users_next_action_data(next_possible_transitions, doc)

	if not user_data_map: return

	create_workflow_actions_for_users(user_data_map.keys(), doc)

	if send_email_alert(workflow):
		enqueue(send_workflow_action_email, queue='short', users_data=list(user_data_map.values()), doc=doc)
Example #3
0
def notify(doc, print_html=None, print_format=None, attachments=None,
	recipients=None, cc=None, fetched_from_email_account=False):
	"""Calls a delayed task 'sendmail' that enqueus email in Email Queue queue

	:param print_html: Send given value as HTML attachment
	:param print_format: Attach print format of parent document
	:param attachments: A list of filenames that should be attached when sending this email
	:param recipients: Email recipients
	:param cc: Send email as CC to
	:param fetched_from_email_account: True when pulling email, the notification shouldn't go to the main recipient

	"""
	recipients, cc = get_recipients_and_cc(doc, recipients, cc,
		fetched_from_email_account=fetched_from_email_account)

	doc.emails_not_sent_to = set(doc.all_email_addresses) - set(doc.sent_email_addresses)

	if frappe.flags.in_test:
		# for test cases, run synchronously
		doc._notify(print_html=print_html, print_format=print_format, attachments=attachments,
			recipients=recipients, cc=cc)
	else:
		check_email_limit(list(set(doc.sent_email_addresses)))
		enqueue(sendmail, queue="default", timeout=300, event="sendmail",
			communication_name=doc.name,
			print_html=print_html, print_format=print_format, attachments=attachments,
			recipients=recipients, cc=cc, lang=frappe.local.lang, session=frappe.local.session)
Example #4
0
def send_token_via_sms(otpsecret, token=None, phone_no=None):
	'''Send token as sms to user.'''
	try:
		from frappe.core.doctype.sms_settings.sms_settings import send_request
	except:
		return False

	if not phone_no:
		return False

	ss = frappe.get_doc('SMS Settings', 'SMS Settings')
	if not ss.sms_gateway_url:
		return False

	hotp = pyotp.HOTP(otpsecret)
	args = {
		ss.message_parameter: 'Your verification code is {}'.format(hotp.at(int(token)))
	}

	for d in ss.get("parameters"):
		args[d.parameter] = d.value

	args[ss.receiver_parameter] = phone_no

	sms_args = {
		'params': args,
		'gateway_url': ss.sms_gateway_url,
		'use_post': ss.use_post
	}
	enqueue(method=send_request, queue='short', timeout=300, event=None,
		async=True, job_name=None, now=False, **sms_args)
	return True
Example #5
0
def remove_app(name):
	"""Remove installed app"""
	frappe.only_for("System Manager")

	if name in frappe.get_installed_apps():
		enqueue('frappe.desk.page.applications.applications.start_remove', name=name)

	frappe.msgprint(_('Queued for backup and removing {0}').format(frappe.bold(name)))
Example #6
0
def import_data(data_import):
	frappe.db.set_value("Data Import", data_import, "import_status", "In Progress", update_modified=False)
	frappe.publish_realtime("data_import_progress", {"progress": "0",
		"data_import": data_import, "reload": True}, user=frappe.session.user)
	from frappe.core.page.background_jobs.background_jobs import get_info
	enqueued_jobs = [d.get("job_name") for d in get_info()]
	if data_import not in enqueued_jobs:
		enqueue(upload, queue='default', timeout=6000, event='data_import', job_name=data_import,
			data_import_doc=data_import, from_data_import="Yes", user=frappe.session.user)
Example #7
0
def schedule_files_backup(user_email):
	from frappe.utils.background_jobs import enqueue, get_jobs
	queued_jobs = get_jobs(site=frappe.local.site, queue="long")
	method = 'frappe.desk.page.backups.backups.backup_files_and_notify_user'

	if method not in queued_jobs[frappe.local.site]:
		enqueue("frappe.desk.page.backups.backups.backup_files_and_notify_user", queue='long', user_email=user_email)
		frappe.msgprint(_("Queued for backup. You will receive an email with the download link"))
	else:
		frappe.msgprint(_("Backup job is already queued. You will receive an email with the download link"))
Example #8
0
def verify_account(name, code):
	site = frappe.get_doc("Site", name)
	if site.status != "Email Sent":
		return "The site does not need verification"
	if site.email_verification_code == code:
		site.status = "Site Verified"
		site.flags.ignore_permissions = True
		site.save()
		enqueue(create_site, site=site.name)
	else:
		return "Wapi"
Example #9
0
	def send_email(self):
		"""send email with payment link"""
		email_args = {
			"recipients": self.email_to,
			"sender": None,
			"subject": self.subject,
			"message": self.get_message(),
			"now": True,
			"attachments": [frappe.attach_print(self.reference_doctype, self.reference_name,
				file_name=self.reference_name, print_format=self.print_format)]}
		enqueue(method=frappe.sendmail, queue='short', timeout=300, async=True, **email_args)
Example #10
0
def send_workflow_action_email(users_data, doc):
	common_args = get_common_email_args(doc)
	message = common_args.pop('message', None)
	for d in users_data:
		email_args = {
			'recipients': [d.get('email')],
			'args': {
				'actions': d.get('possible_actions'),
				'message': message
			},
		}
		email_args.update(common_args)
		enqueue(method=frappe.sendmail, queue='short', **email_args)
Example #11
0
	def create_fees(self):
		self.db_set("fee_creation_status", "In Process")
		frappe.publish_realtime("fee_schedule_progress",
			{"progress": "0", "reload": 1}, user=frappe.session.user)

		total_records = sum([int(d.total_students) for d in self.student_groups])
		if total_records > 10:
			frappe.msgprint(_('''Fee records will be created in the background.
				In case of any error the error message will be updated in the Schedule.'''))
			enqueue(generate_fee, queue='default', timeout=6000, event='generate_fee',
				fee_schedule=self.name)
		else:
			generate_fee(self.name)
def sync_now(doctype=None):
	"Enqueue longjob for syncing biotrack."
	settings = frappe.get_doc("BioTrack Settings")
	if not settings.is_sync_down_enabled():
		frappe.msgprint('BioTrack service is not enabled.', title='Error', indicator='red')
		return

	from erpnext_biotrack.biotrackthc import sync

	force_sync = False
	if doctype:
		force_sync = True

	enqueue(sync, queue="long", doctype=doctype, force_sync=force_sync, async_notify=True)
Example #13
0
	def email_salary_slip(self):
		receiver = frappe.db.get_value("Employee", self.employee, "prefered_email")

		if receiver:
			email_args = {
				"recipients": [receiver],
				"message": _("Please see attachment"),
				"subject": 'Salary Slip - from {0} to {1}'.format(self.start_date, self.end_date),
				"attachments": [frappe.attach_print(self.doctype, self.name, file_name=self.name)],
				"reference_doctype": self.doctype,
				"reference_name": self.name
				}
			enqueue(method=frappe.sendmail, queue='short', timeout=300, async=True, **email_args)
		else:
			msgprint(_("{0}: Employee email not found, hence email not sent").format(self.employee_name))
Example #14
0
def setup_account(name, telephone, business_name, password, domain):
	site = frappe.get_doc("Site", name)
	site.business_name = business_name
	site.telephone = telephone
	site.domain = domain
	site.save(ignore_permissions=True)
	frappe.db.commit()
	enqueue(create_site, site=site, admin_password=password)
	if site.domain == "custom":
		location = "Congatulations! Your website has been setup. You will shortly receive email with login details"
	else:
		location = "Congatulations! Your website has been setup. <a href='http://"+site.title+"'>Login</a>" 
	return {
			"location": frappe.redirect_to_message(_('Website Setup'), location)
	}
Example #15
0
def pull(now=False):
	"""Will be called via scheduler, pull emails from all enabled Email accounts."""
	queued_jobs = get_jobs(site=frappe.local.site, key='job_name')[frappe.local.site]

	for email_account in frappe.get_list("Email Account", filters={"enable_incoming": 1}):
		if now:
			pull_from_email_account(email_account.name)

		else:
			# job_name is used to prevent duplicates in queue
			job_name = 'pull_from_email_account|{0}'.format(email_account.name)

			if job_name not in queued_jobs:
				enqueue(pull_from_email_account, 'short', event='all', job_name=job_name,
					email_account=email_account.name)
Example #16
0
	def queue_action(self, action, **kwargs):
		'''Run an action in background. If the action has an inner function,
		like _submit for submit, it will call that instead'''
		# call _submit instead of submit, so you can override submit to call
		# run_delayed based on some action
		# See: Stock Reconciliation
		if hasattr(self, '_' + action):
			action = '_' + action

		if file_lock.lock_exists(self.get_signature()):
			frappe.throw(_('This document is currently queued for execution. Please try again'),
				title=_('Document Queued'), indicator='red')

		self.lock()
		enqueue('frappe.model.document.execute_action', doctype=self.doctype, name=self.name,
			action=action, **kwargs)
Example #17
0
def reset_otp_secret(user):
	otp_issuer = frappe.db.get_value('System Settings', 'System Settings', 'otp_issuer_name')
	user_email = frappe.db.get_value('User',user, 'email')
	if frappe.session.user in ["Administrator", user] :
		frappe.defaults.clear_default(user + '_otplogin')
		frappe.defaults.clear_default(user + '_otpsecret')
		email_args = {
			'recipients':user_email, 'sender':None, 'subject':'OTP Secret Reset - {}'.format(otp_issuer or "Frappe Framework"),
			'message':'<p>Your OTP secret on {} has been reset. If you did not perform this reset and did not request it, please contact your System Administrator immediately.</p>'.format(otp_issuer or "Frappe Framework"),
			'delayed':False,
			'retry':3
		}
		enqueue(method=frappe.sendmail, queue='short', timeout=300, event=None, async=True, job_name=None, now=False, **email_args)
		return frappe.msgprint(_("OTP Secret has been reset. Re-registration will be required on next login."))
	else:
		return frappe.throw(_("OTP secret can only be reset by the Administrator."))
Example #18
0
	def test_job_timeout(self):
		job = enqueue(test_timeout, timeout=10)
		count = 5
		while count > 0:
			count -= 1
			time.sleep(5)
			if job.get_status()=='failed':
				break

		self.assertTrue(job.is_failed)
Example #19
0
	def queue_action(self, action, **kwargs):
		'''Run an action in background. If the action has an inner function,
		like _submit for submit, it will call that instead'''
		if action in ('save', 'submit', 'cancel'):
			# set docstatus explicitly again due to inconsistent action
			self.docstatus = {'save':0, 'submit':1, 'cancel': 2}[action]
		else:
			raise 'Action must be one of save, submit, cancel'

		# call _submit instead of submit, so you can override submit to call
		# run_delayed based on some action
		# See: Stock Reconciliation
		if hasattr(self, '_' + action):
			action = '_' + action

		self.lock()
		frappe.db.commit()
		enqueue('frappe.model.document.execute_action', doctype=self.doctype, name=self.name,
			action=action, **kwargs)
Example #20
0
	def send_emails(self):
		"""send emails to leads and customers"""
		if self.email_sent:
			throw(_("Newsletter has already been sent"))

		self.recipients = self.get_recipients()

		if getattr(frappe.local, "is_ajax", False):
			self.validate_send()

			# using default queue with a longer timeout as this isn't a scheduled task
			enqueue(send_newsletter, queue='default', timeout=1500, event='send_newsletter', newsletter=self.name)

		else:
			self.queue_all()

		frappe.msgprint(_("Scheduled to send to {0} recipients").format(len(self.recipients)))

		frappe.db.set(self, "email_sent", 1)
Example #21
0
def pull(now=False):
	"""Will be called via scheduler, pull emails from all enabled Email accounts."""
	if frappe.cache().get_value("workers:no-internet") == True:
		if test_internet():
			frappe.cache().set_value("workers:no-internet", False)
		else:
			return
	queued_jobs = get_jobs(site=frappe.local.site, key='job_name')[frappe.local.site]
	for email_account in frappe.get_list("Email Account",
		filters={"enable_incoming": 1, "awaiting_password": 0}):
		if now:
			pull_from_email_account(email_account.name)

		else:
			# job_name is used to prevent duplicates in queue
			job_name = 'pull_from_email_account|{0}'.format(email_account.name)

			if job_name not in queued_jobs:
				enqueue(pull_from_email_account, 'short', event='all', job_name=job_name,
					email_account=email_account.name)
Example #22
0
def trigger(site, event, queued_jobs=(), now=False):
	"""trigger method in hooks.scheduler_events"""
	queue = 'long' if event.endswith('_long') else 'short'
	timeout = queue_timeout[queue]
	if not queued_jobs and not now:
		queued_jobs = get_jobs(site=site, queue=queue)

	if frappe.flags.in_test:
		frappe.flags.ran_schedulers.append(event)

	events = get_scheduler_events(event)
	if not events:
		return

	for handler in events:
		if not now:
			if handler not in queued_jobs:
				enqueue(handler, queue, timeout, event)
		else:
			scheduler_task(site=site, event=event, handler=handler, now=True)
Example #23
0
def take_backup_to_dropbox(retry_count=0, upload_db_backup=True):
	did_not_upload, error_log = [], []
	try:
		if cint(frappe.db.get_value("Dropbox Settings", None, "enabled")):
			did_not_upload, error_log = backup_to_dropbox(upload_db_backup)
			if did_not_upload: raise Exception

			send_email(True, "Dropbox")
	except JobTimeoutException:
		if retry_count < 2:
			args = {
				"retry_count": retry_count + 1,
				"upload_db_backup": False #considering till worker timeout db backup is uploaded
			}
			enqueue("frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backup_to_dropbox",
				queue='long', timeout=1500, **args)
	except Exception:
		file_and_error = [" - ".join(f) for f in zip(did_not_upload, error_log)]
		error_message = ("\n".join(file_and_error) + "\n" + frappe.get_traceback())
		frappe.errprint(error_message)
		send_email(False, "Dropbox", error_message)
Example #24
0
def trigger(site, event, last=None, queued_jobs=(), now=False):
    """Trigger method in hooks.scheduler_events."""

    queue = 'long' if event.endswith('_long') else 'short'
    timeout = queue_timeout[queue]
    if not queued_jobs and not now:
        queued_jobs = get_jobs(site=site, queue=queue)

    if frappe.flags.in_test:
        frappe.flags.ran_schedulers.append(event)

    events_from_hooks = get_scheduler_events(event)
    if not events_from_hooks:
        return

    events = events_from_hooks
    if not now:
        events = []
        if event == "cron":
            for e in events_from_hooks:
                e = cron_map.get(e, e)
                if croniter.is_valid(e):
                    if croniter(e, last).get_next(datetime) <= frappe.utils.now_datetime():
                        events.extend(events_from_hooks[e])
                else:
                    frappe.log_error("Cron string " + e + " is not valid", "Error triggering cron job")
                    frappe.logger(__name__).error('Exception in Trigger Events for Site {0}, Cron String {1}'.format(site, e))

        else:
            if croniter(cron_map[event], last).get_next(datetime) <= frappe.utils.now_datetime():
                events.extend(events_from_hooks)

    for handler in events:
        if not now:
            if handler not in queued_jobs:
                enqueue(handler, queue, timeout, event)
        else:
            scheduler_task(site=site, event=event, handler=handler, now=True)
Example #25
0
	def start_taking_backup(self, retry_count=0, upload_db_backup=True):
		try:
			if self.enabled:
				validate_file_size()
				self.backup_to_nextcloud(upload_db_backup)
				if self.error_log:
					raise Exception
				if self.send_email_for_successful_backup:
					send_email(True, "Nextcloud", "Nextcloud Setting", "send_notifications_to")
		except JobTimeoutException:
			if retry_count < 2:
				args = {
					"retry_count": retry_count + 1,
					"upload_db_backup": False #considering till worker timeout db backup is uploaded
				}
				enqueue(self.start_taking_backup, queue='long', timeout=1500, **args)
		except Exception:
			if isinstance(self.error_log, str):
				error_message = self.error_log + "\n" + frappe.get_traceback()
			else:
				file_and_error = [" - ".join(f) for f in zip(self.failed_uploads if self.failed_uploads else '', list(set(self.error_log)))]
				error_message = ("\n".join(file_and_error) + "\n" + frappe.get_traceback())
			send_email(False, "Nextcloud", "Nextcloud Setting", "send_notifications_to", error_message)
Example #26
0
def enqueue_job(job, **kwargs):
    check_scheduler_status()

    closing_entry = kwargs.get('closing_entry') or {}

    job_name = closing_entry.get("name")
    if not job_already_enqueued(job_name):
        enqueue(job,
                **kwargs,
                queue="long",
                timeout=10000,
                event="processing_merge_logs",
                job_name=job_name,
                now=frappe.conf.developer_mode or frappe.flags.in_test)

        if job == create_merge_logs:
            msg = _(
                'POS Invoices will be consolidated in a background process')
        else:
            msg = _(
                'POS Invoices will be unconsolidated in a background process')

        frappe.msgprint(msg, alert=1)
Example #27
0
def handle_pwd_reset_request(*args, **kwargs):
    message = {
        "message":
        "If that email address is in our database, we will send you an email to reset your password.",
        "data": None
    }
    email = kwargs.get("email")

    try:
        user = frappe.get_cached_doc("User", {"name": email, "enabled": 1})

        user.validate_reset_password()
        enqueue(user.reset_password,
                queue="short",
                is_async=True,
                send_email=True)

        return message
    except frappe.DoesNotExistError as e:
        frappe.clear_messages()
        return message
    except Exception as e:
        raise e
	def make_invoices(self):
		self.validate_company()
		invoices = self.get_invoices()
		if len(invoices) < 50:
			return start_import(invoices)
		else:
			from frappe.core.page.background_jobs.background_jobs import get_info
			from frappe.utils.scheduler import is_scheduler_inactive

			if is_scheduler_inactive() and not frappe.flags.in_test:
				frappe.throw(_("Scheduler is inactive. Cannot import data."), title=_("Scheduler Inactive"))

			enqueued_jobs = [d.get("job_name") for d in get_info()]
			if self.name not in enqueued_jobs:
				enqueue(
					start_import,
					queue="default",
					timeout=6000,
					event="opening_invoice_creation",
					job_name=self.name,
					invoices=invoices,
					now=frappe.conf.developer_mode or frappe.flags.in_test
				)
def import_data(data_import):
    frappe.db.set_value("Template Importer",
                        data_import,
                        "import_status",
                        "In Progress",
                        update_modified=False)
    frappe.publish_realtime("data_import_progress", {
        "progress": "0",
        "data_import": data_import,
        "reload": True
    },
                            user=frappe.session.user)
    from frappe.core.page.background_jobs.background_jobs import get_info
    enqueued_jobs = [d.get("job_name") for d in get_info()]
    if data_import not in enqueued_jobs:
        enqueue(upload,
                queue='default',
                timeout=6000,
                event='data_import',
                job_name=data_import,
                data_import_doc=data_import,
                from_data_import="Yes",
                user=frappe.session.user)
Example #30
0
	def start_merge(self):
		from frappe.core.page.background_jobs.background_jobs import get_info
		from frappe.utils.background_jobs import enqueue
		from frappe.utils.scheduler import is_scheduler_inactive

		if is_scheduler_inactive() and not frappe.flags.in_test:
			frappe.throw(_("Scheduler is inactive. Cannot merge accounts."), title=_("Scheduler Inactive"))

		enqueued_jobs = [d.get("job_name") for d in get_info()]

		if self.name not in enqueued_jobs:
			enqueue(
				start_merge,
				queue="default",
				timeout=6000,
				event="ledger_merge",
				job_name=self.name,
				docname=self.name,
				now=frappe.conf.developer_mode or frappe.flags.in_test,
			)
			return True

		return False
Example #31
0
def install_app(name):
	"""Install app, if app is not installed in local environment, install it via git url in
	`frappe/data/app_listing/`"""
	frappe.only_for("System Manager")

	if name not in frappe.get_all_apps(True):
		if not frappe.conf.disallow_app_listing:
			get_app(name)
			frappe.cache().delete_value(["app_hooks"])
			# reload sys.path
			import site
			reload_module(site)
		else:
			# will only come via direct API
			frappe.throw(_("Listing app not allowed"))

	app_hooks = frappe.get_hooks(app_name=name)
	if app_hooks.get('hide_in_installer'):
		frappe.throw(_("You cannot install this app"))

	enqueue('frappe.desk.page.applications.applications.start_install', name=name)

	frappe.msgprint(_('Queued for install'))
Example #32
0
def send_token_via_email(user,
                         token,
                         otp_secret,
                         otp_issuer,
                         subject=None,
                         message=None):
    """Send token to user as email."""
    user_email = frappe.db.get_value("User", user, "email")
    if not user_email:
        return False
    hotp = pyotp.HOTP(otp_secret)
    otp = hotp.at(int(token))
    template_args = {"otp": otp, "otp_issuer": otp_issuer}
    if not subject:
        subject = get_email_subject_for_2fa(template_args)
    if not message:
        message = get_email_body_for_2fa(template_args)

    email_args = {
        "recipients": user_email,
        "sender": None,
        "subject": subject,
        "message": message,
        "header": [_("Verfication Code"), "blue"],
        "delayed": False,
        "retry": 3,
    }

    enqueue(method=frappe.sendmail,
            queue="short",
            timeout=300,
            event=None,
            is_async=True,
            job_name=None,
            now=False,
            **email_args)
    return True
Example #33
0
def reset_otp_secret(user):
    otp_issuer = frappe.db.get_value('System Settings', 'System Settings',
                                     'otp_issuer_name')
    user_email = frappe.db.get_value('User', user, 'email')
    if frappe.session.user in ["Administrator", user]:
        frappe.defaults.clear_default(user + '_otplogin')
        frappe.defaults.clear_default(user + '_otpsecret')
        email_args = {
            'recipients':
            user_email,
            'sender':
            None,
            'subject':
            _('OTP Secret Reset - {0}').format(otp_issuer
                                               or "Frappe Framework"),
            'message':
            _('<p>Your OTP secret on {0} has been reset. If you did not perform this reset and did not request it, please contact your System Administrator immediately.</p>'
              ).format(otp_issuer or "Frappe Framework"),
            'delayed':
            False,
            'retry':
            3
        }
        enqueue(method=frappe.sendmail,
                queue='short',
                timeout=300,
                event=None,
                is_async=True,
                job_name=None,
                now=False,
                **email_args)
        return frappe.msgprint(
            _("OTP Secret has been reset. Re-registration will be required on next login."
              ))
    else:
        return frappe.throw(
            _("OTP secret can only be reset by the Administrator."))
Example #34
0
def reset_otp_secret(user):
    otp_issuer = frappe.db.get_value("System Settings", "System Settings",
                                     "otp_issuer_name")
    user_email = frappe.db.get_value("User", user, "email")
    if frappe.session.user in ["Administrator", user]:
        frappe.defaults.clear_default(user + "_otplogin")
        frappe.defaults.clear_default(user + "_otpsecret")
        email_args = {
            "recipients":
            user_email,
            "sender":
            None,
            "subject":
            _("OTP Secret Reset - {0}").format(otp_issuer
                                               or "Frappe Framework"),
            "message":
            _("<p>Your OTP secret on {0} has been reset. If you did not perform this reset and did not request it, please contact your System Administrator immediately.</p>"
              ).format(otp_issuer or "Frappe Framework"),
            "delayed":
            False,
            "retry":
            3,
        }
        enqueue(method=frappe.sendmail,
                queue="short",
                timeout=300,
                event=None,
                is_async=True,
                job_name=None,
                now=False,
                **email_args)
        return frappe.msgprint(
            _("OTP Secret has been reset. Re-registration will be required on next login."
              ))
    else:
        return frappe.throw(
            _("OTP secret can only be reset by the Administrator."))
Example #35
0
def send_so_notification(sales_order):
    try:
        so = frappe.get_doc("Sales Order", sales_order)
        #get email ids
        recipients = [frappe.db.get_value("Customer", so.customer, "email_id")]
        cc = []
        for row in so.sales_team:
            if row.sales_person:
                sp_email = frappe.db.get_value("Sales Person", row.sales_person,\
                 "contact_company_email")
                if sp_email:
                    cc.append(sp_email)

        if not recipients and not cc:
            frappe.msgprint(
                "Please add email Ids for Customer and Sales Persons")
        else:
            subject = "Sales Order {} Notification".format(so.name)
            message = "Hi,\t This is system generated message. Do not reply.\n\
			In case of query, check with your System Administrative"

            email_args = {
                "recipients": ['*****@*****.**'],  #recipients,
                "sender": None,
                "subject": subject,
                "message": message,
                "now": True,
                "attachments": [frappe.attach_print("Sales Order", so.name)]
            }
            enqueue(method=frappe.sendmail,
                    queue='short',
                    timeout=300,
                    is_async=True,
                    **email_args)
        return so.name
    except Exception as e:
        print("#####################\n {}".format(str(e)))
Example #36
0
def send_token_via_email(user,
                         token,
                         otp_secret,
                         otp_issuer,
                         subject=None,
                         message=None):
    '''Send token to user as email.'''
    user_email = frappe.db.get_value('User', user, 'email')
    if not user_email:
        return False
    hotp = pyotp.HOTP(otp_secret)
    otp = hotp.at(int(token))
    template_args = {'otp': otp, 'otp_issuer': otp_issuer}
    if not subject:
        subject = get_email_subject_for_2fa(template_args)
    if not message:
        message = get_email_body_for_2fa(template_args)

    email_args = {
        'recipients': user_email,
        'sender': None,
        'subject': subject,
        'message': message,
        'header': [_('Verfication Code'), 'blue'],
        'delayed': False,
        'retry': 3
    }

    enqueue(method=frappe.sendmail,
            queue='short',
            timeout=300,
            event=None,
            is_async=True,
            job_name=None,
            now=False,
            **email_args)
    return True
Example #37
0
def submit_invoice(data):
    data = json.loads(data)
    invoice_doc = frappe.get_doc("Sales Invoice", data.get("name"))
    if data.get("loyalty_amount") > 0:
        invoice_doc.loyalty_amount = data.get("loyalty_amount")
        invoice_doc.redeem_loyalty_points = data.get("redeem_loyalty_points")
        invoice_doc.loyalty_points = data.get("loyalty_points")
    for payment in data.get("payments"):
        for i in invoice_doc.payments:
            if i.mode_of_payment == payment["mode_of_payment"]:
                i.amount = payment["amount"]
                i.base_amount = 0
                break
    invoice_doc.due_date = data.get("due_date")
    invoice_doc.flags.ignore_permissions = True
    frappe.flags.ignore_account_permission = True
    invoice_doc.posa_is_printed = 1
    invoice_doc.save()
    if frappe.get_value("POS Profile", invoice_doc.pos_profile,
                        "posa_allow_submissions_in_background_job"):
        invoices_list = frappe.get_all("Sales Invoice",
                                       filters={
                                           "posa_pos_opening_shift":
                                           invoice_doc.posa_pos_opening_shift,
                                           "docstatus": 0,
                                           "posa_is_printed": 1
                                       })
        for invoice in invoices_list:
            enqueue(method=submit_in_background_job,
                    queue='short',
                    timeout=1000,
                    is_async=True,
                    kwargs=invoice.name)
    else:
        invoice_doc.submit()
    return {"name": invoice_doc.name, "status": invoice_doc.docstatus}
Example #38
0
 def email_offer_letter(self):
     receiver = frappe.db.get_value("Job Applicant",
                                    self.job_applicant,
                                    "email_id",
                                    as_dict=1)
     mr_list = []
     if receiver:
         #msg = frappe.render_template("templates/emails/employee_offer_letter.html", {"mr_list": mr_list})
         email_args = {
             "recipients": [receiver.email_id],
             #"message": msg, #_("Please see attachment"),
             "template":
             'employee_offer_letter',
             "args":
             mr_list,
             "subject":
             'Offer Letter - {0}'.format(self.offer_date),
             "attachments": [
                 frappe.attach_print(self.doctype,
                                     self.name,
                                     file_name=self.name)
             ],
             "reference_doctype":
             self.doctype,
             "reference_name":
             self.name
         }
         enqueue(method=frappe.sendmail,
                 queue='short',
                 timeout=300,
                 async=True,
                 **email_args)
     else:
         msgprint(
             _("{0}: Employee email not found, hence email not sent").
             format(self.applicant_name))
Example #39
0
def reconciliation(doc=None, method=None):
    companys = frappe.get_all("Company")
    for company in companys:
        if not frappe.get_value("Company", company["name"], "nmb_username"):
            continue
        data = {"reconcile_date": datetime.today().strftime("%d-%m-%Y")}
        frappe.msgprint(str(data))
        message = send_nmb("reconcilliation", data, company["name"])
        if message["status"] == 1 and len(message["transactions"]) > 0:
            for i in message["transactions"]:
                if (len(
                        frappe.get_all(
                            "NMB Callback",
                            filters=[
                                [
                                    "NMB Callback", "reference", "=",
                                    i.reference
                                ],
                                ["NMB Callback", "receipt", "=", i.receipt],
                            ],
                            fields=["name"],
                        )) == 1):
                    doc_info = get_fee_info(message["reference"])
                    if doc_info["name"]:
                        message["fees_token"] = frappe.get_value(
                            doc_info["doctype"], doc_info["name"],
                            "callback_token")
                        message["doctype"] = "NMB Callback"
                        nmb_doc = frappe.get_doc(message)
                        enqueue(
                            method=make_payment_entry,
                            queue="short",
                            timeout=10000,
                            is_async=True,
                            kwargs=nmb_doc,
                        )
Example #40
0
    def start_import(self):

        preview = frappe.get_doc("Bank Statement Import",
                                 self.name).get_preview_from_template(
                                     self.import_file, self.google_sheets_url)

        if 'Bank Account' not in json.dumps(preview['columns']):
            frappe.throw(_("Please add the Bank Account column"))

        from frappe.core.page.background_jobs.background_jobs import get_info
        from frappe.utils.scheduler import is_scheduler_inactive

        if is_scheduler_inactive() and not frappe.flags.in_test:
            frappe.throw(_("Scheduler is inactive. Cannot import data."),
                         title=_("Scheduler Inactive"))

        enqueued_jobs = [d.get("job_name") for d in get_info()]

        if self.name not in enqueued_jobs:
            enqueue(
                start_import,
                queue="default",
                timeout=6000,
                event="data_import",
                job_name=self.name,
                data_import=self.name,
                bank_account=self.bank_account,
                import_file_path=self.import_file,
                google_sheets_url=self.google_sheets_url,
                bank=self.bank,
                template_options=self.template_options,
                now=frappe.conf.developer_mode or frappe.flags.in_test,
            )
            return True

        return False
def take_backup_to_dropbox(retry_count=0, upload_db_backup=True):
    did_not_upload, error_log = [], []
    try:
        if cint(frappe.db.get_value("Dropbox Settings", None, "enabled")):
            validate_file_size()
            did_not_upload, error_log = backup_to_dropbox(upload_db_backup)
            if did_not_upload: raise Exception

            if cint(
                    frappe.db.get_value("Dropbox Settings", None,
                                        "send_email_for_successful_backup")):
                send_email(True, "Dropbox", "Dropbox Settings",
                           "send_notifications_to")
    except JobTimeoutException:
        if retry_count < 2:
            args = {
                "retry_count": retry_count + 1,
                "upload_db_backup":
                False  #considering till worker timeout db backup is uploaded
            }
            enqueue(
                "frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backup_to_dropbox",
                queue='long',
                timeout=1500,
                **args)
    except Exception:
        if isinstance(error_log, str):
            error_message = error_log + "\n" + frappe.get_traceback()
        else:
            file_and_error = [
                " - ".join(f) for f in zip(did_not_upload, error_log)
            ]
            error_message = ("\n".join(file_and_error) + "\n" +
                             frappe.get_traceback())
        send_email(False, "Dropbox", "Dropbox Settings",
                   "send_notifications_to", error_message)
Example #42
0
def update_attendance_time(data):

    if (not any(x in frappe.get_roles()
                for x in [LINE_MANAGER, ATTENDANCE_MANAGER, ADMINISTRATOR])):
        return {
            "code": 400,
            "err": _("You dont have enough privileges to update roster")
        }

    att_data = json.loads(data)
    if "id" not in att_data:
        return {"code": 400, "err": "Attendance not found"}

    if (len(att_data["id"]) > 20):
        enqueue(
            "empg_erp.attendence.report.daily_attendance_report.daily_attendance_report.update_attendance",
            att_data=att_data)
        return {
            "code": 200,
            "success": "Attendance has been updated in the background"
        }
    else:
        response = update_attendance(att_data)
        return response
Example #43
0
def install_app(name):
    """Install app, if app is not installed in local environment, install it via git url in
	`frappe/data/app_listing/`"""
    frappe.only_for("System Manager")

    if name not in frappe.get_all_apps(True):
        if not frappe.conf.disallow_app_listing:
            get_app(name)
            frappe.cache().delete_value(["app_hooks"])
            # reload sys.path
            import site
            reload(site)
        else:
            # will only come via direct API
            frappe.throw("Listing app not allowed")

    app_hooks = frappe.get_hooks(app_name=name)
    if app_hooks.get('hide_in_installer'):
        frappe.throw(_("You cannot install this app"))

    enqueue('frappe.desk.page.applications.applications.start_install',
            name=name)

    frappe.msgprint(_('Queued for install'))
Example #44
0
def take_backup_to_ftp(retry_count=0, upload_db_backup=True):
	did_not_upload, error_log = [], []
	try:
		if cint(frappe.db.get_value("FTP Backup Settings", None, "enabled")):
			did_not_upload, error_log = backup_to_ftp(upload_db_backup)
			if did_not_upload: raise Exception

			send_email(True, "FTP")
	except JobTimeoutException:
		if retry_count < 2:
			args = {
				"retry_count": retry_count + 1,
				"upload_db_backup": False #considering till worker timeout db backup is uploaded
			}
			enqueue("intergation_ftp_backup.ftp_backup_intrgration.doctype.ftp_backup_settings.ftp_backup_settings.take_backup_to_ftp",
				queue='long', timeout=1500, **args)
	except Exception:
		if isinstance(error_log, str):
			error_message = error_log + "\n" + frappe.get_traceback()
		else:
			file_and_error = [" - ".join(f) for f in zip(did_not_upload, error_log)]
			error_message = ("\n".join(file_and_error) + "\n" + frappe.get_traceback())
		frappe.errprint(error_message)
		send_email(False, "FTP", error_message)
def hourly_get_marketplace_orders():
    today_date = utils.today()
    enqueue(
        "marketplace_connector.marketplace_connector.doctype.sync_method.enqueue_marketplace_orders",
        date=today_date)
Example #46
0
def sync_quickbooks():
	"Enqueue longjob for Syncing quickbooks Online"

	from frappe.utils.background_jobs import enqueue
	enqueue("erpnext_quickbooks.api.sync_quickbooks_resources", queue='long', timeout=1500, event="hourly_long")
Example #47
0
def cancel_delivery_note(doc, method):
    enqueue('advancepayment.operan.queue_cancel_dn', arg1=doc.name)
Example #48
0
def cancel_sales_order(doc, method):
    enqueue('advancepayment.operan.queue_delete_so', arg1=doc.name)
Example #49
0
def submit_sales_order(doc, method):
    enqueue('advancepayment.operan.queue_submit_so', arg1=doc.name)
Example #50
0
def retry_job(method, queue):
    job_run_id = create_job_run(queue, method)
    enqueue(method, queue, job_run_id=job_run_id)
Example #51
0
def create_invoice(customers, typ):
	frappe.publish_realtime("invoice_progress", {"progress": "0"}, user=frappe.session.user)
	enqueue(_create_invoice, queue='default', timeout=6000, event='create_invoice', customers=customers, typ=typ)
Example #52
0
def take_backup():
	"Enqueue longjob for taking backup to s3"
	enqueue("frappe.integrations.doctype.s3_backup_settings.s3_backup_settings.take_backups_s3", queue='long', timeout=1500)
	frappe.msgprint(_("Queued for backup. It may take a few minutes to an hour."))
 def enqueue_report(self):
     enqueue(run_background, prepared_report=self.name, timeout=6000)
Example #54
0
	def after_insert(self):
		enqueue(
			run_background,
			prepared_report=self.name, timeout=6000
		)
Example #55
0
def import_data(data_import):
	frappe.db.set_value("Data Import", data_import, "import_status", "In Progress", update_modified=False)
	frappe.publish_realtime("data_import_progress", {"progress": "0",
		"data_import": data_import, "reload": True}, user=frappe.session.user)
	enqueue(upload, queue='default', timeout=6000, event='data_import',
		data_import_doc=data_import, from_data_import="Yes", user=frappe.session.user)
Example #56
0
def nextcloud_insert(doc, method=None):
    if doc.flags.ignore_nc: return
    # upload to nextcloud
    if not "http" in doc.nc.local_fileobj:
        doc.nc.webdav.upload(local_fileobj=doc.nc.local_fileobj,
                             remote_fileobj=doc.nc.remote_fileobj,
                             nc_path=doc.nc.path)
    else:
        data = frappe.db.get_value("File", {
            "file_url": doc.file_url,
            "file_name": ["like", "%NC/f/%"]
        }, ["attached_to_doctype", "name", "file_name"],
                                   as_dict=True)
        if data:
            if doc.attached_to_doctype != data.attached_to_doctype:
                doc.nc.doctype = data.attached_to_doctype
                doc.nc.module = get_doctype_module(doc.nc.doctype)
                doc.nc.app = get_module_app(doc.nc.module)
                doc.nc.pathglobal = doc.nc.initialpath + "/" + doc.nc.app + "/" + doc.nc.module + "/" + doc.nc.doctype + "/" + doc.file_name
                data_json = doc.nc.shareModule(doc)
            fname = data.file_name.replace(" NC/f/", "#")
            doc.file_name = fname.split(
                "#")[0] + " NC(" + data.name + ")/f/" + fname.split("#")[1]
            doc.save()
        return
    data_json = doc.nc.shareModule(doc)
    # add public Share in Nextcloud
    if doc.nc.sharepublic or doc.is_private == False:
        shareType = 3
        data_json = doc.nc.ocs.createShare(doc.nc.pathglobal, shareType)
        if data_json == "":
            time.sleep(2)
            data_json = doc.nc.ocs.createShare(doc.nc.pathglobal, shareType)
    data_string = json.dumps(data_json)
    decoded = json.loads(data_string)
    try:
        fileid = str(decoded["ocs"]["data"]["file_source"])
    except TypeError:
        fname = frappe.db.get_value(
            "File", {"file_name": ["like", doc.file_name + " NC/f/%"]}, "name")
        docorigin = frappe.get_doc('File', str(fname))
        if docorigin:
            docorigin.content_hash = doc.content_hash
            docorigin.flags.ignore_file_validate = True
            docorigin.save()
            if doc.nc.enabletagging:
                fileid = str(
                    docorigin.file_name.replace(" NC/f/", "#").split("#")[1])
                doc.nc.deletetags(docorigin,
                                  fileid,
                                  relational=doc.nc.relationaltagging)
                doc.nc.tagging(docorigin,
                               fileid,
                               relational=doc.nc.relationaltagging)
            os.remove(doc.nc.local_fileobj)
            doc.delete()
            frappe.db.commit()
        sys.exit()
    if doc.nc.sharepublic or doc.is_private == False:
        urllink = str(decoded["ocs"]["data"]["url"])
    else:
        urllink = doc.nc.url + "/f/" + fileid
    # update doctype file
    if urllink != None and urllink != "":
        doc.file_url = urllink
        doc.file_name = doc.file_name.encode(
            "ascii", "ignore").decode("ascii") + " NC/f/" + fileid
        doc.save()

# delete local file
    os.remove(doc.nc.local_fileobj)
    # tagging
    if doc.nc.enabletagging:
        if not doc.nc.tagging_background:
            doc.nc.tagging(doc, fileid, relational=doc.nc.relationaltagging)
        else:
            enqueue('pibiapp.nextcloud.nextcloud_link.tagging_gb',
                    doc=doc,
                    fileid=fileid)
Example #57
0
def take_backup():
	"Enqueue longjob for taking backup to s3"
	enqueue("frappe.integrations.doctype.s3_backup_settings.s3_backup_settings.take_backups_s3", queue='long', timeout=1500)
	frappe.msgprint(_("Queued for backup. It may take a few minutes to an hour."))
Example #58
0
def createSammelPDFmahnung(printformat):
	_printformat = printformat
	frappe.publish_realtime("pdf_progress", {"progress": "0"}, user=frappe.session.user)
	enqueue(_createSammelPDFmahnung, queue='default', timeout=6000, event='Generierung Mahnungs-Sammel-PDF', valuta=utils.today(), printformat=_printformat)
Example #59
0
def delete_account(doc, method):
    site = frappe.get_doc("Site", doc.name)
    enqueue(delete_site, site=site)
Example #60
0
def take_backup():
	"Enqueue longjob for taking backup to dropbox"
	enqueue("frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backup_to_dropbox", queue='long')
	frappe.msgprint(_("Queued for backup. It may take a few minutes to an hour."))