From 9a56764bf2bc661d5e1505632b13cf2bf6e6c536 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Mon, 27 Apr 2015 17:10:10 +0530 Subject: [PATCH 1/4] Total Purchase Cost added to Projects --- .../purchase_invoice/purchase_invoice.json | 23 +++++++------------ .../purchase_invoice/purchase_invoice.py | 12 +++++++--- erpnext/projects/doctype/project/project.json | 11 ++++++++- erpnext/projects/doctype/project/project.py | 4 ++++ 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index 03ed987745d..0f1eb4bf28a 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -5,21 +5,6 @@ "docstatus": 0, "doctype": "DocType", "fields": [ - { - "fieldname": "supplier_section", - "fieldtype": "Section Break", - "label": "", - "options": "icon-user", - "permlevel": 0 - }, - { - "fieldname": "column_break0", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, - "read_only": 0, - "width": "50%" - }, { "fieldname": "naming_series", "fieldtype": "Select", @@ -91,6 +76,14 @@ "print_hide": 1, "read_only": 1 }, + { + "fieldname": "project", + "fieldtype": "Link", + "label": "Project", + "options": "Project", + "permlevel": 0, + "precision": "" + }, { "fieldname": "column_break1", "fieldtype": "Column Break", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 094d30cff3c..31213afe70c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -239,6 +239,7 @@ class PurchaseInvoice(BuyingController): self.update_against_document_in_jv() self.update_prevdoc_status() self.update_billing_status_for_zero_amount_refdoc("Purchase Order") + self.update_project() def make_gl_entries(self): auto_accounting_for_stock = \ @@ -373,9 +374,14 @@ class PurchaseInvoice(BuyingController): self.update_prevdoc_status() self.update_billing_status_for_zero_amount_refdoc("Purchase Order") self.make_gl_entries_on_cancel() - - def on_update(self): - pass + self.update_project() + + def update_project(self): + if self.project and frappe.db.exists("Project", self.project): + project = frappe.get_doc("Project", self.project) + project.flags.dont_sync_tasks = True + project.update_purchase_costing() + project.save() @frappe.whitelist() def get_expense_account(doctype, txt, searchfield, start, page_len, filters): diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json index 4db087bb446..2aca991877e 100644 --- a/erpnext/projects/doctype/project/project.json +++ b/erpnext/projects/doctype/project/project.json @@ -303,6 +303,15 @@ "precision": "", "read_only": 1 }, + { + "fieldname": "total_purchase_cost", + "fieldtype": "Currency", + "hidden": 0, + "label": "Total Purchase Cost (via Purchase Invoice)", + "permlevel": 0, + "precision": "", + "read_only": 1 + }, { "fieldname": "margin", "fieldtype": "Section Break", @@ -347,7 +356,7 @@ "icon": "icon-puzzle-piece", "idx": 1, "max_attachments": 4, - "modified": "2015-04-23 05:51:53.642253", + "modified": "2015-04-27 07:37:44.239930", "modified_by": "Administrator", "module": "Projects", "name": "Project", diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 89cf523c1e4..eba56d521e3 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -89,6 +89,10 @@ class Project(Document): self.gross_margin = flt(total_cost.billing_amount) - flt(total_cost.costing_amount) if self.total_billing_amount: self.per_gross_margin = (self.gross_margin / flt(self.total_billing_amount)) *100 + + def update_purchase_costing(self): + self.total_purchase_cost = frappe.db.sql("""select sum(grand_total) as cost + from `tabPurchase Invoice` where project = %s and docstatus=1 """, self.name, as_dict=1)[0].cost @frappe.whitelist() def get_cost_center_name(project_name): From 349461e9e6c5507e16f4560f6ddab32196e553ab Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Tue, 28 Apr 2015 16:29:58 +0530 Subject: [PATCH 2/4] Test Cases Added --- .../purchase_invoice/purchase_invoice.py | 2 ++ .../purchase_invoice/test_purchase_invoice.py | 31 ++++++++++++++++++- erpnext/projects/doctype/project/project.py | 2 +- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 31213afe70c..8c238679b55 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -364,6 +364,8 @@ class PurchaseInvoice(BuyingController): ) if gl_entries: + for d in gl_entries: + print d.account, d.debit, d.credit from erpnext.accounts.general_ledger import make_gl_entries make_gl_entries(gl_entries, cancel=(self.docstatus == 2)) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 5ae47d7c4f8..b68220523d9 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -6,7 +6,6 @@ from __future__ import unicode_literals import unittest import frappe import frappe.model -import json from frappe.utils import cint import frappe.defaults from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \ @@ -234,5 +233,35 @@ class TestPurchaseInvoice(unittest.TestCase): def test_recurring_invoice(self): from erpnext.controllers.tests.test_recurring_document import test_recurring_document test_recurring_document(self, test_records) + + def test_total_purchase_cost_for_project(self): + purchase_invoice = frappe.new_doc('Purchase Invoice') + purchase_invoice.update({ + "credit_to": "_Test Payable - _TC", + "project": "_Test Project", + "supplier": "_Test Supplier", + "company": "_Test Company", + "items": [ + { + "rate": 500, + "qty": 1, + "item_code": "_Test Item Home Desktop 100", + "expense_account": "_Test Account Cost for Goods Sold - _TC" + }, + { + "rate": 1500, + "qty": 1, + "item_code": "_Test Item Home Desktop 200", + "expense_account": "_Test Account Cost for Goods Sold - _TC" + } + ] + }) + purchase_invoice.save() + purchase_invoice.submit() + self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), 2000) + + purchase_invoice.cancel() + self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), 0) + test_records = frappe.get_test_records('Purchase Invoice') diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index eba56d521e3..839ad1d62dc 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -92,7 +92,7 @@ class Project(Document): def update_purchase_costing(self): self.total_purchase_cost = frappe.db.sql("""select sum(grand_total) as cost - from `tabPurchase Invoice` where project = %s and docstatus=1 """, self.name, as_dict=1)[0].cost + from `tabPurchase Invoice` where project = %s and docstatus=1 """, self.name, as_dict=1)[0].cost or 0 @frappe.whitelist() def get_cost_center_name(project_name): From 01720404dba14b63bb0d80c77e6c88cd4a52b5bb Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Wed, 29 Apr 2015 12:13:21 +0530 Subject: [PATCH 3/4] fixes in Test Cases --- .../doctype/purchase_invoice/purchase_invoice.py | 2 -- .../purchase_invoice/test_purchase_invoice.py | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 8c238679b55..31213afe70c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -364,8 +364,6 @@ class PurchaseInvoice(BuyingController): ) if gl_entries: - for d in gl_entries: - print d.account, d.debit, d.credit from erpnext.accounts.general_ledger import make_gl_entries make_gl_entries(gl_entries, cancel=(self.docstatus == 2)) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index b68220523d9..d0fb3d93f37 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -246,13 +246,15 @@ class TestPurchaseInvoice(unittest.TestCase): "rate": 500, "qty": 1, "item_code": "_Test Item Home Desktop 100", - "expense_account": "_Test Account Cost for Goods Sold - _TC" + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "cost_center": "_Test Cost Center - _TC" }, { "rate": 1500, "qty": 1, "item_code": "_Test Item Home Desktop 200", - "expense_account": "_Test Account Cost for Goods Sold - _TC" + "expense_account": "_Test Account Cost for Goods Sold - _TC", + "cost_center": "_Test Cost Center - _TC" } ] }) @@ -260,6 +262,15 @@ class TestPurchaseInvoice(unittest.TestCase): purchase_invoice.submit() self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), 2000) + purchase_invoice1 = frappe.copy_doc(purchase_invoice) + purchase_invoice1.save() + purchase_invoice1.submit() + + self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), 4000) + + purchase_invoice1.cancel() + self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), 2000) + purchase_invoice.cancel() self.assertEqual(frappe.db.get_value("Project", "_Test Project", "total_purchase_cost"), 0) From 42a554e5cbbabbc29d59da613502439ce9c51835 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Thu, 30 Apr 2015 13:05:36 +0530 Subject: [PATCH 4/4] fixes in Purchase Invoice --- .../doctype/purchase_invoice/purchase_invoice.json | 10 +--------- .../doctype/purchase_invoice/purchase_invoice.py | 13 ++++++++----- .../purchase_invoice/test_purchase_invoice.py | 3 ++- erpnext/projects/doctype/project/project.py | 4 ++-- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index 0f1eb4bf28a..edbefba9984 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -76,14 +76,6 @@ "print_hide": 1, "read_only": 1 }, - { - "fieldname": "project", - "fieldtype": "Link", - "label": "Project", - "options": "Project", - "permlevel": 0, - "precision": "" - }, { "fieldname": "column_break1", "fieldtype": "Column Break", @@ -946,7 +938,7 @@ "icon": "icon-file-text", "idx": 1, "is_submittable": 1, - "modified": "2015-04-27 20:32:12.436976", + "modified": "2015-04-30 03:05:13.790265", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 31213afe70c..c0ebf686cbc 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -377,11 +377,14 @@ class PurchaseInvoice(BuyingController): self.update_project() def update_project(self): - if self.project and frappe.db.exists("Project", self.project): - project = frappe.get_doc("Project", self.project) - project.flags.dont_sync_tasks = True - project.update_purchase_costing() - project.save() + project_list = [] + for d in self.items: + if d.project_name and d.project_name not in project_list: + project = frappe.get_doc("Project", d.project_name) + project.flags.dont_sync_tasks = True + project.update_purchase_costing() + project.save() + project_list.append(d.project_name) @frappe.whitelist() def get_expense_account(doctype, txt, searchfield, start, page_len, filters): diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index d0fb3d93f37..7f46b083d8f 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -238,13 +238,13 @@ class TestPurchaseInvoice(unittest.TestCase): purchase_invoice = frappe.new_doc('Purchase Invoice') purchase_invoice.update({ "credit_to": "_Test Payable - _TC", - "project": "_Test Project", "supplier": "_Test Supplier", "company": "_Test Company", "items": [ { "rate": 500, "qty": 1, + "project_name": "_Test Project", "item_code": "_Test Item Home Desktop 100", "expense_account": "_Test Account Cost for Goods Sold - _TC", "cost_center": "_Test Cost Center - _TC" @@ -252,6 +252,7 @@ class TestPurchaseInvoice(unittest.TestCase): { "rate": 1500, "qty": 1, + "project_name": "_Test Project", "item_code": "_Test Item Home Desktop 200", "expense_account": "_Test Account Cost for Goods Sold - _TC", "cost_center": "_Test Cost Center - _TC" diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 839ad1d62dc..590788d34d6 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -91,8 +91,8 @@ class Project(Document): self.per_gross_margin = (self.gross_margin / flt(self.total_billing_amount)) *100 def update_purchase_costing(self): - self.total_purchase_cost = frappe.db.sql("""select sum(grand_total) as cost - from `tabPurchase Invoice` where project = %s and docstatus=1 """, self.name, as_dict=1)[0].cost or 0 + self.total_purchase_cost = frappe.db.sql("""select sum(amount) as cost + from `tabPurchase Invoice Item` where project_name = %s and docstatus=1 """, self.name, as_dict=1)[0].cost or 0 @frappe.whitelist() def get_cost_center_name(project_name):