feat: fetching of qty as per received qty from PR to PI (#25837)
This commit is contained in:
parent
da66cefefc
commit
53fefd7513
@ -9,13 +9,14 @@
|
|||||||
"supp_master_name",
|
"supp_master_name",
|
||||||
"supplier_group",
|
"supplier_group",
|
||||||
"buying_price_list",
|
"buying_price_list",
|
||||||
|
"maintain_same_rate_action",
|
||||||
|
"role_to_override_stop_action",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"po_required",
|
"po_required",
|
||||||
"pr_required",
|
"pr_required",
|
||||||
"maintain_same_rate",
|
"maintain_same_rate",
|
||||||
"maintain_same_rate_action",
|
|
||||||
"role_to_override_stop_action",
|
|
||||||
"allow_multiple_items",
|
"allow_multiple_items",
|
||||||
|
"bill_for_rejected_quantity_in_purchase_invoice",
|
||||||
"subcontract",
|
"subcontract",
|
||||||
"backflush_raw_materials_of_subcontract_based_on",
|
"backflush_raw_materials_of_subcontract_based_on",
|
||||||
"column_break_11",
|
"column_break_11",
|
||||||
@ -108,6 +109,13 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Role Allowed to Override Stop Action",
|
"label": "Role Allowed to Override Stop Action",
|
||||||
"options": "Role"
|
"options": "Role"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "1",
|
||||||
|
"description": "If checked, Rejected Quantity will be included while making Purchase Invoice from Purchase Receipt.",
|
||||||
|
"fieldname": "bill_for_rejected_quantity_in_purchase_invoice",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Bill for Rejected Quantity in Purchase Invoice"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-cog",
|
"icon": "fa fa-cog",
|
||||||
@ -115,7 +123,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-04-04 20:01:44.087066",
|
"modified": "2021-06-23 19:40:00.120822",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Buying Settings",
|
"name": "Buying Settings",
|
||||||
|
@ -828,8 +828,14 @@ class AccountsController(TransactionBase):
|
|||||||
role_allowed_to_over_bill = frappe.db.get_single_value('Accounts Settings', 'role_allowed_to_over_bill')
|
role_allowed_to_over_bill = frappe.db.get_single_value('Accounts Settings', 'role_allowed_to_over_bill')
|
||||||
|
|
||||||
if total_billed_amt - max_allowed_amt > 0.01 and role_allowed_to_over_bill not in frappe.get_roles():
|
if total_billed_amt - max_allowed_amt > 0.01 and role_allowed_to_over_bill not in frappe.get_roles():
|
||||||
frappe.throw(_("Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set allowance in Accounts Settings")
|
if self.doctype != "Purchase Invoice":
|
||||||
.format(item.item_code, item.idx, max_allowed_amt))
|
self.throw_overbill_exception(item, max_allowed_amt)
|
||||||
|
elif not cint(frappe.db.get_single_value("Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice")):
|
||||||
|
self.throw_overbill_exception(item, max_allowed_amt)
|
||||||
|
|
||||||
|
def throw_overbill_exception(self, item, max_allowed_amt):
|
||||||
|
frappe.throw(_("Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set allowance in Accounts Settings")
|
||||||
|
.format(item.item_code, item.idx, max_allowed_amt))
|
||||||
|
|
||||||
def get_company_default(self, fieldname):
|
def get_company_default(self, fieldname):
|
||||||
from erpnext.accounts.utils import get_company_default
|
from erpnext.accounts.utils import get_company_default
|
||||||
|
@ -288,4 +288,5 @@ execute:frappe.rename_doc("Workspace", "Loan Management", "Loans", force=True)
|
|||||||
erpnext.patches.v13_0.update_timesheet_changes
|
erpnext.patches.v13_0.update_timesheet_changes
|
||||||
erpnext.patches.v13_0.add_doctype_to_sla #14-06-2021
|
erpnext.patches.v13_0.add_doctype_to_sla #14-06-2021
|
||||||
erpnext.patches.v13_0.set_training_event_attendance
|
erpnext.patches.v13_0.set_training_event_attendance
|
||||||
|
erpnext.patches.v13_0.bill_for_rejected_quantity_in_purchase_invoice
|
||||||
erpnext.patches.v13_0.rename_issue_status_hold_to_on_hold
|
erpnext.patches.v13_0.rename_issue_status_hold_to_on_hold
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doctype("Buying Settings")
|
||||||
|
buying_settings = frappe.get_single("Buying Settings")
|
||||||
|
buying_settings.bill_for_rejected_quantity_in_purchase_invoice = 0
|
||||||
|
buying_settings.save()
|
@ -581,7 +581,6 @@ def update_billing_percentage(pr_doc, update_modified=True):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_purchase_invoice(source_name, target_doc=None):
|
def make_purchase_invoice(source_name, target_doc=None):
|
||||||
from frappe.model.mapper import get_mapped_doc
|
|
||||||
from erpnext.accounts.party import get_payment_terms_template
|
from erpnext.accounts.party import get_payment_terms_template
|
||||||
|
|
||||||
doc = frappe.get_doc('Purchase Receipt', source_name)
|
doc = frappe.get_doc('Purchase Receipt', source_name)
|
||||||
@ -601,11 +600,16 @@ def make_purchase_invoice(source_name, target_doc=None):
|
|||||||
|
|
||||||
def update_item(source_doc, target_doc, source_parent):
|
def update_item(source_doc, target_doc, source_parent):
|
||||||
target_doc.qty, returned_qty = get_pending_qty(source_doc)
|
target_doc.qty, returned_qty = get_pending_qty(source_doc)
|
||||||
|
if frappe.db.get_single_value("Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice"):
|
||||||
|
target_doc.rejected_qty = 0
|
||||||
target_doc.stock_qty = flt(target_doc.qty) * flt(target_doc.conversion_factor, target_doc.precision("conversion_factor"))
|
target_doc.stock_qty = flt(target_doc.qty) * flt(target_doc.conversion_factor, target_doc.precision("conversion_factor"))
|
||||||
returned_qty_map[source_doc.name] = returned_qty
|
returned_qty_map[source_doc.name] = returned_qty
|
||||||
|
|
||||||
def get_pending_qty(item_row):
|
def get_pending_qty(item_row):
|
||||||
pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0)
|
qty = item_row.qty
|
||||||
|
if frappe.db.get_single_value("Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice"):
|
||||||
|
qty = item_row.received_qty
|
||||||
|
pending_qty = qty - invoiced_qty_map.get(item_row.name, 0)
|
||||||
returned_qty = flt(returned_qty_map.get(item_row.name, 0))
|
returned_qty = flt(returned_qty_map.get(item_row.name, 0))
|
||||||
if returned_qty:
|
if returned_qty:
|
||||||
if returned_qty >= pending_qty:
|
if returned_qty >= pending_qty:
|
||||||
|
@ -421,11 +421,18 @@ class TestPurchaseReceipt(unittest.TestCase):
|
|||||||
self.assertEqual(return_pr_2.items[0].qty, -3)
|
self.assertEqual(return_pr_2.items[0].qty, -3)
|
||||||
|
|
||||||
# Make PI against unreturned amount
|
# Make PI against unreturned amount
|
||||||
|
buying_settings = frappe.get_single("Buying Settings")
|
||||||
|
buying_settings.bill_for_rejected_quantity_in_purchase_invoice = 0
|
||||||
|
buying_settings.save()
|
||||||
|
|
||||||
pi = make_purchase_invoice(pr.name)
|
pi = make_purchase_invoice(pr.name)
|
||||||
pi.submit()
|
pi.submit()
|
||||||
|
|
||||||
self.assertEqual(pi.items[0].qty, 3)
|
self.assertEqual(pi.items[0].qty, 3)
|
||||||
|
|
||||||
|
buying_settings.bill_for_rejected_quantity_in_purchase_invoice = 1
|
||||||
|
buying_settings.save()
|
||||||
|
|
||||||
pr.load_from_db()
|
pr.load_from_db()
|
||||||
# PR should be completed on billing all unreturned amount
|
# PR should be completed on billing all unreturned amount
|
||||||
self.assertEqual(pr.items[0].billed_amt, 150)
|
self.assertEqual(pr.items[0].billed_amt, 150)
|
||||||
@ -767,8 +774,8 @@ class TestPurchaseReceipt(unittest.TestCase):
|
|||||||
pr1.items[0].purchase_receipt_item = pr.items[0].name
|
pr1.items[0].purchase_receipt_item = pr.items[0].name
|
||||||
pr1.submit()
|
pr1.submit()
|
||||||
|
|
||||||
pi = make_purchase_invoice(pr.name)
|
pi1 = make_purchase_invoice(pr.name)
|
||||||
self.assertEqual(pi.items[0].qty, 3)
|
self.assertEqual(pi1.items[0].qty, 3)
|
||||||
|
|
||||||
pr1.cancel()
|
pr1.cancel()
|
||||||
pr.reload()
|
pr.reload()
|
||||||
|
Loading…
Reference in New Issue
Block a user