<?php
defined('BASEPATH') or exit('No direct script access allowed');

class StockModel extends ReportModel
{
	/*
		G - Goods, S - Services, Y- Assembly, B- Bundled, R - Rental/Returnable Goods, T- Storage Rental
	*/
	public $it_type = array('G','S','Y','T');
	private $orderListRange = '6';

	public function __construct()
	{
		parent::__construct();

		
		if (sal_mod_active(RETURN_GOODS)) {
			$this->it_type[] = 'R';
		}
	}

	public function get_bw_map($branch, $params=array()) {
		$bw_map = array();
		if (sal_mod_active(BRANCH_MOD) && $branch != -1) {
			if (!empty($params['transaction']) && !empty($params['brachQty'])) {
				// transaction qty validation strictly check selected location
				return array($branch);
			}
			$bw_map = array($branch);
			
			$tmp_bw_map = get_company('bw_map');
			
			if(!empty($tmp_bw_map[$branch])){
				if (!isset($params['location']) || $params['location'] == -1) {
					$bw_map = explode(',',$tmp_bw_map[$branch]);
					$bw_map[] = $branch;
				} else if($params['location']!=$branch){
					$bw_map = array($params['location']);
				}
			}

			if (!$branch && !empty($tmp_bw_map['-1'])) {
				$bw_map = array_merge($bw_map,explode(',',$tmp_bw_map['-1']));
			}
		}

		return $bw_map;
	}


	public function trans_perm_loc($branch) // isactive 2 - location shared with other branchs
	{
		// get all warehouse linked with branch
		$this->db->select('group_concat(c.id) as bw_map')->from('contacts AS c');
		if (!get_user_data('isAdmin')) {
			$this->db->join('compusers_location as cl', 'cl.locId = c.Id AND cl.uId = ' . get_user_data('id'));
		}

		$this->db->where(array(
			"c.cId" => $this->cId,
			"c.isActive >" => "0"
		));

		$this->db->where_in('c.csType', array('B', 'L', 'F'));
		$this->db->group_start();
			$this->db->group_start();
				$this->db->where('c.id', $branch);
				$this->db->or_group_start();
					$this->db->where('c.bId', $branch);
					$this->db->where_in('c.csType', array('L', 'F'));
				$this->db->group_end();
			$this->db->group_end();
			// $this->db->or_group_start();
			// 	$this->db->where(array(
			// 		'c.csType' => 'L',
			// 		'c.isActive' => 2
			// 	));
			// $this->db->group_end();
		$this->db->group_end();
		$this->db->group_by('c.bId');

		$tmp = $this->db->get()->result_array();
		$bw_map=array();

		foreach($tmp as $val){
			$bw_map[] = $val['bw_map'];
		}
		return $bw_map;
	}
	// stk_type  - report type
	// brachQty - brachwise qty
	// detail - summary inward or outward details
	//attrValues - attribute wise qty in transaction
	public function from($params=array(),$stock=false,$detail=false) {
		
		$stock_ledger= (!empty($params['stk_type']) && ($params['stk_type'] == "stock_ledger"))?true:false;
		if (!$stock) {
			$this->db->from('trans AS t');
			$this->db->join('trans_items AS ti', 'ti.transId=t.id');
			$this->db->join('items AS it', 'it.itemId=ti.itemId');
			$this->db->join('item_attr AS iar','iar.itemAttrId=ti.itemAttrId and iar.itemId=ti.itemId','left');
			$this->db->join('itemrelunits AS itr', 'itr.itemId=ti.itemId and itr.relUnitName=ti.unit', 'left');
			if(!empty($params['contBrch'])) {
				$this->db->join("contacts as brchcont","brchcont.id = t.bId","left");
			}
			if (!$detail) {
				$this->db->join('trans_items_rel as tirel', 'tirel.transItemId= ti.id and t.tType IN ("SC","GR")', 'left');
				// $this->db->join('ob_trans_ref as tref', 'tref.transId=t.id', 'left'); removed due to stock summary item qty duplicate on multipe reference
				// $this->db->join('ob_trans as treftrans', 'treftrans.Id=tref.reftransId', 'left');
			}
			if (!empty($params['inward_details']))
			{
				$this->db->join('(SELECT tref.refTransId, tpi.refTitemId,tp.tNo,tp.tType,tp.id,tpi.qty,tpi.freeQty,tpi.chargesAmount,
				tpi.taxableAmount, tpi.itemTotal,tpi.itc,itrr.convFactor from ob_trans_ref AS tref
				JOIN ob_trans tp on tp.id=tref.transId and  tp.tType IN ("PI","PR","EI","PE","PD") 
				JOIN ob_trans_items as tpi on tpi.transid=tp.id
				LEFT JOIN ob_itemrelunits AS itrr ON itrr.itemId=tpi.itemId and itrr.relUnitName=tpi.unit) as refsrc',
				'refsrc.refTransId=t.id  and t.tType IN ("GR")  and t.categoryCode !="TL" and refsrc.refTitemId=ti.id
				','left');
			}
			if(!empty($params['serialIds'])){
				$serial_select_query = "SELECT ts.tsItemId from " . $this->db->dbprefix('trans_serial'). " as ts WHERE ts.asId IN (" . $params['serialIds'] . ")";
				$this->db->join('trans_serial AS ots','ots.tsItemId = ti.id AND ots.tsItemId IN ('. $serial_select_query . ')');
			}
		} else {
			$this->db->from('stock_entries AS se');
			$this->db->join('stock_items AS si', 'si.sId=se.id');
			$this->db->join('items AS it', 'it.itemId=si.itemId');
			$this->db->join('itemrelunits AS itr', 'itr.itemId=si.itemId and itr.relUnitName=si.unit', 'left');
			$this->db->join('item_attr AS iar','iar.itemAttrId=si.itemAttrId and iar.itemId=si.itemId','left');
			if(!empty($params['contBrch'])) {
				$this->db->join("contacts as brchcont","brchcont.id = si.fromLocId","left");
			}
			if(!empty($params['serialIds'])){
				$serial_select_query = "SELECT ts.tsItemId from " . $this->db->dbprefix('trans_serial'). " as ts WHERE ts.asId IN (" . $params['serialIds'] . ")";
				$this->db->join('trans_serial AS ots', 'ots.tsItemId = si.id AND ots.tsItemId IN(' . $serial_select_query. ')');
			}
		}
		
		// include category
		if (!empty($params['catId']) || !empty($params['catColumn']) || !empty($params['catIds'])) {
			if(!empty($params['catId']) && !is_array($params['catId'])){
				$params['catIds'] = $params['catId'];
			}
			// $this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=it.itemId');
			// $this->db->join('category AS c','c.id=ic.catId');
			$cat_query = '(select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catIds'].')) sq_exis';
			$this->db->join($cat_query,'sq_exis.itemId = it.itemId');
		} else if (!empty($params['nested_category'])) 
		{
			$this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=it.itemId');
			$this->db->where('ic.catId in (select id from (select * from '.$this->db->dbprefix("category").' where cId='.$this->cId.' order by pId,id) alldata, (select @pgi:='.$params['nested_category'].') init where cId='.$this->cId.' and find_in_set(pId, @pgi) > 0 and @pgi := concat(@pgi,",",id) union all select '.$params['nested_category'].')',null,false);
		} else if(empty($params['catId']) && !empty($params['stock_category']))
		{
			// items not liked with category
			$this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=it.itemId','left');
			$this->db->where('ic.catId is NULL',null);
		} 
	}

	public function get_child_category($catId){
		if(!empty($catId) && is_array($catId)){
			$catIds = implode(',',$catId);
			$category = $this->db->from("category")->where_in('id',$catId)->where("cId",$this->cId,false)->get()->result_array();
			
				if(!empty($category)){
					foreach($category as $cat){
						if($cat['type'] == 'B'){
							$allCatIds[] = $cat['id'];
						}else{
							$getcatid ="Select group_concat(id) as grpconcatid from ob_category where lft>=".$cat['lft']." and rgt<=".$cat['rgt']." and type='C' and cId=".$this->cId."";
							$getcatids = $this->db->query($getcatid)->row_array();
							if (!empty($getcatids['grpconcatid'])) {
								$allCatIds[] = $getcatids['grpconcatid'];
							}
						}
					}				
					if (!empty($allCatIds)) {
						$catIds = implode(',', $allCatIds);						
					}
				}
			return $catIds;
		}
	}
	public function trans_select($params=array()) {
		//For value,consider only goods
		$detail = (!empty($params['inward_details']) || !empty($params['outward_details'])) ? true : false;
		$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
		$to_date = $params['to_date'];
		get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
		$opening = isset($params['opening']) ? $params['opening'] : 0; // opening balance import

		$open_ttype = '"' . PURINV . '","'.PURRETAIL.'","' . EXPINV .'","' . EXPRETAIL . '","' . PURDBNOTE . '","' . PURRECP . '","' . CRNOTE . '"';
		$pur_ttype = '"' . PURINV . '","'.PURRETAIL.'","' . EXPINV .'","' . EXPRETAIL . '","' . PURDBNOTE . '","' . CRNOTE . '","' . PURRECP . '"';
		$cd_ttype = '"' . PURCRNOTE . '","' . PURDBNOTE . '","' . DBNOTE . '","' . CRNOTE . '"';
		// print_r($params);exit;
		switch ($params['stk_type']) {
			case 'summary': // stock summary
				if (!$detail) {
					$this->db->select('t.tType,ti.locId, ti.itemAttrId, ti.itemId, if(it.name!="",it.name,ti.itemName) as itemName, it.uom AS uom,it.HS as hsn,it.SKU', false);
					$this->db->select('(ti.qty+ti.freeQty) * If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), 1, -1) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
					$this->db->select('If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $pur_ttype . ') and ti.itemTotal > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1), 0) as op_pur_qty', false);
					$this->db->select('If (t.tDate < "' . $from_date . '", IF( t.ttype IN (' . $pur_ttype . ') , /* ti.itc=1 and it.isPurchase != 0 added for maintain Stock Prodcution item cost rate. */ if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + IF( t.ttype IN ("PI","PR","EI","PE"),ti.chargesAmount,0), 0),0) as op_pur_amt', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", IF(t.ttype IN (' . $pur_ttype . ') and ti.itemTotal > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1), 0) as i_pur_qty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", IF( t.ttype IN (' . $pur_ttype . '), if (ti.itc=1, ti.taxableAmount, ti.itemTotal), 0),0)+ IF( t.ttype IN ("PI","PR","EI","PE"),ti.chargesAmount,0) as i_pur_amt', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, (ti.qty+ti.freeQty))) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", IF(it.type = "G",(IF(t.ttype IN (' . $open_ttype . '), 0, if (ti.itc=1, ti.taxableAmount, ti.itemTotal))),0), 0) AS o_amt', false);
					/*used for month wise filter*/
					$this->db->select('IF(t.ttype IN (' . $pur_ttype . ') and ti.itemTotal > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1) as tot_pur_qty', false);
					$this->db->select('IF( t.ttype IN (' . $pur_ttype . '), if (ti.itc=1, ti.taxableAmount, ti.itemTotal), 0)+ IF( t.ttype IN ("PI","PR","EI","PE"),ti.chargesAmount,0) as tot_pur_amt', false);


					$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');
					if ($opening) {
						$this->db->select('iar.mrp', false);
					}
				} else {
					if (!empty($params['inward_details']))
					{
						$this->db->select('if(refsrc.tno is null,t.id,refsrc.id) as id, concat(t.tno,if(refsrc.tno is not null,concat(" (",refsrc.tType,":",refsrc.tno,")"),"")) as tno, if(refsrc.tno is null,t.tType,refsrc.tType) as tType, t.tDate, t.conName, ti.unit,ti.id as itId', false);
						$this->db->select('
						if(refsrc.tno is null,
							if(tirel.cPrice,tirel.cPrice,(if (ti.itc=1, ti.taxableAmount, ti.itemTotal))/(ti.qty+ti.freeQty)) + (IF(t.ttype IN ("PI","PR","EI","PE"),ti.chargesAmount,0)/(ti.qty+ti.freeQty)),
							if(tirel.cPrice,tirel.cPrice,(if (refsrc.itc=1, refsrc.taxableAmount, refsrc.itemTotal))/(refsrc.qty+refsrc.freeQty)) + (IF(refsrc.ttype IN ("PI","PR","EI","PE"),refsrc.chargesAmount,0)/(refsrc.qty+refsrc.freeQty))
						) as trate,
						if(refsrc.tno is null,
							((ti.qty+ti.freeQty)*if(itr.convFactor, itr.convFactor, 1)),
							((refsrc.qty+refsrc.freeQty)*if(refsrc.convFactor, refsrc.convFactor, 1))
						) as s_qty,
						if(refsrc.tno is null,
							if(tirel.cPrice,tirel.cPrice * (ti.qty+ti.freeQty),if (ti.itc=1, ti.taxableAmount, ti.itemTotal)) + IF( t.ttype IN ("PI","PR","EI","PE"),ti.chargesAmount,0),
							if(tirel.cPrice,tirel.cPrice * (refsrc.qty+refsrc.freeQty),if (refsrc.itc=1, refsrc.taxableAmount, refsrc.itemTotal)) + IF( refsrc.ttype IN ("PI","PR","EI","PE"),refsrc.chargesAmount,0)
						) as s_amount,it.uom', false);

					} else {
						$this->db->select('t.id, t.tno, t.tType, t.tDate, t.conName, ti.unit,ti.id as itId', false);
						// $this->db->select('((if (ti.itc=1, ti.taxableAmount, ti.itemTotal))/(ti.qty+ti.freeQty)) + IF( t.ttype IN ("PI","PR","EI","PE"),ti.chargesAmount,0)  as trate,((ti.qty+ti.freeQty)*if(itr.convFactor, itr.convFactor, 1)) as s_qty,if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + IF( t.ttype IN ("PI","PR","EI","PE"),ti.chargesAmount,0) as s_amount,it.uom', false);
						$this->db->select('if(tirel.cPrice,tirel.cPrice,(if (ti.itc=1, ti.taxableAmount, ti.itemTotal))/(ti.qty+ti.freeQty)) + (IF(t.ttype IN ("PI","PR","EI","PE"),ti.chargesAmount,0)/(ti.qty+ti.freeQty))  as trate,((ti.qty+ti.freeQty)*if(itr.convFactor, itr.convFactor, 1)) as s_qty,if(tirel.cPrice,tirel.cPrice * (ti.qty+ti.freeQty),if (ti.itc=1, ti.taxableAmount, ti.itemTotal)) + IF( t.ttype IN ("PI","PR","EI","PE"),ti.chargesAmount,0) as s_amount,it.uom', false);
					}
				}
			break;
			case 'alert':
			case 'current':
				$this->db->select('ti.itemAttrId',false);
				$this->db->select('IF(iar.saleRate IS NULL OR iar.saleRate = 0, it.saleRate, iar.saleRate) AS saleRate, IF(iar.mrp IS NULL OR iar.mrp = 0, it.mrp, iar.mrp) AS mrp, it.stkLevel', false);
				$this->db->select('it.uom',false);
				$this->db->select('sum(if(t.tType IN (' . $this->inward_tTypes . '),if(ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount,0) * if (t.tType!="SC",1,0)) AS pi_rate', false);
				$this->db->select('sum(IF(t.ttype NOT IN (' . $this->inward_tTypes . '), (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1)) as s_qty', false);
				$this->db->select('sum(IF(t.ttype IN (' . $this->inward_tTypes . '), (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1)) as p_qty', false);
				$this->db->select('sum(IF(t.ttype IN (' . $this->inward_tTypes . '), (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1) * if (t.tType!="SC",1,0)) as pur_qty', false); // to ignore sc
				if (!empty($params['brachQty'])) {
					$this->db->select('it.itemId,ti.locId');
				} else {
					$this->db->select('it.itemId,if(it.name!="",it.name,ti.itemName) as itemName,it.SKU', false);
					if(!empty($params['attrValues']) && empty($params['transaction'])) {
						$this->db->select('Replace(iar.sku,"#TID","") as batch', false);
					}
				}

				// include category name
				if (!empty($params['catColumn'])) {
					// $this->db->select('group_concat(distinct c.name) as catName');
					$this->db->select('ic.name as catName');
				}
				if(!empty($params['batchwise_stock'])){
					$this->db->select(',ti.rate',false);
				}
			break;
			case 'stock_value':
				$this->db->select('ti.itemAttrId,ti.itemId as itemId', false);
				$this->db->select('IF(t.ttype IN (' . $this->inward_tTypes . '), 1, -1) * (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) as stk_qty', false);
				$this->db->select('IF(t.ttype IN (' . $pur_ttype . ') and t.tType!="SC" and ti.itemTotal > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1) as pur_qty', false);
				$this->db->select('IF(t.ttype IN (' . $pur_ttype . ') and t.tType!="SC", if (ti.itc=1, ti.taxableAmount, ti.itemTotal)+ ti.chargesAmount, 0) as pur_amt', false);
				$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');	
				
				if(isset($params['branch']))
					$this->db->select('ti.locId as locId');	
			//	$this->db->select('IF(t.ttype IN (' . $pur_ttype . ') and t.tType!="SC" and ti.itemTotal > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1) as tot_pur_qty', false);
			//	$this->db->select('IF( t.ttype IN (' . $pur_ttype . ') and t.tType!="SC" , if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount, 0) as tot_pur_amt', false);
			break;
			case 'stock_ledger':
				$this->db->select('t.id, t.tno, t.tType, t.tDate, t.conName, it.uom, ti.unit,ti.id as itId, 0 as stck', false);
				if(!empty($params['serialIds'])){
					$this->db->select('If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), IF(count(ots.tsItemId) > 1,1,(ti.qty+ti.freeQty)) * -1) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), IF(count(ots.tsItemId) > 1,1,(ti.qty+ti.freeQty)), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, IF(count(ots.tsItemId) > 1,1,(ti.qty+ti.freeQty)))) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
				}else{
					$this->db->select('(ti.qty+ti.freeQty) * If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), 1, -1) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, (ti.qty+ti.freeQty))) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
					if(empty($params['stock_ledger_balance'])){
						$this->db->select('Round(ti.taxableAmount/ti.qty , 2) as rate',false);
					}else{
						$this->db->select('If (t.tDate < "' . $from_date . '" and t.ttype IN ("PI", "PR", "EI", "PE", "PD"), Round((ti.taxableAmount/(ti.qty+ti.freeQty)),2) ,0) as oprate',false);
					}
				
				}
				
				
				if(!empty($params['batchwise_stock'])){
					$this->db->select('iar.itemAttrId,it.itemId,ti.rate,0 as isStock',false);
				}
			break;
			// case 'ledger_balance':
			// 	$this->db->select('ti.itemAttrId, ti.itemId, if(it.name!="",it.name,ti.itemName) as itemName, it.uom AS uom', false);
			// 	$this->db->select('If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), 1, -1) * (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
			// 	$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), 0) - If (t.ttype in (' . $cd_ttype . ') and treftrans.tDate >= "' . $from_date . '",(ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
			// 	$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, (ti.qty+ti.freeQty)) - If (t.ttype in (' . $cd_ttype . ') and treftrans.tDate >= "' . $from_date . '",(ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
			// break;
		}
	}

	public function trans_where($params=array()) {
		//cId validation done in balancesheet.php
		if(isset($params['cId'])) {
			$this->cId = $params['cId'];
		}
		$detail = (!empty($params['inward_details']) || !empty($params['outward_details'])) ? true : false;
		// if(isset($params['batchwise_stock']) && !empty($params['batchwise_stock'])){
		// 	$detail = true;
		// }
		$isReorder = $params['stk_type']=='reorder'?true:false;
		$stktype = !empty($params['expDetail']) ? 'current' : $params['stk_type'];
		switch ($stktype) {
			case 'stock_ledger':
				$ss_tTypes = array(CRNOTE, PURINV, PURRETAIL, EXPINV, EXPRETAIL, PURDBNOTE, PURRECP,SALINV, SALRETAIL, DBNOTE, DELCHALLAN, PURCRNOTE);
				$ss_return = array(CRNOTE, PURDBNOTE,DBNOTE, PURCRNOTE);
				$ss_ref = array(SALINV, SALRETAIL, PURINV, PURRETAIL, EXPINV, EXPRETAIL,CRNOTE, PURDBNOTE,DBNOTE, PURCRNOTE);
			break;
			case 'reorder':
				$ss_ref = $ss_return = $ss_tTypes = array();
				$ss_tTypes = array(SALORD,PURORD);
			break;
			default:
				$ss_tTypes = $this->stock_tTypes;
				$ss_return = array(CRNOTE, DBNOTE, PURCRNOTE, PURDBNOTE);
				$ss_ref = array(SALINV, SALRETAIL, PURINV, PURRETAIL, EXPINV, EXPRETAIL,CRNOTE, PURDBNOTE,DBNOTE, PURCRNOTE);
		}
		
		if ($detail && $params['stk_type'] != 'stock_ledger') {
			if (!empty($params['inward_details'])) {
				$ss_tTypes = array(CRNOTE, PURINV, PURRETAIL, EXPINV, EXPRETAIL, PURDBNOTE, PURRECP);
				$ss_return = array(CRNOTE, PURDBNOTE);
				$ss_ref = array(SALINV, SALRETAIL, PURINV, PURRETAIL, EXPINV, EXPRETAIL,DBNOTE,PURCRNOTE);
			} else {
				$ss_tTypes = array(SALINV, SALRETAIL, DBNOTE, DELCHALLAN, PURCRNOTE);
				$ss_return = array(DBNOTE, PURCRNOTE);
				$ss_ref = array(SALINV, SALRETAIL, PURINV, PURRETAIL, EXPINV, EXPRETAIL,CRNOTE, PURDBNOTE);
			}
		}
		$opening = isset($params['opening']) ? $params['opening'] : 0; // opening balance import
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;

		if (isset($params['attr_ids']) && $params['attr_ids']!=-1) {
			$attr_ids = is_array($params['attr_ids']) ? $params['attr_ids'] : array($params['attr_ids']);
			$this->db->where_in('ti.itemAttrId', $attr_ids);
		}

		// if(!empty($params['serialIds'])){
		// 	$serialIds = is_array($params['serialIds']) ? $params['serialIds'] : array($params['serialIds']);
		// 	$this->db->where_in('ots.asId', $serialIds);
		// }

		if(!empty($params['transitem_id'])){
			$this->db->where('ti.id!=', $params['transitem_id']);
		}
		
		
		$batchwise_stk = (!empty($params['batchwise_stock'])) ? true : false;
		$where = array('t.cId' => $this->cId);
		// $where['it.type'] = 'G';
		$this->db->where_in('it.type',$this->it_type);
		if(!empty($params['contBrch'])) {
			$this->db->group_start();
				$this->db->where(" brchcont.csType  != ","F");
				$this->db->or_where(" brchcont.csType is null");
			$this->db->group_end();
			
			if(!empty($params['taxNo'])) {
				if(isset($params['bgstinId'])) {
					if($params['bgstinId'] == 0) {
						$this->db->group_start();
							$this->db->where("brchcont.taxNo",$params['taxNo']);
							$this->db->or_where("brchcont.taxNo","");
						$this->db->group_end();
					}
					else {
						$this->db->where("brchcont.taxNo",$params['taxNo']);
					}
				}
			}
			
		}
		if (!empty($params['from_date'])) {
			$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
			$to_date = $params['to_date'];
			get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
			if(!empty($params['rpType']) && ($params['rpType'] == 'STE')){
				$start_date = $finish_date = $cur_date = gmdate('Y-m-d');
				get_financial_dates($cur_date,$start_date,$finish_date);
				if($params['expDateFilter'] > $start_date){
					$fin_start_date = $params['from_date'] =$from_date = $start_date;
				}
			} 
			
			$where['t.tDate >='] = (!$detail && !$batchwise_stk)?$fin_start_date:$from_date;
			if (!empty($params['stock_ledger_balance'])) { // get openning
				$where['t.tDate >='] = $fin_start_date;
			}
			$where['t.tDate <='] = $to_date;
		}

		
		if (empty($params['transaction'])) {
			$where['it.isInventory'] = 1;
		}
		if (!empty($params['item_type'])) {
			$where[($params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase?')] = 0;
		}

		if (!empty($params['itemId'])) {
			if (!is_array($params['itemId'])) {
				$where['ti.itemId'] = $params['itemId'];
			} else {
				$this->db->where_in('ti.itemId',$params['itemId']);
			}
		}
		if (!empty($params['transId'])) {
			$where['t.id !='] = $params['transId'];
		}

		if (!empty($params['curStk_tId'])) {
			// used for transaction calculation
			$where['t.id'] = $params['curStk_tId'];
		}
		
		switch ($stktype) {
			
			case 'current':
				// if (!empty($params['catId'])) {
				// 	$this->db->where_in('ic.catId',$params['catId']);
				// }
				// $where['it.isActive'] = 1;
				$this->db->group_by('it.itemId');
				if(!empty($params['rpType']) && $params['rpType'] == 'STE') {
					$this->db->group_by('iar.itemAttrId');
				}
			break;
			case 'alert':
				$where['it.stkLevel >'] = 0;
				$this->db->group_by('it.itemId');
			break;
		
		}
		$this->db->where($where);
		// if(!empty($params['catIds'])){
		// 	$this->db->where('ic.catId IN ('.$params['catIds'] .')');
		// }
		$this->db->where_not_in('t.status', $this->config->item('ignore_status'));
		// branch filter
		$bw_map = $this->get_bw_map($branch, $params);
		if(!empty($params['contBrch'])) {
			 if(!empty($params['locIds'])) {
				$bw_map = array_merge($bw_map,$params['locIds']);
			
			} 
		}
		if ($bw_map) {
			if (empty($params['cal_stkqty'])) {
				$this->db->group_start();
				user_branch_filter('ti.locId', $bw_map, false, true);
				$this->db->group_end();
			}
		}  else if (!empty($params['brachQty'])) {
			$this->db->group_by('ti.locId');
		}
		if (!empty($params['attrValues'])) {
			$this->db->group_by('ti.itemAttrId');	
		}
		// if (sal_mod_active(BRANCH_MOD) && $branch == -1) {
		// 	$this->db->where('t.categoryCode !=','TL'); closing stock issue because of TL (SH,GR) in balancesheet for all branch 
		// }
		$this->db->where_in('t.tType', $ss_tTypes);
		if(!$isReorder) {
			if (sal_mod_active(BRANCH_MOD) && $branch == -1) {
				/*$this->db->group_start();
					$this->db->where('t.categoryCode !=','TL');
				$this->db->group_end();*/
			}
			// reference ignore query
			$this->db->group_start();
			$this->db->where_not_in('t.reftType', $ss_tTypes);

			$this->db->or_group_start();			
			$this->db->where_in('t.tType', $ss_return);
			$this->db->where_in('t.reftType', $ss_ref);
			$this->db->group_end();

			$this->db->or_group_start();			
			// delivery challan refered in goods receipt
			$this->db->where_in('t.tType', array(PURRECP,DELCHALLAN));
			$this->db->group_start();
				$this->db->where_in('t.reftType', array(PURRECP,DELCHALLAN));
			$this->db->group_end();
			$this->db->group_end();
			// if(!($isallbranch)) {
			// 	if (sal_mod_active(BRANCH_MOD) && $branch != -1) {
			// 		$this->db->or_group_start();
			// 		$this->db->where($this->_stock_transfer);
			// 			$this->db->or_group_start();
			// 				$this->db->where($this->__stock_transfer);
			// 			$this->db->group_end();
			// 			$this->db->where($this->___stock_transfer);
			// 		$this->db->group_end();
			// 	} else if (!empty($params['brachQty'])) {
			// 		$this->db->or_group_start();
			// 		$this->db->where('t.categoryCode','TL');
			// 		$this->db->group_end();
			// 	}
			// }
			$this->db->group_end();	
		}

		if ($this->isFranchise && $branch==-1) {
			$this->db->where('t.bId not in (select id from '.$this->db->dbprefix('contacts').' where cId='.$this->cId.' and csType="F")',NULL,FALSE);
		}
	}

	public function stock_select($params=array()) {
		
		$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
		$opening = isset($params['opening']) ? $params['opening'] : 0;
		$to_date = $params['to_date'];
		get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
		$detail = (!empty($params['inward_details']) || !empty($params['outward_details'])) ? true : false;
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;
		$bw_map = $this->get_bw_map($branch, $params);

		$opening_filter = 'se.sDate < "' . $from_date . '"';
		$other_filter = 'se.sDate  >= "' . $from_date . '"';
		// if (strtotime($fin_start_date) <= strtotime($from_date)) {
		// 	$opening_filter = 'se.sDate >= "' . $fin_start_date . '" and se.sType IN ("OP","BF")'; rollbacked this changes
		// 	$other_filter = 'se.sDate >= "' . $fin_start_date . '" and se.sType NOT IN ("OP","BF")';
		// }
		if (strtotime($fin_start_date) == strtotime($from_date)) {
			$opening_filter = 'se.sDate >= "' . $from_date . '" and se.sType IN ("OP","BF")';
			if (!empty($params['isStorage']))
			{
				$opening_filter = '(se.sDate >= "' . $from_date . '" OR YEAR(se.sDate) < ' . date("Y", strtotime($from_date)) . ') and se.sType IN ("OP","BF")';
			}			
			$other_filter = 'se.sDate >= "' . $from_date . '" and se.sType NOT IN ("OP","BF")';
		}
		
		$location = $branch;
		$all_loc = 0;
		if (isset($params['location']))
		{
			// check posted location under our loc map
			if ($params['location']==-1 && $bw_map)
			{
				$all_loc = 1;
				$location = implode(',', $bw_map);
			} else {
				$location = $bw_map && in_array($params['location'], $bw_map)?$params['location']:$branch;	
			}
		}	
		switch ($params['stk_type']) {
			case 'summary':
				if ($detail) {
					$this->db->select('se.id, if(se.stNo!="0",se.stNo,se.id) as tno, se.sType as tType, se.sDate as tDate,  "" as conName, si.unit,si.id as itId,si.rate as trate', false);
					if ((!empty($params['inward_details']) && !empty($params['isInward'])) || (!empty($params['outward_details']) && empty($params['isInward'])))
					{
						$this->db->select('If (' . $other_filter . ',-1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as s_qty', false);
						$this->db->select('If (' . $other_filter . ',-1 ,0) * si.qty * si.rate as s_amount', false);
					} else {
						$this->db->select('If (' . $other_filter . ' AND si.qty>0,1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as s_qty', false);
						$this->db->select('If (' . $other_filter . ' AND si.qty>0,1 ,0) * si.qty * si.rate as s_amount', false);
					}
					$this->db->select('it.uom');
					$this->db->having('s_qty > 0');
					break;
				}
				
				$this->db->select('se.sType as tType');
				$this->db->select((!empty($params['isInward'])?'si.tolocId':'si.fromlocId').' AS locId,si.itemAttrId, it.itemId, it.name AS itemName, it.uom AS uom,it.HS as hsn,it.SKU', false);
				if (!empty($params['isInward']))
				{
					
					$this->db->select('If (' . $opening_filter . ',-1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as opqty', false);
					$this->db->select('If (' . $opening_filter . ',-1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as op_pur_qty', false);
					$this->db->select('If (' . $opening_filter . ',-1 ,0) * si.qty * si.rate as op_pur_amt', false);

					$this->db->select('If (' . $other_filter . ',-1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as iqty', false);
					$this->db->select('If (' . $other_filter . ',-1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as i_pur_qty', false);
					$this->db->select('If (' . $other_filter . ',-1 ,0) * si.qty * si.rate as i_pur_amt', false);

					$this->db->select('0 as oqty', false);
					$this->db->select('0 as o_amt', false);

					$this->db->select('(-1*si.qty * if(itr.convFactor, itr.convFactor, 1)) as tot_pur_qty', false);
					$this->db->select('(-1*si.qty * si.rate) as tot_pur_amt', false);
				} else 
				{
					$this->db->select('If (' . $opening_filter . ',1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as opqty', false);
					$this->db->select('If (' . $opening_filter . '  and si.qty > 0,1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as op_pur_qty', false);
					$this->db->select('If (' . $opening_filter . '  and si.qty > 0,1 ,0) * si.qty * si.rate as op_pur_amt', false);

					$this->db->select('If (' . $other_filter . ' AND si.qty>0,1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as iqty', false);
					$this->db->select('If (' . $other_filter . ' AND si.qty>0,1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as i_pur_qty', false);
					$this->db->select('If (' . $other_filter . ' AND si.qty>0,1 ,0) * si.qty * si.rate as i_pur_amt', false);

					$this->db->select('If (' . $other_filter . ' AND si.qty < 0,-1 ,0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as oqty', false);
					$this->db->select('If (' . $other_filter . 'AND si.qty < 0,-1 ,0) * si.qty * si.rate * if(itr.convFactor, itr.convFactor, 1) as o_amt', false);


					$this->db->select('if(si.qty>0, 1, 0) * si.qty *if(itr.convFactor, itr.convFactor, 1) as tot_pur_qty', false);
					$this->db->select('if(si.qty>0, 1, 0) * si.qty * si.rate as tot_pur_amt', false);
				}

				

				$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');
			
				if ($opening) {
					$this->db->select('iar.mrp', false);
				}
				break;
			case 'alert':
			case 'current':
				$this->db->select('si.itemAttrId, IF(iar.saleRate IS NULL OR iar.saleRate = 0, it.saleRate, iar.saleRate) AS saleRate, IF(iar.mrp IS NULL OR iar.mrp = 0, it.mrp, iar.mrp) AS mrp, it.stkLevel', false);
				// $this->db->select('(si.rate*si.qty) AS pi_rate', false);
				// $tl = !empty($params['includeTL'])?-1:1;

				$this->db->select('it.uom', false);
				if (!empty($params['isInward']))
				{
					$this->db->select('COALESCE(GROUP_CONCAT(IF(si.qty > 0, si.rate*si.qty, NULL) ORDER BY si.id DESC)) AS pi_rate', false);
					$this->db->select('sum(IF(si.qty > 0, si.qty,  0) * if(itr.convFactor, itr.convFactor, 1)) as s_qty');
					$this->db->select('sum(IF(si.qty < 0, si.qty * -1, 0) * if(itr.convFactor, itr.convFactor, 1)) as p_qty', false);
				}
				else
				{
					$this->db->select('COALESCE(GROUP_CONCAT(IF(si.qty > 0, si.rate*si.qty, NULL) ORDER BY si.id DESC)) AS pi_rate', false);
					$this->db->select('sum(si.qty * IF(si.qty < 0, -1, 0) * if(itr.convFactor, itr.convFactor, 1)) as s_qty', false);
					$this->db->select('sum(IF(si.qty > 0, si.qty,  0) * if(itr.convFactor, itr.convFactor, 1)) as p_qty', false);
				}
				$this->db->select('null as pur_qty',false);
				if (!empty($params['brachQty'])) {
					if (isset($params['branch'])) {
						$this->db->select('it.itemId,if(se.sType="TL" && si.tolocId in (' . $location . '),si.tolocId,si.fromlocId) as locId',false);
					} else {
						$this->db->select('it.itemId,se.locId',false);
					}
				} else {
					$this->db->select('it.itemId,it.name AS itemName,it.SKU', false);
					if(!empty($params['attrValues']) && empty($params['transaction'])) {
						$this->db->select('Replace(iar.sku,"#TID","") as batch', false);
					}
				}

				// include category name
				if (!empty($params['catColumn'])) {
					// $this->db->select('group_concat(distinct c.name) as catName');
					$this->db->select('ic.name as catName');
				}
				if(!empty($params['batchwise_stock'])){
					$this->db->select(',0 as rate',false);
				}
			break; 
			case 'stock_value':
				if(!empty($params['isInward'])) {
					$this->db->select('si.itemAttrId,si.itemId as itemId, (si.qty*-1* if(itr.convFactor, itr.convFactor, 1)) as stk_qty', false);
					// $this->db->select('(IF(si.qty > 0, si.qty, if(se.sType="TL" and si.tolocId='.$branch.', -1 * si.qty, 0)) * if(itr.convFactor, itr.convFactor, 1)) as pur_qty', false);
					// $this->db->select('IF(si.qty > 0, si.qty, , if(se.sType="TL" and si.tolocId='.$branch.', -1 * si.qty, 0)) * si.rate as pur_amt', false);
				//	$this->db->select('If (' . $opening_filter . ',1 ,0) *-1* si.qty * if(itr.convFactor, itr.convFactor, 1) as pur_qty', false);
				//	$this->db->select('If (' . $opening_filter . ',1 ,0) *-1*si.qty * if(itr.convFactor, itr.convFactor, 1) as pur_amt', false);

					$this->db->select('si.qty*-1*if(itr.convFactor, itr.convFactor, 1) as pur_qty', false);
					$this->db->select('(si.qty*-1*si.rate) as pur_amt', false);
					$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');	
					$this->db->select("si.toLocId as locId");
				} else {
					$this->db->select('si.itemAttrId,si.itemId as itemId,si.qty * if(itr.convFactor, itr.convFactor, 1) as stk_qty', false);
					// $this->db->select('(IF(si.qty > 0, si.qty, if(se.sType="TL" and si.tolocId='.$branch.', -1 * si.qty, 0)) * if(itr.convFactor, itr.convFactor, 1)) as pur_qty', false);
					// $this->db->select('IF(si.qty > 0, si.qty, , if(se.sType="TL" and si.tolocId='.$branch.', -1 * si.qty, 0)) * si.rate as pur_amt', false);
					$this->db->select('If (si.qty > 0, 1, 0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as pur_qty', false);
					$this->db->select('If (si.qty > 0, 1, 0) * si.qty * si.rate as pur_amt', false);
				//	$this->db->select('If (' . $opening_filter . ' and si.qty > 0 ,1 ,0)*si.qty * if(itr.convFactor, itr.convFactor, 1) as pur_qty', false);
				///	$this->db->select('If (' . $opening_filter . ' and si.qty > 0 ,1 ,0)*si.qty * if(itr.convFactor, itr.convFactor, 1) as pur_amt', false);
					$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');	
					$this->db->select("si.fromLocId as locId");
				}
				if (!empty($params['isInward']))
				{
					//$this->db->select('(-1*si.qty * if(itr.convFactor, itr.convFactor, 1)) as tot_pur_qty', false);
					//$this->db->select('(-1*si.qty * si.rate) as tot_pur_amt', false);
				}
				else {
					//$this->db->select('If (si.qty > 0, 1, 0) * si.qty * if(itr.convFactor, itr.convFactor, 1) as tot_pur_qty', false);
					//$this->db->select('If (si.qty > 0, 1, 0) * si.qty * si.rate as tot_pur_amt', false);
				}
			break;
			case 'stock_ledger':
				$this->db->select('se.id, if(se.stNo!="0",se.stNo,se.id) as tno, se.sType as tType, se.sDate as tDate,  if(se.sType = "TL",si.toLocId,"") as conName,it.uom, si.unit,si.id as itId, 1 as stck', false);
				if(!empty($params['serialIds'])){
					$this->db->select('If (' . $opening_filter . ',IF(se.sType="TL" and si.tolocId in (' . $location . '), IF(count(ots.tsItemId) >1 ,1, si.qty) * -1, IF(count(ots.tsItemId) >1 ,1, si.qty)) * if(itr.convFactor, itr.convFactor, 1) , 0) as opqty', false);
					$this->db->select('If (' . $other_filter . ',IF(si.qty > 0 , IF(count(ots.tsItemId) >1 ,1, si.qty) ,if(se.sType="TL" and si.tolocId in (' . $location . '), -1 *  IF(count(ots.tsItemId) >1 ,1, si.qty) ,0)) * if(itr.convFactor, itr.convFactor, 1) , 0) as iqty', false);
					$this->db->select('If (' . $other_filter . ',IF(si.qty < 0 , IF(count(ots.tsItemId) >1 ,1, si.qty) * if(se.sType="TL",if(si.fromlocId in (' . $location . '),-1,0),-1), 0),0) * if(itr.convFactor, itr.convFactor, 1) as oqty', false);
				}else{
					$this->db->select('If (' . $opening_filter . ',IF(se.sType="TL" and si.tolocId in (' . $location . '), si.qty * -1, si.qty) * if(itr.convFactor, itr.convFactor, 1) , 0) as opqty', false);
					$this->db->select('If (' . $other_filter . ',IF(si.qty > 0 , si.qty ,if(se.sType="TL" and si.tolocId in (' . $location . '), -1 *  si.qty ,0)) * if(itr.convFactor, itr.convFactor, 1) , 0) as iqty', false);
					$this->db->select('If (' . $other_filter . ',IF(si.qty < 0 , si.qty * if(se.sType="TL",if(si.fromlocId in (' . $location . '),-1,0),-1), 0),0) * if(itr.convFactor, itr.convFactor, 1) as oqty', false);
					if(empty($params['stock_ledger_balance'])){
						$this->db->select('si.rate as rate',false);
					}else{
						$this->db->select('If (si.qty > 0, Round(si.rate,2) ,0) as oprate',false);
					}
					
				}

				if(!empty($params['batchwise_stock'])){
					$this->db->select('iar.itemAttrId,it.itemId,0 as rate,1 as isStock',false);
				}
			break;
		}
	}

	public function stock_where($params=array()) {
		//cId validation done in balancesheet.php
		if(isset($params['cId'])) {
			$this->cId = $params['cId'];
		}
		$detail = (!empty($params['inward_details']) || !empty($params['outward_details'])) ? true : false;
		// if(isset($params['batchwise_stock']) && !empty($params['batchwise_stock'])){
		// 	$detail = true;
		// }

		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;
		$serialIds = array();
				
		if (isset($params['attr_ids'])) {
			$attr_ids = is_array($params['attr_ids']) ? $params['attr_ids'] : array($params['attr_ids']);
			$this->db->where_in('si.itemAttrId', $attr_ids);
		}
		
		$where = array('se.cId' => $this->cId);
		if(!empty($params['contBrch'])) {
			$this->db->group_start();
				$this->db->where(" brchcont.csType  != ","F");
				$this->db->or_where(" brchcont.csType is null");
			$this->db->group_end();
		}
		$batchwise_stk = (!empty($params['batchwise_stock'])) ? true : false;

		if (!empty($params['from_date'])) {
			$cur_date = gmdate('Y-m-d');
			$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
			$to_date = $params['to_date'];
			get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
			if(!empty($params['rpType']) && ($params['rpType'] == 'STE')){
				$start_date = $finish_date = $cur_date = gmdate('Y-m-d');
				get_financial_dates($cur_date,$start_date,$finish_date);
				if($params['expDateFilter'] > $start_date){
					$fin_start_date = $params['from_date'] =$from_date = $start_date;
				}
			} 
			$where['se.sDate >='] = (!$detail && !$batchwise_stk)?$fin_start_date:$from_date;

			if (!empty($params['stock_ledger_balance'])) { // get openning
				$where['se.sDate >='] = $fin_start_date;
			}
			$where['se.sDate <='] = $to_date;

			if ($fin_end_date < $to_date)
			{
				// date filter with different finance year ignore BF
				$where['se.sType !='] = "BF";
			}
		}

		if (!empty($params['curStk_sId'])) {
			// used for transaction calculation
			$where['se.id'] = $params['curStk_sId'];
		}

		$this->db->where_in('it.type',$this->it_type);
		if (!empty($params['itemId'])) {
			if (!is_array($params['itemId'])) {
				$where['si.itemId'] = $params['itemId'];
			} else {
				$this->db->where_in('si.itemId',$params['itemId']);
			}
		}
		if (!empty($params['sId'])) {
			$where['se.id !='] = $params['sId'];
		}
		if (empty($params['transaction'])) { // in closing stock add  only if isInventory
			$where['it.isInventory'] = 1;
		}

		$this->db->where($where);
		// if(!empty($params['catIds'])){
		// 	$this->db->where_in('ic.catId', $params['catIds']);
		// }
		if (!empty($params['item_type'])) {
			$this->db->where($params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase >', 0);
		}
		// if ($cur_date != $fin_start_date) {
		$bw_map = $this->get_bw_map($branch, $params);
		if(!empty($params['contBrch'])) {
			if(!empty($params['locIds'])) {
			   $bw_map = array_merge($bw_map,$params['locIds']);
		   
		   } 
	   }
		if (!empty($params['isInward']))
		{
			$this->db->where('se.sType', 'TL');
		}
		
		if ($bw_map) {
			if (empty($params['locReq']) && $branch!=-1 && !empty($params['location']) && $params['location'] == -1)
			{
				// stock transfer duplicate display in all location filter
				if (empty($params['isInward']))
				{
					/* ignore if stock transfer between same location*/
					$this->db->group_start();
					$this->db->where('se.sType !=', 'TL');
					$this->db->or_where_not_in('si.tolocId', $bw_map);
					$this->db->group_end();
				} else {
					$this->db->where_not_in('si.fromlocId', $bw_map);
				}
			}

			$this->db->where_in(!empty($params['isInward'])?'si.tolocId':'si.fromlocId', $bw_map);
		}		
		
		$stk_type = !empty($params['expDetail']) ? 'current' : $params['stk_type'];
		switch ($stk_type) {
			case 'current':
				// include category name
				// if (!empty($params['catId'])) {
				// 	$this->db->where_in('ic.catId',$params['catId']);
				// }
				if (!empty($params['brachQty'])) {
					// $this->db->group_by(!empty($params['includeTL'])?'si.tolocId':'se.locId');
					$this->db->group_by('locId');
				}
				$this->db->group_by('it.itemId');
				if(!empty($params['rpType']) && $params['rpType'] == 'STE'){
					$this->db->group_by('iar.itemAttrId');
				}
				if (!empty($params['attrValues'])) {
					$this->db->group_by('itemAttrId');	
				}
			break;
			case 'alert':
				$this->db->group_by('it.itemId');
			break;
		}

		if ($this->isFranchise && $branch==-1) {
			$this->db->where('se.locId not in (select id from '.$this->db->dbprefix('contacts').' where cId='.$this->cId.' and csType="F")',NULL,FALSE);
		}
	}

	public function getExpAttrIds($params){
		$params['expDetail'] = true;
		$this->db->select('IFNULL(GROUP_CONCAT(ti.itemAttrId),"") as itemAttrId');
		$this->from($params,false,true);
		$this->trans_where($params);
		$this->expiry_filter(false,$params);
		$trans_query = $this->db->get_compiled_select();
		$this->db->select('IFNULL(GROUP_CONCAT(si.itemAttrId),"") as itemAttrId');
		$this->from($params,true);
		$this->stock_where($params);
		$this->expiry_filter(true,$params);
		$stock_query = $this->db->get_compiled_select();
		$stock_query_tl = '';
		// if (!empty($params['brachQty'])) { // union location transfer too
		// 	$params['includeTL'] = true;
		// 	$this->stock_select($params);
		// 	$this->from($params,true);
		// 	$this->stock_where($params);
		// 	$this->expiry_filter(true,$params);
		// 	$stock_query_tl = $this->db->get_compiled_select();
			
		// }
		$union = "$trans_query UNION ALL $stock_query ".($stock_query_tl?" UNION ALL $stock_query_tl ":'');
		$union = "SELECT IFNULL(GROUP_CONCAT(itemAttrId),'') as itemAttrId from (".$union.") uniontable ";
		$attrids = array();
		$query = $this->db->query($union);
		$tmp = $query->row_array();
		if($tmp){
			$itmattrids = trim($tmp['itemAttrId'],',');
			if($itmattrids != ''){
				$attrids = explode(',', $itmattrids);
				$attrids = array_unique($attrids);
			}
		}
		$params['expDetail'] = false;
		return $attrids;
	}

	public function fifo_query($params) {
		if(!empty($params['catId']) && is_array($params['catId'])){
			$params['catId'] = $this->get_child_category($params['catId']);
		}
		// stock_tTypes - in reportmodel
		$page_limit = $this->config->item('page_limit');
		$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
		$to_date 		= $params['to_date'];
		$contBrch = false;
		$config = get_company('config');
		$HasFranchise = !empty($config['isFranchise']) ? $config['isFranchise'] : 0;
		$branch = $this->bId;
		if ((isset($params['branch']))) {
			$branch = $params['branch'];
			if($HasFranchise) {
				if(sal_mod_active(BRANCH_MOD) && $params['branch'] == -1) {
					$contBrch = true;
				}
			}
		}

		get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
		$params['page'] = !empty($params['page'])?$params['page']:0;
		$isPurRate		= !empty($params['purRateType'])?$params['purRateType']:false;
		$is_aging		= !empty($params['aging'])?$params['aging']:false;

		$opening = isset($params['opening']) ? $params['opening'] : 0;
		
		$from = ($params['page'] - 1) * $page_limit;
		$inw_qty = '"'.PURINV.'","'.PURRETAIL.'","'.EXPINV.'","'.EXPRETAIL.'", "'.PURDBNOTE.'", "'.PURRECP.'", "'.CRNOTE.'"';
		$sq_stk_loc_where = '';
		$stk_loc_where = ' AND se.sType!="TL"';
		$bw_map = !$opening?$this->get_bw_map($branch, $params):array($branch); // for opening balance import we need to consider current branch only
		
		if(empty($params['itemId']) && !empty($params['itemName'])){
			$this->load->model("itemsModel");
			$params['itemId'] = $this->itemsModel->get_itemids($params['itemName']);
		}
		if ($bw_map) {	
			// $stk_loc_where = ' AND (si.qty <> 0 OR (se.sType="TL" and (si.fromlocId IN ('.implode('","',$bw_map).') OR si.tolocId IN ('.implode('","',$bw_map).'))))';
			$stk_loc_where = ' AND (si.fromlocId IN("'.implode('","',$bw_map).'") OR (se.sType = "TL" AND si.tolocId IN("'.implode('","',$bw_map).'")))';
			$sq_stk_loc_where = ' AND (sq_si.fromlocId IN("'.implode('","',$bw_map).'") OR (sq_se.sType = "TL" AND sq_si.tolocId IN("'.implode('","',$bw_map).'")))';
		}

		$params['itemId'] = !empty($params['itemId'])?$params['itemId']:array();
		$params['itemId'] = !is_array($params['itemId'])?array($params['itemId']):$params['itemId'];
		
		$items_query = '';
		// agging items query
		if ($is_aging)
		{
			if ($branch && $branch!=get_company('mainbId')) {
				$ag_query = 'JOIN '.$this->db->dbprefix("items_cur").' as sq_itc ON sq_itc.itemId=sq_it.itemId and sq_itc.bId='.$branch.' AND sq_itc.curstk>0 WHERE ';
			} else {
				$ag_query = ' WHERE sq_it.curStk>0 AND ';
			}
		}

		if (empty($params['inv_profit']) && empty($params['is_total']) && empty($params['itemId']) && empty($params['catId']) ) {
			$items_query = 'select sq_it.itemId,sq_it.name from '.$this->db->dbprefix("items").' sq_it JOIN
			( 
			select DISTINCT sq_ti.itemId from
			'.$this->db->dbprefix("trans_items").' sq_ti 
			join '.$this->db->dbprefix("trans").' sq_t on sq_t.id=sq_ti.transId
			WHERE sq_t.cId = "'.$this->cId.'"'
			.(($bw_map)? ' AND sq_ti.locId IN ("'.implode('","',$bw_map).'")':'') .' 
			AND sq_t.tDate >= "'.$fin_start_date.'"
			AND sq_t.tDate <= "'.$to_date.'"'
			.' AND sq_t.status NOT IN("'.implode('","',$this->config->item('ignore_status')).'")
			AND sq_t.tType IN("'.implode('","',$this->stock_tTypes).'")
			AND   (
				sq_t.reftType NOT IN("'.implode('","',$this->stock_tTypes).'")
			OR  /* Credit/Debit Note */  (
				sq_t.tType IN("SC", "SD", "PC", "PD")
			AND sq_t.reftType IN("SI", "SR", "PI", "PR", "EI", "PE","SC", "SD", "PC", "PD")
			)
			OR    /* Goods Return */ (
			sq_t.tType IN("GR","SH")
			AND sq_t.reftType IN("GR","SH")
			)
			)
			UNION
			select sq_si.itemId from
			'.$this->db->dbprefix("stock_items").' sq_si 
			join '.$this->db->dbprefix("stock_entries").' sq_se on sq_se.id=sq_si.sId
			WHERE sq_se.cId = "'.$this->cId.'"
			AND sq_se.sDate >= "'.$fin_start_date.'"
			AND sq_se.sDate <= "'.$to_date.'"'
			.$sq_stk_loc_where
			.') sq_exis on sq_exis.itemId=sq_it.itemId '
			.($is_aging?$ag_query:' where ')
			.' sq_it.cId='.$this->cId.' and 
			sq_it.isinventory=1	  
			 order by sq_it.name ';			
			if(empty($params['f_type']) && !$opening)
				$items_query .=  ($from?('limit '.$from . ',' . $page_limit):'limit '. $page_limit);
			// $tmp = $this->db->query($items_query)->result_array();

			// if (!$tmp) {
			// 	return;
			// }
			// // $params['page']++;
			// foreach ($tmp as $row) {
			// 	$params['itemId'][] = $row['itemId'];
			// }
		}

		$partition = "locId,itemId";
		// if(isset($params['branch']) && $params['branch'] == -1)
		// 	$partition = "locId,itemId";
		// else 
		// 	$partition = "itemId";

		// $partition.=(!empty($params['show_attrs'])? ' ,itemAttrId':'');
		$partition.= (sal_mod_active(CATE_ATTR))?' ,itemAttrId':'';//bydefault itemattr group by when attr used
		/* inValue - Take goods only*/
		$sAll = 'SELECT t.id as tId, ti.id as tiId,t.tDate,t.tType,ti.locId,t.bid as bid, ti.itemAttrId, ti.itemId, it.name as itemName, it.uom AS uom, it.HS as hsn,it.SKU, ti.unit,
		-- IF(t.tType IN ('.$inw_qty.'),ti.qty+ti.freeQty,0) * if(itr.convFactor, itr.convFactor, 1) AS inQty, 
		IF(t.tType IN ('.$inw_qty.'),if(t.ttype="GR" and tpi.id is NOT NULL, (tpi.qty+tpi.freeQty) * if(itrr.convFactor, itrr.convFactor, 1), (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1)),0) AS inQty, 
		IF(t.tType IN ('.$inw_qty.')  and (/* Ignore GR refer DC from contact */ t.tType !="GR" OR (t.categoryCode="TL" or (t.reftType!="DC"))),if(t.ttype="GR" and tpi.id is NOT NULL, (tpi.qty+tpi.freeQty) * if(itrr.convFactor, itrr.convFactor, 1), (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1)),0) AS inValQty, 
		IF(t.tType IN ('.$inw_qty.'), 0, ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) AS outQty, 
		IF(t.tType IN ('.$inw_qty.')   and (/* Ignore GR refer DC from contact */ t.tType !="GR" OR (t.categoryCode="TL" or (t.reftType!="DC"))),if(t.ttype="GR" and tpi.id is NOT NULL,IF(tpi.itc=1, tpi.taxableAmount, tpi.itemTotal) + tpi.chargesAmount,/*use cost price if exists*/if(tirel.cPrice, tirel.cPrice * (ti.qty+ti.freeQty), IF(ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount)),0) as inValue,
		IF(t.tType IN ('.$inw_qty.') ,0,if(it.type = "G",(IF(ti.itc=1, ti.taxableAmount, ti.itemTotal)),0)) as outValue
		FROM '.$this->db->dbprefix("trans").' AS t
		JOIN '.$this->db->dbprefix("trans_items").' AS ti ON ti.transId=t.id
		JOIN '.$this->db->dbprefix("items").' AS it ON it.itemId=ti.itemId '
		.($contBrch ?' LEFT JOIN '.$this->db->dbprefix("contacts").' As brchcont on brchcont.id = t.bId ' : '')
		
		.($items_query?' JOIN ('.$items_query.') as sq ON sq.itemId=it.itemId ' : '')
		.'LEFT JOIN '.$this->db->dbprefix("item_attr").' AS iar ON iar.itemAttrId=ti.itemAttrId and iar.itemId=ti.itemId
		LEFT JOIN '.$this->db->dbprefix("itemrelunits").' AS itr ON itr.itemId=ti.itemId and itr.relUnitName=ti.unit
		LEFT JOIN '.$this->db->dbprefix("trans_items_rel").' AS tirel ON tirel.transItemId=ti.id and t.tType IN ("SC","GR")
		LEFT JOIN /*For GR use Pur If avail */(ob_trans_ref AS tref
		 JOIN ob_trans tp on tp.id=tref.transId and  tp.tType IN ("PI","PR","EI","PE","PD") 
		 JOIN ob_trans_items as tpi on tpi.transid=tp.id
		 LEFT JOIN ob_itemrelunits AS itrr ON itrr.itemId=tpi.itemId and itrr.relUnitName=tpi.unit)  ON tref.refTransId=t.id  and t.tType IN ("GR")  and t.categoryCode !="TL" and tpi.refTitemId=ti.id'
		.((!empty($params['catId'])) ? ' JOIN (select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catId'].')) sq_exis ON sq_exis.itemId = it.itemId':'')
		.' WHERE t.cId = "'.$this->cId.'"'
		.(($bw_map)? ' AND ti.locId IN ("'.implode('","',$bw_map).'")':'') .' 
		AND it.isInventory = 1'
		.($contBrch ?' AND ( brchcont.csType != "F" OR brchcont.csType is null ) ' : '')
		.(!empty($params['taxNo']) && (isset($params['bgstinId']) && $params['bgstinId']) != 0 ?' AND brchcont.taxNo = "'.$params['taxNo'].'"' : '')
		.(!empty($params['taxNo']) && (isset($params['bgstinId']) && $params['bgstinId']) == 0 ?' AND (brchcont.taxNo = "'.$params['taxNo'].'" or brchcont.taxNo = "")' : '')
		// items, category amd  attributes filters
		
		. (!empty($params['itemId'])?' AND ti.itemId IN ('.implode(',',$params['itemId']).')':'')
		. (!empty($params['itemAttrId'])?' AND ti.itemAttrId IN ('.implode(',',$params['itemAttrId']).')':'')

		.' AND t.tDate >= "'.$fin_start_date.'" AND t.tDate <= "'.$to_date.'"'
		.'AND t.status NOT IN("'.implode('","',$this->config->item('ignore_status')).'")
		AND t.tType IN("'.implode('","',$this->stock_tTypes).'")
		AND   (
		t.reftType NOT IN("'.implode('","',$this->stock_tTypes).'")
		OR    (
		t.tType IN("SC", "SD", "PC", "PD")
		AND t.reftType IN("SI", "SR", "PI", "PR", "EI", "PE","SC", "SD", "PC", "PD")
		  )
		OR    (
		t.tType IN("GR","SH")
		AND t.reftType IN("GR","SH")
		  )
		 ) 

		UNION ALL 

		SELECT se.id, si.id as tiId, se.sDate  as tDate,se.sType as tType,si.fromlocId as locId, se.locid as bid,si.itemAttrId, it.itemId, it.name AS itemName, it.uom AS uom, it.HS as hsn,it.SKU, si.unit,
		IF(si.qty > 0, si.qty,  0) * if(itr.convFactor, itr.convFactor, 1) as inQty, 
		IF(si.qty > 0, si.qty,  0) * if(itr.convFactor, itr.convFactor, 1) as inValQty, 
		IF(si.qty < 0, si.qty * -1, 0) * if(itr.convFactor, itr.convFactor, 1) as outQty, 
		IF(si.qty > 0 , si.qty, 0) * si.rate  as inValue,
		IF(si.qty < 0 , si.qty * -1, 0) * si.rate  as outValue
		FROM '.$this->db->dbprefix("stock_entries").' AS se
		JOIN '.$this->db->dbprefix("stock_items").' AS si ON si.sId=se.id
		JOIN '.$this->db->dbprefix("items").'  AS it ON it.itemId=si.itemId '
		.($contBrch ?' LEFT JOIN '.$this->db->dbprefix("contacts").' As brchcont on brchcont.id = si.fromLocId ' : '')
		.($items_query?' JOIN ('.$items_query.') as sq ON sq.itemId=it.itemId ' : '')
		.'LEFT JOIN '.$this->db->dbprefix("itemrelunits").' AS itr ON itr.itemId=si.itemId and itr.relUnitName=si.unit
		LEFT JOIN '.$this->db->dbprefix("item_attr").' AS iar ON iar.itemAttrId=si.itemAttrId and iar.itemId=si.itemId'
		.((!empty($params['catId'])) ? ' JOIN (select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catId'].')) sq_exis ON sq_exis.itemId = si.itemId':'')
		.' WHERE se.cId = "'.$this->cId.'"
		AND it.isInventory = 1'
		.($contBrch ?' AND (brchcont.csType != "F" OR brchcont.csType is null) ' : '')
		.(!empty($params['taxNo']) && (isset($params['bgstinId']) && $params['bgstinId']) != 0 ?' AND brchcont.taxNo = "'.$params['taxNo'].'"' : '')
		.(!empty($params['taxNo']) && (isset($params['bgstinId']) && $params['bgstinId']) == 0 ?' AND (brchcont.taxNo = "'.$params['taxNo'].'" or brchcont.taxNo = "")' : '')
		.(!empty($params['mfgId'])? (' AND se.id !='.$params['mfgId']) : '')
		// items, category amd  attributes filters
		.(!empty($params['itemId'])?' AND si.itemId IN ('.implode(',',$params['itemId']).')':'')
		.(!empty($params['itemAttrId'])?' AND si.itemAttrId IN ('.implode(',',$params['itemAttrId']).')':'')
		.' AND se.sDate >= "'.$fin_start_date.'" AND se.sDate <= "'.$to_date.'"'
		. ($bw_map?' AND si.fromlocId IN("'.implode('","',$bw_map).'")':'')
		// added for stock aging report
		.($is_aging?' AND (se.sType!="BF" or (se.sType="BF" and se.sDate = "'.$from_date.'"))':'');

		$sAll.=' UNION ALL 

		SELECT se.id, si.id as tiId, se.sDate  as tDate,se.sType as tType,si.tolocId as locId, se.locid as bid,si.itemAttrId, it.itemId, it.name AS itemName, it.uom AS uom, it.HS as hsn,it.SKU, si.unit,
		si.qty * -1 * if(itr.convFactor, itr.convFactor, 1) as inQty, 
		si.qty * -1 * if(itr.convFactor, itr.convFactor, 1)  as inValQty, 
		0 as outQty, 
		if(it.type = "G",(-1 * si.qty * si.rate),0)  as inValue,
		0  as outValue
		FROM '.$this->db->dbprefix("stock_entries").' AS se
		JOIN '.$this->db->dbprefix("stock_items").' AS si ON si.sId=se.id
		JOIN '.$this->db->dbprefix("items").'  AS it ON it.itemId=si.itemId '
		.($contBrch ?' LEFT JOIN '.$this->db->dbprefix("contacts").' As brchcont on brchcont.id = si.fromLocId ' : '')
		.($items_query?' JOIN ('.$items_query.') as sq ON sq.itemId=it.itemId ' : '')
		.'LEFT JOIN '.$this->db->dbprefix("itemrelunits").' AS itr ON itr.itemId=si.itemId and itr.relUnitName=si.unit
		LEFT JOIN '.$this->db->dbprefix("item_attr").' AS iar ON iar.itemAttrId=si.itemAttrId and iar.itemId=si.itemId'
		.((!empty($params['catId'])) ? ' JOIN (select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catId'].')) sq_exis ON sq_exis.itemId = si.itemId':'')
		.' WHERE se.cId = "'.$this->cId.'"
		AND it.isInventory = 1'
		.($contBrch ?' AND (brchcont.csType != "F" OR brchcont.csType is null) ' : '')
		.(!empty($params['taxNo']) && (isset($params['bgstinId']) && $params['bgstinId']) != 0 ?' AND brchcont.taxNo = "'.$params['taxNo'].'"' : '')
		.(!empty($params['taxNo']) && (isset($params['bgstinId']) && $params['bgstinId']) == 0 ?' AND (brchcont.taxNo = "'.$params['taxNo'].'" or brchcont.taxNo = "")' : '')
		.(!empty($params['mfgId'])? (' AND se.id !='.$params['mfgId']) : '')
		// items, category amd  attributes filters
		.(!empty($params['itemId'])?' AND si.itemId IN ('.implode(',',$params['itemId']).')':'')
		.(!empty($params['itemAttrId'])?' AND si.itemAttrId IN ('.implode(',',$params['itemAttrId']).')':'')
		.' AND se.sDate >= "'.$fin_start_date.'" AND se.sDate <= "'.$to_date.'"'
		. ($bw_map?' AND se.sType="TL" and si.tolocId IN("'.implode('","',$bw_map).'")':' AND se.sType="TL"')
		// added for stock aging report
		.($is_aging?' AND (se.sType!="BF" or (se.sType="BF" and se.sDate = "'.$from_date.'"))':'');

		if (!$is_aging)
		{
			$sAll='select *, 
			if(inQty > 0,SUM(inQty) OVER (PARTITION BY '.$partition.' ORDER BY tDate, tid, tiId),0)  as  incrQty,
			if(inQty > 0 and inValQty=0,Avg(NULLIF(inValue/inValQty,0)) OVER (PARTITION BY locId,itemId ,itemAttrId ORDER BY tDate, tid, tiId),0)  as  avgRate
			from ('.$sAll.') uniontable';
		}
		

		$sOut = 'select locId,itemId,itemAttrId,greatest(sum(qty),0) as spent ';
		if ($isPurRate) {// for manufacture journal
			$sOut.= ', greatest(sum(qty+newqty),0) as newSpent from (SELECT ti.locId,t.bid,ti.itemAttrId,';
		} else { //default
			$sOut.=', greatest(sum(If(tDate < "'.$from_date.'", qty,0)),0) as opSpent from (SELECT t.tType,ti.locId,t.bid, ti.itemAttrId, ti.unit,';
		}
		
		$sOut.= 'ti.itemId,t.tdate,(ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) * if (t.ttype="SC",-1,1) as  qty,0 as newqty
		FROM '.$this->db->dbprefix("trans").' AS t
		JOIN '.$this->db->dbprefix("trans_items").' AS ti ON ti.transId=t.id
		JOIN '.$this->db->dbprefix("items").' AS it ON it.itemId=ti.itemId '
		.($items_query?' JOIN ('.$items_query.') as sq ON sq.itemId=it.itemId ' : '')
		.'LEFT JOIN '.$this->db->dbprefix("itemrelunits").' AS itr ON itr.itemId=ti.itemId and itr.relUnitName=ti.unit'
		.((!empty($params['catId'])) ? ' JOIN (select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catId'].')) sq_exis ON sq_exis.itemId = it.itemId':'')
		.' WHERE t.cId = "'.$this->cId.'"'
		.(($bw_map)?' AND ti.locId IN ("'.implode('","',$bw_map).'")':'').' 
		AND it.isInventory = 1'
		// items, category amd  attributes filters
		. (!empty($params['itemId'])?' AND ti.itemId IN ('.implode(',',$params['itemId']).')':'')
		. (!empty($params['itemAttrId'])?' AND ti.itemAttrId IN ('.implode(',',$params['itemAttrId']).')':'')
		.' AND t.tDate >= "'.$fin_start_date.'" AND t.tDate <= "'.$to_date.'"'
		.'AND t.status NOT IN("'.implode('","',$this->config->item('ignore_status')).'")
		AND t.tType IN("SI", "SR", "SH",  "SD","PC")
		AND   (
			t.reftType NOT IN("'.implode('","',$this->stock_tTypes).'")
			OR    (
			t.tType IN("SC", "PC")
			AND t.reftType IN("SI", "SR", "PI", "PR", "EI", "PE", "SD", "PD")
		  	)
		  	OR (t.tType ="SH" and t.reftType = "GR")
		 )
		 UNION ALL SELECT ';
		if (!$isPurRate) {
			$sOut.= 'se.sType as tType,si.fromlocId as locId,se.locId as bid,si.itemAttrId, si.unit,';
		}	
		else {
			$sOut.= 'si.fromlocId as locId,se.locId as bid,si.itemAttrId,';
		}
		$sOut.= 'it.itemId,se.sDate as tDate,si.qty * -1 * if(itr.convFactor, itr.convFactor, 1) as qty,0 as newqty
		FROM '.$this->db->dbprefix("stock_entries").' AS se
		JOIN '.$this->db->dbprefix("stock_items").' AS si ON si.sId=se.id
		JOIN '.$this->db->dbprefix("items").' AS it ON it.itemId=si.itemId '
		.($items_query?' JOIN ('.$items_query.') as sq ON sq.itemId=it.itemId ' : '')
		.($contBrch ?' LEFT JOIN '.$this->db->dbprefix("contacts").' As brchcont on brchcont.id = si.fromLocId ' : '')
		.'LEFT JOIN '.$this->db->dbprefix("itemrelunits").' AS itr ON itr.itemId=si.itemId and itr.relUnitName=si.unit
		LEFT JOIN '.$this->db->dbprefix("item_attr").' AS iar ON iar.itemAttrId=si.itemAttrId and iar.itemId=si.itemId'
		.((!empty($params['catId'])) ? ' JOIN (select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catId'].')) sq_exis ON sq_exis.itemId = si.itemId':'')
		.' WHERE se.cId = "'.$this->cId.'"
		AND it.isInventory = 1'
		.(!empty($params['mfgId'])? (' AND se.id !='.$params['mfgId']) : '')
		// items, category amd  attributes filters
		. (!empty($params['itemId'])?' AND si.itemId IN ('.implode(',',$params['itemId']).')':'')
		. (!empty($params['itemAttrId'])?' AND si.itemAttrId IN ('.implode(',',$params['itemAttrId']).')':'')
		.' AND se.sDate >= "'.$fin_start_date.'" AND se.sDate <= "'.$to_date.'"'
		.($contBrch ?' AND (brchcont.csType != "F" OR brchcont.csType is null) ' : '')
		.(isset($params['branch']) && $params['branch'] != -1 && $bw_map ?' AND si.fromlocId IN("'.implode('","',$bw_map).'") ' : '')
		.(!empty($params['taxNo']) && (isset($params['bgstinId']) && $params['bgstinId']) != 0 ?' AND brchcont.taxNo = "'.$params['taxNo'].'"' : '')
		.(!empty($params['taxNo']) && (isset($params['bgstinId']) && $params['bgstinId']) == 0 ?' AND (brchcont.taxNo = "'.$params['taxNo'].'" or brchcont.taxNo = "")' : '')
		."AND si.qty < 0"
		// .($is_aging?' AND se.sType NOT IN ("OP","BF")':'') ;
		// added for stock aging report
		.($is_aging?' AND (se.sType!="BF" or (se.sType="BF" and se.sDate = "'.$from_date.'"))':'');

		if ($isPurRate) {// for manufacture journal
			$params['qty'] = !empty($params['cal_qty'])?$params['cal_qty']:$params['qty'];// used for mfj from bom load
			$sOut.= ' UNION ALL select '.$this->bId.' as locId,'.$this->bId.' as bid,0 as itemAttrId,'.$params['itemId'][0].' as itemId,Null as tdate,0 as qty,'.$params['qty'].' as newqty';
		}
		$sOut.= ') SO GROUP by '.$partition;

		// for opening based on start date
		$opening_filter = 'tDate < "' . $from_date . '"';
		$other_filter = 'tDate  >= "' . $from_date . '"';
		if (strtotime($fin_start_date) == strtotime($from_date)) {
			$opening_filter = 'tDate >= "' . $from_date . '" and tType IN ("OP","BF")';
			$other_filter = 'tDate >= "' . $from_date . '" and tType NOT IN ("OP","BF")';
		}
		//  THEN if(sAll.incrQty - sOUT.spent <>0,sAll.incrQty - sOUT.opSpent,-1)
		$union_sall = "SELECT sAll.*,
			If ($opening_filter and sAll.inValQty > 0,
			CASE WHEN sAll.incrQty - sOUT.opSpent <=  (sAll.inValQty)
					THEN if(sAll.incrQty - sOUT.opSpent <>0,sAll.incrQty - sOUT.opSpent,-1)
					WHEN sOUT.opSpent >= sAll.incrQty
					THEN (sAll.inValQty)
					ELSE 0
					END,0) opexpenseQty";
					
		if ($isPurRate) {
			// $union_sall = "SELECT sAll.*,
			// 	if (sAll.inValQty > 0,						
			// 	CASE WHEN sAll.incrQty - sOUT.newSpent <=  (sAll.inValQty) THEN if(sAll.incrQty - sOUT.newSpent <>0,sAll.incrQty - sOUT.newSpent,-1)
			// 			WHEN sOUT.newSpent >= sAll.incrQty	THEN (sAll.inValQty)
			// 			ELSE 0
			// 			END,0) newExpenseQty";

			$union_sall = "SELECT sAll.*,If (sAll.inValQty > 0 and sOUT.newSpent>0,						
			CASE WHEN sOUT.newSpent >= sAll.incrQty 
				THEN sAll.inValQty
			WHEN sAll.incrQty - sOUT.newSpent <  sAll.inValQty
				THEN sAll.inValQty-(sAll.incrQty - sOUT.newSpent)
			ELSE 0
				END,0) newExpenseQty ";
		}
					
		// $union_sall.= ",If (sAll.inValQty > 0,						
		// 	CASE WHEN sAll.incrQty - sOUT.spent <=  (sAll.inValQty)
		// 			THEN if(sAll.incrQty - sOUT.spent <>0,sAll.incrQty - sOUT.Spent,-1)
		// 			WHEN sOUT.spent >= sAll.incrQty
		// 			THEN (sAll.inValQty)
		// 			ELSE 0
		// 			END,0) expenseQty    
		$union_sall.= ",If (sAll.inQty > 0 and sOUT.Spent>0,						
		CASE WHEN sOUT.Spent >= sAll.incrQty 
			THEN sAll.inQty
		WHEN sAll.incrQty - sOUT.spent <  sAll.inQty
			THEN sAll.inQty-(sAll.incrQty - sOUT.Spent)
		  ELSE 0
			END,0) expenseQty";

		if (!$is_aging)
		{
			$union_sall.= " FROM sAll
			left JOIN sOUT USING (".$partition.")";
		} else {
			// foraging stock
			$union_sall.= " FROM (/* ---- sAll start --- */ select *,
			if(inValQty > 0,@runInValQty:=IF(@currlocId = locId and @curritemId=itemId and @currItemAttrId=itemAttrId,@runInValQty + inValQty,inValQty),0)  as  incrQty,
	@currlocId:=if(inValQty > 0,locId,@currlocId) as tempassignlocId,
	@curritemId:=if(inValQty > 0,itemId,@curritemId) as tempassignitemId,
	@curritemAttrId:=if(inValQty > 0,itemAttrId,@curritemAttrId) as tempassignitemAttrId
			from
			(Select * from  (
									select
										@curritemId := -1,
										@currlocId:=-1,
										@curritemAttrId := 0,
										@runInValQty := 0.00
								) params cross JOIN (".$sAll.") uniontable
									ORDER BY locid,itemId,itemAttrId,tDate, tid, tiId) as unall /* ---- sAll End --- */) as sAll
									
			left JOIN (/* ---- sOUT start --- */ ".$sOut."/* ---- sOUT end --- */) as sOUT USING (".$partition.")";
		}

		return array('sAll' => $sAll, 'sOut' => $sOut, 'union_sall' => $union_sall, 'page' => $params['page'],'opening_filter' => $opening_filter, 'other_filter' => $other_filter);
	}

	public function profit_query($params)
	{
		$from_date 	= !empty($params['from_date'])?$params['from_date']:gmdate('Y-m-d');
		$to_date 	= !empty($params['to_date'])?$params['to_date']:gmdate('Y-m-d');
		get_financial_dates($from_date, $fin_start_date, $fin_end_date);
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;
		$isBranch = false;
		$stk_sin  =  ' AND si.Qty>0 AND se.sType!="TL"';
		$stk_sout = ' AND si.Qty<0 AND se.sType!="TL"';

		$itemIds = !empty($params['itemIds'])?' AND it.itemId in ('.$params['itemIds'].')':'';

		$conId = !empty($params['conId'])?' AND t.conId in ('.$params['conId'].')':'';

		$catId = !empty($params['catId'])?' AND ic.catId in  ('.implode(',',(!empty($params['catId'])?$params['catId']:array($params['catId']))).')':'';

		//print_R($conId);exit;
		$transAttrIds = $stockAttrIds = '';
		if (!empty($params['attrIds']))
		{
			$transAttrIds = ' AND ti.itemAttrId in ('.$params['attrIds'].')';
			$stockAttrIds = ' AND si.itemAttrId in ('.$params['attrIds'].')';
		}

		$trans_branch = $isBranch?' AND ti.locId='.$branch :'';
		if (sal_mod_active(BRANCH_MOD) && $branch!=-1) {
			$isBranch = true;
			$bw_map = $this->trans_perm_loc($branch);
			
			if (!$bw_map) {
				$bw_map = array($branch);
			}
			if(isset($params['branch']) && $branch == 0) {
				array_unshift($bw_map,0);
			}
			$stk_sin	= ' AND  ((si.Qty>0 AND si.fromlocId IN ('.implode(',',$bw_map).')) or (si.Qty < 0 and se.sType="TL" and si.tolocId IN('.implode(',',$bw_map).')))';
			$stk_sout	= ' AND (si.Qty<0 AND si.fromlocId IN ('.implode(',',$bw_map).'))';
			$trans_branch = $isBranch?' AND ti.locId IN ('.implode(',',$bw_map).')' :'';
		}
		// $sq_stk_loc_where = '';
		// $stk_loc_where = ' AND se.sType!="TL"';
		// if ($bw_map) {	
		// 	// $stk_loc_where = ' AND (si.qty <> 0 OR (se.sType="TL" and (si.fromlocId IN ('.implode('","',$bw_map).') OR si.tolocId IN ('.implode('","',$bw_map).'))))';
		// 	$stk_loc_where = ' AND (si.fromlocId IN("'.implode('","',$bw_map).'") OR (se.sType = "TL" AND si.tolocId IN("'.implode('","',$bw_map).'")))';
		// 	$sq_stk_loc_where = ' AND (sq_si.fromlocId IN("'.implode('","',$bw_map).'") OR (sq_se.sType = "TL" AND sq_si.tolocId IN("'.implode('","',$bw_map).'")))';
		// }

		
		
		#$sinSelect
		$sumQuery = "IF(@pitemId = itemId AND @pitemAttrId = itemAttrId AND @plocId=locId,
		@runtotal := @runtotal + inValQty,
		@runtotal := inValQty) as  incrQty,
		@pitemId  := itemId  AS `ritemId`,
		@pitemAttrId := itemAttrId AS ritemAttrid,
		@plocId := locId AS rbId
		from
		( SELECT @pitemId  := NULL
		, @pitemAttrId := NULL
		, @plocId := NULL
		, @runtotal := 0
		) i join  ";
		$res['sIn'] = ' JOIN (/*------- sIN -------*/select *, 
		'.$sumQuery.'
		
		((/*Union Table: Pur/CN/Stock */SELECT t.id as tId, t.conId, ti.id as tiId,t.tDate,t.tType,t.seriesId,t.bid,ti.locId, ti.itemAttrId, ti.itemId, it.name as itemName, it.uom AS uom, it.HS as hsn,it.SKU, ti.unit,
		(ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) AS inValQty, 
		IF(ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount as inValue
		FROM ob_trans AS t
		JOIN ob_trans_items AS ti ON ti.transId=t.id
		JOIN ob_items AS it ON it.itemId=ti.itemId LEFT JOIN ob_item_attr AS iar ON iar.itemAttrId=ti.itemAttrId and iar.itemId=ti.itemId
		LEFT JOIN ob_itemrelunits AS itr ON itr.itemId=ti.itemId and itr.relUnitName=ti.unit'
		.($catId?' JOIN ob_items_category AS ic ON  ic.itemId=it.itemId ':'')
		.' WHERE t.cId = '.$this->cId.$trans_branch
		.$itemIds.$transAttrIds.$catId.' AND it.isInventory = 1 AND t.tDate >= "'.$fin_start_date.'" AND t.tDate <= "'.$fin_end_date.'" AND t.status NOT IN("'.implode('","',$this->config->item('ignore_status')).'")
		AND (t.tType IN("PI", "PR", "EI", "PE", "PD") or (t.tType ="GR" and t.categoryCode="TL"))
		AND   (
		t.reftType NOT IN("SI","SR","SC","SD","PI","PR","EI","PE","PC","PD")
		OR    (
		t.tType IN("SC", "SD", "PC", "PD")
		AND t.reftType IN("SI", "SR", "PI", "PR", "EI", "PE","SC", "SD", "PC", "PD")
		  )
		OR    (
		t.tType IN("GR","SH")
		AND t.reftType IN("GR","SH")
		  ) and (ti.qty+ti.freeQty) > 0
		 )) 
		UNION ALL
		(/*Credit Note*/SELECT t.id as tId, 0 as conId, ti.id as tiId,t.tDate,t.tType,t.seriesId,t.bid,ti.locId, ti.itemAttrId, ti.itemId, it.name as itemName, it.uom AS uom, it.HS as hsn,it.SKU, ti.unit,
		(ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) AS inValQty, 
		if (tirl.cPrice is NULL, ti.taxableAmount, (tirl.cPrice * (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1))) as inValue
		FROM ob_trans AS t
		JOIN ob_trans_items AS ti ON ti.transId=t.id
		JOIN ob_items AS it ON it.itemId=ti.itemId LEFT JOIN ob_item_attr AS iar ON iar.itemAttrId=ti.itemAttrId and iar.itemId=ti.itemId
		LEFT JOIN ob_itemrelunits AS itr ON itr.itemId=ti.itemId and itr.relUnitName=ti.unit
		LEFT JOIN ob_trans_items_rel as tirl on tirl.transItemId=ti.id and tirl.transItemId=tirl.ptitemId'
		.($catId?' JOIN ob_items_category AS ic ON  ic.itemId=it.itemId ':'')
		.' WHERE t.cId = '.$this->cId.$trans_branch
		.$itemIds.$transAttrIds.$catId.' AND it.isInventory = 1 AND t.tDate >= "'.$fin_start_date.'" AND t.tDate <= "'.$fin_end_date.'" AND t.status NOT IN("'.implode('","',$this->config->item('ignore_status')).'")
		AND t.tType IN("SC") AND (ti.qty+ti.freeQty) > 0)
		UNION ALL 
		(/*Stock Journal 1*/ SELECT se.id, 0 as conId, si.id as tiId, se.sDate  as tDate,se.sType as tType,0 as seriesId,se.locId as bid,If(si.Qty < 0,si.tolocId,si.fromlocId) as locId,si.itemAttrId, it.itemId, it.name AS itemName, it.uom AS uom, it.HS as hsn,it.SKU, si.unit,
		IF(si.qty > 0, si.qty,  si.qty * -1) * if(itr.convFactor, itr.convFactor, 1) as inValQty, 
		IF(si.qty > 0, si.qty,  si.qty * -1) * si.rate  as inValue
		FROM ob_stock_entries AS se
		JOIN ob_stock_items AS si ON si.sId=se.id
		JOIN ob_items  AS it ON it.itemId=si.itemId LEFT JOIN ob_itemrelunits AS itr ON itr.itemId=si.itemId and itr.relUnitName=si.unit
		LEFT JOIN ob_item_attr AS iar ON iar.itemAttrId=si.itemAttrId and iar.itemId=si.itemId
		LEFT JOIN ob_contacts as fromBr on fromBr.id=si.fromlocId and fromBr.csType="L"
		LEFT JOIN ob_contacts as toBr on toBr.id=si.fromlocId and toBr.csType="L"
		WHERE se.cId = '.$this->cId
		// .$stk_loc_where 
		.$itemIds.$stockAttrIds.' AND it.isInventory = 1 AND se.sDate >= "'.$fin_start_date.'" AND se.sDate <= "'.$fin_end_date.'" '.$stk_sin
		.') order BY locId, itemId, itemAttrId, tDate, tid, tiId) uniontable ) as sIN ';

		$sumQuery = "IF(@opitemId = itemId AND @opitemAttrId = itemAttrId AND @oplocId=locId,
         @oruntotal := @oruntotal + outQty,
         @oruntotal := outQty) as  incrQty,
      @opitemId  := itemId  AS `ritemId`,
      @opitemAttrId := itemAttrId AS `ritemAttrid`,
	  @oplocId := locId AS `rbId`
		from
( SELECT @opitemId  := NULL
              , @opitemAttrId := NULL
              , @oplocId := NULL
              , @oruntotal := 0
       ) i join  ";
		$res['sOut'] = '/*------- sOUT -------*/   select *,  
		'.$sumQuery.'  
 		((/*SO: Sales/Sup.CN/Stock */SELECT t.id as tId, t.tNo, t.conId, t.conName, t.tType,t.seriesId, t.bId,ti.locId,ti.id as tiId, ti.itemAttrId, ti.unit,ti.itemId,t.tdate as tdate,
		(ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) AS outQty, 
		ti.taxableAmount as outValue
		FROM ob_trans AS t
		
		JOIN ob_trans_items AS ti ON ti.transId=t.id'
		
		// project profit mismatched with invoice wise profit moved to outer
		// .((!empty($params['conId']) && !empty($params['csType']) && $params['csType']=='P')?' JOIN ob_trans_billable AS tb ON tb.transId=t.id and tb.prjconId = "'.$params['conId'].'"':'')
		.' JOIN ob_items AS it ON it.itemId=ti.itemId LEFT JOIN ob_itemrelunits AS itr ON itr.itemId=ti.itemId and itr.relUnitName=ti.unit'
		.($catId?' JOIN ob_items_category AS ic ON  ic.itemId=it.itemId ':'')
		.' WHERE t.cId = '.$this->cId.$trans_branch
		.$itemIds.$transAttrIds.$catId.' AND it.isInventory = 1 AND t.tDate >= "'.$fin_start_date.'" AND t.tDate <= "'.$to_date.'" AND t.status NOT IN("'.implode('","',$this->config->item('ignore_status')).'")
		AND (t.tType IN("SI", "SR", "SD") or (t.tType ="SH" and t.categoryCode="TL"))
		AND   (
			t.reftType NOT IN ("SI","SR","SC","SD","PI","PR","EI","PE","PC","PD")
			OR    (
			t.tType IN("SC", "PC")
			AND t.reftType IN("SI", "SR", "PI","PR","EI","PE","SD","PD")
		  	)
		  	OR (t.tType ="SH" and t.reftType = "GR")
		 ))
		 UNION ALL 
		 (SELECT t.id as tId, t.tNo, t.conId, t.conName, t.tType,t.seriesId, t.bId,ti.locId,ti.id as tiId, ti.itemAttrId, ti.unit,ti.itemId,t.tdate as tdate,
		 (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) AS outQty, 
		 if (tr.id is NULL, ti.taxableAmount, ((IF(tir.itc=1, tir.taxableAmount, tir.itemTotal) + tir.chargesAmount)/
		 (tir.qty+tir.freeQty) * if(itrr.convFactor, itrr.convFactor, 1)) * 
		 (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1)) as outValue
		 FROM ob_trans AS t
		 JOIN ob_trans_items AS ti ON ti.transId=t.id
		 JOIN ob_items AS it ON it.itemId=ti.itemId 
		 LEFT JOIN ob_item_attr AS iar ON iar.itemAttrId=ti.itemAttrId and iar.itemId=ti.itemId
 		 LEFT JOIN ob_trans_items as tir on tir.id=ti.refTitemId 
		 LEFT JOIN ob_trans tr on tr.id=tir.transId and tr.tType IN  ("PI","PR","EI","PE","PD")
		 LEFT JOIN ob_itemrelunits AS itr ON itr.itemId=ti.itemId and itr.relUnitName=ti.unit
		LEFT JOIN ob_itemrelunits AS itrr ON itrr.itemId=tir.itemId and itrr.relUnitName=tir.unit'
		.($catId?' JOIN ob_items_category AS ic ON  ic.itemId=it.itemId ':'')
		.' WHERE t.cId = '.$this->cId.$trans_branch
		 .$itemIds.$transAttrIds.$catId.' AND it.isInventory = 1 AND t.tDate >= "'.$fin_start_date.'" AND t.tDate <= "'.$to_date.'" AND t.status NOT IN("'.implode('","',$this->config->item('ignore_status')).'")
		 AND t.tType IN("PC")
		 AND (ti.qty+ti.freeQty) > 0)
		  UNION ALL   
	 	(SELECT se.id as tId, if(se.stNo!="0",se.stNo,se.id) as tNo, 0 as conId,"" as conName, se.sType as tType, 0 as seriesId,se.locId as bid,si.fromlocId as locId, si.id as tiId, si.itemAttrId, si.unit,it.itemId,se.sDate as tDate,
		si.qty * -1 * if(itr.convFactor, itr.convFactor, 1) as outQty,
		si.qty * -1 * si.rate  as outValue
		FROM ob_stock_entries AS se
		JOIN ob_stock_items AS si ON si.sId=se.id
		JOIN ob_items AS it ON it.itemId=si.itemId LEFT JOIN ob_itemrelunits AS itr ON itr.itemId=si.itemId and itr.relUnitName=si.unit
		LEFT JOIN ob_item_attr AS iar ON iar.itemAttrId=si.itemAttrId and iar.itemId=si.itemId
		LEFT JOIN ob_contacts as fromBr on fromBr.id=si.fromlocId and fromBr.csType="L"
		WHERE se.cId = '.$this->cId
		.$itemIds.$stockAttrIds.' AND it.isInventory = 1 AND se.sDate >= "'.$fin_start_date.'" AND se.sDate <= "'.$to_date.'" '.$stk_sout.' ) order BY locId, itemId, itemAttrId,  tDate, tid, tiId) SO ) as sOUT  ';
	
		$res['sIn_sOut'] = '/*src Joining sOut & sIn*/ SELECT 
		sOUT.tid, sOUT.ttype, sOUT.seriesId,sOUT.tNo, sOUT.tdate, sOUT.conId as custId, sOUT.conName, sIN.conId as suppId, sIN.itemId, sIN.itemAttrId, sOUT.bid ,sIN.inValue/sIN.inValQty as cPrice, sOUT.outValue/sOUT.outQty as sPrice, 
		LEAST(IFNULL(sIN.incrQty,0), sOUT.incrQty) - GREATEST(sOUT.incrQty - sOUT.outQty, IFNULL(sIN.incrQty,0) - IFNULL(sIN.inValQty,0))
			AS pUseQty';
		$res['sRes_JOIN' ] = " ON  sIN.itemId = sOUT.itemId
		AND sIN.itemAttrId=sOUT.itemAttrId
		AND sIN.locId=sOUT.locId
		AND sOUT.incrQty - sOUT.outQty < sIN.incrQty
		AND sIN.incrQty - sIN.inValQty < sOUT.incrQty
		ORDER BY
		sIN.locId, sIN.itemId, sIN.itemAttrId, sIN.tdate, sIN.tid";
		return $res;
	}

	public function wise_profit ($params)
	{
		//print_R($params['conId']);exit;
		$params['pageType'] = !empty($params['pageType'])?$params['pageType']:'I';
		$from_date 	= !empty($params['from_date'])?$params['from_date']:gmdate('Y-m-d');
		$to_date 	= !empty($params['to_date'])?$params['to_date']:gmdate('Y-m-d');
		get_financial_dates($from_date, $fin_start_date, $fin_end_date);
		$page_limit = $this->config->item('page_limit');
		$params['page'] = !empty($params['page']) ? $params['page'] : 1;
		$from = ($params['page'] - 1) * $page_limit;

		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;
		$isBranch = false;
		if (sal_mod_active(BRANCH_MOD) && $branch!=-1) {
			$isBranch = true;
		}
		$trans_branch = $isBranch?' AND ti.locId in ('.$branch .')':'';

		
		$query = $this->profit_query($params);
		//print_R($query);
		
		$sales 		= 'Round(sum(if(pUseQty > 0, pUseQty, 1) * sprice),2) as salAmount';
		$cost		= 'Round(sum(if(pUseQty > 0, pUseQty, 1) * cPrice),2) as costAmount';
		$profit 	= 'Round(sum((if(pUseQty > 0, pUseQty, 1) * sprice) - (if(pUseQty > 0, pUseQty, 1) * cprice)),2) as profit';
		$profitper 	= 'Round(sum((if(pUseQty > 0, pUseQty, 1) * sprice) - (if(pUseQty > 0, pUseQty, 1) * cprice))/sum((if(pUseQty > 0, pUseQty, 1) * cprice)) * 100,2) as profitper';

		$select = "$sales, $cost, $profit, $profitper";
	
		switch ($params['pageType'])
		{
			case 'I': // invocie wise profit
					$union = 'select ttype as tType,tId as id, seriesId,  tNo as tno, tDate as tDate, conName,bid,'.$select
					.' from (/*sRes linked expenses + sales Charges*/ select * from (' .$query['sIn_sOut'].' from '.' ( '.$query['sOut'].' '.$query['sIn']. ' '.$query['sRes_JOIN'].') src'
					.' UNION ALL
					/* Include linked Expenses Cost Price */
					select t.id as tid, t.ttype, t.seriesId,t.tNo, t.tdate, t.conId as custId, t.conName, 0 as suppId, 0 as itemId, 0 as itemAttrId, t.bid as bid , sum(ti.itemTotal) as cPrice, 0 as sPrice, 
							1 AS pUseQty 
					from ob_trans t 
					JOIN `ob_trans_billable` AS `tb` ON tb.invTransId=t.id and tb.tsType="T"
					Join `ob_trans_items` as ti on ti.transId=tb.transId and (`ti`.id=tb.transItemId OR tb.transItemId=0)
					where
					t.cId = '.$this->cId.$trans_branch.' AND t.tDate >= "'.$fin_start_date.'" AND t.tDate <= "'.$to_date.'" AND t.status NOT IN("D","X","V")
							AND t.tType IN("SI", "SR", "SD") 
					group by t.id
					
					UNION ALL
					/* Include linked Expenses Sales Price */
					select t.id as tid, t.ttype, t.seriesId,t.tNo, t.tdate, t.conId as custId, t.conName, 0 as suppId, 0 as itemId, 0 as itemAttrId, t.bid as bid , 0 as cPrice, sum(ti.taxableAmount) as sPrice, 
					1 AS pUseQty 
					from ob_trans t 
					JOIN `ob_trans_billable` AS `tb` ON tb.invTransId=t.id and tb.tsType="T"
					Join `ob_trans_items` as ti on ti.transId=t.id 
					
					LEFT JOIN ob_items AS it ON it.itemId=ti.itemId
					where
					t.cId = '.$this->cId.$trans_branch.' and ifnull(it.isinventory,0) != 1 AND ti.unit not in ("LBT","LAT") AND  t.tDate >= "'.$fin_start_date.'" AND t.tDate <= "'.$to_date.'" AND t.status NOT IN("D","X","V")
							AND t.tType IN("SI", "SR", "SD") 
					group by t.id'					
					.') as sRes '
					.((!empty($params['conId']) && !empty($params['csType']) && $params['csType']=='P')?' JOIN ob_trans_billable AS tb ON tb.transId=sRes.tId and tb.prjconId = "'.$params['conId'].'"':'')
					.' WHERE '. (!empty($params['tType']) && in_array($params['tType'], ['SI', 'SR']) ? 'tType IN ("'.$params['tType'].'")' : 'ttype IN ("SI","SR","SD")') .($branch!=-1 ? 'AND bId="'.$branch.'"' : '').' AND tDate >= "'.$from_date.'" AND tDate <= "'.$to_date.'"';
					if (!empty($params['conId']) && (empty($params['csType']) || $params['csType']!='P')){
						$union .= ' AND sRes.custId = "'.$params['conId'].'"';				
					}
					if (!empty($params['conId']) && (empty($params['csType']) || $params['csType']!='P')){
						$union .= ' AND sRes.custId = "'.$params['conId'].'"';				
					}
					if(!empty($params['seriesId'])&& ($params['seriesId'] != '-1')){
						$union .= ' AND sRes.seriesId = "'.$params['seriesId'].'"';
					}
					
					$grp_by = ' group by id order by tdate, tNo';
				break;
			case 'T': // item wise profit
				$union = 'select i.itemId, i.name as conName, sum(puseQty) as qty, i.mrp, avg(sprice) as srate,avg(cprice) as prate,'.$select.' from (' .$query['sIn_sOut'].' from '.' ( '.$query['sOut'].' '.$query['sIn']. ' '.$query['sRes_JOIN'].') as sRes JOIN ob_items i on i.itemId=sRes.itemId '
				.' WHERE ttype IN ("SI","SR","SD") AND tDate >= "'.$from_date.'" AND tDate <= "'.$to_date.'"';

					//$union = 'WITH '.$query['sIn'].', '.$query['sOut'].' select i.itemId, i.name as conName, sum(puseQty) as qty, i.mrp, avg(sprice) as srate,avg(cprice) as prate,'.$select.' from ('.$query['sIn_sOut'].')  as sRes JOIN ob_items i on i.itemId=sRes.itemId'
				//	.' WHERE ttype IN ("SI","SR","SD") AND tDate >= "'.$from_date.'" AND tDate <= "'.$to_date.'"';
					$grp_by = ' group by itemId order by i.name';
				break;
			case 'C': // customer wise profit
				$union = 'select custId as conId, c.Name AS conName,'.$select.' from (' .$query['sIn_sOut'].' from '.' ( '.$query['sOut'].' '.$query['sIn']. ' '.$query['sRes_JOIN'].') as sRes  JOIN ob_contacts c on c.id=sRes.custId  '
				.' WHERE ttype IN ("SI","SR","SD") AND tDate >= "'.$from_date.'" AND tDate <= "'.$to_date.'" AND sRes.custId > 0';
				if(!empty($params['conId'])){
					$union .= ' AND sRes.custId = "'.$params['conId'].'"';				
				}
				//	$union = 'WITH '.$query['sIn'].', '.$query['sOut'].' select custId as conId, c.Name AS conName,'.$select.' from ('.$query['sIn_sOut'].')  as sRes JOIN ob_contacts c on c.id=sRes.custId '
				//	.' WHERE ttype IN ("SI","SR","SD") AND tDate >= "'.$from_date.'" AND tDate <= "'.$to_date.'" AND sRes.custId > 0  ';
					$grp_by = ' group by custId order by name';
				break;
			case 'S': // supllier wise profit
				$union = 'select suppId as conId, c.Name AS conName,'.$select.' from (' .$query['sIn_sOut'].' from '.' ( '.$query['sOut'].' '.$query['sIn']. ' '.$query['sRes_JOIN'].') as sRes JOIN ob_contacts c on c.id=sRes.suppId  '
				.' WHERE ttype IN ("SI","SR","SD") AND tDate >= "'.$from_date.'" AND tDate <= "'.$to_date.'" AND sRes.suppId > 0';
				if(!empty($params['conId'])){
					$union .= ' AND sRes.suppId = "'.$params['conId'].'"';				
				}
					//$union = 'WITH '.$query['sIn'].', '.$query['sOut'].' select suppId as conId, c.Name AS conName,'.$select.' from ('.$query['sIn_sOut'].')  as sRes JOIN ob_contacts c on c.id=sRes.suppId'
				//	.' WHERE ttype IN ("SI","SR","SD") AND tDate >= "'.$from_date.'" AND tDate <= "'.$to_date.'" AND sRes.suppId > 0';
					$grp_by = ' group by suppId order by name';
				break;
		}

		$tot_union = $union;
		//print_R($tot_union);
		if (empty($params['onlyTot'])) {
			$union .= $grp_by;
				
			if(empty($params['f_type']))	
				$union .= " limit " . $from . ',' . $page_limit;
			$result['items'] = $this->db->query($union)->result_array();
		}
		if (!$from && (!empty($params['onlyTot']) || !empty($result['items'])))
		{
			$balance = $this->db->query($tot_union)->row_array();
			$result['balance'] = array('totsalAmount' => $balance['salAmount'], 'totcostAmount' => $balance['costAmount'], 'totprofit' => $balance['profit']);
		}
		return $result;
	}
	/* 'inv_profit' function replaced with 'wise_profit' so it removed */

	public function summary_fifo($params) {
		// opening balance import
		$opening = isset($params['opening']) ? $params['opening'] : 0;
		$params['page'] = !empty($params['page']) ? $params['page'] : 1;
		$isPurRate		= !empty($params['purRateType'])?$params['purRateType']:false;
		
		$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
		$to_date = $params['to_date'];
		get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);

		$inw_qty = '"'.PURINV.'","'.PURRETAIL.'", "'.EXPINV.'", "'.EXPRETAIL.'", "'.PURDBNOTE.'", "'.PURRECP.'", "'.CRNOTE.'"';	
		$result['items'] = $items = array();

		if (!$isPurRate) {
			// prepare sall and sout query
			$query = $this->fifo_query($params);

			if (!$query) {
				return array();
			}
			$union_sall		= $query['union_sall'];
			$opening_filter = $query['opening_filter'];
			$other_filter 	= $query['other_filter'];
			$addGroup = '';
			if (isset($params['location']) &&  $params['location'] == -1)
			{
				$addGroup = 'locId,';
			}
			//round(sum(If (inValQty > 0 and expenseQty>=0, if (expenseQty=0, inValue, Round(expenseQty * (inValue/inValQty),2)),0)) ,2) as bvalue
			$query = 'WITH sAll AS ('.$query['sAll'].'), sOUT AS ('.$query['sOut'].') ';
			$sel_query = 'select itemId,itemAttrId,uom,locId,itemName,hsn,SKU,unit,tDate,tType,inQty,outQty,
			round(sum(If ('.$opening_filter.', inQty - outQty, 0)),3) AS opqty, 
			round(sum(If ('.$opening_filter.', If (inValQty > 0, CASE WHEN opexpenseQty=0 then inValue WHEN opexpenseQty > 0 then opexpenseQty * (inValue/inValQty) End,0) ,0)) ,2) as opvalue,
			round(sum(If ('.$other_filter.', inQty, 0)),3) AS iqty, 
			round(sum(If ('.$other_filter.' and inQty > 0, if(inValQty>0,inValue, if(avgRate> 0, avgRate, inValue/inQty) * inQty),0)) ,2) as ivalue,
			round(sum(If ('.$other_filter.', outQty, 0)),3) AS oqty, 
			round(sum(If ('.$other_filter.' and outQty > 0,outValue,0)) ,2) as ovalue,
			round(sum(inQty-outQty),3) AS bqty,
			round(sum(If (inValQty > 0 and inValue>=0 , if (expenseQty=0, inValue, Round((inValQty-expenseQty) * (inValue/inValQty),2)),if(avgRate> 0, avgRate, inValue/inQty) * (inQty-expenseQty))) ,2) as bvalue
			from ('.$union_sall.') sINOUT group by '.$addGroup.'itemId'
			.($opening || !empty($params['show_attrs'])? ' ,itemAttrId':'');
			
			$sel_having = (!empty($params['zeroStocks'])? ' having opqty+iqty+oqty<>0':'')
			.((empty($params['zeroStocks']) && !empty($opening))? ' having bqty<>0':''); //opening ignore 0 closing qty to import

			if ($addGroup)
			{
				$sel_query = 'select itemId,itemAttrId,uom,locId,itemName,hsn,SKU,unit,tDate,tType,inQty,outQty,
				sum(if(opqty>0,opqty,0)) as opqty,sum(if(opvalue>0,opvalue,0)) as opvalue,
				sum(if(iqty>0,iqty,0)) as iqty,sum(if(ivalue>0,ivalue,0)) as ivalue,
				sum(if(oqty>0,oqty,0)) as oqty,sum(if(ovalue>0,ovalue,0)) as ovalue,
				sum(if(bqty>0,bqty,0)) as bqty,sum(if(bqty>0,bvalue,0)) as bvalue from '
				.'('.$sel_query.') res group by itemId'
				.($opening || !empty($params['show_attrs'])? ' ,itemAttrId':'');
			}
			

			$query = $query.$sel_query.$sel_having.' ORDER BY itemName,itemId';

			if (!empty($params['inv_profit'])) {
				// invoice based profit
				return $query;
			}
			$items = $this->db->query($query)->result_array();

			if ($opening) {
				return array_merge($result['items'],$items);
			}
			$result['page'] = $params['page'];
			$result['items'] = array_merge($result['items'],$items);

			$from = 0;
			if (!$from) { // get total
				$result['totals'] = $this->calc_stock_value_fifo($params);
			}
		} else {
			$result = $this->calc_stock_value_fifo($params);
		}

		if (!empty($params['show_attrs'])) {
			$params = array ('group_attr' => false, 'zeroStocks' => !empty($params['zeroStocks'])?true:false);
			$result = $this->get_attributes($result,$params,false,true);
		}
		if(!empty($params['itemId'])) {
			$result['outwardStockInfo'] = $this->getOutwardStockInformation($params);
		}
		return $result;
	}

	public function calc_stock_value_fifo($params) {
		
		$params['is_total'] = true;

		$to_date = $params['to_date'];
		get_financial_dates($to_date, $fin_start_date, $fin_end_date);
		if (!empty($params['isOpening']) && strtotime($to_date) > strtotime($fin_start_date))
		{ // date wise opening balance exclude from date purchase
			$params['to_date'] = date('Y-m-d', strtotime($params['to_date'] . ' -1 day'));
		}
		$query = $this->fifo_query($params);

		$sAll = $query['sAll'];
		$sOut = $query['sOut'];
		$union_sall		= $query['union_sall'];
		$opening_filter = $query['opening_filter'];
		$other_filter 	= $query['other_filter'];
		$isPurRate		= !empty($params['purRateType'])?$params['purRateType']:false;
		$addBid = 'locId,';
		// if(isset($params['branch']) && $params['branch'] == -1) {
		// 	$addBid = "bid,";
		// }
		// else {
		// 	$addBid = "";
		// }
		//print_R($addBid );exit;
		/*
		incrQty - increment inward qty
		spent or newspent - outward qty
		expense or newexpense qty - used qty
		*/
		$query = 'WITH sAll AS ('.$sAll.'),sOUT AS ('.$sOut.') select ';
		$bNewvalue = ''; 
		if ($isPurRate) {
			$params['qty'] = !empty($params['cal_qty'])?$params['cal_qty']:$params['qty'];// used for mfj from bom load
			// $query.='(sum(if(bqty>0,bvalue,0)) - sum(if(bqty>0,bNewValue,0))) / '.$params['qty'].'  as bNewValue from (select ';
			$query.='(if(bqty>0,(sum(bvalue-bNewValue) / least(bqty,'.$params['qty'].')),0)) as bNewValue from (select ';
			$bNewvalue = ',round(sum(If (inValQty > 0 and inValue>=0, if (newExpenseQty=0, inValue, Round((inValQty-newExpenseQty) * (inValue/inValQty),2)),0)) ,2) as bNewvalue';
		} else {
			if (empty($params['stk_type']) || $params['stk_type']!='stock_value') {	
			$query .= 'sum(if(opqty>0,opqty,0)) as opqty,sum(if(opvalue>0,opvalue,0)) as opvalue,
				sum(if(iqty>0,iqty,0)) as iqty,sum(if(ivalue>0,ivalue,0)) as ivalue,
				sum(if(oqty>0,oqty,0)) as oqty,sum(if(ovalue>0,ovalue,0)) as ovalue,';
			}
			$bal_query = 'sum(if(bqty>0,bqty,0)) as bqty,sum(if(bqty>0,bvalue,0)) as bvalue';			
			if (!empty($params['isOpening']) && (strtotime($to_date) == strtotime($params['from_date'])))
			{
				$bal_query = 'sum(if(opqty>0,opqty,0)) as bqty,sum(if(opvalue>0,opvalue,0)) as bvalue';
			}
			$query .= $bal_query.' from 
			(select 
			round(sum(If ('.$opening_filter.' , inQty - outQty, 0)),3) AS opqty, 
			round(sum(If ('.$opening_filter.', If (inValQty > 0, CASE WHEN opexpenseQty=0 then inValue WHEN opexpenseQty > 0 then opexpenseQty * (inValue/inValQty) End,0) ,0)) ,2) as opvalue,
			round(sum(If ('.$other_filter.', inQty, 0)),3) AS iqty, 
			round(sum(If ('.$other_filter.' and inQty > 0, if(inValQty>0,inValue, if(avgRate> 0, avgRate, inValue/inQty) * inQty),0)) ,2) as ivalue,
			round(sum(If ('.$other_filter.', outQty, 0)),3) AS oqty, 
			round(sum(If ('.$other_filter.' and outQty > 0,outValue,0)) ,2) as ovalue, ';
		}
		//round(sum(If (inValQty > 0 and expenseQty>=0, if (expenseQty=0, inValue, Round(expenseQty * (inValue/inValQty),2)),0)) ,2) as bvalue
		$query .= 'round(sum(inQty-outQty),3) AS bqty,
		round(sum(If (inValQty > 0 and inValue>=0 , if (expenseQty=0, inValue, Round((inValQty-expenseQty) * (inValue/inValQty),2)),if(avgRate> 0, avgRate, inValue/inQty) * (inQty-expenseQty))) ,2) as bvalue'.$bNewvalue.' from ('.$union_sall.') sINOUT group by '.$addBid. ' itemId '
		
		.(!empty($params['show_attrs'])? ' ,itemAttrId ':'')
		.') res';
// echo $query;exit;
		$query = $this->db->query($query);
		return $query->row_array();

	}

	// Modify only for storage items in stock ledger
	public function storage_stock_ledger ($sql='',$params=array())
	{
		if(!empty($params['isStorage'])) {

			$sql = preg_replace("/AND\s+`t`.`tDate`\s*>=\s*'[^']*'\s*/", "/*For Storage item */", $sql);
			$sql = preg_replace("/AND\s+`se`.`sDate`\s*>=\s*'[^']*'\s*/", "/*For Storage item */", $sql);
		}
		return $sql;
	}

	public function summary($params) {
		$params['stk_type'] = !empty($params['stk_type'])?$params['stk_type']:'summary';
		$stock_ledger 		= $params['stk_type']=='stock_ledger'?true:false;
		$fifo 				= (!$stock_ledger && empty($params['outward_details']) && empty($params['inward_details']))?true:false;
		$stkRate 			= get_company('stkRate');
		$isAllBranch		= (isset($params['branch']) && $params['branch']==-1)?true:false;
		$ispurRate		= false;
		// if (!empty($params['isStorage']))
		// {
		// 	$this->it_type = array('T');
		// }
		if (!empty($params['purRateType'])) {
			//purRateType used from mfj
			$stkRate = $params['purRateType'];
			$ispurRate = true;
		}
		if(!empty($params['catIds'])){	 
			$params['catIds'] = $this->get_child_category($params['catIds']);//print_R($params['catIds']);exit;		
		}
		if(isset($params['taxNo']) && $params['bgstinId'] == 0) {
			$gstquery = "select id from ob_contacts where (taxNo='".$params['taxNo']."' or taxNo='') and cstype in ('B','L')";
			$locIds = $this->db->query($gstquery)->result_array();
			$locIds = array_column($locIds,"id");
			$params['locIds'] = $locIds;
		} else if(isset($params['taxNo'])) {
			$gstquery = "select id from ob_contacts where (taxNo='".$params['taxNo']."') and cstype in ('B','L')";
			$locIds = $this->db->query($gstquery)->result_array();
			$locIds = array_column($locIds,"id");
			$params['locIds'] = $locIds;	
		}
		// print_r($stkRate);
		// exit;
		if ($fifo && $stkRate==='F'&& empty($params['isDetail']))
		{ //fifo stk rate
			return $this->summary_fifo($params);
		}
		
		$diff_fyr = false;//date filter diff finance year
		if (!empty($params['from_date']) && !empty($params['to_date']))
		{
			get_financial_dates($params['from_date'], $std, $edd);
			$diff_fyr = ($params['to_date']>$edd)?true:false;
		}
		// to prepare query
		$params['expDetailLedger'] = false;
		if(!empty($params['stk_exp'])){
			$params['attr_ids'] = $this->getExpAttrIds($params);
			$params['expDetailLedger'] = true;
		}
		if(empty($params['itemId']) && !empty($params['itemName'])){
			$this->load->model("itemsModel");
			$params['itemId'] = $this->itemsModel->get_itemids($params['itemName']);
		}

		//one franchise can be selected. No option for All branches.
		if (get_user_data('roleCode')=='F' && !empty($params['branch']) && $params['branch']==-1) {
			return array();
		}

		// opening balance import
		$opening = isset($params['opening']) ? $params['opening'] : 0;
		// stock summary inward outward detail
		$detail = (!empty($params['inward_details']) || !empty($params['outward_details'])) ? true : false; 
		$params['direction'] = !empty($params['direction']) ? strtoupper($params['direction']) : 'ASC';
		$params['order_by'] = !empty($params['order_by']) ? $params['order_by'] : 'itemName';
		$page_limit = $this->config->item('page_limit');
		if(!empty($params['batchwise_stock'])){
			$page_limit = $this->config->item('batch_stk_page_limit');
		}
		$params['page'] = !empty($params['page']) ? $params['page'] : '1';
		// $page_limit = 20;
		$from = ($params['page'] - 1) * $page_limit;
		//print_r($params);
		// exit;
		$params['contBrch'] = false;
		$config = get_company('config');
		$HasFranchise = !empty($config['isFranchise']) ? $config['isFranchise'] : 0;
		
		if ((isset($params['branch']))) {
		
			if($HasFranchise) {
				if(sal_mod_active(BRANCH_MOD) && $params['branch'] == -1) {
					$params['contBrch'] = true;
				}
			}
		}
		$this->trans_select($params);
		if($stock_ledger){
			$this->from($params,false,false);
		}else{
			$this->from($params);
		}
		$this->trans_where($params);
		if($stock_ledger && !empty($params['serialIds'])){
			$this->db->group_by('t.id');
		}
		$trans_query = $this->db->get_compiled_select();
		// echo $trans_query;exit;
		$this->stock_select($params);
		$this->from($params,true);
		$this->stock_where($params);
		if($stock_ledger){ //ignore opening and bf from stock ledger
			if ($diff_fyr)
			{
				$this->db->where_not_in('se.sType',array(STOCK_OPENING,BROUGHT_FORWARD));
			}
			if(!empty($params['serialIds'])){
				$this->db->group_by('se.id');
			}
		}
		$stock_query = $this->db->get_compiled_select();
		if(!empty($params['itemId'])) {
			$result['outwardStockInfo'] = $this->getOutwardStockInformation($params);
		}
		//print_R($result);
		// if (!$isAllBranch) @all branch stock value fixes
		// {
			$st_params = $params;
			$st_params['isInward'] = true;
			$this->stock_select($st_params);
			$this->from($st_params,true);
			$this->stock_where($st_params);
			if($stock_ledger){ //ignore opening and bf from stock ledger
				if ($diff_fyr)
				{
					$this->db->where_not_in('se.sType',array(STOCK_OPENING,BROUGHT_FORWARD));
				}
				if(!empty($st_params['serialIds'])){
					$this->db->group_by('se.id');
				}
			}
			$stock_query.= ' UNION ALL '. $this->db->get_compiled_select();
		// }
		// echo $stock_query;exit;
		if($stock_ledger){
			if(!empty($params['batchwise_stock'])) {
				$union = " select * from ($trans_query UNION ALL $stock_query) uniontable order by itemId asc,itemAttrId desc";	
			}else{
				$union = " select * from ($trans_query UNION ALL $stock_query) uniontable ";
				if (defined('DEBUG_SERIAL') && !empty($params['attr_ids'])) {
					$attr_ids = is_array($params['attr_ids']) ? $params['attr_ids'] : array($params['attr_ids']);
					$union.=" left JOIN (select ljts.tsItemId, group_concat(ljial.serialNo) as serialNo from ".$this->db->dbprefix("trans_serial")." as ljts join  ".$this->db->dbprefix("item_attr_serial")." as ljial on ljial.id=ljts.asId where ljial.itemAttrId in ('".implode("','",$attr_ids)."') group by ljts.tsItemId) as lj ON lj.tsItemId=uniontable.itId";
				}
				$union .= " where uniontable.tType != 'BF'  AND uniontable.tType != 'OP'";//group by uniontable.id,uniontable.bId
				if (!empty($params['pageType']) && !empty($params['wtype']) && $params['pageType'] == 'DWS') {
					$union .= " and uniontable.tType = " . $this->db->escape($params['wtype']) ."";
				}
				$union .= " order by uniontable.tDate asc,uniontable.iqty desc,uniontable.id asc";
			}
			if (empty($params['f_type'])) {

				$union .= " limit " . $from . ',' . $page_limit;
			}
			$union = $this->db->query($union);
			$result['items'] = $union->result_array();
			// echo $this->db->last_query();exit;
			if(!isset($params['batchwise_stock'])){
				if (!$from) {
					$params['stock_ledger_balance'] = true;
					$this->trans_select($params);
					$this->from($params,false,false);
					$this->trans_where($params);
					if(!empty($params['serialIds'])){
						$this->db->group_by('t.id');
					}
					$trans_query = $this->db->get_compiled_select();

					$this->stock_select($params);
					$this->from($params,true);
					$this->stock_where($params);
					if($stock_ledger){ //ignore opening and bf from stock ledger
						if ($diff_fyr)
						{
							$this->db->where_not_in('se.sType',array(STOCK_OPENING,BROUGHT_FORWARD));
						}
						if(!empty($params['serialIds'])){
							$this->db->group_by('se.id');
						}
					}
					$stock_query = $this->db->get_compiled_select();
					if ($isAllBranch)
					{
						$stock_query.= ' AND se.sType !="TL"';
					} else{
						$st_params = $params;
						$st_params['isInward'] = true;
						$this->stock_select($st_params);
						$this->from($st_params,true);
						$this->stock_where($st_params);
						if($stock_ledger){ //ignore opening and bf from stock ledger
							if ($diff_fyr)
							{
								$this->db->where_not_in('se.sType',array(STOCK_OPENING,BROUGHT_FORWARD));
							}
							if(!empty($st_params['serialIds'])){
								$this->db->group_by('se.id');
							}
						}
						$stock_query.= ' UNION ALL '. $this->db->get_compiled_select();
					}

					$union = " select round(sum(opqty+iqty-oqty),3) AS closeqtyTot,round(sum(opqty),3) AS openqtyTot,round(sum(opqty+iqty),3) AS inqtyTot,round(sum(oqty),3) AS outqtyTot,uom,Round(sum(opqty * oprate)/sum(opqty),2) as openqtyrate from ($trans_query UNION ALL $stock_query) uniontable";
					if (!empty($params['pageType']) &&  !empty($params['wtype']) && $params['pageType'] == 'DWS') {
						$union .= " where uniontable.tType = " . $this->db->escape($params['wtype']) . "";
					}
					// $union = $this->storage_stock_ledger($union,$params);
					$union = $this->db->query($union);
					
					$result['balance'] = $union->row_array();
					
					if (!empty($params['attr_ids']) && $params['attr_ids']!=-1) {
						// get attributes details
						$slat_query  = $this->get_serial_attributes($params);

						$this->db->select('concat(ag.name, " : ", if(ag.fldType="E", GROUP_CONCAT(if (ias.curStk>1 || ias.curStk<1, CONCAT(ias.serialNo,"(",ias.curStk,")"), ias.serialNo) ORDER BY ias.curStk SEPARATOR ", "), a.name)) AS text',false);
						$this->db->from('item_attr as ita');
						$this->db->join('item_attr_link as ial', 'ial.itemAttrId=ita.itemAttrId');
						$this->db->join('attributes as a', 'a.attrId=ial.attrId');
						$this->db->join('attributes_group as ag', 'ag.attrGrpId=a.attrGrpId', 'left');
						$this->db->join('('.$slat_query.') as ias','ias.itemAttrId=ita.itemAttrId  ', 'left');
						$this->db->where(array(
							'ita.cId' => $this->cId,
						));
						
						$this->db->where_in('ita.itemAttrId', $params['attr_ids']);
						$this->db->group_by('a.attrId');
						$this->db->limit(4);
						$tmp = $this->db->get()->result_array();
						
						if ($tmp) {
							$result['attrs'] = array();
							foreach ($tmp as $row) {
								$result['attrs'][] = $row['text'];
							}
							$result['attrs'] = implode(', ',$result['attrs']);
						}
					}
				}
			}
			return $result;
		}

		if ($detail) {
			$union = " select * from ($trans_query UNION ALL $stock_query) uniontable ";
			if(isset($params["subPageType"])) {
				switch ($params["subPageType"]) { 
					case 'i_purchse':
						$union .= " Where tType IN ('PI','PR','EI','PE','PD') ";
					break;
					case 'i_salesreturn':
						$union .= " Where tType IN ('SC') ";
					break;
					case 'i_manufacturer':
						$union .= " Where tType IN ('MJ','PO') ";
					break;
					case 'i_transfer':
						$union .= " Where tType NOT IN ('PI','PR','EI','PE','PD','SC','MJ','PO') ";
					break;
					case 'o_sales':
						$union .= " Where tType IN ('SI','SR','SD') ";
					break;
					case 'o_purchasereturn':
						$union .= " Where tType IN ('PC') ";
					break;
					case 'o_consume':
						$union .= " Where tType IN ('MJ','CO') ";
					break;
					case 'o_expiry':
						$union .= " Where tType IN ('DI','WE','WD','WL','WT','AD') ";
					break;
					case 'o_transfer':
						$union .= " Where tType NOT IN ('SI','SR','SD','PC','MJ','CO','DI','WE','WD','WL','WT','AD') ";
					break;
				}				
			}			
			$union .= "ORDER By tDate";
			if (empty($params['f_type'])) { // export file ignore page limit
				$union .= " limit " . $from . ',' . $page_limit;
			}
			
			$union = $this->db->query($union);
			$result['items'] = $union->result_array();
			
			if (!$from) {
				$query = 'select sum(s_qty) as qty,Round(sum(s_amount),2) as tot_amt,COUNT(DISTINCT unit) as uomCnt,uom as unit from (' . $trans_query . ' UNION ALL ' . $stock_query . ') stkTable';
				if(isset($params["subPageType"])) {
					switch ($params["subPageType"]) { 
						case 'i_purchse':
							$query .= " Where tType IN ('PI','PR','EI','PE','PD') ";
						break;
						case 'i_salesreturn':
							$query .= " Where tType IN ('SC') ";
						break;
						case 'i_manufacturer':
							$query .= " Where tType IN ('MJ','PO') ";
						break;
						case 'i_transfer':
							$query .= " Where tType NOT IN ('PI','PR','EI','PE','PD','SC','MJ','PO') ";
						break;
						case 'o_sales':
							$query .= " Where tType IN ('SI','SR','SD') ";
						break;
						case 'o_purchasereturn':
							$query .= " Where tType IN ('PC') ";
						break;
						case 'o_consume':
							$query .= " Where tType IN ('MJ','CO') ";
						break;
						case 'o_expiry':
							$query .= " Where tType IN ('DI','WE','WD','WL','WT','AD') ";
						break;
						case 'o_transfer':
							$query .= " Where tType NOT IN ('SI','SR','SD','PC','MJ','CO','DI','WE','WD','WL','WT','AD') ";
						break;
					}				
				}
				$query = $this->db->query($query);
				$result['balance'] = $query->row_array();

				if ($result['balance']['uomCnt'] == 1) {
					$result['balance']['totunit'] = $result['balance']['unit'];
				}
			}	
			return $result;
		}

		
		// select
		$select = 'round(sum(opqty+iqty-oqty),3) AS bqty';
		// $select .= ',if(sum(opqty+iqty-oqty) > 0, round(round(sum(opqty+iqty-oqty),3) * round(if("' . get_company('stkRate') . '"!="A" && saleRate,saleRate,sum(op_pur_amt + i_pur_amt)/sum(op_pur_qty + i_pur_qty)),2) ,2),0) as bvalue'; round issue mismatch in close
		$select .= ',if(sum(opqty+iqty-oqty) > 0, round(sum(opqty+iqty-oqty) * round(if("' .((!empty($params['isDetail'])) ? "A" : get_company('stkRate')) . '"!="A" && saleRate,saleRate,sum(if(tType!="SC",tot_pur_amt,0))/sum(if(tType!="SC",tot_pur_qty,0))),2) ,2),0) as bvalue';
		// * round(if("' . (!empty($params['isDetail'])) ? "A" : get_company('stkRate') . '"!="A" && saleRate

		// union query
		$union = " from ($trans_query UNION ALL $stock_query) uniontable";	
			
		if ($opening) { //opening balance import
			$list_query = 'select max(mrp) as mrp,itemId,itemAttrId,uom,locId,itemName,' . $select . $union . ' group by itemId,itemAttrId';
			if (sal_mod_active(BRANCH_MOD)) {
				$list_query .= ',locId';
			}
			$list_query .= " HAVING bqty<>0 ORDER BY " . $params['order_by'] . " " . $params['direction'];
			$list_query = $this->db->query($list_query);
			return $list_query->result_array();
		} else { // summary
			//print_R("DFgdfgdf");
			$select .= ',round(sum(opqty),3) AS opqty,round(if(sum(opqty)>0,1,0) * sum(opqty) * round(sum(if(tType!="SC",op_pur_amt,0))/sum(if(tType!="SC",op_pur_qty,0)),2) ,2) as opvalue,round(sum(iqty),3) AS iqty';
			$select .= ',if(sum(iqty) > 0, round(sum((i_pur_amt/i_pur_qty) * iqty),2),0) AS ivalue,round(sum(oqty),3) AS oqty,round(sum(o_amt),2) AS ovalue';
			if(!empty($params['isDetail'])) {
				$select .= ",round(sum(if (tType IN ('PI','PR','EI','PE','PD'), iqty,0)),3) as i_purqty,round(sum(ifnull((i_pur_amt/i_pur_qty),0) *  if(tType IN ('PI','PR','EI','PE','PD'),ifnull(iqty,0),0)),2) AS i_purvalue,round(sum(if (tType IN ('SC'), iqty,0)),3) as i_salretqty,round(sum(ifnull((i_pur_amt/i_pur_qty),0) *  if(tType IN ('SC'),ifnull(iqty,0),0)),2) AS i_salretvalue,round(sum(if (tType IN ('MJ','PO'), iqty,0)),3) as i_manfqty,round(sum(ifnull((i_pur_amt/i_pur_qty),0) *  if(tType IN ('MJ','PO'),ifnull(iqty,0),0)),2) AS i_manfvalue,round(sum(if (tType NOT IN ('PI','PR','EI','PE','PD','SC','MJ','PO'), iqty,0)),3) as i_trqty,round(sum(ifnull((i_pur_amt/i_pur_qty),0) *  if(tType NOT IN ('PI','PR','EI','PE','PD','SC','MJ','PO'),ifnull(iqty,0),0)),2) AS i_trvalue,round(sum(if (tType IN ('SI','SR','SD'), oqty,0)),3) as o_salqty,round(sum(if(tType IN ('SI','SR','SD'),o_amt,0)),2) AS o_salvalue,round(sum(if (tType IN ('PC'), oqty,0)),3) as o_purretqty,round(sum(if(tType IN ('PC'),o_amt,0)),2) AS o_purretvalue,round(sum(if (tType IN ('MJ','CO'), oqty,0)),3) as o_consqty,round(sum(if(tType IN ('MJ','CO'),o_amt,0)),2) AS o_consvalue,round(sum(if (tType IN ('DI','WE','WD','WL','WT','AD'), oqty,0)),3) as o_expqty,round(sum(if(tType IN ('DI','WE','WD','WL','WT','AD'),o_amt,0)),2) AS o_expvalue,round(sum(if (tType NOT IN ('SI','SR','SD','PC','MJ','CO','DI','WE','WD','WL','WT','AD'), oqty,0)),3) as o_trqty,round(sum(if(tType NOT IN ('SI','SR','SD','PC','MJ','CO','DI','WE','WD','WL','WT','AD'),o_amt,0)),2) AS o_trvalue";
			}
			if (!$ispurRate) {
				$list_query = 'select itemAttrId,itemId,uom,locId,itemName,hsn,SKU,' . $select . $union . ' ';
				if(isset($params['branch'])) {
					$list_query .= "group by locId,itemId";
				}
				else {
					$list_query .= "group by itemId";
				}
				if (sal_mod_active(CATE_ATTR)) {
					$list_query .= ",itemAttrId";
				}
				if (!empty($params['zeroStocks'])) { // exclude zero stocks items only in current stock
					$list_query.=" HAVING opqty+iqty-oqty<>0";
				}
				// $list_query .= " ORDER BY " . $params['order_by'] . " " . $params['direction'];

				if (empty($params['show_attrs'])) {
					// attribute based rate calculated and grouped by itemId
					if(!get_user_data('isAdmin') && !get_user_data('isAccountant') && get_user_data('isSale')){
						$list_query = 'SELECT itemAttrId,itemId,uom,locId,itemName,hsn,SKU,sum(bqty) as bqty, 0 as bvalue,sum(opqty) as opqty,0 as opvalue,sum(iqty) as iqty,sum(ivalue) as ivalue,sum(oqty) as oqty,0 as ovalue'. (!empty($params["isDetail"])? ",sum(i_purqty) as i_purqty, sum(i_purvalue) as i_purvalue,sum(i_salretqty) as i_salretqty,sum(i_salretvalue) as i_salretvalue,sum(i_manfqty) as i_manfqty,sum(i_manfvalue) as i_manfvalue,sum(i_trqty) as i_trqty,sum(i_trvalue) as i_trvalue,sum(o_salqty) as o_salqty, 0 as o_salvalue,sum(o_purretqty) as o_purretqty,0 as o_purretvalue,sum(o_consqty) as o_consqty,0 as o_consvalue,sum(o_expqty) as o_expqty,0 as o_expvalue,sum(o_trqty) as o_trqty,0 as o_trvalue ":"").' FROM ('.$list_query.') src GROUP BY itemId';
					}else if (!get_user_data('isAdmin') && !get_user_data('isAccountant') && get_user_data('isPurchase')){
						$list_query = 'SELECT itemAttrId,itemId,uom,locId,itemName,hsn,SKU,sum(bqty) as bqty,0 as bvalue,sum(opqty) as opqty,0 as opvalue,sum(iqty) as iqty,0 as ivalue,sum(oqty) as oqty,sum(ovalue) as ovalue '. (!empty($params["isDetail"])? ",sum(i_purqty) as i_purqty, 0 as i_purvalue,sum(i_salretqty) as i_salretqty,0 as i_salretvalue,sum(i_manfqty) as i_manfqty,0 as i_manfvalue,sum(i_trqty) as i_trqty,0 as i_trvalue,sum(o_salqty) as o_salqty, sum(o_salvalue) as o_salvalue,sum(o_purretqty) as o_purretqty,sum(o_purretvalue) as o_purretvalue,sum(o_consqty) as o_consqty,sum(o_consvalue) as o_consvalue,sum(o_expqty) as o_expqty,sum(o_expvalue) as o_expvalue,sum(o_trqty) as o_trqty,sum(o_trvalue) as o_trvalue ":"").' FROM ('.$list_query.') src GROUP BY itemId';
					}else{
						$list_query = 'SELECT itemAttrId,itemId,uom,locId,itemName,hsn,SKU,sum(bqty) as bqty,sum(bvalue) as bvalue,sum(opqty) as opqty,sum(opvalue) as opvalue,sum(iqty) as iqty,sum(ivalue) as ivalue,sum(oqty) as oqty,sum(ovalue) as ovalue '. (!empty($params["isDetail"])? ",sum(i_purqty) as i_purqty, sum(i_purvalue) as i_purvalue,sum(i_salretqty) as i_salretqty,sum(i_salretvalue) as i_salretvalue,sum(i_manfqty) as i_manfqty,sum(i_manfvalue) as i_manfvalue,sum(i_trqty) as i_trqty,sum(i_trvalue) as i_trvalue,sum(o_salqty) as o_salqty, sum(o_salvalue) as o_salvalue,sum(o_purretqty) as o_purretqty,sum(o_purretvalue) as o_purretvalue,sum(o_consqty) as o_consqty,sum(o_consvalue) as o_consvalue,sum(o_expqty) as o_expqty,sum(o_expvalue) as o_expvalue,sum(o_trqty) as o_trqty,sum(o_trvalue) as o_trvalue ":"").' FROM ('.$list_query.') src GROUP BY itemId';
					}
					if (!empty($params['zeroStocks'])) { // exclude zero stocks items only in current stock
						$list_query.=" HAVING opqty+iqty-oqty<>0";
					}
				}
				$list_query .= " ORDER BY " . $params['order_by'] . " " . $params['direction'];
				// page limit
				if (empty($params['export_type']) && empty($params['closing'])) {
					$list_query .= " limit " . $from . ',' . $page_limit;
				}

				$list_query = $this->db->query($list_query);
				$result['items'] = $list_query->result_array();
				if (!empty($params['closing'])) {
					return $result['items'];
				}
			} else {
				
				//average purchase return for mfj
				$query = 'select Round(sum(if(bqty > 0, bqty,0)),3) as bqty,round((sum(bvalue) / sum(if(bqty > 0, bqty,0))),2) as bNewValue
				from (select ' . $select . $union . ' ';
				if(isset($params['branch']))
					$query .= "group by locId,itemId";
				else 
					$query .= "group by locId,itemId";
				if (!empty($params['show_attrs'])) {
					$query .= ",itemAttrId";
				}
				if (!empty($params['zeroStocks'])) { // exclude zero stocks items only in current stock
					$query.=" HAVING opqty+iqty-oqty<>0";
				}
				$query .= ') stkTable';
				$query = $this->db->query($query);
				return $query->row_array();
			}
		}
		

		if (!$from && !$ispurRate) { // get total
			// $query = 'select Round(sum(if(opqty > 0, opqty,0)),3) as opqty,round(sum(opvalue),2) as opvalue,
			// Round(sum(if(iqty > 0, iqty,0)),3) as iqty,round(sum(ivalue),2) as ivalue,
			// Round(sum(if(oqty > 0, oqty,0)),3) as oqty,round(sum(ovalue),2) as ovalue,
			// Round(sum(if(bqty > 0, bqty,0)),3) as bqty,round(sum(bvalue),2) as bvalue
			if(!get_user_data('isAdmin') && !get_user_data('isAccountant') && get_user_data('isSale')){
				$query = 'select Round(sum(ifnull(opqty,0)),3) as opqty,0 as opvalue,
							Round(sum(ifnull(iqty,0)),3) as iqty,round(sum(ivalue),2) as ivalue,
							Round(sum(ifnull(oqty,0)),3) as oqty, 0 as ovalue,';
				if(!empty($params['isDetail'])) {
					$query .= 'Round(sum(ifnull(i_purqty, 0)), 3) as i_purqty,round(sum(i_purvalue), 2) as i_purvalue,
								Round(sum(ifnull(i_salretqty, 0)), 3) as i_salretqty,round(sum(i_salretvalue), 2) as i_salretvalue,
								Round(sum(ifnull(i_manfqty, 0)), 3) as i_manfqty,round(sum(i_manfvalue), 2) as i_manfvalue,
								Round(sum(ifnull(i_trqty, 0)), 3) as i_trqty,round(sum(i_trvalue), 2) as i_trvalue,
								Round(sum(ifnull(o_salqty, 0)), 3) as o_salqty,0 as o_salvalue,
								Round(sum(ifnull(o_purretqty, 0)), 3) as o_purretqty,0 as o_purretvalue,
								Round(sum(ifnull(o_consqty, 0)), 3) as o_consqty,0 as o_consvalue,
								Round(sum(ifnull(o_expqty, 0)), 3) as o_expqty,0 as o_expvalue,
								Round(sum(ifnull(o_trqty, 0)), 3) as o_trqty,0 as o_trvalue,';
				}
				$query .= 'Round(sum(ifnull(bqty,0)),3) as bqty, 0 as bvalue';
			} else if (!get_user_data('isAdmin') && !get_user_data('isAccountant') && get_user_data('isPurchase')){
				$query = 'select Round(sum(ifnull(opqty,0)),3) as opqty,0 as opvalue,
						Round(sum(ifnull(iqty,0)),3) as iqty, 0 as ivalue,
						Round(sum(ifnull(oqty,0)),3) as oqty,round(sum(ovalue),2) as ovalue,';
				if(!empty($params['isDetail'])) {
					$query .= 'Round(sum(ifnull(i_purqty, 0)), 3) as i_purqty,0 as i_purvalue,
							Round(sum(ifnull(i_salretqty, 0)), 3) as i_salretqty,0 as i_salretvalue,
							Round(sum(ifnull(i_manfqty, 0)), 3) as i_manfqty,0 as i_manfvalue,
							Round(sum(ifnull(i_trqty, 0)), 3) as i_trqty,0 as i_trvalue,
							Round(sum(ifnull(o_salqty, 0)), 3) as o_salqty,0 as o_salvalue,
							Round(sum(ifnull(o_purretqty, 0)), 3) as o_purretqty,round(sum(o_purretvalue), 2) as o_purretvalue,
							Round(sum(ifnull(o_consqty, 0)), 3) as o_consqty,round(sum(o_consvalue), 2) as o_consvalue,
							Round(sum(ifnull(o_expqty, 0)), 3) as o_expqty,round(sum(o_expvalue), 2) as o_expvalue,
							Round(sum(ifnull(o_trqty, 0)), 3) as o_trqty,round(sum(o_trvalue), 2) as o_trvalue,';
				}
				$query .= 'Round(sum(ifnull(bqty,0)),3) as bqty,0 as bvalue';
			} else {
				$query = 'select Round(sum(ifnull(opqty,0)),3) as opqty,round(sum(opvalue),2) as opvalue,Round(sum(ifnull(iqty,0)),3) as iqty,round(sum(ivalue),2) as ivalue,Round(sum(ifnull(oqty,0)),3) as oqty,round(sum(ovalue),2) as ovalue,';
				if(!empty($params['isDetail'])) {
					$query .= 'Round(sum(ifnull(i_purqty, 0)), 3) as i_purqty,round(sum(i_purvalue), 2) as i_purvalue,
								Round(sum(ifnull(i_salretqty, 0)), 3) as i_salretqty,round(sum(i_salretvalue), 2) as i_salretvalue,
								Round(sum(ifnull(i_manfqty, 0)), 3) as i_manfqty,round(sum(i_manfvalue), 2) as i_manfvalue,
								Round(sum(ifnull(i_trqty, 0)), 3) as i_trqty,round(sum(i_trvalue), 2) as i_trvalue,
								Round(sum(ifnull(o_salqty, 0)), 3) as o_salqty,round(sum(o_salvalue), 2) as o_salvalue,
								Round(sum(ifnull(o_purretqty, 0)), 3) as o_purretqty,round(sum(o_purretvalue), 2) as o_purretvalue,
								Round(sum(ifnull(o_consqty, 0)), 3) as o_consqty,round(sum(o_consvalue), 2) as o_consvalue,
								Round(sum(ifnull(o_expqty, 0)), 3) as o_expqty,round(sum(o_expvalue), 2) as o_expvalue,
								Round(sum(ifnull(o_trqty, 0)), 3) as o_trqty,round(sum(o_trvalue), 2) as o_trvalue,';
				}
				$query .= 'Round(sum(ifnull(bqty,0)),3) as bqty,round(sum(bvalue),2) as bvalue';
			}			
			$query .=' from (select ' . $select . $union . ' ';
			if(isset($params['branch'])) {
				$query .= "group by locId,itemId";
			}
			else {
				$query .= "group by locId,itemId";
			}
			 if (sal_mod_active(CATE_ATTR)) {
				$query .= ",itemAttrId";
			}
			 if (!empty($params['zeroStocks'])) { // exclude zero stocks items only in current stock
				$query.=" HAVING (opqty+iqty-oqty)<>0";
			}
			$query .= ') stkTable';
			$query = $this->db->query($query);
			$result['totals'] = $query->row_array();
		}
		if (!empty($params['show_attrs'])) {
			$params = array ('group_attr' => false, 'zeroStocks' => !empty($params['zeroStocks'])?true:false);
			$result = $this->get_attributes($result,$params,$page_limit?true:false,true);
		}
		
		return $result;
		
	}

	public function expiry_filter ($stock=false,$params=array()){
		$exp_date_filter = (!empty($params['expDateFilter'])) ? $params['expDateFilter'] : $params['expFilter'];
		if(empty($params['expFilter'])){
			$this->db->select('att.name as expDate', false);
			$this->db->select('attBatch.name as batchName', false);
		}
		$this->db->join('item_attr_link AS ial',($stock?'ial.itemAttrId=si.itemAttrId':'ial.itemAttrId=ti.itemAttrId'));
		$this->db->join('attributes AS att','att.attrId=ial.attrId');

		$this->db->join(''.$this->db->dbprefix("attributes_group").' AS atg','atg.attrGrpId=att.attrGrpId and atg.grpCode="ED" and '.($stock?'atg.cId=se.cid':'atg.cId=t.cid'));
		$this->db->join('(Select ialB.itemAttrId, attB.name from '.$this->db->dbprefix("item_attr_link").' AS ialB
		JOIN '.$this->db->dbprefix("attributes").' AS attB ON attB.attrId=ialB.attrId
		JOIN '.$this->db->dbprefix("attributes_group").' atgB on attB.attrGrpId=atgB.attrGrpId and atgB.grpCode ="BA" and atgB.cId='. $this->cId .') AS attBatch', ($stock?'attBatch.itemAttrId=si.itemAttrId':'attBatch.itemAttrId=ti.itemAttrId'),'left',false);
		$this->db->where('cast(att.name as Date) <',$exp_date_filter);
		$this->db->where("CAST(att.name AS DATE) IS NOT NULL");
	}


	public function reorder($params=array()) {
		$_code = 'RSTROR';
		$start_date = $end_date = $cur_date = gmdate('Y-m-d');
		get_financial_dates($cur_date, $start_date, $end_date);
		$rpType = !empty($params['rpType'])?$params['rpType']:'sal';

		$isTecho = ($rpType=='sal')?true:false;

		if (!empty($params['compCont'])) {
			$content = $params['compCont'] = json_encode($params['compCont']);
			if (empty($params['page']) || $params['page']==1) {
				$this->db->select('id')->from('compcontent');
				$this->db->where(array('cId' => $this->cId, 'contentCode' => $_code));
				$row = $this->db->get()->row_array();
				if ($row) {
					$this->db->where(array('cId' => $this->cId, 'id' => $row['id']));
					$this->db->update('compcontent', array('content' => $params['compCont']));
				} else {
					$this->db->insert('compcontent', array('cId' => $this->cId,'contentCode' => $_code,'content' => $params['compCont']));
				}
			}
		} else {
			$this->load->model("TransModel");
			$compCont = $this->TransModel->get_compcontent($_code);
			if (!$compCont) {
				$compCont = array(array('content' => '{"obo":{"oboDays":14}}'));
			}
			$content = $compCont[0]['content'];			
		}

		if (!$content) {
			return array();
		}
		$content = json_decode($content,true);

		$result = array();
		if (!$isTecho) {
			$config =  $content[$rpType];
			
			// query start
			$this->db->from('trans as rr_t');
			$this->db->join('trans_items as rr_ti','rr_t.id=rr_ti.transid');
			$this->db->join('items as rr_it','rr_ti.itemId=rr_it.itemid');
			$this->db->join('items_cur as rr_icur','rr_icur.itemId=rr_it.itemid and rr_t.cid=rr_icur.cid and rr_icur.bid=rr_t.bid','left');
			$this->db->join('itemrelunits as rr_itr','rr_itr.itemId=rr_ti.itemId and rr_itr.relUnitName=rr_ti.unit','left');
			$this->db->where(array(
				'rr_t.cId' 	=> $this->cId,
				// 'rr_it.type' 	=> 'G',
				'rr_it.isInventory' => 1
			));
			$this->db->where_not_in('rr_t.status', $this->config->item('ignore_status'));
			$this->db->where_in('rr_t.tType',array(SALINV,SALRETAIL,DBNOTE));
			if (!empty($params['itemId'])) {
				$this->db->where('rr_it.itemId',$params['itemId']);
			}
			if (!empty($params['conId'])) {
				$this->db->where('rr_t.conId',$params['conId']);
			}
			$this->db->group_by('rr_it.itemId');
			
			switch ($rpType) {
				case 'obo':
					$range_cnt 	= 3;
					$oboDays = !empty($config['oboDays'])?$config['oboDays']:14;
					
					$ranges 	= array();
					$end_date 	= $cur_date;
					// y1,y2 ...
					for($i=$range_cnt;$i>0;$i--) {
						$col = 'y'.$i;
						$from_date = date('Y-m-d',strtotime($end_date. ' -'.$oboDays.' days'));
						$ranges[$col] = "sum(if(rr_t.tdate > '".$from_date."' and rr_t.tdate <= '".$end_date."', (rr_ti.qty+rr_ti.freeQty) * if(rr_itr.convFactor, rr_itr.convFactor, 1),0)) as ".$col;
						$end_date = $from_date;
					}
					
					$this->db->select('rr_ti.itemId,rr_it.name,CEILING(sum((rr_ti.qty+rr_ti.freeQty) * if(rr_itr.convFactor, rr_itr.convFactor, 1)) * ('.$oboDays.'/90)) as avgExpsal,ifnull(rr_icur.curStk,0) as cl_qty',false);
					$this->db->select(implode(',',$ranges),false);
					$start_date = 	date('Y-m-d',strtotime($cur_date. ' -'.max($oboDays*$range_cnt,90).' days'));
					$this->db->where(array(
						'rr_t.tDate >='	=> $start_date,
						'rr_t.tDate <='	=> $cur_date)
					);
					$query1 = $this->db->get_compiled_select();

					//((y1+y2+y3)/3)
					$avg = '(('.implode('+',array_keys($ranges)).')/'.$range_cnt.')';

					$query = 'select t.itemId,t.name as itemName, t.cl_qty,CEILING(if((slope * '.($range_cnt+1).') + interc > 0 AND (y1>0 AND y2>0 AND y3>0),(slope * '.($range_cnt+1).') + interc, avgExpsal)) as to_order,ror.so_qty,ror.po_qty from '
					.'(select *, ((-1 * (y1-'.$avg.'))  + (1 * (y3-'.$avg.')))/2 as slope, '.$avg.' - (2 *  ((-1 * (y1-'.$avg.'))  + (1 * (y3-'.$avg.')))/2) as interc from ('
					.$query1.') as t)  as t';

					// $tmp_items = $this->db->query($query)->result_array();
					break;

				case 'cal':
					// Reorder Quantity = Avg Sale per day X (Reorder days + buffer days) X (1 + Expected Growth) - Current Stock
					$reOrdDays = !empty($config['reOrdDays'])?$config['reOrdDays']:14;
					$basSales = !empty($config['basSales'])?$config['basSales']:14;
					$consDays = !empty($config['consDays'])?$config['consDays']:90;
					$expGrowth = !empty($config['expGrowth'])?$config['expGrowth']:0;
					$delBuffer = !empty($config['delBuffer'])?$config['delBuffer']:0;
					$reOrdDays = $reOrdDays + $delBuffer; //ReOrdDays=ReOrdDays+Buffer

					$end_date 	= $cur_date;
					$from_date = date('Y-m-d',strtotime($cur_date. ' -'.$consDays.' days'));

					$this->db->select('rr_it.itemId, rr_it.name as itemName');
					$this->db->select("CEILING(sum(if(rr_t.tdate > '".$from_date."' and rr_t.tdate <= '".$cur_date."', (rr_ti.qty+rr_ti.freeQty) * if(rr_itr.convFactor, rr_itr.convFactor, 1),0)) * ($reOrdDays/$basSales)) as spExpsal",false);
					$this->db->select("CEILING(sum((rr_ti.qty+rr_ti.freeQty) * if(rr_itr.convFactor, rr_itr.convFactor, 1)) * ($reOrdDays/$consDays)) as avgExpsal",false);
					$this->db->select("ifnull(rr_icur.curStk,0) as cl_qty",false);
					$start_date = 	date('Y-m-d',strtotime($cur_date. ' -90 days'));
					$this->db->where(array(
						'rr_t.tDate >='	=> $start_date,
						'rr_t.tDate <='	=> $cur_date)
					);
					$query1 = $this->db->get_compiled_select();

					$query = 'select t.itemId,t.itemName, t.cl_qty, ROUND(if(spExpSal > 0,spExpSal,avgExpSal)  * (1+'.$expGrowth.'/100),2) as to_order,ror.so_qty,ror.po_qty from ('.$query1.') as t';
					// $tmp_items = $this->db->query($query)->result_array();
					break;
			}

			$params['from_date'] 	= $start_date;
			$params['to_date'] 		= $cur_date;
			// sales & purchase order query
			$this->db->select('it.itemId,if(it.name!="",it.name,ti.itemName) as itemName,it.SKU', false);
			$this->db->select('sum(IF(t.tType IN ("' . SALORD . '"), (ti.qty+ti.freeQty-ifnull(ref.qty2,0)), 0) * if(itr.convFactor, itr.convFactor, 1)) as so_qty', false);
			$this->db->select('sum(IF(t.tType IN ("' . PURORD . '"), (ti.qty+ti.freeQty-ifnull(ref.qty2,0)), 0) * if(itr.convFactor, itr.convFactor, 1)) as po_qty', false);
			if (!empty($params['catColumn'])) {
				// $this->db->select('group_concat(distinct c.name) as catName');
				$this->db->select('ic.name as catName');
			}
			$this->from($params,false,true);
			$params['stk_type'] = 'reorder';
			$this->trans_where($params);
			$this->db->join('(select ref_t.tType,ref_ti.transId,sum(ifnull(ref_ti.qty,0)+ifnull(ref_ti.freeQty, 0)) as qty2,ref_ti.refTitemId from '.$this->db->dbprefix("trans").' as ref_t join '.$this->db->dbprefix("trans_items").' as ref_ti on ref_ti.transId=ref_t.id group by ref_ti.refTitemId) as ref','ref.refTitemId=ti.id and  ref.tType IN ("SH","SI","GR","PI")','left');
			$this->db->where_in('t.status',array('S','R'));
			if(!empty($params['expDateFilter']) && empty($params['brachQty'])) {
				$this->expiry_filter(false,$params);
			}
			$this->db->group_by('it.itemId');
			$reorder_query = $this->db->get_compiled_select();

			$query .=' LEFT JOIN ('.$reorder_query.')  AS ror ON ror.itemId=t.itemId  order by itemName,itemId';
			if (empty($params['export_type']) && empty($params['transaction'])) {
				$page_limit = $this->config->item('page_limit');
				$params['page'] = !empty($params['page']) ? $params['page'] : '1';
				$from = ($params['page'] - 1) * $page_limit;
				$query.= " limit " . $from . ',' . $page_limit;
			}

			$tmp_items = $this->db->query($query)->result_array();

		} else {
			$tmp_items =   $this->tachometer($params);
		}

		$result =  array('compCont' => $content);
		$result['items'] = array();
		if ($tmp_items) {
			foreach($tmp_items as $key => $row) {
				$row['po_qty'] = (!empty($row['po_qty']))?$row['po_qty']:0;
				$row['so_qty'] = (!empty($row['so_qty']))?$row['so_qty']:0;

				if ($isTecho) {
					$row['nett_qty'] = $row['cl_qty'] + $row['po_qty'] - $row['so_qty'];
					$row['to_order'] = (!empty($row['stkLevel']))?$row['stkLevel']-$row['nett_qty']:0;
					$row['to_order'] = $row['to_order']>=0?$row['to_order']:0;
					$row['stkLevel'] = (float)$row['stkLevel'];
					$row['nett_qty'] = (float)$row['nett_qty'];
				}

				$row['cl_qty'] = (float)$row['cl_qty'];				
				$row['so_qty'] = (float)$row['so_qty'];
				$row['po_qty'] = (float)$row['po_qty'];				
				$row['to_order'] = (float)$row['to_order'];
				$result['items'][$key] = $row;
			}
		}
		
		return $result?$result:array('items' => array());

		$result['compCont'] = $content;		

		return $result;
	}
	public function new_reorder($params=array()) {

		$isitemeditPermission = true;
		if (
			get_user_data('roleCode') != 'A' && 
			isset(get_user_data('rights')['MNITM']['actionRights']) &&
			get_user_data('rights')['MNITM']['actionRights'] != 3 && 
			get_user_data('rights')['MNITM']['actionRights'] != 4
		) {
		
			$isitemeditPermission = false;
		}
		$params['isitemeditPermission'] = $isitemeditPermission;
		$is_latest_server = $this->session->userdata('is_latest_server');
		$cur_date 	= gmdate('Y-m-d');
		$page_limit = $this->config->item('page_limit');
		$max_tDate = date('Y-m-d', strtotime('- '.$this->orderListRange.' months', strtotime(gmdate('Y-m-d'))));
		$branchId = isset($params['branch']) ? $params['branch'] : $this->bId;
		$isMainBranch = (float)$branchId == (float)get_company('mainbId');
// print_r($branchId);exit;
		$salesOrderQuery =$this->salesOrderQuery($max_tDate,$branchId);
		$purchaseOrderQuery =$this->purchaseOrderQuery($max_tDate,$branchId);
		$params['page'] = !empty($params['page']) ? $params['page'] : '1';
		$from = ($params['page'] - 1) * $page_limit;
		$limit = '';
		if(empty($params['f_type'])) {
			$limit = " LIMIT " . $from . ',' . $page_limit;
		}
		if(!empty($params['ignoreLimit'])) {
			$limit = "";
		}
		$isBOM = false;
		$salModCodes = get_company('salModCodes');
        $salModCodes = explode(',',$salModCodes);
		$isBOM = in_array('BM',$salModCodes);
		$sItemsStkQuery =$this->sItemsStockQuery($isBOM,$branchId,$params['page'],!empty($params['itemId']) ? $params['itemId'] : 0,$params);
		// print_r($sItemsStkQuery);
		// exit;
		if($is_latest_server) {
			$bomInnerQuery = "SELECT bmi.ItemId as mItemId,/* Times of Prod Needed Qty SO-Stk-PO / BOM Prod Qty */
			sum(ROUND((abs(bmi.qty) * IF(itbmi.convFactor, itbmi.convFactor, 1)) * (((pSO.soQty - GREATEST(IFNULL(itms.curStk, 0), 0) - IFNULL(pPO.poQty, 0)) / (bmp.qty * IF(itbmp.convFactor, itbmp.convFactor, 1)))),2)) AS mQty
			FROM " .$this->db->dbprefix('bom') ." AS bom 
			JOIN " .$this->db->dbprefix('bom_items') ." AS bmi ON bmi.bomid = bom.id AND bmi.pType = 'C'
			JOIN " .$this->db->dbprefix('bom_items') ." AS bmp ON bmp.bomid = bom.id AND bmp.pType = 'P'
			JOIN sItemsStk AS itms ON itms.itemId = bmp.itemId
			JOIN sSO AS pSO ON pSO.itemId = bom.itemId /* JOIN as SO is required. Not LEFT JOIN */
			LEFT JOIN ".$this->db->dbprefix('itemrelunits')." AS itbmi ON itbmi.itemId = bmi.itemId AND itbmi.relUnitName = bmi.unit
			LEFT JOIN ".$this->db->dbprefix('itemrelunits')." AS itbmp ON itbmp.itemId = bmp.itemId AND itbmp.relUnitName = bmp.unit
			LEFT JOIN sPO AS pPO ON pPO.itemId = bmp.itemId	where bom.bomType = 'P'	GROUP BY bmi.itemId";

			$childQuery = "SELECT i.itemId, i.itemName, i.sku, i.uom AS unit, " . ($isitemeditPermission ? "i.purchaseRate,i.saleRate" : "0 as purchaseRate,0 as saleRate") . " ,i.isOboLevel,i.minOrdQty,i.isPurchase, IFNULL(c.name, '') AS supName,
			IFNULL(i.curStk, 0) AS curStk,IFNULL(i.stkLevel, 0) AS stkLevel,IFNULL(po.poqty, 0) AS poQty,
			IFNULL(so.soqty, 0) AS soQty, IFNULL(prdSO.mQty, 0) AS psoQty,
			IFNULL(i.curStk, 0) + IFNULL(po.poqty, 0) - IFNULL(i.stkLevel, 0) - IFNULL(so.soqty, 0) - IFNULL(prdSO.mQty, 0) AS result,
			IFNULL(i.stkLevel, 0) + IFNULL(po.poqty, 0) + IFNULL(i.curStk, 0) + IFNULL(so.soqty, 0) + IFNULL(prdSO.mQty, 0) AS totalVal /* To display or hide */ 
			FROM sItemsStk AS i 			 
			LEFT JOIN " .$this->db->dbprefix('contacts') ." AS c  ON c.id = i.supConId
			LEFT JOIN sPO AS po ON po.itemId = i.itemid 
			LEFT JOIN sSO AS so ON so.itemId = i.itemid /* IF BOM get SO of Production Item Qty */
			LEFT JOIN (" . $bomInnerQuery .") AS prdSO ON prdSO.mItemId = i.itemId";
			$where = '';
			$whereMerge = "";
			// if(!empty($params['itemId'])) {
			// 	if(empty($where)) {
			// 		$where = ' WHERE ';
			// 	}
			// 	$where .= $whereMerge." i.itemId = ".$params['itemId'];
			// 	$whereMerge = " AND ";
			// } 
			if(!empty($params['conId'])) {
				if(empty($where)) {
					$where = ' WHERE ';
				}
				$where .= $whereMerge." i.supConId = ".$params['conId'];
				$where .= " OR EXISTS(SELECT 1 FROM " . $this->db->dbprefix('trans_items')." AS ti";
				$where .= " JOIN ".$this->db->dbprefix('trans'). " AS t ON ti.transId = t.id WHERE t.conId =".$params['conId']." AND ti.itemId=i.itemId AND t.tType IN ('PQ','PI','PR','EI','PE'))";
				$whereMerge = " AND ";
			} 
			if(!empty($params['includeStockAlert'])) {
				if(empty($where)) {
					$where = ' WHERE ';
				}
				$stockAlertQuery = "(SELECT 1 FROM ".$this->db->dbprefix('trans')." AS t 
				JOIN ".$this->db->dbprefix('trans_items')." AS ti ON t.id=ti.transid
				WHERE t.status NOT IN('D', 'X') AND
				t.tType IN('SI', 'SR', 'SD','SO','JO') AND
				t.cid=i.cid AND". (!$isMainBranch ? ' t.bId = i.bId AND'  : ''). " t.tDate >= DATE_SUB(CURDATE(),INTERVAL 1 DAY) AND
				ti.itemId=i.itemId UNION ALL SELECT 1
				FROM ".$this->db->dbprefix('stock_entries')." AS se
				JOIN  ".$this->db->dbprefix('stock_items')." AS si ON si.sId=se.id
				WHERE se.cid=i.cid AND". (!$isMainBranch ? ' se.locId = i.bId AND' : ''). " se.sDate >=  DATE_SUB(CURDATE(),INTERVAL 1 DAY) AND 
				si.qty < 0 AND si.itemId=i.itemId)";
				$where .= $whereMerge. ' EXISTS '.$stockAlertQuery;

			}

			$orderby = ' ORDER BY i.itemName ASC';
			$having = "";
			$havingJoin = "";
			if(!empty($params['isNegative'])) {
				if(empty($having)) {
					$having = " HAVING";
				}
				$having .= $havingJoin." result < 0";
				$havingJoin = ' AND';
			} 
			if(!empty($params['hideEmpty'])) {
				if(empty($having)) {
					$having = " HAVING";
				}
				$having .= $havingJoin." totalVal != 0";
				$havingJoin = ' AND';
			} 
			$final_SO_query = "WITH sPO AS ( /* PO */". $purchaseOrderQuery ."), sSO AS ( /* SO */ ".$salesOrderQuery."), sItemsStk AS (".$sItemsStkQuery.")".$childQuery.$where.$having.$orderby. ($limit);
		} else {
			$bomInnerQuery = "SELECT bmi.ItemId as mItemId,/* Times of Prod Needed Qty SO-Stk-PO / BOM Prod Qty */
			sum(ROUND((abs(bmi.qty) * IF(itbmi.convFactor, itbmi.convFactor, 1)) * (((pSO.soQty - GREATEST(i.curStk + IFNULL(icur.curStk, 0), 0) - IFNULL(pPO.poQty, 0)) / (bmp.qty * IF(itbmp.convFactor, itbmp.convFactor, 1)))),2)) AS mQty
			FROM " .$this->db->dbprefix('bom') ." AS bom 
			JOIN " .$this->db->dbprefix('bom_items') ." AS bmi ON bmi.bomid = bom.id AND bmi.pType = 'C'
			JOIN " .$this->db->dbprefix('bom_items') ." AS bmp ON bmp.bomid = bom.id AND bmp.pType = 'P'
			JOIN " .$this->db->dbprefix('items') ." AS i ON i.itemId = bmp.itemId
			LEFT JOIN (SELECT  ic.itemId, sum(ic.curstk) AS curstk FROM ".$this->db->dbprefix('items_cur') . " AS ic JOIN ".$this->db->dbprefix('contacts') ." AS c ON c.id = ic.bId
			and c.csType = 'L' AND c.bId = ". $branchId ." GROUP BY ic.itemId) AS icur ON icur.itemId = i.itemId
			JOIN ( /* SO */ ".$salesOrderQuery."  /* SO END */) AS pSO ON pSO.itemId = bom.itemId
			LEFT JOIN ".$this->db->dbprefix('itemrelunits')." AS itbmi ON itbmi.itemId = bmi.itemId AND itbmi.relUnitName = bmi.unit
			LEFT JOIN ".$this->db->dbprefix('itemrelunits')." AS itbmp ON itbmp.itemId = bmp.itemId AND itbmp.relUnitName = bmp.unit
			LEFT JOIN ( /* PO */". $purchaseOrderQuery ."/* PO END */) AS pPO ON pPO.itemId = bmp.itemId WHERE bom.bomType = 'P' GROUP BY bmi.itemId";

			$childQuery = "SELECT i.itemId, i.name AS itemName , i.sku, i.uom AS unit, " . ($isitemeditPermission ? " i.purchaseRate,i.saleRate " : "0 as purchaseRate ,0 as saleRate") . " ,i.isOboLevel,i.minOrdQty,i.isPurchase,
			".($isMainBranch || $branchId == -1  ? 'i.curStk' : 'IFNULL(i_cur.curStk, 0)')." +  IFNULL(icur.curStk, 0) as curStk,IFNULL(". ($isMainBranch || $branchId == -1  ? 'i.stkLevel' : 'i_cur.stkLevel') .", 0) AS stkLevel,IFNULL(po.poqty, 0) AS poQty,
			IFNULL(so.soqty, 0) AS soQty, IFNULL(prdSO.mQty, 0) AS psoQty,
			IFNULL(".($isMainBranch || $branchId == -1  ? 'i.curStk' : 'IFNULL(i_cur.curStk, 0)')." + IFNULL(icur.curStk, 0), 0) + IFNULL(po.poqty, 0) - IFNULL(". ($isMainBranch || $branchId == -1  ? 'i.stkLevel' : 'i_cur.stkLevel') .", 0) - IFNULL(so.soqty, 0) - IFNULL(prdSO.mQty, 0) AS result,
			IFNULL(". ($isMainBranch || $branchId == -1  ? 'i.stkLevel' : 'i_cur.stkLevel') .", 0) + IFNULL(po.poqty, 0) + IFNULL(i.curStk + IFNULL(icur.curStk, 0), 0) + IFNULL(so.soqty, 0) + IFNULL(prdSO.mQty, 0) AS totalVal /* To display or hide */ 
			FROM " .$this->db->dbprefix('items') ." AS i 
			". ($isMainBranch || $branchId == -1  ? '' : 'LEFT JOIN ob_items_cur AS i_cur ON i_cur.itemId = i.itemId AND i_cur.cId = '.$this->cId.' AND i_cur.bId ='.$branchId) ."
			LEFT JOIN (SELECT  ic.itemId, sum(ic.curstk) AS curstk FROM ".$this->db->dbprefix('items_cur') . " AS ic JOIN ".$this->db->dbprefix('contacts') ." AS c ON c.id = ic.bId
			and c.csType = 'L' AND c.bId = ". $branchId ." GROUP BY ic.itemId) AS icur ON icur.itemId = i.itemId
			LEFT JOIN ( /* PO */". $purchaseOrderQuery ."/* PO END*/) AS po ON po.itemId = i.itemid 
			LEFT JOIN ( /* SO */ ".$salesOrderQuery." /* SO END*/) AS so ON so.itemId = i.itemid /* IF BOM get SO of Production Item Qty */
			LEFT JOIN (" . $bomInnerQuery .") AS prdSO ON prdSO.mItemId = i.itemId";
			$where = ' WHERE i.isActive > 0 AND i.cId = '. $this->cId .' AND i.isInventory = 1 AND i.type = "G"';
			$whereMerge = " AND ";
			 if(!empty($params['itemId'])) {
				if(empty($where)) {
			 		$where = ' WHERE ';
			 	}
			 	$where .= $whereMerge." i.itemId = ".$params['itemId'];
			 	$whereMerge = " AND ";
			 } 
			if(!empty($params['conId'])) {
				if(empty($where)) {
					$where = ' WHERE ';
				}
				$where .= $whereMerge." i.supConId = ".$params['conId'];
				$where .= " OR EXISTS(SELECT 1 FROM " .$this->db->dbprefix('trans_items'). " AS ti";
				$where .= " JOIN ".$this->db->dbprefix('trans'). " AS t ON ti.transId = t.id WHERE t.conId =".$params['conId']." AND ti.itemId=i.itemId AND t.tType IN ('PQ','PI','PR','EI','PE'))";
				$whereMerge = " AND ";
			} 
			if(!empty($params['includeStockAlert'])) {
				if(empty($where)) {
					$where = ' WHERE ';
				}
				$stockAlertQuery = "(SELECT 1 FROM ".$this->db->dbprefix('trans')." AS t 
				JOIN ".$this->db->dbprefix('trans_items')." AS ti ON t.id=ti.transid
				WHERE t.status NOT IN('D', 'X') AND
				t.tType IN('SI', 'SR', 'SD','SO','JO') AND
				t.cid=i.cid AND". (!$isMainBranch ? ' t.bId = i.bId AND'  : ''). " t.tDate >= DATE_SUB(CURDATE(),INTERVAL 1 DAY) AND
				ti.itemId=i.itemId UNION ALL SELECT 1
				FROM ".$this->db->dbprefix('stock_entries')." AS se
				JOIN  ".$this->db->dbprefix('stock_items')." AS si ON si.sId=se.id
				WHERE se.cid=i.cid AND". (!$isMainBranch ? ' se.locId = i.bId AND' : ''). " se.sDate >=  DATE_SUB(CURDATE(),INTERVAL 1 DAY) AND 
				si.qty < 0 AND si.itemId=i.itemId)";
				$where .= $whereMerge. ' EXISTS '.$stockAlertQuery;

			}

			$orderby = ' ORDER BY i.name ASC';
			$having = "";
			$havingJoin = "";
			if(!empty($params['isNegative'])) {
				if(empty($having)) {
					$having = " HAVING";
				}
				$having .= $havingJoin." result < 0";
				$havingJoin = ' AND';
			} 
			if(!empty($params['hideEmpty'])) {
				if(empty($having)) {
					$having = " HAVING";
				}
				$having .= $havingJoin." totalVal != 0";
				$havingJoin = ' AND';
			} 
			$final_SO_query = $childQuery.$where.$having.$orderby. ($limit);

		}
		
		$query_list =	$this->db->query($final_SO_query);
		$result['items'] = $query_list->result_array();
		//echo $this->db->last_query();
		return $result;
		// $final_SO_query = 	


		
	}

	// public function new_reorder($params=array()) {

	// 	// $params['isNegative'] = 1;
	// 	// $params['supConId'] = 3;
	// 	// $params['includeStockAlert'] = 1;
	// 	$cur_date 	= gmdate('Y-m-d');
	// 	$page_limit = $this->config->item('page_limit');
	// 	$max_tDate = date('Y-m-d', strtotime('- '.$this->orderListRange.' months', strtotime(gmdate('Y-m-d'))));
	// 	$salesOrderQuery =$this->salesOrderQuery($max_tDate);
	// 	$purchaseOrderQuery =$this->purchaseOrderQuery($max_tDate);
	// 	$params['page'] = !empty($params['page']) ? $params['page'] : '1';
	// 	$from = ($params['page'] - 1) * $page_limit;
	// 	$limit = '';
	// 	if(empty($params['f_type'])) {
	// 		$limit = " LIMIT " . $from . ',' . $page_limit;
	// 	}		
	// 	$isBOM = false;
	// 	$salModCodes = get_company('salModCodes');
    //     $salModCodes = explode(',',$salModCodes);
	// 	$isBOM = in_array('BM',$salModCodes);
	// 	$sItemsStkQuery =$this->sItemsStockQuery($isBOM,$params['page']);
	// 	$branchId = $this->bId;

	// 	$bomInnerQuery = "SELECT bmi.ItemId as mItemId,/* Times of Prod Needed Qty SO-Stk-PO / BOM Prod Qty */
	// 	sum((abs(bmi.qty) * IF(itbmi.convFactor, itbmi.convFactor, 1)) * (((pSO.soQty - GREATEST(IFNULL(itms.curStk, 0), 0) - IFNULL(pPO.poQty, 0)) DIV (bmp.qty * IF(itbmp.convFactor, itbmp.convFactor, 1))) + if((pSO.soQty - GREATEST(IFNULL(itms.curStk, 0), 0) - IFNULL(pPO.poQty, 0)) MOD (bmp.qty * IF(itbmp.convFactor, itbmp.convFactor, 1)) > 0,1,0))) AS mQty 
	// 	FROM " .$this->db->dbprefix('bom') ." AS bom 
	// 	JOIN " .$this->db->dbprefix('bom_items') ." AS bmi ON bmi.bomid = bom.id AND bmi.pType = 'C'
	// 	JOIN " .$this->db->dbprefix('bom_items') ." AS bmp ON bmp.bomid = bom.id AND bmp.pType = 'P'
	// 	JOIN sItemsStk AS itms ON itms.itemId = bmp.itemId
	// 	JOIN sSO AS pSO ON pSO.itemId = bom.itemId /* JOIN as SO is required. Not LEFT JOIN */
	// 	LEFT JOIN ".$this->db->dbprefix('itemrelunits')." AS itbmi ON itbmi.itemId = bmi.itemId AND itbmi.relUnitName = bmi.unit
	// 	LEFT JOIN ".$this->db->dbprefix('itemrelunits')." AS itbmp ON itbmp.itemId = bmp.itemId AND itbmp.relUnitName = bmp.unit
	// 	LEFT JOIN sPO AS pPO ON pPO.itemId = bmp.itemId	where bom.bomType = 'P'	GROUP BY bmi.itemId";


	// 	$childQuery = "SELECT i.itemId, i.itemName, i.sku, i.uom AS unit,i.purchaseRate,i.isOboLevel,i.minOrdQty, IFNULL(c.name, '') AS supName,
	// 	IFNULL(i.curStk, 0) AS curStk,IFNULL(i.stkLevel, 0) AS stkLevel,IFNULL(po.poqty, 0) AS poQty,
	// 	IFNULL(so.soqty, 0) AS soQty, IFNULL(prdSO.mQty, 0) AS psoQty,
	// 	IFNULL(i.curStk, 0) + IFNULL(po.poqty, 0) - IFNULL(i.stkLevel, 0) - IFNULL(so.soqty, 0) - IFNULL(prdSO.mQty, 0) AS result,
	// 	IFNULL(i.stkLevel, 0) + IFNULL(po.poqty, 0) + IFNULL(i.curStk, 0) + IFNULL(so.soqty, 0) + IFNULL(prdSO.mQty, 0) AS totalVal /* To display or hide */ 
	// 	FROM sItemsStk AS i 
	// 	" .(empty($branchId) ? ''  : 'LEFT JOIN '.$this->db->dbprefix('items_cur') . ' AS itms ON itms.itemId = i.itemId')." 
	// 	LEFT JOIN " .$this->db->dbprefix('contacts') ." AS c  ON c.id = i.supConId
	// 	LEFT JOIN sPO AS po ON po.itemId = i.itemid 
	// 	LEFT JOIN sSO AS so ON so.itemId = i.itemid /* IF BOM get SO of Production Item Qty */
	// 	LEFT JOIN (" . $bomInnerQuery .") AS prdSO ON prdSO.mItemId = i.itemId";
	// 	$where = '';
	// 	$whereMerge = "";
	// 	if(!empty($params['itemId'])) {
	// 		if(empty($where)) {
	// 			$where = ' WHERE ';
	// 		}
	// 		$where .= $whereMerge." i.itemId = ".$params['itemId'];
	// 		$whereMerge = " AND ";
	// 	} 
	// 	if(!empty($params['conId'])) {
	// 		if(empty($where)) {
	// 			$where = ' WHERE ';
	// 		}
	// 		$where .= $whereMerge." i.supConId = ".$params['conId'];
	// 		$whereMerge = " AND ";
	// 	} 
	// 	if(!empty($params['includeStockAlert'])) {
	// 		if(empty($where)) {
	// 			$where = ' WHERE ';
	// 		}
	// 		$stockAlertQuery = "(SELECT 1 FROM ".$this->db->dbprefix('trans')." AS t 
	// 		JOIN ".$this->db->dbprefix('trans_items')." AS ti ON t.id=ti.transid
	// 		WHERE t.status NOT IN('D', 'X') AND
	// 		t.tType IN('SI', 'SR', 'SD','SO','JO') AND
	// 		t.cid=i.cid AND". (!empty($branchId) ? ' t.bId = i.bId AND'  : ''). " t.tDate >= DATE_SUB(CURDATE(),INTERVAL 1 DAY) AND
	// 		ti.itemId=i.itemId UNION ALL SELECT 1
	// 		FROM ".$this->db->dbprefix('stock_entries')." AS se
	// 		JOIN  ".$this->db->dbprefix('stock_items')." AS si ON si.sId=se.id
	// 		WHERE se.cid=i.cid AND". (!empty($branchId) ? ' se.locId = i.bId AND' : ''). " se.sDate >=  DATE_SUB(CURDATE(),INTERVAL 1 DAY) AND 
	// 		si.qty < 0 AND si.itemId=i.itemId)";
	// 		$where .= $whereMerge. ' EXISTS '.$stockAlertQuery;

	// 	}

	// 	$orderby = ' ORDER BY i.itemName ASC';
	// 	$having = "";
	// 	$havingJoin = "";
	// 	if(!empty($params['isNegative'])) {
	// 		if(empty($having)) {
	// 			$having = " HAVING";
	// 		}
	// 		$having .= $havingJoin." result < 0";
	// 		$havingJoin = ' AND';
	// 	} 
	// 	if(!empty($params['hideEmpty'])) {
	// 		if(empty($having)) {
	// 			$having = " HAVING";
	// 		}
	// 		$having .= $havingJoin." totalVal != 0";
	// 		$havingJoin = ' AND';
	// 	} 
	// 	$final_SO_query = "WITH sPO AS ( /* PO */". $purchaseOrderQuery ."), sSO AS ( /* SO */ ".$salesOrderQuery."), sItemsStk AS (".$sItemsStkQuery.")".$childQuery.$where.$having.$orderby. ($isBOM ? $limit : '');
	// 	// print_r($final_SO_query);
	// 	// exit;
	// 	$query_list =	$this->db->query($final_SO_query);
	// 	$result['items'] = $query_list->result_array();
	// 	return $result;
		
	// }

	
	public  function salesOrderQuery($tdate,$bId) {
        $salesOrderdeliveredQuery = $this->salesOrderdeliveredQuery();
        $this->db->select("p_ti.itemId, sum(((IFNULL(p_ti.qty,0)+IFNULL(p_ti.freeQty, 0))  * IF(itr.convFactor, itr.convFactor, 1))  - IFNULL(dt.recivQty,0)) AS soQty");
        $this->db->from('trans AS p_t');
        $this->db->join('trans_items AS p_ti','p_ti.transId=p_t.id');
        $this->db->join('itemrelunits AS itr','itr.itemId=p_ti.itemId AND itr.relUnitName=p_ti.unit','left');
        $this->db->join('(/* SO DELIVERED */'. $salesOrderdeliveredQuery .' ) AS dt','dt.refTransId=p_t.id and dt.refTitemId=p_ti.id','left');
        $this->db->where(array('p_t.tType'=>'SO','p_t.cid'=>$this->cId,'p_t.tDate >'=>$tdate));
		if (sal_mod_active(BRANCH_MOD)) {
			if($bId != -1) {
				$this->db->where('p_t.bId',$bId);
			}
		}
        $this->db->where_in('p_t.status', array('S','R'));
        $this->db->group_by('p_ti.itemId');
        return $this->db->get_compiled_select();
    }

	public function salesOrderdeliveredQuery() {
        $outwardtypes = array("SH", "SI", "SR", "SD");
        $this->db->select("d_trf.refTransId, d_ti.refTitemId,sum((IFNULL(d_ti.qty,0)+IFNULL(d_ti.freeQty, 0)) * IF(itr.convFactor, itr.convFactor, 1)) AS recivQty");
        $this->db->from('trans AS d_t');
        $this->db->join('trans_items AS d_ti','d_ti.transId=d_t.id');
        $this->db->join('trans_ref AS d_trf','d_trf.transId=d_t.id');
        $this->db->join('itemrelunits AS itr','itr.itemId=d_ti.itemId and itr.relUnitName=d_ti.unit','left');
        $this->db->where_in('d_t.tType',$outwardtypes);
        $this->db->group_by('d_ti.refTitemId');
        return $this->db->get_compiled_select();
    }

	public  function purchaseOrderQuery($tdate,$bId) {
        $purchaseOrderConsumedQuery = $this->purchaseOrderConsumedQuery();
        $this->db->select("p_ti.itemId, sum(((IFNULL(p_ti.qty,0)+IFNULL(p_ti.freeQty, 0))  * IF(itr.convFactor, itr.convFactor, 1))  - IFNULL(dt.recivQty,0)) AS poQty");
        $this->db->from('trans AS p_t');
        $this->db->join('trans_items AS p_ti','p_ti.transId=p_t.id');
        $this->db->join('itemrelunits AS itr','itr.itemId=p_ti.itemId AND itr.relUnitName=p_ti.unit','left');
        $this->db->join('(/* PO CONSUMED*/'. $purchaseOrderConsumedQuery .' ) AS dt','dt.refTransId=p_t.id and dt.refTitemId=p_ti.id','left');
        $this->db->where(array('p_t.tType'=>'PO','p_t.categoryCode !='=>'TL','p_t.cid'=>$this->cId,'p_t.tDate >'=>$tdate));
		if (sal_mod_active(BRANCH_MOD)) {
			if($bId != -1) {
				$this->db->where('p_t.bId',$bId);
			}
		}
        $this->db->where_in('p_t.status', array('S','R'));
        $this->db->group_by('p_ti.itemId');
        return $this->db->get_compiled_select();
    }

	public function purchaseOrderConsumedQuery() {
        $inwardypes = array("GR","PI","PR","EI","PE","PD");
        $this->db->select("d_trf.refTransId, d_ti.refTitemId,sum((IFNULL(d_ti.qty,0)+IFNULL(d_ti.freeQty, 0)) * IF(itr.convFactor, itr.convFactor, 1)) AS recivQty");
        $this->db->from('trans AS d_t');
        $this->db->join('trans_items AS d_ti','d_ti.transId=d_t.id');
        $this->db->join('trans_ref AS d_trf','d_trf.transId=d_t.id');
        $this->db->join('itemrelunits AS itr','itr.itemId=d_ti.itemId and itr.relUnitName=d_ti.unit','left');
        $this->db->where_in('d_t.tType',$inwardypes);
        $this->db->group_by('d_ti.refTitemId');
        return $this->db->get_compiled_select();
    }


	public function sItemsStockQuery($isBOM,$branchId,$pageNo = 0,$itemId = 0,$params =[]) {
		$isMainBranch = (float)$branchId == (float)get_company('mainbId');
		$innerJoin = '';
		$select = 'i.itemId, i.Name as itemName,i.SKU, i.uom,i.cId,i.isActive,i.isInventory,i.type,' . ($params['isitemeditPermission'] ? "i.purchaseRate,i.saleRate" : "0 as purchaseRate,0 as saleRate") . ',i.isOboLevel,i.isPurchase,';
		if($isMainBranch || $branchId == -1) {
			$select .= 'IFNULL(icur.curStk, 0) as curStk, i.supConId,i.stkLevel,i.minOrdQty';
			$innerJoin ='SELECT icur.itemId,sum(icur.curstk) AS curstk  FROM '. $this->db->dbprefix('items_cur').' AS icur JOIN '. $this->db->dbprefix('contacts') . ' AS c ON c.id = icur.bId and c.csType = "L" and c.bId = 0 GROUP BY itemId';
		} else {
			$select .= 'sum(IFNULL(icur.curStk,0)) as curStk, i_cur.supConId,i_cur.stkLevel,i_cur.minOrdQty';
		}
		$branchStockinnerQuery =  "SELECT itemId,sum(curStk) AS curStk, supConId AS supConId,stkLevel AS stkLevel,minOrdQty AS minOrdQty FROM(SELECT oi.itemId,oi.curStk,oi.supConId,oi.stkLevel,oi.minOrdQty FROM ".($isMainBranch || $branchId == -1 ? $this->db->dbprefix('items')  : $this->db->dbprefix('items_cur'))." as oi  WHERE oi.cId = ".$this->cId."".(($isMainBranch || $branchId == -1 ? "" : " AND oi.bId = ".$branchId."") ). " UNION ALL SELECT ic.itemId, ic.curStk,ic.supConId,ic.stkLevel,ic.minOrdQty FROM ". $this->db->dbprefix('items_cur')." AS ic JOIN ". $this->db->dbprefix('contacts') ." AS bc ON bc.id = ic.bId WHERE " .( !$isMainBranch && $branchId == -1 ? "" : " bc.csType = 'L' AND ")." bc.cId =".$this->cId."". (!$isMainBranch && $branchId == -1 ? '' : ( " AND bc.bId = ".$branchId)) .") AS u group by u.itemId";
		$this->db->select($select);
		$this->db->from('items AS i');
		if(!empty($params['catId'])){
			$this->db->join('items_category AS ict' ,' ict.itemId = i.itemId AND ict.cId = i.cId','left');
		}
		// if($isMainBranch) { 
			$this->db->join('('.$branchStockinnerQuery.') AS icur',' icur.itemId = i.itemId','left');
		// } else {
		// 	$this->db->join('items_cur AS icur','icur.itemId = i.itemId','left');
		// 	$this->db->join('contacts AS c','c.id = icur.bId ','left');
		// }
		if(!$isMainBranch && $branchId != -1) {
			$this->db->join('items_cur AS i_cur' ,' i_cur.itemId = i.itemId AND i_cur.cId = '.$this->cId.' AND i_cur.bId ='.$branchId,'left');
		}		
		$this->db->where(array('i.isActive >'=>0,'i.cId'=>$this->cId,'i.isInventory'=>1
		// ,'i.type'=>'G'
		));
		if(!empty($itemId)){
			$this->db->where('i.itemId',$itemId);
		}
		if(!empty($params['catId'])){
			$this->db->where_in('ict.catId',$params['catId']);
		}
		// if(!$isMainBranch) {
		// 	$this->db->group_start();
		// 	$this->db->where('icur.bId',$branchId);
		// 		$this->db->or_group_start();
		// 			$this->db->where('c.csType','L');
		// 			$this->db->where('c.bId',$branchId);
		// 		$this->db->group_end();
		// 	$this->db->group_end();	
		// }
		$this->db->group_by("i.itemId");
		// if(!$isBOM) {
		// 	$this->db->order_by('i.name');
		// 	$limit = '';
		// 	$page_limit = $this->config->item('page_limit');
		// 	$pageNo = !empty($pageNo) ? $pageNo : '1';
		// 	$from = ($pageNo - 1) * $page_limit;
		// 	if ($from) {
		// 		$this->db->limit($page_limit, $from);
		// 	} else {
		// 		$this->db->limit($page_limit);
		// 	}
		// }
		return $this->db->get_compiled_select();
		
	}

	public function tachometer($params=array()) {
		$result = array();
		// $params['to_date'] = $params['from_date'] = !empty($params['tDate'])?$params['tDate']:gmdate('Y-m-d');
		if (empty($params['from_date'])) {
			$params['to_date'] = $params['from_date'] = !empty($params['tDate'])?$params['tDate']:gmdate('Y-m-d');
		}
		$params['stk_type'] = !empty($params['stk_type'])?$params['stk_type']:'current';
		$params['stkAlert'] = isset($params['stkAlert'])?$params['stkAlert']:true;

		
		if (sal_mod_active(BRANCH_MOD) && !isset($params['branch'])) {
			$params['branch']=-1;
		}
		if(empty($params['itemId']) && !empty($params['itemName'])){
			$this->load->model("itemsModel");
			$params['itemId'] = $this->itemsModel->get_itemids($params['itemName']);
		}

		$this->trans_select($params);
		$this->db->select('0 as so_qty,0 as po_qty',false);
		$this->from($params,false,true);
		$this->trans_where($params);
		if(!empty($params['expDateFilter']) && empty($params['brachQty'])) {
			$this->expiry_filter(false,$params);
		}
		$trans_query = $this->db->get_compiled_select();	

		$this->stock_select($params);
		$this->db->select('0 as so_qty,0 as po_qty',false);
		$this->from($params,true);
		$this->stock_where($params);
		if(!empty($params['expDateFilter']) && empty($params['brachQty'])) {
			$this->expiry_filter(true,$params);
		}
		$stock_query = $this->db->get_compiled_select();
		 

		// reorder qty select similar to trans_select
		if ($params['stk_type']!='alert') {
			$this->db->select('ti.itemAttrId, 0 as pi_rate,IF(iar.saleRate IS NULL OR iar.saleRate = 0, it.saleRate, iar.saleRate) AS saleRate, IF(iar.mrp IS NULL OR iar.mrp = 0, it.mrp, iar.mrp) AS mrp,it.stkLevel',false);
		}
		$this->db->select('it.uom,0 as s_qty,0 as p_qty',false);
		$this->db->select('null as pur_qty',false);
		if (!empty($params['brachQty'])) {
			$this->db->select('it.itemId,ti.locId');
		} else {
			$this->db->select('it.itemId,if(it.name!="",it.name,ti.itemName) as itemName,it.SKU', false);
		}
		$this->db->select('sum(IF(t.ttype IN ("' . SALORD . '"), (ti.qty+ti.freeQty-ifnull(ref.qty2,0)), 0) * if(itr.convFactor, itr.convFactor, 1)) as so_qty', false);
		$this->db->select('sum(IF(t.ttype IN ("' . PURORD . '"), (ti.qty+ti.freeQty-ifnull(ref.qty2,0)), 0) * if(itr.convFactor, itr.convFactor, 1)) as po_qty', false);
		if (!empty($params['catColumn'])) {
			// $this->db->select('group_concat(distinct c.name) as catName');
			$this->db->select('ic.name as catName');
		}
		$this->from($params,false,true);
		$params['stk_type'] = 'reorder';
		$this->trans_where($params);
		$this->db->join('(select ref_t.tType,ref_ti.transId,sum(ifnull(ref_ti.qty,0)+ifnull(ref_ti.freeQty, 0)) as qty2,ref_ti.refTitemId from '.$this->db->dbprefix("trans").' as ref_t join '.$this->db->dbprefix("trans_items").' as ref_ti on ref_ti.transId=ref_t.id group by ref_ti.refTitemId) as ref','ref.refTitemId=ti.id and  ref.tType IN ("SH","SI","GR","PI")','left');
		$this->db->where_in('t.status',array('S','R'));
		if(!empty($params['expDateFilter']) && empty($params['brachQty'])) {
			$this->expiry_filter(false,$params);
		}
		$this->db->group_by('it.itemId');
		$reorder_query = $this->db->get_compiled_select();

		
		$query = $trans_query. ' UNION ALL '.$stock_query.' UNION ALL '.$reorder_query;
		
		$query = 'select itemId,ROUND(sum(p_qty-s_qty),3) as cl_qty,itemName,stkLevel,ROUND(sum(so_qty),3) as so_qty,ROUND(sum(po_qty),3) as po_qty,uom as unit  from ('.$query.')';
		$query.=' uniontable';
		if (!empty($params['conId'])) {
			$con_where = array();
			$this->db->select('DISTINCT it.itemId', false);
			$this->db->from('trans_items AS ti');
			$this->db->join('items AS it', 'it.itemId=ti.itemId');
			$this->db->join('trans AS t', 'ti.transid=t.id');
			$con_where['t.conId'] = $params['conId'];
			if (!empty($params['itemId'])) {
				// $where['it.itemId'] = $params['itemId'];
				$this->db->where_in('it.itemId', $params['itemId']);
			}
			$this->db->where($con_where);
			if (isset($params['branch'])) {
				user_branch_filter('t.bId', array($params['branch']));
			}
			if (!empty($params['item_type'])) {
				$this->db->where($params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase >', 0);
			}
			$query .= ' where itemId in (' . $this->db->get_compiled_select() . ') ';
		}
		$query .=' group by itemId';
		if (!empty($params['stkAlert']))
		{
			$query .=' HAVING stkLevel>0 and (cl_qty-so_qty+po_qty)<stkLevel';
		}


		$limit = '';
		if (empty($params['export_type']) && empty($params['transaction'])) {
			$page_limit = $this->config->item('page_limit');
			$params['page'] = !empty($params['page']) ? $params['page'] : '1';
			$from = ($params['page'] - 1) * $page_limit;
			$limit = " limit " . $from . ',' . $page_limit;
		}
		
		$query = $this->db->query($query.$limit);
		
		return $query->result_array();
		
		// if ($tmp) {
		// 	foreach($tmp as $key => $row) {
		// 		$row['nett_qty'] = $row['cl_qty'] + $row['po_qty'] - $row['so_qty'];

		// 		$row['to_order'] = (!empty($row['stkLevel']))?$row['stkLevel']-$row['nett_qty']:0;
		// 		$row['to_order'] = $row['to_order']>=0?$row['to_order']:0;
		// 		$row['cl_qty'] = (float)$row['cl_qty'];
		// 		$row['stkLevel'] = (float)$row['stkLevel'];
		// 		$row['so_qty'] = (float)$row['so_qty'];
		// 		$row['po_qty'] = (float)$row['po_qty'];
		// 		$row['nett_qty'] = (float)$row['nett_qty'];
		// 		$row['to_order'] = (float)$row['to_order'];
		// 		$result['items'][$key] = $row;
		// 	}
		// }
		
		// return $result?$result:array('items' => array());
	}
	
	
	// zeroStocks - show zero stock items
	public function alert($params) {
		$batchwise_stk = true;
		if (!empty($params['isStorage']))
		{
			$this->it_type = array('T');
		}
		if(empty($params['batchwise_stock'])){
			$batchwise_stk = false;
			$params['to_date'] = $params['from_date'] = !empty($params['tDate'])?$params['tDate']:(!empty($params['to_date'])?$params['to_date']:gmdate('Y-m-d'));
		}
		if(!empty($params['catIds'])) {
			$params['catIds'] = $this->get_child_category($params['catIds']);
		}
		$params['stk_type'] = !empty($params['stk_type'])?$params['stk_type']:'current';
		if (sal_mod_active(BRANCH_MOD) && !isset($params['branch'])) {
			$params['branch']=-1;
		}
		if(empty($params['itemId']) && !empty($params['itemName'])){
			$this->load->model("itemsModel");
			$params['itemId'] = $this->itemsModel->get_itemids($params['itemName']);
		}
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;

		$loc_required = !empty($params['mergType'])?true:false; //mergType used to merge
		if ($branch != -1) {
			if (empty($params['brachQty']) && !empty($params['transaction']) && (!empty($params['attrValues']) || !empty($params['locReq']))) {
				$loc_required = true;
			}
		}

		// if(!empty($params['attrSearchText'])) {
		// 	$this->db->select('ia.itemAttrId');
		// 	$this->db->from('item_attr as ia');
		// 	$this->db->join('item_attr_link as ial','ial.itemAttrId = ia.itemAttrId');
		// 	$this->db->join('attributes as a','a.attrId = ial.attrId');
		// 	$this->db->where('ia.cId',$this->cId);
		// 	if (!empty($params['itemId'])) {
		// 		$this->db->where_in('ia.itemId', $params['itemId']);
		// 	}
		// 	$this->db->like('a.name', $params['attrSearchText'], 'both');
		// 	$params['filterItemAttrId'] = $this->db->get()->result_array();
		// }
		
		// include currency code
		$isMulcur = !empty($params['transaction'])?true:false;

		if ($isMulcur)
		{
			$this->db->select('it.currencyCode');
		}
		$this->trans_select($params);
		//include location in select
		if ($loc_required)
		{
			$this->db->select('ti.locId');
			$this->db->group_by('ti.locId');
		}
		$this->from($params,false,true);
		$this->trans_where($params);
		if(!empty($params['expDateFilter']) && empty($params['brachQty'])) {
			$this->expiry_filter(false,$params);
		}
		$trans_query = $this->db->get_compiled_select();
		// print_r($trans_query);exit;

		if ($isMulcur)
		{
			$this->db->select('it.currencyCode');
		}
		$this->stock_select($params);
		//include location in select
		if ($loc_required)
		{
			$this->db->select('si.fromlocId as locId');
			$this->db->group_by('locId');
		}
		$this->from($params,true);
		$this->stock_where($params);
		if(!empty($params['expDateFilter']) && empty($params['brachQty'])) {
			$this->expiry_filter(true,$params);
		}
		$stock_query = $this->db->get_compiled_select();

		$st_params = $params;
		$st_params['isInward'] = true;
		if ($isMulcur)
		{
			$this->db->select('it.currencyCode');
		}
		$this->stock_select($st_params);
		//include location in select
		if ($loc_required)
		{
			$this->db->select('si.tolocId as locId');
			$this->db->group_by('locId');
		}
		$this->from($st_params,true);
		$this->stock_where($st_params);
		if(!empty($st_params['expDateFilter']) && empty($st_params['brachQty'])) {
			$this->expiry_filter(true,$st_params);
		}
		$stock_query.= ' UNION ALL '.$this->db->get_compiled_select();
		
		$stock_query_tl = '';		
		// if (empty($params['itemId']) && !empty($params['attrValues'])) { current stock item total with attributes 
		if (empty($params['transaction']) && !empty($params['attrValues'])) {
			// $query .=",itemAttrId";
			$hvg_attr = ($params['rpType']=='STC' || $params['rpType']=='STM')?'':' Having (itemAttrId != 0)'; // get othere count for current stock
			$trans_query = str_replace('ti.itemAttrId', '"-1" as itemAttrId', $trans_query) . ' UNION ALL ' . $trans_query . $hvg_attr;
			$stock_query = str_replace('si.itemAttrId', '"-1" as itemAttrId', $stock_query) . ' UNION ALL ' . $stock_query . $hvg_attr;
			if (!empty($stock_query_tl)) {
				$stock_query_tl = str_replace('si.itemAttrId', '"-1" as itemAttrId', $stock_query_tl) . ' UNION ALL ' . $stock_query_tl . $hvg_attr;
			}
		}
		
		$union = "$trans_query UNION ALL $stock_query ".($stock_query_tl?" UNION ALL $stock_query_tl ":'');
		
		if (empty($params['itemId']) && empty($params['zeroStocks']) && empty($params['expDateFilter'])) { // include zero stocks items
			$pur_qty = ',null as pur_qty';
			if ($params['stk_type']=='alert' || $params['stk_type']=='current') {
				if ($isMulcur)
				{
					$this->db->select('it.currencyCode');
				}
				$this->db->select('0 as itemAttrId, 0 as  pi_rate,saleRate,',false);
			}
			$this->db->select('0 as mrp, it.stkLevel,it.uom,0 as s_qty, 0 as  p_qty'.$pur_qty.', it.itemId, it.name AS itemName, it.SKU', false);
			if(!empty($params['attrValues']) && empty($params['transaction'])) {
				$this->db->select('"" AS batch');
			}
			if ($loc_required)
			{
				$this->db->select($this->bId.' as locId', false);
			}
			if (!empty($params['catColumn'])) {
				$this->db->select('group_concat(distinct c.name) as catName');
			}
			$this->db->from('items as it');
			$this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=it.itemId');
			$this->db->join('category AS c','c.id=ic.catId');
			if(!empty($params['catIds'])) {
				$cat_query = '(select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catIds'].')) sq_exis';
				$this->db->join($cat_query,'sq_exis.itemId = it.itemId');
			}
			$where = array('it.cId' => $this->cId);
			// if (!empty($params['brachQty'])) {
			// 	//$this->db->select('0 as locId', false);
			// 	$this->db->select('if(se.sType = "TL",si.toLocId,si.fromLocId) as locId');	
			// }
			if (!empty($params['item_type'])) {
				$where[$params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase >'] = 0;
			}
			$this->db->where($where);
			if (!empty($params['catColumn'])) {
				$this->db->group_by('it.itemId');
			}
			$union = $union . ' UNION ALL ' . $this->db->get_compiled_select();
		} // include zero stocks items

		

		$union = " from (".$union.") uniontable ";
		
		//OB: If filter items for Contact
		$con_query = '';
		if (!empty($params['conId'])) {
			$con_where = array();
			$this->db->select('DISTINCT it.itemId', false);
			$this->db->from('trans_items AS ti');
			$this->db->join('items AS it', 'it.itemId=ti.itemId');
			$this->db->join('trans AS t', 'ti.transid=t.id');
			$con_where['t.conId'] = $params['conId'];
			if (!empty($params['itemId'])) {
				// $where['it.itemId'] = $params['itemId'];
				$this->db->where_in('it.itemId', $params['itemId']);
			}
			$this->db->where($con_where);
			if (isset($params['branch'])) {
				user_branch_filter('t.bId', array($params['branch']));
			}
			if (!empty($params['item_type'])) {
				$this->db->where($params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase >', 0);
			}
			$union .= ' where itemId in (' . $this->db->get_compiled_select() . ') ';
		}

		$curStk = '';		
		switch ($params['stk_type']) {
			case 'alert':
				$query = "select itemId,ROUND(sum(p_qty),3) as p_qty,ROUND(sum(s_qty),3) as s_qty,itemName,SKU";
				$query .= ",max(if(itemAttrId>0,mrp,0)) as mrp,ROUND(sum(pi_rate)/sum(p_qty),2) AS pi_rate,ROUND(stkLevel,3) AS stkLevel ".$union." group by itemId HAVING (p_qty-s_qty) <= stkLevel";			
			break;
	
			default:
				// $query = ",max(mrp) as mrp,itemAttrId ";
				$query = ",saleRate,max(if(itemAttrId>0,mrp,0)) as mrp,";
				if ($isMulcur) {
					$query.='currencyCode,';
				}
				if ($params['stk_type']=='current') {
					$query .="ROUND(sum(pi_rate)/sum(ifnull(pur_qty,p_qty)),2) AS pi_rate,";// sold qty added
				
				}
				
				$query .= (empty($params['attrValues'])?"-1 as itemAttrId":"itemAttrId ");
				
				if ($loc_required)
				{
					$query .= ",locId ";
				}
				
				if ($params['stk_type']=='current') {
					if(!empty($params['attrValues']) && empty($params['transaction']))
						$query .= ",batch";
				}
				if(!empty($params['batchwise_stock'])){
					$query .= ',rate';
				}
				// include category name
				if (!empty($params['catColumn'])) {
					$query .= ",catName";
				}
				$query.=$union." group by itemId ";
				if (!empty($params['attrValues'])|| (!empty($params['rpType']) && $params['rpType'] == 'STE')) {
					$query .= ",itemAttrId ";
				}
				if ($loc_required)
				{
					$query .= ",locId ";
				}
				if (empty($params['brachQty'])) {
					$newField = '';
					if(!empty($params['rpType']) && $params['rpType'] == 'STE') {
						$newField = ',expDate,batchName';
					}
					$query = "select itemId,uom,ROUND(sum(p_qty),3) as p_qty,ROUND(sum(s_qty),3) as s_qty,itemName,SKU ".$newField.$query;
				} else {
					$query = "select uom,locId,itemId,ROUND(sum(p_qty),3) as p_qty,ROUND(sum(s_qty),3) as s_qty,ROUND(sum(p_qty-s_qty),3) as qty ".$query.",locId ";
				}
		}		

		if (!empty ($params['prepared_query'])) {
			// stock category report average purchase rate
			return $query;
		}
		if(!empty($params['order_by'])){
			$query .= " ORDER BY " . $params['order_by'] . " " . $params['direction'];
		}
		$limit = '';
		if (empty($params['export_type']) && empty($params['itemExport']) && empty($params['transaction']) && !$batchwise_stk)
		{
			$page_limit = $this->config->item('page_limit');
			$params['page'] = !empty($params['page']) ? $params['page'] : '1';
			$from = ($params['page'] - 1) * $page_limit;
			if(empty($params['f_type']))
			{
				$limit = " limit " . $from . ',' . $page_limit;
			}
		}

		$cnt  = array();
		if(empty($params['aGrpCnt']))
		{
			$this->db->select("count(ag.attrGrpId) AS aGrpCnt, count(If(ag.fldType='E',1,NULL)) AS aSerCount", FALSE);
			$this->db->from("attributes_group AS ag");
			$this->db->where(array(
				"ag.cId" => $this->cId,
				"ag.isActive >=" => 1
			));

			if (!empty($params["itemId"]))
			{
				if (!is_array($params["itemId"]))
				{
					$params["itemId"] = array($params["itemId"]);
				}

				$this->db->join("category_attrgrp AS ca", "ca.attrGrpId=ag.attrGrpId");
				$this->db->join("items_category AS ic", "ic.catId=ca.catId");
				$this->db->where_in("ic.itemId", $params["itemId"]);
			}

			$cnt = $this->db->get()->row_array();
		}
		else
		{
			$cnt['aGrpCnt'] = !empty($params['aGrpCnt']) ? $params['aGrpCnt'] : '';
			$cnt['aSerCount'] = !empty($params['aSerCount']) ? $params['aSerCount'] : '';
		}

		if(!empty($cnt['aGrpCnt']))
		{
			$result['aGrpCnt'] = $cnt['aGrpCnt'];
		}

		if(!empty($cnt['aSerCount']))
		{
			$result['aSerCount'] = $cnt['aSerCount'];
		}

		$attQuery = "";
		$curstk_att = '';

		if (!empty($result['aGrpCnt']))
		{
			//Atttributes Join
			$this->db->select("ita.itemAttrId as itaAttrId, GROUP_CONCAT(If (ag.fldType!='E', CONCAT(ag.Name , '\t', 
			if(ag.fldType = 'D',(CASE
				WHEN ag.format = 'd-m-Y' THEN DATE_FORMAT(a.name, '%d/%m/%Y')
				WHEN ag.format = 'm-d-Y' THEN DATE_FORMAT(a.name, '%m-%d-%Y')
				WHEN ag.format = 'MY' THEN DATE_FORMAT(a.name, '%b %Y')
			 	WHEN ag.format = 'FY' THEN DATE_FORMAT(a.name, '%M %Y')
				 ELSE DATE_FORMAT(a.name, '%d/%m/%Y')
			END ),a.name)),'')  ORDER BY ag.sortNo SEPARATOR '\n') as atList ");
			
			$this->db->from('item_attr as ita');
			$this->db->join('item_attr_link as ial', 'ial.itemAttrId=ita.itemAttrId');
			$this->db->join('attributes as a', 'a.attrId=ial.attrId');
			$this->db->join('attributes_group as ag', 'ag.attrGrpId=a.attrGrpId');
			$this->db->where("ita.cId",$this->cId);
			$this->db->group_by("ita.itemAttrId");

			if (isset($params["skipExpiryAttr"]) && $params["skipExpiryAttr"])
			{
				// Skip Expired attributes list
				$this->db->select("GROUP_CONCAT(If (ag.grpCode='ED' AND DATE(a.name) < NOW(), 'Y', '') SEPARATOR '') AS isExpired");
				$this->db->having("isExpired", "");
			}

			$attrSearchText = !empty($params['attrSearchText'])?trim($params['attrSearchText']):'';	
			$attQuery = $this->db->get_compiled_select();
			
		    if (!empty($params['stcklvl']) && $params['stcklvl']!='ALL')
		    {
				switch ($params['stcklvl'])
				{
					case 'zerostck':
					    $limit = ' having (p_qty - s_qty) = 0 '.$limit;
					break;
					case 'negativstck':
					    $limit = ' having (p_qty - s_qty) < 0 '.$limit;
					break;
					default:
						if (!isset($params['zeroStocks']) || $params['zeroStocks'])
						{
					    	$limit = ' having (p_qty - s_qty) > 0 '.$limit;
						}
					break;
				}
		    }

			if (!$attrSearchText)
		    {
		        // attribute search text empty left join attributes
		        $attQuery = " LEFT JOIN (".$attQuery.") ita on ita.itaAttrId=itms.itemAttrId";// ".$curstk_att."";
		    }
		    else
		    {
				$attQuery = " JOIN ( SELECT * FROM (".$attQuery.") atrflt having  atList like ('%". $attrSearchText . "%') ) ita on ita.itaAttrId=itms.itemAttrId";
			}
		}

		$serQuery = "";
		if(!empty($cnt['aSerCount']))
		{
			//Serial Attributes join
			$this->db->select('tias.itemAttrId as tiasItemAttrId, GROUP_CONCAT(CONCAT(ag.name,"\t",if (iasc.curStk>1 || iasc.curStk<0, CONCAT(tias.serialNo, " (", iasc.curStk, ") "), CONCAT(tias.serialNo))) ORDER BY iasc.curStk SEPARATOR "\n") as slList');
			$this->db->from('item_attr_serial as tias');
			$this->db->join('item_attr_link as ial', 'ial.itemAttrId=tias.itemAttrId');
			if (empty($params["asId"]))
			{
				$this->db->join('item_attr_serial_cur as iasc', 'iasc.asId=tias.id');
			}
			else
			{
				$this->db->join('item_attr_serial_cur as iasc', 'iasc.asId=tias.id', 'left');
			}
			$this->db->join('attributes as a', 'a.attrId=ial.attrId');
			$this->db->join('attributes_group as ag', 'ag.attrGrpId=a.attrGrpId AND ag.fldType="E"');
			$this->db->where("tias.cId",$this->cId);

			if (empty($params["asId"]))
			{
				if(isset($params['branch']))
				{
					$bw_map = $this->get_bw_map($params['branch'], $params);
					if (($bw_map))
					{
						$this->db->group_start();
						user_branch_filter('iasc.bId', $bw_map, false, true);
						$this->db->group_end();
					}
				}
				$this->db->where("iasc.curStk != ",0);
			}
			else
			{
				// print_R(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
			}

			$this->db->group_by("tias.itemAttrId");
			$serQuery = $this->db->get_compiled_select();
			$serQuery = " LEFT JOIN (".$serQuery.") ias on ias.tiasitemAttrId=itms.itemAttrId ";

			if(!empty($params['attrValues']) && !empty($params['rpType']) && $params['rpType'] == 'STC')
			{
				$serQuery .= " JOIN (SELECT @pstk:=0) r ";
			}

			if ($curstk_att)
			{
				$serQuery .= " " . $curstk_att;
			}

			if(empty($params['order_by']))
			{
				if (empty($params['transaction']) && (!empty($params['rpType'])) && ($params['rpType']=='STC' || $params['rpType']=='STM'))
				{
					$serQuery .= " order by itemName,itemAttrId".($loc_required?',locId':'')." asc";
				} else {
					$serQuery .= " order by itemId,itemAttrId".($loc_required?',locId':'')." asc";
				}
			}
		}
		else
		{
			$attQuery .= " " . $curstk_att;
		}

		/*$_cnt = $this->db->select("count(id) as cusCnt")->from("compfields")->where(array("cId" => $this->cId,"isActive" => 1,'tType' => "IT"))->get()->row_array();
		//Custom fields
		$this->db->select('fv.modId as ItemId, GROUP_CONCAT(CONCAT(f.fname,"\t",fv.fvalue) order by f.orderId SEPARATOR "\n") as cfList');
		$this->db->from('compfields as f');
		$this->db->join('field_values as fv', 'fv.fid=f.id');
		
	
		$this->db->where("fv.modType","I");
		$this->db->where("f.ttype","IT");
		$this->db->where("f.cId",$this->cId);
		$this->db->group_by("fv.modId");	
		$custQuery = $this->db->get_compiled_select();
		$custQuery = " LEFT JOIN (".$custQuery.") as cf on cf.itemId=itms.ItemId";*/
		$wholeSelect = "select itms.* ";
		if ($isMulcur)
		{
			$wholeSelect.=',currencyCode';
		}
		if(!empty($cnt['aGrpCnt']))
		{
			$wholeSelect .= ",IFNULL(ita.atList,'') as atList ";
		}

		if(!empty($cnt['aSerCount']))
		{
			$wholeSelect .= ",IFNULL(ias.slList,'') as slList ";
		}

		if(!empty($params['attrValues']) && !empty($params['stk_type']) && $params['stk_type'] == "current" && empty($params['transaction']))
			$wholeSelect .= ",batch as batchSKU";

		if(!empty($params['attrValues']) && !empty($params['rpType']) && $params['rpType'] == 'STC'){
			$wholeSelect .= ", if(itemAttrId = -1 ,  @pstk := itms.p_qty-itms.s_qty, abs( @pstk - itms.p_qty + itms.s_qty)  + itemAttrId ) as attrdisp ";
		}
		//if($_cnt['cusCnt'])
		//	$wholeSelect .= ",IFNULL(cf.cflist,'') as cfList";

		$list_query = $this->db->query($wholeSelect." from ( ".$query.$limit." ) itms ".$attQuery.$serQuery);
		//print_R($list_query);

		$result['items'] = $items = $list_query->result_array();
	//	print_R($result['items']);
		if (!empty($params['transaction'])) {
			// return if from transaction page
			return $items;
		}
		$bal_select = 'SELECT sum(p_qty - s_qty) AS totQty,sum((p_qty - s_qty) * pi_rate) as totValue FROM ('.$query.') src ';
		if(!empty($params['attrValues'])) {	
			$bal_select .= ' where src.itemAttrId != -1';
		}
		$bal_query = $this->db->query($bal_select);
		$result['totals'] = $bal_query->row_array();
		
		// group attribute quantity
		$group_attr = false;
		if (empty($params['brachQty']) && !empty($params['attrValues']) && !empty($params['group_attr'])) {
			$group_attr = true;
		}

		if (!empty($params['attrValues']) && $result['items']) {
			$ispdf = false;
			if(!empty($params['export_type'])){
				if($params['export_type'] == "pdf"){
					$ispdf = true;	
				}
			}
			if(!empty($params['batchwise_stock'])){
				$ispdf = true;
			}
			$is_current = ($params['stk_type'] == 'current' && empty($params['batchwise_stock'])) ? true : false;
			$params['group_attr'] = $group_attr;
			$params['curStk'] = $curStk;
			//$result = $this->get_attributes($result,$params,$limit?true:false,$ispdf,$is_current);
			
		}
		// print_R($result);
		return $result;
	}


	public function get_serial_attributes($params=array()) {
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;

		$this->db->select('sum(iasc.curStk) as curStk,tias.*');
		$this->db->from('item_attr_serial as tias');
		$this->db->join('item_attr_serial_cur as iasc','iasc.asId=tias.id');
		$this->db->where('iasc.cId',$this->cId);
		if (!empty($params['attr_ids']))
		{
			$this->db->where_in('tias.itemAttrId', $params['attr_ids']);
		}
		$bw_map = $this->get_bw_map($branch, $params);
		if ($bw_map) {
			$this->db->group_start();
			user_branch_filter('iasc.bId', $bw_map, false, true);
			$this->db->group_end();
		}
		$this->db->group_by('tias.id');

		return $this->db->get_compiled_select();
	}


	public function get_attributes($result, $params,$limit=false,$ispdf=false,$is_current=false)
	{
		if (empty($result['items']))
		{
			return $result;
		}

		$group_attr = !empty($params['group_attr'])?$params['group_attr']:false;
		$curStk 	= !empty($params['curStk'])?$params['curStk']:false;
		$itm_attr_ids = array();
		if ($limit) {
			foreach($result['items'] as $d_key=>$row)
			{
					if (!empty($row['itemAttrId'])) {
						$itm_attr_ids[$row['itemAttrId']] = $d_key;
					}
			}
		}
		
		if ($itm_attr_ids || !$limit) {
			$params['attr_ids'] = $itm_attr_ids?array_keys($itm_attr_ids):array();
			$slat_query  = $this->get_serial_attributes($params);
			$this->db->select('ita.itemAttrId, ita.sku, ita.saleRate, a.attrId, a.attrGrpId, ag.name, ag.grpCode, ag.fldType, ag.isPrint, ag.sortNo', false);
			$this->db->select('if(ag.fldType="E", GROUP_CONCAT(if (ias.curStk>1 || ias.curStk<0, CONCAT(ias.serialNo," (",ias.curStk,") "), CONCAT(ias.serialNo)) ORDER BY ias.curStk SEPARATOR ", "), a.name) AS text',false);
			//$this->db->select('a.name AS text',false);
			//$this->db->where(array('ag.fldType !=' => 'E'));
			$this->db->from('item_attr as ita');
			$this->db->join('item_attr_link as ial', 'ial.itemAttrId=ita.itemAttrId');
			$this->db->join('attributes as a', 'a.attrId=ial.attrId');
			$this->db->join('attributes_group as ag', 'ag.attrGrpId=a.attrGrpId', 'left');
			// $this->db->join('item_attr_serial as ias', 'ias.itemAttrId=ita.itemAttrId  '.($zeroStocks?' and ias.curStk!=0':''), 'left');
			$this->db->join('('.$slat_query.') as ias','ias.itemAttrId=ita.itemAttrId  '.($curStk?' and ias.curStk!=0':''), 'left');
			$this->db->where(array(
				'ita.cId' => $this->cId,
			));
			$this->db->group_by('ita.itemId,ita.itemAttrId,a.attrId');
			if ($limit) // if page limit applied
				$this->db->where_in('ita.itemAttrId', $params['attr_ids']);
			$tmp = $this->db->get()->result_array();
			// echo $this->db->last_query();exit;
			if ($tmp) {
				// $attr_values  = array();
				$attr_values = array(0 => array('Others'));
				foreach ($tmp as $row) {
					if (empty($attr_values[$row['itemAttrId']])) {
						$attr_values[$row['itemAttrId']] = [];
					}
					if ($row["fldType"] == "D") {
						$row["text"] = preg_replace("/(\d{4})-(\d{2})-(\d{2})/i", "$3/$2/$1", $row["text"]);
					}
					if($ispdf){
						$attr_values[$row['itemAttrId']][] = $row['name'] . ' : ' . $row['text'] ;
					}else{
						$attr_values[$row['itemAttrId']][] = $row['name'] . ' : ' . '<b>' . $row['text'] . '</b>';
					}
				}

				foreach ($result['items'] as $d_key => $row) {
					$result['items'][$d_key]['attrs'] = '';
					if (!empty($params['stock_opening']) && get_company("mrpInPurSal"))
					{
						if(!empty($row['mrp']))
						{
							$row['mrp'] = formatAmount($row['mrp'], get_company('currency'));
							$attr_values[$row['itemAttrId']]['MRP'] = 'MRP : ' . '<b>'.$row['mrp'].'</b>';
						}

						if(!empty($row['saleRate']))
						{
							$row['saleRate'] = formatAmount($row['saleRate'], get_company('currency'));
							$attr_values[$row['itemAttrId']]['SaleRate'] = 'SaleRate : ' . '<b>'.$row['saleRate'].'</b>';
						}
					}

					if (!$group_attr && !empty($attr_values[$row['itemAttrId']])) {
						$result['items'][$d_key]['attrs'] = implode("# ", $attr_values[$row['itemAttrId']]);
					}
					if ($group_attr && !empty($row['locqty'])) {
						$locqty = explode(',', $row['locqty']);
						unset($row['locqty']);
						$row['details'] = [];
						if ($locqty) {
							foreach ($locqty as $lkey => $lval) {
								$lval = explode(':', $lval); //itemattrid:qty
								$lval[0] = !empty($attr_values[$lval[0]]) ? implode(", ", $attr_values[$lval[0]]) : 'Others';
								$row['details'][] = $lval;
							}
						}
						$result['items'][$d_key] = $row;
					}
				}
			}
		}
		return $result;
	}

	public function details($params = array())
	{

		$where = array('t.cId' => $this->cId, 'ti.ItemId' => $params['itemId']);
		$where['t.tDate >='] = $params['from_date'];
		$where['t.tDate <='] = $params['to_date'];
		$where['it.isInventory'] = 1;
		$this->db->select('ti.transId AS id,ti.itemId,it.uom AS uom,
		CASE WHEN t.tType in ("' . SALINV . '","' . SALRETAIL . '","' . DBNOTE . '","' . PURCRNOTE . '") THEN ((ti.qty+ti.freeQty) * 
			if(itr.convFactor,itr.convFactor,1)) ELSE 0 end AS opqty,
		0 AS oqty, 0 AS iqty,t.tNo', false)->from('trans AS t');
		$this->db->join('trans_items AS ti', 'ti.transId=t.id');
		$this->db->join('items AS it', 'it.itemId=ti.itemId');
		$this->db->join('itemrelunits AS itr', 'itr.itemId=ti.itemId and itr.cId=ti.cId and itr.relUnitName=ti.unit', 'left');
		$this->db->where($where);
		$this->db->where_not_in('t.status', $this->config->item('ignore_status'));
		$this->db->where_not_in('t.tType', $this->non_stock_trans);
		$query1 = $this->db->get_compiled_select();

		$where = array('se.cId' => $this->cId, 'si.ItemId' => $params['itemId']);
		//$where['se.sDate <'] = $params['from_date'];
		$where['se.sDate >='] = $params['from_date'];
		$where['se.sDate <='] = $params['to_date'];
		$where['it.isInventory'] = 1;
		$this->db->select('se.id AS id,si.itemId,it.uom AS uom,
		 if(se.sType = "OP",if(itr.convFactor, si.qty*itr.convFactor, si.qty), 0) AS opqty,
		 if(si.qty < 0 && se.sType != "OP", -(if(itr.convFactor, si.qty*itr.convFactor, si.qty)),0 ) AS oqty,
		 if(si.qty > 0 && se.sType != "OP",if(itr.convFactor, si.qty*itr.convFactor, si.qty),0) AS iqty,
		 si.sId as tNo', false)->from('stock_entries AS se');
		$this->db->join('stock_items AS si', 'si.sId=se.id');
		$this->db->join('items AS it', 'it.itemId=si.itemId');
		$this->db->join('itemrelunits AS itr', 'itr.itemId=si.itemId and itr.relUnitName=si.unit and and itr.cId=se.cId', 'left');
		$this->db->where($where);
		$query2 = $this->db->get_compiled_select();

		$where = array('t.cId' => $this->cId, 'ti.ItemId' => $params['itemId']);
		$where['t.tDate >='] = $params['from_date'];
		$where['t.tDate <='] = $params['to_date'];
		$where['it.isInventory'] = 1;

		$this->db->select('ti.transId AS id,ti.itemId,t.tDate AS tdate, it.uom AS uom,t.tType,0 AS opqty, if(t.tType in ("' . SALINV . '","' . SALRETAIL . '","' . DBNOTE . '","' . PURCRNOTE . '"),if(itr.convFactor,ti.qty*itr.convFactor,ti.qty),0) AS oqty, if(t.tType in ("' . PURINV . '","'.PURRETAIL.'","' . CRNOTE . '","' . PURDBNOTE . '"),if(itr.convFactor,ti.qty*itr.convFactor,ti.qty),0) AS iqty,t.tNo', false)->from('trans AS t');
		// $this->db->select('t.tDate AS tdate, t.tType, if(t.tType like "S%",ti.qty,0) AS iqty, if(t.tType like "P%",ti.qty,0) AS oqty', false)->from('trans AS t');
		$this->db->join('trans_items AS ti', 'ti.transId=t.id');
		$this->db->join('items AS it', 'it.itemId=ti.itemId');
		$this->db->join('itemrelunits AS itr', 'itr.itemId=ti.itemId and itr.cId=ti.cId and itr.relUnitName=ti.unit', 'left');
		// $this->db->join('items AS ite', 'ite.itemId=ti.itemId');
		$this->db->where($where);
		$this->db->where_not_in('t.tType', $this->non_stock_trans);
		$query3 = $this->db->get_compiled_select();

		$where = array('se.cId' => $this->cId, 'si.ItemId' => $params['itemId']);
		$where['se.sDate >='] = $params['from_date'];
		$where['se.sDate <='] = $params['to_date'];
		$where['it.isInventory'] = 1;
		$this->db->select('se.id AS id,si.itemId,se.sDate as tdate,it.uom AS uom, se.sType AS tType,if(se.sType = "OP",if(itr.convFactor, si.qty*itr.convFactor, si.qty), 0) AS opqty, if(si.qty < 0 && se.sType != "OP",-(if(itr.convFactor, si.qty*itr.convFactor, si.qty)),0 ) AS oqty ,if(si.qty > 0 && se.sType != "OP",if(itr.convFactor, si.qty*itr.convFactor, si.qty),0) AS iqty,si.sId as tNo', false)->from('stock_entries AS se');
		$this->db->join('stock_items AS si', 'si.sId=se.id');
		$this->db->join('items AS it', 'it.itemId=si.itemId');
		$this->db->join('itemrelunits AS itr', 'itr.itemId=si.itemId and itr.relUnitName=si.unit and and itr.cId=se.cId', 'left');
		// $this->db->join('items AS ite', 'ite.itemId=si.itemId');
		$this->db->where($where);
		$query4 = $this->db->get_compiled_select();

		$query = $this->db->query("select sum(opqty) AS opqty  from ($query3 UNION ALL $query4) uniontable group by itemId");
		$tmp_balance = $query->row_array();
		$result['open'] = $tmp_balance['opqty'];

		$limit = 'limit';
		$page_limit = $this->config->item('page_limit');
		$params['page'] = !empty($params['page']) ? $params['page'] : '1';
		$from = ($params['page'] - 1) * $page_limit;

		$query = $this->db->query("select *  from ($query3 UNION ALL $query4) AS uniontable order by tdate limit " . $from . ',' . $page_limit);
		$result['items'] = $query->result_array();

		return $result;
	}
	public function batchwise_stock($params){
		$categories = array();
		$start_date = $end_date = $cur_date = gmdate('Y-m-d');
		get_financial_dates($cur_date, $start_date, $end_date);
		$where = array('ic.catId' => $params['catId'],'ic.cId' => $this->cId);
		$params['from_date'] = !empty($params['from_date']) ? $params['from_date'] : $start_date;
		$params['to_date'] = !empty($params['to_date']) ? $params['to_date'] : $start_date;
		$this->db->select('it.itemId', false)->from('items AS it');
		$this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=it.itemId');
		$this->db->where($where);
		$items = $this->db->get()->result_array();

		$result = array();
		$ids = array();
		foreach($items as $row){
			array_push($ids,$row['itemId']);
		}
		$params['rpType'] = 'STC';
		// $mod_codes = explode(',',get_company('salModCodes'));
		// if (in_array('IA',$mod_codes)) {
			$params['attrValues'] = true;
		// }
		$params['itemId'] = $ids;
		// $params['transaction'] = true;
		$params['validQty'] = true;
		$params['tDate'] = $params['to_date'];
		// $params['zeroStocks'] = true;
		// get current stock using
		if (sal_mod_active(BRANCH_MOD) && !isset($params['branch'])) {
			$params['branch'] = $this->bId;
		}
		$params['batchwise_stock'] = 1;
		$result_alert = $this->alert($params);
		$result_attrs = array();
		$attributeIds = array();

		$result['total']['p_qty'] =  0;
		$result['total']['s_qty'] =  0;
		$result['total']['b_qty'] =  0;
		$result['total']['amount'] =  0;
		foreach($result_alert['items'] as $item){
			if(isset($item['itemAttrId']) && $item['itemAttrId'] > 0){
				$result_attrs[$item['itemAttrId']] = $item;
				array_push($attributeIds,$item['itemAttrId']);
				$result['total']['p_qty'] +=  isset($item['p_qty']) ? $item['p_qty'] : 0;
				$result['total']['s_qty'] +=  isset($item['s_qty']) ? $item['s_qty'] : 0;
				$bal_current = abs((isset($item['p_qty']) ? $item['p_qty'] : 0) - (isset($item['s_qty']) ? $item['s_qty'] : 0));
				$result['total']['b_qty'] += $bal_current;
				$result['total']['amount'] += $bal_current * $item['rate'];
			}
		}
		if(empty($result_attrs)){
			return $result;
		}
		// $params['attr_ids'] = $attributeIds;
		$params['stk_type'] = "stock_ledger";
		
		$params['inward_details'] = $params['outward_details'] = true;
		unset($params['catId']);
		unset($params['rpType']);
		unset($params['attrValues']);
		unset($params['validQty']);
		// unset($params['itemId']);
		$result_summary = $this->summary($params);
		// print_r($result_summary);
		// exit;
		
		$attributeIds = array();
		$this->db->select('name', false)->from('attributes_group');
		$where = array('cId' => $this->cId);
		$this->db->where($where);
		$this->db->order_by('sortNo,attrGrpId','asc');
		$attributes_res = $this->db->get()->result_array();
		$attributes = array();
		foreach($attributes_res as $row){
			array_push($attributes,$row['name']);
		}
		
		$result_attributes = array();
		$is_res_attr_assinged = false;
		$current_item = 0;
		$current_arrtibid = 0;
		
		foreach($result_summary['items'] as $item){
			
			// exit;
			if(isset($item['itemAttrId']) && $item['itemAttrId'] > 0){
				$res_data = array();
				$item_details = $result_attrs[$item['itemAttrId']];
				$detail_itemId = $item_details['itemId'];
				$detail_attriId = $item_details['itemAttrId'];
				// print_r($detail_itemId);
				// echo $detail_itemId . ' : ' . $detail_attriId;
				// echo $item['itemAttrId'] . ' : ';
				if(isset($result_attrs[$item['itemAttrId']])){
					// echo $item['itemAttrId'];
					$cur_attr = $result_attrs[$item['itemAttrId']];
					if($current_item != $detail_itemId){
						$res_data['itemName'] = (isset($cur_attr['itemName'])) ? $cur_attr['itemName'] : '';
						$res_data['SKU'] = (isset($cur_attr['SKU'])) ? $cur_attr['SKU'] : '';
						$res_data['unit'] = (isset($item['unit'])) ? $item['unit'] : '';
						$current_item = $detail_itemId;
					}else{
						$res_data['itemName'] = '';
						$res_data['SKU'] = '';
						$res_data['unit'] = '';
					}
					
					if(isset($item_details['attrs'])){
						$itemattributes = explode('#',$item_details['attrs']);
						$arributes_data = array();
						foreach($itemattributes as $itm_atr){
							$tempattrb = explode(':',$itm_atr);
							if($current_arrtibid != $detail_attriId){
								$arributes_data[trim($tempattrb[0])] = trim($tempattrb[1]);
							}else{
								$arributes_data[trim($tempattrb[0])] = '';
							}
						}
						if($current_arrtibid != $detail_attriId){
							$res_data['p_qty'] = (isset($cur_attr['p_qty'])) ? (float)$cur_attr['p_qty'] : 0;
							$res_data['s_qty'] = (isset($cur_attr['s_qty'])) ? (float)$cur_attr['s_qty'] : 0;
							$res_data['b_qty'] = $res_data['p_qty'] - $res_data['s_qty'];
							$res_data['rate'] = (isset($item_details['rate'])) ? (float)$item_details['rate'] : 0;
							$res_data['amount'] = ($res_data['b_qty'] > 0) ? $res_data['b_qty'] * $res_data['rate'] : '';
								
						}else{
							$res_data['p_qty'] = '';
							$res_data['s_qty'] = '';
							$res_data['b_qty'] = '';
							$res_data['rate'] = '';
							$res_data['amount'] = '';
						}
						$current_arrtibid = $detail_attriId;
						foreach($attributes as $key => $att){
							if(isset($arributes_data[$att])){
								$res_data['attributes'][$att] = $arributes_data[$att];
								if(!$is_res_attr_assinged){
									if(!in_array($att,$result_attributes))
										array_push($result_attributes,$att);
								}
							}
						}
					}
					
					$res_data['conName'] = (isset($item['conName'])) ? $item['conName'] : '';
					$res_data['tDate'] = (isset($item['tDate'])) ? $item['tDate'] : '';
					$res_data['tType'] = (isset($item['tType'])) ? $item['tType'] : '';
					$res_data['tno'] = (isset($item['tno'])) ? $item['tno'] : '';
					$res_data['id'] = (isset($item['id'])) ? $item['id'] : '';
					$res_data['trans_rate'] = (isset($item['rate'])) ? (float)$item['rate'] : 0;
					$res_data['qty'] = (isset($item['iqty'])) ? (float)$item['iqty'] : 0;
					$res_data['qty'] -= (isset($item['oqty'])) ? (float)$item['oqty'] : 0;
					$res_data['qty'] = abs($res_data['qty']);
					$res_data['trans_amount'] = $res_data['trans_rate'] * $res_data['qty'];
					$res_data['isStock'] = (isset($item['isStock'])) ? $item['isStock'] : 0;
					$result['items'][] = $res_data;
					if(!empty($result_attributes) && !$is_res_attr_assinged){
						$result['attributes'] = $result_attributes;
						$is_res_attr_assinged = true;
					}
				}
			}

		}
		return $result;

	}
	public function category($params)
	{
		$params['catId'] = !empty($params['catId'])?$params['catId']:0;
		if (get_company('stkRate')=='F')
		{ 
			$this->db->select('*')->from('category');
			$where = array('cId' => $this->cId);
			$where['pId'] = $params['catId'];
			$this->db->where($where);
			$cats = $this->db->order_by('name','asc')->get()->result_array();

			$items = array();
			if (!empty($params['catId'])) {
				// prepare sall and sout query
				$query = $this->fifo_query($params);
				if($query) {
					$sAll 			= $query['sAll'];
					$sOut 			= $query['sOut'];
					$union_sall 	= $query['union_sall'];
					$opening_filter = $query['opening_filter'];
					$other_filter 	= $query['other_filter'];

					//round(sum(If (inValQty > 0 and expenseQty>=0, if (expenseQty=0, inValue, Round(expenseQty * (inValue/inValQty),2)),0)) ,2) as stockValue
					$query = 'WITH sAll AS ('.$sAll.'),sOUT AS ('.$sOut.')	
					SELECT "" as catId,id,name,uom,qty_hand,stockValue,0 AS isCat,"" AS SKU,round((stockValue/qty_hand),3) as rate,qty_hand,stockValue FROM (
					select   itemId as id,itemName as name,uom,unit,tDate,tType,inQty,outQty,
					round(sum(If ('.$opening_filter.', inQty - outQty, 0)),3) AS opqty, 
					round(sum(If ('.$opening_filter.', If (inValQty > 0, CASE WHEN opexpenseQty=0 then inValue WHEN opexpenseQty > 0 then opexpenseQty * (inValue/inValQty) End,0) ,0)) ,2) as opvalue,
					round(sum(If ('.$other_filter.', inQty, 0)),3) AS iqty, 
					round(sum(If ('.$other_filter.' and inQty > 0, inValue,0)) ,2) as ivalue,
					round(sum(If ('.$other_filter.', outQty, 0)),3) AS oqty, 
					round(sum(If ('.$other_filter.' and outQty > 0,outValue,0)) ,2) as ovalue,
					round(sum(inQty-outQty),3) AS qty_hand,
					round(sum(If (inValQty > 0 and inValue>=0 , if (expenseQty=0, inValue, Round((inValQty-expenseQty) * (inValue/inValQty),2)),0)) ,2) as stockValue
					from ('.$union_sall.') sINOUT group by itemId) Res group by id having qty_hand<>0';

					$items =  $this->db->query($query)->result_array();
				}
			}


			// $params['is_subcat'] = true;
			if ($cats) {
				$categories = array();
				foreach ($cats as $val)
				{
					$item_params = $params;
					if (isset($item_params['catId'])) {
						unset($item_params['catId']);
					}
					$catId = $val['id'];
					$tmp = $this->db->query('select group_concat(distinct ic.itemId) as itemIds from '.$this->db->dbprefix("items_category ").' as ic Join (select id from (select * from '.$this->db->dbprefix("category ").' where cId='.$this->cId.' order by pId,id) alldata, (select @pgi:='.$catId.') init where cId='.$this->cId.' and find_in_set(pId, @pgi) > 0 and @pgi := concat(@pgi,",",id) union all select '.$catId.') cl on cl.id=catId where ic.cId='.$this->cId)->row_array();
					
					if ($tmp['itemIds']) {
						$item_params['itemId'] = explode(',',$tmp['itemIds']);

						// $params['catId'] = $val['id'];
						$query = $this->fifo_query($item_params);
						if($query) {
							$sAll 			= $query['sAll'];
							$sOut 			= $query['sOut'];
							$union_sall 	= $query['union_sall'];
							$opening_filter = $query['opening_filter'];
							$other_filter 	= $query['other_filter'];

							//round(sum(If (inValQty > 0 and expenseQty>=0, if (expenseQty=0, inValue, Round(expenseQty * (inValue/inValQty),2)),0)) ,2) as stockValue
							$query = 'WITH sAll AS ('.$sAll.'),sOUT AS ('.$sOut.')	
							SELECT "" as catId,id,name,GROUP_CONCAT(distinct uom) as uom,qty_hand,stockValue,1 AS isCat,"" AS SKU,sum(round((stockValue/qty_hand),3)) as rate,sum(qty_hand) AS qty_hand,sum(stockValue) AS stockValue FROM (
							select   itemId as id,itemName as name,uom,unit,tDate,tType,inQty,outQty,
							round(sum(inQty-outQty),3) AS qty_hand,							
							round(sum(If (inValQty > 0 and inValue>=0 , if (expenseQty=0, inValue, Round((inValQty-expenseQty) * (inValue/inValQty),2)),0)) ,2) as stockValue
							from ('.$union_sall.') sINOUT group by itemId) Res  having qty_hand<>0';

							$tmp =  $this->db->query($query)->row_array();
							if ($tmp) {
								$tmp['catId'] 	= $val['id'];
								$tmp['name'] 	= $val['name'];
								$categories 			= array_merge($categories,array($tmp));
							}
						}
					}
				}

				$items = array_merge($categories, $items);
			}

			// $query = $this->fifo_query($params);			
			// $categories =  $this->db->query($query)->result_array();
			// $items = array_merge($categories, $items);

			return array('items' => $items,'uomCnt' => 0);
			
		}
		$categories = array();
		$start_date = $end_date = $cur_date = gmdate('Y-m-d');
		get_financial_dates($cur_date, $start_date, $end_date);
		$where="";
		$where = array('c.pId' => $params['catId']);
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;
		$params['from_date'] = !empty($params['from_date']) ? $params['from_date'] : $start_date;
		$params['to_date'] = !empty($params['to_date']) ? $params['to_date'] : $start_date;


		if (empty($params['page']) || $params['page'] == 1) {

			$this->db->select('*')->from('category');
			$where = array('cId' => $this->cId);
			$where['pId'] = $params['catId'];
			$this->db->where($where);
			$cats = $this->db->order_by('name','asc')->get()->result_array();

			$categories = array();
			if ($cats) {
				foreach ($cats as $row) {
					$catId = $row['id'];
					// $tmp = $this->db->query('select group_concat(distinct itemId) as itemIds from ob_items_category Join (select id from (select * from ob_category where cId='.$this->cId.' order by pId,id) alldata, (select @pgi:='.$catId.') init where cId='.$this->cId.' and find_in_set(pId, @pgi) > 0 and @pgi := concat(@pgi,",",id) union all select '.$catId.') cl on cl.id=catId')->row_array();
						
					// if (!$tmp['itemIds']) {
					// 	continue;
					// }
					// $where = array('catId' => $catId);

					if (empty($params['page']) || $params['page'] == 1) {
						$tmp = $params;
						$tmp['rpType'] = 'STC';
						$tmp['zeroStocks'] = true;
						$tmp['nested_category'] = $catId;
						if (!empty($tmp['catId'])) {
							unset($tmp['catId']);
						}
						$tmp['prepared_query'] = true;
						$this->load->model("report/StockModel", "stockModel");
						$query = $this->stockModel->alert($tmp);
						
						// $query = $query_array[0] . ' group by id,itemId UNION ALL ' . $query_array[1] . ' group by id,itemId';
						$cat_query = "select c.id as catId,id,c.name,IFNULL(ROUND(sum(p_qty),3),0) as qty,IFNULL(ROUND(sum(p_qty-s_qty),3),0) as qty_hand,'' as stockValue,1 AS isCat,'' AS SKU,'' AS uom from ("
						.$query.") uni, ". $this->db->dbprefix('category'). " as c where c.cId=$this->cId and c.id=".$catId;
						$tmp_cat = $this->db->query($cat_query)->row_array();
						if ($tmp_cat) {
							$tmp_cat['name'] = $row['name'];
							$tmp_cat['catId'] = $row['id'];
							$categories = array_merge($categories,array($tmp_cat));
						}
					}
				}
			}
		}

		$params['rpType'] = 'STC';
		$params['zeroStocks'] = true;
		$params['stock_category'] = 'true';
		$this->load->model("report/StockModel", "stockModel");
		$tmp = $this->stockModel->alert($params);

		$items = array();
		if (!empty($tmp['items'])) {
			foreach ($tmp['items'] as $item) {
				$tmp_item = array(
					'catId' => $params['catId'],
					'id' => $item['itemId'],
					'name' => $item['itemName'],
					'qty' => $item['p_qty'] - $item['s_qty'],
					'qty_hand' => $item['p_qty'] - $item['s_qty']
				);
				$tmp_item['qty']		= $tmp_item['qty_hand'];
				$tmp_item['stockValue'] = $tmp_item['qty_hand'] * $item['pi_rate'];

				$tmp_item['isCat'] = 0;
				$tmp_item['SKU'] 		= $item['SKU']; 
				$tmp_item['uom'] 		= $item['uom'];

				$items[] = $tmp_item;
			}
		}
		$items = array_merge($categories, $items);
		
		return array('items' => $items, 'uomCnt' => 0);
	}
	public function allBranch_stock($params = array()) {
		$page_limit = $this->config->item('page_limit');
		$params['page'] = !empty($params['page']) ? $params['page'] : '1';
		$addLimit = $catJoin = '';
		$from = ($params['page'] - 1) * $page_limit;
		if(empty($params['itemId']) && empty($params['f_type'])) {
			$addLimit = "limit  ". $from . ',' . $page_limit."";
		}
		if (!empty($params['catId']) || !empty($params['catColumn']) || !empty($params['catIds'])) {
			$catJoin = "JOIN '".$this->db->dbprefix("items_category")."' itc on itc.cId=".$this->cId." and itc.itemId=i.itemId
						
			";
		} 
		// $query = "SELECT i.itemId,i.name,i.sku as SKU, s.curstk,s.bid,i.uom,-1 as itemAttrId FROM 
		// 	ob_items i 
		// 	JOIN ob_items_cur s on i.itemId=s.itemId			
		// 	join (select itemId from ob_items where isinventory=1 AND cid='".$this->cId."' order by name ".$addLimit.") ic on ic.itemId=i.itemId 
		// 	".$catJoin."
		// 	";

		$query = "SELECT * FROM (
			SELECT it.cid,it.itemId,it.name,it.sku as SKU, it.curstk,".get_company('mainbId')." as bid,it.uom,-1 as itemAttrId FROM ".$this->db->dbprefix("items")." as it where it.cid='".$this->cId."'".(!empty($params['itemId'])?" AND it.itemId='".$params['itemId']."'":'')
			."UNION ALL (SELECT ib.cId,ib.itemId,ib.name,ib.sku as SKU, s.curstk,s.bid,ib.uom,-1 as itemAttrId FROM ".$this->db->dbprefix("items")." as ib JOIN ".$this->db->dbprefix("items_cur")." s on ib.itemId=s.itemId join ".$this->db->dbprefix("contacts")." as c on c.id=s.bId where c.csType!='F' AND ib.cid='".$this->cId."'".(!empty($params['itemId'])?" AND ib.itemId='".$params['itemId']."'":'')
			.")) i  JOIN (SELECT itemId FROM ".$this->db->dbprefix("items")." WHERE isinventory=1 AND cid='".$this->cId."'".(!empty($params['itemId'])?" AND itemId='".$params['itemId']."'":'')." order by name ".$addLimit.") ic on ic.itemId=i.itemId "
		.$catJoin;

		$query .= " where i.cId ='".$this->cId."'";
		if(!empty($params['itemId'])) {	
			$query .= " AND i.itemId = ".$params['itemId'];
		}
		if(!empty($params['catId'])) {	
			$query .= " AND itc.catId IN (";
			$i = 0;
			foreach($params['catId'] as $cat) {
				$i++;
				$query .= $cat;
				if(count($params['catId']) != $i) {
					$query .= ",";
				}
			}
			$query .= ")";
		}
		$query .= " order by name";
		$result['items'] = $this->db->query($query)->result_array();
		$result['isPaging'] = count($result['items']);
		$isBranchModule = get_company('salModCodes');
        $isBranchModule = explode(',',$isBranchModule);
		$isBranchModule = in_array('BL',$isBranchModule);
      	if(!empty($params['isDet']) && $isBranchModule) {
			$result['items'] = $this->processStock($params,$result,'STC');
		}
		//print_R($result);
		return $result;
	}
	function slowMovingStock($params = array()) {	
		$isBranchModule = get_company('salModCodes');
        $isBranchModule = explode(',',$isBranchModule);
		$isBranchModule = in_array('BL',$isBranchModule);
		$page_limit = $this->config->item('page_limit');
		$params['page'] = !empty($params['page']) ? $params['page'] : '1';
		$from = ($params['page'] - 1) * $page_limit;
		$params['branch'] = isset($params['branch']) ? $params['branch'] : -1;
		$params['isDet'] = !empty($params['isDet']) ? $params['isDet'] : -1;
		$isMainBranch = (int)$params['branch'] == (int)get_company('mainbId');
		$branchId = (int)$params['branch'];
		$variations = array('groupBy' => '','branchWhere' => '','joinAnd' => '','orderBy' => ',icur.bid','itemId' => '','join' => '');
			
		$branchStockinnerQuery =  "SELECT itemId,sum(curStk) AS curStk, bId FROM(SELECT oi.itemId,oi.curStk,". ($isMainBranch || $branchId == -1 ? get_company('mainbId') : 'oi.bId') ." AS bId FROM ".($isMainBranch || $branchId == -1 ? $this->db->dbprefix('items')  : $this->db->dbprefix('items_cur'))." as oi  WHERE oi.cId = ".$this->cId."".(($isMainBranch || $branchId == -1 ? "" : " AND oi.bId = ".$branchId."") ). " UNION ALL SELECT ic.itemId, ic.curStk,if (bc.csType='L', bc.bId,ic.bid) as bid FROM ". $this->db->dbprefix('items_cur')." AS ic JOIN ". $this->db->dbprefix('contacts') ." AS bc ON bc.id = ic.bId WHERE " .($branchId == -1 ? "" : " bc.csType = 'L' AND ")." bc.cId =".$this->cId."". ($branchId == -1 ? '' : ( " AND bc.bId = ".$branchId)) .") AS u group by u.itemId,u.bId";
// print_r($branchStockinnerQuery);
// exit;
		if(!empty($params['itemId'])) {
			$variations['itemId'] = "AND it.itemId = ".$params['itemId'];
		}
		$groupBy = $branchWhere = "";
		if(!empty($isBranchModule)) {
			if(!empty($params['branch']) && ($params['branch'] == '-1' ||!empty($params['location']) &&  $params['location'] == -1)) {
				$variations['groupBy'] = ",icur.bid";
				$variations['orderby'] = ",icur.bid";
			}
			else { 
				$variations['branchWhere'] = 'AND icur.bid="'.$params['branch'].'"';
			}
			if($params['branch'] == '-1') {
				///$variations['joinAnd'] = "AND t.bid=icur.bid";
			}
			else if(!empty($params['location']) && $params['location'] != -1){
				$variations['joinAnd'] = "AND t.bId=".$params['branch'];
			}
			if(!empty($params['location']) && $params['location'] == -1 && $params['branch'] != -1) {
				$variations['join'] = "left join ".$this->db->dbprefix("contacts")." c on c.id=icur.bId";
				$variations['branchWhere'] = 'AND (icur.bid = '.$params['branch'].' or (c.csType="L" and c.bid='.$params['branch'].'))';
			}
		}
		// $query = "Select it.itemId, it.name , it.sku as SKU, icur.bid, sum((ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1)) as sales, min(t.tdate) as minstDate,it.uom,FLOOR(icur.curStk /  IFNULL((sum((ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1)) /DATEDIFF(CURDATE(),min(t.tdate))) * 31,0))  as stkMonth,ifnull(icur.curStk,0) as curstk,-1 as itemAttrId
		// from ".$this->db->dbprefix("items")." it
		// join (".$branchStockinnerQuery.") as icur on icur.itemId=it.itemid
		// left join (".$this->db->dbprefix("trans")." t 
		// inner join ".$this->db->dbprefix("trans_items")." ti on t.id=ti.transId  
		// AND  t.tDate  >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
		// AND  t.tDate  <= CURDATE()
		// AND  t.status  NOT IN('D', 'X')
		// AND  t.tType  IN('SI', 'SR', 'SH') 
		// and t.reftType NOT IN('SI', 'SR', 'SH')           
		// LEFT JOIN ".$this->db->dbprefix("itemrelunits")." itr ON itr.itemId = ti.itemId  and  itr.relUnitName = ti.unit 
		// )  on ti.itemid=it.itemId AND t.bid=icur.bid
		// where it.cid=".$this->cId."
		
		// AND it.isInventory  = 1
		// AND icur.curStk > 0
		// ".$variations['itemId']."		
		// GROUP BY  it . itemId  ".$variations['groupBy']." having ((stkMonth > ".$params['month']." or stkMonth=0 ) and (minstDate is NULL or minstDate < DATE_SUB(CURDATE(), INTERVAL 1 MONTH)))  order by name".$variations['orderBy'].",itemId";
		
		$innerquery1 = "(select i.itemId, ((ti.qty + ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) * DATEDIFF(CURDATE(), t.tDate) ) as tscore,
						(ti.qty + ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) * if(t.tType in ('PI','PR','EI','PE','PD','GR', 'SC'), 1 ,-1) as trqty,
						(ti.qty + ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) * if(t.tType in ('PI','PR','EI','PE','PD','GR', 'SC'), 0 ,1) as outqty, t.tDate as tDate
						FROM ".$this->db->dbprefix("items")." i 
						JOIN ".$this->db->dbprefix("trans_items")." ti on ti.itemId=i.itemId
						JOIN ".$this->db->dbprefix("trans")." t on t.id=ti.transId
						LEFT JOIN ".$this->db->dbprefix("itemrelunits")." AS `itr` ON `itr`.`itemId`=`ti`.`itemId` and `itr`.`relUnitName`=`ti`.`unit`					
						WHERE
						i.isInventory='1' AND
						i.cId = $this->cId AND
						t.tDate >= DATE_SUB(CURDATE(),INTERVAL 6 MONTH ) 
						AND (t.tType != 'AO' or (t.tType='AO' AND t.tNo=$this->bId)) 
						AND t.tType in ('AO','PI','PR','EI','PE','GR','SH','PD', 'SI','SR','SD','SC','PC') 
						AND t.refTtype NOT in ('PI','PR','EI','PE','PD','SI','SR','SD','SC','PC') 
						AND t.status not in ('D','X','V')"
						.($params['branch'] != -1 ? " AND t.bId = " . $params['branch'] : "") ." " ;

		$innerquery2 = "Select i.itemId, (si.qty  * if(itr.convFactor, itr.convFactor, 1) * DATEDIFF(CURDATE(), se.sDate) ) as tscore, 
					si.qty * if(itr.convFactor, itr.convFactor, 1) as trqty,
					(if(se.sType NOT IN('DI', 'WE', 'WD', 'WL', 'WT') AND si.qty < 0 ,-1 * si.qty,0)  * if(itr.convFactor, itr.convFactor, 1) ) as outqty , se.sDate as tDate 
					FROM ".$this->db->dbprefix("items")." i 
					JOIN ".$this->db->dbprefix("stock_items")." si on si.itemId=i.itemId
					JOIN ".$this->db->dbprefix("stock_entries")." se on se.id=si.sId
					LEFT JOIN ".$this->db->dbprefix("itemrelunits")." AS `itr` ON `itr`.`itemId`=`si`.`itemId` and `itr`.`relUnitName`=`si`.`unit`
					WHERE i.isInventory='1' 
					AND i.cId=$this->cId 
					AND se.sDate >= DATE_SUB(CURDATE(),INTERVAL 6 MONTH ) 
					AND se.sType != 'BF'"
					.($params['branch'] != -1 ? " AND se.locId = " . $params['branch'] : "") . " )";

		$innerquery = ''.$innerquery1. ' UNION ALL ' .$innerquery2 . '';
		
		$query1 = "(Select itemId, sum(tscore) as tscore, sum(trqty) as trqty, sum(outqty) as outqty, sum(if(outqty>0,1,0)) as cntOut, 
					COUNT(DISTINCT if(outqty > 0, tDate, NULL)) as disCnt,
					max(if(outqty > 0, tDate, Null)) as maxSalDate
					FROM ".$innerquery." ua GROUP by itemId)";

		$query2 = "(Select i.itemId, i.name, ts.trqty,ts.tscore, ((sum(".($params['branch'] != -1 ? "ic.curStk" : "i.curStk" ).") - ts.trqty) * DateDiff(curdate(), curdate() - INTERVAL 6 Month)) + ts.tscore as score, ts.outqty,disCnt as salvel,
				@min_salvel := if(@min_salvel is NULL or @min_salvel > disCnt, disCnt, @min_salvel),
				@max_salvel := if(@max_salvel is NULL or @max_salvel < disCnt, disCnt, @max_salvel),
				".($params['branch'] != -1 ? "sum(ic.curStk) as curstk, " : "i.curStk, " )."
				DATEDIFF(curdate(), maxSaldate ) as idleDays,
				i.uom
				FROM ".$this->db->dbprefix("items")." i 
				".($params['branch'] != -1 ? "JOIN ".$this->db->dbprefix("items_cur")." ic on ic.itemId=i.itemId" : "") ."						
				JOIN ".$query1." ts on ts.itemId=i.itemId
				".(!empty($params['catIds'])  ? "JOIN ".$this->db->dbprefix("items_category")." icc ON icc.cId = 16754 AND icc.itemId = i.itemId " : "" )."
				".(!empty($params['catIds'])  ? "JOIN ".$this->db->dbprefix("category")." ca ON ca.id = icc.catId " : "" )."	
				".((!empty($params['conId']) || !empty($params['tagId']))  ? "JOIN ".$this->db->dbprefix("trans_items")." ti ON i.itemId=ti.itemId " : "" )."	
				".((!empty($params['conId']) || !empty($params['tagId']))  ? "JOIN ".$this->db->dbprefix("trans")." t ON ti.transid=t.id " : "" )."	
				".(!empty($params['tagId'])  ? "JOIN ".$this->db->dbprefix("contacts")." c ON c.id=t.conId " : "" )."
				".(!empty($params['tagId'])  ? "JOIN ".$this->db->dbprefix("contacts_tags")." ct ON ct.cId=c.cId and ct.conId= c.id" : "" )."	
				WHERE i.isInventory='1' 
				AND i.cId=$this->cId
				".($isMainBranch ? "" : ($params['branch'] != -1 ? " AND ic.bId = " . $params['branch'] : ""))." 
				".(!empty($params['catIds']) ? "AND icc.catId IN (" . implode(',', $params['catIds']) . ")" : "")." 
				".(!empty($params['conId']) ? "AND t.conId = " . $params['conId'] . " " : "")."
				".(!empty($params['tagId']) ? "AND ct.tagId = " . $params['tagId'] . " " : "")."
				GROUP by itemId)";
		
		$finalquery = "select itemId, name, score,outqty, round(((salvel-@min_salvel)/ ( @max_salvel-@min_salvel))/2,1)  as norsalvel /* 0 to .5 */, 
				curstk,idleDays, uom
				FROM ".$query2." iall ";

		$idle_innerquery1 = "(Select i.itemId,  max(t.tDate) as tDate
							FROM ".$this->db->dbprefix("items")." i
							JOIN ".$this->db->dbprefix("trans_items")." ti on ti.itemId=i.itemId
							JOIN ".$this->db->dbprefix("trans")." t on t.id=ti.transId
							WHERE i.isInventory='1' 
							AND i.cId=$this->cId  
							AND t.tDate >= DATE_SUB(CURDATE(),INTERVAL 12 MONTH ) 
							AND (t.tType != 'AO' or (t.tType='AO' AND t.tNo=1)) 
							AND t.tType in ('AO','SH','SI','SR','SD') 
							AND t.refTtype NOT in ('PI','PR','EI','PE','PD','SI','SR','SD','SC','PC') 
							AND t.status not in ('D','X','V')"
							.($params['branch'] != -1 ? " AND t.bId = " . $params['branch'] : "") . 
		                    " group by ti.itemId";
		

		$idle_innerquery2 = "Select i.itemId,  se.sDate as tDate 
							FROM ".$this->db->dbprefix("items")." i 
							JOIN ".$this->db->dbprefix("stock_items")." si on si.itemId=i.itemId
							JOIN ".$this->db->dbprefix("stock_entries")." se on se.id=si.sId
							WHERE i.isInventory='1' 
							AND i.cId=$this->cId  
							AND se.sDate >= DATE_SUB(CURDATE(),INTERVAL 12 MONTH ) 
							AND se.sType != 'BF' 
							AND si.qty < 0 
							AND se.sType NOT IN ('DI', 'WE', 'WD', 'WL', 'WT')"
							.($params['branch'] != -1 ? " AND se.locId = " . $params['branch'] : "") . 
		                    " group by si.itemId)";
		
		$idle_innerquery = ''.$idle_innerquery1. ' UNION ALL ' .$idle_innerquery2 . '';

		$idle_query = "(Select i.itemId, i.name,
						".($params['branch'] != -1 ? "sum(ic.curStk) as curstk, " : "i.curStk, " )."
						If (maxSaldate is NOT NULL, DATEDIFF(curdate(), maxSaldate ), 999) as idleDays,i.uom  
						FROM ".$this->db->dbprefix("items")." i 
						".($params['branch'] != -1 ? "JOIN ".$this->db->dbprefix("items_cur")." ic on ic.itemId=i.itemId" : "") ."					
						LEFT JOIN (Select itemId, max(tDate) as maxSalDate FROM ".$idle_innerquery." ua GROUP by itemId)ts on ts.itemId=i.itemId
						".(!empty($params['catIds'])  ? "JOIN ".$this->db->dbprefix("items_category")." icc ON icc.cId = 16754 AND icc.itemId = i.itemId " : "" )."
						".(!empty($params['catIds'])  ? "JOIN ".$this->db->dbprefix("category")." ca ON ca.id = icc.catId " : "" )."		
						".((!empty($params['conId']) || !empty($params['tagId']))  ? "JOIN ".$this->db->dbprefix("trans_items")." ti ON i.itemId=ti.itemId " : "" )."	
						".((!empty($params['conId']) || !empty($params['tagId']))  ? "JOIN ".$this->db->dbprefix("trans")." t ON ti.transid=t.id " : "" )."	
						".(!empty($params['tagId'])  ? "JOIN ".$this->db->dbprefix("contacts")." c ON c.id=t.conId " : "" )."
						".(!empty($params['tagId'])  ? "JOIN ".$this->db->dbprefix("contacts_tags")." ct ON ct.cId=c.cId and ct.conId= c.id" : "" )."	
						WHERE i.isInventory='1' 
						AND i.cId=$this->cId 
						".($isMainBranch ? "" : ($params['branch'] != -1 ? " AND ic.bId = " . $params['branch'] : ""))."
						".(!empty($params['catIds']) ? "AND icc.catId IN (" . implode(',', $params['catIds']) . ")" : "")."
						".(!empty($params['conId']) ? "AND t.conId = " . $params['conId'] . " " : "")."
						".(!empty($params['tagId']) ? "AND ct.tagId = " . $params['tagId'] . " " : "")."
						GROUP by itemId)";

		$init_query = "SET @min_salvel := CAST(NULL AS DECIMAL(3,2)), @max_salvel := CAST(NULL AS DECIMAL(3,2))";

		if($params['reftype'] == "slow"){
			$query = ' '.$finalquery. ' HAVING  norsalvel in  (0.2, 0.3) ORDER BY norsalvel ASC, score DESC'; 
			$this->db->query($init_query);
		}elseif($params['reftype'] == "fast"){
			$query = ' '.$finalquery. ' HAVING norsalvel in  (0.4, 0.5) ORDER BY norsalvel DESC, score ASC';
			$this->db->query($init_query);
		}elseif($params['reftype'] == 'idle'){
			$query = 'select itemId, name, curstk, uom,idleDays, if(idleDays=999,"-",idleDays) as dispDays FROM '.$idle_query.' iall  
						WHERE idleDays > 90 
						AND curstk > 0
						order by idleDays Desc' ;
		}
						
		
		if(empty($params['f_type']))
			$query .= " limit  ". $from . ',' . $page_limit.""; //print_R($query);exit;
				
		$result['items'] = $this->db->query($query)->result_array();

		// print_R($result['items']);exit;
		
		$result['isPaging'] = count($result['items']);
		
      	// if(!empty($params['isDet']) && $isBranchModule && ($params['branch']) == -1 || (!empty($params['location']) && ($params['location']) == -1)) {
		// 	// $result['items'] = $this->processStock($params,$result,'SMS',$params['branch'] == -1 ? true : false);
		// }
	
		return $result;
	}
	function allBranch($params = array()) {	
		$page_limit = $this->config->item('page_limit');
		$params['page'] = !empty($params['page']) ? $params['page'] : '1';
		$from = ($params['page'] - 1) * $page_limit;
		$isBranchModule = get_company('salModCodes');
        $isBranchModule = explode(',',$isBranchModule);
		$isBranchModule = in_array('BL',$isBranchModule);
		if(empty($params['branch'] )) {
			$params['branch']  = get_user_data('defaultbId',true);
		}
		$isMainBranch = (int)$params['branch'] == (int)get_company('mainbId');
		$branchId = (int)$params['branch'];
		$variations = array('joinAnd' => '','joinWhere' => '','itemId' => '');
		$branchStockinnerQuery =  "SELECT itemId,sum(curStk) AS curStk, bId FROM(SELECT oi.itemId,oi.curStk,". ($isMainBranch || $branchId == -1 ? get_company('mainbId') : 'oi.bId') ." AS bId FROM ".($isMainBranch || $branchId == -1 ? $this->db->dbprefix('items')  : $this->db->dbprefix('items_cur'))." as oi  WHERE oi.cId = ".$this->cId."".(($isMainBranch || $branchId == -1 ? "" : " AND oi.bId = ".$branchId."") ). " UNION ALL SELECT ic.itemId, ic.curStk,if (bc.csType='L', bc.bId,ic.bid) as bid FROM ". $this->db->dbprefix('items_cur')." AS ic JOIN ". $this->db->dbprefix('contacts') ." AS bc ON bc.id = ic.bId WHERE " .($branchId == -1 ? "" : " bc.csType = 'L' AND ")." bc.cId =".$this->cId."". ($branchId == -1 ? '' : ( " AND bc.bId = ".$branchId)) .") AS u group by u.itemId,u.bId";
		if(!empty($params['itemId'])) {
			$variations['itemId'] = "AND it.itemId = ".$params['itemId'];
		}
		if(!empty($isBranchModule)) {
			if($params['branch'] == -1) {
				$variations['joinAnd'] = " and itcur.bid=icur.bid ";
				$variations['joinWhere'] = "AND (icur.bId=".get_company('mainbId')." or c.csType IN ('B','F'))  ";
			}
			else {
				$variations['joinAnd'] = " AND (icur.bId=".$params['branch']." or c.csType IN ('B','F')) ";
				$variations['joinWhere'] = "AND (icur.bId=".$params['branch']." or c.csType IN ('B','F'))  ";
			}
		}
		$query = "Select it.itemId, it.name , it.sku as SKU, icur.bid, sum((ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1)) as sales, min(t.tdate) as minstDate,it.uom,FLOOR(icur.curStk /  IFNULL((sum((ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1)) /DATEDIFF(CURDATE(),min(t.tdate))) * 31,0))  as stkMonth, ifnull(icur.curStk,0) as curstk,-1 as itemAttrId
		from ".$this->db->dbprefix("items")." it
		join (".$branchStockinnerQuery.") icur on icur.itemId=it.itemid		
		left join (".$this->db->dbprefix("trans")." t 
		inner join ".$this->db->dbprefix("trans_items")." ti on t.id=ti.transId  
		AND  t.tDate  >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
		AND  t.tDate  <= CURDATE()
		AND  t.status  NOT IN('D', 'X')
		AND  t.tType  IN('SI', 'SR') 
		AND  t.reftType NOT IN('SI', 'SR')   
		LEFT JOIN ".$this->db->dbprefix("itemrelunits")." itr ON itr.itemId = ti.itemId  and  itr.relUnitName = ti.unit      
		) on ti.itemid=it.itemId  and t.bid=icur.bId
		where it.cid=".$this->cId."
		AND it.isInventory  = 1
		AND icur.curStk > 0
		".$variations['itemId']."
		GROUP BY  it . itemId  ,icur.bid 
		having ((stkMonth > ".$params['month']." or stkMonth=0 ) and (minstDate is NULL or minstDate < DATE_SUB(CURDATE(), INTERVAL 1 MONTH)))  order by name,itemId";
		if(empty($params['f_type']))
			$query .= " limit  ". $from . ',' . $page_limit."";

		// print_r($query);
		// exit;
		$result['items'] = $this->db->query($query)->result_array();
		
		$result['isPaging'] = count($result['items']);
		if($isBranchModule && ($params['branch']) == -1 || (!empty($params['location']) && ($params['location']) == -1)) {
			// $result['items'] = $this->processStock($params,$result,'SMS',$params['branch'] == -1 ? true : false);
		}
	
		return $result;
		
	}
	function processStock($params,$result,$type,$isAddWarehouse = false) {

		$groupItem = $finalArr = array();
		foreach ($result['items'] as $item) {
			$groupItem[$item['itemId']][] = $item;
		}
		$this->load->model('contactsModel');
		$branches = $this->contactsModel->get_branches();
		if(!empty($branches)) {
			$branches = $branches['items'];
		}
		$ids = array_column($branches, 'id');
		array_push($ids,-2);		
		foreach($groupItem  as $gpkey => $gpval) {
			$totalstock = 0;
			$itemValue=array();
			//Assigning Empty values to avoid column colapse
			foreach($branches as $brchkey => $brchval) {
				$itemValue["bid".$brchval['id']] = 0;
				
				if($type == 'SMS') 
					$itemValue["bid".$brchval['id']."stkmonth"] = "-";
			}

			foreach ($gpval  as $key => $val) {
				if(in_array(($val['bid']),$ids)) {
					if(empty($itemValue["bid".$val['bid']]))  {
						$itemValue["bid".$val['bid']] = 0;
					}
					if(empty($itemValue["bid-2"]))  {
						$itemValue["bid-2"] = 0;
					}
					
					if(!empty($val['curStk']))
						$itemValue["bid".$val['bid']]= !empty($val['curStk']) ? (float)$val['curStk'] : '';
					if(!empty($val['curstk']))
						$itemValue["bid".$val['bid']]= (float)$val['curstk'];
					if(!empty($val['curstk']))
						$val['curStk'] = $val['curstk'];
					if(isset($val['bid'])){ 
						if($params['rpType'] == 'SMS')  {
						foreach($branches as $brchkey => $brchval) {
							if(($brchval['csType'] == 'L' || $brchval['csType'] == 'F')
								&& isset($val['bid'])
								&& $val['bid'] == $brchval['id'] 
								&& $brchval['bid']!=-1 
							) {	
								$itemValue["bid".$brchval['id']] = $itemValue["bid".$brchval['id']] + (float)$val['curStk'];
								// $itemValue["bid".$brchval['id']] = 0;
							}
						}
						}
					}
					if(($params['rpType'] == 'SMS' || $params['rpType'] == 'STC') && ( $params['branch'] == -1 || !empty($val['bflag'])))
						$totalstock += (float)$val['curstk'] ;
					
					if($type == 'SMS') 
						$itemValue["bid".$val['bid']."stkmonth"] = $val['stkMonth'];
				}else if(empty($itemValue["bid-2"])){/*user login main branch column collapse due to following value missed*/
					$itemValue["bid-2"] = 0;
				}

			}
			foreach(array_keys($gpval[0]) as $itmkey => $itm_val) {
				$itemValue[$itm_val] = $gpval[0][$itm_val] ;
			}	
			// print_r($itemValue);
			// exit;
			if($params['rpType'] == 'SMS')	
				$itemValue['curstk'] = (float)$totalstock;
			if($params['rpType'] == 'STC')	{
				if($params['branch'] == -1)  {
					$itemValue['TotStk'] = $itemValue['bidtot'] = $totalstock;
				}
				else  {
					$itemValue['bTotStk'] = $itemValue['bidtot'] = $totalstock;
				}
			}
			array_push($finalArr,$itemValue);
		}

		return $finalArr;
	
	}
	public function current_stock($params) {

		$mainBranch = isset($params['branch']) && $params['branch'] == get_company('mainbId') ? 1 : '';
		
		
		$isBranchModule = false;
		$page_limit = $this->config->item('page_limit');
		
		$salModCodes = get_company('salModCodes');
        $salModCodes = explode(',',$salModCodes);
		$isBranchModule = in_array('BL',$salModCodes);
		if(!empty($isBranchModule)) {
			$this->load->model('contactsModel');
			$branches = $this->contactsModel->get_branches();
			if(!empty($branches)) {
				$branches = $branches['items'];
			}
			$page_limit = (15 * count($branches));
			if($page_limit < 40) {
				$page_limit = 40;
			}
		}
		if(!empty($params['catIds'])) {
			$params['catIds'] = $this->get_child_category($params['catIds']);
		}
		$params['branch'] = isset($params['branch']) ? $params['branch'] : '';
		$from = 0;
		if (isset($params['page'])) {
			$from = ($params['page']  - 1) * $page_limit;	
		}
		$_cnt = array();
		if(!empty($params['custFields'])) {
			if(empty($params['cusCnt'])) {
				$_cnt = $this->db->select("count(id) as cusCnt")->from("compfields")->where(array("cId" => $this->cId,"isActive >=" => 1,'tType' => "IT"))->get()->row_array();
			}
			else  {
				$_cnt['cusCnt'] = $params['cusCnt'];
			}
			$result['cusCnt'] = $_cnt['cusCnt'];
		}
		$custQuery = "";
		
		if(!empty($_cnt['cusCnt'])) {
			// $this->db->select('fv.modId as ItemId, GROUP_CONCAT(CONCAT("<b>", f.fname,"</b>: ",fv.fvalue) order by f.orderId SEPARATOR "  ") as cfList');
			$this->db->select('fv.modId as ItemId, CONCAT("[", GROUP_CONCAT(				
					JSON_OBJECT(
						"name", f.fname,
						"val", fv.fvalue
					) 
					ORDER BY f.orderId 
					SEPARATOR ","
				),"]") AS cfList');
			$this->db->from('compfields as f');
			$this->db->join('field_values as fv', 'fv.fid=f.id');
			$this->db->where("fv.modType","I");
			$this->db->where("f.ttype","IT");
			$this->db->where("f.cId",$this->cId);
			$this->db->group_by("fv.modId");	
			$custQuery = $this->db->get_compiled_select();
		}
		//All Branch / Main Branch
		if($params['branch'] == -1 || $mainBranch || !$params['branch']) {
			if(!$isBranchModule) {
				if(empty($params['itemId']) && !empty($params['itemName'])){
					$this->load->model("itemsModel");
					$params['itemId'] = $this->itemsModel->get_itemids($params['itemName']);//print_R($params['itemId']);
					if(!empty($params['itemId']))
						$this->db->where_in("i.itemId",$params['itemId']);
				}
				else if(!empty($params['itemId'])) {
					$this->db->where("i.itemId",$params['itemId']);
				}
			}

			$select = "i.itemId,i.name ,i.SKU,i.cId,i.type,";
			//Without branches
			$this->db->select($select." ".get_company('mainbId')." as bid,i.curstk,i.uom");		
			
			if($mainBranch) {
				$this->db->select('1 as bflag');
			}
			if(!empty($params['saleRate'])) {
				$this->db->select('i.saleRate');		
			}
			if(!empty($params['desc'])) {
				$this->db->select('i.saleDesc as desc');		
			}
			if (!empty($params['secunit'])) {
			$this->db->select('if (isr.convFactor, Round(i.curStk / isr.convFactor,2), "") as secqty,
					ifnull(isr.relUnitName,"") as secuom');
			}		
			$this->db->from("items as i");
			if (!empty($params['secunit'])) {
				$secunitquery = 'SELECT itemId, relUnitName, convFactor 
								 FROM ob_itemrelunits 
								 WHERE type = "R" 
								 AND cid = ' . $this->cId . ' 
								 GROUP BY itemId';
								 
				$this->db->join('(' . $secunitquery . ') as isr', 'isr.itemId = i.itemId', 'left');
			}
			if (!empty($params['conId'])) {
					$this->db->join('trans_items AS ti', 'i.itemId=ti.itemId');
					$this->db->join('trans AS t', 'ti.transid=t.id');
					$this->db->where("t.conId",$params['conId']);
					$this->db->group_by("i.itemId");	
					
			}
		
			if(!empty($params['catIds'])) {
					// $cat_query = '(select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catIds'].')) sq_exis';
					// $this->db->join($cat_query,'sq_exis.itemId = i.itemId');
					$cat_query = '(select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catIds'].')) sq_exis';
					$this->db->join($cat_query,'sq_exis.itemId = i.itemId');
					$this->db->group_by('i.itemId'); // to avoid duplicate if item map with more than one category 
			}
			
			$this->db->where(array("i.isActive >" => 0,
						"i.cId" => $this->cId,
						"i.isInventory" => 1
			));
			if(!empty($params['stcklvl']) && $params['stcklvl']!= 'All') {
				switch ($params['stcklvl']) {
					case 'zerostck':
						$this->db->where('IFNULL(i.curStk, 0) =', 0);
					break;
					case 'negativstck':
						$this->db->where('IFNULL(i.curStk, 0) <', 0);
					break;
					case 'nonnegativstck':
						$this->db->where('IFNULL(i.curStk, 0) !=', 0);
					break;
				}
			}
			// if(!empty($params['zeroStocks'])) {
			// 	$this->db->where('i.curStk !=',0);
			// }
			if(!$isBranchModule) {
				 if (!empty($params['catColumn']) || !empty($params['catIds'])) {
				 	$this->db->select("c.name as catName");
				 	$this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=i.itemId ');
				 	$this->db->join('category AS c','c.id=ic.catId and c.type = "C"','left');
				 }
				if(!empty($_cnt['cusCnt'])) {
					$this->db->select("IFNULL(cf.cflist,'') as cfList");
					$this->db->join('('.$custQuery.") as cf", 'cf.itemId=i.ItemId','left');
					//$query = $query." LEFT JOIN (".$custQuery.") as cf on cf.itemId=i.ItemId ";
				}
				
				// if(!empty($params['catIds'])) {
				//  	$this->db->where_in('ic.catId', $params['catIds']);
				// }
				if(!empty($params['desc'])) {
					$this->db->select('i.saleDesc');		
				}
				
			}

			$query = $query1 = $this->db->get_compiled_select();
			if(!$params['branch']) {
				if(!empty($params['zeroStocks']))
				//	$query .= " having curStk != 0";
				$query .= " order by i.name,i.itemId";
				if(empty($params['f_type']))
					$query .= " limit  ". $from . ',' . $page_limit."";
			}
			if($params['branch'] == -1 || $mainBranch) {
				if($mainBranch) {
					$select = $select."IF(c.csType = 'L' and c.bid !=".get_company('mainbId').", c.bId, icur.bId) AS bId, icur.curStk , i.uom, IF((c.csType = 'L' and c.bid=".$params['branch'].") or c.id=".$params['branch'].", 1,".$params['branch'].") as bflag,";
				}
				else {	
					$select = $select."IF(c.bid=0 OR (c.csType='L' and IFNULL(ppb.bid,-2)=-1), IF(c.csType = 'L' and c.bid !=-1, c.bId, icur.bId), -2) as bid,IFNULL(icur.curStk, 0) AS curstk, i.uom,";
				}
				
				$this->db->select($select);	
				if(!empty($params['desc'])) {
					$this->db->select('i.saleDesc');		
				}
				if(!empty($params['saleRate'])) {
					$this->db->select('i.saleRate');		
				}	
				if (!empty($params['secunit'])) {
					$this->db->select('if (isr.convFactor, Round(i.curStk / isr.convFactor,2), "") as secqty,
							ifnull(isr.relUnitName,"") as secuom');
					}	
				$this->db->from("items as i");
				if (!empty($params['secunit'])) {
					$secunitquery = 'SELECT itemId, relUnitName, convFactor 
									 FROM ob_itemrelunits 
									 WHERE type = "R" 
									 AND cid = ' . $this->cId . ' 
									 GROUP BY itemId';
									 
					$this->db->join('(' . $secunitquery . ') as isr', 'isr.itemId = i.itemId', 'left');
				}
				$this->db->join("items_cur as icur","icur.itemId = i.itemId");
				$this->db->join("contacts as c","c.id = icur.bId");
				$this->db->join("contacts as ppb"," ppb.id = c.bid","left");
				if(!empty($params['catIds'])) {
					$cat_query = '(select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catIds'].')) sq_exis';
					$this->db->join($cat_query,'sq_exis.itemId = i.itemId');
				}
				
				$this->db->where(array("i.isActive >" => 0,
							"i.cId" => $this->cId,
							"i.isInventory" => 1
				));
				
				if(!empty($params['stcklvl']) && $params['stcklvl']!= 'All') {
					switch ($params['stcklvl']) {
						case 'zerostck':
							$this->db->where('IFNULL(icur.curStk, 0) =', 0);
						break;
						case 'negativstck':
							$this->db->where('IFNULL(icur.curStk, 0) <', 0);
						break;
						case 'nonnegativstck':
							$this->db->where('IFNULL(icur.curStk, 0) !=', 0);
						break;
					}
				}
				$where = "";
				if(!empty($params['itemId'])) {
					$where = " AND i.itemId = ".$params['itemId'] ;
				} else if(!empty($params['itemName'])) {
					$where = " AND (i.name LIKE ('%".$params['itemName']."%') OR i.SKU LIKE ('%".$params['itemName']."%'))";
				}
				if($mainBranch) {
					$this->db->where("(icur.bId = ".get_company('mainbId')."  or c.bid=".get_company('mainbId')." OR (c.csType='L' and IFNULL(ppb.bid,-2)=0))");
				}
				$query2 = $this->db->get_compiled_select();
				$query = $query1." UNION ALL ".$query2;
				if($params['branch'] == -1  || $mainBranch) {
					//$this->db->query("SET @runStk:=0.00,@currItem:=0");
					
					$wholeselect = "select *";
					if($mainBranch) {
						// $wholeselect .= ",SUM(IF(bflag=1,curstk,0)) OVER(PARTITION BY itemId) AS bTotStk";
						//@runStk := if(@currItem=itemId, if(bflag=1,@runStk+curstk,@runStk), if(bflag=1,curstk,0)), @runStk as bTotStk,@currItem:=itemId
						$wholeselect .= "";
					}
					else {
						//@runStk := if(@currItem=itemId,@runStk+curstk,curstk), @runStk as TotStk,@currItem:=itemId
						$wholeselect .= "";
					}
				}
			
				$catJoin = $catSelect = $addLimit = "";
				if(!empty($params['catColumn']) ) {
					// $catSelect = " ,ca.name as catName";
					// $catJoin = "JOIN ob_items_category AS ic on ic.cId=".$this->cId." and ic.itemId=i.itemId join ob_category AS ca on ca.id=ic.catId";
					$cat_query = '(select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catIds'].')) sq_exis ON sq_exis.itemId = i.itemId';
				}
				if(!empty($params['catColumn'])) {
					// if(!empty($params['catIds'])) {
					// 	$where .= " AND ca.catId IN (".implode(",",$params['catIds']).' )';
					// }
				}
				if(empty($params['f_type']))
					$addLimit = "limit  ". $from . ',' . $page_limit."";
				$__select = "*,sum(curstk) as curstk";
				if(!empty($_cnt['cusCnt'])) {
					$__select .= ",IFNULL(cf.cflist,'') as cfList";
					$custQuery = " LEFT JOIN (".$custQuery.") as cf on cf.itemId=src.ItemId ";
				}
				$query3 = "select ".$__select." from (".$wholeselect."
							from (".$query." ) as it 
							JOIN (SELECT i.itemId as itId".$catSelect." 
									FROM ".$this->db->dbprefix("items")." as i ".$catJoin."
								 	WHERE i.isInventory=1 
									AND i.cId=".$this->cId." 
									And i.isActive > 0 ".$where." 
									order by i.name ,i.itemId ) ic on ic.itId=it.itemId 
							) src ".$custQuery ;
				if (!empty($params['conId']) || !empty($params['tagId'])) {
					$con_where = array();
					$this->db->select('DISTINCT it.itemId', false);
					$this->db->from('trans_items AS ti');
					$this->db->join('items AS it', 'it.itemId=ti.itemId');
					$this->db->join('trans AS t', 'ti.transid=t.id');
					if (!empty($params['tagId'])) {
						$this->db->join('contacts as c','c.id=t.conId','left');	
						$this->db->join('contacts_tags as ct','ct.cId=c.cId and ct.conId= c.id','left');
						$this->db->where_in('ct.tagId',$params['tagId']);
					}
					if (!empty($params['conId'])) {
						$con_where['t.conId'] = $params['conId'];
					}
					if (!empty($params['itemId'])) {
						// $where['it.itemId'] = $params['itemId'];
						$this->db->where_in('it.itemId', $params['itemId']);
					}
					$this->db->where($con_where);
					if (isset($params['branch'])) {
						user_branch_filter('t.bId', array($params['branch']));
					}
					if (!empty($params['item_type'])) {
						$this->db->where($params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase >', 0);
					}
					
					$query3 .= ' where src.itemId in (' . $this->db->get_compiled_select() . ') ';
				}
				if($mainBranch && empty($params['sub_branch'])){
					$query3 .= ' WHERE src.bid = '.$params['branch'].'';
				}
				$query3 .= " GROUP BY src.bId, src.itemId";
				// if(!empty($params['zeroStocks'])) {
				// 	if($params['branch'] == -1)
				// 		$query3 .= " having curStk != 0";
				// 	if($mainBranch)
				// 		$query3 .= " having curStk != 0";
				// }
				$query3 .= " order by src.name ,src.itemId ".$addLimit."";
				$query = $query3;
			}
		}
		//Branch > 0
		else {
			$this->db->select('i.itemId,  i.name,  i.SKU,   i.cId, i.type, 
	 IF(c.csType = "L" and c.bid !='.$params['branch'].' and c.id != '.$params['branch'].', c.bId, icur.bId) AS bid, IFNULL(icur.curStk, 0) AS curstk, i.uom, IF((c.csType = "L" and c.bid='.$params['branch'].') or c.id='.$params['branch'].', 1,0) as bflag');
			if(!empty($params['saleRate'])) {
				$this->db->select('i.saleRate');		
			}
			if(!empty($params['secunit'])) {
				if($mainBranch){
					$this->db->select('if (isr.convFactor, Round(i.curStk / isr.convFactor,2), "") as secqty,
					ifnull(isr.relUnitName,"") as secuom');
				}else{
					$this->db->select('if (isr.convFactor, Round(icur.curStk / isr.convFactor,2), "") as secqty,
					ifnull(isr.relUnitName,"") as secuom');
				}
			}
			if(!empty($params['desc'])) {
				$this->db->select('i.saleDesc');		
			}
			$this->db->from('items as i');
			if (!empty($params['secunit'])) {
				$secunitquery = 'SELECT itemId, relUnitName, convFactor 
								 FROM ob_itemrelunits 
								 WHERE type = "R" 
								 AND cid = ' . $this->cId . ' 
								 GROUP BY itemId';
								 
				$this->db->join('(' . $secunitquery . ') as isr', 'isr.itemId = i.itemId', 'left');
			}
			if(!empty($params['catIds'])) {
				$cat_query = '(select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catIds'].')) sq_exis';
				$this->db->join($cat_query,'sq_exis.itemId = i.itemId');
			}
			$this->db->join('items_cur as icur','icur.itemId = i.itemId');
			$this->db->join("contacts as c","c.id = icur.bId");
			$this->db->join("contacts as ppb"," ppb.id = c.bid","left");
			$this->db->where(array("i.isActive >" => 0,
						"i.cId" => $this->cId,
						"i.isInventory" => 1
			));
			if(!empty($params['stcklvl']) && $params['stcklvl']!= 'All') {
				switch ($params['stcklvl']) {
					case 'zerostck':
						$this->db->where('IFNULL(icur.curStk, 0) =', 0);
					break;
					case 'negativstck':
						$this->db->where('IFNULL(icur.curStk, 0) <', 0);
					break;
					case 'nonnegativstck':
						$this->db->where('IFNULL(icur.curStk, 0) !=', 0);
					break;
				}
			}
			$where = "";
			if(!empty($params['itemId'])) {
				$where = " AND i.itemId = ".$params['itemId'] ;
			} else if(!empty($params['itemName'])) {
				$where = " AND (i.name LIKE ('%".$params['itemName']."%') OR i.SKU LIKE ('%".$params['itemName']."%'))";
			}
			if($params['branch'] > 0) {
				if(empty($params['f_type']) && empty($_cnt['cusCnt']) ) {
					
					$this->db->where("(icur.bid =".$params['branch']." OR c.bid=".$params['branch']." OR (c.csType='L' and IFNULL(ppb.bid,-2)=".$params['branch']."))");
				}
				else 
					$this->db->where("(icur.bid =".$params['branch'].")");
			}
			$_query = $this->db->get_compiled_select();
			$catJoin = $catSelect = $addLimit = "";
			if(!empty($params['catColumn']) || !empty($params['catIds'])) { 
				$catSelect = " ,ca.name as catName";
				
			}
			// if(!empty($params['catIds'])) {
			// 	$where .= " AND ic.catId IN (".implode(",",$params['catIds']).' )';
			// }
			if(empty($params['f_type']))
					$addLimit = "limit  ". $from . ',' . $page_limit."";
			// $query3 = "select *  from (select *, SUM(IF(bflag=1,curstk,0)) OVER(PARTITION BY itemid) AS bTotStk
			$this->db->query("SET @runStk:=0.00,@currItem:=0");
			//,@runStk := if(@currItem=itemId, if(bflag=1,@runStk+curstk,@runStk), if(bflag=1,curstk,0)), @runStk as bTotStk,@currItem:=itemId  
			//$custQuery = "";
			$wholeSelect = "*";
			if(!empty($_cnt['cusCnt'])) {
				$wholeSelect .= ",IFNULL(cf.cflist,'') as cfList";
				$custQuery = " LEFT JOIN (".$custQuery.") as cf on cf.itemId=src.ItemId";
			}
			$query3 = "select ".$wholeSelect." from (select *
			from (".$_query." ) as it 
			JOIN (SELECT i.itemId as itId  
					FROM ".$this->db->dbprefix("items")." as i ".$catJoin." 
					WHERE i.isInventory=1
					
					AND i.cId=".$this->cId." 
					And i.isActive > 0 ".$where." 
					order by i.name,i.itemId  
					
				) ic on ic.itId=it.itemId) src".$custQuery."
				";
			if (!empty($params['conId'])) {
				$con_where = array();
				$this->db->select('DISTINCT it.itemId', false);
				$this->db->from('trans_items AS ti');
				$this->db->join('items AS it', 'it.itemId=ti.itemId');
				$this->db->join('trans AS t', 'ti.transid=t.id');
				$con_where['t.conId'] = $params['conId'];
				if (!empty($params['itemId'])) {
					// $where['it.itemId'] = $params['itemId'];
					$this->db->where_in('it.itemId', $params['itemId']);
				}
				$this->db->where($con_where);
				if (isset($params['branch'])) {
					user_branch_filter('t.bId', array($params['branch']));
				}
				if (!empty($params['item_type'])) {
					$this->db->where($params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase >', 0);
				}
				
				$query3 .= ' where src.itemId in (' . $this->db->get_compiled_select() . ') ';
			}
			$query3 .=  " GROUP BY src.bId, src.itemId";
			// if(!empty($params['zeroStocks'])) {
			// 	$query3 .= " having curStk != 0";
			// }
			$query3 .= " order by src.name ,src.itemId, src.bflag desc ".$addLimit."";
			$query = $query3;
		}
	
		
		$result['items'] = $this->db->query($query)->result_array();
		//$balance = "Select sum(src.curstk) as totQty from (".$query.") as src";
		//$result['totals'] = $this->db->query($balance)->row_array();
		if($params['branch'] == -1 || $mainBranch || $params['branch'] > 0 || !empty($params['f_type']))
			$result['items'] = $this->processStock($params,$result,'STC',$params['branch'] == -1 ? true : false);
	//	echo $this->db->last_query();
		return $result;

	}
	public function stock_aging ($params=array())
	{
		$min_days = !empty($params['interval'])?$params['interval']:30;
		$min_days = 4 * $min_days;
		$cur_date	= gmdate('Y-m-d');
		$date_min 	= date('Y-m-d',strtotime('- '.$min_days.' day',strtotime($cur_date)));
		// $branch 	= isset($params['branch']) ? $params['branch'] : $this->bId;

		get_financial_dates($cur_date,$start_date, $end_date);
		if ($date_min<$start_date)
		{
			// Check Current Date – 120 Days >= Current FY Start Date. Use St.Date = Current FY Start Date
		// 	$start_date = $date_120;
		// } else {
			// Else St.Date=Last Year Financial Start Date
			get_financial_dates($date_min,$start_date, $end_date);
		}
		$params['aging']		= true;
		$params['from_date'] 	= $start_date;
		$params['to_date'] 		= $cur_date;
		$params['page']			= !empty($params['page'])?$params['page']:1;

		// prepare sall and sout query
		$query = $this->fifo_query($params);

		if (!$query) {
			return array();
		}
		$result['page'] = $query['page'];

		$union_sall		= $query['union_sall'];
		$opening_filter = $query['opening_filter'];
		$other_filter 	= $query['other_filter'];
		$ratequery = '';
		if(!empty($params['rate'])){
			$ratequery = ',round(SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.$params['interval'].' day',strtotime($params['to_date']))).'" AND "'.$params['to_date'].'"  THEN If (inValQty > 0 and inValue>=0 , if (expenseQty=0, inValue, Round((inValQty-expenseQty) * (inValue/inValQty),2)),0) ELSE 0 END),2) AS "rec_30_val",
						round(SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.(2*$params['interval']).' day',strtotime($params['to_date']))).'" AND "'.date('Y-m-d',strtotime('- '.(($params['interval'])+1).' day',strtotime($params['to_date']))).'"  THEN If (inValQty > 0 and inValue>=0 , if (expenseQty=0, inValue, Round((inValQty-expenseQty) * (inValue/inValQty),2)),0) ELSE 0 END),2) AS "rec_60_val",
						round(SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.(3*$params['interval']).' day',strtotime($params['to_date']))).'" AND "'.date('Y-m-d',strtotime('- '.((2*$params['interval'])+1).' day',strtotime($params['to_date']))).'"  THEN If (inValQty > 0 and inValue>=0 , if (expenseQty=0, inValue, Round((inValQty-expenseQty) * (inValue/inValQty),2)),0) ELSE 0 END),2) AS "rec_90_val",
						round(SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.(4*$params['interval']).' day',strtotime($params['to_date']))).'" AND "'.date('Y-m-d',strtotime('- '.((3*$params['interval'])+1).' day',strtotime($params['to_date']))).'"  THEN If (inValQty > 0 and inValue>=0 , if (expenseQty=0, inValue, Round((inValQty-expenseQty) * (inValue/inValQty),2)),0) ELSE 0 END),2) AS "rec_120_val",
						round(SUM(case when tDate < "'.date('Y-m-d',strtotime('- '.(4*$params['interval']).' day',strtotime($params['to_date']))).'" THEN If (inValQty > 0 and inValue>=0 , if (expenseQty=0, inValue, Round((inValQty-expenseQty) * (inValue/inValQty),2)),0) ELSE 0 END),2) AS "rec_121_val"';
		}
		/*$query = 'WITH 
			sAll AS ('.$query['sAll'].'),
			sOUT AS ('.$query['sOut'].') 
			select itemId,itemName,SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.$params['interval'].' day',strtotime($params['to_date']))).'" AND "'.$params['to_date'].'"  THEN inValQty-expenseQty ELSE 0 END) AS "rec_30", 
			SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.(2*$params['interval']).' day',strtotime($params['to_date']))).'" AND "'.date('Y-m-d',strtotime('- '.(($params['interval'])+1).' day',strtotime($params['to_date']))).'" THEN inValQty-expenseQty ELSE 0 END) AS "rec_60", 
			SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.(3*$params['interval']).' day',strtotime($params['to_date']))).'" AND "'.date('Y-m-d',strtotime('- '.((2*$params['interval'])+1).' day',strtotime($params['to_date']))).'" THEN inValQty-expenseQty ELSE 0 END) AS "rec_90", 
			SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.(4*$params['interval']).' day',strtotime($params['to_date']))).'" AND "'.date('Y-m-d',strtotime('- '.((3*$params['interval'])+1).' day',strtotime($params['to_date']))).'" THEN inValQty-expenseQty ELSE 0 END) AS "rec_120",
			SUM(case when tDate < "'.date('Y-m-d',strtotime('- '.(4*$params['interval']).' day',strtotime($params['to_date']))).'" THEN inValQty-expenseQty ELSE 0 END) AS "rec_121" ,
			round(sum(inQty-outQty),3) AS bqty,
			round(sum(If (inValQty > 0 and expenseQty>=0, if (expenseQty=0, inValue, Round(expenseQty * (inValue/inValQty),2)),0)) ,2) as bvalue
			'.$ratequery.' from ('.$union_sall.') sINOUT group by itemId'
			.(!empty($params['show_attrs'])? ' ,itemAttrId':'')
			// .(!empty($params['zeroStocks'])? ' having bqty<>0':'')
			.' ORDER BY itemName,itemId';*/

		$query = '
			select itemId,itemName,SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.$params['interval'].' day',strtotime($params['to_date']))).'" AND "'.$params['to_date'].'"  THEN inValQty-expenseQty ELSE 0 END) AS "rec_30", 
			SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.(2*$params['interval']).' day',strtotime($params['to_date']))).'" AND "'.date('Y-m-d',strtotime('- '.(($params['interval'])+1).' day',strtotime($params['to_date']))).'" THEN inValQty-expenseQty ELSE 0 END) AS "rec_60", 
			SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.(3*$params['interval']).' day',strtotime($params['to_date']))).'" AND "'.date('Y-m-d',strtotime('- '.((2*$params['interval'])+1).' day',strtotime($params['to_date']))).'" THEN inValQty-expenseQty ELSE 0 END) AS "rec_90", 
			SUM(case when tDate BETWEEN "'.date('Y-m-d',strtotime('- '.(4*$params['interval']).' day',strtotime($params['to_date']))).'" AND "'.date('Y-m-d',strtotime('- '.((3*$params['interval'])+1).' day',strtotime($params['to_date']))).'" THEN inValQty-expenseQty ELSE 0 END) AS "rec_120",
			SUM(case when tDate < "'.date('Y-m-d',strtotime('- '.(4*$params['interval']).' day',strtotime($params['to_date']))).'" THEN inValQty-expenseQty ELSE 0 END) AS "rec_121" ,
			round(sum(inQty-outQty),3) AS bqty,
			round(sum(If (inValQty > 0 and expenseQty>=0, if (expenseQty=0, inValue, Round(expenseQty * (inValue/inValQty),2)),0)) ,2) as bvalue
			'.$ratequery.' from ('.$union_sall.') sINOUT group by itemId'
			.(!empty($params['show_attrs'])? ' ,itemAttrId':'')
			// .(!empty($params['zeroStocks'])? ' having bqty<>0':'')
			.' ORDER BY itemName,itemId';

		$result = $this->db->query($query)->result_array();

		return $result;
		
		// $where = array('it.cId' => $this->cId, 'it.isinventory'  => 1, 'it.type' => 'G');
		// // get items
		// $this->db->select('it.itemId,it.name')->from('items as it');
		// if ($branch)
		// {
		// 	if ($branch!=-1)
		// 	{				
		// 		$where['ic.bId'] 		= $branch;
		// 		$this->db->select('ic.curstk');
		// 		$this->db->join('items_cur as ic','ic.itemId=it.itemId and ic.cid=it.cid');
		// 	} else 
		// 	{
		// 		// main branch stk qty stored in items table itself for all branch include
		// 		$this->db->select('sum(it.curstk,ifnull(ic.curstk,0)) as curstk');
		// 		$this->db->join('items_cur as ic','ic.itemId=it.itemId and ic.cid=it.cid','left');
		// 	}
		// } else 
		// {
		// 	$this->db->select('it.curstk');
		// }
		// $this->db->where($where);
		// $this->db->group_by('it.itemId');
		// $this->db->order_by('it.name');
		// $this->db->having('curstk > 0');
		// if (!empty($data['export_type']))
		// {
		// 	if ($from) {
		// 		$this->db->limit($page_limit, $from);
		// 	} else {
		// 		$this->db->limit($page_limit);
		// 	}
		// }
		// $result = $this->db->get()->result_array();

		return $result;
	}
	public function disposedWastageStock($params) {
		$mainBranch = isset($params['branch']) && $params['branch'] == 0 ? 1 : '';
		get_financial_dates($params['to_date'],$start_date, $end_date);
		if(!empty($params['from_date'])) {
			$start_date = $params['from_date'];
		}
		$firstquery = "";
		$secondquery ="";
		$types = array("WE" => "Expired","WD" => "Damaged","WL" => "Lost / Missing","WT" => "Damaged in Transit","DI" => "Disposed");	
		//if((isset($params['branch']) && ($params['branch'] == -1 || $mainBranch)) || empty($params['branch'])) {
			$this->db->select("it.itemId, it.name, it.sku,  se.cid, se.locid as bid, 
			Round(sum((si.qty *  -1) * if(itr.convFactor, itr.convFactor, 1)),2) as curstk ,si.unit,se.sType,si.itemAttrId,it.uom");
			$this->db->from("stock_entries AS se");
			$this->db->join("stock_items AS si","si.sId=se.id");
			$this->db->join("items  AS it","it.itemId=si.itemId");
			$this->db->join("itemrelunits AS itr","itr.itemId=si.itemId and itr.relUnitName=si.unit","left");
			$this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=it.itemId');
			$where = array('se.cId' => $this->cId);	
			$where['se.sDate >= '] = $start_date;
			$where['se.sDate <= '] = $params['to_date'];
			if(!empty($params['wtype'])){
				$where['se.sType'] = $params['wtype'];
			}else{
			$this->db->where_in('se.sType', array("DI","WE","WD","WL","WT"));
			}
			if (isset($params['branch'])) {
				user_branch_filter('se.locId',array($params['branch']));
			}
			$this->db->where($where);
			if(!empty($params['catIds'])){
				$this->db->where_in('ic.catId', $params['catIds']);
			}
			if (!empty($params['itemId'])) {
				$this->db->where_in('it.itemId', $params['itemId']);
			}
			$this->db->group_by('itemId,sType');
		
		/*	$firstquery = $this->db->get_compiled_select();
			if(isset($params['branch']))
				$firstquery .=  " union all ";
		}
	
		if(isset($params['branch'])) {
			if($params['branch'] > 0)
				$branchCondition = "IF(c.csType = 'L' and c.bid !=".$params['branch']." and c.id != ".$params['branch'].", c.bId, se.locId) AS bid,";
			else 
				$branchCondition = "IF(c.bid=".$params['branch']." OR (c.csType='L' and IFNULL(ppb.bid, -2)=".$params['branch']."), IF(c.csType = 'L' and c.bid !=".$params['branch'].", c.bId, se.locId), -2) as bid,";
			$this->db->select("it.itemId, it.name, it.SKU, it.cId, ".$branchCondition." Round(sum((si.qty *  -1) * if(itr.convFactor, itr.convFactor, 1)),2) as curstk, si.unit,se.sType,si.itemAttrId,it.uom");
			$this->db->from("stock_entries AS se");
			$this->db->join("stock_items AS si","si.sId=se.id");
			$this->db->join("items AS it","it.itemId=si.itemId");
			$this->db->join("contacts as c","c.id = se.locId");
			$this->db->join("contacts as ppb","ppb.id = c.bid","left");
			$this->db->join("itemrelunits AS itr","itr.itemId=si.itemId and itr.relUnitName=si.unit","left");
			$where = array('se.cId' => $this->cId);	
			$where['se.sDate >= '] = $start_date;
			$where['se.sDate <= '] = $params['to_date'];
			if(!empty($params['wtype'])){
				$where['se.sType'] = $params['wtype'];
			}else{
				$this->db->where_in('se.sType', array("DI","WE","WD","WL","WT"));
			}
			$this->db->where($where);
			if(!empty($params['branch']) && $params['branch'] != -1) {
			$this->db->group_start();
				$this->db->where("se.locid",$params['branch']);
				$this->db->or_where("c.bid",$params['branch']);
					$this->db->or_where(" ( c.csType = ","L");
					$this->db->where("IFNULL(ppb.bid,-2)",$params['branch']);
				$this->db->group_end();
			$this->db->group_end();
			}
			$this->db->group_by('itemId,bId,sType');
		
			$secondquery = $this->db->get_compiled_select();
		}
		$query = "select * from (".$firstquery.$secondquery.") src GROUP BY src.bId, src.itemId,src.sType";
		$result['items'] = $this->db->query($query)->result_array();
		*/
		$from = 0;
		if (!empty($params['page']) && empty($params['f_type'])) {
			$page_limit = $this->config->item('page_limit');
			$from = ($params['page'] - 1) * $page_limit;
			if ($from) {
				$this->db->limit($page_limit, $from);
			} else {
				$this->db->limit($page_limit);
			}

		}
		$result['items'] = $this->db->get()->result_array();
		if(!empty($result['items'])){
			foreach($result['items'] as $key => $val){
				if(!empty($val['sType'])){
					$val['wastagetype'] =  $types[$val['sType']]; 
				}else{
					$val['wastagetype']  = "";
				}
				$result['items'][$key]  = $val;
			}
		}
		if (!empty($params['attrValues']) && $result['items']) {
			$this->db->select('ita.itemAttrId, ita.sku, ita.saleRate, a.attrId, a.attrGrpId, a.name AS text, ag.name, ag.grpCode, ag.fldType, ag.isPrint, ag.sortNo', false);
			$this->db->from('item_attr as ita');
			$this->db->join('item_attr_link as ial', 'ial.itemAttrId=ita.itemAttrId');
			$this->db->join('attributes as a', 'a.attrId=ial.attrId');
			$this->db->join('attributes_group as ag', 'ag.attrGrpId=a.attrGrpId', 'left');
			$this->db->where(array(
				'ita.cId' => $this->cId,
			));
			$tmp = $this->db->get()->result_array();
			if ($tmp) {
				// $attr_values  = array();
				$attr_values = array(0 => array(''));
				foreach ($tmp as $row) {
					
					if (empty($attr_values[$row['itemAttrId']])) {
						$attr_values[$row['itemAttrId']] = [];
					}
					if ($row["fldType"] == "D") {
						$row["text"] = preg_replace("/(\d{4})-(\d{2})-(\d{2})/i", "$3/$2/$1", $row["text"]);
					}
					$attr_values[$row['itemAttrId']][] = $row['name'] . ' : ' . '<b>' . $row['text'] . '</b>';
					
				} 
				
				foreach ($result['items'] as $d_key => $row) { 
					$result['items'][$d_key]['attrs'] = '';
					if ( !empty($attr_values[$row['itemAttrId']])) {
						$result['items'][$d_key]['attrs'] = implode(", ", $attr_values[$row['itemAttrId']]);
					}
					
				}
				
			}
		}
		//print_R($result);exit;
			return $result;
	}
	public function batchAttr($params) {
		$params['groupByCust'] = !empty($params['groupByCust']) ? $params['groupByCust'] : 0;
		$batchwise_stk = true;
		if(empty($params['batchwise_stock'])){
			$batchwise_stk = false;
			$params['to_date'] = $params['from_date'] = !empty($params['tDate'])?$params['tDate']:(!empty($params['to_date'])?$params['to_date']:gmdate('Y-m-d'));
		}
		$params['stk_type'] = !empty($params['stk_type'])?$params['stk_type']:'current';
		if (sal_mod_active(BRANCH_MOD) && !isset($params['branch'])) {
			$params['branch']=-1;
		}
		if(empty($params['itemId']) && !empty($params['itemName'])){
			$this->load->model("itemsModel");
			$params['itemId'] = $this->itemsModel->get_itemids($params['itemName']);
		}
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;
		// include currency code
		$isMulcur = !empty($params['transaction'])?true:false;

		if ($isMulcur)
		{
			$this->db->select('it.currencyCode');
		}
		$this->batch_select($params);
		$this->batch_from($params,false,true);
		$this->batch_trans_where($params);
		if(!empty($params['expDateFilter']) && empty($params['brachQty'])) {
			$this->expiry_filter(false,$params);
		}
		$trans_query = $this->db->get_compiled_select();
		//print_r($trans_query);exit;
		if ($isMulcur)
		{
			$this->db->select('it.currencyCode');
		}
		$this->batch_stock_select($params);
		$this->batch_from($params,true);
		$this->batch_stock_where($params);
		if(!empty($params['expDateFilter']) && empty($params['brachQty'])) {
			$this->expiry_filter(true,$params);
		}
		$stock_query = $this->db->get_compiled_select();
		
		$stock_query_tl = '';		
		// if (empty($params['itemId']) && !empty($params['attrValues'])) { current stock item total with attributes 
		if (empty($params['transaction']) && !empty($params['attrValues'])) {
			// $query .=",itemAttrId";
			$hvg_attr = ''; // get othere count for current stock
			$trans_query = $trans_query . $hvg_attr;
			$stock_query = $stock_query . $hvg_attr;
			if (!empty($stock_query_tl)) {
				$stock_query_tl = str_replace('si.itemAttrId', '"-1" as itemAttrId', $stock_query_tl) . ' UNION ALL ' . $stock_query_tl . $hvg_attr;
			}
		}
	//	print_R($trans_query);
		$union = "$trans_query UNION ALL $stock_query ".($stock_query_tl?" UNION ALL $stock_query_tl ":'');
		
		if (empty($params['itemId']) && empty($params['zeroStocks']) && empty($params['expDateFilter'])) { // include zero stocks items
			$pur_qty = ',null as pur_qty';
			if ($params['stk_type']=='alert' || $params['stk_type']=='current') {
				$this->db->select('0 as itemAttrId, 0 as  pi_rate,saleRate,',false);
			}
			$this->db->select('0 as mrp, it.stkLevel,it.uom,0 as s_qty, 0 as  p_qty'.$pur_qty.', it.itemId, it.name AS itemName, it.SKU,"" as iarSKU,0 as conId', false);
			if (!empty($params['catColumn'])) {
				$this->db->select('group_concat(distinct c.name) as catName');
			}
			$this->db->from('items as it');
			$this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=it.itemId');
			$this->db->join('category AS c','c.id=ic.catId');
			$where = array('it.cId' => $this->cId);
			if (!empty($params['brachQty'])) {
				$this->db->select('0 as locId', false);
			}
			if (!empty($params['item_type'])) {
				$where[$params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase >'] = 0;
			}
			$this->db->where($where);
			if (!empty($params['catColumn'])) {
				$this->db->group_by('it.itemId');
			}
			$union = $union . ' UNION ALL ' . $this->db->get_compiled_select();
		} // include zero stocks items

		

		$union = " from (".$union.") uniontable ";
		
		//OB: If filter items for Contact
		$con_query = '';
		
		if (!empty($params['conId'])) {
			// $con_where = array();
			// $this->db->select('DISTINCT it.itemId', false);
			// $this->db->from('trans_items AS ti');
			// $this->db->join('items AS it', 'it.itemId=ti.itemId');
			// $this->db->join('trans AS t', 'ti.transid=t.id');
			// $con_where['t.conId'] = $params['conId'];
			// if (!empty($params['itemId'])) {
			// 	// $where['it.itemId'] = $params['itemId'];
			// 	$this->db->where_in('it.itemId', $params['itemId']);
			// }
			// $this->db->where($con_where);
			// if (isset($params['branch'])) {
			// 	user_branch_filter('t.bId', array($params['branch']));
			// }
			if (!empty($params['item_type'])) {
				$this->db->where($params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase >', 0);
			}
			// $union .= ' where itemId in (' . $this->db->get_compiled_select() . ') ';
		}

		$curStk = '';		
		switch ($params['stk_type']) {
			case 'alert':
				$query = "select itemId,ROUND(sum(p_qty),3) as p_qty,ROUND(sum(s_qty),3) as s_qty,itemName,SKU";
				$query .= ",max(mrp) as mrp,ROUND(sum(pi_rate)/sum(p_qty),2) AS pi_rate,ROUND(stkLevel,3) AS stkLevel ".$union." group by itemId, itemAttrId HAVING (p_qty-s_qty) <= stkLevel";
			break;
			default:
				// $query = ",max(mrp) as mrp,itemAttrId ";
				$query = ",saleRate,max(mrp) as mrp,";
				if ($isMulcur) {
					$query.='currencyCode,';
				}
				if ($params['stk_type']=='current') {
					$query .="ROUND(sum(pi_rate)/sum(ifnull(pur_qty,p_qty)),2) AS pi_rate,";
				}
				$query .= (empty($params['attrValues'])?"itemAttrId":"itemAttrId ");
				// $query .= ",Replace(Replace(iarSKU,'#TID',''),'#SID','') as iarSKU,max(conId) as conId, isStock";
				$query .= ",iarSKU";
				if(!empty($params['batchwise_stock'])){
					$query .= ',rate';
				}
				// include category name
				if (!empty($params['catColumn'])) {
					$query .= ",catName";
				}
				$query.=$union." group by itemId,itemAttrId ";
				if (!empty($params['attrValues'])) {
					$query .= ",itemAttrId ";
				}
				if (empty($params['brachQty'])) {
					$newField = '';
					if(!empty($params['rpType']) && $params['rpType'] == 'STE') {
						$newField = ',expDate,batchName';
					}
					$query = "select itemId,uom,ROUND(sum(p_qty),3) as p_qty,ROUND(sum(s_qty),3) as s_qty,itemName,SKU ".$newField.$query;
				} else {
					$query = "select uom,locId,itemId,ROUND(sum(p_qty-s_qty),3) as qty ".$query.",locId ";
				}
		
				if (!empty($params['zeroStocks'])) { // exclude zero stocks items only in current stock
					$curStk = (!empty($params['transaction']) || ($params['rpType']!='STC' && $params['rpType']!='STM'))?"<>":"<>";//HAVING (p_qty-s_qty)>0":" HAVING (p_qty-s_qty)<>0";
				} 
				else if (!empty($params['attrValues']) && empty($params['brachQty']) && !$batchwise_stk) {
					if ($params['rpType']!='STC' && $params['rpType']!='STM')
					{
						$curStk = "<>";
					}
					// echo "came else";
				}

				if ($params['rpType']=='STE')
				{ /* stock expiry report ignore 0 qty */
					$curStk = "<>";
				}
				$curStk = "<>";
				if (empty($params['smartmerge'])) {
					// for smart merge query ignore having
					$query.= $curStk? "HAVING (p_qty-s_qty) ".$curStk." 0":"";
				}
				if (empty($params['transaction']) && ($params['rpType']=='STC' || $params['rpType']=='STM'))
				{
					$query.= (!empty($params['zeroStocks'])?' OR itemAttrId=-1':'');
				}

		}		

		if (!empty ($params['prepared_query'])) {
			// stock category report average purchase rate
			return $query;
		}

		$limit = '';
		if (empty($params['export_type']) && empty($params['itemExport']) && empty($params['transaction']) && !$batchwise_stk) {
			$page_limit = $this->config->item('page_limit');
			$params['page'] = !empty($params['page']) ? $params['page'] : '1';
			$from = ($params['page'] - 1) * $page_limit;
			if(empty($params['f_type']))
				$limit = " limit " . $from . ',' . $page_limit;
		}
		
		//Atttributes Join
		
	
		/*$_cnt = $this->db->select("count(id) as cusCnt")->from("compfields")->where(array("cId" => $this->cId,"isActive" => 1,'tType' => "IT"))->get()->row_array();
		//Custom fields
		$this->db->select('fv.modId as ItemId, GROUP_CONCAT(CONCAT(f.fname,"\t",fv.fvalue) order by f.orderId SEPARATOR "\n") as cfList');
		$this->db->from('compfields as f');
		$this->db->join('field_values as fv', 'fv.fid=f.id');
		
	
		$this->db->where("fv.modType","I");
		$this->db->where("f.ttype","IT");
		$this->db->where("f.cId",$this->cId);
		$this->db->group_by("fv.modId");	
		$custQuery = $this->db->get_compiled_select();
		$custQuery = " LEFT JOIN (".$custQuery.") as cf on cf.itemId=itms.ItemId";*/

		// $wholeSelect = "SELECT UT.*, IF(UT.isStock=1, st.id, tt.id) AS transId, IF(UT.isStock=1, st.stNo, tt.tNo) AS tNo, IF(UT.isStock=1, st.sDate, tt.tdate) AS tdate, IFNULL(tc.name, '') as conName, IF(UT.isStock=1, st.sType, tt.tType) AS tType, IF(UT.isStock=1, st.id, tt.id) AS id";
		$wholeSelect = "SELECT UT.*, IFNULL(tt.conid, st.locId) AS conId, IF(tt.id IS NOT NULL, 0, 1) AS isStock, IFNULL(tt.id, st.id) AS transId, IFNULL(tt.tNo, st.stNo) AS tNo, IFNULL(tt.tdate, st.sDate) AS tdate, IF(tc.name IS NULL, (CASE WHEN st.sType='MJ' THEN 'Mfg.Jrnl' WHEN st.sType='PO' THEN 'Production' ELSE '' END), tc.name) AS conName, IFNULL(tt.tType, st.sType) AS tType, IFNULL(tt.id, st.id) AS id";

		if(!empty($params['groupByCust']))
		{
			$wholeSelect .= ", ROUND(sum(UT.s_qty),3) as s_qty, ROUND(sum(UT.p_qty),3) as p_qty";
		}

		if ($isMulcur)
		{
			$wholeSelect.=', currencyCode';
		}

		$_end = "";
		if (!empty($params['from_date']))
		{
			$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
			$to_date = $params['to_date'];
			get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
			 // get openning
			$where['t.tDate >='] = $fin_start_date;
			$where['t.tDate <='] = $to_date;
		}

		$__join = "";
		$__join .= "LEFT JOIN ob_trans_items tti on Right(UT.iarsku,4) = '#TID' AND tti.id=CAST(Replace(UT.iarSKU,'#TID','') as Unsigned) ";
		$__join .= "LEFT JOIN ob_trans tt on tt.id=tti.transId ";
		$__join .= "LEFT JOIN ob_stock_items ssi on Right(UT.iarsku,4) = '#SID' AND ssi.id=CAST(Replace(UT.iarSKU,'#SID','') as Unsigned) ";
		$__join .= "LEFT JOIN ob_stock_entries st on st.id=ssi.sId ";
		$__join .= "LEFT JOIN ob_contacts tc on tc.id=tt.conId ";

		// if(empty($params['itemId']) || empty($params['conId']))
		// {
		// 	$__join .= "WHERE (ttype IN ('PI', 'PR', 'EI', 'PE', 'PD', 'GR', 'SC') OR sType IN ('MJ', 'PO')) ";
		// }

		if(empty($params['groupByCust']) && (empty($params['itemId'] ) && !empty($params['itemName']) || !empty($params['conId'])))
		{
			// if(!empty($params['itemName']))
			// {
			// 	$__join .= " AND UT.itemName like '%".$params['itemName']."%'";
			// }
			if(!empty($params['conId']))
			{
				$__join .= " WHERE IFNULL(tc.id, 0) = ".$params['conId'];
			}
		}

		if($params['groupByCust'] == 1)
		{
			$wholeSelect = "select tt.tDate, UT.itemId, UT.itemname, sum(p_qty) as p_qty, sum(s_qty) as s_qty, sum(p_qty-s_qty) as qty, sum(pi_rate) as pi_rate, UT.uom, sku, tt.conId, IFNULL(tc.name, '') as conName ";
    		$__join .= "GROUP BY itemId, conId with ROLLUP ";
			$_wholeSelect = "select itemId,tDate, itemName, qty ,p_qty,s_qty,pi_rate, UOM, sku, IF(conid IS NOT NULL,conName,'') as conName, conId";
			$_end = " tall where  itemId is NOT NULL ";
			if(!empty($params['conId']))
			{
				$_end .= " AND conId = ".$params['conId'];
			}
			$_end .= " order by itemName,conId ";
		}
		else if($params['groupByCust'] == 2)
		{
			$wholeSelect = "select tt.tDate, UT.itemId, UT.itemname, sum(p_qty) as p_qty, sum(s_qty) as s_qty, sum(p_qty-s_qty) as qty, sum(pi_rate) as pi_rate, UT.uom, sku, tt.conId, ifnull(tc.name, '') as conName";
   			$__join .= "GROUP BY conId, itemId with ROLLUP ";
			
			$_wholeSelect = "select itemId, tDate, IF(itemid IS NOT NULL,itemName,'') as itemName, qty , p_qty,s_qty,pi_rate,UOM, sku, conName, conId";
			$_end = " tall where  conId is NOT NULL ";
			if(!empty($params['conId']))
			{
				$_end .= " AND conId = ".$params['conId'];
			}
			$_end .= " order by conName,itemId ";
		}
		else
		{
			if(empty($params['itemId']) && empty($params['conId']))
			{
				$__join .= "ORDER BY itemName ";
			}

			// $wholeSelect = "select UT.*, IF(UT.isStock=1, st.id, tt.id) AS transId, IF(UT.isStock=1, st.stNo, tt.tNo) AS tNo, IF(UT.isStock=1, st.sDate, tt.tdate) AS tdate, IF(tc.name IS NULL, (CASE WHEN st.sType='MJ' THEN 'Mfg.Jrnl' WHEN st.sType='PO' THEN 'Production' ELSE '' END), tc.name) as conName, IF(UT.isStock=1, st.sType, tt.tType) AS tType, IF(UT.isStock=1, st.id, tt.id) AS id";
			$wholeSelect = "SELECT UT.*, IFNULL(tt.conid, st.locId) AS conId, IF(tt.id IS NOT NULL, 0, 1) AS isStock, IFNULL(tt.id, st.id) AS transId, IFNULL(tt.tNo, st.stNo) AS tNo, IFNULL(tt.tdate, st.sDate) AS tdate, IF(tc.name IS NULL, (CASE WHEN st.sType='MJ' THEN 'Mfg.Jrnl' WHEN st.sType='PO' THEN 'Production' ELSE '' END), tc.name) AS conName, IFNULL(tt.tType, st.sType) AS tType, IFNULL(tt.id, st.id) AS id";
		}
		
		//print_R($item_ids);exit;
		//	$wholeSelect .= ",IFNULL(cf.cflist,'') as cfList";
		if($params['groupByCust'] == 0) 
			$list_query = $this->db->query($wholeSelect." from ( ".$query." ) UT ".	$__join.$limit );
		else
			$list_query = $this->db->query($_wholeSelect ." from ( " . $wholeSelect." from ( ".$query." ) UT ".	$__join.' )'.$_end.$limit);
	
		if($params['groupByCust'] == 0) {
			$totalquery = $wholeSelect." from ( ".$query." ) UT ".	$__join;
		}
		else {
			if($params['groupByCust'] == 1) {
				
				$_end = " tall where  itemId is NOT NULL AND conId is NULL  order by itemName,conId ";
			}
			else {
				$_end = " tall where  conId is NOT NULL AND itemId is NULL  order by itemName,conId ";
			}
			$totalquery = $_wholeSelect ." from ( " . $wholeSelect." from ( ".$query." ) UT ".	$__join.' )'.$_end;
		}
		$result['items'] = $items = $list_query->result_array();

		//print_R($result['items']);
		if (!empty($params['transaction'])) {
			// return if from transaction page
			return $items;
		}
	//	print_R($totalquery);
		$bal_select = 'SELECT sum(p_qty - s_qty) AS totQty,sum((p_qty - s_qty) * pi_rate) as totValue FROM ('.$totalquery.') src ';
		if(!empty($params['attrValues'])) {	
			$bal_select .= ' where src.itemAttrId != -1';
		}
		$bal_query = $this->db->query($bal_select);
		$result['totals'] = $bal_query->row_array();
		
		// group attribute quantity
		$group_attr = false;
		if (empty($params['brachQty']) && !empty($params['attrValues']) && !empty($params['group_attr'])) {
			$group_attr = true;
		}

		if (!empty($params['attrValues']) && $result['items']) {
			$ispdf = false;
			if(!empty($params['export_type'])){
				if($params['export_type'] == "pdf"){
					$ispdf = true;	
				}
			}
			if(!empty($params['batchwise_stock'])){
				$ispdf = true;
			}
			$is_current = ($params['stk_type'] == 'current' && empty($params['batchwise_stock'])) ? true : false;
			$params['group_attr'] = $group_attr;
			$params['curStk'] = $curStk;
			//$result = $this->get_attributes($result,$params,$limit?true:false,$ispdf,$is_current);
			
		}
		
	//	print_r($result);
		// exit;
		return $result;
	}
	public function batch_select($params=array()) {
		$detail = (!empty($params['inward_details']) || !empty($params['outward_details'])) ? true : false;
		$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
		$to_date = $params['to_date'];
		get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
		$opening = isset($params['opening']) ? $params['opening'] : 0; // opening balance import

		$open_ttype = '"' . PURINV . '","'.PURRETAIL.'","' . EXPINV .'","' . EXPRETAIL . '","' . PURDBNOTE . '","' . PURRECP . '","' . CRNOTE . '"';
		$pur_ttype = '"' . PURINV . '","'.PURRETAIL.'","' . EXPINV .'","' . EXPRETAIL . '","' . PURDBNOTE . '","' . CRNOTE . '","' . PURRECP . '"';
		$cd_ttype = '"' . PURCRNOTE . '","' . PURDBNOTE . '","' . DBNOTE . '","' . CRNOTE . '"';
		// print_r($params);exit;
		switch ($params['stk_type']) {
			case 'summary': // stock summary
				if (!$detail) {
					$this->db->select('t.tType,ti.locId, ti.itemAttrId, ti.itemId, if(it.name!="",it.name,ti.itemName) as itemName, it.uom AS uom,it.HS as hsn,it.SKU, iar.SKU as iarSKU,If (t.ttype IN ("PI", "PR", "EI", "PE", "PD", "GR", "SC"), t.conId,0) as conId', false);
					$this->db->select('(ti.qty+ti.freeQty) * If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), 1, -1) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
					$this->db->select('If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $pur_ttype . ') and ti.itemTotal > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1), 0) as op_pur_qty', false);
					$this->db->select('If (t.tDate < "' . $from_date . '", IF( t.ttype IN (' . $pur_ttype . '), if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount, 0),0) as op_pur_amt', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", IF(t.ttype IN (' . $pur_ttype . ') and ti.itemTotal > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1), 0) as i_pur_qty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", IF( t.ttype IN (' . $pur_ttype . '), if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount, 0),0) as i_pur_amt', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, (ti.qty+ti.freeQty))) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount)), 0) AS o_amt', false);
					$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');
					if ($opening) {
						$this->db->select('iar.mrp', false);
					}
				} else {
					$this->db->select('t.id, t.tno, t.tType, t.tDate, t.conName, ti.unit,ti.id as itId', false);
					$this->db->select('((if (ti.itc=1, ti.taxableAmount, ti.itemTotal))/(ti.qty+ti.freeQty)) + ti.chargesAmount  as trate,((ti.qty+ti.freeQty)*if(itr.convFactor, itr.convFactor, 1)) as s_qty,if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount as s_amount,it.uom', false);
				}
			break;
			case 'alert':
			case 'current':
				$this->db->select('ti.itemAttrId,sum(if(t.tType IN (' . $this->inward_tTypes . '),if(ti.itc=1,ti.taxableAmount,ti.itemTotal) + ti.chargesAmount,0) * if (t.tType!="SC",1,0)) AS pi_rate', false);
				$this->db->select('IF(iar.saleRate IS NULL OR iar.saleRate = 0, it.saleRate, iar.saleRate) AS saleRate, IF(iar.mrp IS NULL OR iar.mrp = 0, it.mrp, iar.mrp) AS mrp, it.stkLevel,', false);
				
				$this->db->select('it.uom',false);
				$this->db->select('sum(IF(t.ttype NOT IN (' . $this->inward_tTypes . '), (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1)) as s_qty', false);
				$this->db->select('sum(IF(t.ttype IN (' . $this->inward_tTypes . '), (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1)) as p_qty', false);
				$this->db->select('sum(IF(t.ttype IN (' . $this->inward_tTypes . '), (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1) * if (t.tType!="SC",1,0)) as pur_qty', false); // to ignore sc
				if (!empty($params['brachQty'])) {
					$this->db->select('it.itemId,ti.locId');
				} else {
					$this->db->select('it.itemId,if(it.name!="",it.name,ti.itemName) as itemName,it.SKU, iar.SKU as iarSKU', false);
				}
				// $this->db->select("t.conId as conId, 0 AS isStock");
				// include category name
				if (!empty($params['catColumn'])) {
					// $this->db->select('group_concat(distinct c.name) as catName');
					$this->db->select('ic.name as catName');
				}
				if(!empty($params['batchwise_stock'])){
					$this->db->select(',ti.rate',false);
				}
			break;
			case 'stock_value':
				$this->db->select('ti.itemAttrId,ti.itemId as itemId', false);
				$this->db->select('IF(t.ttype IN (' . $this->inward_tTypes . '), 1, -1) * (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) as stk_qty', false);
				$this->db->select('IF(t.ttype IN (' . $pur_ttype . ') and t.tType!="SC" and ti.taxableAmount > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1) as pur_qty', false);
				$this->db->select('IF(t.ttype IN (' . $pur_ttype . ') and t.tType!="SC", if (ti.itc=1, ti.taxableAmount, ti.itemTotal)+ ti.chargesAmount, 0) as pur_amt', false);
				$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');	
	
			break;
			case 'stock_ledger':
				$this->db->select('t.id, t.tno, t.tType, t.tDate, t.conName, it.uom, ti.unit,ti.id as itId, 0 as stck', false);
				if(!empty($params['serialIds'])){
					$this->db->select('If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), IF(count(ots.tsItemId) > 1,1,(ti.qty+ti.freeQty)) * -1) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), IF(count(ots.tsItemId) > 1,1,(ti.qty+ti.freeQty)), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, IF(count(ots.tsItemId) > 1,1,(ti.qty+ti.freeQty)))) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
				}else{
					$this->db->select('(ti.qty+ti.freeQty) * If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), 1, -1) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, (ti.qty+ti.freeQty))) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
				}
				
				
				if(!empty($params['batchwise_stock'])){
					$this->db->select('iar.itemAttrId,it.itemId,ti.rate,0 as isStock',false);
				}
			break;
			// case 'ledger_balance':
			// 	$this->db->select('ti.itemAttrId, ti.itemId, if(it.name!="",it.name,ti.itemName) as itemName, it.uom AS uom', false);
			// 	$this->db->select('If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), 1, -1) * (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
			// 	$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), 0) - If (t.ttype in (' . $cd_ttype . ') and treftrans.tDate >= "' . $from_date . '",(ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
			// 	$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, (ti.qty+ti.freeQty)) - If (t.ttype in (' . $cd_ttype . ') and treftrans.tDate >= "' . $from_date . '",(ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
			// break;
		}
	}
	public function batch_from($params=array(),$stock=false,$detail=false) {
		$stock_ledger= (!empty($params['stk_type']) && ($params['stk_type'] == "stock_ledger"))?true:false;
/*		FROM
ob_items i
JOIN ob_items_cur icur on icur.itemId=i.itemId and i.curStk > 0
JOIN ob_item_attr ia on ia.itemId=i.itemId and ia.sku != ''
JOIN ob_trans_items ti on ti.itemAttrId=ia.itemAttrId*/


		if (!$stock) {
			$this->db->from('trans AS t');
			$this->db->join('trans_items AS ti', 'ti.transId=t.id');
			//$this->db->join('items AS it', 'it.itemId=ti.itemId AND it.curStk > 0');
			//$this->db->join("items_cur as icur","icur.itemId = it.itemId AND it.curStk > 0");
			//For branches with branch > 0 values will be in items_cur table too 
			if (isset($params['branch']) && $params['branch']!=get_user_data('defaultbId',true))
			{
			
				$this->db->join('items AS it', 'it.itemId=ti.itemId');
				$this->db->join("items_cur as icur","icur.itemId = it.itemId AND icur.bId=ti.locid and icur.curStk > 0");				
			} else {
				$this->db->join('items AS it', 'it.itemId=ti.itemId AND it.curStk > 0');
			}
			$this->db->join('item_attr AS iar', 'iar.itemAttrId = ti.itemAttrId AND (RIGHT(iar.sku, 4) = "#TID" OR RIGHT(iar.sku, 4) = "#SID")');
			$this->db->join('itemrelunits AS itr', 'itr.itemId=ti.itemId and itr.relUnitName=ti.unit', 'left');

			if (!$detail) {
				// $this->db->join('ob_trans_ref as tref', 'tref.transId=t.id', 'left'); removed due to stock summary item qty duplicate on multipe reference
				// $this->db->join('ob_trans as treftrans', 'treftrans.Id=tref.reftransId', 'left');
			}
			if(!empty($params['serialIds'])){
				$serial_select_query = "SELECT ts.tsItemId from " . $this->db->dbprefix('trans_serial'). " as ts WHERE ts.asId IN (" . $params['serialIds'] . ")";
				$this->db->join('trans_serial AS ots','ots.tsItemId = ti.id AND ots.tsItemId IN ('. $serial_select_query . ')');
			}
		} else {
			$this->db->from('stock_entries AS se');
			$this->db->join('stock_items AS si', 'si.sId=se.id');
			//$this->db->join('items AS it', 'it.itemId=si.itemId AND it.curStk > 0');
			if (isset($params['branch']) && $params['branch']!=get_user_data('defaultbId',true))
			{
				$this->db->join('items AS it', 'it.itemId=si.itemId');
				$this->db->join("items_cur as icur","icur.itemId = it.itemId AND icur.bId=si.fromLocId and icur.curStk > 0");
			} else {
				$this->db->join('items AS it', 'it.itemId=si.itemId AND it.curStk > 0');
			}
			//$this->db->join("items_cur as icur","icur.itemId = it.itemId AND it.curStk > 0");
			$this->db->join('itemrelunits AS itr', 'itr.itemId=si.itemId and itr.relUnitName=si.unit', 'left');
			$this->db->join('item_attr AS iar', 'iar.itemAttrId = si.itemAttrId AND (RIGHT(iar.sku, 4) = "#TID" OR RIGHT(iar.sku, 4) = "#SID")');
			if(!empty($params['serialIds'])){
				$serial_select_query = "SELECT ts.tsItemId from " . $this->db->dbprefix('trans_serial'). " as ts WHERE ts.asId IN (" . $params['serialIds'] . ")";
				$this->db->join('trans_serial AS ots', 'ots.tsItemId = si.id AND ots.tsItemId IN(' . $serial_select_query. ')');
			}
		}
		// include category
		if (!empty($params['catId']) || !empty($params['catColumn']) || !empty($params['catIds'])) {
			// $this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=it.itemId');
			// $this->db->join('category AS c','c.id=ic.catId');
			// if(!empty($params['catIds'])){
			// 	print_R($params['catIds']);
			// 	$params['catIds'] = $this->get_child_category($params['catIds']);
			// }
			// $cat_query = '(select distinct itemId from '.$this->db->dbprefix("items_category").' where cId='.$this->cId.' and catId in ('.$params['catIds'].')) sq_exis';
			// $this->db->join($cat_query,'sq_exis.itemId = it.itemId');

			// $this->db->join($cat_query,'ic.itemId=it.itemId',(empty($params['catId']) && empty($params['catIds']))?'left':false);
		} else if (!empty($params['nested_category'])) 
		{
			$this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=it.itemId');
			$this->db->where('ic.catId in (select id from (select * from '.$this->db->dbprefix("category").' where cId='.$this->cId.' order by pId,id) alldata, (select @pgi:='.$params['nested_category'].') init where cId='.$this->cId.' and find_in_set(pId, @pgi) > 0 and @pgi := concat(@pgi,",",id) union all select '.$params['nested_category'].')',null,false);
		} else if(empty($params['catId']) && !empty($params['stock_category']))
		{
			// items not liked with category
			$this->db->join('items_category AS ic', 'ic.cId='.$this->cId.' and ic.itemId=it.itemId','left');
			$this->db->where('ic.catId is NULL',null);
		} 
	}


	public function batch_trans_select($params=array()) {
		$detail = (!empty($params['inward_details']) || !empty($params['outward_details'])) ? true : false;
		$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
		$to_date = $params['to_date'];
		get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
		$opening = isset($params['opening']) ? $params['opening'] : 0; // opening balance import

		$open_ttype = '"' . PURINV . '","'.PURRETAIL.'","' . EXPINV .'","' . EXPRETAIL . '","' . PURDBNOTE . '","' . PURRECP . '","' . CRNOTE . '"';
		$pur_ttype = '"' . PURINV . '","'.PURRETAIL.'","' . EXPINV .'","' . EXPRETAIL . '","' . PURDBNOTE . '","' . CRNOTE . '","' . PURRECP . '"';
		$cd_ttype = '"' . PURCRNOTE . '","' . PURDBNOTE . '","' . DBNOTE . '","' . CRNOTE . '"';
		// print_r($params);exit;
		switch ($params['stk_type']) {
			case 'summary': // stock summary
				if (!$detail) {
					$this->db->select('t.tType,ti.locId, ti.itemAttrId, ti.itemId, if(it.name!="",it.name,ti.itemName) as itemName, it.uom AS uom,it.HS as hsn,it.SKU', false);
					$this->db->select('(ti.qty+ti.freeQty) * If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), 1, -1) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
					$this->db->select('If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $pur_ttype . ') and ti.itemTotal > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1), 0) as op_pur_qty', false);
					$this->db->select('If (t.tDate < "' . $from_date . '", IF( t.ttype IN (' . $pur_ttype . '), if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount, 0),0) as op_pur_amt', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", IF(t.ttype IN (' . $pur_ttype . ') and ti.itemTotal > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1), 0) as i_pur_qty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", IF( t.ttype IN (' . $pur_ttype . '), if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount, 0),0) as i_pur_amt', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, (ti.qty+ti.freeQty))) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount)), 0) AS o_amt', false);
					$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');
					if ($opening) {
						$this->db->select('iar.mrp', false);
					}
				} else {
					$this->db->select('t.id, t.tno, t.tType, t.tDate, t.conName, ti.unit,ti.id as itId', false);
					$this->db->select('((if (ti.itc=1, ti.taxableAmount, ti.itemTotal))/(ti.qty+ti.freeQty)) + ti.chargesAmount  as trate,((ti.qty+ti.freeQty)*if(itr.convFactor, itr.convFactor, 1)) as s_qty,if (ti.itc=1, ti.taxableAmount, ti.itemTotal) + ti.chargesAmount as s_amount,it.uom', false);
				}
				
			break;
			case 'alert':
			case 'current':
				$this->db->select('ti.itemAttrId,sum(if(t.tType IN (' . $this->inward_tTypes . '),if(ti.itc=1,ti.taxableAmount,ti.itemTotal) + ti.chargesAmount,0) * if (t.tType!="SC",1,0)) AS pi_rate,iarSKU', false);
				$this->db->select('IF(iar.saleRate IS NULL OR iar.saleRate = 0, it.saleRate, iar.saleRate) AS saleRate, IF(iar.mrp IS NULL OR iar.mrp = 0, it.mrp, iar.mrp) AS mrp, it.stkLevel', false);
				
				$this->db->select('it.uom',false);
				$this->db->select('sum(IF(t.ttype NOT IN (' . $this->inward_tTypes . '), (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1)) as s_qty', false);
				$this->db->select('sum(IF(t.ttype IN (' . $this->inward_tTypes . '), (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1)) as p_qty', false);
				$this->db->select('sum(IF(t.ttype IN (' . $this->inward_tTypes . '), (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1) * if (t.tType!="SC",1,0)) as pur_qty', false); // to ignore sc
				if (!empty($params['brachQty'])) {
					$this->db->select('it.itemId,ti.locId');
				} else {
					$this->db->select('it.itemId,if(it.name!="",it.name,ti.itemName) as itemName,it.SKU,iar.SKU as iarSKU', false);
				}
				$this->db->select('0 AS isStock');

				// include category name
				if (!empty($params['catColumn'])) {
					// $this->db->select('group_concat(distinct c.name) as catName');
					$this->db->select('ic.name as catName');
				}
				if(!empty($params['batchwise_stock'])){
					$this->db->select(',ti.rate',false);
				}
			break;
			case 'stock_value':
				$this->db->select('ti.itemAttrId,ti.itemId as itemId', false);
				$this->db->select('IF(t.ttype IN (' . $this->inward_tTypes . '), 1, -1) * (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) as stk_qty', false);
				$this->db->select('IF(t.ttype IN (' . $pur_ttype . ') and t.tType!="SC" and ti.taxableAmount > 0, (ti.qty+ti.freeQty), 0) * if(itr.convFactor, itr.convFactor, 1) as pur_qty', false);
				$this->db->select('IF(t.ttype IN (' . $pur_ttype . ') and t.tType!="SC", if (ti.itc=1, ti.taxableAmount, ti.itemTotal)+ ti.chargesAmount, 0) as pur_amt', false);
				$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');	
				
			break;
			case 'stock_ledger':
				$this->db->select('t.id, t.tno, t.tType, t.tDate, t.conName, it.uom, ti.unit,ti.id as itId, 0 as stck', false);
				if(!empty($params['serialIds'])){
					$this->db->select('If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), IF(count(ots.tsItemId) > 1,1,(ti.qty+ti.freeQty)) * -1) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), IF(count(ots.tsItemId) > 1,1,(ti.qty+ti.freeQty)), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, IF(count(ots.tsItemId) > 1,1,(ti.qty+ti.freeQty)))) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
				}else{
					$this->db->select('(ti.qty+ti.freeQty) * If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), 1, -1) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
					$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, (ti.qty+ti.freeQty))) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
				}
				
				
				if(!empty($params['batchwise_stock'])){
					$this->db->select('iar.itemAttrId,it.itemId,ti.rate,0 as isStock',false);
				}
			break;
			// case 'ledger_balance':
			// 	$this->db->select('ti.itemAttrId, ti.itemId, if(it.name!="",it.name,ti.itemName) as itemName, it.uom AS uom', false);
			// 	$this->db->select('If (t.tDate < "' . $from_date . '", IF(t.ttype IN (' . $open_ttype . '), 1, -1) * (ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) , 0) AS opqty', false);
			// 	$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), (ti.qty+ti.freeQty), 0) - If (t.ttype in (' . $cd_ttype . ') and treftrans.tDate >= "' . $from_date . '",(ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS iqty', false);
			// 	$this->db->select('If (t.tDate >= "' . $from_date . '", (IF(t.ttype IN (' . $open_ttype . '), 0, (ti.qty+ti.freeQty)) - If (t.ttype in (' . $cd_ttype . ') and treftrans.tDate >= "' . $from_date . '",(ti.qty+ti.freeQty), 0)) * if(itr.convFactor, itr.convFactor, 1) , 0) AS oqty', false);
			// break;
		}
	}

	public function batch_trans_where($params=array()) {
		$detail = (!empty($params['inward_details']) || !empty($params['outward_details'])) ? true : false;
		// if(isset($params['batchwise_stock']) && !empty($params['batchwise_stock'])){
		// 	$detail = true;
		// }
		$isReorder = $params['stk_type']=='reorder'?true:false;
		$stktype = !empty($params['expDetail']) ? 'current' : $params['stk_type'];
		switch ($stktype) {
			case 'stock_ledger':
				$ss_tTypes = array(CRNOTE, PURINV, PURRETAIL, EXPINV, EXPRETAIL, PURDBNOTE, PURRECP,SALINV, SALRETAIL, DBNOTE, DELCHALLAN, PURCRNOTE);
				$ss_return = array(CRNOTE, PURDBNOTE,DBNOTE, PURCRNOTE);
				$ss_ref = array(SALINV, SALRETAIL, PURINV,PURRETAIL, EXPINV, EXPRETAIL);
			break;
			case 'reorder':
				$ss_ref = $ss_return = $ss_tTypes = array();
				$ss_tTypes = array(SALORD,PURORD);
			break;
			default:
				$ss_tTypes = $this->stock_tTypes;
				$ss_return = array(CRNOTE, DBNOTE, PURCRNOTE, PURDBNOTE);
				$ss_ref = array(SALINV, SALRETAIL, PURINV, PURRETAIL, EXPINV, EXPRETAIL);
		}
		
		if ($detail && $params['stk_type'] != 'stock_ledger') {
			if (!empty($params['inward_details'])) {
				$ss_tTypes = array(CRNOTE, PURINV, PURRETAIL, EXPINV, EXPRETAIL, PURDBNOTE, PURRECP);
				$ss_return = array(CRNOTE, PURDBNOTE);
				$ss_ref = array(SALINV, SALRETAIL, PURINV, PURRETAIL, EXPINV, EXPRETAIL);
			} else {
				$ss_tTypes = array(SALINV, SALRETAIL, DBNOTE, DELCHALLAN, PURCRNOTE);
				$ss_return = array(DBNOTE, PURCRNOTE);
				$ss_ref = array(SALINV, SALRETAIL, PURINV, PURRETAIL, EXPINV, EXPRETAIL);
			}
		}
		$opening = isset($params['opening']) ? $params['opening'] : 0; // opening balance import
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;

		if (!empty($params['attr_ids'])) {
			$attr_ids = is_array($params['attr_ids']) ? $params['attr_ids'] : array($params['attr_ids']);
			$this->db->where_in('ti.itemAttrId', $attr_ids);
		}

		// if(!empty($params['serialIds'])){
		// 	$serialIds = is_array($params['serialIds']) ? $params['serialIds'] : array($params['serialIds']);
		// 	$this->db->where_in('ots.asId', $serialIds);
		// }

		if(!empty($params['transitem_id'])){
			$this->db->where('ti.id!=', $params['transitem_id']);
		}
		
		
		$batchwise_stk = (!empty($params['batchwise_stock'])) ? true : false;
		$where = array('t.cId' => $this->cId);
		// $where['it.type'] = 'G';
		$this->db->where_in('it.type',$this->it_type);
	

		if (!empty($params['from_date'])) {
			$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
			$to_date = $params['to_date'];
			get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
			$where['t.tDate >='] = (!$detail && !$batchwise_stk)?$fin_start_date:$from_date;
			if (!empty($params['stock_ledger_balance'])) { // get openning
				$where['t.tDate >='] = $fin_start_date;
			}
			$where['t.tDate <='] = $to_date;
		}


		if (empty($params['transaction'])) {
			$where['it.isInventory'] = 1;
	
		}
		if (!empty($params['item_type'])) {
			$where[($params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase >')] = 0;
		}

		if (!empty($params['itemId'])) {
			if (!is_array($params['itemId'])) {
				$where['ti.itemId'] = $params['itemId'];
			} else {
				$this->db->where_in('ti.itemId',$params['itemId']);
			}
		}
		if (!empty($params['transId'])) {
			$where['t.id !='] = $params['transId'];
		}

		if (!empty($params['curStk_tId'])) {
			// used for transaction calculation
			$where['t.id'] = $params['curStk_tId'];
		}
	
		switch ($stktype) {
			case 'current':
				if (!empty($params['catId'])) {
					$this->db->where_in('ic.catId',$params['catId']);
				}
				// $where['it.isActive'] = 1;
				$this->db->group_by('it.itemId, iar.itemAttrId');
				
			break;
			case 'alert':
				$where['it.stkLevel >'] = 0;
				$this->db->group_by('it.itemId, iar.itemAttrId');
			break;
		}
		$this->db->where($where);
		// if(!empty($params['catIds'])){
		// 	$this->db->where_in('ic.catId', $params['catIds']);
		// }
		$this->db->where_not_in('t.status', $this->config->item('ignore_status'));
		// branch filter
		$bw_map = $this->get_bw_map($branch, $params);
		if ($bw_map) {
			if (empty($params['cal_stkqty'])) {
				$this->db->group_start();
				user_branch_filter('ti.locId', array($branch), false, true);
				$this->db->group_end();
			}
		}  else if (empty($params['brachQty'])) {
			$where['t.categoryCode !='] = 'TL';
		} else {
			$this->db->group_by('ti.locId');
		}
		if (!empty($params['attrValues'])) {
			$this->db->group_by('iar.itemAttrId');	
		}

		$this->db->where_in('t.tType', $ss_tTypes);
		if(!$isReorder) {
			if (sal_mod_active(BRANCH_MOD) && $branch == -1) {
				$this->db->group_start();
					$this->db->where('t.categoryCode !=','TL');
				$this->db->group_end();
			}
			// reference ignore query
			$this->db->group_start();
			$this->db->where_not_in('t.reftType', $ss_tTypes);

			$this->db->or_group_start();			
			$this->db->where_in('t.tType', $ss_return);
			$this->db->where_in('t.reftType', $ss_ref);
			$this->db->group_end();

			$this->db->or_group_start();			
			// delivery challan refered in goods receipt
			$this->db->where_in('t.tType', array(PURRECP,DELCHALLAN));
			$this->db->group_start();
				$this->db->where_in('t.reftType', array(PURRECP,DELCHALLAN));
			$this->db->group_end();
			$this->db->group_end();
			// if(!($isallbranch)) {
			// 	if (sal_mod_active(BRANCH_MOD) && $branch != -1) {
			// 		$this->db->or_group_start();
			// 		$this->db->where($this->_stock_transfer);
			// 			$this->db->or_group_start();
			// 				$this->db->where($this->__stock_transfer);
			// 			$this->db->group_end();
			// 			$this->db->where($this->___stock_transfer);
			// 		$this->db->group_end();
			// 	} else if (!empty($params['brachQty'])) {
			// 		$this->db->or_group_start();
			// 		$this->db->where('t.categoryCode','TL');
			// 		$this->db->group_end();
			// 	}
			// }
			$this->db->group_end();	
		}

		if ($this->isFranchise && $branch==-1) {
			$this->db->where('t.bId not in (select id from '.$this->db->dbprefix('contacts').' where cId='.$this->cId.' and csType="F")',NULL,FALSE);
		}
	}
	public function batch_stock_select($params=array()) {
		// print_r($params);
		$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
		$opening = isset($params['opening']) ? $params['opening'] : 0;
		$to_date = $params['to_date'];
		get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
		$detail = (!empty($params['inward_details']) || !empty($params['outward_details'])) ? true : false;
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;
		$opening_filter = 'se.sDate < "' . $from_date . '"';
		$other_filter = 'se.sDate  >= "' . $from_date . '"';
		if (strtotime($fin_start_date) == strtotime($from_date)) {
			$opening_filter = 'se.sDate >= "' . $from_date . '" and se.sType IN ("OP","BF")';
			$other_filter = 'se.sDate >= "' . $from_date . '" and se.sType NOT IN ("OP","BF")';
		}

		switch ($params['stk_type']) {
			case 'summary': // stock summary
				if (!$detail) {
					$this->db->select('se.sType as tType');
					if (empty($params['opening'])) {
						$this->db->select($branch.' as locId',false);
						
					} else {
						
						$this->db->select('if(se.sType="TL" && si.tolocId=' . $branch . ',si.tolocId,si.fromlocId) as locId');
					}
					$this->db->select('si.itemAttrId, it.itemId, it.name AS itemName, it.uom AS uom,it.HS as hsn,it.SKU,iar.SKU as iarSKU', false);
					// $this->db->select('1 AS isStock');
					$this->db->select('If (' . $opening_filter . ',IF(se.sType="TL" and si.tolocId=' . $branch . ', si.qty * -1, si.qty) * if(itr.convFactor, itr.convFactor, 1) , 0) as opqty', false);
					$this->db->select('If (' . $opening_filter . ',if(se.sType="TL" and si.tolocId='.$branch.', -1 * si.qty, si.qty) * if(itr.convFactor, itr.convFactor, 1),0) as op_pur_qty', false);
					$this->db->select('If (' . $opening_filter . ',if(se.sType="TL" and si.tolocId=' . $branch . ', -1 *  si.qty ,si.qty) * si.rate , 0) as op_pur_amt', false);
					// Inward Qty
					$this->db->select('If (' . $other_filter . ',IF(si.qty > 0 , si.qty ,if(se.sType="TL" and si.tolocId=' . $branch . ', -1 *  si.qty ,0)) * if(itr.convFactor, itr.convFactor, 1) , 0) as iqty', false);
					$this->db->select('If (' . $other_filter . ',(IF(si.qty > 0, si.qty, if(se.sType="TL" and si.tolocId=' . $branch . ', -1 *  si.qty ,0)) * if(itr.convFactor, itr.convFactor, 1)),0) as i_pur_qty', false);
					$this->db->select('If (' . $other_filter . ',IF(si.qty > 0 , si.qty ,if(se.sType="TL" and si.tolocId=' . $branch . ', -1 *  si.qty ,0)) * si.rate , 0) as i_pur_amt', false);
					// Outward Qty
					$this->db->select('If (' . $other_filter . ',IF(si.qty < 0 , si.qty * if(se.sType="TL",if(si.fromlocId=' . $branch . ',-1,0),-1), 0),0) * if(itr.convFactor, itr.convFactor, 1) as oqty', false);
					$this->db->select('If (' . $other_filter . ',IF(si.qty < 0, si.rate * si.qty * if(se.sType="TL",if(si.fromlocId=' . $branch . ',-1,0),-1), 0),0) as o_amt', false);
					$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');
					if ($opening) {
						$this->db->select('iar.mrp', false);
					}
				} else {
					$this->db->select('se.id, if(se.stNo!="0",se.stNo,se.id) as tno, se.sType as tType, se.sDate as tDate,  "" as conName, si.unit,si.id as itId,si.rate as trate', false);
					if (!empty($params['inward_details'])) {
						$this->db->select('If (' . $other_filter . ',IF(si.qty > 0 , si.qty ,if(se.sType="TL" and si.tolocId=' . $branch . ', -1 *  si.qty ,0)) * if(itr.convFactor, itr.convFactor, 1) , 0) as s_qty', false);
						$this->db->select('If (' . $other_filter . ',IF(si.qty > 0 , si.qty ,if(se.sType="TL" and si.tolocId=' . $branch . ', -1 *  si.qty ,0)) * si.rate , 0) as s_amount', false);
					} else {
						$this->db->select('If (' . $other_filter . ',IF(si.qty < 0 , si.qty * if(se.sType="TL",if(si.fromlocId=' . $branch . ',-1,0),-1), 0),0) * if(itr.convFactor, itr.convFactor, 1) as s_qty', false);
						$this->db->select('If (' . $other_filter . ',IF(si.qty < 0 and si.rate > 0, si.rate * si.qty * if(se.sType="TL",if(si.fromlocId=' . $branch . ',-1,0),-1), 0),0) as s_amount', false);
					}
					$this->db->select('it.uom');
					$this->db->having('s_qty > 0');
				}
				
			break;
			case 'alert':
			case 'current':
				
				$this->db->select('si.itemAttrId,sum(if(si.qty > 0,si.rate*si.qty,0)) AS pi_rate, IF(iar.saleRate IS NULL OR iar.saleRate = 0, it.saleRate, iar.saleRate) AS saleRate, IF(iar.mrp IS NULL OR iar.mrp = 0, it.mrp, iar.mrp) AS mrp, it.stkLevel', false);			
				// $tl = !empty($params['includeTL'])?-1:1;

				$this->db->select('it.uom,sum(if(si.qty < 0,if(itr.convFactor, si.qty*itr.convFactor, si.qty) * -1,0)) as s_qty', false);
				if (sal_mod_active(BRANCH_MOD) && isset($params['branch']) && $params['branch'] != -1) {
					$this->db->select('sum(if(itr.convFactor, si.qty*itr.convFactor, si.qty) * if(se.sType="TL" && si.tolocId=' . $params['branch'] . ',-1,1)) as p_qty', false);
				} else {
					$this->db->select('sum(if(si.qty > 0,if(itr.convFactor, si.qty*itr.convFactor, si.qty),0)) as p_qty', false);
				}
				$this->db->select('null as pur_qty',false);
				if (!empty($params['brachQty'])) {
					if (isset($params['branch'])) {
						$this->db->select('it.itemId,if(se.sType="TL" && si.tolocId=' . $params['branch'] . ',si.tolocId,si.fromlocId) as locId',false);
					} else {
						$this->db->select('it.itemId,se.locId',false);
					}
				} else {
					$this->db->select('it.itemId,it.name AS itemName,it.SKU, iar.SKU as iarSKU', false);
				}
				// $this->db->select('1 AS isStock');

				// include category name
				if (!empty($params['catColumn'])) {
					// $this->db->select('group_concat(distinct c.name) as catName');
					$this->db->select('ic.name as catName');
				}
				if(!empty($params['batchwise_stock'])){
					$this->db->select(',0 as rate',false);
				}
			break;
			case 'stock_value':
				$this->db->select('si.itemAttrId,si.itemId as itemId, si.qty * if(se.sType="TL" and si.tolocId=' . $branch . ',-1,1) * if(itr.convFactor, itr.convFactor, 1) as stk_qty', false);
				// $this->db->select('(IF(si.qty > 0, si.qty, if(se.sType="TL" and si.tolocId='.$branch.', -1 * si.qty, 0)) * if(itr.convFactor, itr.convFactor, 1)) as pur_qty', false);
				// $this->db->select('IF(si.qty > 0, si.qty, , if(se.sType="TL" and si.tolocId='.$branch.', -1 * si.qty, 0)) * si.rate as pur_amt', false);
				$this->db->select('if(se.sType="TL" and si.tolocId='.$branch.', -1 * si.qty, si.qty) * if(itr.convFactor, itr.convFactor, 1) as pur_qty', false);
				$this->db->select('if(se.sType="TL" and si.tolocId='.$branch.', -1 * si.qty, si.qty) * si.rate as pur_amt', false);
				$this->db->select('if("' . get_company('stkRate') . '"="S",it.saleRate,it.purchaseRate) as saleRate');	
			
			break;
			case 'stock_ledger':
				$this->db->select('se.id, if(se.stNo!="0",se.stNo,se.id) as tno, se.sType as tType, se.sDate as tDate,  if(se.sType = "TL",si.toLocId,"") as conName,it.uom, si.unit,si.id as itId, 1 as stck', false);
				if(!empty($params['serialIds'])){
					$this->db->select('If (' . $opening_filter . ',IF(se.sType="TL" and si.tolocId=' . $branch . ', IF(count(ots.tsItemId) >1 ,1, si.qty) * -1, IF(count(ots.tsItemId) >1 ,1, si.qty)) * if(itr.convFactor, itr.convFactor, 1) , 0) as opqty', false);
					$this->db->select('If (' . $other_filter . ',IF(si.qty > 0 , IF(count(ots.tsItemId) >1 ,1, si.qty) ,if(se.sType="TL" and si.tolocId=' . $branch . ', -1 *  IF(count(ots.tsItemId) >1 ,1, si.qty) ,0)) * if(itr.convFactor, itr.convFactor, 1) , 0) as iqty', false);
					$this->db->select('If (' . $other_filter . ',IF(si.qty < 0 , IF(count(ots.tsItemId) >1 ,1, si.qty) * if(se.sType="TL",if(si.fromlocId=' . $branch . ',-1,0),-1), 0),0) * if(itr.convFactor, itr.convFactor, 1) as oqty', false);
				}else{
					$this->db->select('If (' . $opening_filter . ',IF(se.sType="TL" and si.tolocId=' . $branch . ', si.qty * -1, si.qty) * if(itr.convFactor, itr.convFactor, 1) , 0) as opqty', false);
					$this->db->select('If (' . $other_filter . ',IF(si.qty > 0 , si.qty ,if(se.sType="TL" and si.tolocId=' . $branch . ', -1 *  si.qty ,0)) * if(itr.convFactor, itr.convFactor, 1) , 0) as iqty', false);
					$this->db->select('If (' . $other_filter . ',IF(si.qty < 0 , si.qty * if(se.sType="TL",if(si.fromlocId=' . $branch . ',-1,0),-1), 0),0) * if(itr.convFactor, itr.convFactor, 1) as oqty', false);
				}

				if(!empty($params['batchwise_stock'])){
					$this->db->select('iar.itemAttrId,it.itemId,0 as rate,1 as isStock',false);
				}
				// $this->db->having('(opqty+iqty+oqty) > 0');
			break;
			// case 'ledger_balance':
			// 	$this->db->select('si.itemAttrId, it.itemId, it.name AS itemName, it.uom AS uom', false);
			// 	$this->db->select('If (' . $opening_filter . ',IF(se.sType="TL" and si.tolocId=' . $branch . ', si.qty * -1, si.qty) * if(itr.convFactor, itr.convFactor, 1) , 0) as opqty', false);
			// 	// Inward Qty
			// 	$this->db->select('If (' . $other_filter . ',IF(si.qty > 0 , si.qty ,if(se.sType="TL" and si.tolocId=' . $branch . ', -1 *  si.qty ,0)) * if(itr.convFactor, itr.convFactor, 1) , 0) as iqty', false);
			// 	// Outward Qty
			// 	$this->db->select('If (' . $other_filter . ',IF(si.qty < 0 , si.qty * if(se.sType="TL",if(se.locId=' . $branch . ',-1,0),-1), 0),0) * if(itr.convFactor, itr.convFactor, 1) as oqty', false);
			// break;

		}
	}
	public function batch_stock_where($params=array()) {
		$detail = (!empty($params['inward_details']) || !empty($params['outward_details'])) ? true : false;
		// if(isset($params['batchwise_stock']) && !empty($params['batchwise_stock'])){
		// 	$detail = true;
		// }

		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;
		$serialIds = array();
				
		if (!empty($params['attr_ids'])) {
			$attr_ids = is_array($params['attr_ids']) ? $params['attr_ids'] : array($params['attr_ids']);
			$this->db->where_in('si.itemAttrId', $attr_ids);
		}
		
		$where = array('se.cId' => $this->cId);
		$batchwise_stk = (!empty($params['batchwise_stock'])) ? true : false;

		if (!empty($params['from_date'])) {
			$cur_date = gmdate('Y-m-d');
			$fin_start_date = $fin_end_date = $from_date = $params['from_date'];
			$to_date = $params['to_date'];
			get_financial_dates($params['from_date'], $fin_start_date, $fin_end_date);
			$where['se.sDate >='] = (!$detail && !$batchwise_stk)?$fin_start_date:$from_date;

			if (!empty($params['stock_ledger_balance'])) { // get openning
				$where['se.sDate >='] = $fin_start_date;
			}
			$where['se.sDate <='] = $to_date;
		}

		if (!empty($params['curStk_sId'])) {
			// used for transaction calculation
			$where['se.id'] = $params['curStk_sId'];
		}

		$this->db->where_in('it.type',$this->it_type);
		if (!empty($params['itemId'])) {
			if (!is_array($params['itemId'])) {
				$where['si.itemId'] = $params['itemId'];
			} else {
				$this->db->where_in('si.itemId',$params['itemId']);
			}
		}
		if (!empty($params['sId'])) {
			$where['se.id !='] = $params['sId'];
		}
		if (empty($params['transaction'])) { // in closing stock add  only if isInventory
			$where['it.isInventory'] = 1;
		}
		$where['it.isActive >='] = 1;
		$this->db->where($where);
		// if(!empty($params['catIds'])){
		// 	$this->db->where_in('ic.catId', $params['catIds']);
		// }
		if (!empty($params['item_type'])) {
			$this->db->where($params['item_type'] == 'S' ? 'it.isSale >' : 'it.isPurchase >', 0);
		}
		// if ($cur_date != $fin_start_date) {
		$bw_map = $this->get_bw_map($branch, $params);
		if ($bw_map) {
				$this->db->group_start();
				$this->db->where_in('si.fromlocId', $bw_map);
				$this->db->or_group_start();
				$this->db->where('se.sType', 'TL');
				$this->db->where_in('si.tolocId', $bw_map);
				$this->db->group_end();
				$this->db->group_end();		
		} else if (empty($params['brachQty'])) {
			$this->db->where('se.sType!=', 'TL');
		}
		/*} else { // date and start date same check only opening
			.disabled due to stockadjustment not included in summary when start and finance start date matched
			$this->db->where_in('se.sType', array('OP', 'BF'));
			if (sal_mod_active(BRANCH_MOD) && $branch != -1) {
				$bw_map = array();
				user_branch_filter('si.fromlocId', array($params['branch']));
			}
		}*/
		$stk_type = !empty($params['expDetail']) ? 'current' : $params['stk_type'];
		switch ($stk_type) {
			case 'current':
				// include category name
				if (!empty($params['catId'])) {
					$this->db->where_in('ic.catId',$params['catId']);
				}
				if (!empty($params['brachQty'])) {
					// $this->db->group_by(!empty($params['includeTL'])?'si.tolocId':'se.locId');
					$this->db->group_by('locId');
				}
				$this->db->group_by('it.itemId,itemAttrId');
				if (!empty($params['attrValues'])) {
					$this->db->group_by('itemAttrId');	
				}
			break;
			case 'alert':
				$this->db->group_by('it.itemId,itemAttrId');
			break;
		}

		if ($this->isFranchise && $branch==-1) {
			$this->db->where('se.locId not in (select id from '.$this->db->dbprefix('contacts').' where cId='.$this->cId.' and csType="F")',NULL,FALSE);
		}
	}
	function negativestock($params) {
		$page_limit = $this->config->item('page_limit');
		$params['page'] = !empty($params['page']) ? $params['page'] : 1;
		$from = ($params['page'] - 1) * $page_limit;
		
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;
		get_financial_dates($params['to_date'],$start_date,$end_date);
		$end_date= $params['to_date'];

		$this->db->select('t.id as tid, t.tdate, ti.itemId, ti.itemAttrId, ti.locId, (ti.qty + ti.freeQty) * IF(t.ttype IN ("PI", "PR", "EI", "PE", "PD", "GR", "SC"), 1, -1) * IF(itr.convFactor, itr.convFactor, 1) AS qty',false);
		$this->db->from('trans AS t');
		$this->db->join('trans_items AS ti', 'ti.transId = t.id');
		$this->db->join('items AS it', 'it.itemId = ti.itemId and it.isInventory = 1');
		$this->db->join('item_attr AS iar', 'iar.itemAttrId = ti.itemAttrId AND iar.itemId = ti.itemId', 'left');
		$this->db->join('itemrelunits AS itr', 'itr.itemId = ti.itemId AND itr.relUnitName = ti.unit', 'left');
		$this->db->join('trans_items_rel AS tirel', 'tirel.transItemId = ti.id AND t.tType IN ("SC", "GR")', 'left');
		$this->db->where_in('it.type', ['G', 'T', 'S', 'Y']);
		$this->db->where('t.cId', $this->cId);
		if (sal_mod_active(BRANCH_MOD) && isset($params['branch']) && $params['branch'] != -1) {
			$this->db->where('ti.locId', $branch);
		}
		$this->db->where('t.tDate >=', $start_date);
		$this->db->where('t.tDate <=', $params['to_date']);
		// $this->db->where('it.isInventory', 1);
		$this->db->where_not_in('t.status', ['D', 'X', 'V']);
		$this->db->where_in('t.tType', ['SC', 'PI', 'PR', 'EI', 'PE', 'PD', 'GR', 'SI', 'SR', 'SD', 'SH', 'PC']);
		$this->db->group_start();
			$this->db->where_not_in('t.reftType', ['SC', 'PI', 'PR', 'EI', 'PE', 'PD', 'GR', 'SI', 'SR', 'SD', 'SH', 'PC']);
			$this->db->or_group_start();
				$this->db->where_in('t.tType', ['SC', 'PD', 'SD', 'PC']);
				$this->db->where_in('t.reftType', ['SI', 'SR', 'PI', 'PR', 'EI', 'PE', 'SC', 'PD', 'SD', 'PC']);
			$this->db->group_end();
			$this->db->or_group_start();
				$this->db->where_in('t.tType', ['GR', 'SH']);
				$this->db->where_in('t.reftType', ['GR', 'SH']);
			$this->db->group_end();
			$this->db->group_end();

		$sub_query1 = $this->db->get_compiled_select();

		$this->db->select('se.id as tid, se.sDate as tDate, si.itemid as itemId, si.itemAttrId as itemAttrId, si.fromLocId as locId, si.qty * IF(itr.convFactor, itr.convFactor, 1) as qty');
		$this->db->from('stock_entries AS se', true);
		$this->db->join('stock_items AS si', 'si.sId = se.id');
		$this->db->join('items AS it', 'it.itemId = si.itemId and it.isInventory = 1');
		$this->db->join('itemrelunits AS itr', 'itr.itemId = si.itemId AND itr.relUnitName = si.unit', 'left');
		$this->db->join('item_attr AS iar', 'iar.itemAttrId = si.itemAttrId AND iar.itemId = si.itemId', 'left');
		$this->db->where_in('it.type', ['G', 'T', 'S', 'Y']);
		$this->db->where('se.cId',  $this->cId);
		if (sal_mod_active(BRANCH_MOD) && isset($params['branch']) && $params['branch'] != -1) {
			$this->db->where('si.fromLocId', $branch);
		}
		$this->db->where('se.sDate >=', $start_date);
		$this->db->where('se.sDate <=', $params['to_date']);
		// $this->db->where('it.isInventory', 1);
		$sub_query2 = $this->db->get_compiled_select();

		$this->db->select('se.id as tid, se.sDate as tDate, si.itemid as itemId, si.itemAttrId as itemAttrId, si.toLocId as locId, si.qty * -1 * if(itr.convFactor, itr.convFactor, 1) as qty');
		$this->db->from('stock_entries as se');
		$this->db->join('stock_items as si', 'si.sId = se.id');
		$this->db->join('items as it', 'it.itemId = si.itemId and it.isInventory = 1');
		$this->db->join('itemrelunits as itr', 'itr.itemId = si.itemId and itr.relUnitName = si.unit', 'left');
		$this->db->join('item_attr as iar', 'iar.itemAttrId = si.itemAttrId and iar.itemId = si.itemId', 'left');
		$this->db->where_in('it.type',["G", "T", "S", "Y"]);
		$this->db->where('se.cId',  $this->cId);
		if (sal_mod_active(BRANCH_MOD) && isset($params['branch']) && $params['branch'] != -1) {
			$this->db->where('si.toLocId', $branch);
		}
		$this->db->where('se.sDate >=',  $start_date);
		$this->db->where('se.sDate <=', $params['to_date']);
		// $this->db->where('it.isInventory', 1);
		$this->db->where('se.sType', 'TL');
		$sub_query3 = $this->db->get_compiled_select();

		$mainquery = 'SELECT i.itemid, i.name, i.SKU, rbal.itemAttrId, c.name as locName , min(tdate) as nsdate FROM (SELECT itemid,itemAttrId, locId, tdate,
		SUM(qty) OVER (PARTITION BY itemId, itemAttrId, locId ORDER BY tdate) AS running_balance
		FROM ('.$sub_query1.' UNION ALL '.$sub_query2.' UNION ALL '.$sub_query3.' ) AS st order by itemId, itemAttrid, locId, tdate) as rbal join ob_items i on i.itemId=rbal.itemId
	join ob_contacts c on c.id=rbal.locid  WHERE running_balance < 0 group by i.itemId, rbal.itemAttrid, rbal.locId';

		$mainquery .=  ($from?(' limit '.$from . ',' . $page_limit):' limit '. $page_limit);
		
		$result['items'] = $this->db->query($mainquery)->result_array();

		return $result;
				/*LEFT JOIN (SELECT ita.itemAttrId as itaAttrId, GROUP_CONCAT(If (ag.fldType!="E", CONCAT(ag.Name, "	", if(ag.fldType = "D", (CASE
		WHEN ag.format = "d-m-Y" THEN DATE_FORMAT(a.name, "%d/%m/%Y")
		WHEN ag.format = "m-d-Y" THEN DATE_FORMAT(a.name, "%m-%d-%Y")
		WHEN ag.format = "MY" THEN DATE_FORMAT(a.name, "%b %Y")
		WHEN ag.format = "FY" THEN DATE_FORMAT(a.name, "%M %Y")
			ELSE DATE_FORMAT(a.name, "%d/%m/%Y")
		END ), a.name)), "")  ORDER BY ag.sortNo SEPARATOR "
		") as atList
		FROM ob_item_attr as ita
		JOIN ob_item_attr_link as ial ON ial.itemAttrId=ita.itemAttrId
		JOIN ob_attributes as a ON a.attrId = ial.attrId
		JOIN ob_attributes_group as ag ON ag.attrGrpId=a.attrGrpId
		WHERE ita.cId = '.$this->cId.'
		GROUP BY ita.itemAttrId) ita on ita.itaAttrId=rbal.itemAttrId */
	}
	function getOutwardStockInformation($params) {
		$branch = isset($params['branch']) ? $params['branch'] : $this->bId;
		$this->db->select("(ti.qty+ti.freeQty)*if(itr.convFactor,itr.convFactor,1) as tfqty,0 as consqty,0 as damqty","false");
		$this->db->from("trans as t");
		$this->db->join("trans_items as ti","ti.transId = t.id");
		$this->db->join("items as it","it.itemId=ti.itemId");
		$this->db->join("itemrelunits as itr","itr.itemId=ti.itemId and itr.relUnitName=ti.unit","left");
		
		$transwhere['t.cId'] = $this->cId;
		$transwhere['it.isInventory'] = 1;
		$transwhere['t.tDate >= '] = $params['from_date'];
		$transwhere['t.tDate <= '] = $params['to_date'];
		$this->db->where($transwhere);

		$this->db->where_in("ti.itemId",$params['itemId']);
		$this->db->where_not_in("t.status",array("D","X","V"));
		$bw_map = $this->get_bw_map($branch, $params);
		if ($bw_map) {
			if (empty($params['cal_stkqty'])) {
				
				$this->db->where_in('ti.locId', $bw_map);
				
			}
		}
		$this->db->where("t.tType","SH");
		$this->db->where("t.classCode","TL");
		
		$transQuery = $this->db->get_compiled_select();

		$this->db->select('if(se.sType="TL",si.qty,0)*-1*if(itr.convFactor, itr.convFactor, 1)  as tfqty,
		if(se.sType in ("MJ","CO") , si.qty,0)*-1*if(itr.convFactor, itr.convFactor, 1)  as consqty,
		if(se.sType in ("WD","WL","WT","DI","WE") , si.qty,0)*-1*if(itr.convFactor, itr.convFactor,1)  as damqty',"false");
		$this->db->from("stock_entries as se");
		$this->db->join("stock_items as si","si.sId=se.id");
		$this->db->join("items as it","it.itemId=si.itemId");
		$this->db->join("itemrelunits as itr","itr.itemId=si.itemId and itr.relUnitName=si.unit","left");
		$this->db->join("item_attr as iar","iar.itemAttrId=si.itemAttrId and iar.itemId=si.itemId","left");

		$stockwhere['se.cId'] = $this->cId;
		$stockwhere['it.isInventory'] = 1;
		$stockwhere['se.sDate >= '] = $params['from_date'];
		$stockwhere['se.sDate <= '] = $params['to_date'];
		$this->db->where($stockwhere);

		$this->db->where_in("si.itemId",$params['itemId']);
		$this->db->where("si.qty < ","0");
		
		$stockQuery = $this->db->get_compiled_select();

		$query3 = 'select sum(tfqty) as tfqty, sum(consqty) as consqty, sum(damqty) as damqty
		from  ('.$transQuery.' UNION ALL '.$stockQuery.') sOut';

		$query = $this->db->query($query3)->row_array();
		return $query;
		/*Src Query
		-------------------
		select sum(tfqty) as tfqty, sum(consqty) as consqty, sum(damqty) as damqty
from  
(select 		(ti.qty+ti.freeQty) * if(itr.convFactor, itr.convFactor, 1) as tfqty,
0 as consqty,
0 as damqty
		FROM ob_trans AS t
		JOIN ob_trans_items AS ti ON ti.transId=t.id
		JOIN ob_items AS it ON it.itemId=ti.itemId LEFT JOIN ob_itemrelunits AS itr ON itr.itemId=ti.itemId and itr.relUnitName=ti.unit
		WHERE t.cId = "3" AND ti.locId IN ("32") 
		AND it.isInventory = 1 AND ti.itemId IN (133) AND t.tDate >= "2022-04-01" AND t.tDate <= "2023-02-20"AND t.status NOT IN("D","X","V")
		AND t.tType = "SH"
		AND t.classCode="TL"
		 UNION ALL SELECT 
		if(se.sType="TL",si.qty,0) * -1 * if(itr.convFactor, itr.convFactor, 1)  as tfqty,
if(se.sType in ("MJ","CO") , si.qty,0) * -1 * if(itr.convFactor, itr.convFactor, 1)  as consqty,
if(se.sType in ("WD","WL","WT","DI","WE") , si.qty,0) * -1 * if(itr.convFactor, itr.convFactor, 1)  as damqty
		FROM ob_stock_entries AS se
		JOIN ob_stock_items AS si ON si.sId=se.id
		JOIN ob_items AS it ON it.itemId=si.itemId LEFT JOIN ob_itemrelunits AS itr ON itr.itemId=si.itemId and itr.relUnitName=si.unit
		LEFT JOIN ob_item_attr AS iar ON iar.itemAttrId=si.itemAttrId and iar.itemId=si.itemId
		
		WHERE se.cId = "3"
		AND it.isInventory = 1 AND si.itemId IN (133) AND se.sDate >= "2022-04-01" AND se.sDate <= "2023-02-20"AND si.qty < 0 ) sOUT*/
	}
}

