Details
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
index e0f6ed0..56ee93f 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
@@ -16,6 +16,7 @@
package com.ning.billing.invoice.api;
+import com.ning.billing.catalog.api.Currency;
import com.ning.billing.util.callcontext.CallContext;
import org.joda.time.DateTime;
@@ -42,4 +43,9 @@ public interface InvoiceUserApi {
public void tagInvoiceAsWrittenOff(UUID invoiceId, CallContext context);
public void tagInvoiceAsNotWrittenOff(UUID invoiceId, CallContext context) throws InvoiceApiException;
+
+ public InvoiceItem getCreditById(UUID creditId) throws InvoiceApiException;
+
+ public InvoiceItem insertCredit( UUID accountId, BigDecimal amount, DateTime effectiveDate,
+ Currency currency, CallContext context) throws InvoiceApiException;
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
index ebb1216..7f2ced3 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -20,6 +20,8 @@ import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.util.callcontext.CallContext;
import org.joda.time.DateTime;
@@ -88,4 +90,15 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
public void tagInvoiceAsNotWrittenOff(final UUID invoiceId, final CallContext context) throws InvoiceApiException {
dao.removeWrittenOff(invoiceId, context);
}
+
+ @Override
+ public InvoiceItem getCreditById(final UUID creditId) throws InvoiceApiException {
+ return dao.getCreditById(creditId);
+ }
+
+ @Override
+ public InvoiceItem insertCredit(final UUID accountId, final BigDecimal amount, final DateTime effectiveDate,
+ final Currency currency, final CallContext context) throws InvoiceApiException {
+ return dao.insertCredit(accountId, amount, effectiveDate, currency, context);
+ }
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
index e33eced..779a359 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
@@ -22,8 +22,10 @@ import java.util.List;
import java.util.UUID;
import com.ning.billing.ErrorCode;
+import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.invoice.model.CreditInvoiceItem;
+import com.ning.billing.invoice.model.DefaultInvoice;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.IDBI;
import org.skife.jdbi.v2.Transaction;
@@ -47,6 +49,7 @@ import com.ning.billing.util.tag.dao.TagDao;
public class DefaultInvoiceDao implements InvoiceDao {
private final InvoiceSqlDao invoiceSqlDao;
private final InvoicePaymentSqlDao invoicePaymentSqlDao;
+ private final CreditInvoiceItemSqlDao creditInvoiceItemSqlDao;
private final TagDao tagDao;
private final NextBillingDatePoster nextBillingDatePoster;
@@ -57,6 +60,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
final TagDao tagDao) {
this.invoiceSqlDao = dbi.onDemand(InvoiceSqlDao.class);
this.invoicePaymentSqlDao = dbi.onDemand(InvoicePaymentSqlDao.class);
+ this.creditInvoiceItemSqlDao = dbi.onDemand(CreditInvoiceItemSqlDao.class);
this.nextBillingDatePoster = nextBillingDatePoster;
this.tagDao = tagDao;
}
@@ -317,6 +321,25 @@ public class DefaultInvoiceDao implements InvoiceDao {
}
@Override
+ public InvoiceItem getCreditById(final UUID creditId) throws InvoiceApiException {
+ return creditInvoiceItemSqlDao.getById(creditId.toString());
+ }
+
+ // TODO: make this transactional
+ @Override
+ public InvoiceItem insertCredit(final UUID accountId, final BigDecimal amount,
+ final DateTime effectiveDate, final Currency currency,
+ final CallContext context) {
+ Invoice invoice = new DefaultInvoice(accountId, effectiveDate, effectiveDate, currency);
+ invoiceSqlDao.create(invoice, context);
+
+ InvoiceItem credit = new CreditInvoiceItem(invoice.getId(), accountId, effectiveDate, amount, currency);
+ creditInvoiceItemSqlDao.create(credit, context);
+
+ return credit;
+ }
+
+ @Override
public void test() {
invoiceSqlDao.test();
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
index 870e756..c7e520b 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
@@ -16,8 +16,10 @@
package com.ning.billing.invoice.dao;
+import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceApiException;
+import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.api.InvoicePayment;
import com.ning.billing.util.callcontext.CallContext;
import org.joda.time.DateTime;
@@ -67,5 +69,11 @@ public interface InvoiceDao {
List<InvoicePayment> getChargebacksByPaymentAttemptId(final UUID paymentAttemptId);
- InvoicePayment getChargebackById(UUID chargebackId) throws InvoiceApiException;
+ InvoicePayment getChargebackById(final UUID chargebackId) throws InvoiceApiException;
+
+ InvoiceItem getCreditById(final UUID creditId) throws InvoiceApiException;
+
+ InvoiceItem insertCredit(final UUID accountId, final BigDecimal amount,
+ final DateTime effectiveDate, final Currency currency,
+ final CallContext context);
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
index 5eadd4e..e24effb 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
+import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.InvoiceApiException;
import org.joda.time.DateTime;
@@ -241,4 +242,14 @@ public class MockInvoiceDao implements InvoiceDao {
public InvoicePayment getChargebackById(UUID chargebackId) throws InvoiceApiException {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public InvoiceItem getCreditById(UUID creditId) throws InvoiceApiException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public InvoiceItem insertCredit(UUID accountId, BigDecimal amount, DateTime effectiveDate, Currency currency, CallContext context) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditCollectionJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditCollectionJson.java
new file mode 100644
index 0000000..66f4d0c
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditCollectionJson.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.json;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.List;
+import java.util.UUID;
+
+public class CreditCollectionJson {
+ private final UUID accountId;
+ private final List<CreditJson> credits;
+
+ @JsonCreator
+ public CreditCollectionJson(@JsonProperty("accountId") final UUID accountId,
+ @JsonProperty("credits") final List<CreditJson> credits) {
+ this.accountId = accountId;
+ this.credits = credits;
+ }
+
+ public UUID getAccountId() {
+ return accountId;
+ }
+
+ public List<CreditJson> getCredits() {
+ return credits;
+ }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java
new file mode 100644
index 0000000..bea3cf4
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.json;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.ning.billing.invoice.api.InvoiceItem;
+import org.joda.time.DateTime;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+// TODO: add invoice number, reason and requested date to the json
+public class CreditJson {
+ private final BigDecimal creditAmount;
+ private final UUID invoiceId;
+ private final String invoiceNumber;
+ private final DateTime requestedDate;
+ private final DateTime effectiveDate;
+ private final String reason;
+
+ @JsonCreator
+ public CreditJson(@JsonProperty("creditAmount") final BigDecimal creditAmount,
+ @JsonProperty("invoiceId") final UUID invoiceId,
+ @JsonProperty("invoiceNumber") final String invoiceNumber,
+ @JsonProperty("requestedDate") final DateTime requestedDate,
+ @JsonProperty("effectiveDate") final DateTime effectiveDate,
+ @JsonProperty("reason") final String reason) {
+ this.creditAmount = creditAmount;
+ this.invoiceId = invoiceId;
+ this.invoiceNumber = invoiceNumber;
+ this.requestedDate = requestedDate;
+ this.effectiveDate = effectiveDate;
+ this.reason = reason;
+ }
+
+ public CreditJson(InvoiceItem credit) {
+ this.creditAmount = credit.getAmount();
+ this.invoiceId = credit.getInvoiceId();
+ this.invoiceNumber = null;
+ this.requestedDate = null;
+ this.effectiveDate = credit.getStartDate();
+ this.reason = null;
+ }
+
+ public BigDecimal getCreditAmount() {
+ return creditAmount;
+ }
+
+ public UUID getInvoiceId() {
+ return invoiceId;
+ }
+
+ public String getInvoiceNumber() {
+ return invoiceNumber;
+ }
+
+ public DateTime getRequestedDate() {
+ return requestedDate;
+ }
+
+ public DateTime getEffectiveDate() {
+ return effectiveDate;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargeBackResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargeBackResource.java
index 7090040..cfb8305 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargeBackResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargeBackResource.java
@@ -121,6 +121,7 @@ public class ChargebackResource implements JaxrsResource {
}
@POST
+ @Path("/chargebacks")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Response createChargeback(final ChargebackJson json,
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
index 076dbff..79e4e7e 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
@@ -16,6 +16,121 @@
package com.ning.billing.jaxrs.resources;
-public class CreditResource {
+import com.google.inject.Singleton;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.invoice.api.InvoiceApiException;
+import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.invoice.api.InvoiceUserApi;
+import com.ning.billing.jaxrs.json.CreditJson;
+import com.ning.billing.jaxrs.util.Context;
+import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+import java.util.UUID;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+@Singleton
+@Path(JaxrsResource.PREFIX)
+public class CreditResource implements JaxrsResource {
+ private static final Logger log = LoggerFactory.getLogger(CreditResource.class);
+
+ private final JaxrsUriBuilder uriBuilder;
+ private final InvoiceUserApi invoiceUserApi;
+ private final AccountUserApi accountUserApi;
+ private final Context context;
+
+ public CreditResource(JaxrsUriBuilder uriBuilder, InvoiceUserApi invoiceUserApi, AccountUserApi accountUserApi, Context context) {
+ this.uriBuilder = uriBuilder;
+ this.invoiceUserApi = invoiceUserApi;
+ this.accountUserApi = accountUserApi;
+ this.context = context;
+ }
+
+ @GET
+ @Path("/credits/{creditId:" + UUID_PATTERN + "}")
+ @Produces(APPLICATION_JSON)
+ public Response getCredit(@PathParam("creditId") String creditId) {
+ try {
+ InvoiceItem credit = invoiceUserApi.getCreditById(UUID.fromString(creditId));
+ CreditJson creditJson = new CreditJson(credit);
+
+ return Response.status(Response.Status.OK).entity(creditJson).build();
+ } catch (InvoiceApiException e) {
+ final String error = String.format("Failed to locate credit for id %s", creditId);
+ log.info(error, e);
+ return Response.status(Response.Status.NO_CONTENT).build();
+ }
+ }
+
+ @POST
+ @Path("/accounts/{accountId:" + UUID_PATTERN + "}/credits")
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ public Response createChargeback(final CreditJson json,
+ @PathParam("accountId") final String accountId,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
+ try {
+ Account account = accountUserApi.getAccountById(UUID.fromString(accountId));
+
+ InvoiceItem credit = invoiceUserApi.insertCredit(account.getId(), json.getCreditAmount(), json.getEffectiveDate(),
+ account.getCurrency(), context.createContext(createdBy, reason, comment));
+
+ return uriBuilder.buildResponse(ChargebackResource.class, "getCredit", credit.getId());
+ } catch (InvoiceApiException e) {
+ final String error = String.format("Failed to create credit %s", json);
+ log.info(error, e);
+ return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
+ } catch (AccountApiException e) {
+ final String error = String.format("Failed to create credit %s", json);
+ log.info(error, e);
+ return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
+ }
+ }
+
}
+
+
+
+//POST /1.0/accounts/<account_id>/credits Creates a credit for that account 201 (CREATED), 400 (BAD_REQUEST), 404 (NOT_FOUND)
+//Semantics:
+//
+//All operations are synchronous
+//JSON Credit GET:
+// {
+// "accountId" : "theAccountId",
+// "credits" : [{
+// "requestedDate" : "2012-05-12T15:34:22.000Z",
+// "effectiveDate" : "2012-05-12T15:34:22.000Z",
+// "creditAmount" : 54.32,
+// "invoiceId" : "theInvoiceId",
+// "invoiceNumber" : "TheInvoiceNumber",
+// "reason" : "whatever"
+// }]
+// }
+//
+//JSON Credit POST:
+// {
+// "creditAmount" : 54.32,
+// "reason" : "whatever",
+// "requestedDate" : "2012-05-12T15:34:22.000Z",
+// "invoiceId" : "theInvoiceId",
+// "invoiceNumber" : "TheInvoiceNumber"
+// }
\ No newline at end of file
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
index da8318f..6248357 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
@@ -23,8 +23,6 @@ import java.util.List;
import javax.ws.rs.core.Response.Status;
import com.ning.billing.jaxrs.resources.JaxrsResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.testng.annotations.Test;
import com.fasterxml.jackson.core.type.TypeReference;
@@ -32,13 +30,10 @@ import com.ning.billing.jaxrs.json.TagDefinitionJson;
import com.ning.http.client.Response;
public class TestTag extends TestJaxrsBase {
-
- private static final Logger log = LoggerFactory.getLogger(TestTag.class);
-
@Test(groups="slow", enabled=true)
public void testTagDefinitionOk() throws Exception {
- TagDefinitionJson input = new TagDefinitionJson("blue", "realxing color");
+ TagDefinitionJson input = new TagDefinitionJson("blue", "relaxing color");
String baseJson = mapper.writeValueAsString(input);
Response response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
@@ -66,7 +61,7 @@ public class TestTag extends TestJaxrsBase {
List<TagDefinitionJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
int sizeSystemTag = (objFromJson == null || objFromJson.size() == 0) ? 0 : objFromJson.size();
- TagDefinitionJson input = new TagDefinitionJson("blue", "realxing color");
+ TagDefinitionJson input = new TagDefinitionJson("blue", "relaxing color");
baseJson = mapper.writeValueAsString(input);
response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
@@ -81,7 +76,7 @@ public class TestTag extends TestJaxrsBase {
response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
- input = new TagDefinitionJson("green", "super realxing color");
+ input = new TagDefinitionJson("green", "super relaxing color");
baseJson = mapper.writeValueAsString(input);
response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());