def _execute(filters=None):
	if not filters: filters = {}
	columns = get_columns()

	company_currency = erpnext.get_company_currency(filters.company)
	item_list = get_items(filters)
	if item_list:
		itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)

	data = []
	for d in item_list:
		row = [d.gst_hsn_code, d.description, d.stock_uom, d.stock_qty]
		total_tax = 0
		for tax in tax_columns:
			item_tax = itemised_tax.get(d.name, {}).get(tax, {})
			total_tax += flt(item_tax.get("tax_amount"))

		row += [d.base_net_amount + total_tax]
		row += [d.base_net_amount]

		for tax in tax_columns:
			item_tax = itemised_tax.get(d.name, {}).get(tax, {})
			row += [item_tax.get("tax_amount", 0)]

		data.append(row)
	if data:
		data = get_merged_data(columns, data) # merge same hsn code data
	return columns, data
Пример #2
0
def get_itemised_tax_breakup_html(doc):
	if not doc.taxes:
		return
	frappe.flags.company = doc.company
	
	# get headers
	tax_accounts = []
	for tax in doc.taxes:
		if getattr(tax, "category", None) and tax.category=="Valuation":
			continue
		if tax.description not in tax_accounts:
			tax_accounts.append(tax.description)

	headers = get_itemised_tax_breakup_header(doc.doctype + " Item", tax_accounts)
	
	# get tax breakup data
	itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(doc)

	get_rounded_tax_amount(itemised_tax, doc.precision("tax_amount", "taxes"))

	frappe.flags.company = None
	
	return frappe.render_template(
		"templates/includes/itemised_tax_breakup.html", dict(
			headers=headers,
			itemised_tax=itemised_tax,
			itemised_taxable_amount=itemised_taxable_amount,
			tax_accounts=tax_accounts,
			company_currency=erpnext.get_company_currency(doc.company)
		)
	)
Пример #3
0
	def get_serialized_values(self, sle):
		incoming_rate = flt(sle.incoming_rate)
		actual_qty = flt(sle.actual_qty)
		serial_no = cstr(sle.serial_no).split("\n")

		if incoming_rate < 0:
			# wrong incoming rate
			incoming_rate = self.valuation_rate

		stock_value_change = 0
		if incoming_rate:
			stock_value_change = actual_qty * incoming_rate
		elif actual_qty < 0:
			# In case of delivery/stock issue, get average purchase rate
			# of serial nos of current entry
			stock_value_change = -1 * flt(frappe.db.sql("""select sum(purchase_rate)
				from `tabSerial No` where name in (%s)""" % (", ".join(["%s"]*len(serial_no))),
				tuple(serial_no))[0][0])

		new_stock_qty = self.qty_after_transaction + actual_qty
		if new_stock_qty > 0:
			new_stock_value = (self.qty_after_transaction * self.valuation_rate) + stock_value_change
			if new_stock_value > 0:
				# calculate new valuation rate only if stock value is positive
				# else it remains the same as that of previous entry
				self.valuation_rate = new_stock_value / new_stock_qty

		if not self.valuation_rate and sle.voucher_detail_no:
			allow_zero_rate = self.check_if_allow_zero_valuation_rate(sle.voucher_type, sle.voucher_detail_no)
			if not allow_zero_rate:
				self.valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse,
					sle.voucher_type, sle.voucher_no, self.allow_zero_rate,
					currency=erpnext.get_company_currency(sle.company))
Пример #4
0
def get_incoming_rate(args):
	"""Get Incoming Rate based on valuation method"""
	from erpnext.stock.stock_ledger import get_previous_sle, get_valuation_rate
	if isinstance(args, basestring):
		args = json.loads(args)

	in_rate = 0
	if (args.get("serial_no") or "").strip():
		in_rate = get_avg_purchase_rate(args.get("serial_no"))
	else:
		valuation_method = get_valuation_method(args.get("item_code"))
		previous_sle = get_previous_sle(args)
		if valuation_method == 'FIFO':
			if previous_sle:
				previous_stock_queue = json.loads(previous_sle.get('stock_queue', '[]') or '[]')
				in_rate = get_fifo_rate(previous_stock_queue, args.get("qty") or 0) if previous_stock_queue else 0
		elif valuation_method == 'Moving Average':
			in_rate = previous_sle.get('valuation_rate') or 0

	if not in_rate:
		voucher_no = args.get('voucher_no') or args.get('name')
		in_rate = get_valuation_rate(args.get('item_code'), args.get('warehouse'),
			args.get('voucher_type'), voucher_no, args.get('allow_zero_valuation'),
			currency=erpnext.get_company_currency(args.get('company')), company=args.get('company'))

	return in_rate
Пример #5
0
def validate_quantity(doc, args, ref, valid_items, already_returned_items):
	fields = ['stock_qty']
	if doc.doctype in ['Purchase Receipt', 'Purchase Invoice']:
		fields.extend(['received_qty', 'rejected_qty'])

	already_returned_data = already_returned_items.get(args.item_code) or {}

	company_currency = erpnext.get_company_currency(doc.company)
	stock_qty_precision = get_field_precision(frappe.get_meta(doc.doctype + " Item")
			.get_field("stock_qty"), company_currency)

	for column in fields:
		returned_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0

		if column == 'stock_qty':
			reference_qty = ref.get(column)
			current_stock_qty = args.get(column)
		else:
			reference_qty = ref.get(column) * ref.get("conversion_factor", 1.0)
			current_stock_qty = args.get(column) * args.get("conversion_factor", 1.0)

		max_returnable_qty = flt(reference_qty, stock_qty_precision) - returned_qty
		label = column.replace('_', ' ').title()

		if reference_qty:
			if flt(args.get(column)) > 0:
				frappe.throw(_("{0} must be negative in return document").format(label))
			elif returned_qty >= reference_qty and args.get(column):
				frappe.throw(_("Item {0} has already been returned")
					.format(args.item_code), StockOverReturnError)
			elif abs(flt(current_stock_qty, stock_qty_precision)) > max_returnable_qty:
				frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
					.format(args.idx, max_returnable_qty, args.item_code), StockOverReturnError)
Пример #6
0
def get_price_list_currency_and_exchange_rate(args):
	if not args.price_list:
		return {}

	if args.doctype in ['Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice']:
		args.update({"exchange_rate": "for_selling"})
	elif args.doctype in ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice']:
		args.update({"exchange_rate": "for_buying"})

	price_list_currency = get_price_list_currency(args.price_list)
	price_list_uom_dependant = get_price_list_uom_dependant(args.price_list)
	plc_conversion_rate = args.plc_conversion_rate
	company_currency = get_company_currency(args.company)

	if (not plc_conversion_rate) or (price_list_currency and args.price_list_currency \
		and price_list_currency != args.price_list_currency):
			# cksgb 19/09/2016: added args.transaction_date as posting_date argument for get_exchange_rate
			plc_conversion_rate = get_exchange_rate(price_list_currency, company_currency,
				args.transaction_date, args.exchange_rate) or plc_conversion_rate

	return frappe._dict({
		"price_list_currency": price_list_currency,
		"price_list_uom_dependant": price_list_uom_dependant,
		"plc_conversion_rate": plc_conversion_rate
	})
Пример #7
0
def _get_party_details(party=None, account=None, party_type="Customer", company=None, posting_date=None,
	price_list=None, currency=None, doctype=None, ignore_permissions=False, fetch_payment_terms_template=True):

	out = frappe._dict(set_account_and_due_date(party, account, party_type, company, posting_date, doctype))

	party = out[party_type.lower()]

	if not ignore_permissions and not frappe.has_permission(party_type, "read", party):
		frappe.throw(_("Not permitted for {0}").format(party), frappe.PermissionError)

	party = frappe.get_doc(party_type, party)
	currency = party.default_currency if party.default_currency else get_company_currency(company)

	set_address_details(out, party, party_type, doctype, company)
	set_contact_details(out, party, party_type)
	set_other_values(out, party, party_type)
	set_price_list(out, party, party_type, price_list)
	out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group, out.supplier_type)

	if fetch_payment_terms_template:
		out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company)

	if not out.get("currency"):
		out["currency"] = currency

	# sales team
	if party_type=="Customer":
		out["sales_team"] = [{
			"sales_person": d.sales_person,
			"allocated_percentage": d.allocated_percentage or None
		} for d in party.get("sales_team")]

	return out
Пример #8
0
	def validate_overlapping_shipping_rule_conditions(self):
		def overlap_exists_between(num_range1, num_range2):
			"""
				num_range1 and num_range2 are two ranges
				ranges are represented as a tuple e.g. range 100 to 300 is represented as (100, 300)
				if condition num_range1 = 100 to 300
				then condition num_range2 can only be like 50 to 99 or 301 to 400
				hence, non-overlapping condition = (x1 <= x2 < y1 <= y2) or (y1 <= y2 < x1 <= x2)
			"""
			(x1, x2), (y1, y2) = num_range1, num_range2
			separate = (x1 <= x2 <= y1 <= y2) or (y1 <= y2 <= x1 <= x2)
			return (not separate)

		overlaps = []
		for i in xrange(0, len(self.conditions)):
			for j in xrange(i+1, len(self.conditions)):
				d1, d2 = self.conditions[i], self.conditions[j]
				if d1.as_dict() != d2.as_dict():
					# in our case, to_value can be zero, hence pass the from_value if so
					range_a = (d1.from_value, d1.to_value or d1.from_value)
					range_b = (d2.from_value, d2.to_value or d2.from_value)
					if overlap_exists_between(range_a, range_b):
						overlaps.append([d1, d2])

		if overlaps:
			company_currency = erpnext.get_company_currency(self.company)
			msgprint(_("Overlapping conditions found between:"))
			messages = []
			for d1, d2 in overlaps:
				messages.append("%s-%s = %s " % (d1.from_value, d1.to_value, fmt_money(d1.shipping_amount, currency=company_currency)) +
					_("and") + " %s-%s = %s" % (d2.from_value, d2.to_value, fmt_money(d2.shipping_amount, currency=company_currency)))

			msgprint("\n".join(messages), raise_exception=OverlappingConditionError)
	def get_accounts_data(self, account=None):
		accounts = []
		self.validate_mandatory()
		company_currency = erpnext.get_company_currency(self.company)
		precision = get_field_precision(frappe.get_meta("Exchange Rate Revaluation Account")
			.get_field("new_balance_in_base_currency"), company_currency)
		for d in self.get_accounts_from_gle():
			
			current_exchange_rate = d.balance / d.balance_in_account_currency \
				if d.balance_in_account_currency else 0
			new_exchange_rate = get_exchange_rate(d.account_currency, company_currency, self.posting_date)
			new_balance_in_base_currency = flt(d.balance_in_account_currency * new_exchange_rate)
			gain_loss = flt(new_balance_in_base_currency, precision) - flt(d.balance, precision)
			if gain_loss:
				accounts.append({
					"account": d.account,
					"party_type": d.party_type,
					"party": d.party,
					"account_currency": d.account_currency,
					"balance_in_base_currency": d.balance,
					"balance_in_account_currency": d.balance_in_account_currency,
					"current_exchange_rate": current_exchange_rate,
					"new_exchange_rate": new_exchange_rate,
					"new_balance_in_base_currency": new_balance_in_base_currency
				})
		return accounts
Пример #10
0
	def get_accounts_from_gle(self):
		company_currency = erpnext.get_company_currency(self.company)
		accounts = frappe.db.sql_list("""
			select name
			from tabAccount
			where is_group = 0
				and report_type = 'Balance Sheet'
				and root_type in ('Asset', 'Liability', 'Equity')
				and account_type != 'Stock'
				and company=%s
				and account_currency != %s
			order by name""",(self.company, company_currency))

		account_details = []
		if accounts:
			account_details = frappe.db.sql("""
				select
					account, party_type, party, account_currency,
					sum(debit_in_account_currency) - sum(credit_in_account_currency) as balance_in_account_currency,
					sum(debit) - sum(credit) as balance
				from `tabGL Entry`
				where account in (%s)
				group by account, party_type, party
				having sum(debit) != sum(credit)
				order by account
			""" % ', '.join(['%s']*len(accounts)), tuple(accounts), as_dict=1)

		return account_details
Пример #11
0
def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None):
	"""Returns dict of account balance and party type to be set in Journal Entry on selection of account."""
	if not frappe.has_permission("Account"):
		frappe.msgprint(_("No Permission"), raise_exception=1)

	company_currency = erpnext.get_company_currency(company)
	account_details = frappe.db.get_value("Account", account, ["account_type", "account_currency"], as_dict=1)

	if not account_details:
		return

	if account_details.account_type == "Receivable":
		party_type = "Customer"
	elif account_details.account_type == "Payable":
		party_type = "Supplier"
	else:
		party_type = ""

	grid_values = {
		"balance": get_balance_on(account, date),
		"party_type": party_type,
		"account_type": account_details.account_type,
		"account_currency": account_details.account_currency or company_currency,

		# The date used to retreive the exchange rate here is the date passed in
		# as an argument to this function. It is assumed to be the date on which the balance is sought
		"exchange_rate": get_exchange_rate(date, account, account_details.account_currency,
			company, debit=debit, credit=credit, exchange_rate=exchange_rate)
	}

	# un-set party if not party type
	if not party_type:
		grid_values["party"] = ""

	return grid_values
Пример #12
0
def get_exchange_rate(posting_date, account=None, account_currency=None, company=None,
		reference_type=None, reference_name=None, debit=None, credit=None, exchange_rate=None):
	from erpnext.setup.utils import get_exchange_rate
	account_details = frappe.db.get_value("Account", account,
		["account_type", "root_type", "account_currency", "company"], as_dict=1)

	if not account_details:
		frappe.throw(_("Please select correct account"))

	if not company:
		company = account_details.company

	if not account_currency:
		account_currency = account_details.account_currency

	company_currency = erpnext.get_company_currency(company)

	if account_currency != company_currency:
		if reference_type in ("Sales Invoice", "Purchase Invoice") and reference_name:
			exchange_rate = frappe.db.get_value(reference_type, reference_name, "conversion_rate")

		elif account_details and account_details.account_type == "Bank" and \
			((account_details.root_type == "Asset" and flt(credit) > 0) or
				(account_details.root_type == "Liability" and debit)):
			exchange_rate = get_average_exchange_rate(account)

		# The date used to retreive the exchange rate here is the date passed
		# in as an argument to this function.
		if not exchange_rate and account_currency and posting_date:
			exchange_rate = get_exchange_rate(account_currency, company_currency, posting_date)
	else:
		exchange_rate = 1

	# don't return None or 0 as it is multipled with a value and that value could be lost
	return exchange_rate or 1
Пример #13
0
def get_data(filters):
	accounts = frappe.db.sql("""select name, parent_account, account_name, root_type, report_type, lft, rgt
		from `tabAccount` where company=%s order by lft""", filters.company, as_dict=True)
	company_currency = erpnext.get_company_currency(filters.company)

	if not accounts:
		return None

	accounts, accounts_by_name, parent_children_map = filter_accounts(accounts)

	min_lft, max_rgt = frappe.db.sql("""select min(lft), max(rgt) from `tabAccount`
		where company=%s""", (filters.company,))[0]

	gl_entries_by_account = {}

	set_gl_entries_by_account(filters.company, filters.from_date,
		filters.to_date, min_lft, max_rgt, filters, gl_entries_by_account, ignore_closing_entries=not flt(filters.with_period_closing_entry))

	opening_balances = get_opening_balances(filters)

	total_row = calculate_values(accounts, gl_entries_by_account, opening_balances, filters, company_currency)
	accumulate_values_into_parents(accounts, accounts_by_name)

	data = prepare_data(accounts, filters, total_row, parent_children_map, company_currency)
	data = filter_out_zero_value_rows(data, parent_children_map, 
		show_zero_values=filters.get("show_zero_values"))
		
	return data
Пример #14
0
def get_currency(filters):
	"""
	Returns a dictionary containing currency information. The keys of the dict are
	- company: The company for which we are fetching currency information. if no
	company is specified, it will fallback to the default company.
	- company currency: The functional currency of the said company.
	- presentation currency: The presentation currency to use. Only currencies that
	have been used for transactions will be allowed.
	- report date: The report date.
	:param filters: Report filters
	:type filters: dict

	:return: str - Currency
	"""
	company = get_appropriate_company(filters)
	company_currency = get_company_currency(company)
	presentation_currency = filters['presentation_currency'] if filters.get('presentation_currency') else company_currency

	report_date = filters.get('to_date')

	if not report_date:
		fiscal_year_to_date = get_from_and_to_date(filters.get('to_fiscal_year'))["to_date"]
		report_date = formatdate(get_datetime_str(fiscal_year_to_date), "dd-MM-yyyy")

	currency_map = dict(company=company, company_currency=company_currency, presentation_currency=presentation_currency, report_date=report_date)

	return currency_map
Пример #15
0
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
	if not filters: filters = {}
	filters.update({"from_date": filters.get("date_range") and filters.get("date_range")[0], "to_date": filters.get("date_range") and filters.get("date_range")[1]})
	columns = get_columns(additional_table_columns)

	company_currency = erpnext.get_company_currency(filters.get('company'))

	item_list = get_items(filters, additional_query_columns)
	if item_list:
		itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
	columns.append({
		"fieldname": "currency",
		"label": _("Currency"),
		"fieldtype": "Data",
		"width": 80
	})
	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 = []
	for d in item_list:
		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 = [d.item_code, d.item_name, d.item_group, d.description, d.parent, d.posting_date, d.customer, d.customer_name]

		if additional_query_columns:
			for col in additional_query_columns:
				row.append(d.get(col))

		row += [
			d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
			d.territory, d.project, d.company, d.sales_order,
			delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom
		]

		if d.stock_uom != d.uom and d.stock_qty:
			row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount]
		else:
			row += [d.base_net_rate, d.base_net_amount]

		total_tax = 0
		for tax in tax_columns:
			item_tax = itemised_tax.get(d.name, {}).get(tax, {})
			row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
			total_tax += flt(item_tax.get("tax_amount"))

		row += [total_tax, d.base_net_amount + total_tax, company_currency]

		data.append(row)

	return columns, data
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
	if not filters: filters = {}
	filters.update({"from_date": filters.get("date_range")[0], "to_date": filters.get("date_range")[1]})
	columns = get_columns(additional_table_columns)

	company_currency = erpnext.get_company_currency(filters.company)

	item_list = get_items(filters, additional_query_columns)
	aii_account_map = get_aii_accounts()
	if item_list:
		itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency,
			doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")

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

	po_pr_map = get_purchase_receipts_against_purchase_order(item_list)

	data = []
	for d in item_list:
		if not d.stock_qty:
			continue

		purchase_receipt = None
		if d.purchase_receipt:
			purchase_receipt = d.purchase_receipt
		elif d.po_detail:
			purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, []))

		expense_account = d.expense_account or aii_account_map.get(d.company)
		row = [d.item_code, d.item_name, d.item_group, d.description, d.parent, d.posting_date, d.supplier,
			d.supplier_name]

		if additional_query_columns:
			for col in additional_query_columns:
				row.append(d.get(col))

		row += [
			d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
			purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_amount / d.stock_qty, d.base_net_amount
		]

		total_tax = 0
		for tax in tax_columns:
			item_tax = itemised_tax.get(d.name, {}).get(tax, {})
			row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
			total_tax += flt(item_tax.get("tax_amount"))

		row += [total_tax, d.base_net_amount + total_tax, company_currency]

		data.append(row)

	return columns, data
Пример #17
0
def get_reference_details(reference_doctype, reference_name, party_account_currency):
	total_amount = outstanding_amount = exchange_rate = bill_no = None
	ref_doc = frappe.get_doc(reference_doctype, reference_name)
	company_currency = ref_doc.get("company_currency") or erpnext.get_company_currency(ref_doc.company)

	if reference_doctype == "Fees":
		total_amount = ref_doc.get("grand_total")
		exchange_rate = 1
		outstanding_amount = ref_doc.get("outstanding_amount")
	elif reference_doctype == "Journal Entry" and ref_doc.docstatus == 1:
		total_amount = ref_doc.get("total_amount")
		if ref_doc.multi_currency:
			exchange_rate = get_exchange_rate(party_account_currency, company_currency, ref_doc.posting_date)
		else:
			exchange_rate = 1
			outstanding_amount = get_outstanding_on_journal_entry(reference_name)
	elif reference_doctype != "Journal Entry":
		if party_account_currency == company_currency:
			if ref_doc.doctype == "Expense Claim":
				total_amount = ref_doc.total_sanctioned_amount
			elif ref_doc.doctype == "Employee Advance":
				total_amount = ref_doc.advance_amount
			else:
				total_amount = ref_doc.base_grand_total
			exchange_rate = 1
		else:
			total_amount = ref_doc.grand_total

			# Get the exchange rate from the original ref doc
			# or get it based on the posting date of the ref doc
			exchange_rate = ref_doc.get("conversion_rate") or \
				get_exchange_rate(party_account_currency, company_currency, ref_doc.posting_date)

		if reference_doctype in ("Sales Invoice", "Purchase Invoice"):
			outstanding_amount = ref_doc.get("outstanding_amount")
			bill_no = ref_doc.get("bill_no")
		elif reference_doctype == "Expense Claim":
			outstanding_amount = flt(ref_doc.get("total_sanctioned_amount")) \
				- flt(ref_doc.get("total_amount+reimbursed")) - flt(ref_doc.get("total_advance_amount"))
		elif reference_doctype == "Employee Advance":
			outstanding_amount = ref_doc.advance_amount - flt(ref_doc.paid_amount)
		else:
			outstanding_amount = flt(total_amount) - flt(ref_doc.advance_paid)
	else:
		# Get the exchange rate based on the posting date of the ref doc
		exchange_rate = get_exchange_rate(party_account_currency,
			company_currency, ref_doc.posting_date)

	return frappe._dict({
		"due_date": ref_doc.get("due_date"),
		"total_amount": total_amount,
		"outstanding_amount": outstanding_amount,
		"exchange_rate": exchange_rate,
		"bill_no": bill_no
	})
Пример #18
0
	def validate_conversion_rate(self):
		# validate conversion rate
		company_currency = erpnext.get_company_currency(self.doc.company)
		if not self.doc.currency or self.doc.currency == company_currency:
			self.doc.currency = company_currency
			self.doc.conversion_rate = 1.0
		else:
			validate_conversion_rate(self.doc.currency, self.doc.conversion_rate,
				self.doc.meta.get_label("conversion_rate"), self.doc.company)

		self.doc.conversion_rate = flt(self.doc.conversion_rate)
Пример #19
0
	def set_incoming_rate(self):
		for d in self.items:
			if d.s_warehouse:
				args = self.get_args_for_incoming_rate(d)
				d.basic_rate = get_incoming_rate(args)
			elif d.allow_zero_valuation_rate and not d.s_warehouse:
				d.basic_rate = 0.0
			elif d.t_warehouse and not d.basic_rate:
				d.basic_rate = get_valuation_rate(d.item_code, d.t_warehouse,
					self.doctype, d.name, d.allow_zero_valuation_rate,
					currency=erpnext.get_company_currency(self.company))
Пример #20
0
	def test_purchase_order_creation(self):
		bo = make_blanket_order(blanket_order_type="Purchasing")

		po = make_purchase_order(bo.name)
		po.currency = get_company_currency(po.company)
		po.schedule_date = today()
		po.items[0].qty = 10
		po.submit()

		self.assertEqual(po.doctype, "Purchase Order")
		self.assertEqual(len(po.get("items")), len(bo.get("items")))

		# check the rate, quantity and updation for the ordered quantity
		self.assertEqual(po.items[0].rate, po.items[0].rate)

		bo = frappe.get_doc("Blanket Order", bo.name)
		self.assertEqual(po.items[0].qty, bo.items[0].ordered_qty)

		# test the quantity
		po1 = make_sales_order(bo.name)
		po1.currency = get_company_currency(po1.company)
		self.assertEqual(po1.items[0].qty, (bo.items[0].qty-bo.items[0].ordered_qty))
Пример #21
0
	def test_sales_order_creation(self):
		bo = make_blanket_order(blanket_order_type="Selling")

		so = make_sales_order(bo.name)
		so.currency = get_company_currency(so.company)
		so.delivery_date = today()
		so.items[0].qty = 10
		so.submit()

		self.assertEqual(so.doctype, "Sales Order")
		self.assertEqual(len(so.get("items")), len(bo.get("items")))

		# check the rate, quantity and updation for the ordered quantity
		self.assertEqual(so.items[0].rate, bo.items[0].rate)

		bo = frappe.get_doc("Blanket Order", bo.name)
		self.assertEqual(so.items[0].qty, bo.items[0].ordered_qty)

		# test the quantity
		so1 = make_sales_order(bo.name)
		so1.currency = get_company_currency(so1.company)
		self.assertEqual(so1.items[0].qty, (bo.items[0].qty-bo.items[0].ordered_qty))
Пример #22
0
	def validate_currency(self):
		company_currency = erpnext.get_company_currency(self.company)
		account_currency = get_account_currency(self.account)

		if not self.account_currency:
			self.account_currency = company_currency

		if account_currency != self.account_currency:
			frappe.throw(_("{0} {1}: Accounting Entry for {2} can only be made in currency: {3}")
				.format(self.voucher_type, self.voucher_no, self.account,
				(account_currency or company_currency)), InvalidAccountCurrency)

		if self.party_type and self.party:
			validate_party_gle_currency(self.party_type, self.party, self.company, self.account_currency)
Пример #23
0
	def set_rounded_total(self):
		if frappe.db.get_single_value("Global Defaults", "disable_rounded_total"):
			self.doc.rounded_total = self.doc.base_rounded_total = 0
			return

		if self.doc.meta.get_field("rounded_total"):
			self.doc.rounded_total = round_based_on_smallest_currency_fraction(self.doc.grand_total,
				self.doc.currency, self.doc.precision("rounded_total"))

		if self.doc.meta.get_field("base_rounded_total"):
			company_currency = erpnext.get_company_currency(self.doc.company)

			self.doc.base_rounded_total = \
				round_based_on_smallest_currency_fraction(self.doc.base_grand_total,
					company_currency, self.doc.precision("base_rounded_total"))
Пример #24
0
	def get_dashboard_info(self):
		info = {
			"total_paid": 0,
			"total_unpaid": 0,
			"currency": erpnext.get_company_currency(self.company)
		}

		fees_amount = frappe.db.sql("""select sum(grand_total), sum(outstanding_amount) from tabFees
			where fee_schedule=%s and docstatus=1""", (self.name))

		if fees_amount:
			info["total_paid"] = flt(fees_amount[0][0]) - flt(fees_amount[0][1])
			info["total_unpaid"] = flt(fees_amount[0][1])

		return info
Пример #25
0
	def set_missing_accounts_and_fields(self):
		if not self.company:
			self.company = frappe.defaults.get_defaults().company
		if not self.currency:
			self.currency = erpnext.get_company_currency(self.company)
		if not (self.receivable_account and self.income_account and self.cost_center):
			accounts_details = frappe.get_all("Company",
				fields=["default_receivable_account", "default_income_account", "cost_center"],
				filters={"name": self.company})[0]
		if not self.receivable_account:
			self.receivable_account = accounts_details.default_receivable_account
		if not self.income_account:
			self.income_account = accounts_details.default_income_account
		if not self.cost_center:
			self.cost_center = accounts_details.cost_center
		if not self.student_email:
			self.student_email = self.get_student_emails()
Пример #26
0
def get_outstanding(args):
	if not frappe.has_permission("Account"):
		frappe.msgprint(_("No Permission"), raise_exception=1)

	if isinstance(args, basestring):
		args = json.loads(args)

	company_currency = erpnext.get_company_currency(args.get("company"))

	if args.get("doctype") == "Journal Entry":
		condition = " and party=%(party)s" if args.get("party") else ""

		against_jv_amount = frappe.db.sql("""
			select sum(debit_in_account_currency) - sum(credit_in_account_currency)
			from `tabJournal Entry Account` where parent=%(docname)s and account=%(account)s {0}
			and (reference_type is null or reference_type = '')""".format(condition), args)

		against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0
		amount_field = "credit_in_account_currency" if against_jv_amount > 0 else "debit_in_account_currency"
		return {
			amount_field: abs(against_jv_amount)
		}
	elif args.get("doctype") in ("Sales Invoice", "Purchase Invoice"):
		party_type = "Customer" if args.get("doctype") == "Sales Invoice" else "Supplier"
		invoice = frappe.db.get_value(args["doctype"], args["docname"],
			["outstanding_amount", "conversion_rate", scrub(party_type)], as_dict=1)

		exchange_rate = invoice.conversion_rate if (args.get("account_currency") != company_currency) else 1

		if args["doctype"] == "Sales Invoice":
			amount_field = "credit_in_account_currency" \
				if flt(invoice.outstanding_amount) > 0 else "debit_in_account_currency"
		else:
			amount_field = "debit_in_account_currency" \
				if flt(invoice.outstanding_amount) > 0 else "credit_in_account_currency"

		return {
			amount_field: abs(flt(invoice.outstanding_amount)),
			"exchange_rate": exchange_rate,
			"party_type": party_type,
			"party": invoice.get(scrub(party_type))
		}
Пример #27
0
def get_price_list_currency_and_exchange_rate(args):
	if not args.price_list:
		return {}

	price_list_currency = get_price_list_currency(args.price_list)
	price_list_uom_dependant = get_price_list_uom_dependant(args.price_list)
	plc_conversion_rate = args.plc_conversion_rate
	company_currency = get_company_currency(args.company)

	if (not plc_conversion_rate) or (price_list_currency and args.price_list_currency \
		and price_list_currency != args.price_list_currency):
			# cksgb 19/09/2016: added args.transaction_date as posting_date argument for get_exchange_rate
			plc_conversion_rate = get_exchange_rate(price_list_currency, company_currency,
				args.transaction_date) or plc_conversion_rate

	return frappe._dict({
		"price_list_currency": price_list_currency,
		"price_list_uom_dependant": price_list_uom_dependant,
		"plc_conversion_rate": plc_conversion_rate
	})
Пример #28
0
	def calculate_totals(self):
		self.doc.grand_total = flt(self.doc.get("taxes")[-1].total
			if self.doc.get("taxes") else self.doc.net_total)

		self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total,
			self.doc.precision("total_taxes_and_charges"))

		self._set_in_company_currency(self.doc, ["total_taxes_and_charges"])

		if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
			self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \
				if self.doc.total_taxes_and_charges else self.doc.base_net_total
		else:
			self.doc.taxes_and_charges_added = self.doc.taxes_and_charges_deducted = 0.0
			for tax in self.doc.get("taxes"):
				if tax.category in ["Valuation and Total", "Total"]:
					if tax.add_deduct_tax == "Add":
						self.doc.taxes_and_charges_added += flt(tax.tax_amount_after_discount_amount)
					else:
						self.doc.taxes_and_charges_deducted += flt(tax.tax_amount_after_discount_amount)

			self.doc.round_floats_in(self.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"])

			self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \
				if (self.doc.taxes_and_charges_added or self.doc.taxes_and_charges_deducted) \
				else self.doc.base_net_total

			self._set_in_company_currency(self.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"])

		self.doc.round_floats_in(self.doc, ["grand_total", "base_grand_total"])

		if self.doc.meta.get_field("rounded_total"):
			self.doc.rounded_total = round_based_on_smallest_currency_fraction(self.doc.grand_total,
				self.doc.currency, self.doc.precision("rounded_total"))
		if self.doc.meta.get_field("base_rounded_total"):
			company_currency = erpnext.get_company_currency(self.doc.company)

			self.doc.base_rounded_total = \
				round_based_on_smallest_currency_fraction(self.doc.base_grand_total,
					company_currency, self.doc.precision("base_rounded_total"))
def execute(filters=None):
	if not filters: filters = {}

	columns = get_columns(filters)
	entries = get_entries(filters)
	item_details = get_item_details()
	data = []

	company_currency = get_company_currency(filters["company"])

	for d in entries:
		if d.stock_qty > 0 or filters.get('show_return_entries', 0):
			data.append([
				d.name, d.customer, d.territory, d.warehouse, d.posting_date, d.item_code,
				item_details.get(d.item_code, {}).get("item_group"), item_details.get(d.item_code, {}).get("brand"),
				d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt, company_currency
			])

	if data:
		total_row = [""]*len(data[0])
		data.append(total_row)

	return columns, data
Пример #30
0
	def get_moving_average_values(self, sle):
		actual_qty = flt(sle.actual_qty)
		new_stock_qty = flt(self.qty_after_transaction) + actual_qty
		if new_stock_qty >= 0:
			if actual_qty > 0:
				if flt(self.qty_after_transaction) <= 0:
					self.valuation_rate = sle.incoming_rate
				else:
					new_stock_value = (self.qty_after_transaction * self.valuation_rate) + \
						(actual_qty * sle.incoming_rate)

					self.valuation_rate = new_stock_value / new_stock_qty

			elif sle.outgoing_rate:
				if new_stock_qty:
					new_stock_value = (self.qty_after_transaction * self.valuation_rate) + \
						(actual_qty * sle.outgoing_rate)

					self.valuation_rate = new_stock_value / new_stock_qty
				else:
					self.valuation_rate = sle.outgoing_rate

		else:
			if flt(self.qty_after_transaction) >= 0 and sle.outgoing_rate:
				self.valuation_rate = sle.outgoing_rate

			if not self.valuation_rate and actual_qty > 0:
				self.valuation_rate = sle.incoming_rate

			# Get valuation rate from previous SLE or Item master, if item does not have the
			# allow zero valuration rate flag set
			if not self.valuation_rate and sle.voucher_detail_no:
				allow_zero_valuation_rate = self.check_if_allow_zero_valuation_rate(sle.voucher_type, sle.voucher_detail_no)
				if not allow_zero_valuation_rate:
					self.valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse,
						sle.voucher_type, sle.voucher_no, self.allow_zero_rate,
						currency=erpnext.get_company_currency(sle.company))
def get_data(filters, mode_of_payments):
    data = []

    conditions = get_conditions(filters)

    entry = frappe.db.sql(
        """
		select branch, mode_of_payment, sum(net_pay) as net_pay, sum(gross_pay) as gross_pay
		from `tabSalary Slip` sal
		where docstatus = 1 %s
		group by branch, mode_of_payment
		""" % (conditions),
        as_dict=1,
    )

    branch_wise_entries, gross_pay = prepare_data(entry)

    branches = frappe.db.sql_list("""
		select distinct branch from `tabSalary Slip` sal
		where docstatus = 1 %s
	""" % (conditions))

    total_row = {"total": 0, "branch": "Total"}

    for branch in branches:
        total = 0
        row = {"branch": branch}
        for mode in mode_of_payments:
            if branch_wise_entries.get(branch).get(mode):
                row[mode] = branch_wise_entries.get(branch).get(mode)
                total += branch_wise_entries.get(branch).get(mode)

        row["total"] = total
        data.append(row)

    total_row = get_total_based_on_mode_of_payment(data, mode_of_payments)
    total_deductions = gross_pay - total_row.get("total")

    report_summary = []

    if data:
        data.append(total_row)
        data.append({})
        data.append({
            "branch": "<b>Total Gross Pay</b>",
            mode_of_payments[0]: gross_pay
        })
        data.append({
            "branch": "<b>Total Deductions</b>",
            mode_of_payments[0]: total_deductions
        })
        data.append({
            "branch": "<b>Total Net Pay</b>",
            mode_of_payments[0]: total_row.get("total")
        })

        currency = erpnext.get_company_currency(filters.company)
        report_summary = get_report_summary(gross_pay, total_deductions,
                                            total_row.get("total"), currency)

    return data, total_row, report_summary
def _execute(filters=None,
             additional_table_columns=None,
             additional_query_columns=None):
    if not filters: filters = {}
    columns = get_columns(additional_table_columns)

    company_currency = erpnext.get_company_currency(filters.company)

    item_list = get_items(filters, additional_query_columns)
    aii_account_map = get_aii_accounts()
    if item_list:
        itemised_tax, tax_columns = get_tax_accounts(
            item_list,
            columns,
            company_currency,
            doctype="Purchase Invoice",
            tax_doctype="Purchase Taxes and Charges")

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

    po_pr_map = get_purchase_receipts_against_purchase_order(item_list)

    data = []
    for d in item_list:
        purchase_receipt = None
        if d.purchase_receipt:
            purchase_receipt = d.purchase_receipt
        elif d.po_detail:
            purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, []))

        expense_account = d.expense_account or aii_account_map.get(d.company)
        row = [
            d.item_code, d.item_name, d.item_group, d.parent, d.posting_date,
            d.supplier, d.supplier_name
        ]

        if additional_query_columns:
            for col in additional_query_columns:
                row.append(d.get(col))

        row += [
            d.credit_to, d.mode_of_payment, d.project, d.company,
            d.purchase_order, purchase_receipt, expense_account, d.stock_qty,
            d.stock_uom, d.base_net_amount / d.stock_qty, d.base_net_amount
        ]

        total_tax = 0
        for tax in tax_columns:
            item_tax = itemised_tax.get(d.name, {}).get(tax, {})
            row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
            total_tax += flt(item_tax.get("tax_amount"))

        row += [total_tax, d.base_net_amount + total_tax, company_currency]

        data.append(row)

    return columns, data
Пример #33
0
	def make_accrual_jv_entry(self):
		self.check_permission("write")
		earnings = self.get_salary_component_total(component_type="earnings") or {}
		deductions = self.get_salary_component_total(component_type="deductions") or {}
		payroll_payable_account = self.payroll_payable_account
		jv_name = ""
		precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")

		if earnings or deductions:
			journal_entry = frappe.new_doc("Journal Entry")
			journal_entry.voucher_type = "Journal Entry"
			journal_entry.user_remark = _("Accrual Journal Entry for salaries from {0} to {1}").format(
				self.start_date, self.end_date
			)
			journal_entry.company = self.company
			journal_entry.posting_date = self.posting_date
			accounting_dimensions = get_accounting_dimensions() or []

			accounts = []
			currencies = []
			payable_amount = 0
			multi_currency = 0
			company_currency = erpnext.get_company_currency(self.company)

			# Earnings
			for acc_cc, amount in earnings.items():
				exchange_rate, amt = self.get_amount_and_exchange_rate_for_journal_entry(
					acc_cc[0], amount, company_currency, currencies
				)
				payable_amount += flt(amount, precision)
				accounts.append(
					self.update_accounting_dimensions(
						{
							"account": acc_cc[0],
							"debit_in_account_currency": flt(amt, precision),
							"exchange_rate": flt(exchange_rate),
							"cost_center": acc_cc[1] or self.cost_center,
							"project": self.project,
						},
						accounting_dimensions,
					)
				)

			# Deductions
			for acc_cc, amount in deductions.items():
				exchange_rate, amt = self.get_amount_and_exchange_rate_for_journal_entry(
					acc_cc[0], amount, company_currency, currencies
				)
				payable_amount -= flt(amount, precision)
				accounts.append(
					self.update_accounting_dimensions(
						{
							"account": acc_cc[0],
							"credit_in_account_currency": flt(amt, precision),
							"exchange_rate": flt(exchange_rate),
							"cost_center": acc_cc[1] or self.cost_center,
							"project": self.project,
						},
						accounting_dimensions,
					)
				)

			# Payable amount
			exchange_rate, payable_amt = self.get_amount_and_exchange_rate_for_journal_entry(
				payroll_payable_account, payable_amount, company_currency, currencies
			)
			accounts.append(
				self.update_accounting_dimensions(
					{
						"account": payroll_payable_account,
						"credit_in_account_currency": flt(payable_amt, precision),
						"exchange_rate": flt(exchange_rate),
						"cost_center": self.cost_center,
					},
					accounting_dimensions,
				)
			)

			journal_entry.set("accounts", accounts)
			if len(currencies) > 1:
				multi_currency = 1
			journal_entry.multi_currency = multi_currency
			journal_entry.title = payroll_payable_account
			journal_entry.save()

			try:
				journal_entry.submit()
				jv_name = journal_entry.name
				self.update_salary_slip_status(jv_name=jv_name)
			except Exception as e:
				if type(e) in (str, list, tuple):
					frappe.msgprint(e)
				raise

		return jv_name
Пример #34
0
	def company_currency(self):
		if not hasattr(self, "__company_currency"):
			self.__company_currency = erpnext.get_company_currency(self.company)

		return self.__company_currency
Пример #35
0
    def get_fifo_values(self, sle):
        incoming_rate = flt(sle.incoming_rate)
        actual_qty = flt(sle.actual_qty)
        outgoing_rate = flt(sle.outgoing_rate)

        if actual_qty > 0:
            if not self.stock_queue:
                self.stock_queue.append([0, 0])

            # last row has the same rate, just updated the qty
            if self.stock_queue[-1][1] == incoming_rate:
                self.stock_queue[-1][0] += actual_qty
            else:
                if self.stock_queue[-1][0] > 0:
                    self.stock_queue.append([actual_qty, incoming_rate])
                else:
                    qty = self.stock_queue[-1][0] + actual_qty
                    self.stock_queue[-1] = [qty, incoming_rate]
        else:
            qty_to_pop = abs(actual_qty)
            while qty_to_pop:
                if not self.stock_queue:
                    # Get valuation rate from last sle if exists or from valuation rate field in item master
                    is_sample_item = self.check_if_sample_item(
                        sle.voucher_type, sle.voucher_detail_no)
                    if not is_sample_item:
                        _rate = get_valuation_rate(
                            sle.item_code,
                            sle.warehouse,
                            sle.voucher_type,
                            sle.voucher_no,
                            self.allow_zero_rate,
                            currency=erpnext.get_company_currency(sle.company))
                    else:
                        _rate = 0

                    self.stock_queue.append([0, _rate])

                index = None
                if outgoing_rate > 0:
                    # Find the entry where rate matched with outgoing rate
                    for i, v in enumerate(self.stock_queue):
                        if v[1] == outgoing_rate:
                            index = i
                            break

                    # If no entry found with outgoing rate, collapse stack
                    if index == None:
                        new_stock_value = sum(
                            (d[0] * d[1] for d in self.stock_queue
                             )) - qty_to_pop * outgoing_rate
                        new_stock_qty = sum(
                            (d[0] for d in self.stock_queue)) - qty_to_pop
                        self.stock_queue = [[
                            new_stock_qty, new_stock_value / new_stock_qty
                            if new_stock_qty > 0 else outgoing_rate
                        ]]
                        break
                else:
                    index = 0

                # select first batch or the batch with same rate
                batch = self.stock_queue[index]
                if qty_to_pop >= batch[0]:
                    # consume current batch
                    qty_to_pop = qty_to_pop - batch[0]
                    self.stock_queue.pop(index)
                    if not self.stock_queue and qty_to_pop:
                        # stock finished, qty still remains to be withdrawn
                        # negative stock, keep in as a negative batch
                        self.stock_queue.append(
                            [-qty_to_pop, outgoing_rate or batch[1]])
                        break

                else:
                    # qty found in current batch
                    # consume it and exit
                    batch[0] = batch[0] - qty_to_pop
                    qty_to_pop = 0

        stock_value = sum(
            (flt(batch[0]) * flt(batch[1]) for batch in self.stock_queue))
        stock_qty = sum((flt(batch[0]) for batch in self.stock_queue))

        if stock_qty:
            self.valuation_rate = stock_value / flt(stock_qty)

        if not self.stock_queue:
            self.stock_queue.append([
                0, sle.incoming_rate or sle.outgoing_rate
                or self.valuation_rate
            ])
Пример #36
0
	def company_currency(self):
		return erpnext.get_company_currency(self.company)
Пример #37
0
	def validate_employee_advance_account(self):
		company_currency = erpnext.get_company_currency(self.company)
		if (self.advance_account and
			company_currency != frappe.db.get_value('Account', self.advance_account, 'account_currency')):
			frappe.throw(_("Advance account currency should be same as company currency {0}")
				.format(company_currency))