<?php
/**
 * Class represents records from table selfservice_spend
 * {autogenerated}
 * @property int $history_id PK
 * @property datetime $dattm
 * @property int $user_id FK user
 * @property int $type_id FK selfservice_type
 * @property int $value
 * @property string|null $record_type
 * @property string|null $table
 * @property int|null $record_id
 * @property string|null $description
 * @property string|null $url
 * @property date|null $expire
 * {/autogenerated}
 */
class SelfserviceHistory extends Am_Record
{
}

/** @extends Am_Table<SelfserviceHistory> */
class SelfserviceHistoryTable extends Am_Table
{
    protected $_key = 'history_id';
    protected $_table = '?_selfservice_history';

    /**
     * (-)
     *
     * @param User $user
     * @param int $amount
     * @param int $type
     * @param string $comment
     * @return int balance after debit
     */
    function debit(User $user, $amount, $type_id, $comment = '',
                        $table = null, $record_id = null, $url = null)
    {
        if ($amount > $this->getDi()->selfserviceBalanceTable->balance($user, $type_id))
            throw new Am_Exception_SelfServiceError(___("Not enough credits to debit"));

        $r = $this->createRecord();
        $r->dattm = $this->getDi()->sqlDateTime;
        $r->user_id = $user->pk();
        $r->type_id = $type_id;
        $r->value = - abs( $amount );
        $r->description = $comment;
        $r->record_type = 'debit';
        $r->table = $table;
        $r->record_id = $record_id;
        $r->url = $url;

        $r->insert();

        $this->calculateBalance($user);

        return $this->getDi()->selfserviceBalanceTable->balance($user, $type_id);
    }

    /**
     * (+)
     *
     * @param User $user
     * @param int $amount
     * @param int $type
     * @param string $comment
     * @return int balance after credit
     */
    function credit(User $user, $amount, $type_id, $comment = '',
                        $table = null, $record_id = null, $expire=Am_Period::MAX_SQL_DATE)
    {
        $r = $this->createRecord();
        $r->dattm = $this->getDi()->sqlDateTime;
        $r->user_id = $user->pk();
        $r->type_id = $type_id;
        $r->value = abs( $amount );
        $r->description = $comment;
        $r->record_type = 'credit';
        $r->table = $table;
        $r->record_id = $record_id;
        $r->expire = $expire;
        $r->insert();

        $this->calculateBalance($user);

        return $this->getDi()->selfserviceBalanceTable->balance($user, $type_id);
    }

    /**
     * (-)
     *
     * @param User $user
     * @param int $amount
     * @param int $type
     * @param string $comment
     * @return int balance after debit
     */
    function refund(User $user, $amount, $type_id, $comment = '',
                        $table = null, $record_id = null, $url = null)
    {
        $r = $this->createRecord();
        $r->dattm = $this->getDi()->sqlDateTime;
        $r->user_id = $user->pk();
        $r->type_id = $type_id;
        $r->value = - abs( $amount );
        $r->description = $comment;
        $r->record_type = 'debit';
        $r->table = $table;
        $r->record_id = $record_id;
        $r->url = $url;

        $r->insert();

        $this->calculateBalance($user);

        return $this->getDi()->selfserviceBalanceTable->balance($user, $type_id);
    }

    protected function calculateBalance(User $user)
    {
        $this->getDi()->db->query('
            INSERT INTO ?_selfservice_balance (user_id, type_id, balance)
            SELECT user_id, type_id, SUM(value)
                FROM ?_selfservice_history WHERE user_id = ?d
                GROUP BY user_id, type_id
            ON DUPLICATE KEY UPDATE
            balance = VALUES(balance)',
            $user->pk());
    }
}