Beispiel #1
0
def get_open_count(doctype, name):
    '''Get open count for given transactions and filters

	:param doctype: Reference DocType
	:param name: Reference Name
	:param transactions: List of transactions (json/dict)
	:param filters: optional filters (json/list)'''

    frappe.has_permission(doc=frappe.get_doc(doctype, name), throw=True)

    meta = frappe.get_meta(doctype)
    links = meta.get_dashboard_data()

    # compile all items in a list
    items = []
    for group in links.transactions:
        items.extend(group.get('items'))

    out = []
    for d in items:
        if d in links.get('internal_links', {}):
            # internal link
            continue

        filters = get_filters_for(d)
        fieldname = links.get('non_standard_fieldnames',
                              {}).get(d, links.fieldname)
        data = {'name': d}
        if filters:
            # get the fieldname for the current document
            # we only need open documents related to the current document
            filters[fieldname] = name
            total = len(
                frappe.get_all(d,
                               fields='name',
                               filters=filters,
                               limit=100,
                               distinct=True,
                               ignore_ifnull=True))
            data['open_count'] = total

        total = len(
            frappe.get_all(d,
                           fields='name',
                           filters={fieldname: name},
                           limit=100,
                           distinct=True,
                           ignore_ifnull=True))
        data['count'] = total
        out.append(data)

    out = {
        'count': out,
    }

    module = frappe.get_meta_module(doctype)
    if hasattr(module, 'get_timeline_data'):
        out['timeline_data'] = module.get_timeline_data(doctype, name)

    return out
Beispiel #2
0
def get_open_count(doctype, name, items=None):
	'''Get open count for given transactions and filters

	:param doctype: Reference DocType
	:param name: Reference Name
	:param transactions: List of transactions (json/dict)
	:param filters: optional filters (json/list)'''

	if frappe.flags.in_migrate or frappe.flags.in_install:
		return {
			"count": []
		}

	if items is None:
		items = []

	frappe.has_permission(doc=frappe.get_doc(doctype, name), throw=True)

	meta = frappe.get_meta(doctype)
	links = meta.get_dashboard_data()

	# compile all items in a list
	if not items:
		for group in links.transactions:
			items.extend(group.get("items"))

	if not isinstance(items, list):
		items = json.loads(items)

	out = []
	for d in items:
		if d in links.get("internal_links", {}):
			# internal link
			continue

		filters = get_filters_for(d)
		fieldname = links.get("non_standard_fieldnames", {}).get(d, links.get('fieldname'))
		data = {"name": d}
		if filters:
			# get the fieldname for the current document
			# we only need open documents related to the current document
			filters[fieldname] = name
			total = len(frappe.get_all(d, fields="name",
				filters=filters, limit=100, distinct=True, ignore_ifnull=True))
			data["open_count"] = total

		total = len(frappe.get_all(d, fields="name",
			filters={fieldname: name}, limit=100, distinct=True, ignore_ifnull=True))
		data["count"] = total
		out.append(data)

	out = {
		"count": out,
	}

	module = frappe.get_meta_module(doctype)
	if hasattr(module, "get_timeline_data"):
		out["timeline_data"] = module.get_timeline_data(doctype, name)

	return out
Beispiel #3
0
def get_open_count(doctype, name, items=[]):
	'''Get open count for given transactions and filters

	:param doctype: Reference DocType
	:param name: Reference Name
	:param transactions: List of transactions (json/dict)
	:param filters: optional filters (json/list)'''

	if frappe.flags.in_migrate or frappe.flags.in_install:
		return {
			'count': []
		}

	frappe.has_permission(doc=frappe.get_doc(doctype, name), throw=True)

	meta = frappe.get_meta(doctype)
	links = meta.get_dashboard_data()

	# compile all items in a list
	if not items:
		for group in links.transactions:
			items.extend(group.get('items'))

	if not isinstance(items, list):
		items = json.loads(items)

	out = []
	for d in items:
		if d in links.get('internal_links', {}):
			# internal link
			continue

		filters = get_filters_for(d)
		fieldname = links.get('non_standard_fieldnames', {}).get(d, links.fieldname)
		data = {'name': d}
		if filters:
			# get the fieldname for the current document
			# we only need open documents related to the current document
			filters[fieldname] = name
			total = len(frappe.get_all(d, fields='name',
				filters=filters, limit=100, distinct=True, ignore_ifnull=True))
			data['open_count'] = total

		total = len(frappe.get_all(d, fields='name',
			filters={fieldname: name}, limit=100, distinct=True, ignore_ifnull=True))
		data['count'] = total
		out.append(data)

	out = {
		'count': out,
	}

	module = frappe.get_meta_module(doctype)
	if hasattr(module, 'get_timeline_data'):
		out['timeline_data'] = module.get_timeline_data(doctype, name)

	return out
    def set_sender_field_and_subject_field(self):
        '''Identify the sender and subject fields from the `append_to` DocType'''
        # set subject_field and sender_field
        meta_module = frappe.get_meta_module(self.append_to)
        meta = frappe.get_meta(self.append_to)

        self.subject_field = getattr(meta_module, "subject_field", "subject")
        if not meta.get_field(self.subject_field):
            self.subject_field = None

        self.sender_field = getattr(meta_module, "sender_field", "sender")
        if not meta.get_field(self.sender_field):
            self.sender_field = None
Beispiel #5
0
	def set_sender_field_and_subject_field(self):
		'''Identify the sender and subject fields from the `append_to` DocType'''
		# set subject_field and sender_field
		meta_module = frappe.get_meta_module(self.append_to)
		meta = frappe.get_meta(self.append_to)

		self.subject_field = getattr(meta_module, "subject_field", "subject")
		if not meta.get_field(self.subject_field):
			self.subject_field = None

		self.sender_field = getattr(meta_module, "sender_field", "sender")
		if not meta.get_field(self.sender_field):
			self.sender_field = None
Beispiel #6
0
	def set_thread(self, communication, email):
		"""Appends communication to parent based on thread ID. Will extract
		parent communication and will link the communication to the reference of that
		communication. Also set the status of parent transaction to Open or Replied.

		If no thread id is found and `append_to` is set for the email account,
		it will create a new parent transaction (e.g. Issue)"""
		in_reply_to = (email.mail.get("In-Reply-To") or "").strip(" <>")
		parent = None

		if self.append_to:
			# set subject_field and sender_field
			meta_module = frappe.get_meta_module(self.append_to)
			meta = frappe.get_meta(self.append_to)
			subject_field = getattr(meta_module, "subject_field", "subject")
			if not meta.get_field(subject_field):
				subject_field = None
			sender_field = getattr(meta_module, "sender_field", "sender")
			if not meta.get_field(sender_field):
				sender_field = None

		if in_reply_to:
			if "@{0}".format(frappe.local.site) in in_reply_to:

				# reply to a communication sent from the system
				in_reply_to, domain = in_reply_to.split("@", 1)

				if frappe.db.exists("Communication", in_reply_to):
					parent = frappe.get_doc("Communication", in_reply_to)

					# set in_reply_to of current communication
					communication.in_reply_to = in_reply_to

					if parent.reference_name:
						parent = frappe.get_doc(parent.reference_doctype,
							parent.reference_name)

		if not parent and self.append_to and sender_field:
			if subject_field:
				# try and match by subject and sender
				# if sent by same sender with same subject,
				# append it to old coversation
				subject = strip(re.sub("^\s*(Re|RE)[^:]*:\s*", "", email.subject))

				parent = frappe.db.get_all(self.append_to, filters={
					sender_field: email.from_email,
					subject_field: ("like", "%{0}%".format(subject)),
					"creation": (">", (get_datetime() - relativedelta(days=10)).strftime(DATE_FORMAT))
				}, fields="name")

				# match only subject field
				# when the from_email is of a user in the system
				# and subject is atleast 10 chars long
				if not parent and len(subject) > 10 and is_system_user(email.from_email):
					parent = frappe.db.get_all(self.append_to, filters={
						subject_field: ("like", "%{0}%".format(subject)),
						"creation": (">", (get_datetime() - relativedelta(days=10)).strftime(DATE_FORMAT))
					}, fields="name")

			if parent:
				parent = frappe.get_doc(self.append_to, parent[0].name)

		if not parent and self.append_to and self.append_to!="Communication":
			# no parent found, but must be tagged
			# insert parent type doc
			parent = frappe.new_doc(self.append_to)

			if subject_field:
				parent.set(subject_field, email.subject)

			if sender_field:
				parent.set(sender_field, email.from_email)

			parent.flags.ignore_mandatory = True

			try:
				parent.insert(ignore_permissions=True)
			except frappe.DuplicateEntryError:
				# try and find matching parent
				parent_name = frappe.db.get_value(self.append_to, {sender_field: email.from_email})
				if parent_name:
					parent.name = parent_name
				else:
					parent = None

			# NOTE if parent isn't found and there's no subject match, it is likely that it is a new conversation thread and hence is_first = True
			communication.is_first = True

		if parent:
			communication.reference_doctype = parent.doctype
			communication.reference_name = parent.name
Beispiel #7
0
    def set_thread(self, communication, email):
        """Appends communication to parent based on thread ID. Will extract
		parent communication and will link the communication to the reference of that
		communication. Also set the status of parent transaction to Open or Replied.

		If no thread id is found and `append_to` is set for the email account,
		it will create a new parent transaction (e.g. Issue)"""
        in_reply_to = (email.mail.get("In-Reply-To") or "").strip(" <>")
        parent = None

        if self.append_to:
            # set subject_field and sender_field
            meta_module = frappe.get_meta_module(self.append_to)
            meta = frappe.get_meta(self.append_to)
            subject_field = getattr(meta_module, "subject_field", "subject")
            if not meta.get_field(subject_field):
                subject_field = None
            sender_field = getattr(meta_module, "sender_field", "sender")
            if not meta.get_field(sender_field):
                sender_field = None

        if in_reply_to:
            if "@{0}".format(frappe.local.site) in in_reply_to:

                # reply to a communication sent from the system
                in_reply_to, domain = in_reply_to.split("@", 1)

                if frappe.db.exists("Communication", in_reply_to):
                    parent = frappe.get_doc("Communication", in_reply_to)

                    # set in_reply_to of current communication
                    communication.in_reply_to = in_reply_to

                    if parent.reference_name:
                        parent = frappe.get_doc(parent.reference_doctype,
                                                parent.reference_name)

        if not parent and self.append_to and sender_field:
            if subject_field:
                # try and match by subject and sender
                # if sent by same sender with same subject,
                # append it to old coversation
                subject = strip(
                    re.sub("^\s*(Re|RE)[^:]*:\s*", "", email.subject))

                parent = frappe.db.get_all(
                    self.append_to,
                    filters={
                        sender_field:
                        email.from_email,
                        subject_field: ("like", "%{0}%".format(subject)),
                        "creation":
                        (">", (get_datetime() -
                               relativedelta(days=10)).strftime(DATE_FORMAT))
                    },
                    fields="name")

                # match only subject field
                # when the from_email is of a user in the system
                # and subject is atleast 10 chars long
                if not parent and len(subject) > 10 and is_system_user(
                        email.from_email):
                    parent = frappe.db.get_all(
                        self.append_to,
                        filters={
                            subject_field: ("like", "%{0}%".format(subject)),
                            "creation":
                            (">",
                             (get_datetime() -
                              relativedelta(days=10)).strftime(DATE_FORMAT))
                        },
                        fields="name")

            if parent:
                parent = frappe.get_doc(self.append_to, parent[0].name)

        if not parent and self.append_to and self.append_to != "Communication":
            # no parent found, but must be tagged
            # insert parent type doc
            parent = frappe.new_doc(self.append_to)

            if subject_field:
                parent.set(subject_field, email.subject)

            if sender_field:
                parent.set(sender_field, email.from_email)

            parent.flags.ignore_mandatory = True

            try:
                parent.insert(ignore_permissions=True)
            except frappe.DuplicateEntryError:
                # try and find matching parent
                parent_name = frappe.db.get_value(
                    self.append_to, {sender_field: email.from_email})
                if parent_name:
                    parent.name = parent_name
                else:
                    parent = None

            # NOTE if parent isn't found and there's no subject match, it is likely that it is a new conversation thread and hence is_first = True
            communication.is_first = True

        if parent:
            communication.reference_doctype = parent.doctype
            communication.reference_name = parent.name
Beispiel #8
0
	def set_thread(self, communication, email):
		"""Appends communication to parent based on thread ID. Will extract
		parent communication and will link the communication to the reference of that
		communication. Also set the status of parent transaction to Open or Replied.

		If no thread id is found and `append_to` is set for the email account,
		it will create a new parent transaction (e.g. Issue)"""
		in_reply_to = (email.mail.get("In-Reply-To") or "")
		parent = None
		if self.append_to:
			# set subject_field and sender_field
			meta_module = frappe.get_meta_module(self.append_to)
			meta = frappe.get_meta(self.append_to)
			subject_field = getattr(meta_module, "subject_field", "subject")
			if not meta.get_field(subject_field):
				subject_field = None
			sender_field = getattr(meta_module, "sender_field", "sender")
			if not meta.get_field(sender_field):
				sender_field = None
		matched = False
		if in_reply_to:
			# reply to a communication sent from the system
			reply_found = frappe.db.get_value("Communication", {"message_id": in_reply_to}, ["name", "reference_doctype", "reference_name"], order_by="creation", as_dict=1)
			if reply_found:
				
				# set in_reply_to of current communication
				communication.in_reply_to = reply_found.name
				if frappe.db.exists(reply_found.reference_doctype, reply_found.reference_name):
					communication.reference_doctype = reply_found.reference_doctype
					communication.reference_name = reply_found.reference_name
				matched = True
			if email.message_id:
				first = frappe.db.get_value("Communication", {"message_id": email.message_id},["name", "reference_doctype", "reference_name"], order_by="creation", as_dict=1)
			
				if first:
					#set timeline hide to parent doc so are linked
					communication.timeline_hide = first.name
					if frappe.db.exists(first.reference_doctype, first.reference_name):
						communication.reference_doctype = first.reference_doctype
						communication.reference_name = first.reference_name
					matched = True
		if not matched:
			if not parent and self.append_to and sender_field:
				if subject_field:
					# try and match by subject and sender
					# if sent by same sender with same subject,
					# append it to old coversation
					subject = strip(re.sub("^\s*(Re|RE)[^:]*:\s*", "", email.subject))
	
					parent = frappe.db.get_all(self.append_to, filters={
						sender_field: email.from_email,
						subject_field: ("like", "%{0}%".format(subject)),
						"creation": (">", (get_datetime() - relativedelta(days=10)).strftime(DATE_FORMAT))
					}, fields="name")
	
					# match only subject field
					# when the from_email is of a user in the system
					# and subject is atleast 10 chars long
					if not parent and len(subject) > 10 and is_system_user(email.from_email):
						parent = frappe.db.get_all(self.append_to, filters={
							subject_field: ("like", "%{0}%".format(subject)),
							"creation": (">", (get_datetime() - relativedelta(days=10)).strftime(DATE_FORMAT))
						}, fields="name")
	
				if parent:
					parent = frappe.get_doc(self.append_to, parent[0].name)
	
			if not parent:
				# try match doctype based on subject
				if ':' in email.subject:
					try:
						subject = strip(re.sub("(^\s*(Fw|FW|fwd)[^:]*:|\s*(Re|RE)[^:]*:\s*)*","", email.subject))
						if ':' in subject:
							reference_doctype,reference_name = subject.split(': ',1)
							parent = frappe.get_doc(reference_doctype,reference_name)
					except:
						try:
							ref = re.search("((?<=New Leave Application: ).*(?= - Employee:))",email.subject).group(0)
							parent = frappe.get_doc("Leave Application",ref)
						except:
							pass
	
			if not parent and self.append_to and self.append_to!="Communication":
				# no parent found, but must be tagged
				# insert parent type doc
				parent = frappe.new_doc(self.append_to)
	
				if subject_field:
					parent.set(subject_field, email.subject)
	
				if sender_field:
					parent.set(sender_field, email.from_email)
	
				parent.flags.ignore_mandatory = True
	
				try:
					parent.insert(ignore_permissions=True)
				except frappe.DuplicateEntryError:
					# try and find matching parent
					parent_name = frappe.db.get_value(self.append_to, {sender_field: email.from_email})
					if parent_name:
						parent.name = parent_name
					else:
						parent = None
	
				# NOTE if parent isn't found and there's no subject match, it is likely that it is a new conversation thread and hence is_first = True
				communication.is_first = True
	
			if parent:
				communication.reference_doctype = parent.doctype
				communication.reference_name = parent.name

		# check if message is notification and disable notifications for this message
		isnotification = email.mail.get("isnotification")
		if isnotification:
			if "notification" in isnotification:
				communication.unread_notification_sent = 1
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Lin To and Contributors
# See license.txt
from __future__ import unicode_literals

import frappe
import unittest
from accounting.test_helpers import get_doc_names, get_autonamed_items
from accounting.test_helpers import delete_all_docs, check_if_doc_exists
from accounting.test_helpers import get_item_autoname

get_account_name = frappe.get_meta_module("Account").get_account_name


class TestSalesInvoice(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.doc_handler = DocHandler()
        for (
                company,
                customer,
                items,
                receiving_account,
                stock_account,
                posting_date,
        ) in _test_records:
            cls.doc_handler.create_and_insert_sales_invoice(
                company, customer, items, receiving_account, stock_account,
                posting_date)
        cls.doc_handler.save_and_submit_docs()
Beispiel #10
0
	def set_thread(self, communication, email):
		"""Appends communication to parent based on thread ID. Will extract
		parent communication and will link the communication to the reference of that
		communication. Also set the status of parent transaction to Open or Replied.

		If no thread id is found and `append_to` is set for the email account,
		it will create a new parent transaction (e.g. Issue)"""
		in_reply_to = (email.mail.get("In-Reply-To") or "").strip(" <>")
		parent = None

		if self.append_to:
			# set subject_field and sender_field
			meta_module = frappe.get_meta_module(self.append_to)
			meta = frappe.get_meta(self.append_to)
			subject_field = getattr(meta_module, "subject_field", "subject")
			if not meta.get_field(subject_field):
				subject_field = None
			sender_field = getattr(meta_module, "sender_field", "sender")
			if not meta.get_field(sender_field):
				sender_field = None

		if in_reply_to:
			if "@" in in_reply_to:

				# reply to a communication sent from the system
				in_reply_to = in_reply_to.split("@", 1)[0]
				if frappe.db.exists("Communication", in_reply_to):
					parent = frappe.get_doc("Communication", in_reply_to)

					if parent.reference_name:
						if self.append_to:
							# parent must reference only if name matches
							if parent.reference_doctype==self.append_to:
								# parent same as parent of last communication
								parent = frappe.get_doc(parent.reference_doctype,
									parent.reference_name)
						else:
							parent = frappe.get_doc(parent.reference_doctype,
								parent.reference_name)

		if not parent and self.append_to and subject_field and sender_field:
			# try and match by subject and sender
			# if sent by same sender with same subject,
			# append it to old coversation

			subject = re.sub("Re[^:]*:\s*", "", email.subject)

			parent = frappe.db.get_all(self.append_to, filters={
				sender_field: email.from_email,
				subject_field: ("like", "%{0}%".format(subject)),
				"creation": (">", (get_datetime() - relativedelta(days=10)).strftime(DATE_FORMAT))
			}, fields="name")

			if parent:
				parent = frappe.get_doc(self.append_to, parent[0].name)

		if not parent and self.append_to:
			# no parent found, but must be tagged
			# insert parent type doc
			parent = frappe.new_doc(self.append_to)

			if subject_field:
				parent.set(subject_field, email.subject)

			if sender_field:
				parent.set(sender_field, email.from_email)

			parent.flags.ignore_mandatory = True

			parent.insert(ignore_permissions=True)

			communication.is_first = True

		if parent:
			communication.reference_doctype = parent.doctype
			communication.reference_name = parent.name
Beispiel #11
0
def get_open_count(doctype, name, links):
	'''Get open count for given transactions and filters

	:param doctype: Reference DocType
	:param name: Reference Name
	:param transactions: List of transactions (json/dict)
	:param filters: optional filters (json/list)'''

	frappe.has_permission(doc=frappe.get_doc(doctype, name), throw=True)

	meta = frappe.get_meta(doctype)
	#links = meta.get_dashboard_data()

	links = frappe._dict({
		'fieldname': 'party',
		'transactions': [
			{
				'label': _('Outward Sample'),
				'items': ['Outward Sample']
			},
			{
				'label': _('Inward Sample'),
				'items': ['Inward Sample']
			},
		]
	})
    #frappe.msgprint(str(links))
    #links = frappe._dict(links)
    #return {'count':0}


	# compile all items in a list
	items = []
	for group in links.transactions:
		items.extend(group.get('items'))

	out = []
	for d in items:
		if d in links.get('internal_links', {}):
			# internal link
			continue

		filters = get_filters_for(d)
		fieldname = links.get('non_standard_fieldnames', {}).get(d, links.fieldname)
        #return fieldname
		data = {'name': d}
		if filters:
			# get the fieldname for the current document
			# we only need open documents related to the current document
			filters[fieldname] = name
			total = len(frappe.get_all(d, fields='name',
				filters=filters, limit=100, distinct=True, ignore_ifnull=True))
			data['open_count'] = total

		total = len(frappe.get_all(d, fields='name',
			filters={fieldname: name}, limit=100, distinct=True, ignore_ifnull=True))
		data['count'] = total
		out.append(data)

	out = {
		'count': out,
	}

	module = frappe.get_meta_module(doctype)
	if hasattr(module, 'get_timeline_data'):
		out['timeline_data'] = module.get_timeline_data(doctype, name)
    
	return out

	
# 	if isinstance(doc, string_types):
# 		doc = json.loads(doc)
		
# 	so_list = [d['sales_order'] for d in doc['sales_orders'] if d['sales_order']]

# 	sample_list = [d['outward_sample'] for d in doc['finish_items'] if d['outward_sample']]
# 	if not sample_list:
# 		frappe.msgprint(_("Please enter Sales Orders in the above table"))
# 		return []

# 	for sample in sample_list:
# 		sample_doc = frappe.get_doc("Outward Sample",sample)
# 		items_list = [d.item_code for d in sample_doc.details]

# 		for item_code in items_list:
# 			items = frappe.db.sql("""select item as item_code,name as bom_no from `tabBOM` where item = '%s' and is_active = 1 and is_default = 1 and docstatus= 1"""%item_code,as_dict=1)
			
	
# 	if doc['item_code']:
# 		item_condition = ' and so_item.item_code = "{0}"'.format(frappe.db.escape( doc['item_code']))

# 		packed_items = frappe.db.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as warehouse,
# 			(((so_item.qty - so_item.work_order_qty) * pi.qty) / so_item.qty)
# 				as pending_qty, pi.parent_item, so_item.name
# 			from `tabSales Order Item` so_item, `tabPacked Item` pi
# 			where so_item.parent = pi.parent and so_item.docstatus = 1
# 			and pi.parent_item = so_item.item_code
# 			and so_item.parent in (%s) and so_item.qty > so_item.work_order_qty
# 			and exists (select name from `tabBOM` bom where bom.item=pi.item_code
# 					and bom.is_active = 1) %s""" % \
# 			(", ".join(["%s"] * len(so_list)), item_condition), tuple(so_list), as_dict=1)

# 	add_items(items,packed_items)
# 	# calculate_total_planned_qty()

# def add_items(self, items):
# 	self.set('po_items', [])
# 	for data in items:
# 		item_details = get_item_details(data.item_code)
# 		pi = self.append('po_items', {
# 			'include_exploded_items': 1,
# 			'warehouse': data.warehouse,
# 			'item_code': data.item_code,
# 			'description': item_details and item_details.description or '',
# 			'stock_uom': item_details and item_details.stock_uom or '',
# 			'bom_no': item_details and item_details.bom_no or '',
# 			'planned_qty': data.pending_qty,
# 			'pending_qty': data.pending_qty,
# 			'planned_start_date': now_datetime(),
# 			'product_bundle_item': data.parent_item
# 		})

# 		if self.get_items_from == "Sales Order":
# 			pi.sales_order = data.parent
# 			pi.sales_order_item = data.name

# 		elif self.get_items_from == "Material Request":
# 			pi.material_request = data.parent
# 			pi.material_request_item = data.name

# # def calculate_total_planned_qty(self):
# # 	self.total_planned_qty = 0
# # 	for d in self.po_items:
# # 		self.total_planned_qty += flt(d.planned_qty)