github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/blockapps-ba-master/server/lib/project/contracts/ProjectManager.sol (about)

     1  import "./Project.sol";
     2  import "./ProjectState.sol";
     3  import "./ProjectEvent.sol";
     4  import "../../bid/contracts/Bid.sol";
     5  import "../../bid/contracts/BidState.sol";
     6  import "../../common/ErrorCodes.sol";
     7  import "../../common/Util.sol";
     8  
     9  /**
    10  * Interface for Project data contracts
    11  */
    12  contract ProjectManager is ErrorCodes, Util, ProjectState, ProjectEvent, BidState {
    13  
    14    Project[] projects;
    15    uint bidId; // unique identifier for bids
    16  
    17    /*
    18      note on mapping to array index:
    19      a non existing mapping will return 0, so 0 should not be a valid value in a map,
    20      otherwise exists() will not work
    21    */
    22    mapping (bytes32 => uint) nameToIndexMap;
    23  
    24    /**
    25    * Constructor
    26    */
    27    function ProjectManager() {
    28      projects.length = 1; // see above note
    29      bidId = block.number;
    30    }
    31  
    32    function exists(string name) returns (bool) {
    33      return nameToIndexMap[b32(name)] != 0;
    34    }
    35  
    36    function getProject(string name) returns (address) {
    37      uint index = nameToIndexMap[b32(name)];
    38      return projects[index];
    39    }
    40  
    41    /*
    42    string addressStreet,
    43    string addressCity,
    44    string addressState,
    45    string addressZip
    46    */
    47    //      addressStreet,
    48    //      addressCity,
    49    //      addressState,
    50    //      addressZip
    51  
    52    function createProject(
    53      string name,
    54      string buyer,
    55      string description,
    56      string spec,
    57      uint price,
    58      uint created,
    59      uint targetDelivery
    60    ) returns (ErrorCodes) {
    61      // name must be < 32 bytes
    62      if (bytes(name).length > 32) return ErrorCodes.ERROR;
    63      // fail if username exists
    64      if (exists(name)) return ErrorCodes.EXISTS;
    65      // add project
    66      uint index = projects.length;
    67      nameToIndexMap[b32(name)] = index;
    68      projects.push(new Project(
    69        name,
    70        buyer,
    71        description,
    72        spec,
    73        price,
    74        created,
    75        targetDelivery
    76      ));
    77      return ErrorCodes.SUCCESS;
    78    }
    79  
    80    function createBid(string name, string supplier, uint amount) returns (ErrorCodes, uint) {
    81      // fail if project name not found
    82      if (!exists(name)) return (ErrorCodes.NOT_FOUND, 0);
    83      // create bid
    84      bidId++; // increment the unique id
    85      Bid bid = new Bid(bidId, name, supplier, amount);
    86      return (ErrorCodes.SUCCESS, bidId);
    87    }
    88  
    89    function settleProject(string name, address supplierAddress, address bidAddress) returns (ErrorCodes) {
    90      // validity
    91      if (!exists(name)) return (ErrorCodes.NOT_FOUND);
    92      // set project state
    93      address projectAddress = getProject(name);
    94      var (errorCode, state) = handleEvent(projectAddress, ProjectEvent.RECEIVE);
    95      if (errorCode != ErrorCodes.SUCCESS) return errorCode;
    96      // settle
    97      Bid bid = Bid(bidAddress);
    98      return bid.settle(supplierAddress);
    99    }
   100  
   101    /**
   102     * handleEvent - transition project to a new state based on incoming event
   103     */
   104    function handleEvent(address projectAddress, ProjectEvent projectEvent) returns (ErrorCodes, ProjectState) {
   105      Project project = Project(projectAddress);
   106      ProjectState state = project.getState();
   107      // check transition
   108      var (errorCode, newState) = fsm(state, projectEvent);
   109      // event is not valid in current state
   110      if (errorCode != ErrorCodes.SUCCESS) {
   111        return (errorCode, state);
   112      }
   113      // use the new state
   114      project.setState(newState);
   115      return (ErrorCodes.SUCCESS, newState);
   116    }
   117  
   118    function fsm(ProjectState state, ProjectEvent projectEvent) returns (ErrorCodes, ProjectState) {
   119      // NULL
   120      if (state == ProjectState.NULL)
   121        return (ErrorCodes.ERROR, state);
   122      // OPEN
   123      if (state == ProjectState.OPEN) {
   124        if (projectEvent == ProjectEvent.ACCEPT)
   125          return (ErrorCodes.SUCCESS, ProjectState.PRODUCTION);
   126      }
   127      // PRODUCTION
   128      if (state == ProjectState.PRODUCTION) {
   129        if (projectEvent == ProjectEvent.DELIVER)
   130          return (ErrorCodes.SUCCESS, ProjectState.INTRANSIT);
   131      }
   132      // INTRANSIT
   133      if (state == ProjectState.INTRANSIT) {
   134        if (projectEvent == ProjectEvent.RECEIVE)
   135          return (ErrorCodes.SUCCESS, ProjectState.RECEIVED);
   136      }
   137      return (ErrorCodes.ERROR, state);
   138    }
   139  }