mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-09 00:01:18 +00:00
fix: Add validations and other fixes
This commit is contained in:
@@ -761,6 +761,7 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:parent.is_internal_supplier && parent.update_stock",
|
||||
"fieldname": "from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
@@ -794,7 +795,7 @@
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-12-25 23:43:57.272553",
|
||||
"modified": "2020-12-26 17:20:36.415791",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Item",
|
||||
|
||||
@@ -22,6 +22,7 @@ from erpnext.regional.india.utils import get_ewb_data
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
|
||||
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
|
||||
from erpnext.stock.utils import get_incoming_rate
|
||||
|
||||
class TestSalesInvoice(unittest.TestCase):
|
||||
def make(self):
|
||||
@@ -1801,6 +1802,24 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.items[0].target_warehouse = 'Work In Progress - TCP1'
|
||||
add_taxes(si)
|
||||
si.save()
|
||||
|
||||
rate = 0.0
|
||||
for d in si.get('items'):
|
||||
rate = get_incoming_rate({
|
||||
"item_code": d.item_code,
|
||||
"warehouse": d.warehouse,
|
||||
"posting_date": si.posting_date,
|
||||
"posting_time": si.posting_time,
|
||||
"qty": -1 * flt(d.get('stock_qty')),
|
||||
"serial_no": d.serial_no,
|
||||
"company": si.company,
|
||||
"voucher_type": 'Sales Invoice',
|
||||
"voucher_no": si.name,
|
||||
"allow_zero_valuation": d.get("allow_zero_valuation")
|
||||
}, raise_error_if_no_rate=False)
|
||||
|
||||
rate = flt(rate, 2)
|
||||
|
||||
si.submit()
|
||||
|
||||
target_doc = make_inter_company_transaction("Sales Invoice", si.name)
|
||||
@@ -1810,18 +1829,23 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
target_doc.save()
|
||||
target_doc.submit()
|
||||
|
||||
tax_amount = flt(rate * (12/100), 2)
|
||||
si_gl_entries = [
|
||||
["_Test Account Excise Duty - TCP1", 0.0, 12.0, nowdate()],
|
||||
["Unrealized Profit - TCP1", 12.0, 0.0, nowdate()]
|
||||
["_Test Account Excise Duty - TCP1", 0.0, tax_amount, nowdate()],
|
||||
["Unrealized Profit - TCP1", tax_amount, 0.0, nowdate()]
|
||||
]
|
||||
|
||||
check_gl_entries(self, si.name, si_gl_entries, add_days(nowdate(), -1))
|
||||
|
||||
pi_gl_entries = [
|
||||
["_Test Account Excise Duty - TCP1", 12.0 , 0.0, nowdate()],
|
||||
["Unrealized Profit - TCP1", 0.0, 12.0, nowdate()]
|
||||
["_Test Account Excise Duty - TCP1", tax_amount , 0.0, nowdate()],
|
||||
["Unrealized Profit - TCP1", 0.0, tax_amount, nowdate()]
|
||||
]
|
||||
|
||||
# Sale and Purchase both should be at valuation rate
|
||||
self.assertEqual(si.items[0].rate, rate)
|
||||
self.assertEqual(target_doc.items[0].rate, rate)
|
||||
|
||||
check_gl_entries(self, target_doc.name, pi_gl_entries, add_days(nowdate(), -1))
|
||||
|
||||
def test_eway_bill_json(self):
|
||||
|
||||
@@ -565,6 +565,7 @@
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: parent.is_internal_customer && parent.update_stock",
|
||||
"fieldname": "target_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
@@ -815,7 +816,7 @@
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-12-25 22:46:26.778091",
|
||||
"modified": "2020-12-26 17:25:04.090630",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
|
||||
@@ -963,9 +963,9 @@ class AccountsController(TransactionBase):
|
||||
It will an internal transfer if its an internal customer and representation
|
||||
company is same as billing company
|
||||
"""
|
||||
if self.doctype == 'Sales Invoice':
|
||||
if self.doctype in ('Sales Invoice', 'Delivery Note'):
|
||||
internal_party_field = 'is_internal_customer'
|
||||
else:
|
||||
elif self.doctype in ('Purchase Invoice', 'Purchase Invoice Item'):
|
||||
internal_party_field = 'is_internal_supplier'
|
||||
|
||||
if self.get(internal_party_field) and (self.represents_company == self.company):
|
||||
|
||||
@@ -235,7 +235,7 @@ class BuyingController(StockController):
|
||||
"warehouse": d.from_warehouse,
|
||||
"posting_date": self.posting_date,
|
||||
"posting_time": self.posting_time,
|
||||
"qty": -1 * flt(d.stock_qty),
|
||||
"qty": -1 * flt(d.get('stock_qty')),
|
||||
"serial_no": d.serial_no,
|
||||
"company": self.company,
|
||||
"voucher_type": self.doctype,
|
||||
|
||||
@@ -323,7 +323,7 @@ class SellingController(StockController):
|
||||
"warehouse": d.warehouse,
|
||||
"posting_date": self.posting_date,
|
||||
"posting_time": self.posting_time,
|
||||
"qty": -1*flt(d.stock_qty),
|
||||
"qty": -1 * flt(d.get('stock_qty') or d.get('actual_qty')),
|
||||
"serial_no": d.serial_no,
|
||||
"company": self.company,
|
||||
"voucher_type": self.doctype,
|
||||
|
||||
@@ -23,6 +23,7 @@ class StockController(AccountsController):
|
||||
self.validate_inspection()
|
||||
self.validate_serialized_batch()
|
||||
self.validate_customer_provided_item()
|
||||
self.validate_internal_transfer()
|
||||
|
||||
def make_gl_entries(self, gl_entries=None, from_repost=False):
|
||||
if self.docstatus == 2:
|
||||
@@ -72,7 +73,13 @@ class StockController(AccountsController):
|
||||
warehouse_with_no_account = []
|
||||
precision = frappe.get_precision("GL Entry", "debit_in_account_currency")
|
||||
for item_row in voucher_details:
|
||||
sle_list = sle_map.get((item_row.name, item_row.warehouse))
|
||||
|
||||
if self.doctype == 'Stock Entry':
|
||||
warehouse_field = 's_warehouse'
|
||||
else:
|
||||
warehouse_field = 'warehouse'
|
||||
|
||||
sle_list = sle_map.get((item_row.name, item_row.get(warehouse_field)))
|
||||
if sle_list:
|
||||
for sle in sle_list:
|
||||
if warehouse_account.get(sle.warehouse):
|
||||
@@ -391,6 +398,40 @@ class StockController(AccountsController):
|
||||
if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
|
||||
d.allow_zero_valuation_rate = 1
|
||||
|
||||
def validate_internal_transfer(self):
|
||||
if self.doctype in ('Sales Invoice', 'Delivery Note', 'Purchase Invoice', 'Purchase Receipt') \
|
||||
and self.is_internal_transfer():
|
||||
self.validate_in_transit_warehouses()
|
||||
self.validate_multi_currency()
|
||||
self.validate_packed_items()
|
||||
self.validate_inter_company_reference()
|
||||
|
||||
def validate_in_transit_warehouses(self):
|
||||
if self.doctype in ('Sales Invoice', 'Delivery Note'):
|
||||
for item in self.get('items'):
|
||||
if not item.target_warehouse:
|
||||
frappe.throw(_("Row {0}: Target Warehouse is mandatory for internal transfers"))
|
||||
|
||||
if self.doctype in ('Purchase Invoice', 'Purchase Receipt'):
|
||||
for item in self.get('items'):
|
||||
if not item.from_warehouse:
|
||||
frappe.throw(_("Row {0}: From Warehouse is mandatory for internal transfers"))
|
||||
|
||||
def validate_multi_currency(self):
|
||||
if self.currency != self.company_currency:
|
||||
frappe.throw(_("Internal transfers can only be done in company's default currency"))
|
||||
|
||||
def validate_packed_items(self):
|
||||
if self.doctype in ('Sales Invoice', 'Delivery Note Item') and self.get('packed_items'):
|
||||
frappe.throw(_("Packed Items cannot be transferred internally"))
|
||||
|
||||
def validate_inter_company_reference(self):
|
||||
if self.doctype in ('Purchase Invoice', 'Purchase Receipt'):
|
||||
if not (self.get('inter_company_reference') or self.get('inter_company_invoice_reference')):
|
||||
msg = _("Internal Sale or Delivery Reference needed for internal purchase")
|
||||
msg += _("Please create purchase from the internal sale or delivery document itself")
|
||||
frappe.throw(msg)
|
||||
|
||||
def repost_future_sle_and_gle(self):
|
||||
args = frappe._dict({
|
||||
"posting_date": self.posting_date,
|
||||
|
||||
@@ -117,6 +117,7 @@
|
||||
"source",
|
||||
"column_break5",
|
||||
"is_internal_customer",
|
||||
"represents_company",
|
||||
"inter_company_reference",
|
||||
"per_billed",
|
||||
"customer_group",
|
||||
@@ -1261,13 +1262,22 @@
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"description": "Company which internal customer represents.",
|
||||
"fetch_from": "customer.represents_company",
|
||||
"fieldname": "represents_company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Represents Company",
|
||||
"options": "Company",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-truck",
|
||||
"idx": 146,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-12-25 23:11:46.584226",
|
||||
"modified": "2020-12-26 17:07:59.194403",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note",
|
||||
|
||||
@@ -458,7 +458,7 @@
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "From Warehouse",
|
||||
"label": "Warehouse",
|
||||
"oldfieldname": "warehouse",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
@@ -467,11 +467,12 @@
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:parent.is_internal_customer",
|
||||
"fieldname": "target_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Customer Warehouse (Optional)",
|
||||
"label": "Target Warehouse",
|
||||
"no_copy": 1,
|
||||
"options": "Warehouse",
|
||||
"print_hide": 1
|
||||
@@ -748,7 +749,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-12-07 19:59:27.119856",
|
||||
"modified": "2020-12-26 17:31:27.029803",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note Item",
|
||||
|
||||
@@ -115,6 +115,7 @@
|
||||
"per_returned",
|
||||
"is_internal_supplier",
|
||||
"inter_company_reference",
|
||||
"represents_company",
|
||||
"subscription_detail",
|
||||
"auto_repeat",
|
||||
"printing_settings",
|
||||
@@ -1123,13 +1124,21 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Set From Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fetch_from": "supplier.represents_company",
|
||||
"fieldname": "represents_company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Represents Company",
|
||||
"options": "Company",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-truck",
|
||||
"idx": 261,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-12-25 23:15:01.451518",
|
||||
"modified": "2020-12-26 17:10:00.798835",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt",
|
||||
|
||||
@@ -819,11 +819,12 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:parent.is_internal_supplier",
|
||||
"fieldname": "from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Supplier Warehouse",
|
||||
"label": "From Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
@@ -875,7 +876,7 @@
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-12-25 22:33:12.057271",
|
||||
"modified": "2020-12-26 16:50:56.479347",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt Item",
|
||||
|
||||
@@ -377,14 +377,14 @@ class update_entries_after(object):
|
||||
|
||||
def update_rate_on_delivery_and_sales_return(self, sle, outgoing_rate):
|
||||
if frappe.db.get_value(sle.voucher_type, sle.voucher_no, 'is_internal_customer'):
|
||||
frappe.db.set_value(doctype + " Item", voucher_detail_no, "rate", rate)
|
||||
frappe.db.set_value(sle.voucher_type + " Item", sle.voucher_detail_no, "rate", outgoing_rate)
|
||||
update_taxes_and_totals(sle.voucher_type, sle.voucher_no, outgoing_rate)
|
||||
|
||||
purchase_doctype = 'Purchase Invoice' if sle.voucher_type == 'Sales Invoice' else 'Purchase Receipt'
|
||||
ref_field = frappe.scrub(sle.voucher_type + ' Item')
|
||||
|
||||
purchase_document_list = frappe.db.get_all(purchase_doctype, {'inter_company_invoice_reference':
|
||||
sle.voucher_no}, ['name'], as_dict=1)
|
||||
sle.voucher_no}, ['name'])
|
||||
|
||||
for d in purchase_document_list:
|
||||
frappe.db.set_value(purchase_doctype + ' Item', {ref_field: sle.voucher_detail_no}, 'rate', outgoing_rate)
|
||||
@@ -400,13 +400,6 @@ class update_entries_after(object):
|
||||
{"parent_detail_docname": sle.voucher_detail_no, "item_code": sle.item_code},
|
||||
"incoming_rate", outgoing_rate)
|
||||
|
||||
def update_taxes_and_totals(doctype, docname, rate):
|
||||
ref_doc = frappe.get_doc(doctype, docname)
|
||||
ref_doc.calculate_taxes_and_totals()
|
||||
ref_doc.db_update()
|
||||
for d in ref_doc.items:
|
||||
d.db_update()
|
||||
|
||||
def update_rate_on_purchase_receipt(self, sle, outgoing_rate):
|
||||
if frappe.db.exists(sle.voucher_type + " Item", sle.voucher_detail_no):
|
||||
frappe.db.set_value(sle.voucher_type + " Item", sle.voucher_detail_no, "base_net_rate", outgoing_rate)
|
||||
@@ -508,8 +501,6 @@ class update_entries_after(object):
|
||||
self.wh_data.valuation_rate = new_stock_value / new_stock_qty
|
||||
else:
|
||||
self.wh_data.valuation_rate = sle.outgoing_rate
|
||||
|
||||
print(self.wh_data.valuation_rate, "$#$#$#$#")
|
||||
else:
|
||||
if flt(self.wh_data.qty_after_transaction) >= 0 and sle.outgoing_rate:
|
||||
self.wh_data.valuation_rate = sle.outgoing_rate
|
||||
@@ -667,6 +658,13 @@ class update_entries_after(object):
|
||||
bin_doc.flags.via_stock_ledger_entry = True
|
||||
bin_doc.save(ignore_permissions=True)
|
||||
|
||||
def update_taxes_and_totals(doctype, docname, rate):
|
||||
ref_doc = frappe.get_doc(doctype, docname)
|
||||
ref_doc.calculate_taxes_and_totals()
|
||||
ref_doc.db_update()
|
||||
for d in ref_doc.items:
|
||||
d.db_update()
|
||||
|
||||
def get_previous_sle(args, for_update=False):
|
||||
"""
|
||||
get the last sle on or before the current time-bucket,
|
||||
|
||||
Reference in New Issue
Block a user