<?php
/**********************************************************************
***********************************************************************/
//-------------------------------------------------------------------------------------------------------------
include_once($path_to_root . "/inventory/includes/db/adjustments_db.inc");
include_once($path_to_root . "/includes/common_functions.inc");
include_once($path_to_root . "/inventory/includes/db/lot_adjustments_db.inc");

function add_stock_adjustment($items, $location, $date_, $increase, $reference, $memo_, $movement_type, 
        $project_id, $task_id, $sample_item, $tran_type = ST_INVADJUST, $linked_field_type = 0, $linked_field_id = '')
{
	global $loc_notification, $path_to_root, $Refs;
    $current_user_id = $_SESSION['wa_current_user']->user;
	begin_transaction();
	$args = func_get_args();
	$args = (object)array_combine(array('items', 'location', 'date_', 'increase',
            'reference', 'memo_', 'movement_type', 'project_id', 'task_id', 'sample_item', 'tran_type', 
            'linked_field_type', 'linked_field_id'), $args);
	$args->trans_no = 0;
	hook_db_prewrite($args, $tran_type);

	$adj_id = get_next_trans_no($tran_type);

	if ($loc_notification == 1 && !$increase)
	{
		include_once($path_to_root . "/inventory/includes/inventory_db.inc");
		$st_ids = array();
		$st_names = array();
		$st_num = array();
		$st_reorder = array();
	}
        
    $adj_no = add_ia_header($date_, $reference, $location, $project_id, 
                            $increase, $tran_type, $memo_, $movement_type, 
                            $sample_item, $linked_field_type, $linked_field_id);

    if($adj_no != 0)
    {
        foreach ($items as $line_item)
        {
            if ($loc_notification == 1 && !$increase){
                    $loc = calculate_reorder_level($location, $line_item, $st_ids, $st_names, $st_num, $st_reorder); 
            }

            if (!$increase){
                    $line_item->quantity = -$line_item->quantity;
            }

//                    $standard_cost = $line_item->standard_cost/$line_item->convertion_factor;
            
            
            if($tran_type == ST_INVENTORY_RECEIPT || $tran_type == ST_INVENTORY_RECEIPT){
                $standard_cost = get_standard_cost($line_item->stock_id);
            }
            else{
                // Get the user entered new cost
                $standard_cost = $line_item->standard_cost;
            }
            
            add_stock_adjustment_item($adj_no, $line_item->stock_id, $location, $date_, 
                                $reference, $line_item->quantity, $standard_cost, $memo_, 
                                $line_item->tran_unit, $line_item->tran_qty, $line_item->convertion_factor, $tran_type, 
                                $line_item->task_id, $line_item->project_site_id, $project_id);

            $ailqdm_msg =  add_item_line_quantity_detail_movements($tran_type, $adj_no, $location, 
                                                                    $date_, $line_item, $increase, $reference);
            if($ailqdm_msg['success'] !== true){
                cancel_transaction();
                return $ailqdm_msg;
            }                                  
        }
    }
    
	add_comments($tran_type, $adj_no, $date_, $memo_);

	$Refs->save($tran_type, $adj_no, $reference);
	add_audit_trail($tran_type, $adj_no, $date_);

	$args->trans_no = $adj_no;
	hook_db_postwrite($args, $tran_type);
    
    $project = get_project_record($project_id);
    
    $task_costs_summary = array();
    foreach ($items as $stock_item)
    {
        $task_id = $stock_item->task_id;
        $amount = abs($stock_item->quantity) * $stock_item->standard_cost;

        if($increase){ //Receive
            if($project['purchase_to_stock']){ 
                // Cost should be added to the project as it is adding stock to a stock project
            }
            else{
                $amount = -$amount; // Cost should be deducted as it is item returns from the working project to stock
            }
        }
        else{// Issue
            if($project['purchase_to_stock']){ // Issue from a stock project
                $amount = -$amount; // Cost should be deducted as it is issuing stock from a stock project
            }
            else{
                // Cost should be added to the project as it is a consumption
            }
        }

        add_to_task_cost($task_costs_summary, $task_id, $amount, $amount, $amount);
    }
    
    get_task_cost_details($task_costs_summary);
    
//    $tasks_summary = calculate_task_remaining_totals($task_costs_summary);   
    
    $cct_msg = charge_cost_to_tasks($tran_type, $adj_no, 
                                $task_costs_summary, $current_user_id);
                
    if($cct_msg['success'] !== true)
    {
        cancel_transaction();
        return array("success" => $cct_msg['success'], "tran_no" => $adj_no, "message" => $cct_msg['message']);
    }
    
	commit_transaction();
	if ($loc_notification == 1 && !$increase && count($st_ids) > 0){
		send_reorder_email($loc, $st_ids, $st_names, $st_num, $st_reorder);
    }

	return array("success" => true, "tran_no" => $adj_no);
}



//-------------------------------------------------------------------------------------------------------------

function process_stock_adjustment_request($adj_req_no, $items, $location, $date_, $increase, $reference, $memo_, $movement_type, $project_id, 
                                          $task_id, $sample_item, $adj_req_type, $row_state)
{
	global $loc_notification, $path_to_root, $Refs, $systypes_array, $approval_statuses;
        
        $current_user_id = $_SESSION['wa_current_user']->user;
	begin_transaction();
	$args = func_get_args();
	$args = (object)array_combine(array('adj_no', 'items', 'location', 'date_', 'increase','reference', 'memo_', 'movement_type', 'project_id', 
                                            'task_id', 'sample_item', 'tran_type', 'row_state'), $args);
	$args->trans_no = 0;
	hook_db_prewrite($args, $adj_req_type);

//	$adj_id = get_next_trans_no($tran_type);

	if ($loc_notification == 1 && !$increase){
		include_once($path_to_root . "/inventory/includes/inventory_db.inc");
		$st_ids = array();
		$st_names = array();
		$st_num = array();
		$st_reorder = array();
	}
        

    if(!($adj_req_no > 0)){
        cancel_transaction();
        return array("success" => false, "message" => "No Inventory Adjustment Request number found.");
    }
    
//    ST_INVENTORY_ISSUE_REQUEST / ST_INVENTORY_RECEIPT_REQUEST
    
    $sar_row = get_stock_adjustment_request_header_record($adj_req_no);
    
    if($adj_req_type == ST_INVENTORY_ISSUE_REQUEST){
        $trans_type = ST_INVENTORY_ISSUE;
    }elseif($adj_req_type == ST_INVENTORY_RECEIPT_REQUEST){
        $trans_type = ST_INVENTORY_RECEIPT;
    }
    
    $message = $systypes_array[$adj_req_type]." #".$adj_req_no." has been ".$approval_statuses[AS_PROCESSED];
    
    $pid_msg = direct_update_document_status($adj_req_type, $adj_req_no, AS_PROCESSED, $row_state, $message);
    if($pid_msg['success'] !== true){
        cancel_transaction();
        return $pid_msg;
    } 

    
    
    $adj_no = add_stock_adjustment_header($sar_row['ai_date'], $sar_row['reference'], $sar_row['location'], $sar_row['project_id'], $trans_type, 
                                          $sar_row['sample_items'], $sar_row['increase'], $sar_row['comments'], $sar_row['movement_type'], 
                                          $sar_row['linked_field_type'], $sar_row['linked_field_id'], $sar_row['id']);
    

    if(!($adj_no > 0)){
        cancel_transaction();
        return "could not create header record for Stock Adjustment.";
    }     
    
    foreach ($items as $line_item)
    {
            if ($loc_notification == 1 && !$increase){
                    $loc = calculate_reorder_level($location, $line_item, $st_ids, $st_names, $st_num, $st_reorder); 
            }

            if (!$increase){
                    $line_item->quantity = -$line_item->quantity;
            }

//                    $standard_cost = $line_item->standard_cost/$line_item->convertion_factor;
            
            
            if($trans_type == ST_INVENTORY_RECEIPT || $trans_type == ST_INVENTORY_RECEIPT){
                $standard_cost = get_standard_cost($line_item->stock_id);
            }
            else{
                $standard_cost = get_standard_cost($line_item->stock_id);
            }
            
            add_stock_adjustment_item($adj_no, $line_item->stock_id, $location, $date_, 
                                      $reference, $line_item->quantity, $standard_cost, $memo_, 
                                      $line_item->tran_unit, $line_item->tran_qty, $line_item->convertion_factor, $trans_type, 
                                      $line_item->task_id, $line_item->project_site_id, $line_item->row_id, $project_id);
            

            $ailqdm_msg =  add_item_line_quantity_detail_movements($trans_type, $adj_no, $location, 
                                                                    $date_, $line_item, $increase, $reference);
            if($ailqdm_msg['success'] !== true){
                cancel_transaction();
                return $ailqdm_msg;
            }                                  
    }
    
    
    add_comments($trans_type, $adj_no, $date_, $memo_);

    $Refs->save($trans_type, $adj_no, $reference);
    add_audit_trail($trans_type, $adj_no, $date_);

    $args->trans_no = $adj_no;
    hook_db_postwrite($args, $trans_type);
    
    $project = get_project_record($project_id);
    
    $task_costs_summary = array();
    foreach ($items as $stock_item)
    {
        $task_id = $stock_item->task_id;
        $amount = abs($stock_item->quantity) * $stock_item->standard_cost;

//        if($increase){ //Receive. This is an increase in the stock quantities
//            if($project['purchase_to_stock']){ 
//                // Cost should be added to the project as it is adding stock to a stock project
//            }
//            else{
//                // Increase in the stock quantities means returning the already consumed from the project back to stock. So the "used budget" should be reduced
//                $amount = -$amount; // Cost should be deducted as it is item returns from the working project to stock
//            }
//        }
//        else{// Issue. This is a dicrease in the stock quantities
//            if($project['purchase_to_stock']){ // Issue from a stock project
//                $amount = -$amount; // Cost should be deducted as it is issuing stock from a stock project
//            }
//            else{
//                // Decrease in the stock quantities means issuing the stock items to the construction project for consumption. So the "used budget" should be increased.
//                // Cost should be added to the project as it is a consumption
//            }
//        }

        if($increase){
            $amount = -$amount; // Returning back
        }else{
            // Issueing to the project
        }
        add_to_task_cost($task_costs_summary, $task_id, $amount, $amount, $amount);
    }
    
    get_task_cost_details($task_costs_summary);
    
//    $tasks_summary = calculate_task_remaining_totals($task_costs_summary);   
    
    $cct_msg = charge_cost_to_tasks($trans_type, $adj_no, 
                                $task_costs_summary, $current_user_id);
                
    if($cct_msg['success'] !== true)
    {
        cancel_transaction();
        return array("success" => $cct_msg['success'], "tran_no" => $adj_no, "message" => $cct_msg['message']);
    }
    
    commit_transaction();
    
    if ($loc_notification == 1 && !$increase && count($st_ids) > 0){
	send_reorder_email($loc, $st_ids, $st_names, $st_num, $st_reorder);
    }
    
    $message = $systypes_array[$trans_type]." #".$adj_no." has been processed.";
    set_session_variable('ST_PINV_ADJ_messages', $message);
    return array("success" => true, "tran_no" => $adj_no, "message" => $message);
}

//-------------------------------------------------------------------------------------------------------------

function add_stock_adjustment_header($ai_date, $reference, $location, $project_id, $type, 
                                     $sample_items, $increase, $comments, $movement_type, 
                                    $linked_field_type, $linked_field_id, $adj_req_id)
{
    $created_by = $_SESSION['wa_current_user']->user;
    $created_on = date('Y-m-d H:i:s');
    
        
    $sql = "INSERT INTO ".TB_PREF."stock_adjustments(ai_date, reference, location, project_id, type, 
                                                     sample_items, increase, comments, movement_type, 
                                                     linked_field_type, linked_field_id, 
                                                     created_on, created_by, sar_id
                    ) 
            VALUES (".db_escape($ai_date).", ".db_escape($reference).", ".db_escape($location).", ".db_escape($project_id).", ".db_escape($type).", "
                     .db_escape($sample_items).", ".db_escape($increase).", ".db_escape($comments).", ".db_escape($movement_type).", "
                     .db_escape($linked_field_type).", ".db_escape($linked_field_id).", "
                     .db_escape($created_on).", ".db_escape($created_by).", ".db_escape($adj_req_id).")";

    $error_msg = "Stock adjustment header could not be created";

	db_query($sql, $error_msg);

	return db_insert_id();
}



//-------------------------------------------------------------------------------------------------------------

function void_stock_adjustment($type_no)
{
	hook_db_prevoid(ST_INVADJUST, $type_no);
	void_gl_trans(ST_INVADJUST, $type_no);
	void_stock_move(ST_INVADJUST, $type_no);
}

//-------------------------------------------------------------------------------------------------------------

function get_stock_adjustment_items($tran_type, $trans_no)
{
	$result = get_stock_moves($tran_type, $trans_no);

	if (db_num_rows($result) == 0)
	{
		return null;
	}

	return $result;
}

//--------------------------------------------------------------------------------------------------

function add_stock_adjustment_item($adj_no, $stock_id, $location, $date_, 
                                    $reference, $quantity, $standard_cost, $memo_, 
                                    $tran_unit, $tran_qty, $convertion_factor, $tran_type,
                                    $task_id, $project_site_id, $reference_line_id=0, $project_id=0)
{
	$mb_flag = get_mb_flag($stock_id);

    if (is_service($mb_flag))
    {
    	display_db_error("Cannot do inventory adjustment for Service item : $stock_id", "");
    }

	/* Logic shifted to function update_average_material_cost
	//Chaitanya : If negative adjustment result in negative or zero inventory 
	//then difference should be adjusted
	$qoh = get_qoh_on_date($stock_id);
	if ($qoh + $quantity <= 0 && $qoh > 0) //Positive inventory turning zero/negative
	{
		global $Refs;

		$id = get_next_trans_no(ST_JOURNAL);
		$ref = $Refs->get_next(ST_JOURNAL);
		$diff = get_standard_cost($stock_id) - $standard_cost;
		
		if ($diff !=0)
		{
			$stock_gl_code = get_stock_gl_code($stock_id);
			$memo = _("For zero inventory of ").$stock_id." INVADJ REF: ".$reference;
			//Reverse the inventory effect if $qoh <=0
			add_gl_trans_std_cost(ST_JOURNAL, $id, $date_, 
				$stock_gl_code["inventory_account"],
				$stock_gl_code['dimension_id'], $stock_gl_code['dimension2_id'], $memo, 
				-$qoh * $diff);
			//GL Posting to inventory adjustment account
			add_gl_trans_std_cost(ST_JOURNAL, $id, $date_, 
				$stock_gl_code["adjustment_account"],
				$stock_gl_code['dimension_id'], $stock_gl_code['dimension2_id'], $memo,
				$qoh * $diff);
				
			add_audit_trail(ST_JOURNAL, $id, $date_);
			add_comments(ST_JOURNAL, $id, $date_, $memo);
			$Refs->save(ST_JOURNAL, $id, $ref);	
		}		
	}*/

    switch ($tran_type) {
        case ST_INVENTORY_RECEIPT:
            // No need to calculate average cost as it is the current standard cost
            break;
        case ST_INVENTORY_ISSUE:
        case ST_PR_ISSUE:
        case ST_RAW_MATERIAL_ISSUE:
        case ST_JOB_MATERIAL_ISSUE:
        case ST_JOB_MATERIAL_RETURN:
        case ST_SALVAGE_RETURN:
            // No need to calculate average cost
            break;
        case ST_INVADJUST:
            if($quantity > 0){
                // This is a positive stock adjustment. Recalculate average cost
                update_average_material_cost(null, $stock_id, $standard_cost, $quantity, $date_);
            }
            else{
               // No need to calculate average cost as it is the current standard cost
            }
            break;

        case ST_STOCK_ASSET_TRANSFER:
        case ST_PETTY_CASH_ITEM_RECEIPT:
        default:
            update_average_material_cost(null, $stock_id, $standard_cost, $quantity, $date_);
            break;
    }
   

	return add_stock_move($tran_type, $stock_id, $adj_no, $location,
                        $date_, $reference, $quantity, $standard_cost, 0, 1, 0, 0, '', 
                        $tran_unit, $tran_qty, $convertion_factor, $task_id, $project_site_id, $reference_line_id, $project_id);

//	if ($standard_cost > 0)
//	{

//		$stock_gl_codes = get_stock_gl_code($stock_id);

//		add_gl_trans_std_cost($tran_type, $adj_no, $date_,
//			$stock_gl_codes['adjustment_account'], $stock_gl_codes['dimension_id'], $stock_gl_codes['dimension2_id'], $memo_, ($standard_cost * -($quantity)));
//
//		add_gl_trans_std_cost($tran_type, $adj_no, $date_, $stock_gl_codes['inventory_account'], 0, 0, $memo_, ($standard_cost * $quantity));
//	}
}

//-------------------------------------------------------------------------------------------------------------

?>