Example #1
0
def update_modified(original_modified, doc):
	# since there is a new timestamp on the file, update timestamp in
	if doc["doctype"] == doc["name"] and doc["name"] != "DocType":
		singles_table = DocType("Singles")

		frappe.qb.update(singles_table).set(singles_table.value, original_modified).where(
			singles_table["field"] == "modified",  # singles_table.field is a method of pypika Selectable
		).where(singles_table.doctype == doc["name"]).run()
	else:
		doctype_table = DocType(doc["doctype"])

		frappe.qb.update(doctype_table).set(doctype_table.modified, original_modified).where(
			doctype_table.name == doc["name"]
		).run()
Example #2
0
    def make_new_lead_if_required(self):
        """Set lead against new opportunity"""
        if (not self.get("party_name")) and self.contact_email:
            # check if customer is already created agains the self.contact_email
            dynamic_link, contact = DocType("Dynamic Link"), DocType("Contact")
            customer = (frappe.qb.from_(dynamic_link).join(contact).on(
                (contact.name == dynamic_link.parent)
                & (dynamic_link.link_doctype == "Customer")
                & (contact.email_id == self.contact_email)).select(
                    dynamic_link.link_name).distinct().run(as_dict=True))

            if customer and customer[0].link_name:
                self.party_name = customer[0].link_name
                self.opportunity_from = "Customer"
                return

            lead_name = frappe.db.get_value("Lead",
                                            {"email_id": self.contact_email})
            if not lead_name:
                sender_name = get_fullname(self.contact_email)
                if sender_name == self.contact_email:
                    sender_name = None

                if not sender_name and ("@" in self.contact_email):
                    email_name = self.contact_email.split("@")[0]

                    email_split = email_name.split(".")
                    sender_name = ""
                    for s in email_split:
                        sender_name += s.capitalize() + " "

                lead = frappe.get_doc({
                    "doctype": "Lead",
                    "email_id": self.contact_email,
                    "lead_name": sender_name or "Unknown"
                })

                lead.flags.ignore_email_validation = True
                lead.insert(ignore_permissions=True)
                lead_name = lead.name

            self.opportunity_from = "Lead"
            self.party_name = lead_name
Example #3
0
def update_permission_property(doctype,
                               role,
                               permlevel,
                               ptype,
                               value=None,
                               validate=True):
    """Update a property in Custom Perm"""
    from frappe.core.doctype.doctype.doctype import validate_permissions_for_doctype

    out = setup_custom_perms(doctype)

    name = frappe.get_value(
        "Custom DocPerm", dict(parent=doctype, role=role, permlevel=permlevel))

    table = DocType("Custom DocPerm")
    frappe.qb.update(table).set(ptype, value).where(table.name == name).run()

    if validate:
        validate_permissions_for_doctype(doctype)

    return out
Example #4
0
    def add_data(self):
        from frappe.query_builder import DocType

        if self.template and not self.with_data:
            return

        frappe.permissions.can_export(self.parent_doctype,
                                      raise_exception=True)

        # sort nested set doctypes by `lft asc`
        order_by = None
        table_columns = frappe.db.get_table_columns(self.parent_doctype)
        if "lft" in table_columns and "rgt" in table_columns:
            order_by = "`tab{doctype}`.`lft` asc".format(
                doctype=self.parent_doctype)
        # get permitted data only
        self.data = frappe.get_list(self.doctype,
                                    fields=["*"],
                                    filters=self.filters,
                                    limit_page_length=None,
                                    order_by=order_by)

        for doc in self.data:
            op = self.docs_to_export.get("op")
            names = self.docs_to_export.get("name")

            if names and op:
                if op == "=" and doc.name not in names:
                    continue
                elif op == "!=" and doc.name in names:
                    continue
            elif names:
                try:
                    sflags = self.docs_to_export.get("flags", "I,U").upper()
                    flags = 0
                    for a in re.split(r"\W+", sflags):
                        flags = flags | reflags.get(a, 0)

                    c = re.compile(names, flags)
                    m = c.match(doc.name)
                    if not m:
                        continue
                except Exception:
                    if doc.name not in names:
                        continue
            # add main table
            rows = []

            self.add_data_row(rows, self.doctype, None, doc, 0)

            if self.all_doctypes:
                # add child tables
                for c in self.child_doctypes:
                    child_doctype_table = DocType(c["doctype"])
                    data_row = (
                        frappe.qb.from_(child_doctype_table).select("*").where(
                            child_doctype_table.parent == doc.name).where(
                                child_doctype_table.parentfield ==
                                c["parentfield"]).orderby(
                                    child_doctype_table.idx))
                    for ci, child in enumerate(data_row.run(as_dict=True)):
                        self.add_data_row(rows, c["doctype"], c["parentfield"],
                                          child, ci)

            for row in rows:
                self.writer.writerow(row)
Example #5
0
def import_file_by_path(
	path: str,
	force: bool = False,
	data_import: bool = False,
	pre_process=None,
	ignore_version: bool = None,
	reset_permissions: bool = False,
):
	"""Import file from the given path

	Some conditions decide if a file should be imported or not.
	Evaluation takes place in the order they are mentioned below.

	- Check if `force` is true. Import the file. If not, move ahead.
	- Get `db_modified_timestamp`(value of the modified field in the database for the file).
	        If the return is `none,` this file doesn't exist in the DB, so Import the file. If not, move ahead.
	- Check if there is a hash in DB for that file. If there is, Calculate the Hash of the file to import and compare it with the one in DB if they are not equal.
	        Import the file. If Hash doesn't exist, move ahead.
	- Check if `db_modified_timestamp` is older than the timestamp in the file; if it is, we import the file.

	If timestamp comparison happens for doctypes, that means the Hash for it doesn't exist.
	So, even if the timestamp is newer on DB (When comparing timestamps), we import the file and add the calculated Hash to the DB.
	So in the subsequent imports, we can use hashes to compare. As a precautionary measure, the timestamp is updated to the current time as well.

	Args:
	        path (str): Path to the file.
	        force (bool, optional): Load the file without checking any conditions. Defaults to False.
	        data_import (bool, optional): [description]. Defaults to False.
	        pre_process ([type], optional): Any preprocesing that may need to take place on the doc. Defaults to None.
	        ignore_version (bool, optional): ignore current version. Defaults to None.
	        reset_permissions (bool, optional): reset permissions for the file. Defaults to False.

	Returns:
	        [bool]: True if import takes place. False if it wasn't imported.
	"""
	frappe.flags.dt = frappe.flags.dt or []
	try:
		docs = read_doc_from_file(path)
	except IOError:
		print(path + " missing")
		return

	calculated_hash = calculate_hash(path)

	if docs:
		if not isinstance(docs, list):
			docs = [docs]

		for doc in docs:

			# modified timestamp in db, none if doctype's first import
			db_modified_timestamp = frappe.db.get_value(doc["doctype"], doc["name"], "modified")
			is_db_timestamp_latest = db_modified_timestamp and (
				get_datetime(doc.get("modified")) <= get_datetime(db_modified_timestamp)
			)

			if not force or db_modified_timestamp:
				try:
					stored_hash = frappe.db.get_value(doc["doctype"], doc["name"], "migration_hash")
				except Exception:
					frappe.flags.dt += [doc["doctype"]]
					stored_hash = None

				# if hash exists and is equal no need to update
				if stored_hash and stored_hash == calculated_hash:
					continue

				# if hash doesn't exist, check if db timestamp is same as json timestamp, add hash if from doctype
				if is_db_timestamp_latest and doc["doctype"] != "DocType":
					continue

			import_doc(
				docdict=doc,
				force=force,
				data_import=data_import,
				pre_process=pre_process,
				ignore_version=ignore_version,
				reset_permissions=reset_permissions,
				path=path,
			)

			if doc["doctype"] == "DocType":
				doctype_table = DocType("DocType")
				frappe.qb.update(doctype_table).set(doctype_table.migration_hash, calculated_hash).where(
					doctype_table.name == doc["name"]
				).run()

			new_modified_timestamp = doc.get("modified")

			# if db timestamp is newer, hash must have changed, must update db timestamp
			if is_db_timestamp_latest and doc["doctype"] == "DocType":
				new_modified_timestamp = now()

			if new_modified_timestamp:
				update_modified(new_modified_timestamp, doc)

	return True