Merge branch 'develop'
This commit is contained in:
commit
3f7fff04f4
@ -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'''
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -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}.")
|
||||||
|
@ -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`
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -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",
|
||||||
|
@ -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": {
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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))
|
||||||
|
@ -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')
|
||||||
|
@ -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 },
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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"]])
|
||||||
|
|
||||||
|
@ -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'])
|
||||||
|
@ -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 plată
|
DocType: Sales Invoice,Payment Due Date,Scadentă
|
||||||
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',"Deschiderea"
|
apps/erpnext/erpnext/stock/report/stock_ledger/stock_ledger.py +95,'Opening',"Deschiderea"
|
||||||
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
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user