Skip to content

Commit

Permalink
feat: multiple purchase invoice in asset repair doctype (#43460)
Browse files Browse the repository at this point in the history
Co-authored-by: “rahulgupta8848” <“rahul.gupta@8848digital.com”>
  • Loading branch information
rahulgupta8848 and “rahulgupta8848” authored Oct 1, 2024
1 parent c5d5421 commit 2384309
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 58 deletions.
13 changes: 12 additions & 1 deletion erpnext/assets/doctype/asset_repair/asset_repair.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ frappe.ui.form.on("Asset Repair", {
};
});

frm.set_query("purchase_invoice", function () {
frm.set_query("purchase_invoice", "invoices", function () {
return {
query: "erpnext.assets.doctype.asset_repair.asset_repair.get_purchase_invoice",
filters: {
company: frm.doc.company,
docstatus: 1,
Expand Down Expand Up @@ -58,6 +59,16 @@ frappe.ui.form.on("Asset Repair", {
},
};
});

frm.set_query("expense_account", "invoices", function () {
return {
filters: {
company: frm.doc.company,
is_group: ["=", 0],
report_type: ["=", "Profit and Loss"],
},
};
});
},

refresh: function (frm) {
Expand Down
25 changes: 15 additions & 10 deletions erpnext/assets/doctype/asset_repair/asset_repair.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"column_break_14",
"project",
"accounting_details",
"purchase_invoice",
"invoices",
"section_break_y7cc",
"capitalize_repair_cost",
"stock_consumption",
"column_break_8",
Expand Down Expand Up @@ -229,26 +230,30 @@
"label": "Increase In Asset Life(Months)",
"no_copy": 1
},
{
"fieldname": "purchase_invoice",
"fieldtype": "Link",
"label": "Purchase Invoice",
"mandatory_depends_on": "eval: doc.repair_status == 'Completed' && doc.repair_cost > 0",
"no_copy": 1,
"options": "Purchase Invoice"
},
{
"fetch_from": "asset.company",
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
"options": "Company"
},
{
"fieldname": "invoices",
"fieldtype": "Table",
"label": "Asset Repair Purchase Invoices",
"mandatory_depends_on": "eval: doc.repair_status == 'Completed' && doc.repair_cost > 0;",
"no_copy": 1,
"options": "Asset Repair Purchase Invoice"
},
{
"fieldname": "section_break_y7cc",
"fieldtype": "Section Break"
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2024-06-13 16:14:14.398356",
"modified": "2024-09-30 13:02:06.931188",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Repair",
Expand Down
112 changes: 88 additions & 24 deletions erpnext/assets/doctype/asset_repair/asset_repair.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import frappe
from frappe import _
from frappe.query_builder import DocType
from frappe.utils import add_months, cint, flt, get_link_to_form, getdate, time_diff_in_hours

import erpnext
Expand All @@ -28,6 +29,9 @@ class AssetRepair(AccountsController):
from erpnext.assets.doctype.asset_repair_consumed_item.asset_repair_consumed_item import (
AssetRepairConsumedItem,
)
from erpnext.assets.doctype.asset_repair_purchase_invoice.asset_repair_purchase_invoice import (
AssetRepairPurchaseInvoice,
)

actions_performed: DF.LongText | None
amended_from: DF.Link | None
Expand All @@ -41,9 +45,9 @@ class AssetRepair(AccountsController):
downtime: DF.Data | None
failure_date: DF.Datetime
increase_in_asset_life: DF.Int
invoices: DF.Table[AssetRepairPurchaseInvoice]
naming_series: DF.Literal["ACC-ASR-.YYYY.-"]
project: DF.Link | None
purchase_invoice: DF.Link | None
repair_cost: DF.Currency
repair_status: DF.Literal["Pending", "Completed", "Cancelled"]
stock_consumption: DF.Check
Expand All @@ -54,10 +58,15 @@ class AssetRepair(AccountsController):
def validate(self):
self.asset_doc = frappe.get_doc("Asset", self.asset)
self.validate_dates()
self.validate_purchase_invoice()
self.validate_purchase_invoice_repair_cost()
self.validate_purchase_invoice_expense_account()
self.update_status()

if self.get("stock_items"):
self.set_stock_items_cost()

self.calculate_repair_cost()
self.calculate_total_repair_cost()

def validate_dates(self):
Expand All @@ -66,6 +75,31 @@ def validate_dates(self):
_("Completion Date can not be before Failure Date. Please adjust the dates accordingly.")
)

def validate_purchase_invoice(self):
query = expense_item_pi_query(self.company)
purchase_invoice_list = [item[0] for item in query.run()]
for pi in self.invoices:
if pi.purchase_invoice not in purchase_invoice_list:
frappe.throw(_("Expense item not present in Purchase Invoice"))

def validate_purchase_invoice_repair_cost(self):
for pi in self.invoices:
if flt(pi.repair_cost) > frappe.db.get_value(
"Purchase Invoice", pi.purchase_invoice, "base_net_total"
):
frappe.throw(_("Repair cost cannot be greater than purchase invoice base net total"))

def validate_purchase_invoice_expense_account(self):
for pi in self.invoices:
if pi.expense_account not in frappe.db.get_all(
"Purchase Invoice Item", {"parent": pi.purchase_invoice}, pluck="expense_account"
):
frappe.throw(
_("Expense account not present in Purchase Invoice {0}").format(
get_link_to_form("Purchase Invoice", pi.purchase_invoice)
)
)

def update_status(self):
if self.repair_status == "Pending" and self.asset_doc.status != "Out of Order":
frappe.db.set_value("Asset", self.asset, "status", "Out of Order")
Expand All @@ -82,6 +116,9 @@ def set_stock_items_cost(self):
for item in self.get("stock_items"):
item.total_value = flt(item.valuation_rate) * flt(item.consumed_quantity)

def calculate_repair_cost(self):
self.repair_cost = sum(flt(pi.repair_cost) for pi in self.invoices)

def calculate_total_repair_cost(self):
self.total_repair_cost = flt(self.repair_cost)

Expand Down Expand Up @@ -267,40 +304,39 @@ def get_gl_entries_for_repair_cost(self, gl_entries, fixed_asset_account):
if flt(self.repair_cost) <= 0:
return

pi_expense_account = (
frappe.get_doc("Purchase Invoice", self.purchase_invoice).items[0].expense_account
)

debit_against_account = set()

for pi in self.invoices:
debit_against_account.add(pi.expense_account)
gl_entries.append(
self.get_gl_dict(
{
"account": pi.expense_account,
"credit": pi.repair_cost,
"credit_in_account_currency": pi.repair_cost,
"against": fixed_asset_account,
"voucher_type": self.doctype,
"voucher_no": self.name,
"cost_center": self.cost_center,
"posting_date": getdate(),
"company": self.company,
},
item=self,
)
)
debit_against_account = ", ".join(debit_against_account)
gl_entries.append(
self.get_gl_dict(
{
"account": fixed_asset_account,
"debit": self.repair_cost,
"debit_in_account_currency": self.repair_cost,
"against": pi_expense_account,
"against": debit_against_account,
"voucher_type": self.doctype,
"voucher_no": self.name,
"cost_center": self.cost_center,
"posting_date": getdate(),
"against_voucher_type": "Purchase Invoice",
"against_voucher": self.purchase_invoice,
"company": self.company,
},
item=self,
)
)

gl_entries.append(
self.get_gl_dict(
{
"account": pi_expense_account,
"credit": self.repair_cost,
"credit_in_account_currency": self.repair_cost,
"against": fixed_asset_account,
"voucher_type": self.doctype,
"voucher_no": self.name,
"cost_center": self.cost_center,
"posting_date": getdate(),
"company": self.company,
},
item=self,
Expand Down Expand Up @@ -432,3 +468,31 @@ def calculate_last_schedule_date_before_modification(self, asset, row, extra_mon
def get_downtime(failure_date, completion_date):
downtime = time_diff_in_hours(completion_date, failure_date)
return round(downtime, 2)


@frappe.whitelist()
def get_purchase_invoice(doctype, txt, searchfield, start, page_len, filters):
query = expense_item_pi_query(filters.get("company"))
return query.run(as_list=1)


def expense_item_pi_query(company):
PurchaseInvoice = DocType("Purchase Invoice")
PurchaseInvoiceItem = DocType("Purchase Invoice Item")
Item = DocType("Item")

query = (
frappe.qb.from_(PurchaseInvoice)
.join(PurchaseInvoiceItem)
.on(PurchaseInvoiceItem.parent == PurchaseInvoice.name)
.join(Item)
.on(Item.name == PurchaseInvoiceItem.item_code)
.select(PurchaseInvoice.name)
.where(
(Item.is_stock_item == 0)
& (Item.is_fixed_asset == 0)
& (PurchaseInvoice.company == company)
& (PurchaseInvoice.docstatus == 1)
)
)
return query
Loading

0 comments on commit 2384309

Please sign in to comment.