From af0599541867c130e51ac14dc13f1e970d296267 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 7 May 2018 18:46:53 +0530 Subject: [PATCH] Asset accounting --- .../purchase_invoice/purchase_invoice.py | 43 +++++++++++++++++++ erpnext/controllers/buying_controller.py | 24 +++++++---- .../purchase_receipt/purchase_receipt.py | 31 +++++++++++++ erpnext/stock/doctype/serial_no/serial_no.py | 2 +- 4 files changed, 91 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index d2cc4eea9f..fea126945c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -422,6 +422,49 @@ class PurchaseInvoice(BuyingController): "remarks": self.get("remarks") or _("Accounting Entry for Stock"), "credit": flt(item.rm_supp_cost) }, warehouse_account[self.supplier_warehouse]["account_currency"])) + + elif item.is_fixed_asset and not self.update_stock: + asset_accounts = self.get_company_default(["asset_received_but_not_billed", + "expenses_included_in_asset_valuation", "capital_work_in_progress_account"]) + + asset_amount = flt(item.net_amount) + flt(item.item_tax_amount/self.conversion_rate) + base_asset_amount = flt(item.base_net_amount + item.item_tax_amount) + + if not self.update_stock: + asset_rbnb_currency = get_account_currency(asset_accounts[0]) + + gl_entries.append(self.get_gl_dict({ + "account": asset_accounts[0], + "against": self.supplier, + "remarks": self.get("remarks") or _("Accounting Entry for Asset"), + "debit": base_asset_amount, + "debit_in_account_currency": (base_asset_amount + if asset_rbnb_currency == self.company_currency else asset_amount) + })) + else: + cwip_account_currency = get_account_currency(asset_accounts[2]) + + gl_entries.append(self.get_gl_dict({ + "account": asset_accounts[2], + "against": self.supplier, + "remarks": self.get("remarks") or _("Accounting Entry for Asset"), + "debit": base_asset_amount, + "debit_in_account_currency": (base_asset_amount + if cwip_account_currency == self.company_currency else asset_amount) + })) + + asset_eiiav_currency = get_account_currency(asset_accounts[0]) + gl_entries.append(self.get_gl_dict({ + "account": asset_accounts[1], + "against": self.supplier, + "remarks": self.get("remarks") or _("Accounting Entry for Asset"), + "cost_center": item.cost_center, + "credit": item.item_tax_amount, + "credit_in_account_currency": (item.item_tax_amount + if asset_eiiav_currency == self.company_currency else + item.item_tax_amount / self.conversion_rate) + })) + else: gl_entries.append( self.get_gl_dict({ diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 798eee2b9d..a1bc6d7aa7 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -79,7 +79,7 @@ class BuyingController(StockController): break def validate_stock_or_nonstock_items(self): - if self.meta.get_field("taxes") and not self.get_stock_items(): + if self.meta.get_field("taxes") and not self.get_stock_items() and not self.get_asset_items(): tax_for_valuation = [d for d in self.get("taxes") if d.category in ["Valuation", "Valuation and Total"]] @@ -88,6 +88,9 @@ class BuyingController(StockController): d.category = 'Total' msgprint(_('Tax Category has been changed to "Total" because all the Items are non-stock items')) + def get_asset_items(self): + return [d.item_code for d in self.items if d.is_fixed_asset] + def set_landed_cost_voucher_amount(self): for d in self.get("items"): lc_voucher_data = frappe.db.sql("""select sum(applicable_charges), cost_center @@ -112,7 +115,7 @@ class BuyingController(StockController): TODO: rename item_tax_amount to valuation_tax_amount """ - stock_items = self.get_stock_items() + stock_items = self.get_stock_items() + self.get_asset_items() stock_items_qty, stock_items_amount = 0, 0 last_stock_item_idx = 1 @@ -456,14 +459,14 @@ class BuyingController(StockController): if self.doctype in ['Purchase Receipt', 'Purchase Invoice']: field = 'purchase_invoice' if self.doctype == 'Purchase Invoice' else 'purchase_receipt' - self.delete_linked_asset(field) - self.update_fixed_asset(field) + self.delete_linked_asset() + self.update_fixed_asset(field, delete_asset=True) def process_fixed_asset(self): if self.doctype == 'Purchase Invoice' and not self.update_stock: return - asset_items = [d.item_code for d in self.items if d.is_fixed_asset] + asset_items = self.get_asset_items() if asset_items: self.make_serial_nos_for_asset(asset_items) @@ -537,10 +540,16 @@ class BuyingController(StockController): return asset_movement.name - def update_fixed_asset(self, field): + def update_fixed_asset(self, field, delete_asset = False): for d in self.get("items"): if d.is_fixed_asset and d.asset: asset = frappe.get_doc("Asset", d.asset) + + if delete_asset and asset.docstatus == 0: + frappe.delete_doc("Asset", asset.name) + d.db_set('asset', None) + continue + if self.docstatus in [0, 1] and not asset.get(field): asset.set(field, self.name) asset.purchase_date = self.posting_date @@ -555,11 +564,10 @@ class BuyingController(StockController): asset.save() - def delete_linked_asset(self, field): + def delete_linked_asset(self): if self.doctype == 'Purchase Invoice' and not self.get('update_stock'): return - frappe.db.sql("delete from `tabAsset` where {0} = %s and docstatus = 0".format(field), self.name) frappe.db.sql("delete from `tabAsset Movement` where reference_name=%s and docstatus = 0", self.name) frappe.db.sql("delete from `tabSerial No` where purchase_document_no=%s", self.name) diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index c7083be286..984bf33b4b 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -253,6 +253,37 @@ class PurchaseReceipt(BuyingController): d.rejected_warehouse not in warehouse_with_no_account: warehouse_with_no_account.append(d.warehouse) + elif d.is_fixed_asset: + asset_accounts = self.get_company_default(["capital_work_in_progress_account", + "asset_received_but_not_billed"]) + + # CWIP entry + asset_amount = flt(d.net_amount) + flt(d.item_tax_amount/self.conversion_rate) + base_asset_amount = flt(d.base_net_amount + d.item_tax_amount) + + cwip_account_currency = get_account_currency(asset_accounts[0]) + gl_entries.append(self.get_gl_dict({ + "account": asset_accounts[0], + "against": asset_accounts[1], + "cost_center": d.cost_center, + "remarks": self.get("remarks") or _("Accounting Entry for Asset"), + "debit": base_asset_amount, + "debit_in_account_currency": (base_asset_amount + if cwip_account_currency == self.company_currency else asset_amount) + })) + + # Asset received but not billed + asset_rbnb_currency = get_account_currency(asset_accounts[1]) + gl_entries.append(self.get_gl_dict({ + "account": asset_accounts[1], + "against": asset_accounts[0], + "cost_center": d.cost_center, + "remarks": self.get("remarks") or _("Accounting Entry for Asset"), + "credit": base_asset_amount, + "credit_in_account_currency": (base_asset_amount + if asset_rbnb_currency == self.company_currency else asset_amount) + })) + # Cost center-wise amount breakup for other charges included for valuation valuation_tax = {} for tax in self.get("taxes"): diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 6ee679ab82..333963bd66 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -323,12 +323,12 @@ def make_serial_no(serial_no, args): sr.company = args.get('company') sr.via_stock_ledger = args.get('via_stock_ledger') or True sr.asset = args.get('asset') - sr.insert() if args.get('purchase_document_type'): sr.purchase_document_type = args.get('purchase_document_type') sr.purchase_document_no = args.get('purchase_document_no') + sr.insert() if args.get('warehouse'): sr.warehouse = args.get('warehouse') sr.save()