Example #1
1
def get_transitions(doc, workflow = None):
	'''Return list of possible transitions for the given doc'''
	doc = frappe.get_doc(frappe.parse_json(doc))

	if doc.is_new():
		return []

	frappe.has_permission(doc, 'read', throw=True)
	roles = frappe.get_roles()

	if not workflow:
		workflow = get_workflow(doc.doctype)
	current_state = doc.get(workflow.workflow_state_field)

	if not current_state:
		frappe.throw(_('Workflow State not set'), WorkflowStateError)

	transitions = []
	for transition in workflow.transitions:
		if transition.state == current_state and transition.allowed in roles:
			if transition.condition:
				# if condition, evaluate
				# access to frappe.db.get_value and frappe.db.get_list
				success = frappe.safe_eval(transition.condition,
					dict(frappe = frappe._dict(
						db = frappe._dict(get_value = frappe.db.get_value, get_list=frappe.db.get_list),
						session = frappe.session
					)),
					dict(doc = doc))
				if not success:
					continue
			transitions.append(transition.as_dict())

	return transitions
Example #2
0
	def validate_condition(self):
		temp_doc = frappe.new_doc(self.document_type)
		if self.condition:
			try:
				frappe.safe_eval(self.condition, None, get_context(temp_doc))
			except:
				frappe.throw(_("The condition '{0}' is invalid").format(self.condition))
	def validate_formula(self):
		# evaluate the formula with 0's to make sure it is valid
		test_formula = self.formula.replace("\r", "").replace("\n", "")

		regex = r"\{(.*?)\}"

		mylist = re.finditer(regex, test_formula, re.MULTILINE | re.DOTALL)
		for dummy1, match in enumerate(mylist):
			for dummy2 in range(0, len(match.groups())):
				test_formula = test_formula.replace('{' + match.group(1) + '}', "0")

		try:
			frappe.safe_eval(test_formula,  None, {'max':max, 'min': min})
		except Exception:
			frappe.throw(_("Error evaluating the criteria formula"))
Example #4
0
	def set_breadcrumbs(self, context):
		"""Build breadcrumbs template """
		if self.breadcrumbs:
			context.parents = frappe.safe_eval(self.breadcrumbs, { "_": _ })
		if not "no_breadcrumbs" in context:
			if "<!-- no-breadcrumbs -->" in context.main_section:
				context.no_breadcrumbs = 1
	def calculate_weighted_score(self, weighing_function):
		try:
			weighed_score = frappe.safe_eval(self.get_eval_statement(weighing_function),  None, {'max':max, 'min': min})
		except Exception:
			frappe.throw(_("Could not solve weighted score function. Make sure the formula is valid."),frappe.ValidationError)
			weighed_score = 0
		return weighed_score
	def calculate_criteria(self):
		for crit in self.criteria:
			try:
				crit.score = min(crit.max_score, max( 0 ,frappe.safe_eval(self.get_eval_statement(crit.formula),  None, {'max':max, 'min': min})))
			except Exception:
				frappe.throw(_("Could not solve criteria score function for {0}. Make sure the formula is valid.".format(crit.criteria_name)),frappe.ValidationError)
				crit.score = 0
Example #7
0
	def set_status(self, update=False, status=None, update_modified=True):
		if self.is_new():
			if self.get('amended_from'):
				self.status = 'Draft'
			return

		if self.doctype in status_map:
			_status = self.status

			if status and update:
				self.db_set("status", status)

			sl = status_map[self.doctype][:]
			sl.reverse()
			for s in sl:
				if not s[1]:
					self.status = s[0]
					break
				elif s[1].startswith("eval:"):
					if frappe.safe_eval(s[1][5:], None, { "self": self.as_dict(), "getdate": getdate,
							"nowdate": nowdate, "get_value": frappe.db.get_value }):
						self.status = s[0]
						break
				elif getattr(self, s[1])():
					self.status = s[0]
					break

			if self.status != _status and self.status not in ("Cancelled", "Partially Ordered",
																"Ordered", "Issued", "Transferred"):
				self.add_comment("Label", _(self.status))

			if update:
				self.db_set('status', self.status, update_modified = update_modified)
	def calculate_criteria(self):
		#Get the criteria
		for crit in self.criteria:

			#me = ""
			my_eval_statement = crit.formula.replace("\r", "").replace("\n", "")
			#for let in my_eval_statement:
			#	me += let.encode('hex') + " "
			#frappe.msgprint(me)

			for var in self.variables:
				if var.value:
					if var.param_name in my_eval_statement:
						my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', "{:.2f}".format(var.value))
				else:
					if var.param_name in my_eval_statement:
						my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', '0.0')

			#frappe.msgprint(my_eval_statement )

			my_eval_statement = my_eval_statement.replace('&lt;','<').replace('&gt;','>')

			try:
				crit.score = min(crit.max_score, max( 0 ,frappe.safe_eval(my_eval_statement,  None, {'max':max, 'min': min})))
			except Exception:
				frappe.throw(_("Could not solve criteria score function for {0}. Make sure the formula is valid.".format(crit.criteria_name)),frappe.ValidationError)
				crit.score = 0
Example #9
0
	def get_context(self, context):
		'''Build context to render the `web_form.html` template'''
		self.set_web_form_module()

		context._login_required = False
		if self.login_required and frappe.session.user == "Guest":
			context._login_required = True

		doc, delimeter = make_route_string(frappe.form_dict)
		context.doc = doc
		context.delimeter = delimeter

		# check permissions
		if frappe.session.user == "Guest" and frappe.form_dict.name:
			frappe.throw(_("You need to be logged in to access this {0}.").format(self.doc_type), frappe.PermissionError)

		if frappe.form_dict.name and not has_web_form_permission(self.doc_type, frappe.form_dict.name):
			frappe.throw(_("You don't have the permissions to access this document"), frappe.PermissionError)

		self.reset_field_parent()

		if self.is_standard:
			self.use_meta_fields()

		if not context._login_required:
			if self.allow_edit:
				if self.allow_multiple:
					if not frappe.form_dict.name and not frappe.form_dict.new:
						self.build_as_list(context)
				else:
					if frappe.session.user != 'Guest' and not frappe.form_dict.name:
						frappe.form_dict.name = frappe.db.get_value(self.doc_type, {"owner": frappe.session.user}, "name")

					if not frappe.form_dict.name:
						# only a single doc allowed and no existing doc, hence new
						frappe.form_dict.new = 1

		# always render new form if login is not required or doesn't allow editing existing ones
		if not self.login_required or not self.allow_edit:
			frappe.form_dict.new = 1

		self.load_document(context)
		context.parents = self.get_parents(context)

		if self.breadcrumbs:
			context.parents = frappe.safe_eval(self.breadcrumbs, { "_": _ })

		context.has_header = ((frappe.form_dict.name or frappe.form_dict.new)
			and (frappe.session.user!="Guest" or not self.login_required))

		if context.success_message:
			context.success_message = frappe.db.escape(context.success_message.replace("\n",
				"<br>"))

		self.add_custom_context_and_script(context)
		if not context.max_attachment_size:
			context.max_attachment_size = get_max_file_size() / 1024 / 1024
Example #10
0
def get_value_from_fieldname(field_map, fieldname_field, doc):
	field_name = get_source_value(field_map, fieldname_field)

	if field_name.startswith('eval:'):
		value = frappe.safe_eval(field_name[5:], dict(frappe=frappe))
	elif field_name[0] in ('"', "'"):
		value = field_name[1:-1]
	else:
		value = get_source_value(doc, field_name)
	return value
Example #11
0
	def eval_tax_slab_condition(self, condition, data):
		try:
			condition = condition.strip()
			if condition:
				return frappe.safe_eval(condition, self.whitelisted_globals, data)
		except NameError as err:
			frappe.throw(_("Name error: {0}".format(err)))
		except SyntaxError as err:
			frappe.throw(_("Syntax error in condition: {0}".format(err)))
		except Exception as e:
			frappe.throw(_("Error in formula or condition: {0}".format(e)))
			raise
Example #12
0
	def eval_condition_and_formula(self, d, data):
		try:
			if d.condition:
				if not frappe.safe_eval(d.condition, None, data):
					return None
			amount = d.amount
			if d.amount_based_on_formula:
				if d.formula:
					amount = frappe.safe_eval(d.formula, None, data)
			if amount:
				data[d.abbr] = amount

			return amount

		except NameError as err:
			frappe.throw(_("Name error: {0}".format(err)))
		except SyntaxError as err:
			frappe.throw(_("Syntax error in formula or condition: {0}".format(err)))
		except Exception, e:
			frappe.throw(_("Error in formula or condition: {0}".format(e)))
			raise
Example #13
0
def get_feedback_request_details(reference_doctype, reference_name, trigger="Manual", request=None):
	if not frappe.db.get_value(reference_doctype, reference_name):
		# reference document is either deleted or renamed
		return
	elif not trigger and not request and not frappe.db.get_value("Feedback Trigger", { "document_type": reference_doctype }):
		return
	elif not trigger and request:
		trigger = frappe.db.get_value("Feedback Request", request, "feedback_trigger")
	else:
		trigger = frappe.db.get_value("Feedback Trigger", { "document_type": reference_doctype })

	if not trigger:
		return

	feedback_trigger = frappe.get_doc("Feedback Trigger", trigger)

	doc = frappe.get_doc(reference_doctype, reference_name)
	context = get_context(doc)

	recipients = doc.get(feedback_trigger.email_fieldname, None)
	if feedback_trigger.check_communication:
		communications = frappe.get_all("Communication", filters={
			"reference_doctype": reference_doctype,
			"reference_name": reference_name,
			"communication_type": "Communication",
			"sent_or_received": "Sent"
		}, fields=["name"])

		if len(communications) < 1:
			frappe.msgprint(_("At least one reply is mandatory before requesting feedback"))
			return None

	if recipients and (not feedback_trigger.condition or \
		frappe.safe_eval(feedback_trigger.condition, None, context)):
		subject = feedback_trigger.subject
		context.update({ "feedback_trigger": feedback_trigger })

		if "{" in subject:
			subject = frappe.render_template(feedback_trigger.subject, context)

		feedback_request_message = frappe.render_template(feedback_trigger.message, context)

		return {
			"subject": subject,
			"recipients": recipients,
			"reference_name":doc.name,
			"reference_doctype":doc.doctype,
			"message": feedback_request_message,
		}
	else:
		frappe.msgprint(_("Feedback conditions do not match"))
		return None
Example #14
0
	def eval_condition_and_formula(self, d, data):
		try:
			condition = d.condition.strip() if d.condition else None
			if condition:
				if not frappe.safe_eval(condition, self.whitelisted_globals, data):
					return None
			amount = d.amount
			if d.amount_based_on_formula:
				formula = d.formula.strip() if d.formula else None
				if formula:
					amount = frappe.safe_eval(formula, self.whitelisted_globals, data)
			if amount:
				data[d.abbr] = amount

			return amount

		except NameError as err:
			frappe.throw(_("Name error: {0}".format(err)))
		except SyntaxError as err:
			frappe.throw(_("Syntax error in formula or condition: {0}".format(err)))
		except Exception as e:
			frappe.throw(_("Error in formula or condition: {0}".format(e)))
			raise
Example #15
0
	def test_fifo(self):
		frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
		item_code = "_Test Item 2"
		warehouse = "_Test Warehouse - _TC"

		create_stock_reconciliation(item_code="_Test Item 2", warehouse="_Test Warehouse - _TC",
			qty=0, rate=100)

		make_stock_entry(item_code=item_code, target=warehouse, qty=1, basic_rate=10)
		sle = get_sle(item_code = item_code, warehouse = warehouse)[0]

		self.assertEqual([[1, 10]], frappe.safe_eval(sle.stock_queue))

		# negative qty
		make_stock_entry(item_code=item_code, source=warehouse, qty=2, basic_rate=10)
		sle = get_sle(item_code = item_code, warehouse = warehouse)[0]

		self.assertEqual([[-1, 10]], frappe.safe_eval(sle.stock_queue))

		# further negative
		make_stock_entry(item_code=item_code, source=warehouse, qty=1)
		sle = get_sle(item_code = item_code, warehouse = warehouse)[0]

		self.assertEqual([[-2, 10]], frappe.safe_eval(sle.stock_queue))

		# move stock to positive
		make_stock_entry(item_code=item_code, target=warehouse, qty=3, basic_rate=20)
		sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
		self.assertEqual([[1, 20]], frappe.safe_eval(sle.stock_queue))

		# incoming entry with diff rate
		make_stock_entry(item_code=item_code, target=warehouse, qty=1, basic_rate=30)
		sle = get_sle(item_code = item_code, warehouse = warehouse)[0]

		self.assertEqual([[1, 20],[1, 30]], frappe.safe_eval(sle.stock_queue))

		frappe.db.set_default("allow_negative_stock", 0)
Example #16
0
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 calculate_weighted_score(self, weighing_function):
		my_eval_statement = weighing_function.replace("\r", "").replace("\n", "")

		for var in self.variables:
			if var.value:
				if var.param_name in my_eval_statement:
					my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', "{:.2f}".format(var.value))
			else:
				if var.param_name in my_eval_statement:
					my_eval_statement = my_eval_statement.replace('{' + var.param_name + '}', '0.0')

		my_eval_statement = my_eval_statement.replace('&lt;','<').replace('&gt;','>')

		try:
			weighed_score = frappe.safe_eval(my_eval_statement,  None, {'max':max, 'min': min})
		except Exception:
			frappe.throw(_("Could not solve weighted score function. Make sure the formula is valid."),frappe.ValidationError)
			weighed_score = 0
		return weighed_score
Example #18
0
def validate_loyalty(doc):
    def get_dict(obj):
        if isinstance(obj, frappe.model.document.Document):
            return obj.as_dict()
        if isinstance(obj, string_types):
            return json.loads(obj)
        if isinstance(obj, dict):
            return obj
        return {}

    code = frappe.db.get_single_value("Optical Store Settings", "loyalty_validation")
    locals = frappe._dict(pick(["loyalty_points"], get_dict(doc)))
    if code and not frappe.safe_eval(code, eval_locals=locals):
        frappe.throw(
            _(
                "Loyalty validation failed."
                "Please correct loyalty fields or contact System Manager."
            )
        )
Example #19
0
	def eval_tax_slab_condition(self, condition, data):
		whitelisted_globals = {
			"int": int,
			"float": float,
			"long": int,
			"round": round,
			"date": datetime.date
		}
		try:
			condition = condition.strip()
			if condition:
				return frappe.safe_eval(condition, whitelisted_globals, data)
		except NameError as err:
			frappe.throw(_("Name error: {0}".format(err)))
		except SyntaxError as err:
			frappe.throw(_("Syntax error in condition: {0}".format(err)))
		except Exception as e:
			frappe.throw(_("Error in formula or condition: {0}".format(e)))
			raise
Example #20
0
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 Exception as e:
                if frappe.db.is_missing_column(e):
                    alert.db_set('enabled', 0)
                    frappe.log_error(
                        'Notification {0} has been disabled due to missing field'
                        .format(alert.name))
                    return
                else:
                    raise
            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"))
Example #21
0
	def set_status_based_on_acceptance_formula(self, reading):
		if not reading.acceptance_formula:
			frappe.throw(_("Row #{0}: Acceptance Criteria Formula is required.").format(reading.idx),
				title=_("Missing Formula"))

		condition = reading.acceptance_formula
		data = self.get_formula_evaluation_data(reading)

		try:
			result = frappe.safe_eval(condition, None, data)
			reading.status = "Accepted" if result else "Rejected"
		except NameError as e:
			field = frappe.bold(e.args[0].split()[1])
			frappe.throw(_("Row #{0}: {1} is not a valid reading field. Please refer to the field description.")
				.format(reading.idx, field),
				title=_("Invalid Formula"))
		except Exception:
			frappe.throw(_("Row #{0}: Acceptance Criteria Formula is incorrect.").format(reading.idx),
				title=_("Invalid Formula"))
Example #22
0
def evaluate_alert(doc, alert, event):
    from jinja2 import TemplateError
    try:
        if isinstance(alert, basestring):
            alert = frappe.get_doc("Email Alert", 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 frappe.DatabaseOperationalError as e:
                if e.args[0] == 1054:
                    alert.db_set('enabled', 0)
                    frappe.log_error(
                        'Email Alert {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 Email Alert {0}. Please fix your template."
              ).format(alert))
    except Exception, e:
        frappe.log_error(message=frappe.get_traceback(), title=e)
        frappe.throw("Error in Email Alert")
Example #23
0
 def eval_tax_slab_condition(self, condition, data):
     whitelisted_globals = {
         "int": int,
         "float": float,
         "long": int,
         "round": round,
         "date": datetime.date
     }
     try:
         condition = condition.strip()
         if condition:
             return frappe.safe_eval(condition, whitelisted_globals, data)
     except NameError as err:
         frappe.throw(_("Name error: {0}".format(err)))
     except SyntaxError as err:
         frappe.throw(_("Syntax error in condition: {0}".format(err)))
     except Exception as e:
         frappe.throw(_("Error in formula or condition: {0}".format(e)))
         raise
Example #24
0
 def get_mapped_dependency(self, mapping, producer_site, doc):
     inner_mapping = frappe.get_doc('Document Type Mapping',
                                    mapping.mapping)
     filters = json.loads(mapping.remote_value_filters)
     for key, value in iteritems(filters):
         if value.startswith('eval:'):
             val = frappe.safe_eval(value[5:], dict(frappe=frappe))
             filters[key] = val
         if doc.get(value):
             filters[key] = doc.get(value)
     matching_docs = producer_site.get_doc(inner_mapping.remote_doctype,
                                           filters=filters)
     if len(matching_docs):
         remote_docname = matching_docs[0].get('name')
         remote_doc = producer_site.get_doc(inner_mapping.remote_doctype,
                                            remote_docname)
         doc = inner_mapping.get_mapping(remote_doc, producer_site,
                                         'Insert').get('doc')
         return doc
     return
Example #25
0
	def get_receiver_list(self, doc, context):
		''' return receiver list based on the doc field and role specified '''
		receiver_list = []
		for recipient in self.recipients:
			if recipient.condition:
				if not frappe.safe_eval(recipient.condition, None, context):
					continue

			# For sending messages to the owner's mobile phone number
			if recipient.receiver_by_document_field == 'owner':
				receiver_list += get_user_info([dict(user_name=doc.get('owner'))], 'mobile_no')
			# For sending messages to the number specified in the receiver field
			elif recipient.receiver_by_document_field:
				receiver_list.append(doc.get(recipient.receiver_by_document_field))

			#For sending messages to specified role
			if recipient.receiver_by_role:
				receiver_list += get_info_based_on_role(recipient.receiver_by_role, 'mobile_no')

		return receiver_list
Example #26
0
	def get_documents_for_today(self):
		'''get list of documents that will be triggered today'''
		docs = []

		diff_days = self.days_in_advance
		if self.event=="Days After":
			diff_days = -diff_days

		for name in frappe.db.sql_list("""select name from `tab{0}` where
			DATE(`{1}`) = ADDDATE(DATE(%s), INTERVAL %s DAY)""".format(self.document_type,
				self.date_changed), (nowdate(), diff_days or 0)):

			doc = frappe.get_doc(self.document_type, name)

			if self.condition and not frappe.safe_eval(self.condition, None, get_context(doc)):
				continue

			docs.append(doc)

		return docs
Example #27
0
	def get_documents_for_today(self):
		'''get list of documents that will be triggered today'''
		docs = []

		diff_days = self.days_in_advance
		if self.event=="Days After":
			diff_days = -diff_days

		for name in frappe.db.sql_list("""select name from `tab{0}` where
			DATE(`{1}`) = ADDDATE(DATE(%s), INTERVAL %s DAY)""".format(self.document_type,
				self.date_changed), (nowdate(), diff_days or 0)):

			doc = frappe.get_doc(self.document_type, name)

			if self.condition and not frappe.safe_eval(self.condition, None, get_context(doc)):
				continue

			docs.append(doc)

		return docs
Example #28
0
def has_consumer_access(consumer, update_log):
  """Checks if consumer has completely satisfied all the conditions on the doc"""

  if isinstance(consumer, str):
    consumer = frappe.get_doc('Event Consumer', consumer)

  if not frappe.db.exists(update_log.ref_doctype, update_log.docname):
    # Delete Log
    # Check if the last Update Log of this document was read by this consumer
    last_update_log = frappe.get_all(
        'Event Update Log',
        filters={
            'ref_doctype': update_log.ref_doctype,
            'docname': update_log.docname,
            'creation': ['<', update_log.creation]
        },
        order_by="creation desc",
        limit_page_length=1
    )
    if not len(last_update_log):
      return False

    last_update_log = frappe.get_doc(
        "Event Update Log", last_update_log[0].name)
    return len([x for x in last_update_log.consumers if x.consumer == consumer.name])

  doc = frappe.get_doc(update_log.ref_doctype, update_log.docname)
  for dt_entry in consumer.consumer_doctypes:
    if dt_entry.ref_doctype != update_log.ref_doctype:
      continue

    if not dt_entry.condition:
      return True

    condition: str = dt_entry.condition
    if condition.startswith("cmd:"):
      return frappe.call(frappe.get_attr(condition.split("cmd:")[1].strip()), consumer=consumer, update_log=update_log)
    else:
      return frappe.safe_eval(condition.eval, frappe._dict(doc=doc))

  return False
Example #29
0
    def calculate_criteria(self):
        #Get the criteria
        for crit in self.criteria:

            #me = ""
            my_eval_statement = crit.formula.replace("\r",
                                                     "").replace("\n", "")
            #for let in my_eval_statement:
            #	me += let.encode('hex') + " "
            #frappe.msgprint(me)

            for var in self.variables:
                if var.value:
                    if var.param_name in my_eval_statement:
                        my_eval_statement = my_eval_statement.replace(
                            '{' + var.param_name + '}',
                            "{:.2f}".format(var.value))
                else:
                    if var.param_name in my_eval_statement:
                        my_eval_statement = my_eval_statement.replace(
                            '{' + var.param_name + '}', '0.0')

            #frappe.msgprint(my_eval_statement )

            my_eval_statement = my_eval_statement.replace('&lt;', '<').replace(
                '&gt;', '>')

            try:
                crit.score = min(
                    crit.max_score,
                    max(
                        0,
                        frappe.safe_eval(my_eval_statement, None, {
                            'max': max,
                            'min': min
                        })))
            except Exception:
                frappe.throw(
                    _("Could not solve criteria score function for {0}. Make sure the formula is valid."
                      .format(crit.criteria_name)), frappe.ValidationError)
                crit.score = 0
Example #30
0
    def set_status(self, update=False, status=None, update_modified=True):
        if self.is_new():
            if self.get('amended_from'):
                self.status = 'Draft'
            return

        if self.doctype in status_map:
            _status = self.status

            if status and update:
                self.db_set("status", status)

            sl = status_map[self.doctype][:]
            sl.reverse()
            for s in sl:
                if not s[1]:
                    self.status = s[0]
                    break
                elif s[1].startswith("eval:"):
                    if frappe.safe_eval(
                            s[1][5:], None, {
                                "self": self.as_dict(),
                                "getdate": getdate,
                                "nowdate": nowdate,
                                "get_value": frappe.db.get_value
                            }):
                        self.status = s[0]
                        break
                elif getattr(self, s[1])():
                    self.status = s[0]
                    break

            if self.status != _status and self.status not in (
                    "Cancelled", "Partially Ordered", "Ordered", "Issued",
                    "Transferred"):
                self.add_comment("Label", _(self.status))

            if update:
                self.db_set('status',
                            self.status,
                            update_modified=update_modified)
Example #31
0
	def set_status_based_on_acceptance_formula(self):
		for reading in self.readings:
			if not reading.acceptance_formula: continue

			condition = reading.acceptance_formula
			data = {}
			for i in range(1, 11):
				field = "reading_" + str(i)
				data[field] = flt(reading.get(field)) or 0

			try:
				result = frappe.safe_eval(condition, None, data)
				reading.status = "Accepted" if result else "Rejected"
			except SyntaxError:
				frappe.throw(_("Row #{0}: Acceptance Criteria Formula is incorrect.").format(reading.idx),
					title=_("Invalid Formula"))
			except NameError as e:
				field = frappe.bold(e.args[0].split()[1])
				frappe.throw(_("Row #{0}: {1} is not a valid reading field. Please refer to the field description.")
					.format(reading.idx, field),
					title=_("Invalid Formula"))
Example #32
0
    def get_list_of_recipients(self, doc, context):
        recipients = []
        cc = []
        bcc = []
        for recipient in self.recipients:
            if recipient.condition:
                if not frappe.safe_eval(recipient.condition, None, context):
                    continue
            if recipient.email_by_document_field:
                email_ids_value = doc.get(recipient.email_by_document_field)
                if validate_email_add(email_ids_value):
                    email_ids = email_ids_value.replace(",", "\n")
                    recipients = recipients + email_ids.split("\n")

                # else:
                # 	print "invalid email"
            if recipient.cc and "{" in recipient.cc:
                recipient.cc = frappe.render_template(recipient.cc, context)

            if recipient.cc:
                recipient.cc = recipient.cc.replace(",", "\n")
                cc = cc + recipient.cc.split("\n")

            if recipient.bcc and "{" in recipient.bcc:
                recipient.bcc = frappe.render_template(recipient.bcc, context)

            if recipient.bcc:
                recipient.bcc = recipient.bcc.replace(",", "\n")
                bcc = bcc + recipient.bcc.split("\n")

            #For sending emails to specified role
            if recipient.email_by_role:
                emails = get_emails_from_role(recipient.email_by_role)

                for email in emails:
                    recipients = recipients + email.split("\n")

        if not recipients and not cc and not bcc:
            return None, None, None
        return list(set(recipients)), list(set(cc)), list(set(bcc))
Example #33
0
	def get_list_of_recipients(self, doc, context):
		recipients = []
		cc = []
		bcc = []
		for recipient in self.recipients:
			if recipient.condition:
				if not frappe.safe_eval(recipient.condition, None, context):
					continue
			if recipient.email_by_document_field:
				email_ids_value = doc.get(recipient.email_by_document_field)
				if validate_email_add(email_ids_value):
					email_ids = email_ids_value.replace(",", "\n")
					recipients = recipients + email_ids.split("\n")

				# else:
				# 	print "invalid email"
			if recipient.cc and "{" in recipient.cc:
				recipient.cc = frappe.render_template(recipient.cc, context)

			if recipient.cc:
				recipient.cc = recipient.cc.replace(",", "\n")
				cc = cc + recipient.cc.split("\n")

			if recipient.bcc and "{" in recipient.bcc:
				recipient.bcc = frappe.render_template(recipient.bcc, context)

			if recipient.bcc:
				recipient.bcc = recipient.bcc.replace(",", "\n")
				bcc = bcc + recipient.bcc.split("\n")

			#For sending emails to specified role
			if recipient.email_by_role:
				emails = get_emails_from_role(recipient.email_by_role)

				for email in emails:
					recipients = recipients + email.split("\n")

		if not recipients and not cc and not bcc:
			return None, None, None
		return list(set(recipients)), list(set(cc)), list(set(bcc))
Example #34
0
def is_downgrade(sql_file_path, verbose=False):
    """checks if input db backup will get downgraded on current bench"""
    from semantic_version import Version
    head = "INSERT INTO `tabInstalled Application` VALUES"

    with open(sql_file_path) as f:
        for line in f:
            if head in line:
                # 'line' (str) format: ('2056588823','2020-05-11 18:21:31.488367','2020-06-12 11:49:31.079506','Administrator','Administrator',0,'Installed Applications','installed_applications','Installed Applications',1,'frappe','v10.1.71-74 (3c50d5e) (v10.x.x)','v10.x.x'),('855c640b8e','2020-05-11 18:21:31.488367','2020-06-12 11:49:31.079506','Administrator','Administrator',0,'Installed Applications','installed_applications','Installed Applications',2,'your_custom_app','0.0.1','master')
                line = line.strip().lstrip(head).rstrip(";").strip()
                app_rows = frappe.safe_eval(line)
                # check if iterable consists of tuples before trying to transform
                apps_list = app_rows if all(
                    isinstance(app_row, (tuple, list, set))
                    for app_row in app_rows) else (app_rows, )
                # 'all_apps' (list) format: [('frappe', '12.x.x-develop ()', 'develop'), ('your_custom_app', '0.0.1', 'master')]
                all_apps = [x[-3:] for x in apps_list]

                for app in all_apps:
                    app_name = app[0]
                    app_version = app[1].split(" ")[0]

                    if app_name == "frappe":
                        try:
                            current_version = Version(frappe.__version__)
                            backup_version = Version(
                                app_version[1:] if app_version[0] ==
                                "v" else app_version)
                        except ValueError:
                            return False

                        downgrade = backup_version > current_version

                        if verbose and downgrade:
                            print(
                                "Your site will be downgraded from Frappe {0} to {1}"
                                .format(current_version, backup_version))

                        return downgrade
Example #35
0
def get_transitions(doc, workflow=None):
    '''Return list of possible transitions for the given doc'''

    if doc.is_new():
        return []

    frappe.has_permission(doc=doc, ptype='read', throw=True)
    roles = frappe.get_roles()

    if not workflow:
        workflow = get_workflow(doc.doctype)
    current_state = doc.get(workflow.workflow_state_field)

    if not current_state:
        frappe.throw(_('Workflow State not set'), WorkflowStateError)

    transitions = []
    for transition in workflow.transitions:
        if transition.state == current_state and transition.allowed in roles:
            if transition.get('condition'):
                # if condition, evaluate
                # access to frappe.db.get_value and frappe.db.get_list
                success = frappe.safe_eval(
                    transition.condition,
                    dict(frappe=frappe._dict(
                        db=frappe._dict(
                            get_value=frappe.db.get_value,
                            get_list=frappe.db.get_list,
                        ),
                        session=frappe.session,
                    )),
                    dict(doc=doc),
                )
                if not success:
                    continue
            transitions.append(transition.as_dict())

    return transitions
Example #36
0
def get_users_next_action_data(transitions, doc):
    user_data_map = {}
    for transition in transitions:
        # if self_approval is checked it shouldn't make workflow action and email!
        if transition.get('allow_self_approval'):
            continue

        else:
            satisfies_condition = True
            if transition.condition:
                satisfies_condition = frappe.safe_eval(
                    transition.condition,
                    dict(frappe=frappe._dict(db=frappe._dict(
                        get_value=frappe.db.get_value,
                        get_list=frappe.db.get_list),
                                             session=frappe.session)),
                    dict(doc=doc))
            # allowed users should also satisfy the transition condition
            if satisfies_condition:
                users = get_users_with_role(transition.allowed)
                filtered_users = filter_allowed_users(users, doc, transition)
                for user in filtered_users:
                    if not user_data_map.get(user):
                        user_data_map[user] = {
                            'possible_actions': [],
                            'email':
                            frappe.db.get_value('User', user, 'email'),
                        }

                    user_data_map[user].get('possible_actions').append({
                        'action_name':
                        transition.get('action'),
                        'action_link':
                        get_workflow_action_url(transition.get('action'), doc,
                                                user)
                    })
        print(user_data_map)
    return user_data_map
Example #37
0
def evaluate_alert(doc, alert, event):
	from jinja2 import TemplateError
	try:
		if isinstance(alert, string_types):
			alert = frappe.get_doc("Email Alert", 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('Email Alert {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 Email Alert {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 Email Alert"))
Example #38
0
def get_next_possible_transitions(workflow_name, state, doc=None):
    transitions = frappe.get_all('Workflow Transition',
                                 fields=[
                                     'allowed', 'action', 'state',
                                     'allow_self_approval', 'next_state',
                                     '`condition`'
                                 ],
                                 filters=[['parent', '=', workflow_name],
                                          ['state', '=', state]])

    transitions_to_return = []

    for transition in transitions:
        is_next_state_optional = get_state_optional_field_value(
            workflow_name, transition.next_state)
        # skip transition if next state of the transition is optional
        if transition.condition and not frappe.safe_eval(
                transition.condition, None, {'doc': doc.as_dict()}):
            continue
        if is_next_state_optional:
            continue
        transitions_to_return.append(transition)

    return transitions_to_return
Example #39
0
    def send(self, doc):
        '''Build recipients and send email alert'''
        def get_attachment(doc):
            """ check print settings are attach the pdf """
            if not self.attach_print:
                return None

            print_settings = frappe.get_doc("Print Settings", "Print Settings")
            if (doc.docstatus == 0 and not print_settings.allow_print_for_draft) or \
             (doc.docstatus == 2 and not print_settings.allow_print_for_cancelled):

                # ignoring attachment as draft and cancelled documents are not allowed to print
                status = "Draft" if doc.docstatus == 0 else "Cancelled"
                frappe.throw(_("""Not allowed to attach {0} document,
					please enable Allow Print For {0} in Print Settings""".format(status)),
                             title=_("Error in Email Alert"))
            else:
                return [frappe.attach_print(doc.doctype, doc.name)]

        context = get_context(doc)
        recipients = []

        for recipient in self.recipients:
            if recipient.condition:
                if not frappe.safe_eval(recipient.condition, None, context):
                    continue
            if recipient.email_by_document_field:
                if validate_email_add(
                        doc.get(recipient.email_by_document_field)):
                    recipient.email_by_document_field = doc.get(
                        recipient.email_by_document_field).replace(",", "\n")
                    recipients = recipients + recipient.email_by_document_field.split(
                        "\n")

                # else:
                # 	print "invalid email"
            if recipient.cc:
                recipient.cc = recipient.cc.replace(",", "\n")
                recipients = recipients + recipient.cc.split("\n")

            #For sending emails to specified role
            if recipient.email_by_role:
                emails = get_emails_from_role(recipient.email_by_role)

                for email in emails:
                    recipients = recipients + email.split("\n")

        if not recipients:
            return

        recipients = list(set(recipients))
        subject = self.subject

        context = {"doc": doc, "alert": self, "comments": None}

        if self.is_standard:
            self.load_standard_properties(context)

        if doc.get("_comments"):
            context["comments"] = json.loads(doc.get("_comments"))

        if "{" in subject:
            subject = frappe.render_template(self.subject, context)

        attachments = get_attachment(doc)

        frappe.sendmail(recipients=recipients,
                        subject=subject,
                        message=frappe.render_template(self.message, context),
                        reference_doctype=doc.doctype,
                        reference_name=doc.name,
                        attachments=attachments)
Example #40
0
	def set_accounting_cards(self, context):
		"""Create accounting cards if checked"""

		cache = frappe.cache()
		context.cards = []
		for key in (
			"income",
			"expenses_booked",
			"income_year_to_date",
			"expense_year_to_date",
			"bank_balance",
			"credit_balance",
			"invoiced_amount",
			"payables",
			"sales_orders_to_bill",
			"purchase_orders_to_bill",
			"sales_order",
			"purchase_order",
			"sales_orders_to_deliver",
			"purchase_orders_to_receive",
			"sales_invoice",
			"purchase_invoice",
			"new_quotations",
			"pending_quotations",
		):

			if self.get(key):
				cache_key = "email_digest:card:{0}:{1}:{2}:{3}".format(
					self.company, self.frequency, key, self.from_date
				)
				card = cache.get(cache_key)

				if card:
					card = frappe.safe_eval(card)

				else:
					card = frappe._dict(getattr(self, "get_" + key)())

					# format values
					if card.last_value:
						card.diff = int(flt(card.value - card.last_value) / card.last_value * 100)
						if card.diff < 0:
							card.diff = str(card.diff)
							card.gain = False
						else:
							card.diff = "+" + str(card.diff)
							card.gain = True

						if key == "credit_balance":
							card.last_value = card.last_value * -1
						card.last_value = self.fmt_money(
							card.last_value, False if key in ("bank_balance", "credit_balance") else True
						)

					if card.billed_value:
						card.billed = int(flt(card.billed_value) / card.value * 100)
						card.billed = "% Billed " + str(card.billed)

					if card.delivered_value:
						card.delivered = int(flt(card.delivered_value) / card.value * 100)
						if key == "pending_sales_orders":
							card.delivered = "% Delivered " + str(card.delivered)
						else:
							card.delivered = "% Received " + str(card.delivered)

					if key == "credit_balance":
						card.value = card.value * -1
					card.value = self.fmt_money(
						card.value, False if key in ("bank_balance", "credit_balance") else True
					)

					cache.set_value(cache_key, card, expires_in_sec=24 * 60 * 60)

				context.cards.append(card)
Example #41
0
 def get_filters(self):
     if self.condition:
         return frappe.safe_eval(self.condition, dict(frappe=frappe))
Example #42
0
def valida_sub_ferias(doc, dias_pagamento, total_dias_trabalho):

    emp = frappe.get_doc("Employee", doc.employee)
    for d in doc.earnings:
        #print d.salary_component
        print frappe.db.get_value("Salary Component", d.salary_component,
                                  "salary_component_abbr")
        print 'Formula ', d.formula
        qry_cmpnt = frappe.db.sql(
            """ select sd.formula from `tabSalary Structure Employee` as se 
		join `tabSalary Detail` as sd on sd.parent = se.parent where se.employee = %s and sd.abbr = %s """,
            (emp.name, d.abbr),
            as_dict=True)
        qry_result = ''

        if (qry_cmpnt):
            if qry_cmpnt[0].formula != '':
                print '1 ', qry_cmpnt[0].formula
                qry_result = qry_cmpnt[0].formula

        if frappe.db.get_value("Salary Component", d.salary_component,
                               "salary_component_abbr") == "SB":
            #Salary Base
            salariobase = d.amount
        if (d.salary_component == "Subsidio de Ferias") or (d.abbr == "SF"):

            print emp.date_of_joining
            print datetime.date(datetime.datetime.today().year, 12,
                                31) - emp.date_of_joining
            print(
                datetime.date(datetime.datetime.today().year, 12, 31) -
                emp.date_of_joining).days
            print "anos ", divmod(
                (datetime.date(datetime.datetime.today().year, 12, 31) -
                 emp.date_of_joining).days, 365)
            anos, meses = divmod(
                (datetime.date(datetime.datetime.today().year, 12, 31) -
                 emp.date_of_joining).days, 365)
            print anos
            print meses
            if anos > 0:
                print "Tem mais que 1 ano"
                pass
            elif meses / 30 < 12:
                print "Menos que 12 meses!!!!"
                print "rever a formula !!!", d.amount
                print date_diff(frappe.utils.nowdate(), emp.date_of_joining)

                salariohora = ((salariobase * 12) / (52 * 40)
                               )  # em vez de 40horas devem ser 44horas
                print "Salario Hora ", salariohora

                meses1 = date_diff(frappe.utils.nowdate(),
                                   emp.date_of_joining) / 30
                print "Meses ", meses1

                diasTrab = meses1 * 2
                print "dias Trab ", diasTrab

                salariodia = salariohora * 8
                print "salario Dia ", salariodia

                subferias = (salariodia * diasTrab) * 0.50
                print "salario Ferias ", subferias

                d.amount = subferias

        print 'SALARY SLIpppppppppppppppppppp'
        print qry_result

        if qry_result != None:
            print 'payment_days' in qry_result
            if (qry_result.find('payment_days') != -1
                    and dias_pagamento != total_dias_trabalho):
                #found
                print total_dias_trabalho
                print dias_pagamento
                print 'strip ', qry_result.strip()
                ff = qry_result.replace('payment_days', str(dias_pagamento))
                print qry_result.replace('payment_days', str(dias_pagamento))
                qry_result = ff
                if (qry_result.find('total_working_days') != -1):
                    ff = qry_result.replace('total_working_days',
                                            str(total_dias_trabalho))
                    qry_result = ff
                print frappe.safe_eval(qry_result, None, None)

                d.amount = frappe.safe_eval(qry_result, None,
                                            None)  #eval(qry_result)

            if (qry_result.find('total_working_days') != -1
                    and dias_pagamento != total_dias_trabalho):
                ff = qry_result.replace('total_working_days',
                                        str(total_dias_trabalho))
                qry_result = ff
                d.amount = frappe.safe_eval(qry_result, None, None)

                #print frappe.safe_eval(ff,None,None)

        qry_result = ''
def get_active_service_level_agreement_for(doc):
    if not frappe.db.get_single_value("Support Settings",
                                      "track_service_level_agreement"):
        return

    filters = [
        ["Service Level Agreement", "active", "=", 1],
        ["Service Level Agreement", "enable", "=", 1],
    ]

    if doc.get("priority"):
        filters.append(
            ["Service Level Priority", "priority", "=",
             doc.get("priority")])

    customer = doc.get("customer")
    or_filters = [[
        "Service Level Agreement",
        "entity",
        "in",
        [
            customer,
            get_customer_group(customer),
            get_customer_territory(customer)
        ],
    ]]

    service_level_agreement = doc.get("service_level_agreement")
    if service_level_agreement:
        or_filters = [
            [
                "Service Level Agreement", "name", "=",
                doc.get("service_level_agreement")
            ],
        ]

    default_sla_filter = filters + [[
        "Service Level Agreement", "default_service_level_agreement", "=", 1
    ]]
    default_sla = frappe.get_all(
        "Service Level Agreement",
        filters=default_sla_filter,
        fields=["name", "default_priority", "condition"],
    )

    filters += [[
        "Service Level Agreement", "default_service_level_agreement", "=", 0
    ]]
    agreements = frappe.get_all(
        "Service Level Agreement",
        filters=filters,
        or_filters=or_filters,
        fields=["name", "default_priority", "condition"],
    )

    # check if the current document on which SLA is to be applied fulfills all the conditions
    filtered_agreements = []
    for agreement in agreements:
        condition = agreement.get("condition")
        if not condition or (condition and frappe.safe_eval(
                condition, None, get_context(doc))):
            filtered_agreements.append(agreement)

    # if any default sla
    filtered_agreements += default_sla

    return filtered_agreements[0] if filtered_agreements else None
Example #44
0
 def eval_condition(self, doc):
     return self.condition and frappe.safe_eval(self.condition, None,
                                                {"doc": doc.as_dict()})
Example #45
0
	def get_filters(self):
		if self.condition:
			return frappe.safe_eval(self.condition, get_safe_globals())
Example #46
0
def run_webhooks(doc, method):
    """Run webhooks for this method"""
    if (frappe.flags.in_import or frappe.flags.in_patch
            or frappe.flags.in_install or frappe.flags.in_migrate):
        return

    if frappe.flags.webhooks_executed is None:
        frappe.flags.webhooks_executed = {}

    if frappe.flags.webhooks is None:
        # load webhooks from cache
        webhooks = frappe.cache().get_value("webhooks")
        if webhooks is None:
            # query webhooks
            webhooks_list = frappe.get_all(
                "Webhook",
                fields=[
                    "name", "`condition`", "webhook_docevent",
                    "webhook_doctype"
                ],
                filters={"enabled": True},
            )

            # make webhooks map for cache
            webhooks = {}
            for w in webhooks_list:
                webhooks.setdefault(w.webhook_doctype, []).append(w)
            frappe.cache().set_value("webhooks", webhooks)

        frappe.flags.webhooks = webhooks

    # get webhooks for this doctype
    webhooks_for_doc = frappe.flags.webhooks.get(doc.doctype, None)

    if not webhooks_for_doc:
        # no webhooks, quit
        return

    def _webhook_request(webhook):
        if webhook.name not in frappe.flags.webhooks_executed.get(
                doc.name, []):
            frappe.enqueue(
                "frappe.integrations.doctype.webhook.webhook.enqueue_webhook",
                enqueue_after_commit=True,
                doc=doc,
                webhook=webhook,
            )

            # keep list of webhooks executed for this doc in this request
            # so that we don't run the same webhook for the same document multiple times
            # in one request
            frappe.flags.webhooks_executed.setdefault(doc.name,
                                                      []).append(webhook.name)

    event_list = [
        "on_update", "after_insert", "on_submit", "on_cancel", "on_trash"
    ]

    if not doc.flags.in_insert:
        # value change is not applicable in insert
        event_list.append("on_change")
        event_list.append("before_update_after_submit")

    from frappe.integrations.doctype.webhook.webhook import get_context

    for webhook in webhooks_for_doc:
        trigger_webhook = False
        event = method if method in event_list else None
        if not webhook.condition:
            trigger_webhook = True
        elif frappe.safe_eval(webhook.condition, eval_locals=get_context(doc)):
            trigger_webhook = True

        if trigger_webhook and event and webhook.webhook_docevent == event:
            _webhook_request(webhook)
Example #47
0
    def get_employee_financial_data(self):
        self.base = 0.0
        self.maximum_loan_amount_cut = 0.0
        self.total_deserved_amount = 0.0
        self.salary_component_dict = {}
        self.employee = self.applicant
        if self.employee:
            employee_Dict = frappe.db.get_value(
                "Employee",
                self.employee, [
                    "name", "resignation_letter_date", "designation", "status",
                    "department", "relieving_date"
                ],
                as_dict=1)
            if employee_Dict:
                employeename = employee_Dict.name
                resignation_letter_date = employee_Dict.resignation_letter_date
                designation = employee_Dict.designation
                status = employee_Dict.status
                department = employee_Dict.department
                relieving_date = employee_Dict.relieving_date

            if resignation_letter_date or relieving_date or status == "Left":
                frappe.throw(
                    _("Sorry....this is employee is going to leave or already left"
                      ), "Employee Status")

        Salary_Structure_Dict = frappe.db.sql("""
			SELECT SSE.base,SD.amount_based_on_formula,
				SD.formula,SD.amount,
				SD.`condition`,SD.abbr,SD.salary_component
				FROM	`tabSalary Structure Assignment`  as SSE
					INNER join 	
				`tabSalary Structure` as SS
					on SS.`name` = SSE.salary_structure
					INNER JOIN 
					`tabSalary Detail` as SD
					on SD.parent = SS.`name` 
					and SD.parentfield='earnings'
					and SD.docstatus= '1'
					and SS.is_active='Yes'
					and %s >=  SSE.from_date
					and SSE.employee=%s
					and SS.docstatus='1'
					;
			""", (self.posting_date, self.employee),
                                              as_dict=1,
                                              debug=False)

        if Salary_Structure_Dict:
            for item in Salary_Structure_Dict:
                self.base = item["base"]
                self.salary_component_dict["base"] = item["base"]
                if item["amount_based_on_formula"] == 1:
                    try:
                        condition = item["condition"].strip(
                        ) if item["condition"] else None
                        if condition:
                            if not frappe.safe_eval(
                                    condition, None,
                                    self.salary_component_dict):
                                return None

                        formula = item["formula"].strip(
                        ) if item["formula"] else None
                        if formula:
                            amount = frappe.safe_eval(
                                formula, None, self.salary_component_dict)
                            self.salary_component_dict[item["abbr"]] = amount
                            self.total_deserved_amount += amount

                    except NameError as err:
                        frappe.throw(_("Name error: {0}".format(err)))
                    except SyntaxError as err:
                        frappe.throw(
                            _("Syntax error in formula or condition: {0}".
                              format(err)))
                    except Exception as e:
                        frappe.throw(
                            _("Error in formula or condition: {0}".format(e)))
                        raise
                else:
                    self.total_deserved_amount += float(item["amount"])

        if self.total_deserved_amount > 0:
            if int(
                    frappe.db.get_single_value(
                        "HR Settings", "maximum_loan_amount_cut") or 0):
                self.maximum_loan_amount_cut = float(
                    float(
                        frappe.db.get_single_value(
                            "HR Settings", "maximum_loan_amount_cut")) /
                    100) * self.total_deserved_amount
            else:
                self.maximum_loan_amount_cut = 0.1 * self.total_deserved_amount

        # msgprint(str(self.maximum_loan_amount_cut))
        # msgprint(str(self.total_deserved_amount))
        # frappe.throw("not saved")

        else:
            frappe.throw(
                _("Sorry....this is employee has no salary structure "),
                "Employee Salary Structure ")

        return self.maximum_loan_amount_cut
Example #48
0
	def test_safe_eval(self):
		self.assertEqual(frappe.safe_eval('1+1'), 2)
		self.assertRaises(AttributeError, frappe.safe_eval, 'frappe.utils.os.path', get_safe_globals())
Example #49
0
	def get_filters(self):
		if self.condition:
			return frappe.safe_eval(self.condition, dict(frappe=frappe))
Example #50
0
	def send(self, doc):
		'''Build recipients and send email alert'''
		from email.utils import formataddr

		def get_attachment(doc):
			""" check print settings are attach the pdf """
			if not self.attach_print:
				return None

			print_settings = frappe.get_doc("Print Settings", "Print Settings")
			if (doc.docstatus == 0 and not print_settings.allow_print_for_draft) or \
				(doc.docstatus == 2 and not print_settings.allow_print_for_cancelled):

				# ignoring attachment as draft and cancelled documents are not allowed to print
				status = "Draft" if doc.docstatus == 0 else "Cancelled"
				frappe.throw(_("""Not allowed to attach {0} document,
					please enable Allow Print For {0} in Print Settings""".format(status)),
					title=_("Error in Email Alert"))
			else:
				return [{"print_format_attachment":1, "doctype":doc.doctype, "name": doc.name,
					"print_format":self.print_format, "print_letterhead": print_settings.with_letterhead}]

		context = get_context(doc)
		recipients = []
		sender = ""

		for recipient in self.recipients:
			if recipient.condition:
				if not frappe.safe_eval(recipient.condition, None, context):
					continue
			if recipient.email_by_document_field:
				email_ids_value = doc.get(recipient.email_by_document_field)
				if validate_email_add(email_ids_value):
					email_ids = email_ids_value.replace(",", "\n")
					recipients = recipients + email_ids.split("\n")

				# else:
				# 	print "invalid email"
			if recipient.cc:
				recipient.cc = recipient.cc.replace(",", "\n")
				recipients = recipients + recipient.cc.split("\n")

			#For sending emails to specified role
			if recipient.email_by_role:
				emails = get_emails_from_role(recipient.email_by_role)

				for email in emails:
					recipients = recipients + email.split("\n")

		if not recipients:
			return

		recipients = list(set(recipients))
		subject = self.subject

		context = {"doc": doc, "alert": self, "comments": None}

		if self.sender:
			sender = formataddr((self.sender, self.sender_email))

		if self.is_standard:
			self.load_standard_properties(context)

		if doc.get("_comments"):
			context["comments"] = json.loads(doc.get("_comments"))

		if "{" in subject:
			subject = frappe.render_template(self.subject, context)

		attachments = get_attachment(doc)

		frappe.sendmail(recipients=recipients, subject=subject,
			message= frappe.render_template(self.message, context),
			sender = sender,
			reference_doctype = doc.doctype,
			reference_name = doc.name,
			attachments = attachments,
			print_letterhead = ((attachments
				and attachments[0].get('print_letterhead')) or False))

		if self.set_property_after_alert:
			frappe.db.set_value(doc.doctype, doc.name, self.set_property_after_alert,
				self.property_value, update_modified = False)
			doc.set(self.set_property_after_alert, self.property_value)
Example #51
0
    def get_context(self, context):
        '''Build context to render the `web_form.html` template'''
        self.set_web_form_module()

        context._login_required = False
        if self.login_required and frappe.session.user == "Guest":
            context._login_required = True

        doc, delimeter = make_route_string(frappe.form_dict)
        context.doc = doc
        context.delimeter = delimeter

        # check permissions
        if frappe.session.user == "Guest" and frappe.form_dict.name:
            frappe.throw(
                _("You need to be logged in to access this {0}.").format(
                    self.doc_type), frappe.PermissionError)

        if frappe.form_dict.name and not has_web_form_permission(
                self.doc_type, frappe.form_dict.name):
            frappe.throw(
                _("You don't have the permissions to access this document"),
                frappe.PermissionError)

        self.reset_field_parent()

        if self.is_standard:
            self.use_meta_fields()

        if not context._login_required:
            if self.allow_edit:
                if self.allow_multiple:
                    if not frappe.form_dict.name and not frappe.form_dict.new:
                        # list data is queried via JS
                        context.is_list = True
                else:
                    if frappe.session.user != 'Guest' and not frappe.form_dict.name:
                        frappe.form_dict.name = frappe.db.get_value(
                            self.doc_type, {"owner": frappe.session.user},
                            "name")

                    if not frappe.form_dict.name:
                        # only a single doc allowed and no existing doc, hence new
                        frappe.form_dict.new = 1

        # always render new form if login is not required or doesn't allow editing existing ones
        if not self.login_required or not self.allow_edit:
            frappe.form_dict.new = 1

        self.load_document(context)
        context.parents = self.get_parents(context)

        if self.breadcrumbs:
            context.parents = frappe.safe_eval(self.breadcrumbs, {"_": _})

        context.has_header = ((frappe.form_dict.name or frappe.form_dict.new)
                              and (frappe.session.user != "Guest"
                                   or not self.login_required))

        if context.success_message:
            context.success_message = frappe.db.escape(
                context.success_message.replace("\n", "<br>")).strip("'")

        self.add_custom_context_and_script(context)
        if not context.max_attachment_size:
            context.max_attachment_size = get_max_file_size() / 1024 / 1024

        context.show_in_grid = self.show_in_grid
        self.load_translations(context)
Example #52
0
    return {"sms_sent": query[0][0] or 0, "sms_balance": sms_balance}


_get_receiver_list = compose(
    list,
    unique,
    validate_receiver_nos,
    lambda x: x.replace(",", "\n").split(),
    frappe.utils.cstr,
)


_eval_dynamic_params = partial(
    valmap,
    lambda x: frappe.safe_eval(
        x, eval_globals=frappe._dict(frappe=frappe._dict(utils=frappe.utils))
    ),
)


def _make_headers(ss, sx):
    get_dynamic_headers = compose(
        _eval_dynamic_params, lambda x: dissoc(x, "Accept"), get_headers
    )
    return merge(get_headers(ss), get_dynamic_headers(sx))


def _make_params(ss, sx):
    get_param_payload = compose(
        lambda params: reduce(
            lambda a, x: merge(a, {x.parameter: x.value}), params, {}