From 210317c0b5e8cb50d7226fc9a796adfe9ec3be5e Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Fri, 23 Aug 2019 00:21:26 +0530 Subject: [PATCH 01/10] fix: division by zero in asset Depereciation (#18637) * fix: division by zero in asset Depereciation * fix: requested changes --- erpnext/assets/doctype/asset/asset.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 45d2ec2c51..ab37e91538 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -255,9 +255,15 @@ class Asset(AccountsController): precision = self.precision("gross_purchase_amount") if row.depreciation_method in ("Straight Line", "Manual"): + depreciation_left = (cint(row.total_number_of_depreciations) - cint(self.number_of_depreciations_booked)) + + if not depreciation_left: + frappe.msgprint(_("All the depreciations has been booked")) + depreciation_amount = flt(row.expected_value_after_useful_life) + return depreciation_amount + depreciation_amount = (flt(row.value_after_depreciation) - - flt(row.expected_value_after_useful_life)) / (cint(row.total_number_of_depreciations) - - cint(self.number_of_depreciations_booked)) + flt(row.expected_value_after_useful_life)) / depreciation_left else: depreciation_amount = flt(depreciable_value * (flt(row.rate_of_depreciation) / 100), precision) @@ -275,7 +281,7 @@ class Asset(AccountsController): flt(accumulated_depreciation_after_full_schedule), self.precision('gross_purchase_amount')) - if (row.expected_value_after_useful_life and + if (row.expected_value_after_useful_life and row.expected_value_after_useful_life < asset_value_after_full_schedule): frappe.throw(_("Depreciation Row {0}: Expected value after useful life must be greater than or equal to {1}") .format(row.idx, asset_value_after_full_schedule)) From 88ee7d8dbeb62ff080247089219e2783d26c41d3 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Fri, 23 Aug 2019 11:13:58 +0530 Subject: [PATCH 02/10] fix: POS Sync Issue (#18807) --- erpnext/accounts/doctype/sales_invoice/pos.py | 15 ++++----------- erpnext/accounts/page/pos/pos.js | 11 ++--------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py index 479548c6e3..e290b235a9 100755 --- a/erpnext/accounts/doctype/sales_invoice/pos.py +++ b/erpnext/accounts/doctype/sales_invoice/pos.py @@ -432,7 +432,6 @@ def get_customer_id(doc, customer=None): return cust_id - def make_customer_and_address(customers): customers_list = [] for customer, data in iteritems(customers): @@ -449,7 +448,6 @@ def make_customer_and_address(customers): frappe.db.commit() return customers_list - def add_customer(data): customer = data.get('full_name') or data.get('customer') if frappe.db.exists("Customer", customer.strip()): @@ -466,21 +464,18 @@ def add_customer(data): frappe.db.commit() return customer_doc.name - def get_territory(data): if data.get('territory'): return data.get('territory') return frappe.db.get_single_value('Selling Settings','territory') or _('All Territories') - def get_customer_group(data): if data.get('customer_group'): return data.get('customer_group') return frappe.db.get_single_value('Selling Settings', 'customer_group') or frappe.db.get_value('Customer Group', {'is_group': 0}, 'name') - def make_contact(args, customer): if args.get('email_id') or args.get('phone'): name = frappe.db.get_value('Dynamic Link', @@ -506,7 +501,6 @@ def make_contact(args, customer): doc.flags.ignore_mandatory = True doc.save(ignore_permissions=True) - def make_address(args, customer): if not args.get('address_line1'): return @@ -521,7 +515,10 @@ def make_address(args, customer): address = frappe.get_doc('Address', name) else: address = frappe.new_doc('Address') - address.country = frappe.get_cached_value('Company', args.get('company'), 'country') + if args.get('company'): + address.country = frappe.get_cached_value('Company', + args.get('company'), 'country') + address.append('links', { 'link_doctype': 'Customer', 'link_name': customer @@ -533,7 +530,6 @@ def make_address(args, customer): address.flags.ignore_mandatory = True address.save(ignore_permissions=True) - def make_email_queue(email_queue): name_list = [] for key, data in iteritems(email_queue): @@ -550,7 +546,6 @@ def make_email_queue(email_queue): return name_list - def validate_item(doc): for item in doc.get('items'): if not frappe.db.exists('Item', item.get('item_code')): @@ -569,7 +564,6 @@ def validate_item(doc): item_doc.save(ignore_permissions=True) frappe.db.commit() - def submit_invoice(si_doc, name, doc, name_list): try: si_doc.insert() @@ -585,7 +579,6 @@ def submit_invoice(si_doc, name, doc, name_list): return name_list - def save_invoice(doc, name, name_list): try: if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}): diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index 3834c96bfb..b5a02d0e49 100755 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -1762,18 +1762,11 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.si_docs = this.get_submitted_invoice() || []; this.email_queue_list = this.get_email_queue() || {}; this.customers_list = this.get_customers_details() || {}; - if(this.customer_doc) { - this.freeze = this.customer_doc.display - } - - freeze_screen = this.freeze_screen || false; - - if ((this.si_docs.length || this.email_queue_list || this.customers_list) && !this.freeze) { - this.freeze = true; + if (this.si_docs.length || this.email_queue_list || this.customers_list) { frappe.call({ method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice", - freeze: freeze_screen, + freeze: true, args: { doc_list: me.si_docs, email_queue_list: me.email_queue_list, From db88476f8b48965565bb0c45dd9a040e3d76bac2 Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Fri, 23 Aug 2019 11:27:00 +0530 Subject: [PATCH 03/10] feat: refactor invoice_discounting (#18629) * feat: refactor invoice_discountig * Update invoice_discounting.py * Update invoice_discounting.js --- .../discounted_invoice.json | 13 ++++- .../invoice_discounting.js | 53 +++++++++++++------ .../invoice_discounting.py | 13 ++++- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.json b/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.json index 8d7ed74eb9..04d6303774 100644 --- a/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.json +++ b/erpnext/accounts/doctype/discounted_invoice/discounted_invoice.json @@ -8,7 +8,8 @@ "customer", "column_break_3", "posting_date", - "outstanding_amount" + "outstanding_amount", + "debit_to" ], "fields": [ { @@ -48,10 +49,18 @@ { "fieldname": "column_break_3", "fieldtype": "Column Break" + }, + { + "fetch_from": "sales_invoice.debit_to", + "fieldname": "debit_to", + "fieldtype": "Link", + "label": "Debit to", + "options": "Account", + "read_only": 1 } ], "istable": 1, - "modified": "2019-05-30 19:27:29.436153", + "modified": "2019-08-07 15:13:55.808349", "modified_by": "Administrator", "module": "Accounts", "name": "Discounted Invoice", diff --git a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js index 5563f031bb..f1f88a8d64 100644 --- a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js +++ b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js @@ -13,41 +13,57 @@ frappe.ui.form.on('Invoice Discounting', { }; }); - frm.events.filter_accounts("bank_account", frm, {"account_type": "Bank"}); - frm.events.filter_accounts("bank_charges_account", frm, {"root_type": "Expense"}); - frm.events.filter_accounts("short_term_loan", frm, {"root_type": "Liability"}); - frm.events.filter_accounts("accounts_receivable_credit", frm, {"account_type": "Receivable"}); - frm.events.filter_accounts("accounts_receivable_discounted", frm, {"account_type": "Receivable"}); - frm.events.filter_accounts("accounts_receivable_unpaid", frm, {"account_type": "Receivable"}); + + frm.events.filter_accounts("bank_account", frm, [["account_type", "=", "Bank"]]); + frm.events.filter_accounts("bank_charges_account", frm, [["root_type", "=", "Expense"]]); + frm.events.filter_accounts("short_term_loan", frm, [["root_type", "=", "Liability"]]); + frm.events.filter_accounts("accounts_receivable_discounted", frm, [["account_type", "=", "Receivable"]]); + frm.events.filter_accounts("accounts_receivable_credit", frm, [["account_type", "=", "Receivable"]]); + frm.events.filter_accounts("accounts_receivable_unpaid", frm, [["account_type", "=", "Receivable"]]); }, filter_accounts: (fieldname, frm, addl_filters) => { - let filters = { - "company": frm.doc.company, - "is_group": 0 - }; - if(addl_filters) Object.assign(filters, addl_filters); + let filters = [ + ["company", "=", frm.doc.company], + ["is_group", "=", 0] + ]; + if(addl_filters){ + filters = $.merge(filters , addl_filters); + } frm.set_query(fieldname, () => { return { "filters": filters }; }); }, + refresh_filters: (frm) =>{ + let invoice_accounts = Object.keys(frm.doc.invoices).map(function(key) { + return frm.doc.invoices[key].debit_to; + }); + let filters = [ + ["account_type", "=", "Receivable"], + ["name", "not in", invoice_accounts] + ]; + frm.events.filter_accounts("accounts_receivable_credit", frm, filters); + frm.events.filter_accounts("accounts_receivable_discounted", frm, filters); + frm.events.filter_accounts("accounts_receivable_unpaid", frm, filters); + }, + refresh: (frm) => { frm.events.show_general_ledger(frm); - if(frm.doc.docstatus === 0) { + if (frm.doc.docstatus === 0) { frm.add_custom_button(__('Get Invoices'), function() { frm.events.get_invoices(frm); }); } - if(frm.doc.docstatus === 1 && frm.doc.status !== "Settled") { - if(frm.doc.status == "Sanctioned") { + if (frm.doc.docstatus === 1 && frm.doc.status !== "Settled") { + if (frm.doc.status == "Sanctioned") { frm.add_custom_button(__('Disburse Loan'), function() { frm.events.create_disbursement_entry(frm); }).addClass("btn-primary"); } - if(frm.doc.status == "Disbursed") { + if (frm.doc.status == "Disbursed") { frm.add_custom_button(__('Close Loan'), function() { frm.events.close_loan(frm); }).addClass("btn-primary"); @@ -64,7 +80,7 @@ frappe.ui.form.on('Invoice Discounting', { }, set_end_date: (frm) => { - if(frm.doc.loan_start_date && frm.doc.loan_period) { + if (frm.doc.loan_start_date && frm.doc.loan_period) { let end_date = frappe.datetime.add_days(frm.doc.loan_start_date, frm.doc.loan_period); frm.set_value("loan_end_date", end_date); } @@ -132,6 +148,7 @@ frappe.ui.form.on('Invoice Discounting', { frm.doc.invoices = frm.doc.invoices.filter(row => row.sales_invoice); let row = frm.add_child("invoices"); $.extend(row, v); + frm.events.refresh_filters(frm); }); refresh_field("invoices"); } @@ -190,8 +207,10 @@ frappe.ui.form.on('Invoice Discounting', { frappe.ui.form.on('Discounted Invoice', { sales_invoice: (frm) => { frm.events.calculate_total_amount(frm); + frm.events.refresh_filters(frm); }, invoices_remove: (frm) => { frm.events.calculate_total_amount(frm); + frm.events.refresh_filters(frm); } -}); \ No newline at end of file +}); diff --git a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py index 29475d5644..36c29113ea 100644 --- a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py +++ b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py @@ -12,6 +12,7 @@ from erpnext.accounts.general_ledger import make_gl_entries class InvoiceDiscounting(AccountsController): def validate(self): self.validate_mandatory() + self.validate_invoices() self.calculate_total_amount() self.set_status() self.set_end_date() @@ -24,6 +25,15 @@ class InvoiceDiscounting(AccountsController): if self.docstatus == 1 and not (self.loan_start_date and self.loan_period): frappe.throw(_("Loan Start Date and Loan Period are mandatory to save the Invoice Discounting")) + def validate_invoices(self): + discounted_invoices = [record.sales_invoice for record in + frappe.get_all("Discounted Invoice",fields = ["sales_invoice"], filters= {"docstatus":1})] + + for record in self.invoices: + if record.sales_invoice in discounted_invoices: + frappe.throw("Row({0}): {1} is already discounted in {2}" + .format(record.idx, frappe.bold(record.sales_invoice), frappe.bold(record.parent))) + def calculate_total_amount(self): self.total_amount = sum([flt(d.outstanding_amount) for d in self.invoices]) @@ -212,7 +222,8 @@ def get_invoices(filters): name as sales_invoice, customer, posting_date, - outstanding_amount + outstanding_amount, + debit_to from `tabSales Invoice` si where docstatus = 1 From 680e098b872f51c9c2b1e899b5548c492b8d7873 Mon Sep 17 00:00:00 2001 From: Michelle Alva <50285544+michellealva@users.noreply.github.com> Date: Fri, 23 Aug 2019 11:32:43 +0530 Subject: [PATCH 04/10] fix(dash): Added Tax exemption category and sub category in Employee Tax and Benefits (#18545) section From 56d03a456b44890602ddd00130107893f6f223e1 Mon Sep 17 00:00:00 2001 From: Harshit <46772424+harshit-30@users.noreply.github.com> Date: Fri, 23 Aug 2019 11:34:25 +0530 Subject: [PATCH 05/10] fix: add contract to CRM module (#18817) --- erpnext/config/crm.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/config/crm.py b/erpnext/config/crm.py index 70784f3d5f..eba6c7a02a 100644 --- a/erpnext/config/crm.py +++ b/erpnext/config/crm.py @@ -41,6 +41,11 @@ def get_data(): "name": "Lead Source", "description": _("Track Leads by Lead Source.") }, + { + "type": "doctype", + "name": "Contract", + "description": _("Helps you keep tracks of Contracts based on Supplier, Customer and Employee"), + }, ] }, { From 23b5f4ec99d0f22348ba3b8f1384c9f14f9660ee Mon Sep 17 00:00:00 2001 From: KanchanChauhan Date: Fri, 23 Aug 2019 11:40:09 +0530 Subject: [PATCH 06/10] fix: Leave Application status filter (#18770) When we click on Status Open in list view it throws an error. After fix, it filters the results on Open status --- erpnext/hr/doctype/leave_application/leave_application_list.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/hr/doctype/leave_application/leave_application_list.js b/erpnext/hr/doctype/leave_application/leave_application_list.js index f69b182737..cbb4b73227 100644 --- a/erpnext/hr/doctype/leave_application/leave_application_list.js +++ b/erpnext/hr/doctype/leave_application/leave_application_list.js @@ -5,6 +5,8 @@ frappe.listview_settings['Leave Application'] = { return [__("Approved"), "green", "status,=,Approved"]; } else if (doc.status === "Rejected") { return [__("Rejected"), "red", "status,=,Rejected"]; + } else { + return [__("Open"), "red", "status,=,Open"]; } } }; From f3d78dd29c4c98d303fbcfe7f7e1db447c466a82 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Fri, 23 Aug 2019 11:42:35 +0530 Subject: [PATCH 07/10] fix: Duplicate items check in Sales Invoice (#18660) * fix: Duplicate items check in sales Invoice * fix: Commonified function for duplicate items check in selling controller * fix: Set valuation rate and transaction date in child tabel --- erpnext/controllers/selling_controller.py | 29 +++++++++++++++++++ .../doctype/sales_order/sales_order.py | 9 ------ .../doctype/delivery_note/delivery_note.py | 17 ----------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 2cbe596770..52d58dce62 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -45,6 +45,7 @@ class SellingController(StockController): self.set_gross_profit() set_default_income_account_for_item(self) self.set_customer_address() + self.validate_for_duplicate_items() def set_missing_values(self, for_validate=False): @@ -381,6 +382,34 @@ class SellingController(StockController): if self.get(address_field): self.set(address_display_field, get_address_display(self.get(address_field))) + def validate_for_duplicate_items(self): + check_list, chk_dupl_itm = [], [] + if cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")): + return + + for d in self.get('items'): + if self.doctype == "Sales Invoice": + e = [d.item_code, d.description, d.warehouse, d.sales_order or d.delivery_note, d.batch_no or ''] + f = [d.item_code, d.description, d.sales_order or d.delivery_note] + elif self.doctype == "Delivery Note": + e = [d.item_code, d.description, d.warehouse, d.against_sales_order or d.against_sales_invoice, d.batch_no or ''] + f = [d.item_code, d.description, d.against_sales_order or d.against_sales_invoice] + elif self.doctype == "Sales Order": + e = [d.item_code, d.description, d.warehouse, d.batch_no or ''] + f = [d.item_code, d.description] + + if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1: + if e in check_list: + frappe.throw(_("Note: Item {0} entered multiple times").format(d.item_code)) + else: + check_list.append(e) + else: + if f in chk_dupl_itm: + frappe.throw(_("Note: Item {0} entered multiple times").format(d.item_code)) + else: + chk_dupl_itm.append(f) + + def validate_items(self): # validate items to see if they have is_sales_item enabled from erpnext.controllers.buying_controller import validate_item_type diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 09dc9a9932..4342af5e19 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -72,9 +72,7 @@ class SalesOrder(SellingController): frappe.msgprint(_("Warning: Sales Order {0} already exists against Customer's Purchase Order {1}").format(so[0][0], self.po_no)) def validate_for_items(self): - check_list = [] for d in self.get('items'): - check_list.append(cstr(d.item_code)) # used for production plan d.transaction_date = self.transaction_date @@ -83,13 +81,6 @@ class SalesOrder(SellingController): where item_code = %s and warehouse = %s", (d.item_code, d.warehouse)) d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0 - # check for same entry multiple times - unique_chk_list = set(check_list) - if len(unique_chk_list) != len(check_list) and \ - not cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")): - frappe.msgprint(_("Same item has been entered multiple times"), - title=_("Warning"), indicator='orange') - def product_bundle_has_stock_item(self, product_bundle): """Returns true if product bundle has stock item""" ret = len(frappe.db.sql("""select i.name from tabItem i, `tabProduct Bundle Item` pbi diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 2de9b975da..f79d127984 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -166,24 +166,7 @@ class DeliveryNote(SellingController): frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project)) def validate_for_items(self): - check_list, chk_dupl_itm = [], [] - if cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")): - return - for d in self.get('items'): - e = [d.item_code, d.description, d.warehouse, d.against_sales_order or d.against_sales_invoice, d.batch_no or ''] - f = [d.item_code, d.description, d.against_sales_order or d.against_sales_invoice] - - if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1: - if e in check_list: - frappe.msgprint(_("Note: Item {0} entered multiple times").format(d.item_code)) - else: - check_list.append(e) - else: - if f in chk_dupl_itm: - frappe.msgprint(_("Note: Item {0} entered multiple times").format(d.item_code)) - else: - chk_dupl_itm.append(f) #Customer Provided parts will have zero valuation rate if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'): d.allow_zero_valuation_rate = 1 From c890401fec89eb97a0656a1e18a297b78fe805de Mon Sep 17 00:00:00 2001 From: Michelle Alva <50285544+michellealva@users.noreply.github.com> Date: Fri, 23 Aug 2019 11:50:48 +0530 Subject: [PATCH 08/10] fix: added payroll period in HR module (#18543) From 6e7b9b5cb794705c15e8aa1575e7be206ef1470b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 23 Aug 2019 12:27:05 +0530 Subject: [PATCH 09/10] Update sales_invoice.py --- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 4f80b78c88..95c5dd5cd4 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -206,9 +206,9 @@ class SalesInvoice(SellingController): total_amount_in_payments = 0 for payment in self.payments: total_amount_in_payments += payment.amount - - if total_amount_in_payments < self.rounded_total: - frappe.throw(_("Total payments amount can't be greater than {}".format(-self.rounded_total))) + invoice_total = self.rounded_total or self.grand_total + if total_amount_in_payments < invoice_total: + frappe.throw(_("Total payments amount can't be greater than {}".format(-invoice_total))) def validate_pos_paid_amount(self): if len(self.payments) == 0 and self.is_pos: @@ -1510,4 +1510,4 @@ def create_invoice_discounting(source_name, target_doc=None): "outstanding_amount": invoice.outstanding_amount }) - return invoice_discounting \ No newline at end of file + return invoice_discounting From a7ab51c5ba95ae387302fca2d7d222344eccbf5c Mon Sep 17 00:00:00 2001 From: Tufan Kaynak <31142607+toofun666@users.noreply.github.com> Date: Fri, 23 Aug 2019 10:20:52 +0300 Subject: [PATCH 10/10] Update vehicle_expenses.py (#18768) --- erpnext/hr/report/vehicle_expenses/vehicle_expenses.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py index e2989e29c0..e5622b7ae1 100644 --- a/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py +++ b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py @@ -23,7 +23,8 @@ def get_columns(): _("Model") + ":data:50", _("Location") + ":data:100", _("Log") + ":Link/Vehicle Log:100", _("Odometer") + ":Int:80", _("Date") + ":Date:100", _("Fuel Qty") + ":Float:80", - _("Fuel Price") + ":Float:100",_("Service Expense") + ":Float:100" + _("Fuel Price") + ":Float:100",_("Fuel Expense") + ":Float:100", + _("Service Expense") + ":Float:100" ] return columns @@ -32,7 +33,8 @@ def get_log_data(filters): data = frappe.db.sql("""select vhcl.license_plate as "License", vhcl.make as "Make", vhcl.model as "Model", vhcl.location as "Location", log.name as "Log", log.odometer as "Odometer", - log.date as "Date", log.fuel_qty as "Fuel Qty", log.price as "Fuel Price" + log.date as "Date", log.fuel_qty as "Fuel Qty", log.price as "Fuel Price", + log.fuel_qty * log.price as "Fuel Expense" from `tabVehicle` vhcl,`tabVehicle Log` log where @@ -58,7 +60,7 @@ def get_chart_data(data,period_list): total_ser_exp=0 for row in data: if row["Date"] <= period.to_date and row["Date"] >= period.from_date: - total_fuel_exp+=flt(row["Fuel Price"]) + total_fuel_exp+=flt(row["Fuel Expense"]) total_ser_exp+=flt(row["Service Expense"]) fueldata.append([period.key,total_fuel_exp]) servicedata.append([period.key,total_ser_exp]) @@ -84,4 +86,4 @@ def get_chart_data(data,period_list): } } chart["type"] = "line" - return chart \ No newline at end of file + return chart