diff --git a/erpnext/__init__.py b/erpnext/__init__.py index d8122088b6..bd400c0870 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '10.0.9' +__version__ = '10.0.10' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index c457f9ad51..f6d43c7f70 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -142,7 +142,7 @@ class SalesInvoice(SellingController): self.update_time_sheet(self.name) - self.update_current_month_sales() + update_company_current_month_sales(self.company) self.update_project() def validate_pos_paid_amount(self): @@ -181,16 +181,9 @@ class SalesInvoice(SellingController): self.make_gl_entries_on_cancel() frappe.db.set(self, 'status', 'Cancelled') - self.update_current_month_sales() + update_company_current_month_sales(self.company) self.update_project() - def update_current_month_sales(self): - if frappe.flags.in_test: - update_company_current_month_sales(self.company) - else: - frappe.enqueue('erpnext.setup.doctype.company.company.update_company_current_month_sales', - company=self.company) - def update_status_updater_args(self): if cint(self.update_stock): self.status_updater.extend([{ @@ -675,28 +668,28 @@ class SalesInvoice(SellingController): # income account gl entries for item in self.get("items"): if flt(item.base_net_amount): - account_currency = get_account_currency(item.income_account) - gl_entries.append( - self.get_gl_dict({ - "account": item.income_account, - "against": self.customer, - "credit": item.base_net_amount, - "credit_in_account_currency": item.base_net_amount \ - if account_currency==self.company_currency else item.net_amount, - "cost_center": item.cost_center - }, account_currency) - ) - if item.is_fixed_asset: asset = frappe.get_doc("Asset", item.asset) - fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, is_sale=True) + fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, item.base_net_amount) for gle in fixed_asset_gl_entries: gle["against"] = self.customer gl_entries.append(self.get_gl_dict(gle)) asset.db_set("disposal_date", self.posting_date) asset.set_status("Sold" if self.docstatus==1 else None) + else: + account_currency = get_account_currency(item.income_account) + gl_entries.append( + self.get_gl_dict({ + "account": item.income_account, + "against": self.customer, + "credit": item.base_net_amount, + "credit_in_account_currency": item.base_net_amount \ + if account_currency==self.company_currency else item.net_amount, + "cost_center": item.cost_center + }, account_currency) + ) # expense account gl entries if cint(self.update_stock) and \ diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index 2bd5cc5577..fe3bb8cd4c 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -6,7 +6,6 @@ import frappe from frappe import _, scrub from erpnext.stock.utils import get_incoming_rate from erpnext.controllers.queries import get_match_cond -from erpnext.stock.stock_ledger import get_valuation_rate from frappe.utils import flt @@ -248,6 +247,7 @@ class GrossProfitGenerator(object): return 0.0 def get_average_buying_rate(self, row, item_code): + args = row if not item_code in self.average_buying_rate: if item_code in self.non_stock_items: self.average_buying_rate[item_code] = flt(frappe.db.sql(""" @@ -255,14 +255,14 @@ class GrossProfitGenerator(object): from `tabPurchase Invoice Item` where item_code = %s and docstatus=1""", item_code)[0][0]) else: - row.voucher_type = row.parenttype - row.voucher_no = row.parent - average_buying_rate = get_incoming_rate(row) - if not average_buying_rate: - average_buying_rate = get_valuation_rate(item_code, row.warehouse, - row.parenttype, row.parent, allow_zero_rate=row.allow_zero_valuation, - currency=self.filters.currency, company=self.filters.company) + args.update({ + 'voucher_type': row.parenttype, + 'voucher_no': row.parent, + 'allow_zero_valuation': True, + 'company': self.filters.company + }) + average_buying_rate = get_incoming_rate(args) self.average_buying_rate[item_code] = flt(average_buying_rate) return self.average_buying_rate[item_code] @@ -311,8 +311,7 @@ class GrossProfitGenerator(object): `tabSales Invoice Item`.brand, `tabSales Invoice Item`.dn_detail, `tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.stock_qty as qty, `tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount, - `tabSales Invoice Item`.name as "item_row", `tabSales Invoice`.is_return, - `tabSales Invoice Item`.allow_zero_valuation_rate as "allow_zero_valuation" + `tabSales Invoice Item`.name as "item_row", `tabSales Invoice`.is_return {sales_person_cols} from `tabSales Invoice` inner join `tabSales Invoice Item` diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 857aadef61..8bba0b6936 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -51,9 +51,6 @@ class Asset(Document): if not self.get(field): self.set(field, value) - self.value_after_depreciation = (flt(self.gross_purchase_amount) - - flt(self.opening_accumulated_depreciation)) - def validate_asset_values(self): if flt(self.expected_value_after_useful_life) >= flt(self.gross_purchase_amount): frappe.throw(_("Expected Value After Useful Life must be less than Gross Purchase Amount")) @@ -61,7 +58,10 @@ class Asset(Document): if not flt(self.gross_purchase_amount): frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError) - if not self.is_existing_asset and self.calculate_depreciation: + if not self.calculate_depreciation: + return + + if not self.is_existing_asset: self.opening_accumulated_depreciation = 0 self.number_of_depreciations_booked = 0 if not self.next_depreciation_date: @@ -81,6 +81,9 @@ class Asset(Document): if cint(self.number_of_depreciations_booked) > cint(self.total_number_of_depreciations): frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations")) + self.value_after_depreciation = (flt(self.gross_purchase_amount) - + flt(self.opening_accumulated_depreciation)) + if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(nowdate()): frappe.msgprint(_("Next Depreciation Date is entered as past date"), title=_('Warning'), indicator='red') @@ -106,12 +109,13 @@ class Asset(Document): n * cint(self.frequency_of_depreciation)) depreciation_amount = self.get_depreciation_amount(value_after_depreciation) - value_after_depreciation -= flt(depreciation_amount) + if depreciation_amount: + value_after_depreciation -= flt(depreciation_amount) - self.append("schedules", { - "schedule_date": schedule_date, - "depreciation_amount": depreciation_amount - }) + self.append("schedules", { + "schedule_date": schedule_date, + "depreciation_amount": depreciation_amount + }) def set_accumulated_depreciation(self): accumulated_depreciation = flt(self.opening_accumulated_depreciation) diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index c72cb968da..92a251e4fa 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -151,13 +151,11 @@ def restore_asset(asset_name): asset.set_status() @frappe.whitelist() -def get_gl_entries_on_asset_disposal(asset, is_sale=False): +def get_gl_entries_on_asset_disposal(asset, selling_amount=0): fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset) - accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation) + disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company) - expense_account, cost_center = get_disposal_account_and_cost_center(asset.company) - if is_sale: - expense_account = depr_expense_account + accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation) gl_entries = [ { @@ -172,12 +170,14 @@ def get_gl_entries_on_asset_disposal(asset, is_sale=False): } ] - if flt(asset.value_after_depreciation): + profit_amount = flt(selling_amount) - flt(asset.value_after_depreciation) + if profit_amount: + debit_or_credit = "debit" if profit_amount < 0 else "credit" gl_entries.append({ - "account": expense_account, - "cost_center": cost_center, - "debit": flt(asset.value_after_depreciation), - "debit_in_account_currency": flt(asset.value_after_depreciation) + "account": disposal_account, + "cost_center": depreciation_cost_center, + debit_or_credit: abs(profit_amount), + debit_or_credit + "_in_account_currency": abs(profit_amount) }) return gl_entries diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 107ffec038..76c46cff7a 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -234,9 +234,8 @@ class TestAsset(unittest.TestCase): expected_gle = ( ("_Test Accumulated Depreciations - _TC", 30000.0, 0.0), - ("_Test Depreciations - _TC", 70000.0, 0.0), ("_Test Fixed Asset - _TC", 0.0, 100000.0), - ("_Test Gain/Loss on Asset Disposal - _TC", 0.0, 25000.0), + ("_Test Gain/Loss on Asset Disposal - _TC", 45000.0, 0.0), ("Debtors - _TC", 25000.0, 0.0) ) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 81d2786c10..8de1a1219c 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -666,7 +666,7 @@ class AccountsController(TransactionBase): self.remove(item) def set_payment_schedule(self): - posting_date = self.get("posting_date") or self.get("transaction_date") + posting_date = self.get("bill_date") or self.get("posting_date") or self.get("transaction_date") date = self.get("due_date") due_date = date or posting_date grand_total = self.get("rounded_total") or self.grand_total diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index e198c7eecf..9ee82d2118 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -549,7 +549,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ final_message = final_message + message1; } - if (this.frm.doc.payment_schedule.length) { + if ((this.frm.doc.payment_schedule || []).length) { message2 = "Payment Schedule Table"; if (message1.length !== 0) message2 = " and " + message2; final_message = final_message + message2; @@ -1261,11 +1261,14 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ payment_terms_template: function() { var me = this; if(this.frm.doc.payment_terms_template) { + var posting_date = this.frm.doc.bill_date || + this.frm.doc.posting_date || this.frm.doc.transaction_date; + frappe.call({ method: "erpnext.controllers.accounts_controller.get_payment_terms", args: { terms_template: this.frm.doc.payment_terms_template, - posting_date: this.frm.doc.posting_date || this.frm.doc.transaction_date, + posting_date: posting_date, grand_total: this.frm.doc.rounded_total || this.frm.doc.grand_total }, callback: function(r) { diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 6c9e4501f8..eaa82b3713 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -146,7 +146,8 @@ class Customer(TransactionBase): frappe.throw(_("A Customer Group exists with same name please change the Customer name or rename the Customer Group"), frappe.NameError) def validate_credit_limit_on_change(self): - if self.get("__islocal") or self.credit_limit == frappe.db.get_value("Customer", self.name, "credit_limit"): + if self.get("__islocal") or not self.credit_limit \ + or self.credit_limit == frappe.db.get_value("Customer", self.name, "credit_limit"): return for company in frappe.get_all("Company"): diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js index 1863fb2a5e..84176426be 100644 --- a/erpnext/selling/doctype/quotation/quotation.js +++ b/erpnext/selling/doctype/quotation/quotation.js @@ -82,8 +82,8 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ get_query_filters: { status: ["not in", ["Lost", "Closed"]], company: me.frm.doc.company, - // cannot set enquiry_type as setter, as the fieldname is order_type - enquiry_type: me.frm.doc.order_type, + // cannot set opportunity_type as setter, as the fieldname is order_type + opportunity_type: me.frm.doc.order_type, } }) }, __("Get items from"), "btn-default"); diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 81b94bd91f..ac7c830675 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -287,7 +287,9 @@ class Company(Document): frappe.db.sql("delete from tabBOM where company=%s", self.name) for dt in ("BOM Operation", "BOM Item", "BOM Scrap Item", "BOM Explosion Item"): frappe.db.sql("delete from `tab%s` where parent in (%s)""" - % (dt, ', '.join(['%s']*len(boms))), tuple(boms), debug=1) + % (dt, ', '.join(['%s']*len(boms))), tuple(boms)) + + frappe.db.sql("delete from tabEmployee where company=%s", self.name) @frappe.whitelist() def enqueue_replace_abbr(company, old, new): @@ -356,7 +358,6 @@ def update_company_current_month_sales(company): monthly_total = results[0]['total'] if len(results) > 0 else 0 frappe.db.set_value("Company", company, "total_monthly_sales", monthly_total) - frappe.db.commit() def update_company_monthly_sales(company): '''Cache past year monthly sales of every company based on sales invoices''' @@ -367,7 +368,6 @@ def update_company_monthly_sales(company): "posting_date", filter_str, "sum") frappe.db.set_value("Company", company, "sales_monthly_history", json.dumps(month_to_value_dict)) - frappe.db.commit() def cache_companies_monthly_sales_history(): companies = [d['name'] for d in frappe.get_list("Company")] diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js index 9eb2313bb2..ed0597cd98 100644 --- a/erpnext/stock/doctype/material_request/material_request.js +++ b/erpnext/stock/doctype/material_request/material_request.js @@ -170,6 +170,8 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten d.description = item.description; d.warehouse = values.warehouse; d.uom = item.stock_uom; + d.stock_uom = item.stock_uom; + d.conversion_factor = 1; d.qty = item.qty; }); } @@ -282,4 +284,4 @@ function set_schedule_date(frm) { if(frm.doc.schedule_date){ erpnext.utils.copy_value_in_all_row(frm.doc, frm.doc.doctype, frm.doc.name, "items", "schedule_date"); } -} \ No newline at end of file +} diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py index ae71f355b6..9b2fcb7088 100644 --- a/erpnext/stock/utils.py +++ b/erpnext/stock/utils.py @@ -144,10 +144,9 @@ def get_incoming_rate(args): if not in_rate: voucher_no = args.get('voucher_no') or args.get('name') - in_rate = get_valuation_rate(args.get('item_code'), args.get('warehouse'), args.get('voucher_type'), voucher_no, args.get('allow_zero_valuation'), - currency=erpnext.get_company_currency(args.get('company'))) + currency=erpnext.get_company_currency(args.get('company')), company=args.get('company')) return in_rate diff --git a/erpnext/templates/print_formats/includes/total.html b/erpnext/templates/print_formats/includes/total.html index df3f49e024..c13bf92760 100644 --- a/erpnext/templates/print_formats/includes/total.html +++ b/erpnext/templates/print_formats/includes/total.html @@ -1,7 +1,7 @@