def execute():
    for doctype in ['BOM Explosion Item', 'BOM Item', 'Work Order Item', 'Item']:
        if frappe.db.has_column(doctype, 'allow_transfer_for_manufacture'):
            if doctype != 'Item':
                frappe.reload_doc('manufacturing', 'doctype', frappe.scrub(doctype))
            else:
                frappe.reload_doc('stock', 'doctype', frappe.scrub(doctype))

            rename_field(doctype, "allow_transfer_for_manufacture", "include_item_in_manufacturing")

    if frappe.db.has_column('BOM', 'allow_same_item_multiple_times'):
        frappe.db.sql(""" UPDATE tabBOM
            SET
                allow_same_item_multiple_times = 0
            WHERE
                trim(coalesce(allow_same_item_multiple_times, '')) = '' """)

    for doctype in ['BOM', 'Work Order']:
        frappe.reload_doc('manufacturing', 'doctype', frappe.scrub(doctype))

        if frappe.db.has_column(doctype, 'transfer_material_against_job_card'):
            frappe.db.sql(""" UPDATE `tab%s`
                SET transfer_material_against = CASE WHEN
                    transfer_material_against_job_card = 1 then 'Job Card' Else 'Work Order' END
                WHERE docstatus < 2""" % (doctype))
        else:
            frappe.db.sql(""" UPDATE `tab%s`
                SET transfer_material_against = 'Work Order'
                WHERE docstatus < 2""" % (doctype))
def get_column(course_dict):
	columns = [{
		"fieldname": "student",
		"label": _("Student ID"),
		"fieldtype": "Link",
		"options": "Student",
		"width": 90
	},
	{
		"fieldname": "student_name",
		"label": _("Student Name"),
		"fieldtype": "Data",
		"width": 160
	}]
	for course in course_dict:
		columns.append({
			"fieldname": "grade_" + frappe.scrub(course),
			"label": course,
			"fieldtype": "Data",
			"width": 110
		})
		columns.append({
			"fieldname": "score_" + frappe.scrub(course),
			"label": "Score(" + str(course_dict[course]) + ")",
			"fieldtype": "Float",
			"width": 100
		})

	return columns
Example #3
0
def update_number_field(doctype_name, name, field_name, number_value, company):
	'''
		doctype_name = Name of the DocType
		name = Docname being referred
		field_name = Name of the field thats holding the 'number' attribute
		number_value = Numeric value entered in field_name

		Stores the number entered in the dialog to the DocType's field.

		Renames the document by adding the number as a prefix to the current name and updates
		all transaction where it was present.
	'''
	doc_title = frappe.db.get_value(doctype_name, name, frappe.scrub(doctype_name)+"_name")

	validate_field_number(doctype_name, name, number_value, company, field_name)

	frappe.db.set_value(doctype_name, name, field_name, number_value)

	if doc_title[0].isdigit():
		separator = " - " if " - " in doc_title else " "
		doc_title = doc_title.split(separator, 1)[1]

	frappe.db.set_value(doctype_name, name, frappe.scrub(doctype_name)+"_name", doc_title)

	new_name = get_autoname_with_number(number_value, doc_title, name, company)

	if name != new_name:
		frappe.rename_doc(doctype_name, name, new_name)
		return new_name
Example #4
0
	def on_update(self):
		"""
			Writes the .txt for this page and if write_content is checked,
			it will write out a .html file
		"""
		if not frappe.flags.in_import and getattr(frappe.get_conf(),'developer_mode', 0) and self.is_standard:
			from frappe.modules.export_file import export_to_files
			from frappe.modules import get_module_path, scrub
			import os

			# json
			export_to_files(record_list=[['Web Form', self.name]])

			# write files
			path = os.path.join(get_module_path(self.module), 'web_form', scrub(self.name), scrub(self.name))

			# js
			if not os.path.exists(path + '.js'):
				with open(path + '.js', 'w') as f:
					f.write("""frappe.ready(function() {
	// bind events here
})""")

			# py
			if not os.path.exists(path + '.py'):
				with open(path + '.py', 'w') as f:
					f.write("""from __future__ import unicode_literals

import frappe

def get_context(context):
	# do your magic here
	pass
""")
def get_column(assessment_criteria):
	columns = [{
		"fieldname": "student",
		"label": _("Student ID"),
		"fieldtype": "Link",
		"options": "Student",
		"width": 90
	},
	{
		"fieldname": "student_name",
		"label": _("Student Name"),
		"fieldtype": "Data",
		"width": 160
	}]
	for d in assessment_criteria:
		columns.append({
			"fieldname": frappe.scrub(d),
			"label": d,
			"fieldtype": "Data",
			"width": 110
		})
		columns.append({
			"fieldname": frappe.scrub(d) +"_score",
			"label": "Score(" + str(int(assessment_criteria[d])) + ")",
			"fieldtype": "Float",
			"width": 100
		})

	return columns
Example #6
0
def get_columns_dict(columns):
	"""Returns a dict with column docfield values as dict
		The keys for the dict are both idx and fieldname,
		so either index or fieldname can be used to search for a column's docfield properties
	"""
	columns_dict = {}
	for idx, col in enumerate(columns):
		col_dict = {}

		# string
		if isinstance(col, basestring):
			col = col.split(":")
			if len(col) > 1:
				if "/" in col[1]:
					col_dict["fieldtype"], col_dict["options"] = col[1].split("/")
				else:
					col_dict["fieldtype"] = col[1]

			col_dict["fieldname"] = frappe.scrub(col[0])

		# dict
		else:
			col_dict.update(col)
			if "fieldname" not in col_dict:
				col_dict["fieldname"] = frappe.scrub(col_dict["label"])

		columns_dict[idx] = col_dict
		columns_dict[col_dict["fieldname"]] = col_dict

	return columns_dict
Example #7
0
def get_expense_cost_center(doctype, args):
	if doctype == 'Item Group':
		return frappe.db.get_value('Item Default',
			{'parent': args.get(frappe.scrub(doctype)), 'company': args.get('company')},
			['buying_cost_center', 'expense_account'])
	else:
		return frappe.db.get_value(doctype, args.get(frappe.scrub(doctype)),\
			['cost_center', 'default_expense_account'])
Example #8
0
	def rename_inside_controller(self, new, old, new_path):
		for fname in ('{}.js', '{}.py', '{}_list.js', '{}_calendar.js', 'test_{}.py', 'test_{}.js'):
			fname = os.path.join(new_path, fname.format(frappe.scrub(new)))
			if os.path.exists(fname):
				with open(fname, 'r') as f:
					code = f.read()
				with open(fname, 'w') as f:
					f.write(code.replace(frappe.scrub(old).replace(' ', ''), frappe.scrub(new).replace(' ', '')))
Example #9
0
	def get_web_template(self, suffix=''):
		'''Returns the relative path of the row template for this doctype'''
		module_name = frappe.scrub(self.module)
		doctype = frappe.scrub(self.name)
		template_path = frappe.get_module_path(module_name, 'doctype',
			doctype, 'templates', doctype + suffix + '.html')
		if os.path.exists(template_path):
			return '{module_name}/doctype/{doctype_name}/templates/{doctype_name}{suffix}.html'.format(
				module_name = module_name, doctype_name = doctype, suffix=suffix)
		return None
Example #10
0
	def get_defaults(self, key=None, parent="__default"):
		"""Get all defaults"""
		if key:
			defaults = frappe.defaults.get_defaults(parent)
			d = defaults.get(key, None)
			if(not d and key != frappe.scrub(key)):
				d = defaults.get(frappe.scrub(key), None)
			return d
		else:
			return frappe.defaults.get_defaults(parent)
Example #11
0
	def get_mapping_module(self, mapping_name):
		try:
			module_def = frappe.get_doc("Module Def", self.module)
			module = frappe.get_module('{app}.{module}.data_migration_mapping.{mapping_name}'.format(
				app= module_def.app_name,
				module=frappe.scrub(self.module),
				mapping_name=frappe.scrub(mapping_name)
			))
			return module
		except ImportError:
			return None
	def cleanup_fields_value(self):
		for logic_field in ["apply_on", "applicable_for", "price_or_discount"]:
			fieldname = frappe.scrub(self.get(logic_field) or "")

			# reset all values except for the logic field
			options = (self.meta.get_options(logic_field) or "").split("\n")
			for f in options:
				if not f: continue

				f = frappe.scrub(f)
				if f!=fieldname:
					self.set(f, None)
Example #13
0
	def rename_files_and_folders(self, old, new):
		# move files
		new_path = get_doc_path(self.module, 'doctype', new)
		subprocess.check_output(['mv', get_doc_path(self.module, 'doctype', old), new_path])

		# rename files
		for fname in os.listdir(new_path):
			if frappe.scrub(old) in fname:
				subprocess.check_output(['mv', os.path.join(new_path, fname),
					os.path.join(new_path, fname.replace(frappe.scrub(old), frappe.scrub(new)))])

		self.rename_inside_controller(new, old, new_path)
		frappe.msgprint('Renamed files and replaced code in controllers, please check!')
Example #14
0
def get_user_default_as_list(key, user=None):
	user_defaults = get_defaults(user or frappe.session.user)
	d = user_defaults.get(key, None)
	
	if key != frappe.scrub(key):
		if d and isinstance(d, (list, tuple)) and len(d)==1:
			# Use User Permission value when only when it has a single value
			d = [d[0]]
			
		else:
			d = user_defaults.get(frappe.scrub(key), None)

	return (not isinstance(d, (list, tuple))) and [d] or d
def execute(filters=None):
	data, chart, grades = [], [], []
	args = frappe._dict()
	grade_wise_analysis = defaultdict(dict)

	args["academic_year"] = filters.get("academic_year")
	args["course"] = filters.get("course")
	args["assessment_group"] = filters.get("assessment_group")

	args["academic_term"] = filters.get("academic_term")
	args["student_group"] = filters.get("student_group")

	if args["assessment_group"] == "All Assessment Groups":
		frappe.throw(_("Please select the assessment group other than 'All Assessment Groups'"))

	returned_values = get_formatted_result(args, get_assessment_criteria=True)
	student_dict = returned_values["student_details"]
	result_dict = returned_values["assessment_result"]
	assessment_criteria_dict = returned_values["assessment_criteria"]

	for student in result_dict:
		student_row = {}
		student_row["student"] = student
		student_row["student_name"] = student_dict[student]
		for criteria in assessment_criteria_dict:
			scrub_criteria = frappe.scrub(criteria)
			if criteria in result_dict[student][args.course][args.assessment_group]:
				student_row[scrub_criteria] = result_dict[student][args.course][args.assessment_group][criteria]["grade"]
				student_row[scrub_criteria + "_score"] = result_dict[student][args.course][args.assessment_group][criteria]["score"]

				# create the list of possible grades
				if student_row[scrub_criteria] not in grades:
					grades.append(student_row[scrub_criteria])
				
				# create the dict of for gradewise analysis
				if student_row[scrub_criteria] not in grade_wise_analysis[criteria]:
					grade_wise_analysis[criteria][student_row[scrub_criteria]] = 1
				else:
					grade_wise_analysis[criteria][student_row[scrub_criteria]] += 1
			else:
				student_row[frappe.scrub(criteria)] = ""
				student_row[frappe.scrub(criteria)+ "_score"] = ""
		data.append(student_row)

	assessment_criteria_list = [d for d in assessment_criteria_dict]
	columns = get_column(assessment_criteria_dict)
	chart = get_chart_data(grades, assessment_criteria_list, grade_wise_analysis)

	return columns, data, None, chart
Example #16
0
	def add_custom_context_and_script(self, context):
		'''Update context from module if standard and append script'''
		if self.web_form_module:
			new_context = self.web_form_module.get_context(context)

			if new_context:
				context.update(new_context)

			js_path = os.path.join(os.path.dirname(self.web_form_module.__file__), scrub(self.name) + '.js')
			if os.path.exists(js_path):
				context.script = frappe.render_template(open(js_path, 'r').read().decode('utf-8'), context)

			css_path = os.path.join(os.path.dirname(self.web_form_module.__file__), scrub(self.name) + '.css')
			if os.path.exists(css_path):
				context.style = open(css_path, 'r').read()
	def test_Custom_Script_fixture_multi_name_not_equal(self):
		fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"!="}]
		path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
	def test_Custom_Script_fixture_rex_with_flags(self):
		fixture = ["Custom Script", {"name":r"^[i|A]", "flags":"L,M"}]
		path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
Example #19
0
def get_party_account(party_type, party, company):
	"""Returns the account for the given `party`.
		Will first search in party (Customer / Supplier) record, if not found,
		will search in group (Customer Group / Supplier Group),
		finally will return default."""
	if not company:
		frappe.throw(_("Please select a Company"))

	if not party:
		return

	account = frappe.db.get_value("Party Account",
		{"parenttype": party_type, "parent": party, "company": company}, "account")

	if not account and party_type in ['Customer', 'Supplier']:
		party_group_doctype = "Customer Group" if party_type=="Customer" else "Supplier Group"
		group = frappe.get_cached_value(party_type, party, scrub(party_group_doctype))
		account = frappe.db.get_value("Party Account",
			{"parenttype": party_group_doctype, "parent": group, "company": company}, "account")

	if not account and party_type in ['Customer', 'Supplier']:
		default_account_name = "default_receivable_account" \
			if party_type=="Customer" else "default_payable_account"
		account = frappe.get_cached_value('Company',  company,  default_account_name)

	existing_gle_currency = get_party_gle_currency(party_type, party, company)
	if existing_gle_currency:
		if account:
			account_currency = frappe.db.get_value("Account", account, "account_currency", cache=True)
		if (account and account_currency != existing_gle_currency) or not account:
				account = get_party_gle_account(party_type, party, company)

	return account
	def test_Doctype_fixture_rex_with_flags(self):
		fixture = ["ToDo", {"name":r"^TDi", "flags":"L,M"}]
		path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_with_flags_should_be_none.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
	def test_Custom_Script_fixture_simple_name_at_least_equal(self):
		fixture = ["Custom Script", {"name":"Item-Cli"}]
		path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
	def test_Doctype_multi_name_not_equal(self):
		fixture = ["ToDo", {"name":["TDI00000002", "TDI00000008"],"op":"!="}]
		path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
	def test_Doctype_fixture_just_list(self):
		fixture = ["ToDo"]
		path = "Doctype_" + frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
	def test_Doctype_fixture_simple(self):
		fixture = "ToDo"
		path = "Doctype_" + frappe.scrub(fixture) + "_original_style_should_be_all.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
	def test_Doctype_fixture_simple_name_at_least_equal(self):
		fixture = ["ToDo", {"name":"TDI"}]
		path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
	def test_Custom_Field_fixture_empty_object(self):
		fixture = ["Custom Field", {}]
		path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
	def test_Custom_Script_fixture_just_list(self):
		fixture = ["Custom Script"]
		path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
Example #28
0
def get_data(filters):
	data = []
	items = get_items(filters)
	sle = get_stock_ledger_entries(filters, items)
	item_details = get_item_details(items, sle, filters)
	periodic_data = get_periodic_data(sle, filters)
	ranges = get_period_date_ranges(filters)

	for dummy, item_data in iteritems(item_details):
		row = {
			"name": item_data.name,
			"item_name": item_data.item_name,
			"item_group": item_data.item_group,
			"uom": item_data.stock_uom,
			"brand": item_data.brand,
		}
		total = 0
		for dummy, end_date in ranges:
			period = get_period(end_date, filters)
			amount = flt(periodic_data.get(item_data.name, {}).get(period))
			row[scrub(period)] = amount
			total += amount
		row["total"] = total
		data.append(row)

	return data
	def test_Custom_Field_fixture_rex_no_flags(self):
		fixture = ["Custom Field", {"name":r"^[r|L]"}]
		path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
	def test_Custom_Script_fixture_simple(self):
		fixture = "Custom Script"
		path = frappe.scrub(fixture) + "_original_style.csv"
		# print "teste done {}".format(path)
		export_csv(fixture, path)
		self.assertTrue(True)
		os.remove(path)
Example #31
0
	def validate_mandatory(self):
		for field in ["apply_on", "applicable_for"]:
			tocheck = frappe.scrub(self.get(field) or "")
			if tocheck and not self.get(tocheck):
				throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError)
Example #32
0
def get_payment_entry(dt,
                      dn,
                      party_amount=None,
                      bank_account=None,
                      bank_amount=None):
    doc = frappe.get_doc(dt, dn)

    if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
        frappe.throw(
            _("Can only make payment against unbilled {0}").format(dt))

    party_type = "Customer" if dt in ("Sales Invoice",
                                      "Sales Order") else "Supplier"

    # party account
    if dt == "Sales Invoice":
        party_account = doc.debit_to
    elif dt == "Purchase Invoice":
        party_account = doc.credit_to
    else:
        party_account = get_party_account(party_type,
                                          doc.get(party_type.lower()),
                                          doc.company)

    party_account_currency = doc.get(
        "party_account_currency") or get_account_currency(party_account)

    # payment type
    if (dt == "Sales Order" or (dt=="Sales Invoice" and doc.outstanding_amount > 0)) \
     or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
        payment_type = "Receive"
    else:
        payment_type = "Pay"

    # amounts
    grand_total = outstanding_amount = 0
    if party_amount:
        grand_total = outstanding_amount = party_amount
    elif dt in ("Sales Invoice", "Purchase Invoice"):
        grand_total = doc.base_grand_total if party_account_currency == doc.company_currency else doc.grand_total
        outstanding_amount = doc.outstanding_amount
    else:
        total_field = "base_grand_total" if party_account_currency == doc.company_currency else "grand_total"
        grand_total = flt(doc.get(total_field))
        outstanding_amount = grand_total - flt(doc.advance_paid)

    # bank or cash
    bank = get_default_bank_cash_account(
        doc.company,
        "Bank",
        mode_of_payment=doc.get("mode_of_payment"),
        account=bank_account)

    paid_amount = received_amount = 0
    if party_account_currency == bank.account_currency:
        paid_amount = received_amount = abs(outstanding_amount)
    elif payment_type == "Receive":
        paid_amount = abs(outstanding_amount)
        if bank_amount:
            received_amount = bank_amount
    else:
        received_amount = abs(outstanding_amount)
        if bank_amount:
            paid_amount = bank_amount

    pe = frappe.new_doc("Payment Entry")
    pe.payment_type = payment_type
    pe.company = doc.company
    pe.posting_date = nowdate()
    pe.mode_of_payment = doc.get("mode_of_payment")
    pe.party_type = party_type
    pe.party = doc.get(scrub(party_type))
    pe.paid_from = party_account if payment_type == "Receive" else bank.account
    pe.paid_to = party_account if payment_type == "Pay" else bank.account
    pe.paid_from_account_currency = party_account_currency \
     if payment_type=="Receive" else bank.account_currency
    pe.paid_to_account_currency = party_account_currency if payment_type == "Pay" else bank.account_currency
    pe.paid_amount = paid_amount
    pe.received_amount = received_amount
    pe.allocate_payment_amount = 1

    pe.append(
        "references", {
            "reference_doctype": dt,
            "reference_name": dn,
            "due_date": doc.get("due_date"),
            "total_amount": grand_total,
            "outstanding_amount": outstanding_amount,
            "allocated_amount": outstanding_amount
        })

    pe.setup_party_account_field()
    pe.set_missing_values()
    if party_account and bank:
        pe.set_exchange_rate()
        pe.set_amounts()
    return pe
Example #33
0
def get_columns(filters,currency_list):
	if filters.get("presentation_currency"):
		currency = filters["presentation_currency"]
	else:
		if filters.get("company"):
			currency = get_company_currency(filters["company"])
		else:
			company = get_default_company()
			currency = get_company_currency(company)

	columns = [
		{
			"label": _("GL Entry"),
			"fieldname": "gl_entry",
			"fieldtype": "Link",
			"options": "GL Entry",
			"hidden": 1
		},
		{
			"label": _("Posting Date"),
			"fieldname": "posting_date",
			"fieldtype": "Date",
			"width": 90
		},
		{
			"label": _("Account"),
			"fieldname": "account",
			"fieldtype": "Link",
			"options": "Account",
			"width": 180
		},
		{
			"label": _("Debit ({0})".format(currency)),
			"fieldname": "debit",
			"fieldtype": "Float",
			"width": 100
		},
		{
			"label": _("Credit ({0})".format(currency)),
			"fieldname": "credit",
			"fieldtype": "Float",
			"width": 100
		},
		{
			"label": _("Balance ({0})".format(currency)),
			"fieldname": "balance",
			"fieldtype": "Float",
			"width": 130
		}
	]
	if len(currency_list)>1:
		for curr in currency_list:
			if curr!=currency:
				columns.extend([
				{
					"label": _("Debit ({0})".format(curr)),
					"fieldname": "debit_"+frappe.scrub(curr),
					"fieldtype": "Float",
					"width": 100
				},
				{
					"label": _("Credit ({0})".format(curr)),
					"fieldname": "credit_"+frappe.scrub(curr),
					"fieldtype": "Float",
					"width": 100
				},
				{
					"label": _("Balance ({0})".format(curr)),
					"fieldname": "balance_"+frappe.scrub(curr),
					"fieldtype": "Float",
					"width": 130
				}])	

	columns.extend([
		{
			"label": _("Voucher Type"),
			"fieldname": "voucher_type",
			"width": 120
		},
		{
			"label": _("Voucher No"),
			"fieldname": "voucher_no",
			"fieldtype": "Dynamic Link",
			"options": "voucher_type",
			"width": 180
		},
		{
			"label": _("Against Account"),
			"fieldname": "against",
			"width": 120
		},
		{
			"label": _("Party Type"),
			"fieldname": "party_type",
			"width": 100
		},
		{
			"label": _("Party"),
			"fieldname": "party",
			"width": 100
		},
		{
			"label": _("Project"),
			"options": "Project",
			"fieldname": "project",
			"width": 100
		},
		{
			"label": _("Cost Center"),
			"options": "Cost Center",
			"fieldname": "cost_center",
			"width": 100
		},
		{
			"label": _("Against Voucher Type"),
			"fieldname": "against_voucher_type",
			"width": 100
		},
		{
			"label": _("Against Voucher"),
			"fieldname": "against_voucher",
			"fieldtype": "Dynamic Link",
			"options": "against_voucher_type",
			"width": 100
		},
		{
			"label": _("Supplier Invoice No"),
			"fieldname": "bill_no",
			"fieldtype": "Data",
			"width": 100
		},
		{
			"label": _("Remarks"),
			"fieldname": "remarks",
			"width": 400
		}
	])

	return columns
def get_payment_entry(dt,
                      dn,
                      party_amount=None,
                      bank_account=None,
                      bank_amount=None):
    doc = frappe.get_doc(dt, dn)

    if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
        frappe.throw(
            _("Can only make payment against unbilled {0}").format(dt))

    if dt in ("Sales Invoice", "Sales Order"):
        party_type = "Customer"
    elif dt in ("Purchase Invoice", "Purchase Order"):
        party_type = "Supplier"
    elif dt in ("Expense Claim", "Employee Advance"):
        party_type = "Employee"
    elif dt in ("Fees"):
        party_type = "Student"

    # party account
    if dt == "Sales Invoice":
        party_account = doc.debit_to
    elif dt == "Purchase Invoice":
        party_account = doc.credit_to
    elif dt == "Fees":
        party_account = doc.receivable_account
    elif dt == "Employee Advance":
        party_account = doc.advance_account
    else:
        party_account = get_party_account(party_type,
                                          doc.get(party_type.lower()),
                                          doc.company)

    party_account_currency = doc.get(
        "party_account_currency") or get_account_currency(party_account)

    # payment type
    if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \
     or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
        payment_type = "Receive"
    else:
        payment_type = "Pay"

    # amounts
    grand_total = outstanding_amount = 0
    if party_amount:
        grand_total = outstanding_amount = party_amount
    elif dt in ("Sales Invoice", "Purchase Invoice"):
        if party_account_currency == doc.company_currency:
            grand_total = doc.base_rounded_total or doc.base_grand_total
        else:
            grand_total = doc.rounded_total or doc.grand_total
        outstanding_amount = doc.outstanding_amount
    elif dt in ("Expense Claim"):
        grand_total = doc.total_sanctioned_amount
        outstanding_amount = doc.total_sanctioned_amount \
         - doc.total_amount_reimbursed - flt(doc.total_advance_amount)
    elif dt == "Employee Advance":
        grand_total = doc.advance_amount
        outstanding_amount = flt(doc.advance_amount) - flt(doc.paid_amount)
    elif dt == "Fees":
        grand_total = doc.grand_total
        outstanding_amount = doc.outstanding_amount
    else:
        if party_account_currency == doc.company_currency:
            grand_total = flt(
                doc.get("base_rounded_total") or doc.base_grand_total)
        else:
            grand_total = flt(doc.get("rounded_total") or doc.grand_total)
        outstanding_amount = grand_total - flt(doc.advance_paid)

    # bank or cash
    bank = get_default_bank_cash_account(
        doc.company,
        "Bank",
        mode_of_payment=doc.get("mode_of_payment"),
        account=bank_account)

    paid_amount = received_amount = 0
    if party_account_currency == bank.account_currency:
        paid_amount = received_amount = abs(outstanding_amount)
    elif payment_type == "Receive":
        paid_amount = abs(outstanding_amount)
        if bank_amount:
            received_amount = bank_amount
    else:
        received_amount = abs(outstanding_amount)
        if bank_amount:
            paid_amount = bank_amount

    pe = frappe.new_doc("Payment Entry")
    pe.payment_type = payment_type
    pe.company = doc.company
    pe.posting_date = nowdate()
    pe.mode_of_payment = doc.get("mode_of_payment")
    pe.party_type = party_type
    pe.party = doc.get(scrub(party_type))
    pe.paid_from = party_account if payment_type == "Receive" else bank.account
    pe.paid_to = party_account if payment_type == "Pay" else bank.account
    pe.paid_from_account_currency = party_account_currency \
     if payment_type=="Receive" else bank.account_currency
    pe.paid_to_account_currency = party_account_currency if payment_type == "Pay" else bank.account_currency
    pe.paid_amount = paid_amount
    pe.received_amount = received_amount
    pe.allocate_payment_amount = 1
    pe.letter_head = doc.get("letter_head")

    pe.append(
        "references", {
            'reference_doctype': dt,
            'reference_name': dn,
            "bill_no": doc.get("bill_no"),
            "due_date": doc.get("due_date"),
            'total_amount': grand_total,
            'outstanding_amount': outstanding_amount,
            'allocated_amount': outstanding_amount
        })

    pe.setup_party_account_field()
    pe.set_missing_values()
    if party_account and bank:
        pe.set_exchange_rate()
        pe.set_amounts()
    return pe
    def validate_reference_documents(self):
        if self.party_type == "Student":
            valid_reference_doctypes = ("Fees")
        elif self.party_type == "Customer":
            valid_reference_doctypes = ("Sales Order", "Sales Invoice",
                                        "Journal Entry")
        elif self.party_type == "Supplier":
            valid_reference_doctypes = ("Purchase Order", "Purchase Invoice",
                                        "Journal Entry")
        elif self.party_type == "Employee":
            valid_reference_doctypes = ("Expense Claim", "Journal Entry",
                                        "Employee Advance")

        for d in self.get("references"):
            if not d.allocated_amount:
                continue
            if d.reference_doctype not in valid_reference_doctypes:
                frappe.throw(
                    _("Reference Doctype must be one of {0}").format(
                        comma_or(valid_reference_doctypes)))

            elif d.reference_name:
                if not frappe.db.exists(d.reference_doctype, d.reference_name):
                    frappe.throw(
                        _("{0} {1} does not exist").format(
                            d.reference_doctype, d.reference_name))
                else:
                    ref_doc = frappe.get_doc(d.reference_doctype,
                                             d.reference_name)

                    if d.reference_doctype != "Journal Entry":
                        if self.party != ref_doc.get(scrub(self.party_type)):
                            frappe.throw(
                                _("{0} {1} is not associated with {2} {3}").
                                format(d.reference_doctype, d.reference_name,
                                       self.party_type, self.party))
                    else:
                        self.validate_journal_entry()

                    if d.reference_doctype in ("Sales Invoice",
                                               "Purchase Invoice",
                                               "Expense Claim", "Fees"):
                        if self.party_type == "Customer":
                            ref_party_account = ref_doc.debit_to
                        elif self.party_type == "Student":
                            ref_party_account = ref_doc.receivable_account
                        elif self.party_type == "Supplier":
                            ref_party_account = ref_doc.credit_to
                        elif self.party_type == "Employee":
                            ref_party_account = ref_doc.payable_account

                        if ref_party_account != self.party_account:
                            frappe.throw(
                                _("{0} {1} is associated with {2}, but Party Account is {3}"
                                  ).format(d.reference_doctype,
                                           d.reference_name, ref_party_account,
                                           self.party_account))

                    if ref_doc.docstatus != 1:
                        frappe.throw(
                            _("{0} {1} must be submitted").format(
                                d.reference_doctype, d.reference_name))
def execute():
    for doctype in ("Salary Component", "Salary Detail"):
        if "depends_on_lwp" in frappe.db.get_table_columns(doctype):
            frappe.reload_doc("Payroll", "doctype", scrub(doctype))
            rename_field(doctype, "depends_on_lwp", "depends_on_payment_days")
Example #37
0
def filter_pricing_rules(args, pricing_rules, doc=None):
    if not isinstance(pricing_rules, list):
        pricing_rules = [pricing_rules]

    original_pricing_rule = copy.copy(pricing_rules)

    # filter for qty
    if pricing_rules:
        stock_qty = flt(args.get('stock_qty'))
        amount = flt(args.get('price_list_rate')) * flt(args.get('qty'))

        if pricing_rules[0].apply_rule_on_other:
            field = frappe.scrub(pricing_rules[0].apply_rule_on_other)

            if (field and
                    pricing_rules[0].get('other_' + field) != args.get(field)):
                return

        pr_doc = frappe.get_cached_doc('Pricing Rule', pricing_rules[0].name)

        if pricing_rules[0].mixed_conditions and doc:
            stock_qty, amount, items = get_qty_and_rate_for_mixed_conditions(
                doc, pr_doc, args)
            pricing_rules[0].apply_rule_on_other_items = items

        elif pricing_rules[0].is_cumulative:
            items = [args.get(frappe.scrub(pr_doc.get('apply_on')))]
            data = get_qty_amount_data_for_cumulative(pr_doc, args, items)

            if data:
                stock_qty += data[0]
                amount += data[1]

        if pricing_rules[0].apply_rule_on_other and not pricing_rules[
                0].mixed_conditions and doc:
            pricing_rules = get_qty_and_rate_for_other_item(
                doc, pr_doc, pricing_rules) or []
        else:
            pricing_rules = filter_pricing_rules_for_qty_amount(
                stock_qty, amount, pricing_rules, args)

        if not pricing_rules:
            for d in original_pricing_rule:
                if not d.threshold_percentage: continue

                msg = validate_quantity_and_amount_for_suggestion(
                    d, stock_qty, amount, args.get('item_code'),
                    args.get('transaction_type'))

                if msg:
                    return {
                        'suggestion': msg,
                        'item_code': args.get('item_code')
                    }

        # add variant_of property in pricing rule
        for p in pricing_rules:
            if p.item_code and args.variant_of:
                p.variant_of = args.variant_of
            else:
                p.variant_of = None

    # find pricing rule with highest priority
    if pricing_rules:
        max_priority = max([cint(p.priority) for p in pricing_rules])
        if max_priority:
            pricing_rules = list(
                filter(lambda x: cint(x.priority) == max_priority,
                       pricing_rules))

    # apply internal priority
    all_fields = [
        "item_code", "item_group", "brand", "customer", "customer_group",
        "territory", "supplier", "supplier_group", "campaign", "sales_partner",
        "variant_of"
    ]

    if len(pricing_rules) > 1:
        for field_set in [["item_code", "variant_of", "item_group", "brand"],
                          ["customer", "customer_group", "territory"],
                          ["supplier", "supplier_group"]]:
            remaining_fields = list(set(all_fields) - set(field_set))
            if if_all_rules_same(pricing_rules, remaining_fields):
                pricing_rules = apply_internal_priority(
                    pricing_rules, field_set, args)
                break

    if pricing_rules and not isinstance(pricing_rules, list):
        pricing_rules = list(pricing_rules)

    if len(pricing_rules) > 1:
        rate_or_discount = list(
            set([d.rate_or_discount for d in pricing_rules]))
        if len(rate_or_discount
               ) == 1 and rate_or_discount[0] == "Discount Percentage":
            pricing_rules = list(filter(lambda x: x.for_price_list==args.price_list, pricing_rules)) \
             or pricing_rules

    if len(pricing_rules) > 1 and not args.for_shopping_cart:
        frappe.throw(
            _("Multiple Price Rules exists with same criteria, please resolve conflict by assigning priority. Price Rules: {0}"
              ).format("\n".join([d.name for d in pricing_rules])),
            MultiplePricingRuleConflict)
    elif pricing_rules:
        return pricing_rules[0]
    def validate_reference_doc(self):
        """Validates reference document"""
        field_dict = {
            'Sales Invoice': ["Customer", "Debit To"],
            'Purchase Invoice': ["Supplier", "Credit To"],
            'Sales Order': ["Customer"],
            'Purchase Order': ["Supplier"]
        }

        self.reference_totals = {}
        self.reference_types = {}
        self.reference_accounts = {}

        for d in self.get("accounts"):
            if not d.reference_type:
                d.reference_name = None
            if not d.reference_name:
                d.reference_type = None
            if d.reference_type and d.reference_name and (
                    d.reference_type in field_dict.keys()):
                dr_or_cr = "credit_in_account_currency" \
                 if d.reference_type in ("Sales Order", "Sales Invoice") else "debit_in_account_currency"

                # check debit or credit type Sales / Purchase Order
                if d.reference_type == "Sales Order" and flt(d.debit) > 0:
                    frappe.throw(
                        _("Row {0}: Debit entry can not be linked with a {1}").
                        format(d.idx, d.reference_type))

                if d.reference_type == "Purchase Order" and flt(d.credit) > 0:
                    frappe.throw(
                        _("Row {0}: Credit entry can not be linked with a {1}"
                          ).format(d.idx, d.reference_type))

                # set totals
                if not d.reference_name in self.reference_totals:
                    self.reference_totals[d.reference_name] = 0.0
                self.reference_totals[d.reference_name] += flt(d.get(dr_or_cr))
                self.reference_types[d.reference_name] = d.reference_type
                self.reference_accounts[d.reference_name] = d.account

                against_voucher = frappe.db.get_value(
                    d.reference_type, d.reference_name,
                    [scrub(dt) for dt in field_dict.get(d.reference_type)])

                if not against_voucher:
                    frappe.throw(
                        _("Row {0}: Invalid reference {1}").format(
                            d.idx, d.reference_name))

                # check if party and account match
                if d.reference_type in ("Sales Invoice", "Purchase Invoice"):
                    if (against_voucher[0] != d.party
                            or against_voucher[1] != d.account):
                        frappe.throw(
                            _("Row {0}: Party / Account does not match with {1} / {2} in {3} {4}"
                              ).format(d.idx,
                                       field_dict.get(d.reference_type)[0],
                                       field_dict.get(d.reference_type)[1],
                                       d.reference_type, d.reference_name))

                # check if party matches for Sales / Purchase Order
                if d.reference_type in ("Sales Order", "Purchase Order"):
                    # set totals
                    if against_voucher != d.party:
                        frappe.throw(_("Row {0}: {1} {2} does not match with {3}") \
                         .format(d.idx, d.party_type, d.party, d.reference_type))

        self.validate_orders()
        self.validate_invoices()
 def skip_row(self, row, product_bundles):
     if self.filters.get("group_by") != "Invoice" and not row.get(
             scrub(self.filters.get("group_by"))):
         return True
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
	if not filters:
		filters = {}
	columns = get_columns(additional_table_columns, filters)

	company_currency = frappe.get_cached_value("Company", filters.get("company"), "default_currency")

	item_list = get_items(filters, additional_query_columns)
	if item_list:
		itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)

	mode_of_payments = get_mode_of_payments(set(d.parent for d in item_list))
	so_dn_map = get_delivery_notes_against_sales_order(item_list)

	data = []
	total_row_map = {}
	skip_total_row = 0
	prev_group_by_value = ""

	if filters.get("group_by"):
		grand_total = get_grand_total(filters, "Sales Invoice")

	customer_details = get_customer_details()
	item_details = get_item_details()

	for d in item_list:
		customer_record = customer_details.get(d.customer)
		item_record = item_details.get(d.item_code)

		delivery_note = None
		if d.delivery_note:
			delivery_note = d.delivery_note
		elif d.so_detail:
			delivery_note = ", ".join(so_dn_map.get(d.so_detail, []))

		if not delivery_note and d.update_stock:
			delivery_note = d.parent

		row = {
			"item_code": d.item_code,
			"item_name": item_record.item_name if item_record else d.item_name,
			"item_group": item_record.item_group if item_record else d.item_group,
			"description": d.description,
			"invoice": d.parent,
			"posting_date": d.posting_date,
			"customer": d.customer,
			"customer_name": customer_record.customer_name,
			"customer_group": customer_record.customer_group,
		}

		if additional_query_columns:
			for col in additional_query_columns:
				row.update({col: d.get(col)})

		row.update(
			{
				"debit_to": d.debit_to,
				"mode_of_payment": ", ".join(mode_of_payments.get(d.parent, [])),
				"territory": d.territory,
				"project": d.project,
				"company": d.company,
				"sales_order": d.sales_order,
				"delivery_note": d.delivery_note,
				"income_account": d.unrealized_profit_loss_account
				if d.is_internal_customer == 1
				else d.income_account,
				"cost_center": d.cost_center,
				"stock_qty": d.stock_qty,
				"stock_uom": d.stock_uom,
			}
		)

		if d.stock_uom != d.uom and d.stock_qty:
			row.update({"rate": (d.base_net_rate * d.qty) / d.stock_qty, "amount": d.base_net_amount})
		else:
			row.update({"rate": d.base_net_rate, "amount": d.base_net_amount})

		total_tax = 0
		for tax in tax_columns:
			item_tax = itemised_tax.get(d.name, {}).get(tax, {})
			row.update(
				{
					frappe.scrub(tax + " Rate"): item_tax.get("tax_rate", 0),
					frappe.scrub(tax + " Amount"): item_tax.get("tax_amount", 0),
				}
			)
			total_tax += flt(item_tax.get("tax_amount"))

		row.update(
			{"total_tax": total_tax, "total": d.base_net_amount + total_tax, "currency": company_currency}
		)

		if filters.get("group_by"):
			row.update({"percent_gt": flt(row["total"] / grand_total) * 100})
			group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters)
			data, prev_group_by_value = add_total_row(
				data,
				filters,
				prev_group_by_value,
				d,
				total_row_map,
				group_by_field,
				subtotal_display_field,
				grand_total,
				tax_columns,
			)
			add_sub_total_row(row, total_row_map, d.get(group_by_field, ""), tax_columns)

		data.append(row)

	if filters.get("group_by") and item_list:
		total_row = total_row_map.get(prev_group_by_value or d.get("item_name"))
		total_row["percent_gt"] = flt(total_row["total"] / grand_total * 100)
		data.append(total_row)
		data.append({})
		add_sub_total_row(total_row, total_row_map, "total_row", tax_columns)
		data.append(total_row_map.get("total_row"))
		skip_total_row = 1

	return columns, data, None, None, None, skip_total_row
	def get_columns(self):
		columns = [{
			"label": _(self.filters.party_type),
			"fieldtype": "Link",
			"fieldname": "party",
			"options": self.filters.party_type,
			"width": 200
		}]

		if self.party_naming_by == "Naming Series":
			columns.append({
				"label": _(self.filters.party_type + "Name"),
				"fieldtype": "Data",
				"fieldname": "party_name",
				"width": 110
			})

		credit_or_debit_note = "Credit Note" if self.filters.party_type == "Customer" else "Debit Note"

		columns += [
			{
				"label": _("Opening Balance"),
				"fieldname": "opening_balance",
				"fieldtype": "Currency",
				"options": "currency",
				"width": 120
			},
			{
				"label": _("Invoiced Amount"),
				"fieldname": "invoiced_amount",
				"fieldtype": "Currency",
				"options": "currency",
				"width": 120
			},
			{
				"label": _("Paid Amount"),
				"fieldname": "paid_amount",
				"fieldtype": "Currency",
				"options": "currency",
				"width": 120
			},
			{
				"label": _(credit_or_debit_note),
				"fieldname": "return_amount",
				"fieldtype": "Currency",
				"options": "currency",
				"width": 120
			},
		]

		for account in self.party_adjustment_accounts:
			columns.append({
				"label": account,
				"fieldname": "adj_" + scrub(account),
				"fieldtype": "Currency",
				"options": "currency",
				"width": 120,
				"is_adjustment": 1
			})

		columns += [
			{
				"label": _("Closing Balance"),
				"fieldname": "closing_balance",
				"fieldtype": "Currency",
				"options": "currency",
				"width": 120
			},
			{
				"label": _("Currency"),
				"fieldname": "currency",
				"fieldtype": "Link",
				"options": "Currency",
				"width": 50
			}
		]

		return columns
Example #42
0
    def prepare_conditions(self, party_type):
        conditions = [""]
        values = [party_type]

        party_type_field = scrub(party_type)

        if self.filters.company:
            conditions.append("company=%s")
            values.append(self.filters.company)

        company_finance_book = erpnext.get_default_finance_book(
            self.filters.company)

        if not self.filters.finance_book or (self.filters.finance_book
                                             == company_finance_book):
            conditions.append("ifnull(finance_book,'') in (%s, '')")
            values.append(company_finance_book)
        elif self.filters.finance_book:
            conditions.append("ifnull(finance_book,'') = %s")
            values.append(self.filters.finance_book)

        if self.filters.get(party_type_field):
            conditions.append("party=%s")
            values.append(self.filters.get(party_type_field))

        if party_type_field == "customer":
            account_type = "Receivable"
            if self.filters.get("customer_group"):
                lft, rgt = frappe.db.get_value(
                    "Customer Group", self.filters.get("customer_group"),
                    ["lft", "rgt"])

                conditions.append("""party in (select name from tabCustomer
					where exists(select name from `tabCustomer Group` where lft >= {0} and rgt <= {1}
						and name=tabCustomer.customer_group))""".format(lft, rgt))

            if self.filters.get("territory"):
                lft, rgt = frappe.db.get_value("Territory",
                                               self.filters.get("territory"),
                                               ["lft", "rgt"])

                conditions.append("""party in (select name from tabCustomer
					where exists(select name from `tabTerritory` where lft >= {0} and rgt <= {1}
						and name=tabCustomer.territory))""".format(lft, rgt))

            if self.filters.get("payment_terms_template"):
                conditions.append(
                    "party in (select name from tabCustomer where payment_terms=%s)"
                )
                values.append(self.filters.get("payment_terms_template"))

            if self.filters.get("sales_partner"):
                conditions.append(
                    "party in (select name from tabCustomer where default_sales_partner=%s)"
                )
                values.append(self.filters.get("sales_partner"))

            if self.filters.get("sales_person"):
                lft, rgt = frappe.db.get_value(
                    "Sales Person", self.filters.get("sales_person"),
                    ["lft", "rgt"])

                conditions.append(
                    """exists(select name from `tabSales Team` steam where
					steam.sales_person in (select name from `tabSales Person` where lft >= {0} and rgt <= {1})
					and ((steam.parent = voucher_no and steam.parenttype = voucher_type)
						or (steam.parent = against_voucher and steam.parenttype = against_voucher_type)
						or (steam.parent = party and steam.parenttype = 'Customer')))""".format(
                        lft, rgt))

        elif party_type_field == "supplier":
            account_type = "Payable"
            if self.filters.get("supplier_group"):
                conditions.append("""party in (select name from tabSupplier
					where supplier_group=%s)""")
                values.append(self.filters.get("supplier_group"))

        accounts = [
            d.name for d in frappe.get_all("Account",
                                           filters={
                                               "account_type": account_type,
                                               "company": self.filters.company
                                           })
        ]
        conditions.append("account in (%s)" % ','.join(['%s'] * len(accounts)))
        values += accounts

        return " and ".join(conditions), values
Example #43
0
    def get_columns(self, party_naming_by, args):
        columns = []
        columns.append({
            "label": _("Posting Date"),
            "fieldtype": "Date",
            "fieldname": "posting_date",
            "width": 90
        })

        columns += [
            _(args.get("party_type")) + ":Link/" + args.get("party_type") +
            ":200"
        ]

        if args.get("party_type") == 'Customer':
            columns.append({
                "label": _("Customer Contact"),
                "fieldtype": "Link",
                "fieldname": "contact",
                "options": "Contact",
                "width": 100
            })

        if party_naming_by == "Naming Series":
            columns += [args.get("party_type") + " Name::110"]

        columns.append({
            "label": _("Voucher Type"),
            "fieldtype": "Data",
            "fieldname": "voucher_type",
            "width": 110
        })

        columns.append({
            "label": _("Voucher No"),
            "fieldtype": "Dynamic Link",
            "fieldname": "voucher_no",
            "width": 110,
            "options": "voucher_type",
        })

        columns += [_("Due Date") + ":Date:80"]

        if args.get("party_type") == "Supplier":
            columns += [_("Bill No") + "::80", _("Bill Date") + ":Date:80"]

        credit_or_debit_note = "Credit Note" if args.get(
            "party_type") == "Customer" else "Debit Note"

        if self.filters.based_on_payment_terms:
            columns.append({
                "label": "Payment Term",
                "fieldname": "payment_term",
                "fieldtype": "Data",
                "width": 120
            })
            columns.append({
                "label": "Invoice Grand Total",
                "fieldname": "invoice_grand_total",
                "fieldtype": "Currency",
                "options": "currency",
                "width": 120
            })

        for label in ("Invoiced Amount", "Paid Amount", credit_or_debit_note,
                      "Outstanding Amount"):
            columns.append({
                "label": label,
                "fieldname": frappe.scrub(label),
                "fieldtype": "Currency",
                "options": "currency",
                "width": 120
            })

        columns += [_("Age (Days)") + ":Int:80"]

        self.ageing_col_idx_start = len(columns)

        if not "range1" in self.filters:
            self.filters["range1"] = "30"
        if not "range2" in self.filters:
            self.filters["range2"] = "60"
        if not "range3" in self.filters:
            self.filters["range3"] = "90"

        for label in ("0-{range1}".format(range1=self.filters["range1"]),
                      "{range1}-{range2}".format(
                          range1=cint(self.filters["range1"]) + 1,
                          range2=self.filters["range2"]),
                      "{range2}-{range3}".format(
                          range2=cint(self.filters["range2"]) + 1,
                          range3=self.filters["range3"]),
                      "{range3}-{above}".format(
                          range3=cint(self.filters["range3"]) + 1,
                          above=_("Above"))):
            columns.append({
                "label": label,
                "fieldname": label,
                "fieldtype": "Currency",
                "options": "currency",
                "width": 120
            })

        columns += [{
            "fieldname": "currency",
            "label": _("Currency"),
            "fieldtype": "Link",
            "options": "Currency",
            "width": 100
        }, {
            "fieldname": "pdc/lc_ref",
            "label": _("PDC/LC Ref"),
            "fieldtype": "Data",
            "width": 110
        }, {
            "fieldname": "pdc/lc_amount",
            "label": _("PDC/LC Amount"),
            "fieldtype": "Currency",
            "options": "currency",
            "width": 130
        }, {
            "fieldname": "remaining_balance",
            "label": _("Remaining Balance"),
            "fieldtype": "Currency",
            "options": "currency",
            "width": 130
        }]

        if args.get('party_type') == 'Customer':
            columns += [{
                "label": _("Customer LPO"),
                "fieldtype": "Data",
                "fieldname": "po_no",
                "width": 100,
            },
                        _("Delivery Note") + ":Data:100",
                        _("Territory") + ":Link/Territory:80",
                        _("Customer Group") + ":Link/Customer Group:120", {
                            "label": _("Sales Person"),
                            "fieldtype": "Data",
                            "fieldname": "sales_person",
                            "width": 120,
                        }]
        if args.get("party_type") == "Supplier":
            columns += [_("Supplier Group") + ":Link/Supplier Group:80"]

        columns.append(_("Remarks") + "::200")

        return columns
    def get_data(self, party_naming_by, args):
        from erpnext.accounts.utils import get_currency_precision
        currency_precision = get_currency_precision() or 2
        dr_or_cr = "debit" if args.get(
            "party_type") == "Customer" else "credit"

        dn_details = get_dn_details(args.get("party_type"))
        voucher_details = self.get_voucher_details(args.get("party_type"),
                                                   dn_details)

        future_vouchers = self.get_entries_after(self.filters.report_date,
                                                 args.get("party_type"))

        if not self.filters.get("company"):
            self.filters["company"] = frappe.db.get_single_value(
                'Global Defaults', 'default_company')

        company_currency = frappe.db.get_value("Company",
                                               self.filters.get("company"),
                                               "default_currency")

        return_entries = self.get_return_entries(args.get("party_type"))

        data = []
        pdc_details = get_pdc_details(args.get("party_type"))

        for gle in self.get_entries_till(self.filters.report_date,
                                         args.get("party_type")):
            if self.is_receivable_or_payable(gle, dr_or_cr, future_vouchers):
                outstanding_amount, credit_note_amount = self.get_outstanding_amount(
                    gle, self.filters.report_date, dr_or_cr, return_entries,
                    currency_precision)
                if abs(outstanding_amount) > 0.1 / 10**currency_precision:
                    row = [gle.posting_date, gle.party]

                    # customer / supplier name
                    if party_naming_by == "Naming Series":
                        row += [self.get_party_name(gle.party_type, gle.party)]

                    # get due date
                    due_date = voucher_details.get(gle.voucher_no,
                                                   {}).get("due_date", "")

                    row += [gle.voucher_type, gle.voucher_no, due_date]

                    # get supplier bill details
                    if args.get("party_type") == "Supplier":
                        row += [
                            voucher_details.get(gle.voucher_no,
                                                {}).get("bill_no", ""),
                            voucher_details.get(gle.voucher_no,
                                                {}).get("bill_date", "")
                        ]

                    # invoiced and paid amounts
                    invoiced_amount = gle.get(dr_or_cr) if (
                        gle.get(dr_or_cr) > 0) else 0
                    paid_amt = invoiced_amount - outstanding_amount - credit_note_amount
                    row += [
                        invoiced_amount, paid_amt, credit_note_amount,
                        outstanding_amount
                    ]

                    # ageing data
                    entry_date = due_date if self.filters.ageing_based_on == "Due Date" else gle.posting_date
                    row += get_ageing_data(cint(self.filters.range1),
                                           cint(self.filters.range2),
                                           cint(self.filters.range3),
                                           self.age_as_on, entry_date,
                                           outstanding_amount)

                    # issue 6371-Ageing buckets should not have amounts if due date is not reached
                    if self.filters.ageing_based_on == "Due Date" \
                      and getdate(due_date) > getdate(self.filters.report_date):
                        row[-1] = row[-2] = row[-3] = row[-4] = 0

                    if self.filters.get(scrub(args.get("party_type"))):
                        row.append(gle.account_currency)
                    else:
                        row.append(company_currency)

                    pdc = pdc_details.get(gle.voucher_no, {})
                    remaining_balance = outstanding_amount - flt(
                        pdc.get("pdc_amount"))
                    row += [
                        pdc.get("pdc_date"),
                        pdc.get("pdc_ref"),
                        flt(pdc.get("pdc_amount")), remaining_balance
                    ]

                    if args.get('party_type') == 'Customer':
                        # customer LPO
                        row += [
                            voucher_details.get(gle.voucher_no,
                                                {}).get("po_no")
                        ]

                        # Delivery Note
                        row += [
                            voucher_details.get(gle.voucher_no,
                                                {}).get("delivery_note")
                        ]

                    # customer territory / supplier type
                    if args.get("party_type") == "Customer":
                        row += [
                            self.get_territory(gle.party),
                            self.get_customer_group(gle.party)
                        ]
                    if args.get("party_type") == "Supplier":
                        row += [self.get_supplier_type(gle.party)]

                    row.append(gle.remarks)
                    data.append(row)

        return data
def _execute(filters,
             additional_table_columns=None,
             additional_query_columns=None):
    if not filters: filters = frappe._dict({})

    invoice_list = get_invoices(filters, additional_query_columns)
    columns, income_accounts, tax_accounts, unrealized_profit_loss_accounts = get_columns(
        invoice_list, additional_table_columns)

    if not invoice_list:
        msgprint(_("No record found"))
        return columns, invoice_list

    invoice_income_map = get_invoice_income_map(invoice_list)
    internal_invoice_map = get_internal_invoice_map(invoice_list)
    invoice_income_map, invoice_tax_map = get_invoice_tax_map(
        invoice_list, invoice_income_map, income_accounts)
    #Cost Center & Warehouse Map
    invoice_cc_wh_map = get_invoice_cc_wh_map(invoice_list)
    invoice_so_dn_map = get_invoice_so_dn_map(invoice_list)
    company_currency = frappe.get_cached_value('Company',
                                               filters.get("company"),
                                               "default_currency")
    mode_of_payments = get_mode_of_payments([inv.name for inv in invoice_list])

    data = []
    for inv in invoice_list:
        # invoice details
        sales_order = list(
            set(invoice_so_dn_map.get(inv.name, {}).get("sales_order", [])))
        delivery_note = list(
            set(invoice_so_dn_map.get(inv.name, {}).get("delivery_note", [])))
        cost_center = list(
            set(invoice_cc_wh_map.get(inv.name, {}).get("cost_center", [])))
        warehouse = list(
            set(invoice_cc_wh_map.get(inv.name, {}).get("warehouse", [])))

        row = {
            'invoice': inv.name,
            'posting_date': inv.posting_date,
            'customer': inv.customer,
            'customer_name': inv.customer_name
        }

        if additional_query_columns:
            for col in additional_query_columns:
                row.update({col: inv.get(col)})

        row.update({
            'customer_group':
            inv.get("customer_group"),
            'territory':
            inv.get("territory"),
            'tax_id':
            inv.get("tax_id"),
            'receivable_account':
            inv.debit_to,
            'mode_of_payment':
            ", ".join(mode_of_payments.get(inv.name, [])),
            'project':
            inv.project,
            'owner':
            inv.owner,
            'remarks':
            inv.remarks,
            'sales_order':
            ", ".join(sales_order),
            'delivery_note':
            ", ".join(delivery_note),
            'cost_center':
            ", ".join(cost_center),
            'warehouse':
            ", ".join(warehouse),
            'currency':
            company_currency
        })

        # map income values
        base_net_total = 0
        for income_acc in income_accounts:
            if inv.is_internal_customer and inv.company == inv.represents_company:
                income_amount = 0
            else:
                income_amount = flt(
                    invoice_income_map.get(inv.name, {}).get(income_acc))

            base_net_total += income_amount
            row.update({frappe.scrub(income_acc): income_amount})

        # Add amount in unrealized account
        for account in unrealized_profit_loss_accounts:
            row.update({
                frappe.scrub(account):
                flt(internal_invoice_map.get((inv.name, account)))
            })

        # net total
        row.update({'net_total': base_net_total or inv.base_net_total})

        # tax account
        total_tax = 0
        for tax_acc in tax_accounts:
            if tax_acc not in income_accounts:
                tax_amount_precision = get_field_precision(
                    frappe.get_meta("Sales Taxes and Charges").get_field(
                        "tax_amount"),
                    currency=company_currency) or 2
                tax_amount = flt(
                    invoice_tax_map.get(inv.name, {}).get(tax_acc),
                    tax_amount_precision)
                total_tax += tax_amount
                row.update({frappe.scrub(tax_acc): tax_amount})

        # total tax, grand total, outstanding amount & rounded total

        row.update({
            'tax_total': total_tax,
            'grand_total': inv.base_grand_total,
            'rounded_total': inv.base_rounded_total,
            'outstanding_amount': inv.outstanding_amount
        })

        data.append(row)

    return columns, data
Example #46
0
    def prepare_row(self,
                    party_naming_by,
                    args,
                    gle,
                    outstanding_amount,
                    credit_note_amount,
                    due_date=None,
                    paid_amt=None,
                    payment_term_amount=None,
                    payment_term=None,
                    pdc_amount=None,
                    pdc_details=None):
        row = [gle.posting_date, gle.party]

        # customer / supplier name
        if party_naming_by == "Naming Series":
            row += [self.get_party_name(gle.party_type, gle.party)]

        if args.get("party_type") == 'Customer':
            row += [self.get_customer_contact(gle.party_type, gle.party)]

        # get due date
        if not due_date:
            due_date = self.voucher_details.get(gle.voucher_no,
                                                {}).get("due_date", "")
        bill_date = self.voucher_details.get(gle.voucher_no,
                                             {}).get("bill_date", "")

        row += [gle.voucher_type, gle.voucher_no, due_date]

        # get supplier bill details
        if args.get("party_type") == "Supplier":
            row += [
                self.voucher_details.get(gle.voucher_no,
                                         {}).get("bill_no", ""),
                self.voucher_details.get(gle.voucher_no,
                                         {}).get("bill_date", "")
            ]

        # invoiced and paid amounts
        invoiced_amount = gle.get(
            self.dr_or_cr) if (gle.get(self.dr_or_cr) > 0) else 0

        if self.filters.based_on_payment_terms:
            row += [payment_term, invoiced_amount]
            if payment_term_amount:
                invoiced_amount = payment_term_amount

        if not payment_term_amount:
            paid_amt = invoiced_amount - outstanding_amount - credit_note_amount
        row += [
            invoiced_amount, paid_amt, credit_note_amount, outstanding_amount
        ]

        # ageing data
        if self.filters.ageing_based_on == "Due Date":
            entry_date = due_date
        elif self.filters.ageing_based_on == "Supplier Invoice Date":
            entry_date = bill_date
        else:
            entry_date = gle.posting_date

        row += get_ageing_data(cint(self.filters.range1),
                               cint(self.filters.range2),
                               cint(self.filters.range3), self.age_as_on,
                               entry_date, outstanding_amount)

        # issue 6371-Ageing buckets should not have amounts if due date is not reached
        if self.filters.ageing_based_on == "Due Date" \
          and getdate(due_date) > getdate(self.filters.report_date):
            row[-1] = row[-2] = row[-3] = row[-4] = 0

        if self.filters.ageing_based_on == "Supplier Invoice Date" \
          and getdate(bill_date) > getdate(self.filters.report_date):

            row[-1] = row[-2] = row[-3] = row[-4] = 0

        if self.filters.get(scrub(args.get("party_type"))):
            row.append(gle.account_currency)
        else:
            row.append(self.company_currency)

        remaining_balance = outstanding_amount - flt(pdc_amount)
        pdc_details = ", ".join(pdc_details)
        row += [pdc_details, pdc_amount, remaining_balance]

        if args.get('party_type') == 'Customer':
            # customer LPO
            row += [self.voucher_details.get(gle.voucher_no, {}).get("po_no")]

            # Delivery Note
            row += [
                self.voucher_details.get(gle.voucher_no,
                                         {}).get("delivery_note")
            ]

        # customer territory / supplier group
        if args.get("party_type") == "Customer":
            row += [
                self.get_territory(gle.party),
                self.get_customer_group(gle.party),
                self.voucher_details.get(gle.voucher_no,
                                         {}).get("sales_person")
            ]
        if args.get("party_type") == "Supplier":
            row += [self.get_supplier_group(gle.party)]

        row.append(gle.remarks)

        return row
Example #47
0
	def validate_preferred_email(self):
		if self.prefered_contact_email and not self.get(scrub(self.prefered_contact_email)):
			frappe.msgprint(_("Please enter {0}").format(self.prefered_contact_email))
Example #48
0
 def validate_rate_or_discount(self):
     for field in ["Rate"]:
         if flt(self.get(frappe.scrub(field))) < 0:
             throw(_("{0} can not be negative").format(field))
Example #49
0
def execute(filters=None):
    if not filters:
        filters = {}

    conditions = get_conditions(filters)
    columns = get_column(filters, conditions)
    data = []

    master = get_master(conditions, filters)
    # details = get_details(conditions,filters)
    combo_dict = {}
    total = 0
    for i in master:
        row = {}
        row["ifw_retailskusuffix"] = i.get("ifw_retailskusuffix")
        row["item_name"] = i.get("item_name")
        row["item_code"] = i.get("item_code")

        row["ifw_duty_rate"] = i.get("ifw_duty_rate")
        row["ifw_discontinued"] = i.get("ifw_discontinued")
        row["ifw_product_name_ci"] = i.get("ifw_product_name_ci")
        row["ifw_item_notes"] = i.get("ifw_item_notes")
        row["ifw_item_notes2"] = i.get("ifw_item_notes2")
        row["ifw_po_notes"] = i.get("ifw_po_notes")
        row["country_of_origin"] = i.get("country_of_origin")
        row["customs_tariff_number"] = i.get("customs_tariff_number")

        row["supplier_sku"] = i.get("supplier_part_no")

        row["supplier_name"] = i.get("supplier")

        row["barcode"] = frappe.db.get_value("Item Barcode",
                                             {"parent": i.get("item_code")},
                                             "barcode")

        row["asi_item_class"] = i.get("asi_item_class")

        row["item_image"] = "<a target=" + str("_blank") + " href = " + str(
            i.get("image")) + "> " + str(i.get("image")) + " </a>"

        row["rate"] = get_item_details(i.get("item_code"), "Selling")
        # row["item_discontinued"] = i.get("disabled")
        row["date_last_received"] = get_date_last_received(
            i.get("item_code"), i.get("supplier"))
        row["item_cost"] = get_item_details(i.get("item_code"), "Buying",
                                            i.get("supplier"))

        row["wh_whs"] = get_qty(i.get("item_code"),
                                "W01-WHS-Active Stock - ICL") or 0
        row["wh_dtn"] = get_qty(i.get("item_code"),
                                "R05-DTN-Active Stock - ICL") or 0
        row["wh_queen"] = get_qty(i.get("item_code"),
                                  "R07-Queen-Active Stock - ICL") or 0
        row["wh_amb"] = get_qty(i.get("item_code"),
                                "R06-AMB-Active Stock - ICL") or 0
        row["wh_mon"] = get_qty(i.get("item_code"),
                                "R04-Mon-Active Stock - ICL") or 0
        row["wh_vic"] = get_qty(i.get("item_code"),
                                "R03-Vic-Active Stock - ICL") or 0
        row["wh_edm"] = get_qty(i.get("item_code"),
                                "R02-Edm-Active Stock - ICL") or 0
        row["wh_gor"] = get_qty(i.get("item_code"),
                                "R01-Gor-Active Stock - ICL") or 0

        row["total_actual_qty"] = (row.get("wh_whs") or 0) + (
            row.get("wh_dtn") or 0) + (row.get("wh_queen") or 0) + (
                row.get("wh_amb") or 0) + (row.get("wh_mon") or 0) + (
                    row.get("wh_vic") or 0) + (row.get("wh_edm")
                                               or 0) + (row.get("wh_gor") or 0)
        row["material_request"] = get_open_material_request(i.get("item_code"))
        row["tag"] = get_tags(i.get("item_code"))
        expected_pos = get_purchase_orders(i.get("item_code"),
                                           i.get("supplier"))
        row["expected_pos"] = expected_pos
        row["po_eta"] = get_last_purchase_orders(i.get("item_code"),
                                                 i.get("supplier"))
        ordered_qty = get_open_po_qty(i.get("item_code"), i.get("supplier"))
        row["ordered_qty"] = ordered_qty or 0.0
        row["last_sold_date"] = get_date_last_sold(i.get("item_code"))
        sales_data = get_total_sold(i.get("item_code"))
        row["previous_year_sale"] = 0
        row["total"] = 0
        row["last_twelve_months"] = 0

        today = getdate(nowdate())
        last_year = today.year - 1
        current_year = today.year

        last_month = getdate(str(datetime(today.year - 1, 1, 1)))
        while last_month <= today:
            month = last_month.strftime("%B")
            row[frappe.scrub("sold" + month + str(last_month.year))] = 0
            last_month = last_month + relativedelta(months=1)

        row["sold_last_ten_days"] = 0
        row["sold_last_thirty_days"] = 0
        row["sold_last_sixty_days"] = 0
        for d in sales_data:
            posting_date = getdate(d.get("posting_date"))
            qty = d.get("qty")
            month = posting_date.strftime("%B")
            if posting_date.year == last_year:
                row["previous_year_sale"] += qty
                row[frappe.scrub("sold" + month +
                                 str(posting_date.year))] += qty
            elif posting_date.year == current_year:
                row["total"] += qty
                row[frappe.scrub("sold" + month +
                                 str(posting_date.year))] += qty
            # if row.get(frappe.scrub("sold"+month+str(posting_date.year))):
            # 	row[frappe.scrub("sold"+month+str(posting_date.year))] += qty
            # row[frappe.scrub("soldjanuary2021")] += qty

            last12_month_date = today - relativedelta(years=1)
            if posting_date >= last12_month_date:
                row["last_twelve_months"] += qty

            sold_last_ten_days = today - timedelta(days=10)
            sold_last_thirty_days = today - timedelta(days=30)
            sold_last_sixty_days = today - timedelta(days=60)

            if posting_date >= sold_last_sixty_days:
                row["sold_last_sixty_days"] += qty
                if posting_date >= sold_last_thirty_days:
                    row["sold_last_thirty_days"] += qty
                    if posting_date >= sold_last_ten_days:
                        row["sold_last_ten_days"] += qty
        data.append(row)

    return columns, data
def get_columns(invoice_list, additional_table_columns):
    """return columns based on filters"""
    columns = [
        {
            'label': _("Invoice"),
            'fieldname': 'invoice',
            'fieldtype': 'Link',
            'options': 'Sales Invoice',
            'width': 120
        },
        {
            'label': _("Posting Date"),
            'fieldname': 'posting_date',
            'fieldtype': 'Date',
            'width': 80
        },
        {
            'label': _("Customer"),
            'fieldname': 'customer',
            'fieldtype': 'Link',
            'options': 'Customer',
            'width': 120
        },
        {
            'label': _("Customer Name"),
            'fieldname': 'customer_name',
            'fieldtype': 'Data',
            'width': 120
        },
    ]

    if additional_table_columns:
        columns += additional_table_columns

    columns += [{
        'label': _("Customer Group"),
        'fieldname': 'customer_group',
        'fieldtype': 'Link',
        'options': 'Customer Group',
        'width': 120
    }, {
        'label': _("Territory"),
        'fieldname': 'territory',
        'fieldtype': 'Link',
        'options': 'Territory',
        'width': 80
    }, {
        'label': _("Tax Id"),
        'fieldname': 'tax_id',
        'fieldtype': 'Data',
        'width': 120
    }, {
        'label': _("Receivable Account"),
        'fieldname': 'receivable_account',
        'fieldtype': 'Link',
        'options': 'Account',
        'width': 80
    }, {
        'label': _("Mode Of Payment"),
        'fieldname': 'mode_of_payment',
        'fieldtype': 'Data',
        'width': 120
    }, {
        'label': _("Project"),
        'fieldname': 'project',
        'fieldtype': 'Link',
        'options': 'Project',
        'width': 80
    }, {
        'label': _("Owner"),
        'fieldname': 'owner',
        'fieldtype': 'Data',
        'width': 150
    }, {
        'label': _("Remarks"),
        'fieldname': 'remarks',
        'fieldtype': 'Data',
        'width': 150
    }, {
        'label': _("Sales Order"),
        'fieldname': 'sales_order',
        'fieldtype': 'Link',
        'options': 'Sales Order',
        'width': 100
    }, {
        'label': _("Delivery Note"),
        'fieldname': 'delivery_note',
        'fieldtype': 'Link',
        'options': 'Delivery Note',
        'width': 100
    }, {
        'label': _("Cost Center"),
        'fieldname': 'cost_center',
        'fieldtype': 'Link',
        'options': 'Cost Center',
        'width': 100
    }, {
        'label': _("Warehouse"),
        'fieldname': 'warehouse',
        'fieldtype': 'Link',
        'options': 'Warehouse',
        'width': 100
    }, {
        "fieldname": "currency",
        "label": _("Currency"),
        "fieldtype": "Data",
        "width": 80
    }]

    income_accounts = []
    tax_accounts = []
    income_columns = []
    tax_columns = []
    unrealized_profit_loss_accounts = []
    unrealized_profit_loss_account_columns = []

    if invoice_list:
        income_accounts = frappe.db.sql_list(
            """select distinct income_account
			from `tabSales Invoice Item` where docstatus = 1 and parent in (%s)
			order by income_account""" % ', '.join(['%s'] * len(invoice_list)),
            tuple([inv.name for inv in invoice_list]))

        tax_accounts = frappe.db.sql_list(
            """select distinct account_head
			from `tabSales Taxes and Charges` where parenttype = 'Sales Invoice'
			and docstatus = 1 and base_tax_amount_after_discount_amount != 0
			and parent in (%s) order by account_head""" %
            ', '.join(['%s'] * len(invoice_list)),
            tuple([inv.name for inv in invoice_list]))

        unrealized_profit_loss_accounts = frappe.db.sql_list(
            """SELECT distinct unrealized_profit_loss_account
			from `tabSales Invoice` where docstatus = 1 and name in (%s)
			and ifnull(unrealized_profit_loss_account, '') != ''
			order by unrealized_profit_loss_account""" %
            ', '.join(['%s'] * len(invoice_list)),
            tuple([inv.name for inv in invoice_list]))

    for account in income_accounts:
        income_columns.append({
            "label": account,
            "fieldname": frappe.scrub(account),
            "fieldtype": "Currency",
            "options": "currency",
            "width": 120
        })

    for account in tax_accounts:
        if account not in income_accounts:
            tax_columns.append({
                "label": account,
                "fieldname": frappe.scrub(account),
                "fieldtype": "Currency",
                "options": "currency",
                "width": 120
            })

    for account in unrealized_profit_loss_accounts:
        unrealized_profit_loss_account_columns.append({
            "label":
            account,
            "fieldname":
            frappe.scrub(account),
            "fieldtype":
            "Currency",
            "options":
            "currency",
            "width":
            120
        })

    net_total_column = [{
        "label": _("Net Total"),
        "fieldname": "net_total",
        "fieldtype": "Currency",
        "options": "currency",
        "width": 120
    }]

    total_columns = [{
        "label": _("Tax Total"),
        "fieldname": "tax_total",
        "fieldtype": "Currency",
        "options": 'currency',
        "width": 120
    }, {
        "label": _("Grand Total"),
        "fieldname": "grand_total",
        "fieldtype": "Currency",
        "options": 'currency',
        "width": 120
    }, {
        "label": _("Rounded Total"),
        "fieldname": "rounded_total",
        "fieldtype": "Currency",
        "options": 'currency',
        "width": 120
    }, {
        "label": _("Outstanding Amount"),
        "fieldname": "outstanding_amount",
        "fieldtype": "Currency",
        "options": 'currency',
        "width": 120
    }]

    columns = columns + income_columns + unrealized_profit_loss_account_columns + \
     net_total_column + tax_columns + total_columns

    return columns, income_accounts, tax_accounts, unrealized_profit_loss_accounts
Example #51
0
 def set_discount_amount(self):
     if self.doc.additional_discount_percentage:
         self.doc.discount_amount = flt(
             flt(self.doc.get(scrub(self.doc.apply_discount_on))) *
             self.doc.additional_discount_percentage / 100,
             self.doc.precision("discount_amount"))
Example #52
0
	def set_preferred_email(self):
		preferred_email_field = frappe.scrub(self.prefered_contact_email)
		if preferred_email_field:
			preferred_email = self.get(preferred_email_field)
			self.prefered_email = preferred_email
def make_boilerplate(dest, app_name):
	if not os.path.exists(dest):
		print "Destination directory does not exist"
		return

	# app_name should be in snake_case
	app_name = frappe.scrub(app_name)

	hooks = frappe._dict()
	hooks.app_name = app_name
	app_title = hooks.app_name.replace("_", " ").title()
	for key in ("App Title (default: {0})".format(app_title),
		"App Description", "App Publisher", "App Email",
		"App Icon (default 'octicon octicon-file-directory')",
		"App Color (default 'grey')",
		"App License (default 'MIT')"):
		hook_key = key.split(" (")[0].lower().replace(" ", "_")
		hook_val = None
		while not hook_val:
			hook_val = cstr(raw_input(key + ": "))

			if not hook_val:
				defaults = {
					"app_title": app_title,
					"app_icon": "octicon octicon-file-directory",
					"app_color": "grey",
					"app_license": "MIT"
				}
				if hook_key in defaults:
					hook_val = defaults[hook_key]

			if hook_key=="app_name" and hook_val.lower().replace(" ", "_") != hook_val:
				print "App Name must be all lowercase and without spaces"
  				hook_val = ""
			elif hook_key=="app_title" and not re.match("^(?![\W])[^\d_\s][\w -]+$", hook_val, re.UNICODE):
				print "App Title should start with a letter and it can only consist of letters, numbers, spaces and underscores"
				hook_val = ""

		hooks[hook_key] = hook_val

	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, frappe.scrub(hooks.app_title)),
		with_init=True)
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates"), with_init=True)
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "www"))
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates",
		"pages"), with_init=True)
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates",
		"generators"), with_init=True)
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "templates",
		"includes"))
	frappe.create_folder(os.path.join(dest, hooks.app_name, hooks.app_name, "config"), with_init=True)

	with open(os.path.join(dest, hooks.app_name, hooks.app_name, "__init__.py"), "w") as f:
		f.write(encode(init_template))

	with open(os.path.join(dest, hooks.app_name, "MANIFEST.in"), "w") as f:
		f.write(encode(manifest_template.format(**hooks)))

	with open(os.path.join(dest, hooks.app_name, ".gitignore"), "w") as f:
		f.write(encode(gitignore_template.format(app_name = hooks.app_name)))

	with open(os.path.join(dest, hooks.app_name, "setup.py"), "w") as f:
		f.write(encode(setup_template.format(**hooks)))

	with open(os.path.join(dest, hooks.app_name, "requirements.txt"), "w") as f:
		f.write("frappe")

	with open(os.path.join(dest, hooks.app_name, "README.md"), "w") as f:
		f.write(encode("## {0}\n\n{1}\n\n#### License\n\n{2}".format(hooks.app_title,
			hooks.app_description, hooks.app_license)))

	with open(os.path.join(dest, hooks.app_name, "license.txt"), "w") as f:
		f.write(encode("License: " + hooks.app_license))

	with open(os.path.join(dest, hooks.app_name, hooks.app_name, "modules.txt"), "w") as f:
		f.write(encode(hooks.app_title))

	with open(os.path.join(dest, hooks.app_name, hooks.app_name, "hooks.py"), "w") as f:
		f.write(encode(hooks_template.format(**hooks)))

	touch_file(os.path.join(dest, hooks.app_name, hooks.app_name, "patches.txt"))

	with open(os.path.join(dest, hooks.app_name, hooks.app_name, "config", "desktop.py"), "w") as f:
		f.write(encode(desktop_template.format(**hooks)))

	with open(os.path.join(dest, hooks.app_name, hooks.app_name, "config", "docs.py"), "w") as f:
		f.write(encode(docs_template.format(**hooks)))

	print "'{app}' created at {path}".format(app=app_name, path=os.path.join(dest, app_name))
Example #54
0
def clear_doctype_map(doctype, name):
    cache_key = frappe.scrub(doctype) + '_map'
    frappe.cache().hdel(cache_key, name)
Example #55
0
def get_column(filters, conditions):
    columns = [
        {
            "label": _("RetailSkuSuffix"),
            "fieldname": "ifw_retailskusuffix",
            "fieldtype": "Data",
            "width": 150,
        },
        {
            "label": "ERPNextItemCode",
            "options": "Item",
            "fieldname": "item_code",
            "fieldtype": "Link",
            "width": 150,
            "align": "left",
        },
        {
            "label": _("Barcode"),
            "fieldname": "barcode",
            "fieldtype": "Data",
            "width": 150,
            "align": "left",
        },
        {
            "label": _("ItemClass"),
            "fieldname": "asi_item_class",
            "fieldtype": "Data",
            "width": 150,
            "align": "left",
        },
        {
            "label": _("ItemName"),
            "fieldname": "item_name",
            "fieldtype": "Data",
            "width": 300,
        },
        {
            "label": _("ItemImage"),
            "fieldname": "item_image",
            "fieldtype": "Data",
            "width": 200,
        },
        {
            "label": _("Duty rate"),
            "fieldname": "ifw_duty_rate",
            "fieldtype": "Float",
            "width": 100,
        },
        {
            "label": _("Discontinued"),
            "fieldname": "ifw_discontinued",
            "fieldtype": "Check",
            "width": 100,
        },
        {
            "label": _("ProductNameCI"),
            "fieldname": "ifw_product_name_ci",
            "fieldtype": "Data",
            "width": 100,
        },
        {
            "label": _("Item Notes"),
            "fieldname": "ifw_item_notes",
            "fieldtype": "Data",
            "width": 100,
        },
        {
            "label": _("Item Notes2"),
            "fieldname": "ifw_item_notes2",
            "fieldtype": "Data",
            "width": 100,
        },
        {
            "label": _("PONotes"),
            "fieldname": "ifw_po_notes",
            "fieldtype": "Data",
            "width": 100,
        },
        {
            "label": _("Country of Origin"),
            "fieldname": "country_of_origin",
            "fieldtype": "Link",
            "options": "Country",
            "width": 100,
        },
        {
            "label": _("HS Code"),
            "fieldname": "customs_tariff_number",
            "fieldtype": "Link",
            "options": "Customs Tariff Number",
            "width": 100,
        },
        {
            "label": _("Tags"),
            "fieldname": "tag",
            "fieldtype": "Data",
            "width": 100,
        },
        {
            "label": _("Rate"),
            "fieldname": "rate",
            "fieldtype": "Currency",
            "width": 100,
        },
        # {
        # 	"label": _("Discointinued"),
        # 	"fieldname": "item_discontinued",
        # 	"fieldtype": "Boolean",
        # 	"width": 100,
        # 	"default": False,
        # },
        {
            "label": _("ETA"),
            "fieldname": "eta",
            "fieldtype": "Date",
            "width": 100,
        },
        {
            "label": _("DateLastReceived"),
            "fieldname": "date_last_received",
            "fieldtype": "DateTime",
            "width": 200,
        },
        {
            "label": _("Cost"),
            "fieldname": "item_cost",
            "fieldtype": "Currency",
            "width": 100,
        },
        {
            "label": _("Suplier SKU"),
            "fieldname": "supplier_sku",
            "fieldtype": "Data",
            "width": 100,
        },
        {
            "label": _("Supplier Name"),
            "fieldname": "supplier_name",
            "fieldtype": "Link",
            "options": "Supplier",
            "width": 200,
        },
        {
            "label": _("W01-WHS-Active Stock - ICL"),
            "fieldname": "wh_whs",
            "fieldtype": "Int",
            "width": 200,
        },
        {
            "label": _("R05-DTN-Active Stock - ICL"),
            "fieldname": "wh_dtn",
            "fieldtype": "Int",
            "width": 200,
        },
        {
            "label": _("R07-Queen-Active Stock - ICL"),
            "fieldname": "wh_queen",
            "fieldtype": "Int",
            "width": 200,
        },
        {
            "label": _("R06-AMB-Active Stock - ICL"),
            "fieldname": "wh_amb",
            "fieldtype": "Int",
            "width": 200,
        },
        {
            "label": _("R04-Mon-Active Stock - ICL"),
            "fieldname": "wh_mon",
            "fieldtype": "Int",
            "width": 200,
        },
        {
            "label": _("R03-Vic-Active Stock - ICL"),
            "fieldname": "wh_vic",
            "fieldtype": "Int",
            "width": 200,
        },
        {
            "label": _("R02-Edm-Active Stock - ICL"),
            "fieldname": "wh_edm",
            "fieldtype": "Int",
            "width": 200,
        },
        {
            "label": _("R01-Gor-Active Stock - ICL"),
            "fieldname": "wh_gor",
            "fieldtype": "Int",
            "width": 200,
        },
        {
            "label": _("TotalQOH"),
            "fieldname": "total_actual_qty",
            "fieldtype": "Int",
            "width": 140,
        },
        {
            "label": _("Material Request"),
            "fieldname": "material_request",
            "fieldtype": "Data",
            "width": 200,
        },
        {
            "label": _("Expected PO Nos"),
            "fieldname": "expected_pos",
            "fieldtype": "Data",
            "width": 240,
        },
        {
            "label": _("ETA date PO"),
            "fieldname": "po_eta",
            "fieldtype": "Data",
            "width": 200,
        },
        {
            "label": _("OrderedQty"),
            "fieldname": "ordered_qty",
            "fieldtype": "Float",
            "width": 120,
        },
        {
            "label": _("PreviousYSale"),
            "fieldname": "previous_year_sale",
            "fieldtype": "Int",
            "width": 140,
        },
        {
            "label": _("CurrentYearSales"),
            "fieldname": "total",
            "fieldtype": "Int",
            "width": 140,
        },
        {
            "label": _("TotalSold12Months"),
            "fieldname": "last_twelve_months",
            "fieldtype": "Int",
            "width": 140,
        }
    ]
    today = getdate(nowdate())
    last_month = getdate(str(datetime(today.year - 1, today.month, 1)))
    while last_month <= today:
        month = last_month.strftime("%B")
        columns.append({
            "label":
            _(str(last_month.year) + "_Sold" + month),
            "fieldname":
            frappe.scrub("sold" + month + str(last_month.year)),
            "fieldtype":
            "Int",
            "width":
            140,
        })
        last_month = last_month + relativedelta(months=1)

    columns.extend([{
        "label": _("SoldLast10Days"),
        "fieldname": "sold_last_ten_days",
        "fieldtype": "Int",
        "width": 140,
    }, {
        "label": _("SoldLast30Days"),
        "fieldname": "sold_last_thirty_days",
        "fieldtype": "Int",
        "width": 140,
    }, {
        "label": _("SoldLast60Days"),
        "fieldname": "sold_last_sixty_days",
        "fieldtype": "Int",
        "width": 140,
        "default": False,
    }, {
        "label": _("DateLastSold"),
        "fieldname": "last_sold_date",
        "fieldtype": "Data",
        "width": 100,
    }])
    return columns
Example #56
0
def get_columns(filters, period_list, partner_doctype):
	fieldtype, options = "Currency", "currency"

	if filters.get("target_on") == 'Quantity':
		fieldtype, options = "Float", ""

	columns = [{
		"fieldname": frappe.scrub(partner_doctype),
		"label": _(partner_doctype),
		"fieldtype": "Link",
		"options": partner_doctype,
		"width": 100
	}, {
		"fieldname": "item_group",
		"label": _("Item Group"),
		"fieldtype": "Link",
		"options": "Item Group",
		"width": 100
	}]

	for period in period_list:
		target_key = 'target_{}'.format(period.key)
		variance_key = 'variance_{}'.format(period.key)

		columns.extend([{
			"fieldname": target_key,
			"label": _("Target ({})").format(period.label),
			"fieldtype": fieldtype,
			"options": options,
			"width": 100
		}, {
			"fieldname": period.key,
			"label": _("Achieved ({})").format(period.label),
			"fieldtype": fieldtype,
			"options": options,
			"width": 100
		}, {
			"fieldname": variance_key,
			"label": _("Variance ({})").format(period.label),
			"fieldtype": fieldtype,
			"options": options,
			"width": 100
		}])

	columns.extend([{
		"fieldname": "total_target",
		"label": _("Total Target"),
		"fieldtype": fieldtype,
		"options": options,
		"width": 100
	}, {
		"fieldname": "total_achieved",
		"label": _("Total Achieved"),
		"fieldtype": fieldtype,
		"options": options,
		"width": 100
	}, {
		"fieldname": "total_variance",
		"label": _("Total Variance"),
		"fieldtype": fieldtype,
		"options": options,
		"width": 100
	}])

	return columns
Example #57
0
def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None):
	doc = frappe.get_doc(dt, dn)
	if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
		frappe.throw(_("Can only make payment against unbilled {0}").format(dt))

	if dt in ("Sales Invoice", "Sales Order"):
		party_type = "Customer"
	elif dt in ("Purchase Invoice", "Purchase Order"):
		party_type = "Supplier"
	elif dt in ("Expense Claim", "Employee Advance"):
		party_type = "Employee"
	elif dt in ("Fees"):
		party_type = "Student"

	# party account
	if dt == "Sales Invoice":
		party_account = get_party_account_based_on_invoice_discounting(dn) or doc.debit_to
	elif dt == "Purchase Invoice":
		party_account = doc.credit_to
	elif dt == "Fees":
		party_account = doc.receivable_account
	elif dt == "Employee Advance":
		party_account = doc.advance_account
	elif dt == "Expense Claim":
		party_account = doc.payable_account
	else:
		party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)

	if dt not in ("Sales Invoice", "Purchase Invoice"):
		party_account_currency = get_account_currency(party_account)
	else:
		party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)

	# payment type
	if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \
		or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
			payment_type = "Receive"
	else:
		payment_type = "Pay"

	# amounts
	grand_total = outstanding_amount = 0
	if party_amount:
		grand_total = outstanding_amount = party_amount
	elif dt in ("Sales Invoice", "Purchase Invoice"):
		if party_account_currency == doc.company_currency:
			grand_total = doc.base_rounded_total or doc.base_grand_total
		else:
			grand_total = doc.rounded_total or doc.grand_total
		outstanding_amount = doc.outstanding_amount
	elif dt in ("Expense Claim"):
		grand_total = doc.total_sanctioned_amount + doc.total_taxes_and_charges
		outstanding_amount = doc.grand_total \
			- doc.total_amount_reimbursed
	elif dt == "Employee Advance":
		grand_total = doc.advance_amount
		outstanding_amount = flt(doc.advance_amount) - flt(doc.paid_amount)
	elif dt == "Fees":
		grand_total = doc.grand_total
		outstanding_amount = doc.outstanding_amount
	else:
		if party_account_currency == doc.company_currency:
			grand_total = flt(doc.get("base_rounded_total") or doc.base_grand_total)
		else:
			grand_total = flt(doc.get("rounded_total") or doc.grand_total)
		outstanding_amount = grand_total - flt(doc.advance_paid)

	# bank or cash
	bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"),
		account=bank_account)

	if not bank:
		bank = get_default_bank_cash_account(doc.company, "Cash", mode_of_payment=doc.get("mode_of_payment"),
			account=bank_account)

	paid_amount = received_amount = 0
	if party_account_currency == bank.account_currency:
		paid_amount = received_amount = abs(outstanding_amount)
	elif payment_type == "Receive":
		paid_amount = abs(outstanding_amount)
		if bank_amount:
			received_amount = bank_amount
		else:
			received_amount = paid_amount * doc.conversion_rate
	else:
		received_amount = abs(outstanding_amount)
		if bank_amount:
			paid_amount = bank_amount
		else:
			# if party account currency and bank currency is different then populate paid amount as well
			paid_amount = received_amount * doc.conversion_rate

	pe = frappe.new_doc("Payment Entry")
	pe.payment_type = payment_type
	pe.company = doc.company
	pe.cost_center = doc.get("cost_center")
	pe.posting_date = nowdate()
	pe.mode_of_payment = doc.get("mode_of_payment")
	pe.party_type = party_type
	pe.party = doc.get(scrub(party_type))
	pe.contact_person = doc.get("contact_person")
	pe.contact_email = doc.get("contact_email")
	pe.ensure_supplier_is_not_blocked()

	pe.paid_from = party_account if payment_type=="Receive" else bank.account
	pe.paid_to = party_account if payment_type=="Pay" else bank.account
	pe.paid_from_account_currency = party_account_currency \
		if payment_type=="Receive" else bank.account_currency
	pe.paid_to_account_currency = party_account_currency if payment_type=="Pay" else bank.account_currency
	pe.paid_amount = paid_amount
	pe.received_amount = received_amount
	pe.letter_head = doc.get("letter_head")

	if pe.party_type in ["Customer", "Supplier"]:
		bank_account = get_party_bank_account(pe.party_type, pe.party)
		pe.set("bank_account", bank_account)
		pe.set_bank_account_data()

	# only Purchase Invoice can be blocked individually
	if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked():
		frappe.msgprint(_('{0} is on hold till {1}').format(doc.name, doc.release_date))
	else:
		if (doc.doctype in ('Sales Invoice', 'Purchase Invoice')
			and frappe.get_value('Payment Terms Template',
			{'name': doc.payment_terms_template}, 'allocate_payment_based_on_payment_terms')):

			for reference in get_reference_as_per_payment_terms(doc.payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
				pe.append('references', reference)
		else:
			pe.append("references", {
				'reference_doctype': dt,
				'reference_name': dn,
				"bill_no": doc.get("bill_no"),
				"due_date": doc.get("due_date"),
				'total_amount': grand_total,
				'outstanding_amount': outstanding_amount,
				'allocated_amount': outstanding_amount
			})

	pe.setup_party_account_field()
	pe.set_missing_values()
	if party_account and bank:
		pe.set_exchange_rate()
		pe.set_amounts()
	return pe
Example #58
0
    def get_columns(self, party_naming_by, args):
        columns = [
            _(args.get("party_type")) + ":Link/" + args.get("party_type") +
            ":200"
        ]

        if party_naming_by == "Naming Series":
            columns += [args.get("party_type") + " Name::140"]

        credit_debit_label = "Credit Note Amt" if args.get(
            'party_type') == 'Customer' else "Debit Note Amt"

        columns += [{
            "label": _("Advance Amount"),
            "fieldname": "advance_amount",
            "fieldtype": "Currency",
            "options": "currency",
            "width": 100
        }, {
            "label": _("Total Invoiced Amt"),
            "fieldname": "total_invoiced_amt",
            "fieldtype": "Currency",
            "options": "currency",
            "width": 100
        }, {
            "label": _("Total Paid Amt"),
            "fieldname": "total_paid_amt",
            "fieldtype": "Currency",
            "options": "currency",
            "width": 100
        }]

        columns += [{
            "label": _(credit_debit_label),
            "fieldname": scrub(credit_debit_label),
            "fieldtype": "Currency",
            "options": "currency",
            "width": 140
        }, {
            "label": _("Total Outstanding Amt"),
            "fieldname": "total_outstanding_amt",
            "fieldtype": "Currency",
            "options": "currency",
            "width": 160
        }, {
            "label": _("0-" + str(self.filters.range1)),
            "fieldname": scrub("0-" + str(self.filters.range1)),
            "fieldtype": "Currency",
            "options": "currency",
            "width": 160
        }, {
            "label":
            _(str(self.filters.range1) + "-" + str(self.filters.range2)),
            "fieldname":
            scrub(str(self.filters.range1) + "-" + str(self.filters.range2)),
            "fieldtype":
            "Currency",
            "options":
            "currency",
            "width":
            160
        }, {
            "label":
            _(str(self.filters.range2) + "-" + str(self.filters.range3)),
            "fieldname":
            scrub(str(self.filters.range2) + "-" + str(self.filters.range3)),
            "fieldtype":
            "Currency",
            "options":
            "currency",
            "width":
            160
        }, {
            "label": _(str(self.filters.range3) + _("-Above")),
            "fieldname": scrub(str(self.filters.range3) + _("-Above")),
            "fieldtype": "Currency",
            "options": "currency",
            "width": 160
        }]

        if args.get("party_type") == "Customer":
            columns += [{
                "label": _("Territory"),
                "fieldname": "territory",
                "fieldtype": "Link",
                "options": "Territory",
                "width": 80
            }, {
                "label": _("Customer Group"),
                "fieldname": "customer_group",
                "fieldtype": "Link",
                "options": "Customer Group",
                "width": 80
            }, {
                "label": _("Sales Person"),
                "fieldtype": "Data",
                "fieldname": "sales_person",
                "width": 120,
            }]

        if args.get("party_type") == "Supplier":
            columns += [{
                "label": _("Supplier Group"),
                "fieldname": "supplier_group",
                "fieldtype": "Link",
                "options": "Supplier Group",
                "width": 80
            }]

        columns.append({
            "fieldname": "currency",
            "label": _("Currency"),
            "fieldtype": "Link",
            "options": "Currency",
            "width": 80
        })

        return columns
def get_tax_accounts(
	item_list,
	columns,
	company_currency,
	doctype="Sales Invoice",
	tax_doctype="Sales Taxes and Charges",
):
	import json

	item_row_map = {}
	tax_columns = []
	invoice_item_row = {}
	itemised_tax = {}

	tax_amount_precision = (
		get_field_precision(
			frappe.get_meta(tax_doctype).get_field("tax_amount"), currency=company_currency
		)
		or 2
	)

	for d in item_list:
		invoice_item_row.setdefault(d.parent, []).append(d)
		item_row_map.setdefault(d.parent, {}).setdefault(d.item_code or d.item_name, []).append(d)

	conditions = ""
	if doctype == "Purchase Invoice":
		conditions = " and category in ('Total', 'Valuation and Total') and base_tax_amount_after_discount_amount != 0"

	deducted_tax = get_deducted_taxes()
	tax_details = frappe.db.sql(
		"""
		select
			name, parent, description, item_wise_tax_detail,
			charge_type, base_tax_amount_after_discount_amount
		from `tab%s`
		where
			parenttype = %s and docstatus = 1
			and (description is not null and description != '')
			and parent in (%s)
			%s
		order by description
	"""
		% (tax_doctype, "%s", ", ".join(["%s"] * len(invoice_item_row)), conditions),
		tuple([doctype] + list(invoice_item_row)),
	)

	for name, parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
		description = handle_html(description)
		if description not in tax_columns and tax_amount:
			# as description is text editor earlier and markup can break the column convention in reports
			tax_columns.append(description)

		if item_wise_tax_detail:
			try:
				item_wise_tax_detail = json.loads(item_wise_tax_detail)

				for item_code, tax_data in item_wise_tax_detail.items():
					itemised_tax.setdefault(item_code, frappe._dict())

					if isinstance(tax_data, list):
						tax_rate, tax_amount = tax_data
					else:
						tax_rate = tax_data
						tax_amount = 0

					if charge_type == "Actual" and not tax_rate:
						tax_rate = "NA"

					item_net_amount = sum(
						[flt(d.base_net_amount) for d in item_row_map.get(parent, {}).get(item_code, [])]
					)

					for d in item_row_map.get(parent, {}).get(item_code, []):
						item_tax_amount = (
							flt((tax_amount * d.base_net_amount) / item_net_amount) if item_net_amount else 0
						)
						if item_tax_amount:
							tax_value = flt(item_tax_amount, tax_amount_precision)
							tax_value = (
								tax_value * -1 if (doctype == "Purchase Invoice" and name in deducted_tax) else tax_value
							)

							itemised_tax.setdefault(d.name, {})[description] = frappe._dict(
								{"tax_rate": tax_rate, "tax_amount": tax_value}
							)

			except ValueError:
				continue
		elif charge_type == "Actual" and tax_amount:
			for d in invoice_item_row.get(parent, []):
				itemised_tax.setdefault(d.name, {})[description] = frappe._dict(
					{
						"tax_rate": "NA",
						"tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total, tax_amount_precision),
					}
				)

	tax_columns.sort()
	for desc in tax_columns:
		columns.append(
			{
				"label": _(desc + " Rate"),
				"fieldname": frappe.scrub(desc + " Rate"),
				"fieldtype": "Float",
				"width": 100,
			}
		)

		columns.append(
			{
				"label": _(desc + " Amount"),
				"fieldname": frappe.scrub(desc + " Amount"),
				"fieldtype": "Currency",
				"options": "currency",
				"width": 100,
			}
		)

	columns += [
		{
			"label": _("Total Tax"),
			"fieldname": "total_tax",
			"fieldtype": "Currency",
			"options": "currency",
			"width": 100,
		},
		{
			"label": _("Total"),
			"fieldname": "total",
			"fieldtype": "Currency",
			"options": "currency",
			"width": 100,
		},
		{
			"fieldname": "currency",
			"label": _("Currency"),
			"fieldtype": "Currency",
			"width": 80,
			"hidden": 1,
		},
	]

	return itemised_tax, tax_columns
Example #60
0
def get_report_module_dotted_path(module, report_name):
    return frappe.local.module_app[scrub(module)] + "." + scrub(module) \
     + ".report." + scrub(report_name) + "." + scrub(report_name)