Skip to content

Commit

Permalink
feat: link purchase invoice item with purchase order
Browse files Browse the repository at this point in the history
  • Loading branch information
Sanket322 committed Sep 26, 2024
1 parent e4e96d2 commit a6911d0
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 2 deletions.
65 changes: 65 additions & 0 deletions erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,26 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
);
}

if (doc.docstatus === 0) {
const cur_doc = this.frm.doc;
const invoice_items = cur_doc.items;

this.frm.add_custom_button(__("Link to Purchase Order"), function () {
let unmapped_items = get_unmapped_items(invoice_items);

frappe.call({
method: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.link_purchase_order",
args: {
pi_item_code: unmapped_items,
supplier: cur_doc.supplier,
},
callback: function (r) {
assign_purchase_order(invoice_items, r.message, cur_doc);
},
});
});
}

if (doc.docstatus === 0) {
this.frm.add_custom_button(
__("Purchase Order"),
Expand Down Expand Up @@ -446,6 +466,51 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
}
};

function get_unmapped_items(invoice_items) {
return invoice_items.map((item) => {
item.purchase_order = "";
return item.item_code;
});
}

function assign_purchase_order(invoice_items, items_to_link, cur_doc) {
if (!Object.keys(items_to_link).length) {
frappe.msgprint(__("No Purchase Orders matched"));
return;
}

let total_idx = invoice_items.length;

invoice_items.forEach((item) => {
const matched_item = items_to_link[item.item_code];
if (!matched_item) return;

if (item.qty > matched_item.qty) {
const new_row = frappe.model.add_child(cur_doc, item.doctype, "items");
Object.assign(new_row, item);
new_row.qty = item.qty - matched_item.qty;
new_row.idx = ++total_idx;

frappe.msgprint("Splitting " + new_row.qty + " units of " + new_row.item_code);
item.qty = matched_item.qty;
}

frappe.msgprint(
"Assigning " + matched_item.purchase_order + " to " + item.item_code + " (row " + item.idx + ")"
);
item.purchase_order = matched_item.purchase_order;

if (items_to_link[item.item_code]) {
items_to_link[item.item_code] -= item.qty;

if (items_to_link[item.item_code] <= 0) {
delete items_to_link[item.item_code];
}
}
});
refresh_field("items");
}

cur_frm.script_manager.make(erpnext.accounts.PurchaseInvoice);

// Hide Fields
Expand Down
30 changes: 28 additions & 2 deletions erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt

import json

import frappe
from frappe import _, qb, throw
from frappe.model.mapper import get_mapped_doc
from frappe.model import child_table_fields, default_fields, table_fields
from frappe.model.mapper import get_mapped_doc, map_fetch_fields, map_fields
from frappe.query_builder.functions import Sum
from frappe.utils import cint, cstr, flt, formatdate, get_link_to_form, getdate, nowdate

Expand Down Expand Up @@ -1934,6 +1935,31 @@ def make_stock_entry(source_name, target_doc=None):
return doc


@frappe.whitelist()
def link_purchase_order(pi_item_code, supplier):
pi_item_code = json.loads(pi_item_code)

purchase_orders = frappe.get_all(
"Purchase Order",
filters={"supplier": supplier, "docstatus": 1},
pluck="name",
order_by="creation asc",
)
purchase_order_items = frappe.get_all(
"Purchase Order Item",
filters={"parent": ["in", purchase_orders]},
fields=["parent", "item_code", "qty"],
)

item_to_po_map = {
item.item_code: {"purchase_order": item.parent, "qty": item.qty}
for item in purchase_order_items
if item.item_code in pi_item_code
}

return item_to_po_map


@frappe.whitelist()
def change_release_date(name, release_date=None):
if frappe.db.exists("Purchase Invoice", name):
Expand Down

0 comments on commit a6911d0

Please sign in to comment.