Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cms] Add ProposalSpendingSummary and ProposalSpendingDetails #1224

Merged
merged 14 commits into from
Jul 24, 2020
182 changes: 182 additions & 0 deletions politeiawww/api/cms/v1/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,188 @@ Reply:
}
```

### `Proposal Billing Summary`

Retrieve all billing information for all approved proposals.

This retrieves the tokens for approved proposals and uses those tokens to
search through the database for invoices that have line-items that have that
as proposal token added.

There is also a basic pagination feature implemented with an offset and a
page count of proposals to return. Note, there is a max proposal
spending list page count. If above 20, then it will be set to that max.
These are optional and if both unset, all proposal summaries will be returned.

Note: This call requires admin privileges.

**Route:** `GET /v1/proposals/spendingsummary`

**Params:**

| Parameter | Type | Description | Required |
|-|-|-|-|
| offset | int | Page offset | No |
| count | int | Page count | No |

**Results:**

| | Type | Description |
| - | - | - |
| proposals | Array of ProposalSpending | Aggregated information of spending for all approved proposals. |

**ProposalSpending:**

| | Type | Description |
| - | - | - |
| token | string | Censorship record token of proposal. |
| title | string | Title of approved proposal. |
| totalbilled | int64 | Total billed against the proposal (in US Cents) |
| invoices | Array of InvoiceRecord | All (partially filled) invoice records that have line items with the proposal token. |

**Example**

Request:

``` json
{}
```

Reply:

```json
{
"proposals": [{
"token": "8d14c77d9a28a1764832d0fcfb86b6af08f6b327347ab4af4803f9e6f7927225",
"title": "Super awesome proposal!",
"totalbilled": 115000,
"invoices": [
{
"status": 0,
"timestamp": 0,
"userid": "5c36086c-fa22-4c53-aee1-adafc4446751",
"username": "admin",
"publickey": "c0876a34451431b77ee9cd2e65662d0829010e0285d9fe1cc1e3ea20005b88bf",
"signature": "",
"file": null,
"version": "",
"input": {
"version": 0,
"month": 5,
"year": 2020,
"exchangerate": 1411,
"contractorname": "",
"contractorlocation": "",
"contractorcontact": "",
"contractorrate": 5000,
"paymentaddress": "",
"lineitems": [ {
"type": 1,
"domain": "Development",
"subdomain": "dvdddasf",
"description": "sadfasdfsdf",
"proposaltoken": "0de5bd82bcccf22f4ccd1881fc9d88159ace56d0c1cfc7dcd86656e738e46a87",
"subuserid": "",
"subrate": 0,
"labor": 1380,
"expenses": 0
}
]
}
}
]
}]
}
}
```

### `Proposal Billing Details`

Retrieve all billing information for the given proposal token.

Note: This call requires admin privileges.

**Route:** `POST /v1/proposals/spendingdetails`

**Params:**

| Parameter | Type | Description | Required |
|-|-|-|-|
| token | string | Token for approved proposal. | Yes |

**Results:**

| | Type | Description |
| - | - | - |
| details | ProposalSpending | Aggregated information for the given proposal token. |

**ProposalSpending:**

| | Type | Description |
| - | - | - |
| token | string | Censorship record token of proposal. |
| title | string | Title of approved proposal. |
| totalbilled | int64 | Total billed against the proposal (in US Cents) |
| invoices | Array of InvoiceRecord | All (partially filled) invoice records that have line items with the proposal token. |

**Example**

Request:

``` json
{
"token": "0de5bd82bcccf22f4ccd1881fc9d88159ace56d0c1cfc7dcd86656e738e46a87"
}
```

Reply:

```json
{
"details": {
"token": "8d14c77d9a28a1764832d0fcfb86b6af08f6b327347ab4af4803f9e6f7927225",
"title": "Super awesome proposal!",
"totalbilled": 115000,
"invoices": [
{
"status": 0,
"timestamp": 0,
"userid": "5c36086c-fa22-4c53-aee1-adafc4446751",
"username": "admin",
"publickey": "c0876a34451431b77ee9cd2e65662d0829010e0285d9fe1cc1e3ea20005b88bf",
"signature": "",
"file": null,
"version": "",
"input": {
"version": 0,
"month": 5,
"year": 2020,
"exchangerate": 1411,
"contractorname": "",
"contractorlocation": "",
"contractorcontact": "",
"contractorrate": 5000,
"paymentaddress": "",
"lineitems": [ {
"type": 1,
"domain": "Development",
"subdomain": "dvdddasf",
"description": "sadfasdfsdf",
"proposaltoken": "0de5bd82bcccf22f4ccd1881fc9d88159ace56d0c1cfc7dcd86656e738e46a87",
"subuserid": "",
"subrate": 0,
"labor": 1380,
"expenses": 0
}
]
}
}
]
}
}

```

### Error codes

| Status | Value | Description |
Expand Down
101 changes: 71 additions & 30 deletions politeiawww/api/cms/v1/v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,38 @@ const (
APIVersion = 1

// Contractor Management Routes
RouteInviteNewUser = "/invite"
RouteRegisterUser = "/register"
RouteCMSUsers = "/cmsusers"
RouteNewInvoice = "/invoices/new"
RouteEditInvoice = "/invoices/edit"
RouteInvoiceDetails = "/invoices/{token:[A-z0-9]{64}}"
RouteSetInvoiceStatus = "/invoices/{token:[A-z0-9]{64}}/status"
RouteUserInvoices = "/user/invoices"
RouteUserSubContractors = "/user/subcontractors"
RouteNewDCC = "/dcc/new"
RouteDCCDetails = "/dcc/{token:[A-z0-9]{64}}"
RouteGetDCCs = "/dcc"
RouteSupportOpposeDCC = "/dcc/supportoppose"
RouteNewCommentDCC = "/dcc/newcomment"
RouteDCCComments = "/dcc/{token:[A-z0-9]{64}}/comments"
RouteSetDCCStatus = "/dcc/{token:[A-z0-9]{64}}/status"
RouteCastVoteDCC = "/dcc/vote"
RouteVoteDetailsDCC = "/dcc/votedetails"
RouteActiveVotesDCC = "/dcc/activevotes"
RouteStartVoteDCC = "/dcc/startvote"
RouteAdminInvoices = "/admin/invoices"
RouteManageCMSUser = "/admin/managecms"
RouteAdminUserInvoices = "/admin/userinvoices"
RouteGeneratePayouts = "/admin/generatepayouts"
RouteInvoicePayouts = "/admin/invoicepayouts"
RoutePayInvoices = "/admin/payinvoices"
RouteInvoiceComments = "/invoices/{token:[A-z0-9]{64}}/comments"
RouteInvoiceExchangeRate = "/invoices/exchangerate"
RouteProposalOwner = "/proposals/owner"
RouteProposalBilling = "/proposals/billing"
RouteInviteNewUser = "/invite"
RouteRegisterUser = "/register"
RouteCMSUsers = "/cmsusers"
RouteNewInvoice = "/invoices/new"
RouteEditInvoice = "/invoices/edit"
RouteInvoiceDetails = "/invoices/{token:[A-z0-9]{64}}"
RouteSetInvoiceStatus = "/invoices/{token:[A-z0-9]{64}}/status"
RouteUserInvoices = "/user/invoices"
RouteUserSubContractors = "/user/subcontractors"
RouteNewDCC = "/dcc/new"
RouteDCCDetails = "/dcc/{token:[A-z0-9]{64}}"
RouteGetDCCs = "/dcc"
RouteSupportOpposeDCC = "/dcc/supportoppose"
RouteNewCommentDCC = "/dcc/newcomment"
RouteDCCComments = "/dcc/{token:[A-z0-9]{64}}/comments"
RouteSetDCCStatus = "/dcc/{token:[A-z0-9]{64}}/status"
RouteCastVoteDCC = "/dcc/vote"
RouteVoteDetailsDCC = "/dcc/votedetails"
RouteActiveVotesDCC = "/dcc/activevotes"
RouteStartVoteDCC = "/dcc/startvote"
RouteAdminInvoices = "/admin/invoices"
RouteManageCMSUser = "/admin/managecms"
RouteAdminUserInvoices = "/admin/userinvoices"
RouteGeneratePayouts = "/admin/generatepayouts"
RouteInvoicePayouts = "/admin/invoicepayouts"
RoutePayInvoices = "/admin/payinvoices"
RouteInvoiceComments = "/invoices/{token:[A-z0-9]{64}}/comments"
RouteInvoiceExchangeRate = "/invoices/exchangerate"
RouteProposalOwner = "/proposals/owner"
RouteProposalBilling = "/proposals/billing"
RouteProposalBillingSummary = "/proposals/spendingsummary"
RouteProposalBillingDetails = "/proposals/spendingdetails"

// Invoice status codes
InvoiceStatusInvalid InvoiceStatusT = 0 // Invalid status
Expand Down Expand Up @@ -174,6 +176,11 @@ const (
// statement contained within a DCC
PolicyMaxSponsorStatementLength = 5000

// ProposalBillingListPageSize is the maximum number of proposal billing
// summaries returned for the routes that return lists of proposal billing
// summaries.
ProposalBillingListPageSize = 50

ErrorStatusMalformedName www.ErrorStatusT = 1001
ErrorStatusMalformedLocation www.ErrorStatusT = 1002
ErrorStatusInvoiceNotFound www.ErrorStatusT = 1003
Expand Down Expand Up @@ -992,3 +999,37 @@ type CastVoteReply struct {
Error string `json:"error"` // Error status message
ErrorStatus cmsplugin.ErrorStatusT `json:"errorstatus,omitempty"` // Error status code
}

// ProposalBillingSummary allows for all proposal spending to be returned for
// an admin to review.
type ProposalBillingSummary struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I noticed that there's this struct defined but it doesn't seem like I can send start and end params (at least it's not documented).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops sorry that was an early addition and forgot to remove. Thanks for pointing out. Removed.

lukebp marked this conversation as resolved.
Show resolved Hide resolved
lukebp marked this conversation as resolved.
Show resolved Hide resolved
Offset int `json:"offset"` // Amount to offset for pagination
Count int `json:"count"` // Size of page for pagination
}

// ProposalBillingSummaryReply returns an array of proposal spending based on
// the list of approved invoices returned from the respective proposals site.
type ProposalBillingSummaryReply struct {
Proposals []ProposalSpending `json:"proposals"`
}

// ProposalSpending contains all the information about a given proposal's
// spending.
type ProposalSpending struct {
Token string `json:"token"`
Title string `json:"title"`
TotalBilled int64 `json:"totalbilled"`
Invoices []InvoiceRecord `json:"invoices"`
}

// ProposalBillingDetails returns all the information about the given proposal's
// spending.
type ProposalBillingDetails struct {
Token string `json:"token"`
}

// ProposalBillingDetailsReply returns the spending information about the
// requested proposal.
type ProposalBillingDetailsReply struct {
Details ProposalSpending `json:"details"`
}
Loading