Setting Batch for existing items

Dear All,
i solved this problem 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
2 Likes