Source code for market.restapi.campaigns_endpoint

import json

from datetime import datetime, timedelta
from twisted.web import http
from twisted.web import resource

from market.models.campaign import Campaign
from market.models.investment import InvestmentStatus
from market.restapi import get_param


[docs]class CampaignsEndpoint(resource.Resource): """ This class handles requests regarding campaigns in the mortgage market community. """ def __init__(self, market_community): resource.Resource.__init__(self) self.market_community = market_community
[docs] def render_GET(self, request): """ .. http:get:: /campaigns A GET request to this endpoint returns information about the ongoing campaigns. **Example request**: .. sourcecode:: none curl -X GET http://localhost:8085/campaigns **Example response**: .. sourcecode:: javascript { "campaigns": [{ "id": 8593AB_23, "mortgage": { "user_id": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "house": { "postal_code": "8593AB", "house_number": "23", "address": "Teststraat, Rotterdam", "price": 395000, "url": "http://www.funda.nl/koop/hollandscheveld/huis-49981036-3e-zandwijkje-8/", "seller_phone_number": "+31685938573", "seller_email": "seller@gmail.com" }, "bank": "ABN", "amount": 395000, "bank_amount": 200000, "mortgage_type": "FIXEDRATE", "interest_rate": 5.3, "max_investment_rate": 4.3, "default_rate": 4.3, "duration": 120, "risk": 300000, "status": "ACCEPTED" }, "amount": "195000", "end_date": "23-08-2017", "completed": False }, ...] } """ return json.dumps({"campaigns": [campaign.to_dictionary() for campaign in self.data_manager.campaigns]})
[docs] def render_PUT(self, request): """ .. http:put:: /campaigns A PUT request to this endpoint will create a new campaign. Various parameters are required: - mortgage_id: the identifier of the mortgage. This mortgage should be yours and be accepted. **Example request**: .. sourcecode:: none curl -X PUT http://localhost:8085/campaign --data "mortgage_id=8593AB_89" **Example response**: .. sourcecode:: javascript {"success": True} """ parameters = http.parse_qs(request.content.read(), 1) mortgage_id = get_param(parameters, 'mortgage_id') if not mortgage_id: request.setResponseCode(http.BAD_REQUEST) return json.dumps({"error": "missing mortgage id"}) mortgage = self.market_community.data_manager.get_mortgage(mortgage_id) if not mortgage: request.setResponseCode(http.NOT_FOUND) return json.dumps({"error": "mortgage with specified id not found"}) if mortgage.user_id != self.market_community.data_manager.you.id: request.setResponseCode(http.BAD_REQUEST) return json.dumps({"error": "this mortgage is not yours"}) if mortgage.campaign is not None: request.setResponseCode(http.BAD_REQUEST) return json.dumps({"error": "campaign for this mortgage already exists"}) # Create the campaign end_date = datetime.now() + timedelta(days=30) finance_goal = mortgage.amount - mortgage.bank_amount campaign = Campaign(self.market_community.data_manager.you, mortgage, finance_goal, end_date, False) self.data_manager.campaigns.append(campaign) #TODO(Martijn): broadcast it into the network return json.dumps({"success": True})
def getChild(self, path, request): return SpecificCampaignEndpoint(self.market_community, path)
[docs]class SpecificCampaignEndpoint(resource.Resource): """ This class handles requests for a specific campaign. """ def __init__(self, market_community, campaign_id): resource.Resource.__init__(self) self.market_community = market_community self.campaign_id = campaign_id self.putChild("investments", CampaignInvestmentsEndpoint(market_community, campaign_id))
[docs] def render_GET(self, request): """ .. http:get:: /campaigns/(string: campaign_id) A GET request to this endpoint returns detailled information about a specific campaign. **Example request**: .. sourcecode:: none curl -X GET http://localhost:8085/campaigns/8593AB_89 **Example response**: .. sourcecode:: javascript { "campaign": { "id": "8593AB_89", "user_id": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "mortgage": { "user_id": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "house": { "postal_code": "8593AB", "house_number": "23", "address": "Teststraat, Rotterdam", "price": 395000, "url": "http://www.funda.nl/koop/hollandscheveld/huis-49981036-3e-zandwijkje-8/", "seller_phone_number": "+31685938573", "seller_email": "seller@gmail.com" }, "bank": "ABN", "amount": 395000, "bank_amount": 200000, "mortgage_type": "FIXEDRATE", "interest_rate": 5.3, "max_investment_rate": 4.3, "default_rate": 4.3, "duration": 120, "risk": 300000, "status": "ACCEPTED" }, "amount": "195000", "end_date": "23-08-2017", "completed": False } } """ campaign = self.market_community.data_manager.get_campaign(self.campaign_id) if not campaign: request.setResponseCode(http.NOT_FOUND) return json.dumps({"error": "campaign not found"}) return json.dumps({"campaign": campaign.to_dictionary()})
[docs]class CampaignInvestmentsEndpoint(resource.Resource): """ This class handles requests regarding investments of a particular campaign """ def __init__(self, market_community, campaign_id): resource.Resource.__init__(self) self.market_community = market_community self.campaign_id = campaign_id def getChild(self, path, request): return SpecificCampaignInvestmentEndpoint(self.market_community, self.campaign_id, path)
[docs] def render_GET(self, request): """ .. http:get:: /campaigns/(string: campaign_id)/investments A GET request to this endpoint returns a list of investments of a campaign. **Example request**: .. sourcecode:: none curl -X GET http://localhost:8085/campaigns/8593AB_89/investments **Example response**: .. sourcecode:: javascript { "investments": [{ "investor_id": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "amount": 9000, "duration": 24, "interest_rate": 4.9, "mortgage_id": "8593AB_89", "status": "ACCEPTED" }, ...] } """ campaign = self.market_community.data_manager.get_campaign(self.campaign_id) if not campaign: request.setResponseCode(http.NOT_FOUND) return json.dumps({"error": "campaign not found"}) return json.dumps({"investments": [investment.to_dictionary() for investment in campaign.mortage.investments]})
[docs]class SpecificCampaignInvestmentEndpoint(resource.Resource): """ This class handles requests for a specific investment in a campaign """ def __init__(self, market_community, campaign_id, investment_id): resource.Resource.__init__(self) self.market_community = market_community self.campaign_id = campaign_id self.investment_id = investment_id
[docs] def render_PATCH(self, request): """ .. http:patch:: /campaigns/(string: campaign_id)/investments/(string: investment_id) A PATCH request to this endpoint will accept/reject an investment offer. This is performed by the borrower of a mortgage. **Example request**: .. sourcecode:: none curl -X PATCH http://localhost:8085/campaigns/8948EE_43/investments/4344503b7e797ebf31582327a5baae35b11bda01 --data "state=ACCEPT" **Example response**: .. sourcecode:: javascript {"success": True} """ campaign = self.market_community.data_manager.get_campaign(self.campaign_id) if not campaign: request.setResponseCode(http.NOT_FOUND) return json.dumps({"error": "campaign not found"}) investment = campaign.mortgage.get_investment(self.investment_id) if not investment: request.setResponseCode(http.NOT_FOUND) return json.dumps({"error": "investment not found"}) parameters = http.parse_qs(request.content.read(), 1) status = get_param(parameters, 'status') if not status: request.setResponseCode(http.BAD_REQUEST) return json.dumps({"error": "missing status parameter"}) if status not in ['ACCEPT', 'REJECT']: request.setResponseCode(http.BAD_REQUEST) return json.dumps({"error": "invalid status value"}) if investment.status[self.market_community.data_manager.you.id] != InvestmentStatus.PENDING: request.setResponseCode(http.BAD_REQUEST) return json.dumps({"error": "loan request is already accepted/rejected"}) if status == "ACCEPT": investment.status = InvestmentStatus.ACCEPTED else: investment.status = InvestmentStatus.REJECTED # TODO broadcast this into the network return json.dumps({"success": True})