Ejemplo n.º 1
0
	def validate_condition(self):
		temp_doc = dataent.new_doc(self.document_type)
		if self.condition:
			try:
				dataent.safe_eval(self.condition, None, get_context(temp_doc))
			except Exception:
				dataent.throw(_("The Condition '{0}' is invalid").format(self.condition))
Ejemplo n.º 2
0
    def eval_condition_and_formula(self, d, data):
        try:
            condition = d.condition.strip() if d.condition else None
            if condition:
                if not dataent.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 = flt(
                        dataent.safe_eval(formula, self.whitelisted_globals,
                                          data), d.precision("amount"))
            if amount:
                data[d.abbr] = amount

            return amount

        except NameError as err:
            dataent.throw(_("Name error: {0}".format(err)))
        except SyntaxError as err:
            dataent.throw(
                _("Syntax error in formula or condition: {0}".format(err)))
        except Exception as e:
            dataent.throw(_("Error in formula or condition: {0}".format(e)))
            raise
Ejemplo n.º 3
0
    def test_fifo(self):
        dataent.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]], dataent.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]], dataent.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]], dataent.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]], dataent.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]],
                         dataent.safe_eval(sle.stock_queue))

        dataent.db.set_default("allow_negative_stock", 0)
Ejemplo n.º 4
0
 def set_breadcrumbs(self, context):
     """Build breadcrumbs template """
     if self.breadcrumbs:
         context.parents = dataent.safe_eval(self.breadcrumbs, {"_": _})
     if not "no_breadcrumbs" in context:
         if "<!-- no-breadcrumbs -->" in context.main_section:
             context.no_breadcrumbs = 1
Ejemplo n.º 5
0
	def calculate_weighted_score(self, weighing_function):
		try:
			weighed_score = dataent.safe_eval(self.get_eval_statement(weighing_function),  None, {'max':max, 'min': min})
		except Exception:
			dataent.throw(_("Could not solve weighted score function. Make sure the formula is valid."),dataent.ValidationError)
			weighed_score = 0
		return weighed_score
Ejemplo n.º 6
0
	def calculate_criteria(self):
		for crit in self.criteria:
			try:
				crit.score = min(crit.max_score, max( 0 ,dataent.safe_eval(self.get_eval_statement(crit.formula),  None, {'max':max, 'min': min})))
			except Exception:
				dataent.throw(_("Could not solve criteria score function for {0}. Make sure the formula is valid.".format(crit.criteria_name)),dataent.ValidationError)
				crit.score = 0
Ejemplo n.º 7
0
def get_transitions(doc, workflow = None):
	'''Return list of possible transitions for the given doc'''
	doc = dataent.get_doc(dataent.parse_json(doc))

	if doc.is_new():
		return []

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

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

	if not current_state:
		dataent.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 dataent.db.get_value and dataent.db.get_list
				success = dataent.safe_eval(transition.condition,
					dict(dataent = dataent._dict(
						db = dataent._dict(get_value = dataent.db.get_value, get_list=dataent.db.get_list),
						session = dataent.session
					)),
					dict(doc = doc))
				if not success:
					continue
			transitions.append(transition.as_dict())

	return transitions
Ejemplo n.º 8
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 = dataent.safe_eval(field_name[5:], dict(dataent=dataent))
    elif field_name[0] in ('"', "'"):
        value = field_name[1:-1]
    else:
        value = get_source_value(doc, field_name)
    return value
Ejemplo n.º 9
0
 def eval_tax_slab_condition(self, condition, data):
     try:
         condition = condition.strip()
         if condition:
             return dataent.safe_eval(condition, self.whitelisted_globals,
                                      data)
     except NameError as err:
         dataent.throw(_("Name error: {0}".format(err)))
     except SyntaxError as err:
         dataent.throw(_("Syntax error in condition: {0}".format(err)))
     except Exception as e:
         dataent.throw(_("Error in formula or condition: {0}".format(e)))
         raise
Ejemplo n.º 10
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 dataent.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 = dataent.get_doc(self.document_type, name)

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

			docs.append(doc)

		return docs
Ejemplo n.º 11
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 dataent.safe_eval(
                            s[1][5:], None, {
                                "self": self.as_dict(),
                                "getdate": getdate,
                                "nowdate": nowdate,
                                "get_value": dataent.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)
Ejemplo n.º 12
0
	def get_list_of_recipients(self, doc, context):
		recipients = []
		cc = []
		bcc = []
		for recipient in self.recipients:
			if recipient.condition:
				if not dataent.safe_eval(recipient.condition, None, context):
					continue
			if recipient.email_by_document_field:
				email_ids_value = doc.get(recipient.email_by_document_field)
				if validate_email_add(email_ids_value):
					email_ids = email_ids_value.replace(",", "\n")
					recipients = recipients + email_ids.split("\n")

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

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

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

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

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

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

		if not recipients and not cc and not bcc:
			return None, None, None
		return list(set(recipients)), list(set(cc)), list(set(bcc))
Ejemplo n.º 13
0
def evaluate_alert(doc, alert, event):
	from jinja2 import TemplateError
	try:
		if isinstance(alert, string_types):
			alert = dataent.get_doc("Notification", alert)

		context = get_context(doc)

		if alert.condition:
			if not dataent.safe_eval(alert.condition, None, context):
				return

		if event=="Value Change" and not doc.is_new():
			try:
				db_value = dataent.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)
					dataent.log_error('Notification {0} has been disabled due to missing field'.format(alert.name))
					return

			db_value = parse_val(db_value)
			if (doc.get(alert.value_changed) == db_value) or \
				(not db_value and not doc.get(alert.value_changed)):

				return # value not changed

		if event != "Value Change" and not doc.is_new():
			# reload the doc for the latest values & comments,
			# except for validate type event.
			doc = dataent.get_doc(doc.doctype, doc.name)
		alert.send(doc)
	except TemplateError:
		dataent.throw(_("Error while evaluating Notification {0}. Please fix your template.").format(alert))
	except Exception as e:
		dataent.log_error(message=dataent.get_traceback(), title=str(e))
		dataent.throw(_("Error in Notification"))
Ejemplo n.º 14
0
def get_feedback_request_details(reference_doctype,
                                 reference_name,
                                 trigger="Manual",
                                 request=None):
    if not dataent.db.get_value(reference_doctype, reference_name):
        # reference document is either deleted or renamed
        return
    elif not trigger and not request and not dataent.db.get_value(
            "Feedback Trigger", {"document_type": reference_doctype}):
        return
    elif not trigger and request:
        trigger = dataent.db.get_value("Feedback Request", request,
                                       "feedback_trigger")
    else:
        trigger = dataent.db.get_value("Feedback Trigger",
                                       {"document_type": reference_doctype})

    if not trigger:
        return

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

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

    recipients = doc.get(feedback_trigger.email_fieldname, None)
    if feedback_trigger.check_communication:
        communications = dataent.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:
            dataent.msgprint(
                _("At least one reply is mandatory before requesting feedback")
            )
            return None

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

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

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

        return {
            "subject": subject,
            "recipients": recipients,
            "reference_name": doc.name,
            "reference_doctype": doc.doctype,
            "message": feedback_request_message,
        }
    else:
        dataent.msgprint(_("Feedback conditions do not match"))
        return None
Ejemplo n.º 15
0
 def get_filters(self):
     if self.condition:
         return dataent.safe_eval(self.condition, dict(dataent=dataent))
Ejemplo n.º 16
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 dataent.session.user == "Guest":
            context._login_required = True

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

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

        if dataent.form_dict.name and not has_web_form_permission(
                self.doc_type, dataent.form_dict.name):
            dataent.throw(
                _("You don't have the permissions to access this document"),
                dataent.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 dataent.form_dict.name and not dataent.form_dict.new:
                        self.build_as_list(context)
                else:
                    if dataent.session.user != 'Guest' and not dataent.form_dict.name:
                        dataent.form_dict.name = dataent.db.get_value(
                            self.doc_type, {"owner": dataent.session.user},
                            "name")

                    if not dataent.form_dict.name:
                        # only a single doc allowed and no existing doc, hence new
                        dataent.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:
            dataent.form_dict.new = 1

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

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

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

        if context.success_message:
            context.success_message = dataent.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

        context.show_in_grid = self.show_in_grid