Skip to content

Commit

Permalink
feat: Batch wise item pricing (#24470)
Browse files Browse the repository at this point in the history
* feat: Batch wise item pricing

* fix: Rate for items with no batch

* fix: Add test case for batch pricing

* fix: Sider Issues

* fix: Add item filter for batch
  • Loading branch information
deepeshgarg007 authored Jan 28, 2021
1 parent 907e299 commit bd9bdc5
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 31 deletions.
4 changes: 4 additions & 0 deletions erpnext/public/js/controllers/buying.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
this._super(doc, cdt, cdn);
},

batch_no: function(doc, cdt, cdn) {
this._super(doc, cdt, cdn);
},

received_qty: function(doc, cdt, cdn) {
this.calculate_accepted_qty(doc, cdt, cdn)
},
Expand Down
6 changes: 6 additions & 0 deletions erpnext/public/js/controllers/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
}
},

batch_no: function(doc, cdt, cdn) {
let item = frappe.get_doc(cdt, cdn);
this.apply_price_list(item, true);
},

toggle_conversion_factor: function(item) {
// toggle read only property for conversion factor field if the uom and stock uom are same
if(this.frm.get_field('items').grid.fields_map.conversion_factor) {
Expand Down Expand Up @@ -1403,6 +1408,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
"pricing_rules": d.pricing_rules,
"warehouse": d.warehouse,
"serial_no": d.serial_no,
"batch_no": d.batch_no,
"price_list_rate": d.price_list_rate,
"conversion_factor": d.conversion_factor || 1.0
});
Expand Down
4 changes: 4 additions & 0 deletions erpnext/selling/sales_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,10 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
}
},

batch_no: function(doc, cdt, cdn) {
this._super(doc, cdt, cdn);
},

qty: function(doc, cdt, cdn) {
this._super(doc, cdt, cdn);

Expand Down
70 changes: 69 additions & 1 deletion erpnext/stock/doctype/batch/test_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from erpnext.stock.doctype.batch.batch import get_batch_qty, UnableToSelectBatchError, get_batch_no
from frappe.utils import cint, flt
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.stock.get_item_details import get_item_details

class TestBatch(unittest.TestCase):
def test_item_has_batch_enabled(self):
Expand Down Expand Up @@ -182,7 +184,7 @@ def test_total_batch_qty(self):
stock_entry.cancel()
current_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty"))
self.assertEqual(current_batch_qty, existing_batch_qty)

@classmethod
def make_new_batch_and_entry(cls, item_name, batch_name, warehouse):
'''Make a new stock entry for given target warehouse and batch name of item'''
Expand Down Expand Up @@ -252,6 +254,72 @@ def make_new_batch(self, item_name, batch_id=None, do_not_insert=0):

return batch

def test_batch_wise_item_price(self):
if not frappe.db.get_value('Item', '_Test Batch Price Item'):
frappe.get_doc({
'doctype': 'Item',
'is_stock_item': 1,
'item_code': '_Test Batch Price Item',
'item_group': 'Products',
'has_batch_no': 1,
'create_new_batch': 1
}).insert(ignore_permissions=True)

batch1 = create_batch('_Test Batch Price Item', 200, 1)
batch2 = create_batch('_Test Batch Price Item', 300, 1)
batch3 = create_batch('_Test Batch Price Item', 400, 0)

args = frappe._dict({
"item_code": "_Test Batch Price Item",
"company": "_Test Company with perpetual inventory",
"price_list": "_Test Price List",
"currency": "_Test Currency",
"doctype": "Sales Invoice",
"conversion_rate": 1,
"price_list_currency": "_Test Currency",
"plc_conversion_rate": 1,
"customer": "_Test Customer",
"name": None
})

#test price for batch1
args.update({'batch_no': batch1})
details = get_item_details(args)
self.assertEqual(details.get('price_list_rate'), 200)

#test price for batch2
args.update({'batch_no': batch2})
details = get_item_details(args)
self.assertEqual(details.get('price_list_rate'), 300)

#test price for batch3
args.update({'batch_no': batch3})
details = get_item_details(args)
self.assertEqual(details.get('price_list_rate'), 400)

def create_batch(item_code, rate, create_item_price_for_batch):
pi = make_purchase_invoice(company="_Test Company with perpetual inventory",
warehouse= "Stores - TCP1", cost_center = "Main - TCP1", update_stock=1,
expense_account ="_Test Account Cost for Goods Sold - TCP1", item_code=item_code)

batch = frappe.db.get_value('Batch', {'item': item_code, 'reference_name': pi.name})

if not create_item_price_for_batch:
create_price_list_for_batch(item_code, None, rate)
else:
create_price_list_for_batch(item_code, batch, rate)

return batch

def create_price_list_for_batch(item_code, batch, rate):
frappe.get_doc({
'doctype': 'Item Price',
'item_code': '_Test Batch Price Item',
'price_list': '_Test Price List',
'batch_no': batch,
'price_list_rate': rate
}).insert()

def make_new_batch(**args):
args = frappe._dict(args)

Expand Down
8 changes: 8 additions & 0 deletions erpnext/stock/doctype/item_price/item_price.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,13 @@ frappe.ui.form.on("Item Price", {

frm.set_df_property("bulk_import_help", "options",
'<a href="#data-import-tool/Item Price">' + __("Import in Bulk") + '</a>');

frm.set_query('batch_no', function() {
return {
filters: {
'item': frm.doc.item_code
}
}
});
}
});
Loading

0 comments on commit bd9bdc5

Please sign in to comment.