diff --git a/erpnext/__init__.py b/erpnext/__init__.py index a55d0e7562..d1e9417db1 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from erpnext.hooks import regional_overrides -__version__ = '9.2.13' +__version__ = '9.2.14' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/pos_settings/pos_settings.py b/erpnext/accounts/doctype/pos_settings/pos_settings.py index 13a50042fb..bdfd969df7 100644 --- a/erpnext/accounts/doctype/pos_settings/pos_settings.py +++ b/erpnext/accounts/doctype/pos_settings/pos_settings.py @@ -12,8 +12,5 @@ class POSSettings(Document): def set_link_for_pos(self): link = 'pos' if self.use_pos_in_offline_mode else 'point-of-sale' - desktop_icon = frappe.db.get_value('Desktop Icon', - {'standard': 1, 'module_name': 'POS'}, 'name') - - if desktop_icon: - frappe.db.set_value('Desktop Icon', desktop_icon, 'link', link) \ No newline at end of file + frappe.db.sql(""" update `tabDesktop Icon` set link = '{0}' + where module_name like '%pos%'""".format(link)) \ No newline at end of file diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index f7aa341e12..bcce6a1613 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -593,7 +593,9 @@ def get_outstanding_invoices(party_type, party, account, condition=None): select ifnull(sum({payment_dr_or_cr}), 0) from `tabGL Entry` payment_gl_entry where payment_gl_entry.against_voucher_type = invoice_gl_entry.voucher_type - and payment_gl_entry.against_voucher = invoice_gl_entry.against_voucher + and if(invoice_gl_entry.voucher_type='Journal Entry', + payment_gl_entry.against_voucher = invoice_gl_entry.voucher_no, + payment_gl_entry.against_voucher = invoice_gl_entry.against_voucher) and payment_gl_entry.party_type = invoice_gl_entry.party_type and payment_gl_entry.party = invoice_gl_entry.party and payment_gl_entry.account = invoice_gl_entry.account diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 1ae99a3d3a..e3d61d9885 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -460,3 +460,4 @@ erpnext.patches.v9_0.remove_non_existing_warehouse_from_stock_settings execute:frappe.delete_doc_if_exists("DocType", "Program Fee") erpnext.patches.v9_0.update_employee_loan_details erpnext.patches.v9_2.delete_healthcare_domain_default_items +erpnext.patches.v9_2.rename_translated_domains_in_en diff --git a/erpnext/patches/v9_2/rename_translated_domains_in_en.py b/erpnext/patches/v9_2/rename_translated_domains_in_en.py new file mode 100644 index 0000000000..88ffbb7a3d --- /dev/null +++ b/erpnext/patches/v9_2/rename_translated_domains_in_en.py @@ -0,0 +1,26 @@ +import frappe +from frappe import _ + +def execute(): + language = frappe.get_single("System Settings").language + + if language.startswith('en'): return + + all_domains = frappe.get_hooks("domains") + + for domain in all_domains: + translated_domain = _(domain, lang=language) + if frappe.db.exists("Domain", translated_domain): + frappe.rename_doc("Domain", translated_domain, domain, ignore_permissions=True, merge=True) + + domain_settings = frappe.get_single("Domain Settings") + active_domains = [d.domain for d in domain_settings.active_domains] + + for domain in active_domains: + domain = frappe.get_doc("Domain", domain) + domain.setup_domain() + + if int(frappe.db.get_single_value('System Settings', 'setup_complete')): + domain.setup_sidebar_items() + domain.setup_desktop_icons() + domain.set_default_portal_role() diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index adde913fb6..b167bcda6c 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -991,7 +991,7 @@ class POSItems { this.get_items({search_value: search_term, item_group }) .then(({ items, serial_no, batch_no, barcode }) => { - if (search_term) { + if (search_term && !barcode) { this.search_index[search_term] = items; } diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.js b/erpnext/setup/doctype/sales_partner/sales_partner.js index b1c18d67c7..30c2c91d6f 100644 --- a/erpnext/setup/doctype/sales_partner/sales_partner.js +++ b/erpnext/setup/doctype/sales_partner/sales_partner.js @@ -3,7 +3,7 @@ frappe.ui.form.on('Sales Partner', { refresh: function(frm) { - frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Person'} + frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Partner'} if(frm.doc.__islocal){ hide_field(['address_html', 'contact_html', 'address_contacts']); diff --git a/erpnext/setup/setup_wizard/install_fixtures.py b/erpnext/setup/setup_wizard/install_fixtures.py index e6a4a81959..0f98214e5c 100644 --- a/erpnext/setup/setup_wizard/install_fixtures.py +++ b/erpnext/setup/setup_wizard/install_fixtures.py @@ -14,12 +14,12 @@ default_lead_sources = ["Existing Customer", "Reference", "Advertisement", def install(country=None): records = [ # domains - { 'doctype': 'Domain', 'domain': _('Distribution')}, - { 'doctype': 'Domain', 'domain': _('Manufacturing')}, - { 'doctype': 'Domain', 'domain': _('Retail')}, - { 'doctype': 'Domain', 'domain': _('Services')}, - { 'doctype': 'Domain', 'domain': _('Education')}, - { 'doctype': 'Domain', 'domain': _('Healthcare')}, + { 'doctype': 'Domain', 'domain': 'Distribution'}, + { 'doctype': 'Domain', 'domain': 'Manufacturing'}, + { 'doctype': 'Domain', 'domain': 'Retail'}, + { 'doctype': 'Domain', 'domain': 'Services'}, + { 'doctype': 'Domain', 'domain': 'Education'}, + { 'doctype': 'Domain', 'domain': 'Healthcare'}, # Setup Progress {'doctype': "Setup Progress", "actions": [ diff --git a/erpnext/setup/setup_wizard/setup_wizard.py b/erpnext/setup/setup_wizard/setup_wizard.py index 766f9b5223..28e617faf7 100644 --- a/erpnext/setup/setup_wizard/setup_wizard.py +++ b/erpnext/setup/setup_wizard/setup_wizard.py @@ -40,7 +40,7 @@ def setup_complete(args=None): frappe.local.message_log = [] domain_settings = frappe.get_single('Domain Settings') - domain_settings.set_active_domains([_(args.get('domain'))]) + domain_settings.set_active_domains([args.get('domain')]) frappe.db.commit() login_as_first_user(args) @@ -186,10 +186,6 @@ def set_defaults(args): hr_settings.emp_created_by = "Naming Series" hr_settings.save() - domain_settings = frappe.get_doc("Domain Settings") - domain_settings.append('active_domains', dict(domain=_(args.get('domain')))) - domain_settings.save() - def create_feed_and_todo(): """update Activity feed and create todo for creation of item, customer, vendor""" add_info_comment(**{ diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py index 9b49b69209..626a9db97f 100644 --- a/erpnext/stock/doctype/bin/bin.py +++ b/erpnext/stock/doctype/bin/bin.py @@ -88,10 +88,11 @@ class Bin(Document): and item.source_warehouse = %s and pro.status not in ("Stopped", "Completed")''', (self.item_code, self.warehouse))[0][0] - self.set_projected_qty() + if self.reserved_qty_for_production: + self.set_projected_qty() - self.db_set('reserved_qty_for_production', self.reserved_qty_for_production) - self.db_set('projected_qty', self.projected_qty) + self.db_set('reserved_qty_for_production', self.reserved_qty_for_production) + self.db_set('projected_qty', self.projected_qty) def update_item_projected_qty(item_code): diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 5315253f7e..853b20dd22 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -14,8 +14,6 @@ frappe.ui.form.on('Stock Entry', { ] } }); - // }, - // onload_post_render: function(frm) { frm.set_query('batch_no', 'items', function(doc, cdt, cdn) { var item = locals[cdt][cdn]; @@ -40,9 +38,8 @@ frappe.ui.form.on('Stock Entry', { } } }); - - }, + refresh: function(frm) { if(!frm.doc.docstatus) { frm.add_custom_button(__('Make Material Request'), function() { @@ -73,10 +70,12 @@ frappe.ui.form.on('Stock Entry', { frm.trigger("toggle_display_account_head"); } }, + purpose: function(frm) { frm.fields_dict.items.grid.refresh(); frm.cscript.toggle_related_fields(frm.doc); }, + company: function(frm) { if(frm.doc.company) { var company_doc = frappe.get_doc(":Company", frm.doc.company); @@ -86,6 +85,7 @@ frappe.ui.form.on('Stock Entry', { frm.trigger("toggle_display_account_head"); } }, + set_serial_no: function(frm, cdt, cdn) { var d = frappe.model.get_doc(cdt, cdn); if(!d.item_code && !d.s_warehouse && !d.qty) return; @@ -104,20 +104,142 @@ frappe.ui.form.on('Stock Entry', { } }); }, + toggle_display_account_head: function(frm) { var enabled = erpnext.is_perpetual_inventory_enabled(frm.doc.company); frm.fields_dict["items"].grid.set_column_disp(["cost_center", "expense_account"], enabled); - } + }, + + set_basic_rate: function(frm, cdt, cdn, callback) { + const item = locals[cdt][cdn]; + item.transfer_qty = flt(item.qty) * flt(item.conversion_factor); + + const args = { + 'item_code' : item.item_code, + 'posting_date' : frm.doc.posting_date, + 'posting_time' : frm.doc.posting_time, + 'warehouse' : cstr(item.s_warehouse) || cstr(item.t_warehouse), + 'serial_no ' : item.serial_no, + 'company' : frm.doc.company, + 'qty' : item.s_warehouse ? -1*flt(item.transfer_qty) : flt(item.transfer_qty) + }; + + frappe.call({ + method: "erpnext.stock.utils.get_incoming_rate", + args: { + args: args + }, + callback: function(r) { + frappe.model.set_value(cdt, cdn, 'basic_rate', r.message); + frm.events.calculate_basic_amount(frm, item); + + if (callback) { + callback(); + } + } + }) + }, + + get_warehouse_details: function(frm, cdt, cdn, callback) { + var child = locals[cdt][cdn]; + if(!child.bom_no) { + frappe.call({ + method: "erpnext.stock.doctype.stock_entry.stock_entry.get_warehouse_details", + args: { + "args": { + 'item_code': child.item_code, + 'warehouse': cstr(child.s_warehouse) || cstr(child.t_warehouse), + 'transfer_qty': child.transfer_qty, + 'serial_no': child.serial_no, + 'qty': child.s_warehouse ? -1* child.transfer_qty : child.transfer_qty, + 'posting_date': frm.doc.posting_date, + 'posting_time': frm.doc.posting_time + } + }, + callback: function(r) { + if (!r.exc) { + $.extend(child, r.message); + frm.events.calculate_basic_amount(frm, child); + } + + if (callback) { + callback(); + } + } + }); + } + }, + + calculate_basic_amount: function(frm, item) { + item.basic_amount = flt(flt(item.transfer_qty) * flt(item.basic_rate), + precision("basic_amount", item)); + + frm.events.calculate_amount(frm); + }, + + calculate_amount: function(frm) { + frm.events.calculate_total_additional_costs(frm); + + const total_basic_amount = frappe.utils.sum( + (frm.doc.items || []).map(function(i) { return i.t_warehouse ? flt(i.basic_amount) : 0; }) + ); + + for (let i in frm.doc.items) { + let item = frm.doc.items[i]; + + if (item.t_warehouse && total_basic_amount) { + item.additional_cost = (flt(item.basic_amount) / total_basic_amount) * frm.doc.total_additional_costs; + } else { + item.additional_cost = 0; + } + + item.amount = flt(item.basic_amount + flt(item.additional_cost), + precision("amount", item)); + + item.valuation_rate = flt(flt(item.basic_rate) + + (flt(item.additional_cost) / flt(item.transfer_qty)), + precision("valuation_rate", item)); + } + + refresh_field('items'); + }, + + calculate_total_additional_costs: function(frm) { + const total_additional_costs = frappe.utils.sum( + (frm.doc.additional_costs || []).map(function(c) { return flt(c.amount); }) + ); + + frm.set_value("total_additional_costs", + flt(total_additional_costs, precision("total_additional_costs"))); + }, }) frappe.ui.form.on('Stock Entry Detail', { qty: function(frm, cdt, cdn) { - frm.events.set_serial_no(frm, cdt, cdn); + frm.events.set_basic_rate(frm, cdt, cdn, () => { + frm.events.set_serial_no(frm, cdt, cdn); + }); + }, + + conversion_factor: function(frm, cdt, cdn) { + frm.events.set_basic_rate(frm, cdt, cdn); }, s_warehouse: function(frm, cdt, cdn) { - frm.events.set_serial_no(frm, cdt, cdn); + frm.events.get_warehouse_details(frm, cdt, cdn, () => { + frm.events.set_serial_no(frm, cdt, cdn); + }); }, + + t_warehouse: function(frm, cdt, cdn) { + frm.events.get_warehouse_details(frm, cdt, cdn); + }, + + basic_rate: function(frm, cdt, cdn) { + var item = locals[cdt][cdn]; + frm.events.calculate_basic_amount(frm, item); + }, + barcode: function(doc, cdt, cdn) { var d = locals[cdt][cdn]; if (d.barcode) { @@ -132,6 +254,7 @@ frappe.ui.form.on('Stock Entry Detail', { }); } }, + uom: function(doc, cdt, cdn) { var d = locals[cdt][cdn]; if(d.uom && d.item_code){ @@ -150,6 +273,7 @@ frappe.ui.form.on('Stock Entry Detail', { }); } }, + item_code: function(frm, cdt, cdn) { var d = locals[cdt][cdn]; if(d.item_code) { @@ -191,7 +315,7 @@ frappe.ui.form.on('Stock Entry Detail', { frappe.ui.form.on('Landed Cost Taxes and Charges', { amount: function(frm) { - frm.events.calculate_amount(); + frm.events.calculate_amount(frm); } }); @@ -330,12 +454,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ } }, - qty: function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; - d.transfer_qty = flt(d.qty) * flt(d.conversion_factor); - this.calculate_basic_amount(d); - }, - production_order: function() { var me = this; this.toggle_enable_bom(); @@ -434,88 +552,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ erpnext.setup_serial_no(); }, - basic_rate: function(doc, cdt, cdn) { - var item = frappe.model.get_doc(cdt, cdn); - this.calculate_basic_amount(item); - }, - - s_warehouse: function(doc, cdt, cdn) { - this.get_warehouse_details(doc, cdt, cdn) - }, - - t_warehouse: function(doc, cdt, cdn) { - this.get_warehouse_details(doc, cdt, cdn) - }, - - get_warehouse_details: function(doc, cdt, cdn) { - var me = this; - var d = locals[cdt][cdn]; - if(!d.bom_no) { - frappe.call({ - method: "erpnext.stock.doctype.stock_entry.stock_entry.get_warehouse_details", - args: { - "args": { - 'item_code': d.item_code, - 'warehouse': cstr(d.s_warehouse) || cstr(d.t_warehouse), - 'transfer_qty': d.transfer_qty, - 'serial_no': d.serial_no, - 'qty': d.s_warehouse ? -1* d.qty : d.qty, - 'posting_date': this.frm.doc.posting_date, - 'posting_time': this.frm.doc.posting_time - } - }, - callback: function(r) { - if (!r.exc) { - $.extend(d, r.message); - me.calculate_basic_amount(d); - } - } - }); - } - }, - - calculate_basic_amount: function(item) { - item.basic_amount = flt(flt(item.transfer_qty) * flt(item.basic_rate), - precision("basic_amount", item)); - - this.calculate_amount(); - }, - - calculate_amount: function() { - this.calculate_total_additional_costs(); - - var total_basic_amount = frappe.utils.sum( - (this.frm.doc.items || []).map(function(i) { return i.t_warehouse ? flt(i.basic_amount) : 0; }) - ); - - for (var i in this.frm.doc.items) { - var item = this.frm.doc.items[i]; - - if (item.t_warehouse && total_basic_amount) { - item.additional_cost = (flt(item.basic_amount) / total_basic_amount) * this.frm.doc.total_additional_costs; - } else { - item.additional_cost = 0; - } - - item.amount = flt(item.basic_amount + flt(item.additional_cost), - precision("amount", item)); - - item.valuation_rate = flt(flt(item.basic_rate) - + (flt(item.additional_cost) / flt(item.transfer_qty)), - precision("valuation_rate", item)); - } - - refresh_field('items'); - }, - - calculate_total_additional_costs: function() { - var total_additional_costs = frappe.utils.sum( - (this.frm.doc.additional_costs || []).map(function(c) { return flt(c.amount); }) - ); - - this.frm.set_value("total_additional_costs", flt(total_additional_costs, precision("total_additional_costs"))); - }, - toggle_related_fields: function(doc) { this.frm.toggle_enable("from_warehouse", doc.purpose!='Material Receipt'); this.frm.toggle_enable("to_warehouse", doc.purpose!='Material Issue'); diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index fc45f13602..4d79e13d74 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -517,7 +517,7 @@ class StockEntry(StockController): args['posting_date'] = self.posting_date args['posting_time'] = self.posting_time - stock_and_rate = args.get('warehouse') and get_warehouse_details(args) or {} + stock_and_rate = get_warehouse_details(args) if args.get('warehouse') else {} ret.update(stock_and_rate) # automatically select batch for outgoing item