#------------------------------------------------------------
# Copyright (C) 2012 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------
package RPS::DB::Item::DynamicReport::Sales::ByRoyaltyRun;

use strict;
use warnings;
use lib '/app/tools/common/lib';
use Common::RSApp;
use Common::Log;
use Common::DB::Item;
use Common::DB::ItemCollection;
use Common::Assert;
use Data::Dumper;

use lib '/app/tools/rps/lib';

use RPS::DB::Item::SaleRunMap;

# !!! Not sure if I can actually inherit from 'Base' or not.
# !!! They do return the same columns, and support the same options.
# !!! But, this class queries sale_run_map primarily, and joins sale.
# !!! Still, it might work...
use base 'RPS::DB::Item::DynamicReport::Sales::Base';

use constant kDB => Common::DB::Item::kClientDB();



# Before we do the 'real' query, we need to build a temporary table to contain all the sale_ids, gleaned
# from the sale_run_map.   Using a temp table avoids having to do a dependent subquery, which would be 
# extrememly slow on large data sets.
#
sub ReportQuery
{
    my ($class, %args) = @_;
    my $showByType = $args{showByType};

    # Create a reasonable unique table name using our PID.
    #
    my $tempTable = 'zz_sale_report_sale_ids_'.$$;
    $class->_BuildTemporarySaleIDTable($tempTable, %args);

    $args{_tempTableName} = $tempTable;
    $class->SUPER::ReportQuery(%args);
}

sub _BuildTemporarySaleIDTable
{
    my ($class, $tableName, %args) = @_;

    my $dbo = Common::RSApp::GetClientDB();
    my $sql = "CREATE TEMPORARY TABLE $tableName SELECT DISTINCT sale_id FROM sale_run_map WHERE "
     . 'sale_run_map.run_id = ' . $class->quote($args{runID})
     . ' AND sale_run_map.run_type = ' . $class->quote($class->_getRunType(%args))
     . " AND sale_run_map.status = 'paid'";
     
    $dbo->DoCmd($sql);
}


sub _____BuildSelect
{
    my ($class, $select, %args) = @_;


    # !!! This is perhaps a bit of a hack.  We'll call the inherited method first.
    # !!! Then we'll modify the first item in the array.
    # !!! I consider this a hack because if we make changes in the base class that
    # !!! subsequently violates our expectations of what the first item in the array is,
    # !!! this will break.
    #
    # !!! Actually, because of that, I'm going to make this slightly inefficient, but safer.
    #

    # Let's isolate the select items the inherited method returns in a seperate array.
    # That way I can safely examine them and decide which ones I _really_ want.
    #
    my @inheritedSelect;
    $class->SUPER::_BuildSelect(\@inheritedSelect, %args);

    foreach my $clause (@inheritedSelect)
    {
        if ($clause =~ /AS sale_sale_id/i)
        {
            push @$select, 'DISTINCT sale_run_map.sale_id AS sale_sale_id';
        }
        else
        {
            push @$select, $clause;
        }
    }
}

sub _____BuildFrom
{
    my ($class, $from, %args) = @_;
    
    # The primary difference in this class is that we primarily query sale_run_map, not sale.
    #
    push @$from, 'sale_run_map';
}


sub _BuildJoins
{
    my ($class, $joins, %args) = @_;
    my $showByType = $args{showByType};

#    push @$joins, 'LEFT JOIN sale ON (sale.sale_id = sale_run_map.sale_id)';

    my $tempTable = $args{_tempTableName};
    if ($tempTable)
    {
        push @$joins, "INNER JOIN $tempTable USING (sale_id)";
    }
    
    return $class->SUPER::_BuildJoins($joins, %args);
}


sub ____BuildWhere
{
    my ($class, $where, %args) = @_;

    my $runID = $args{runID};
    push @$where, 'sale_run_map.run_id = ' . $class->quote($args{runID});
    push @$where, 'sale_run_map.run_type = ' . $class->quote($class->_getRunType(%args));
    push @$where, "sale_run_map.status = 'paid'";

    return $class->SUPER::_BuildWhere($where, %args);
}


1;
