Untitled

mail@pastecode.io avatar
unknown
plain_text
3 years ago
4.2 kB
1
Indexable
Never
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";

contract RealState{

    using SafeMath for uint;

    address public contractOwner;
    address public owner;
    address public tenant;

    //پورسانت صاحب قرار داد
    uint public contractFee;

    uint firstDeposit;
    uint rentAmount;

    uint startDate;
    uint delayDates;

    uint month = 1;

    constructor(address _owner, uint _firstDeposit, uint _rentAmount, uint _contractFee){
        contractOwner = _owner;
        firstDeposit = _firstDeposit;
        rentAmount = _rentAmount;
        contractFee = _contractFee;
    }

    event paymentPaid (address indexed _Owner, address indexed Tenant, uint _Amount);

    enum contractSate {NotStarted, Started, Ended, Suspanded}
    contractSate state;
    contractSate constant defaultState = contractSate.NotStarted;

    //چک کردن هزینه اجاره هر ماه
    modifier checkRentAmount(uint _amount){
        require(_amount == rentAmount, "your money is not equal to rent payment");
        _;
    }

    //چک کردن هزینه اولیه قرار داد
    modifier checkInitialAmount(uint _amount){
        require(_amount == firstDeposit, "your money is not equal to rent payment");
        _;
    }

    modifier onlyTenant{
        require(msg.sender == tenant && state == contractSate.Ended, "you cannot withdraw initial payment now !");
        _;
    }

    modifier onlyOwner{
        require(msg.sender == owner && address(this).balance==delayDates*0.01 ether, "you cannot call this function MAN !");
        _;
    }

    //دیتای مربوط به پرداخت هر ماه
    struct paidMonths{
        uint _month;
        uint _time;
        uint _amount;
    }

    //ذخیره وضعیت هر ماه در مپیینگ
    mapping(uint => paidMonths) public statusMonths;

    //پرداخت مبلغ اولیه اجاره و مشخص کردن مستاجر و شروع قرار داد 
    function payInitialMoney(uint _amount) public payable checkInitialAmount(_amount){

        tenant = msg.sender;
        state = contractSate.Started;
        startDate = block.timestamp;

        emit paymentPaid(msg.sender, address(this), _amount);

    }

    //پرداخت ماهیانه اجاره ها
    function payRent(uint _amount) public payable checkRentAmount(_amount){

        //محاسبه کارمزد صاحب قرار داد
        uint getContractFee = (address(this).balance.mul(contractFee)).div(100);
        uint finalPayment = address(this).balance.sub(getContractFee);

        //پرداخت کارمزد به صاحب قرار داد
        payable(contractOwner).transfer(getContractFee);

        payable(owner).transfer(finalPayment);
        
        emit paymentPaid(msg.sender, owner, finalPayment);

        if( month == 12 ){

            state = contractSate.Ended;
            delayDates = delayDates.add(block.timestamp-(firstDeposit + 35 days))/86400;
            paidMonths memory newPayment = paidMonths(month, block.timestamp, _amount);
            statusMonths[month] = newPayment;

        } else{

        delayDates = delayDates.add(block.timestamp-(firstDeposit + 35 days))/86400;
        paidMonths memory newPayment = paidMonths(month, block.timestamp, _amount);
        statusMonths[month] = newPayment;

        month = month.add(1);

        }
    }

    //برداشت پول اولیه
    function withdrawInitialPayment() public onlyTenant{
        uint remainingDeposit = address(this).balance.sub(delayDates*0.01 ether);
        payable(tenant).transfer(remainingDeposit);
        emit paymentPaid(address(this), tenant, remainingDeposit);

        payable(owner).transfer(delayDates*0.01 ether);
        emit paymentPaid(address(this), owner, delayDates*0.01 ether);
    }

    //کنسل شن قرار داد
    function cancellContractByOwner() public onlyOwner{

        payable(owner).transfer(address(this).balance);
        emit paymentPaid(address(this), owner, address(this).balance);

        state = contractSate.Suspanded;
    }
}