Merge branch 'develop'

This commit is contained in:
Nabin Hait 2017-05-06 13:40:52 +05:30
commit 3f7fff04f4
21 changed files with 162 additions and 73 deletions

View File

@ -2,7 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
__version__ = '8.0.22' __version__ = '8.0.23'
def get_default_company(user=None): def get_default_company(user=None):
'''Get default company for user''' '''Get default company for user'''

View File

@ -204,7 +204,7 @@ class PurchaseInvoice(BuyingController):
if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes': if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes':
for d in self.get('items'): for d in self.get('items'):
if not d.purchase_order: if not d.purchase_order:
throw(_("Purchse Order number required for Item {0}").format(d.item_code)) throw(_("Purchase Order number required for Item {0}").format(d.item_code))
def pr_required(self): def pr_required(self):
stock_items = self.get_stock_items() stock_items = self.get_stock_items()

View File

@ -341,13 +341,23 @@ class SalesInvoice(SellingController):
super(SalesInvoice, self).validate_with_previous_doc({ super(SalesInvoice, self).validate_with_previous_doc({
"Sales Order": { "Sales Order": {
"ref_dn_field": "sales_order", "ref_dn_field": "sales_order",
"compare_fields": [["customer", "="], ["company", "="], ["project", "="], "compare_fields": [["customer", "="], ["company", "="], ["project", "="], ["currency", "="]]
["currency", "="]], },
"Sales Order Item": {
"ref_dn_field": "so_detail",
"compare_fields": [["item_code", "="], ["uom", "="], ["conversion_factor", "="]],
"is_child_table": True,
"allow_duplicate_prev_row_id": True
}, },
"Delivery Note": { "Delivery Note": {
"ref_dn_field": "delivery_note", "ref_dn_field": "delivery_note",
"compare_fields": [["customer", "="], ["company", "="], ["project", "="], "compare_fields": [["customer", "="], ["company", "="], ["project", "="], ["currency", "="]]
["currency", "="]], },
"Delivery Note Item": {
"ref_dn_field": "dn_detail",
"compare_fields": [["item_code", "="], ["uom", "="], ["conversion_factor", "="]],
"is_child_table": True,
"allow_duplicate_prev_row_id": True
}, },
}) })

View File

@ -123,10 +123,10 @@ def round_off_debit_credit(gl_map):
debit_credit_diff = flt(debit_credit_diff, precision) debit_credit_diff = flt(debit_credit_diff, precision)
if gl_map[0]["voucher_type"] == "Journal Entry": if gl_map[0]["voucher_type"] in ("Journal Entry", "Payment Entry"):
allowance = 5.0 / (10**precision) allowance = 5.0 / (10**precision)
else: else:
allowance = 1 allowance = .5
if abs(debit_credit_diff) >= allowance: if abs(debit_credit_diff) >= allowance:
frappe.throw(_("Debit and Credit not equal for {0} #{1}. Difference is {2}.") frappe.throw(_("Debit and Credit not equal for {0} #{1}. Difference is {2}.")

View File

@ -20,7 +20,7 @@ def execute(filters=None):
invoice_expense_map, invoice_tax_map = get_invoice_tax_map(invoice_list, invoice_expense_map, invoice_tax_map = get_invoice_tax_map(invoice_list,
invoice_expense_map, expense_accounts) invoice_expense_map, expense_accounts)
invoice_po_pr_map = get_invoice_po_pr_map(invoice_list) invoice_po_pr_map = get_invoice_po_pr_map(invoice_list)
supplier_details = get_supplier_deatils(invoice_list) supplier_details = get_supplier_details(invoice_list)
company_currency = frappe.db.get_value("Company", filters.company, "default_currency") company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
@ -205,7 +205,7 @@ def get_account_details(invoice_list):
return account_map return account_map
def get_supplier_deatils(invoice_list): def get_supplier_details(invoice_list):
supplier_details = {} supplier_details = {}
suppliers = list(set([inv.supplier for inv in invoice_list])) suppliers = list(set([inv.supplier for inv in invoice_list]))
for supp in frappe.db.sql("""select name, supplier_type from `tabSupplier` for supp in frappe.db.sql("""select name, supplier_type from `tabSupplier`

View File

@ -59,7 +59,8 @@ class PurchaseOrder(BuyingController):
}, },
"Supplier Quotation Item": { "Supplier Quotation Item": {
"ref_dn_field": "supplier_quotation_item", "ref_dn_field": "supplier_quotation_item",
"compare_fields": [["rate", "="], ["project", "="], ["item_code", "="]], "compare_fields": [["rate", "="], ["project", "="], ["item_code", "="],
["uom", "="], ["conversion_factor", "="]],
"is_child_table": True "is_child_table": True
} }
}) })

View File

@ -15,6 +15,7 @@
"engine": "InnoDB", "engine": "InnoDB",
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -45,6 +46,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -76,6 +78,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 1, "bold": 1,
"collapsible": 0, "collapsible": 0,
@ -106,6 +109,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -136,6 +140,37 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "tax_id",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Tax ID",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -165,6 +200,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -193,6 +229,7 @@
"width": "50%" "width": "50%"
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -224,6 +261,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -254,6 +292,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 1, "bold": 1,
"collapsible": 0, "collapsible": 0,
@ -284,6 +323,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
@ -313,6 +353,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -342,6 +383,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -370,6 +412,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -399,6 +442,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
@ -428,6 +472,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -458,6 +503,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -487,6 +533,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -518,6 +565,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -546,6 +594,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -574,6 +623,7 @@
"width": "50%" "width": "50%"
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -602,6 +652,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
@ -631,6 +682,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -662,6 +714,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
@ -692,6 +745,7 @@
"width": "50%" "width": "50%"
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -722,6 +776,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -753,6 +808,7 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
@ -794,7 +850,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2017-03-14 17:04:17.785461", "modified": "2017-05-05 04:24:03.884380",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Buying", "module": "Buying",
"name": "Supplier", "name": "Supplier",

View File

@ -35,11 +35,7 @@ erpnext.PurchaseAnalytics = frappe.views.TreeGridReport.extend({
item_key: "supplier", item_key: "supplier",
parent_field: "parent_supplier_type", parent_field: "parent_supplier_type",
formatter: function(item) { formatter: function(item) {
// return repl('<a href="#Report/stock-invoices/customer=%(enc_value)s">%(value)s</a>', { return item.supplier_name ? item.supplier_name + " (" + item.name + ")" : item.name;
// value: item.name,
// enc_value: encodeURIComponent(item.name)
// });
return item.name;
} }
}, },
"Supplier": { "Supplier": {
@ -47,7 +43,7 @@ erpnext.PurchaseAnalytics = frappe.views.TreeGridReport.extend({
show: false, show: false,
item_key: "supplier", item_key: "supplier",
formatter: function(item) { formatter: function(item) {
return item.name; return item.supplier_name ? item.supplier_name + " (" + item.name + ")" : item.name;
} }
}, },
"Item Group": { "Item Group": {

View File

@ -64,7 +64,7 @@ def validate_for_items(doc):
validate_end_of_life(d.item_code, item.end_of_life, item.disabled) validate_end_of_life(d.item_code, item.end_of_life, item.disabled)
# validate stock item # validate stock item
if item.is_stock_item==1 and d.qty and not d.warehouse and not d.delivered_by_supplier: if item.is_stock_item==1 and d.qty and not d.warehouse and not d.get("delivered_by_supplier"):
frappe.throw(_("Warehouse is mandatory for stock Item {0} in row {1}").format(d.item_code, d.idx)) frappe.throw(_("Warehouse is mandatory for stock Item {0} in row {1}").format(d.item_code, d.idx))
items.append(cstr(d.item_code)) items.append(cstr(d.item_code))

View File

@ -360,7 +360,8 @@ def warehouse_query(doctype, txt, searchfield, start, page_len, filters):
sub_query = """ select round(`tabBin`.actual_qty, 2) from `tabBin` sub_query = """ select round(`tabBin`.actual_qty, 2) from `tabBin`
where `tabBin`.warehouse = `tabWarehouse`.name where `tabBin`.warehouse = `tabWarehouse`.name
{bin_conditions} """.format( {bin_conditions} """.format(
bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"), bin_conditions)) bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"), bin_conditions),
ignore_permissions=True)
response = frappe.db.sql("""select `tabWarehouse`.name, response = frappe.db.sql("""select `tabWarehouse`.name,
CONCAT_WS(" : ", "Actual Qty", ifnull( ({sub_query}), 0) ) as actual_qty CONCAT_WS(" : ", "Actual Qty", ifnull( ({sub_query}), 0) ) as actual_qty

View File

@ -170,7 +170,7 @@ class SellingController(StockController):
def validate_selling_price(self): def validate_selling_price(self):
def throw_message(item_name, rate, ref_rate_field): def throw_message(item_name, rate, ref_rate_field):
frappe.throw(_("""Selling price for item {0} is lower than its {1}. Selling price should be atleast {2}""") frappe.throw(_("""Selling rate for item {0} is lower than its {1}. Selling rate should be atleast {2}""")
.format(item_name, ref_rate_field, rate)) .format(item_name, ref_rate_field, rate))
if not frappe.db.get_single_value("Selling Settings", "validate_selling_price"): if not frappe.db.get_single_value("Selling Settings", "validate_selling_price"):
@ -178,18 +178,19 @@ class SellingController(StockController):
for it in self.get("items"): for it in self.get("items"):
last_purchase_rate, is_stock_item = frappe.db.get_value("Item", it.item_code, ["last_purchase_rate", "is_stock_item"]) last_purchase_rate, is_stock_item = frappe.db.get_value("Item", it.item_code, ["last_purchase_rate", "is_stock_item"])
last_purchase_rate_in_sales_uom = last_purchase_rate / (it.conversion_factor or 1)
if flt(it.base_rate) < flt(last_purchase_rate): if flt(it.base_rate) < flt(last_purchase_rate_in_sales_uom):
throw_message(it.item_name, last_purchase_rate, "last purchase rate") throw_message(it.item_name, last_purchase_rate_in_sales_uom, "last purchase rate")
last_valuation_rate = frappe.db.sql(""" last_valuation_rate = frappe.db.sql("""
SELECT valuation_rate FROM `tabStock Ledger Entry` WHERE item_code = %s SELECT valuation_rate FROM `tabStock Ledger Entry` WHERE item_code = %s
AND warehouse = %s AND valuation_rate > 0 AND warehouse = %s AND valuation_rate > 0
ORDER BY posting_date DESC, posting_time DESC, name DESC LIMIT 1 ORDER BY posting_date DESC, posting_time DESC, name DESC LIMIT 1
""", (it.item_code, it.warehouse)) """, (it.item_code, it.warehouse))
if last_valuation_rate:
if is_stock_item and flt(it.base_rate) < flt(last_valuation_rate): last_valuation_rate_in_sales_uom = last_valuation_rate[0][0] / (it.conversion_factor or 1)
throw_message(it.name, last_valuation_rate, "valuation rate") if is_stock_item and flt(it.base_rate) < flt(last_valuation_rate_in_sales_uom):
throw_message(it.name, last_valuation_rate_in_sales_uom, "valuation rate")
def get_item_list(self): def get_item_list(self):

View File

@ -321,9 +321,13 @@ class SalarySlip(TransactionBase):
def sum_components(self, component_type, total_field): def sum_components(self, component_type, total_field):
joining_date, relieving_date = frappe.db.get_value("Employee", self.employee, joining_date, relieving_date = frappe.db.get_value("Employee", self.employee,
["date_of_joining", "relieving_date"]) ["date_of_joining", "relieving_date"])
if not relieving_date: if not relieving_date:
relieving_date = getdate(self.end_date) relieving_date = getdate(self.end_date)
if not joining_date:
frappe.throw(_("Please set the Date Of Joining for employee {0}").format(frappe.bold(employee.employee)))
for d in self.get(component_type): for d in self.get(component_type):
if ((cint(d.depends_on_lwp) == 1 and not self.salary_slip_based_on_timesheet) or\ if ((cint(d.depends_on_lwp) == 1 and not self.salary_slip_based_on_timesheet) or\
getdate(self.start_date) < joining_date or getdate(self.end_date) > relieving_date): getdate(self.start_date) < joining_date or getdate(self.end_date) > relieving_date):

View File

@ -33,6 +33,7 @@ class SalaryStructure(Document):
for employee in self.get('employees'): for employee in self.get('employees'):
joining_date, relieving_date = frappe.db.get_value("Employee", employee.employee, joining_date, relieving_date = frappe.db.get_value("Employee", employee.employee,
["date_of_joining", "relieving_date"]) ["date_of_joining", "relieving_date"])
if employee.from_date and joining_date and getdate(employee.from_date) < joining_date: if employee.from_date and joining_date and getdate(employee.from_date) < joining_date:
frappe.throw(_("From Date {0} for Employee {1} cannot be before employee's joining Date {2}") frappe.throw(_("From Date {0} for Employee {1} cannot be before employee's joining Date {2}")
.format(employee.from_date, employee.employee, joining_date)) .format(employee.from_date, employee.employee, joining_date))

View File

@ -4,14 +4,17 @@ def set_default_role(doc, method):
'''Set customer, supplier, student based on email''' '''Set customer, supplier, student based on email'''
if frappe.flags.setting_role or frappe.flags.in_migrate: if frappe.flags.setting_role or frappe.flags.in_migrate:
return return
roles = frappe.get_roles(doc.name)
contact_name = frappe.get_value('Contact', dict(email_id=doc.email)) contact_name = frappe.get_value('Contact', dict(email_id=doc.email))
if contact_name: if contact_name:
contact = frappe.get_doc('Contact', contact_name) contact = frappe.get_doc('Contact', contact_name)
for link in contact.links: for link in contact.links:
frappe.flags.setting_role = True frappe.flags.setting_role = True
if link.link_doctype=='Customer': if link.link_doctype=='Customer' and 'Customer' not in roles:
doc.add_roles('Customer') doc.add_roles('Customer')
elif link.link_doctype=='Supplier': elif link.link_doctype=='Supplier' and 'Supplier' not in roles:
doc.add_roles('Supplier') doc.add_roles('Supplier')
elif frappe.get_value('Student', dict(student_email_id=doc.email)): elif frappe.get_value('Student', dict(student_email_id=doc.email)) and 'Student' not in roles:
doc.add_roles('Student') doc.add_roles('Student')

View File

@ -500,6 +500,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
}, },
get_exchange_rate: function(transaction_date, from_currency, to_currency, callback) { get_exchange_rate: function(transaction_date, from_currency, to_currency, callback) {
if (!transaction_date || !from_currency || !to_currency) return;
return frappe.call({ return frappe.call({
method: "erpnext.setup.utils.get_exchange_rate", method: "erpnext.setup.utils.get_exchange_rate",
args: { args: {
@ -563,14 +564,14 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
} }
}, },
conversion_factor: function(doc, cdt, cdn) { conversion_factor: function(doc, cdt, cdn, dont_fetch_price_list_rate) {
if(frappe.meta.get_docfield(cdt, "stock_qty", cdn)) { if(frappe.meta.get_docfield(cdt, "stock_qty", cdn)) {
var item = frappe.get_doc(cdt, cdn); var item = frappe.get_doc(cdt, cdn);
frappe.model.round_floats_in(item, ["qty", "conversion_factor"]); frappe.model.round_floats_in(item, ["qty", "conversion_factor"]);
item.stock_qty = flt(item.qty * item.conversion_factor, precision("stock_qty", item)); item.stock_qty = flt(item.qty * item.conversion_factor, precision("stock_qty", item));
refresh_field("stock_qty", item.name, item.parentfield); refresh_field("stock_qty", item.name, item.parentfield);
this.toggle_conversion_factor(item); this.toggle_conversion_factor(item);
this.apply_price_list(item, true); if(!dont_fetch_price_list_rate) this.apply_price_list(item, true);
} }
}, },
@ -581,7 +582,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
}, },
qty: function(doc, cdt, cdn) { qty: function(doc, cdt, cdn) {
this.conversion_factor(doc, cdt, cdn); this.conversion_factor(doc, cdt, cdn, true);
this.apply_pricing_rule(frappe.get_doc(cdt, cdn), true);
}, },
set_dynamic_labels: function() { set_dynamic_labels: function() {
@ -762,7 +764,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
if(calculate_taxes_and_totals) me.calculate_taxes_and_totals(); if(calculate_taxes_and_totals) me.calculate_taxes_and_totals();
return; return;
} }
return this.frm.call({ return this.frm.call({
method: "erpnext.accounts.doctype.pricing_rule.pricing_rule.apply_pricing_rule", method: "erpnext.accounts.doctype.pricing_rule.pricing_rule.apply_pricing_rule",
args: { args: args }, args: { args: args },

View File

@ -42,7 +42,7 @@ frappe.ui.form.on("Student Group", {
}, },
get_students: function(frm) { get_students: function(frm) {
if (frm.doc.group_based_on != "Activity") { if (frm.doc.group_based_on == "Batch" || frm.doc.group_based_on == "Course") {
var student_list = []; var student_list = [];
var max_roll_no = 0; var max_roll_no = 0;
$.each(frm.doc.students, function(i,d) { $.each(frm.doc.students, function(i,d) {

View File

@ -34,14 +34,16 @@ erpnext.SalesAnalytics = frappe.views.TreeGridReport.extend({
show: true, show: true,
item_key: "customer", item_key: "customer",
parent_field: "parent_customer_group", parent_field: "parent_customer_group",
formatter: function(item) { return item.customer_name || item.name; } formatter: function(item) {
return item.customer_name? item.customer_name + " (" + item.name + ")" : item.name;
}
}, },
"Customer": { "Customer": {
label: __("Customer"), label: __("Customer"),
show: false, show: false,
item_key: "customer", item_key: "customer",
formatter: function(item) { formatter: function(item) {
return item.customer_name || item.name; return item.customer_name? item.customer_name + " (" + item.name + ")" : item.name;
} }
}, },
"Item Group": { "Item Group": {
@ -67,7 +69,7 @@ erpnext.SalesAnalytics = frappe.views.TreeGridReport.extend({
item_key: "customer", item_key: "customer",
parent_field: "parent_territory", parent_field: "parent_territory",
formatter: function(item) { formatter: function(item) {
return item.name; return item.customer_name? item.customer_name + " (" + item.name + ")" : item.name;
} }
} }
} }

View File

@ -282,7 +282,7 @@ def replace_abbr(company, old, new):
if len(parts) == 1 or parts[1].lower() == old.lower(): if len(parts) == 1 or parts[1].lower() == old.lower():
frappe.rename_doc(dt, d[0], parts[0] + " - " + new) frappe.rename_doc(dt, d[0], parts[0] + " - " + new)
for dt in ["Account", "Cost Center", "Warehouse"]: for dt in ["Warehouse", "Account", "Cost Center"]:
_rename_record(dt) _rename_record(dt)
frappe.db.commit() frappe.db.commit()

View File

@ -117,18 +117,31 @@ class DeliveryNote(SellingController):
if not self.installation_status: self.installation_status = 'Not Installed' if not self.installation_status: self.installation_status = 'Not Installed'
def validate_with_previous_doc(self): def validate_with_previous_doc(self):
for fn in (("Sales Order", "against_sales_order", "so_detail"), super(DeliveryNote, self).validate_with_previous_doc({
("Sales Invoice", "against_sales_invoice", "si_detail")): "Sales Order": {
if filter(None, [getattr(d, fn[1], None) for d in self.get("items")]): "ref_dn_field": "against_sales_order",
super(DeliveryNote, self).validate_with_previous_doc({ "compare_fields": [["customer", "="], ["company", "="], ["project", "="], ["currency", "="]]
fn[0]: { },
"ref_dn_field": fn[1], "Sales Order Item": {
"compare_fields": [["customer", "="], ["company", "="], ["project", "="], "ref_dn_field": "so_detail",
["currency", "="]], "compare_fields": [["item_code", "="], ["uom", "="], ["conversion_factor", "="]],
}, "is_child_table": True,
}) "allow_duplicate_prev_row_id": True
},
"Sales Invoice": {
"ref_dn_field": "against_sales_invoice",
"compare_fields": [["customer", "="], ["company", "="], ["project", "="], ["currency", "="]]
},
"Sales Invoice Item": {
"ref_dn_field": "si_detail",
"compare_fields": [["item_code", "="], ["uom", "="], ["conversion_factor", "="]],
"is_child_table": True,
"allow_duplicate_prev_row_id": True
},
})
if cint(frappe.db.get_single_value('Selling Settings', 'maintain_same_sales_rate')) and not self.is_return: if cint(frappe.db.get_single_value('Selling Settings', 'maintain_same_sales_rate')) \
and not self.is_return:
self.validate_rate_with_reference_doc([["Sales Order", "against_sales_order", "so_detail"], self.validate_rate_with_reference_doc([["Sales Order", "against_sales_order", "so_detail"],
["Sales Invoice", "against_sales_invoice", "si_detail"]]) ["Sales Invoice", "against_sales_invoice", "si_detail"]])

View File

@ -142,7 +142,7 @@ class Item(WebsiteGenerator):
def make_route(self): def make_route(self):
if not self.route: if not self.route:
return cstr(frappe.db.get_value('Item Group', self.item_group, 'route')) + '/' + self.scrub(self.item_name) return cstr(frappe.db.get_value('Item Group', self.item_group, 'route')) + '/' + self.scrub(self.name)
def get_parents(self, context): def get_parents(self, context):
item_group, route = frappe.db.get_value('Item Group', self.item_group, ['name', 'route']) item_group, route = frappe.db.get_value('Item Group', self.item_group, ['name', 'route'])

View File

@ -36,7 +36,7 @@ DocType: Purchase Receipt Item,Required By,Cerute de
DocType: Delivery Note,Return Against Delivery Note,Reveni Împotriva livrare Nota DocType: Delivery Note,Return Against Delivery Note,Reveni Împotriva livrare Nota
DocType: Purchase Order,% Billed,% Facurat DocType: Purchase Order,% Billed,% Facurat
apps/erpnext/erpnext/controllers/sales_and_purchase_return.py +43,Exchange Rate must be same as {0} {1} ({2}),Rata de schimb trebuie să fie aceeași ca și {0} {1} ({2}) apps/erpnext/erpnext/controllers/sales_and_purchase_return.py +43,Exchange Rate must be same as {0} {1} ({2}),Rata de schimb trebuie să fie aceeași ca și {0} {1} ({2})
DocType: Sales Invoice,Customer Name,Nume client DocType: Sales Invoice,Customer Name,Cumpărător
DocType: Vehicle,Natural Gas,Gaz natural DocType: Vehicle,Natural Gas,Gaz natural
apps/erpnext/erpnext/setup/setup_wizard/setup_wizard.py +130,Bank account cannot be named as {0},Contul bancar nu poate fi numit ca {0} apps/erpnext/erpnext/setup/setup_wizard/setup_wizard.py +130,Bank account cannot be named as {0},Contul bancar nu poate fi numit ca {0}
DocType: Account,Heads (or groups) against which Accounting Entries are made and balances are maintained.,Heads (sau grupuri) față de care înregistrările contabile sunt făcute și soldurile sunt menținute. DocType: Account,Heads (or groups) against which Accounting Entries are made and balances are maintained.,Heads (sau grupuri) față de care înregistrările contabile sunt făcute și soldurile sunt menținute.
@ -893,7 +893,7 @@ DocType: Employee,Provide Email Address registered in company,Furnizarea Adresa
DocType: Shopping Cart Settings,Enable Checkout,activaţi Checkout DocType: Shopping Cart Settings,Enable Checkout,activaţi Checkout
apps/erpnext/erpnext/config/learn.py +202,Purchase Order to Payment,Comandă de aprovizionare de plata apps/erpnext/erpnext/config/learn.py +202,Purchase Order to Payment,Comandă de aprovizionare de plata
apps/erpnext/erpnext/stock/page/stock_balance/stock_balance.js +48,Projected Qty,Proiectat Cantitate apps/erpnext/erpnext/stock/page/stock_balance/stock_balance.js +48,Projected Qty,Proiectat Cantitate
DocType: Sales Invoice,Payment Due Date,Data scadentă de pla DocType: Sales Invoice,Payment Due Date,Scaden
apps/erpnext/erpnext/stock/doctype/item/item.js +340,Item Variant {0} already exists with same attributes,Postul Varianta {0} există deja cu aceleași atribute apps/erpnext/erpnext/stock/doctype/item/item.js +340,Item Variant {0} already exists with same attributes,Postul Varianta {0} există deja cu aceleași atribute
apps/erpnext/erpnext/stock/report/stock_ledger/stock_ledger.py +95,'Opening',&quot;Deschiderea&quot; apps/erpnext/erpnext/stock/report/stock_ledger/stock_ledger.py +95,'Opening',&quot;Deschiderea&quot;
apps/erpnext/erpnext/setup/doctype/email_digest/templates/default.html +130,Open To Do,Deschideți To Do apps/erpnext/erpnext/setup/doctype/email_digest/templates/default.html +130,Open To Do,Deschideți To Do
@ -3743,7 +3743,7 @@ apps/erpnext/erpnext/config/learn.py +107,Newsletters,Buletine
DocType: Stock Ledger Entry,Stock Ledger Entry,Stoc Ledger intrare DocType: Stock Ledger Entry,Stock Ledger Entry,Stoc Ledger intrare
apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +87,Same item has been entered multiple times,Același articol a fost introdus de mai multe ori apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py +87,Same item has been entered multiple times,Același articol a fost introdus de mai multe ori
DocType: Department,Leave Block List,Lista Concedii Blocate DocType: Department,Leave Block List,Lista Concedii Blocate
DocType: Sales Invoice,Tax ID,ID impozit DocType: Sales Invoice,Tax ID,Cod inregistrare fiscala
apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py +188,Item {0} is not setup for Serial Nos. Column must be blank,Articolul {0} nu este configurat pentru Numerotare Seriala. Coloana trebuie să fie vida apps/erpnext/erpnext/stock/doctype/serial_no/serial_no.py +188,Item {0} is not setup for Serial Nos. Column must be blank,Articolul {0} nu este configurat pentru Numerotare Seriala. Coloana trebuie să fie vida
DocType: Accounts Settings,Accounts Settings,Setări Conturi DocType: Accounts Settings,Accounts Settings,Setări Conturi
apps/erpnext/erpnext/schools/doctype/student_applicant/student_applicant.js +7,Approve,Aproba apps/erpnext/erpnext/schools/doctype/student_applicant/student_applicant.js +7,Approve,Aproba

1 DocType: Employee Salary Mode Mod de salariu
36 DocType: Delivery Note Return Against Delivery Note Reveni Împotriva livrare Nota
37 DocType: Purchase Order % Billed % Facurat
38 apps/erpnext/erpnext/controllers/sales_and_purchase_return.py +43 Exchange Rate must be same as {0} {1} ({2}) Rata de schimb trebuie să fie aceeași ca și {0} {1} ({2})
39 DocType: Sales Invoice Customer Name Nume client Cumpărător
40 DocType: Vehicle Natural Gas Gaz natural
41 apps/erpnext/erpnext/setup/setup_wizard/setup_wizard.py +130 Bank account cannot be named as {0} Contul bancar nu poate fi numit ca {0}
42 DocType: Account Heads (or groups) against which Accounting Entries are made and balances are maintained. Heads (sau grupuri) față de care înregistrările contabile sunt făcute și soldurile sunt menținute.
893 DocType: Job Applicant Hold Păstrarea / Ţinerea / Deţinerea
894 DocType: Employee Date of Joining Data Aderării
895 DocType: Naming Series Update Series Actualizare Series
896 DocType: Supplier Quotation Is Subcontracted Este subcontractată
897 DocType: Item Attribute Item Attribute Values Valori Postul Atribut
898 DocType: Examination Result Examination Result examinarea Rezultat
899 apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +788 Purchase Receipt Primirea de cumpărare
3743 DocType: Workstation per hour pe oră
3744 apps/erpnext/erpnext/config/buying.py +7 Purchasing cumpărare
3745 DocType: Announcement Announcement Anunţ
3746 DocType: Warehouse Account for the warehouse (Perpetual Inventory) will be created under this Account. Contul aferent depozitului (Inventar Permanent) va fi creat in cadrul acest Cont.
3747 apps/erpnext/erpnext/stock/doctype/warehouse/warehouse.py +123 Warehouse can not be deleted as stock ledger entry exists for this warehouse. Depozit nu pot fi șterse ca exista intrare stoc registrul pentru acest depozit.
3748 DocType: Company Distribution Distribuire
3749 apps/erpnext/erpnext/schools/doctype/fees/fees.js +27 Amount Paid Sumă plătită