#!/usr/bin/perl -Ilibs
use strict;

package API::Warehouse::Receiving;

use Date::Format;
use List::Util ();

use API::Order::Process;
use API::Order;
use API::Order::Payment;

our $Config;
BEGIN {
	use API::Config;
	$Config = $API::Config::Config;
}
use lib ($Config->{'Website_libs'});

use ECS::Order ();
use ECS::Site;
use ECS::SQL;
use ECS::Error;
use ECS::Config;
use ECS::Warehouse::Receiving;

# Sends products to OOB bin. 
# This request is used when items are scanned from WIP_REC into WIP_OOB.
# Requires
# - productID
# - qtyScanned
# - qtyWipOO
# - user	
# - ipaddress
sub sendToOOB {
 
	my $self = shift;
	my $input = shift;
    # @success_orders = no processing errors . insert these into cartComponentShipped table
    my @success_orders;
	my $result = {
		'success' => 1,
		'error' => undef,
		'update_DB'	=> $Config->{'update_DB'}
	};

	if (!defined $input->{'productID'} || !$input->{'productID'}) {
		$result->{'success'} = 0;
		$result->{'error'} = 'No productID specified.';
		return $result;
	}
	
	if (!defined $input->{'qtyScanned'}) {
		$result->{'success'} = 0;
		$result->{'error'} = 'No qty specified';
		return $result;
	}
	
	if (!$input->{'qtyWipOO'}) {
		$result->{'success'} = 0;
		$result->{'error'} = 'No qty for OOB bin. Send qty to shelf.';
		return $result;
	}
	
	if (!defined $input->{'user'} || !$input->{'user'} 
		|| !defined $input->{'ipaddress'} || !$input->{'ipaddress'}) {
		$result->{'success'} = 0;
		$result->{'error'} = 'Web Error: Missing Connection Credentials';
		return $result;
	}

	return $result if (!$Config->{'update_DB'});
	
	my $p = {
		'DBH' => ECS::SQL::connect(),
		'DBHr'=> ECS::SQL::connect('SLAVE'),
		'input' => $input
	};

    my $user = API::Warehouse::User::getUser({
        'DBH'    => $p->{'DBHr'},
        'userID' => $input->{'user'},
        });
    if(not $user) {
        $result->{'success'} = 0;
        $result->{'error'} = "Unable to look up user ID";
        return $result;
    }
	
	# get the queue of one item orders that are gtg
	my $orderQueue = ECS::Warehouse::Receiving::getOnHandGTG({
		'dbh'			=>	$p->{'DBHr'},
		'dbhr'      	=>  $p->{'DBHr'},
		'productID'		=>	$p->{'input'}->{'productID'}
	});
				
	my $ooOrderQueue = ECS::Warehouse::Receiving::filterOneItemOrders({
		'orderQueue'	=>	$orderQueue	
	});
	
	if (!scalar(@{$ooOrderQueue})) {
		$result->{'success'} = 0;
		$result->{'error'} = 'No qty for OOB bin. Send qty to shelf.';
		
		# make sure we empty the entire wip_oo first; send all wip_oo qty to wip_rec
		my $res = ECS::Product::Inventory::WIP::adjustWipQty({
			'dbh'   =>	$p->{'DBH'},
			'info'  => {
				'productID'	=>	$p->{'input'}->{'productID'},
				'fromLoc'	=>	'oo',
				'toLoc'		=>	'rec',
				'qtyToMove'	=>	$input->{'qtyWipOO'}
				}
			});

		$result->{'error'} = 'Web error.Please try again.' if !$res;
		
		return $result;
	}
	
	my $orders = ECS::Order->loadMulti({
		'DBH'     => $p->{'DBH'},
		'orderID' => [map { $_->{'orderID'} } @{ $ooOrderQueue }],
	});
	
	my $oobQty = 0;
	my $failedQty = 0;

    # check that our orders site matches our bin (if we're looking for a specific site)
    my @ooSiteOrders = @{ $ooOrderQueue };
    if($input->{'site'}) {
        @ooSiteOrders = grep { ECS::Site->fromID( $orders->{ $_->{orderID} }{siteID} )->name eq $input->{site} } @$ooOrderQueue;
    }

    unless (@ooSiteOrders) {
      	my $newBin = sprintf "OOB%s" => ECS::Site->fromID( $orders->{ $ooOrderQueue->[0]{orderID} }{ siteID } )->name;
		$result->{'success'} = 0;
		$result->{'error'} = sprintf 'No qty for this OOB bin.  Send qty to %s bin' => $newBin;
		return $result;
    }

    local $input->{'qtyWipOO'} = List::Util::min( scalar @ooSiteOrders, $input->{qtyWipOO} );
    my $newBin = "OOB";
	foreach my $ooOrder (@ooSiteOrders) {
		my $order = $orders->{$ooOrder->{'orderID'}};

		next unless $order;

      	$newBin = sprintf "OOB%s" => ECS::Site->fromID( $order->{ siteID } )->name;
		
		
		last if $oobQty == $input->{'qtyScanned'};
		
		$p->{'order'} = $order;
		
		$order->user($user->{'name'});
		$order->ipaddress($input->{'ipaddress'});
		
		$order->{'picker'} = $user->{'name'};
		
		# lock the order		
		$p->{'reqStatus'} = [ 'Received', 'Warehouse Transfer' ];
		next if !API::Order::lock($p);
		
		if ($order->automatePayments('fetch')) {
			
			# If payment was successful, but was marked as Fraud
			#    - Send order to "Processing Error" status/queue
			if ($order->reviewPaymentFraud) {
				$order->status('Processing Error');
				$order->addNote('Review Payment Fraud');
			} else {
				$order->status('Picked OOB');
			}
			
		} else {
			$order->status('Processing Error');
			$order->addNote('Payment Failed');
		}
		
		if ($order->status eq 'Picked OOB') {
			$oobQty++;
            push(@success_orders, $order);
		}else {
			$failedQty++;
		}
		
		unless ($order->save) {
			$result->{'success'} = 0;
			$result->{'error'} = "Could not update order. Report to manager.";
			return $result;
		}
	}

	# push picked products into cartComponentShipped
    if(scalar(@success_orders)) {
        API::Order::Cart::insertMultipleOrderIdsIntoCartComponentPicked( $p, {'orders'	=>	\@success_orders } );
    }
    
	# update WIP
	# move qty of successful (packed) orders from WIP_OO to WIP_OOB
	my $updateOOB;
	$updateOOB = ECS::Product::Inventory::WIP::adjustWipQty({
		'dbh'   =>	$p->{'DBH'},
		'info'  => {
			'productID'	=>	$p->{'input'}->{'productID'},
			'fromLoc'	=>	'oo',
			'toLoc'		=>	'oob',
			'qtyToMove'	=>	$oobQty
		}
	}) if $oobQty;
	
	if (defined $updateOOB and $updateOOB) {
		# $result->{'userMsg'} =	"Place ". $oobQty . " qty in the OOB bin.";
		$result->{'userMsg'} =	sprintf "Place %d qty in the %s bin." => $oobQty, $newBin; 
	} else {
		$result->{'error'} = "No qty for OOB bin. Send qty to shelf.";
	}
	
	# move whatever qty left, that failed authorization, from WIP_OO to WIP_REC
	my $updateReceive;
	$updateReceive = ECS::Product::Inventory::WIP::adjustWipQty({
		'dbh'   =>	$p->{'DBH'},
		'info'  => {
			'productID'	=>	$p->{'input'}->{'productID'},
			'fromLoc'	=>	'oo',
			'toLoc'		=>	'rec',
			'qtyToMove'	=>	($failedQty < $input->{'qtyWipOO'}) ? $failedQty : $input->{'qtyWipOO'}
		}
	}) if $failedQty;
	
	# Don't tell the user how many to send to shelf.
	# He will eventually be prompted on the final scan to move 'everything left' to the bin for shelf
	# $result->{'userMsg'} .= "Place " . $qty . " qty in the bin for shelf." if $updateReceive;
	
	return $result;
}
