[Tutorial]
Dear All,
i solved this problem of changing has_batch for an item(s) after making transactions easily as below : (Use carefully and only if you know what you are doing)
First create a custom app with any name with a single DocType
then create a button field named convert_non_batch_to_has_batch
Second use the below code for client-side
frappe.ui.form.on('Infinity', {
refresh: function(frm) {
},
convert_non_batch_to_has_batch: function(frm){
handle_convert_non_batch_to_has_batch(frm);
}
});
var handle_convert_non_batch_to_has_batch = function(frm){
frappe.warn('Are you sure you want to proceed?',
'This is a low level procedure and may harm your data if misused!!',
() => {
// action to perform if Continue is selected
frappe.prompt([
{
label: 'Item Group',
fieldname: 'item_group',
fieldtype: 'Link',
options: 'Item Group'
},
{
label: 'Batch Number Series',
fieldname: 'batch_number_series',
fieldtype: 'Data'
}
], (values) => {
var group = values.item_group;
var series = values.batch_number_series;
frappe.call({
method: "ifp.ifp_utils.get_items_without_has_batch_in_item_group",
args: {
group: group,
series: series
},
callback: function(res){
if (res && res.message){
frappe.confirm('Are you sure you want to proceed with ' + res.message +' items in '+ group + ' Group?',
() => {
// action to perform if Yes is selected
frappe.call({
method: "ifp.ifp_utils.handle_convert_non_batch_to_has_batch",
args: {
group: group,
series: series
},
callback: function(res){
if (res && res.message){
frappe.msgprint('Successfully processed '+ res.message +' Items.');
}
}
});
}, () => {
// action to perform if No is selected
}
)
}
}
});
})
},
'Continue',
//true // Sets dialog as minimizable
)
}
Third use the below code for server-side
from __future__ import unicode_literals
from frappe import publish_progress
import frappe
import json
@frappe.whitelist()
def get_items_without_has_batch_in_item_group(group, series):
if not group or not series:
return 0
counter = 0
for item in frappe.db.get_list('Item', filters={'item_group': group, 'has_batch_no': 0}, fields=['item_code', 'item_name'], order_by='item_code', as_list=False):
counter+=1
return counter
def set_item_batch_properities(item_code, series):
frappe.db.set_value('Item', item_code, {
'has_batch_no': 1,
'create_new_batch': 1,
'batch_number_series': series
})
def create_new_batch(item_code):
batch_no = frappe.get_doc(dict(
doctype='Batch',
item=item_code)).insert().name
return batch_no
def update_stock_ledger(item_code):
batch_no =''
size = len(frappe.db.get_list('Stock Ledger Entry', filters={'item_code': item_code}, fields=['name', 'actual_qty', 'qty_after_transaction', 'voucher_type', 'voucher_detail_no', 'voucher_no'], order_by='name', as_list=False))
if size > 0:
batch_no = create_new_batch(item_code)
for entry in frappe.db.get_list('Stock Ledger Entry', filters={'item_code': item_code}, fields=['name', 'actual_qty', 'qty_after_transaction', 'voucher_type', 'voucher_detail_no', 'voucher_no'], order_by='name', as_list=False):
frappe.db.set_value('Stock Ledger Entry', entry.name, {
'batch_no': batch_no
})
if entry.voucher_type == 'Stock Reconciliation':
srd = frappe.get_doc('Stock Reconciliation', entry.voucher_no)
if srd.purpose == 'Opening Stock' and entry.actual_qty == 0:
frappe.db.set_value('Stock Ledger Entry', entry.name, {
'actual_qty': entry.qty_after_transaction
})
@frappe.whitelist()
def handle_convert_non_batch_to_has_batch(group, series):
if not group or not series:
return 0
counter = 0
size = len(frappe.db.get_list('Item', filters={'item_group': group, 'has_batch_no': 0}, fields=['item_code', 'item_name'], order_by='item_code', as_list=False))
for item in frappe.db.get_list('Item', filters={'item_group': group, 'has_batch_no': 0}, fields=['item_code', 'item_name'], order_by='item_code', as_list=False):
if counter > -1:
set_item_batch_properities(item.item_code, series)
update_stock_ledger(item.item_code)
counter+=1
progress = counter / size * 100
frappe.publish_progress(float(counter*100)/size, title = "Processing Items...")
return counter