Merge branch 'develop' of https://github.com/frappe/erpnext into quotation_blanket_order
This commit is contained in:
		
						commit
						242a079bcb
					
				| @ -317,13 +317,13 @@ def make_payment_request(**args): | ||||
| 			"payment_request_type": args.get("payment_request_type"), | ||||
| 			"currency": ref_doc.currency, | ||||
| 			"grand_total": grand_total, | ||||
| 			"email_to": args.recipient_id or "", | ||||
| 			"email_to": args.recipient_id or ref_doc.owner, | ||||
| 			"subject": _("Payment Request for {0}").format(args.dn), | ||||
| 			"message": gateway_account.get("message") or get_dummy_message(ref_doc), | ||||
| 			"reference_doctype": args.dt, | ||||
| 			"reference_name": args.dn, | ||||
| 			"party_type": args.get("party_type"), | ||||
| 			"party": args.get("party"), | ||||
| 			"party_type": args.get("party_type") or "Customer", | ||||
| 			"party": args.get("party") or ref_doc.customer, | ||||
| 			"bank_account": bank_account | ||||
| 		}) | ||||
| 
 | ||||
|  | ||||
| @ -499,7 +499,8 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( | ||||
| 						reference_doctype: me.frm.doctype, | ||||
| 						reference_name: me.frm.docname, | ||||
| 						content: __('Reason for hold: ')+data.reason_for_hold, | ||||
| 						comment_email: frappe.session.user | ||||
| 						comment_email: frappe.session.user, | ||||
| 						comment_by: frappe.session.user_fullname | ||||
| 					}, | ||||
| 					callback: function(r) { | ||||
| 						if(!r.exc) { | ||||
|  | ||||
| @ -1,22 +0,0 @@ | ||||
| { | ||||
|  "cards": [], | ||||
|  "charts": [], | ||||
|  "creation": "2020-01-28 11:49:55.003637", | ||||
|  "developer_mode_only": 0, | ||||
|  "disable_user_customization": 0, | ||||
|  "docstatus": 0, | ||||
|  "doctype": "Desk Page", | ||||
|  "extends_another_page": 0, | ||||
|  "icon": "", | ||||
|  "idx": 0, | ||||
|  "is_standard": 1, | ||||
|  "label": "Communication", | ||||
|  "modified": "2020-03-12 16:30:40.534226", | ||||
|  "modified_by": "Administrator", | ||||
|  "module": "Communication", | ||||
|  "name": "Communication", | ||||
|  "owner": "Administrator", | ||||
|  "pin_to_bottom": 0, | ||||
|  "pin_to_top": 0, | ||||
|  "shortcuts": [] | ||||
| } | ||||
| @ -672,19 +672,32 @@ class BuyingController(StockController): | ||||
| 					# If asset has to be auto created | ||||
| 					# Check for asset naming series | ||||
| 					if item_data.get('asset_naming_series'): | ||||
| 						created_assets = [] | ||||
| 
 | ||||
| 						for qty in range(cint(d.qty)): | ||||
| 							self.make_asset(d) | ||||
| 						is_plural = 's' if cint(d.qty) != 1 else '' | ||||
| 						messages.append(_('{0} Asset{2} Created for <b>{1}</b>').format(cint(d.qty), d.item_code, is_plural)) | ||||
| 							asset = self.make_asset(d) | ||||
| 							created_assets.append(asset) | ||||
| 						 | ||||
| 						if len(created_assets) > 5: | ||||
| 							# dont show asset form links if more than 5 assets are created | ||||
| 							messages.append(_('{} Asset{} created for {}').format(len(created_assets), is_plural, frappe.bold(d.item_code))) | ||||
| 						else: | ||||
| 							assets_link = list(map(lambda d: frappe.utils.get_link_to_form('Asset', d), created_assets)) | ||||
| 							assets_link = frappe.bold(','.join(assets_link)) | ||||
| 
 | ||||
| 							is_plural = 's' if len(created_assets) != 1 else '' | ||||
| 							messages.append( | ||||
| 								_('Asset{} {assets_link} created for {}').format(is_plural, frappe.bold(d.item_code), assets_link=assets_link) | ||||
| 							) | ||||
| 					else: | ||||
| 						frappe.throw(_("Row {1}: Asset Naming Series is mandatory for the auto creation for item {0}") | ||||
| 							.format(d.item_code, d.idx)) | ||||
| 						frappe.throw(_("Row {}: Asset Naming Series is mandatory for the auto creation for item {}") | ||||
| 							.format(d.idx, frappe.bold(d.item_code))) | ||||
| 				else: | ||||
| 					messages.append(_("Assets not created for <b>{0}</b>. You will have to create asset manually.") | ||||
| 						.format(d.item_code)) | ||||
| 					messages.append(_("Assets not created for {0}. You will have to create asset manually.") | ||||
| 						.format(frappe.bold(d.item_code))) | ||||
| 
 | ||||
| 		for message in messages: | ||||
| 			frappe.msgprint(message, title="Success") | ||||
| 			frappe.msgprint(message, title="Success", indicator="green") | ||||
| 
 | ||||
| 	def make_asset(self, row): | ||||
| 		if not row.asset_location: | ||||
| @ -716,6 +729,8 @@ class BuyingController(StockController): | ||||
| 		asset.set_missing_values() | ||||
| 		asset.insert() | ||||
| 
 | ||||
| 		return asset.name | ||||
| 
 | ||||
| 	def update_fixed_asset(self, field, delete_asset = False): | ||||
| 		for d in self.get("items"): | ||||
| 			if d.is_fixed_asset: | ||||
| @ -1026,4 +1041,4 @@ def get_batches_with_qty(item_code, fg_item, required_qty, transferred_batch_qty | ||||
| 			available_batches.append({'batch': batch, 'qty': available_qty}) | ||||
| 			required_qty -= available_qty | ||||
| 
 | ||||
| 	return available_batches | ||||
| 	return available_batches | ||||
|  | ||||
| @ -3,6 +3,7 @@ | ||||
| 
 | ||||
| from __future__ import unicode_literals | ||||
| import frappe | ||||
| import erpnext | ||||
| from frappe.desk.reportview import get_match_cond, get_filters_cond | ||||
| from frappe.utils import nowdate, getdate | ||||
| from collections import defaultdict | ||||
| @ -129,23 +130,26 @@ def supplier_query(doctype, txt, searchfield, start, page_len, filters): | ||||
| 		}) | ||||
| 
 | ||||
| def tax_account_query(doctype, txt, searchfield, start, page_len, filters): | ||||
| 	company_currency = erpnext.get_company_currency(filters.get('company')) | ||||
| 
 | ||||
| 	tax_accounts = frappe.db.sql("""select name, parent_account	from tabAccount | ||||
| 		where tabAccount.docstatus!=2 | ||||
| 			and account_type in (%s) | ||||
| 			and is_group = 0 | ||||
| 			and company = %s | ||||
| 			and account_currency = %s | ||||
| 			and `%s` LIKE %s | ||||
| 		order by idx desc, name | ||||
| 		limit %s, %s""" % | ||||
| 		(", ".join(['%s']*len(filters.get("account_type"))), "%s", searchfield, "%s", "%s", "%s"), | ||||
| 		tuple(filters.get("account_type") + [filters.get("company"), "%%%s%%" % txt, | ||||
| 		(", ".join(['%s']*len(filters.get("account_type"))), "%s", "%s", searchfield, "%s", "%s", "%s"), | ||||
| 		tuple(filters.get("account_type") + [filters.get("company"), company_currency, "%%%s%%" % txt, | ||||
| 			start, page_len])) | ||||
| 	if not tax_accounts: | ||||
| 		tax_accounts = frappe.db.sql("""select name, parent_account	from tabAccount | ||||
| 			where tabAccount.docstatus!=2 and is_group = 0 | ||||
| 				and company = %s and `%s` LIKE %s limit %s, %s""" | ||||
| 			% ("%s", searchfield, "%s", "%s", "%s"), | ||||
| 			(filters.get("company"), "%%%s%%" % txt, start, page_len)) | ||||
| 				and company = %s and account_currency = %s and `%s` LIKE %s limit %s, %s""" #nosec | ||||
| 			% ("%s", "%s", searchfield, "%s", "%s", "%s"), | ||||
| 			(filters.get("company"), company_currency, "%%%s%%" % txt, start, page_len)) | ||||
| 
 | ||||
| 	return tax_accounts | ||||
| 
 | ||||
|  | ||||
| @ -171,7 +171,6 @@ | ||||
|    "options": "Customer" | ||||
|   }, | ||||
|   { | ||||
|    "depends_on": "eval: doc.source==\"Campaign\"", | ||||
|    "fieldname": "campaign_name", | ||||
|    "fieldtype": "Link", | ||||
|    "label": "Campaign Name", | ||||
| @ -512,4 +511,4 @@ | ||||
|  "sort_field": "modified", | ||||
|  "sort_order": "DESC", | ||||
|  "title_field": "title" | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -4,11 +4,12 @@ import frappe | ||||
| def execute(): | ||||
| 	frappe.reload_doc('accounts', 'doctype', 'bank', force=1) | ||||
| 
 | ||||
| 	frappe.db.sql(""" | ||||
| 		UPDATE `tabBank` b, `tabBank Account` ba | ||||
| 		SET b.swift_number = ba.swift_number, b.branch_code = ba.branch_code | ||||
| 		WHERE b.name = ba.bank | ||||
| 	""") | ||||
| 	if frappe.db.table_exists('Bank') and frappe.db.table_exists('Bank Account'): | ||||
| 		frappe.db.sql(""" | ||||
| 			UPDATE `tabBank` b, `tabBank Account` ba | ||||
| 			SET b.swift_number = ba.swift_number, b.branch_code = ba.branch_code | ||||
| 			WHERE b.name = ba.bank | ||||
| 		""") | ||||
| 
 | ||||
| 	frappe.reload_doc('accounts', 'doctype', 'bank_account') | ||||
| 	frappe.reload_doc('accounts', 'doctype', 'payment_request') | ||||
| @ -18,7 +18,7 @@ frappe.ui.form.on("Project", { | ||||
| 		}; | ||||
| 	}, | ||||
| 	onload: function (frm) { | ||||
| 		var so = frappe.meta.get_docfield("Project", "sales_order"); | ||||
| 		var so = frm.get_docfield("Project", "sales_order"); | ||||
| 		so.get_route_options_for_new_doc = function (field) { | ||||
| 			if (frm.is_new()) return; | ||||
| 			return { | ||||
| @ -135,4 +135,4 @@ function open_form(frm, doctype, child_doctype, parentfield) { | ||||
| 		frappe.ui.form.make_quick_entry(doctype, null, null, new_doc); | ||||
| 	}); | ||||
| 
 | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -21,6 +21,12 @@ frappe.query_reports["DATEV"] = { | ||||
| 			"default": frappe.datetime.now_date(), | ||||
| 			"fieldtype": "Date", | ||||
| 			"reqd": 1 | ||||
| 		}, | ||||
| 		{ | ||||
| 			"fieldname": "voucher_type", | ||||
| 			"label": __("Voucher Type"), | ||||
| 			"fieldtype": "Select", | ||||
| 			"options": "\nSales Invoice\nPurchase Invoice\nPayment Entry\nExpense Claim\nPayroll Entry\nBank Reconciliation\nAsset\nStock Entry" | ||||
| 		} | ||||
| 	], | ||||
| 	onload: function(query_report) { | ||||
|  | ||||
| @ -62,6 +62,7 @@ def get_transactions(filters, as_dict=1): | ||||
| 	filters -- dict of filters to be passed to the sql query | ||||
| 	as_dict -- return as list of dicts [0,1] | ||||
| 	""" | ||||
| 	filter_by_voucher = 'AND gl.voucher_type = %(voucher_type)s' if filters.get('voucher_type') else '' | ||||
| 	gl_entries = frappe.db.sql(""" | ||||
| 		SELECT | ||||
| 
 | ||||
| @ -80,8 +81,10 @@ def get_transactions(filters, as_dict=1): | ||||
| 			gl.posting_date as 'Belegdatum', | ||||
| 			gl.voucher_no as 'Belegfeld 1', | ||||
| 			gl.remarks as 'Buchungstext', | ||||
| 			gl.against_voucher_type as 'Beleginfo - Art 1', | ||||
| 			gl.against_voucher as 'Beleginfo - Inhalt 1' | ||||
| 			gl.voucher_type as 'Beleginfo - Art 1', | ||||
| 			gl.voucher_no as 'Beleginfo - Inhalt 1', | ||||
| 			gl.against_voucher_type as 'Beleginfo - Art 2', | ||||
| 			gl.against_voucher as 'Beleginfo - Inhalt 2' | ||||
| 
 | ||||
| 		FROM `tabGL Entry` gl | ||||
| 
 | ||||
| @ -109,7 +112,8 @@ def get_transactions(filters, as_dict=1): | ||||
| 		WHERE gl.company = %(company)s  | ||||
| 		AND DATE(gl.posting_date) >= %(from_date)s | ||||
| 		AND DATE(gl.posting_date) <= %(to_date)s | ||||
| 		ORDER BY 'Belegdatum', gl.voucher_no""", filters, as_dict=as_dict) | ||||
| 		{} | ||||
| 		ORDER BY 'Belegdatum', gl.voucher_no""".format(filter_by_voucher), filters, as_dict=as_dict) | ||||
| 
 | ||||
| 	return gl_entries | ||||
| 
 | ||||
| @ -281,24 +285,24 @@ def get_datev_csv(data, filters, csv_class): | ||||
| 
 | ||||
| def get_header(filters, csv_class): | ||||
| 	coa = frappe.get_value("Company", filters.get("company"), "chart_of_accounts") | ||||
| 	coa_used = "SKR04" if "SKR04" in coa else ("SKR03" if "SKR03" in coa else "") | ||||
| 	coa_used = "04" if "SKR04" in coa else ("03" if "SKR03" in coa else "") | ||||
| 
 | ||||
| 	header = [ | ||||
| 		# DATEV format | ||||
| 		#   "DTVF" = created by DATEV software, | ||||
| 		#   "EXTF" = created by other software | ||||
| 		#	"DTVF" = created by DATEV software, | ||||
| 		#	"EXTF" = created by other software | ||||
| 		'"EXTF"', | ||||
| 		# version of the DATEV format | ||||
| 		#   141 = 1.41,  | ||||
| 		#   510 = 5.10, | ||||
| 		#   720 = 7.20 | ||||
| 		#	141 = 1.41,  | ||||
| 		#	510 = 5.10, | ||||
| 		#	720 = 7.20 | ||||
| 		'700', | ||||
| 		csv_class.DATA_CATEGORY, | ||||
| 		'"%s"' % csv_class.FORMAT_NAME, | ||||
| 		# Format version (regarding format name) | ||||
| 		csv_class.FORMAT_VERSION, | ||||
| 		# Generated on | ||||
| 		datetime.datetime.now().strftime("%Y%m%d%H%M%S"), | ||||
| 		datetime.datetime.now().strftime("%Y%m%d%H%M%S") + '000', | ||||
| 		# Imported on -- stays empty | ||||
| 		'', | ||||
| 		# Origin. Any two symbols, will be replaced by "SV" on import. | ||||
| @ -328,13 +332,21 @@ def get_header(filters, csv_class): | ||||
| 		# R = Diktatkürzel | ||||
| 		'', | ||||
| 		# S = Buchungstyp | ||||
| 		#   1 = Transaction batch (Finanzbuchführung), | ||||
| 		#   2 = Annual financial statement (Jahresabschluss) | ||||
| 		#	1 = Transaction batch (Finanzbuchführung), | ||||
| 		#	2 = Annual financial statement (Jahresabschluss) | ||||
| 		'1' if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '', | ||||
| 		# T = Rechnungslegungszweck | ||||
| 		'', | ||||
| 		#	0 oder leer = vom Rechnungslegungszweck unabhängig | ||||
| 		#	50 = Handelsrecht | ||||
| 		#	30 = Steuerrecht | ||||
| 		#	64 = IFRS | ||||
| 		#	40 = Kalkulatorik | ||||
| 		#	11 = Reserviert | ||||
| 		#	12 = Reserviert | ||||
| 		'0', | ||||
| 		# U = Festschreibung | ||||
| 		'', | ||||
| 		# TODO: Filter by Accounting Period. In export for closed Accounting Period, this will be "1" | ||||
| 		'0', | ||||
| 		# V = Default currency, for example, "EUR" | ||||
| 		'"%s"' % frappe.get_value("Company", filters.get("company"), "default_currency"), | ||||
| 		# reserviert | ||||
|  | ||||
| @ -498,13 +498,27 @@ QUERY_REPORT_COLUMNS = [ | ||||
| 	}, | ||||
| 	{ | ||||
| 		"label": "Beleginfo - Art 1", | ||||
| 		"fieldname": "Beleginfo - Art 2", | ||||
| 		"fieldtype": "Data", | ||||
| 		"fieldname": "Beleginfo - Art 1", | ||||
| 		"fieldtype": "Link", | ||||
| 		"options": "DocType" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"label": "Beleginfo - Inhalt 1", | ||||
| 		"fieldname": "Beleginfo - Inhalt 1", | ||||
| 		"fieldtype": "Dynamic Link", | ||||
| 		"options": "Beleginfo - Art 1" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"label": "Beleginfo - Art 2", | ||||
| 		"fieldname": "Beleginfo - Art 2", | ||||
| 		"fieldtype": "Link", | ||||
| 		"options": "DocType" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"label": "Beleginfo - Inhalt 2", | ||||
| 		"fieldname": "Beleginfo - Inhalt 2", | ||||
| 		"fieldtype": "Data", | ||||
| 		"fieldtype": "Dynamic Link", | ||||
| 		"options": "Beleginfo - Art 2" | ||||
| 	} | ||||
| ] | ||||
| 
 | ||||
|  | ||||
| @ -664,7 +664,8 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( | ||||
| 						reference_doctype: me.frm.doctype, | ||||
| 						reference_name: me.frm.docname, | ||||
| 						content: __('Reason for hold: ')+data.reason_for_hold, | ||||
| 						comment_email: frappe.session.user | ||||
| 						comment_email: frappe.session.user, | ||||
| 						comment_by: frappe.session.user_fullname | ||||
| 					}, | ||||
| 					callback: function(r) { | ||||
| 						if(!r.exc) { | ||||
|  | ||||
| @ -41,8 +41,7 @@ | ||||
|  "charts": [ | ||||
|   { | ||||
|    "chart_name": "Bank Balance", | ||||
|    "label": "All Your Money", | ||||
|    "size": "Full" | ||||
|    "label": "Bank Balance" | ||||
|   } | ||||
|  ], | ||||
|  "creation": "2020-01-23 13:46:38.833076", | ||||
| @ -55,7 +54,7 @@ | ||||
|  "idx": 0, | ||||
|  "is_standard": 1, | ||||
|  "label": "Getting Started", | ||||
|  "modified": "2020-03-12 16:30:37.821762", | ||||
|  "modified": "2020-03-23 11:20:49.161823", | ||||
|  "modified_by": "Administrator", | ||||
|  "module": "Setup", | ||||
|  "name": "Getting Started", | ||||
| @ -82,6 +81,16 @@ | ||||
|    "is_query_report": 0, | ||||
|    "link_to": "Sales Invoice", | ||||
|    "type": "DocType" | ||||
|   }, | ||||
|   { | ||||
|    "is_query_report": 0, | ||||
|    "link_to": "dashboard", | ||||
|    "type": "Page" | ||||
|   }, | ||||
|   { | ||||
|    "is_query_report": 0, | ||||
|    "link_to": "leaderboard", | ||||
|    "type": "Page" | ||||
|   } | ||||
|  ] | ||||
| } | ||||
| @ -8,6 +8,7 @@ from frappe.utils import flt | ||||
| from frappe.model.meta import get_field_precision | ||||
| from frappe.model.document import Document | ||||
| from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos | ||||
| from erpnext.accounts.doctype.account.account import get_account_currency | ||||
| 
 | ||||
| class LandedCostVoucher(Document): | ||||
| 	def get_items_from_purchase_receipts(self): | ||||
| @ -43,6 +44,7 @@ class LandedCostVoucher(Document): | ||||
| 		else: | ||||
| 			self.validate_applicable_charges_for_item() | ||||
| 		self.validate_purchase_receipts() | ||||
| 		self.validate_expense_accounts() | ||||
| 		self.set_total_taxes_and_charges() | ||||
| 
 | ||||
| 	def check_mandatory(self): | ||||
| @ -71,6 +73,14 @@ class LandedCostVoucher(Document): | ||||
| 				frappe.throw(_("Row {0}: Cost center is required for an item {1}") | ||||
| 					.format(item.idx, item.item_code)) | ||||
| 
 | ||||
| 	def validate_expense_accounts(self): | ||||
| 		company_currency = erpnext.get_company_currency(self.company) | ||||
| 		for account in self.taxes: | ||||
| 			if get_account_currency(account.expense_account) != company_currency: | ||||
| 				frappe.throw(msg=_(""" Row {0}: Expense account currency should be same as company's default currency. | ||||
| 					Please select expense account with account currency as {1}""") | ||||
| 					.format(account.idx, frappe.bold(company_currency)), title=_("Invalid Account Currency")) | ||||
| 
 | ||||
| 	def set_total_taxes_and_charges(self): | ||||
| 		self.total_taxes_and_charges = sum([flt(d.amount) for d in self.get("taxes")]) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user