#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package RPS::DB::Item::FinanceTransaction;
use strict;
use warnings;
use Carp;

use lib '/app/tools/common/lib';
use Common::DB::Item;
use Common::DB::ItemCollection;
use Common::Assert;
use base 'Common::DB::Item';

use lib '/app/tools/rps/lib';
use RPS::DB::Item::FinanceAccount;

# !!! Need to define currency types someplace
#

use constant kTypeOpeningBalance => 1;
use constant kTypeAdjustment     => 2;
use constant kTypeAdvance        => 3;
use constant kTypePayment        => 4;
use constant kTypeClosingBalance => 5;

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

sub rawSave {
    my ($self) = @_;
    return $self->SUPER::save();
}

sub save {
    my ($self) = @_;

    # Fetch the account's currency type for a quick sanity check.
    # We can't mix currencies in an account...
    #
    # !!! If it wasn't specified, default to the account's currency_code
    #
    my $accountID = $self->finance_account_id;
    my $accountDBItem = RPS::DB::Item::FinanceAccount->Lookup( finance_account_id => $accountID );
    die "ERROR - invalid account ID $accountID" unless $accountDBItem;

    my $accountCurrency = $accountDBItem->currency_code;

    if ( !$self->currency_code() ) {
        $self->currency_code($accountCurrency);
    } else {
        die "ERROR - account currency_code $accountCurrency does not match transaction currency_code " . $self->currency_code()
          unless $self->currency_code() eq $accountCurrency;
    }

    # JPK - Setting the balance.  This would be better handled as a stored procedure...
    # But for now, select the _last_ transaction posted to this account, and add.
    #
    my $balance   = 0;
    my $lastTrans = RPS::DB::Item::FinanceTransaction->GetLastAccountTransaction( $self->finance_account_id );
    if ($lastTrans) {
        $balance = $lastTrans->balance;
    }
    $balance += $self->amount();
    $self->balance($balance);

    return $self->SUPER::save();
}

sub GetLastAccountTransaction {
    my ( $class, $accountID ) = @_;
    assert($accountID);

    # Going to use the collection interface, even though I only expect 1 result.
    # Just seems easier this way, oddly enough.
    #
    my $sql = "SELECT * FROM " . kTable . " WHERE finance_account_id=$accountID ORDER BY finance_transaction_id DESC LIMIT 1";

    my $collection = $class->GetAll($sql);

    return $collection->next();
}

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

    my $accountID = $args{finance_account_id};
    assert($accountID);

    # These dates _must_ be in datetime format,
    # YYYY-MM-DD HH-MM-SS
    #
    my $startDate = $args{start_date};
    my $endDate   = $args{end_date};

    my $sql = "SELECT * FROM " . kTable . " WHERE finance_account_id=$accountID";
    if ($startDate) {
        $sql .= " AND date >= '$startDate'";
    }
    if ($endDate) {
        $sql .= " AND date <= '$endDate'";
    }
    if ( $args{order_by} ) {
        $sql .= " ORDER BY " . $args{order_by};
    } else {
        $sql .= " ORDER BY finance_transaction_id";
    }

    return $class->GetAll($sql);
}

sub GetTransactionsHistoryByPublisher {
    my ( $class, $publisherID ) = @_;
    assert($publisherID);

    my $sql = "SELECT * FROM " . kTable . " WHERE finance_account_id IN (
        SELECT finance_account_id FROM publisher_account WHERE publisher_id = $publisherID
    )";

    return $class->GetAll($sql);
}

sub GetTransactionsHistoryByCAPublisher {
    my ( $class, $publisherID ) = @_;
    assert($publisherID);

    my $sql = "SELECT * FROM " . kTable . " WHERE finance_account_id IN (
        SELECT finance_account_id FROM ca_publisher_account WHERE ca_publisher_id = $publisherID
    )";

    return $class->GetAll($sql);
}

1;

