contract    DiamondTransaction is ERC20
{
    struct TDiamondTransaction
    {
        bool        isBuyTransaction;           // Tells if this transaction was for us to buy diamonds or just to sell diamonds
        uint        authorityId;                // id(0)=GIA
        uint        certificate;                // Can be a direct certificat value (from GIA), or an HEX value if alpnumeric from other authorities
        uint        providerId;                 // The vendor/Acqueror of the TTransaction
        uint        vaultId;                    // ID of the secured vault used in our database
        uint        sourceId;                   // Diamcoin: 0     partners > 0
        uint        caratAmount;                // 3 decimals value flatten to an integer
        uint        tokenAmount;                //
        uint        tokenId;                    // ID of the token used to sold. IT should be id=0 for Diamcoin
        uint        timestamp;                  // When the transaction occurred
        bool        isValid;                    // Should always be TRUE (=1)
    }

    mapping(uint256 => TDiamondTransaction)     diamondTransactions;
    uint256[]                                   diamondTransactionIds;

    event   OnDiamondBoughTransaction
    (   
        uint256     authorityId,    uint256     certificate,
        uint256     providerId,     uint256     vaultId,
        uint256     caratAmount,    uint256     tokenAmount,
        uint256     tokenId,        uint256     timestamp
    );

    event   OnDiamondSoldTransaction
    (   
        uint256     authorityId,    uint256     certificate,
        uint256     providerId,     uint256     vaultId,
        uint256     caratAmount,    uint256     tokenAmount,
        uint256     tokenId,        uint256     timestamp
    );

    //--------------------------------------------------------------------------
    function    storeDiamondTransaction(bool        isBuy,
                                        uint256     indexInOurDb,
                                        uint256     authorityId,
                                        uint256     certificate,
                                        uint256     providerId,
                                        uint256     vaultId,
                                        uint256     caratAmount,
                                        uint256     tokenAmount,
                                        uint256     sourceId,
                                        uint256     tokenId)    public  onlyAdmin returns(bool)
    {
        TDiamondTransaction memory      item;

        item.isBuyTransaction = isBuy;          item.authorityId = authorityId;
        item.certificate      = certificate;    item.providerId  = providerId;
        item.vaultId          = vaultId;        item.caratAmount = caratAmount;
        item.tokenAmount      = tokenAmount;    item.tokenId     = tokenId;
        item.timestamp        = now;            item.isValid     = true;
        item.sourceId         = sourceId;

        diamondTransactions[indexInOurDb] = item; 
        diamondTransactionIds.push(indexInOurDb)-1;

        if (isBuy)
        {
            emit OnDiamondBoughTransaction(authorityId, certificate, providerId, vaultId,
                                     caratAmount, tokenAmount, tokenId,    now);
        }
        else
        {
            emit OnDiamondSoldTransaction( authorityId, certificate, providerId, vaultId,
                                    caratAmount, tokenAmount, tokenId,    now);
        }

        return true;                    // this is only for our external API use
    }
    //--------------------------------------------------------------------------
    function    getDiamondTransaction(uint256 transactionId) public view  returns(/*uint256,*/uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)
    {
        TDiamondTransaction memory    item;

        item = diamondTransactions[transactionId];

        return
        (
            (item.isBuyTransaction)?1:0,
             item.authorityId,
             item.certificate,
             item.providerId,
             item.vaultId,
             item.caratAmount,
            (item.isValid?1:0),
             item.tokenId,
             item.timestamp,
             item.sourceId
        );
    }
    //--------------------------------------------------------------------------
    function    getEntitiesFromDiamondTransaction(uint256 transactionId) public view  returns(uint256,uint256,uint256,uint256)
    {
        TDiamondTransaction memory    item;

        item = diamondTransactions[transactionId];

        return                                      // If you want to know who was involved in that transaction
        (
            item.authorityId,
            item.certificate,
            item.providerId,
            item.vaultId
        );
    }
    //--------------------------------------------------------------------------
    function    getAmountsAndTypesFromDiamondTransaction(uint256 transactionId) public view  returns(uint256,uint256,uint256,uint256,uint256,uint256,uint256)
    {
        TDiamondTransaction memory    item;

        item = diamondTransactions[transactionId];

        return
        (
            (item.isBuyTransaction)?1:0,
             item.caratAmount,
             item.tokenAmount,
             item.tokenId,
            (item.isValid?1:0),
             item.timestamp,
             item.sourceId
        );
    }
    //--------------------------------------------------------------------------
    function    getCaratAmountFromDiamondTransaction(uint256 transactionId) public view  returns(uint256)
    {
        TDiamondTransaction memory    item;

        item = diamondTransactions[transactionId];

        return item.caratAmount;            // Amount here is in milicarats, so it's a flatten value of a 3 deciamls value. ie: 1.546 carats is 1546 here
    }
    //--------------------------------------------------------------------------
    function    getTokenAmountFromDiamondTransaction(uint256 transactionId) public view  returns(uint256)
    {
        TDiamondTransaction memory    item;

        item = diamondTransactions[transactionId];

        return item.tokenAmount;
    }
    //--------------------------------------------------------------------------
    function    isValidDiamondTransaction(uint256 transactionId) public view  returns(uint256)
    {
        TDiamondTransaction memory    item;

        item = diamondTransactions[transactionId];

        return (item.isValid?1:0);
    }
    //--------------------------------------------------------------------------
    function    changeDiamondTransactionStatus(uint256 transactionId, uint256 newStatus) public view  onlyAdmin returns(uint256)
    {
        TDiamondTransaction memory    item;

        item         = diamondTransactions[transactionId];

        item.isValid = (newStatus==0) ? false:false;            // in case there was any issue with the transaction, set it as invalid (=2) or invalid=0

        return 1;           // needed for our API
    }
    //--------------------------------------------------------------------------
    function    getDiamondTransactionCount() public view  returns(uint256)
    {
        return diamondTransactionIds.length;
    }
    //--------------------------------------------------------------------------
    function    getDiamondTransactionAtIndex(uint256 index) public view  returns(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)
    {
        TDiamondTransaction memory  DT;
        uint256                     txId;

        if (index<diamondTransactionIds.length)
        {
            txId = diamondTransactionIds[index];
            DT   = diamondTransactions[txId];

            return
            (
                (DT.isBuyTransaction)?1:0,
                 DT.authorityId,
                 DT.certificate,
                 DT.providerId,
                 DT.vaultId,
                 DT.caratAmount,
                (DT.isValid?1:0),
                 DT.tokenId,
                 DT.timestamp,
                 DT.sourceId
            );
        }

        return (0,0,0,0,0,0,0,0,0,0);
    }
}
////////////////////////////////////////////////////////////////////////////////
function    changeDiamondTransactionStatus(uint256 transactionId, uint256 newStatus) public view  onlyAdmin returns(uint256)
{
    TDiamondTransaction memory    item;

    item         = diamondTransactions[transactionId];

    item.isValid = (newStatus==0) ? false:false;            // in case there was any issue with the transaction, set it as invalid (=2) or invalid=0

    return 1;           // needed for our API
}

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