From the Zuora user interface I can preview a subscription using a convenient "Preview" button. I'd like to perform the same action using the Zuora SOAP API so that I can preview what the upcoming invoices and write some tests.
So far, my theory is to create an empty Amendment with PreviewOptions.enablePreviewMode=true to get the results of the previewed invoice.
Relevant SOAP docs:
This has partially worked, but it has returned one InvoiceData object, but two would be expected.
public List<InvoiceData> getInvoicePreview(String subscriptionId){
ID id = new ID();
id.setID(subscriptionId);
PreviewOptions previewOptions = new PreviewOptions();
previewOptions.setEnablePreviewMode(true);
previewOptions.setPreviewThroughTermEnd(true);
Calendar forever = new DateTime().plusDays(1000).toCalendar(Locale.getDefault());
// A null amendment
Amendment amendment = new Amendment();
amendment.setName("Draft amendment for preview");
amendment.setStatus("Draft");
amendment.setContractEffectiveDate(forever);
amendment.setSubscriptionId(id);
amendment.setType("TermsAndConditions");
AmendOptions amendOptions = new AmendOptions();
AmendRequest amendRequest = new AmendRequest();
amendRequest.setAmendments(new Amendment[]{amendment});
amendRequest.setAmendOptions(amendOptions);
amendRequest.setPreviewOptions(previewOptions);
Amend amend = new Amend();
amend.setRequests(new AmendRequest[]{amendRequest});
AmendResponse amendResults;
try {
ZuoraCredentials creds = credentialProvider.get();
ZuoraServiceStub stub = new ZuoraServiceStub(creds.zuoraApiEndpoint);
Login login = new Login();
login.setUsername(creds.zuoraApiUser);
login.setPassword(creds.zuoraApiPassword);
LoginResponse loginResponse = stub.login(login);
String session = loginResponse.getResult().getSession();
SessionHeader sessionHeader = new SessionHeader();
sessionHeader.setSession(session);
amendResults = stub.amend(amend, sessionHeader);
} catch (RemoteException e) {
throw new RuntimeException("Error executing Zuora API.", e);
} catch (UnexpectedErrorFault e) {
throw new RuntimeException("Error executing Zuora API.", e);
} catch (LoginFault e) {
throw new RuntimeException("Error executing Zuora API.", e);
}
AmendResult[] amendResult = amendResults.getResults();
printOut(amendResult);
return new ArrayList<InvoiceData>(Arrays.asList(amendResult[0].getInvoiceDatas()));
}
Here's what the data looks like from the Zuora UI

I have been trying to achieve something similar myself for a
subscribe()call and ended up raising a ticket with Zuora. They said that it was not supported but you could achieve the same thing by aggregating theInvoiceItemrecords.What I have done is manually group them together based on the start of the service period (
ServiceStartDate) and sum the totals (e.g.ChargeAmount,TaxAmount). It appears to work out correctly and you can get the total due at the start of each period.I suspect this will work for amendments in the same way because an
InvoiceDatarecord is returned in the same was as forsubscribe().Update
EVERGREENif needed when previewing (even if the subscription is to beTERMEDwhen created).