//pragma solidity >=0.6.10 <0.8.20;
pragma solidity ^0.4.24;
pragma experimental ABIEncoderV2;

import "../Table.sol";

//档案申请
contract Application {
    event CreateResult(int256 count);
    event InsertResult(int256 count);
    event UpdateResult(int256 count);
    event RemoveResult(int256 count);
    
    
    TableFactory tableFactory = TableFactory(0x1001); 
    string constant TABLE_SUFFIX = "_application";
    string constant KEY_NAME = "key";
    string constant KEY_VALUE = "key";
    
    struct ApplicationData{
        string  id;
        string  used_org_code;
        int256  provider_audit_status;
        string  used_json_data;
        string  provider_json_data;
        string  application_json_data;
        int256  create_time;
        int256  update_time;
    }
    
    //利用方审批完成后上链
    function insert(string memory table_prefix,string memory id,string memory used_org_code,string memory used_json_data,string memory application_json_data,int256 create_time,int256 update_time) 
    public 
    returns(int256,string memory){
        //确定表格名称
        string memory table_name = string(abi.encodePacked(table_prefix, TABLE_SUFFIX));
        Table table = tableFactory.openTable(table_name);
         //id重复校验
        if(existById(id,table)){
            return (0,"id exists,insert failed");
        }
        Entry entry = table.newEntry();
        entry.set(KEY_NAME, KEY_VALUE);
        entry.set("id", id);
        entry.set("used_org_code", used_org_code);
        entry.set("provider_audit_status", int256(0));
        entry.set("used_json_data", used_json_data);
        entry.set("application_json_data", application_json_data);
        entry.set("create_time", create_time);
        entry.set("update_time", update_time);

        int256 count = table.insert(KEY_VALUE, entry);
        if(count>0){
            emit InsertResult(count);
        }

        return (count,"success");
        
    }
    
    //提供方完成审批后的结果上链
    function updateAudit(string memory table_prefix,string memory id,string memory provider_json_data,int256 update_time) 
    public 
    returns(int256,string memory){
        //确定表格名称
        string memory table_name = string(abi.encodePacked(table_prefix, TABLE_SUFFIX));
        Table table = tableFactory.openTable(table_name);
         //id重复校验
        if(!existById(id,table)){
            return (0,"id not find");
        }
        Entry entry = table.newEntry();
        entry.set(KEY_NAME, KEY_VALUE);
        entry.set("provider_json_data", provider_json_data);
        entry.set("provider_audit_status",  int256(1));
        entry.set("update_time", update_time);

        Condition condition = table.newCondition();
        condition.EQ("id", id);

        int256 count = table.update(KEY_VALUE, entry, condition);
        if(count>0){
            emit UpdateResult(count);
        }
        return (count,"success");
        
    }
    
    //提供方查询目标为本提供方的待本公司审批的审批记录
    function selectProviderNotAudit(string memory table_prefix)
    public
    view
    returns (ApplicationData[]){
         //确定表格名称
        string memory table_name = string(abi.encodePacked(table_prefix, TABLE_SUFFIX));
        Table table = tableFactory.openTable(table_name);

        Condition condition = table.newCondition();
        condition.EQ("provider_audit_status", int256(0));
        
        Entries entries = table.select(KEY_VALUE, condition);
         uint256  dataLen =   uint256(entries.size());
        ApplicationData[] memory applicationDatas =  new ApplicationData[](dataLen);
        
        for (uint256 i = 0; i < dataLen; ++i) {
            Entry entry = entries.get(int256(i));
            applicationDatas[i]=ApplicationData(entry.getString("id"),entry.getString("used_org_code"),entry.getInt("provider_audit_status"),entry.getString("used_json_data"),entry.getString("provider_json_data"),entry.getString("application_json_data"),entry.getInt("create_time"),entry.getInt("update_time"));
        }

        return (applicationDatas);
    }
    
    //利用方查询本机构发起的且提供方已经完成的审批结果
    function selectUsedAudit(string memory table_prefix,string memory used_org_code)
    public
    view
    returns (ApplicationData[]){
         //确定表格名称
        string memory table_name = string(abi.encodePacked(table_prefix, TABLE_SUFFIX));
        Table table = tableFactory.openTable(table_name);

        Condition condition = table.newCondition();
        condition.EQ("provider_audit_status", int256(1));
        condition.EQ("used_org_code", used_org_code);
        
        Entries entries = table.select(KEY_VALUE, condition);
         uint256  dataLen =   uint256(entries.size());
        ApplicationData[] memory applicationDatas =  new ApplicationData[](dataLen);
        
        for (uint256 i = 0; i < dataLen; ++i) {
            Entry entry = entries.get(int256(i));
            applicationDatas[i]=ApplicationData(entry.getString("id"),entry.getString("used_org_code"),entry.getInt("provider_audit_status"),entry.getString("used_json_data"),entry.getString("provider_json_data"),entry.getString("application_json_data"),entry.getInt("create_time"),entry.getInt("update_time"));
        }

        return (applicationDatas);

    }
    
    //利用方查询本机构发起的且提供方已经完成的审批结果，更新时间后的
    function selectUsedAuditAndUpdateTime(string memory table_prefix,string memory used_org_code,int256 update_time)
    public
    view
    returns (ApplicationData[]){
         //确定表格名称
        string memory table_name = string(abi.encodePacked(table_prefix, TABLE_SUFFIX));
        Table table = tableFactory.openTable(table_name);

        Condition condition = table.newCondition();
        condition.EQ("provider_audit_status", int256(1));
        condition.EQ("used_org_code", used_org_code);
        condition.GE("update_time", update_time);
        
        Entries entries = table.select(KEY_VALUE, condition);
         uint256  dataLen =   uint256(entries.size());
        ApplicationData[] memory applicationDatas =  new ApplicationData[](dataLen);
        
        for (uint256 i = 0; i < dataLen; ++i) {
            Entry entry = entries.get(int256(i));
            applicationDatas[i]=ApplicationData(entry.getString("id"),entry.getString("used_org_code"),entry.getInt("provider_audit_status"),entry.getString("used_json_data"),entry.getString("provider_json_data"),entry.getString("application_json_data"),entry.getInt("create_time"),entry.getInt("update_time"));
        }

        return (applicationDatas);

    }
    
        
    //根据id判定是否存在
    function existById(string memory id,Table table)
    private
    view
    returns (bool){
        Condition condition = table.newCondition();
        condition.EQ("id", id);
        Entries entries = table.select(KEY_VALUE, condition);
        return entries.size()>0;
    }
    
}