I am fairly new to CRM Web API and coding in general but I did want to try my hand at this regardless.
I was trying to implement a custom "convert Contract to Invoice" functionality by first creating an Invoice with the data from a contract and secondly create an InvoiceDetail from ContractDetail/lines, which kind of works via httprequests, though very quickly I have noticed that requesting and posting data in such a way is very limited. I've read that its possible to work with more data by utilizing batches, however I am not really sure how to convert my code to batch appropriately.
I'd really appreciate any kind of help in that regard!
function retrieveProducts(data, newInvoiceID) {
var data = data;
var ID = newInvoiceID;
for (var i = 0; i < data.length; i++) {
var existingProduct = data[i];
var lineitem = {};
lineitem["productid@odata.bind"] = "/products(" + existingProduct._productid_value + ")";
lineitem["uomid@odata.bind"] = "/uoms(" + existingProduct._uomid_value + ")";
lineitem["new_contractactiveon"] = existingProduct.activeon;
lineitem["new_contractexpireson"] = existingProduct.expireson;
lineitem.quantity = existingProduct.initialquantity;
lineitem["invoiceid@odata.bind"] = "/invoices("+ ID +")";
createRecords(lineitem);
}
}
function createRecords(data) {
var req = new XMLHttpRequest();
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/invoicedetails", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 204) {
var uri = this.getResponseHeader("OData-EntityId");
var regExp = /\(([^)]+)\)/;
var matches = regExp.exec(uri);
var newEntityId = matches[1];
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(data));
}
EDIT: Here the full code
function start() {
var ID = parent.Xrm.Page.data.entity.getId().substring(1, 37);
var fetchxml = `
<fetch distinct="false" mapping="logical" output-format="xml-platform" version="1.0">
<entity name="contractdetail">
<attribute name="title"/>
<attribute name="productid"/>
<attribute name="allotmentsremaining"/>
<attribute name="contractdetailid"/>
<attribute name="net"/>
<attribute name="activeon"/>
<attribute name="serviceaddress"/>
<attribute name="initialquantity"/>
<attribute name="customerid"/>
<attribute name="expireson"/>
<attribute name="uomid"/>
<attribute name="new_ortfirma"/>
<order descending="false" attribute="title"/>
<link-entity name="contract" alias="ab" to="contractid" from="contractid">
<filter type="and">
<condition attribute="contractid" value="{` + ID + `}" uitype="contract" operator="eq"/>
</filter>
</link-entity>
</entity>
</fetch>`;
var encodedFetchXML = encodeURIComponent(fetchxml);
var queryPath = "/api/data/v8.2/contractdetails?fetchXml=" + encodedFetchXML;
var requestPath = parent.Xrm.Page.context.getClientUrl() + queryPath;
var req = new XMLHttpRequest();
req.open("GET", requestPath, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function ()
{
if (this.readyState === 4)
{
this.onreadystatechange = null;
if (this.status === 200)
{
var returned = JSON.parse(this.responseText);
var results = returned.value;
getContractInfo(results);
} else
{
alert(this.statusText);
}
}
};
req.send();
window.alert("Invoice created.");
setStatus(ID);
}
function retrieveProducts(data, newInvoiceID) {
var data = data;
var ID = newInvoiceID;
for (var i = 0; i < data.length; i++) {
var existingProduct = data[i];
var lineitem = {};
lineitem["productid@odata.bind"] = "/products(" + existingProduct._productid_value + ")";
lineitem["uomid@odata.bind"] = "/uoms(" + existingProduct._uomid_value + ")";
lineitem["new_contractactiveon"] = existingProduct.activeon;
lineitem["new_contractexpireson"] = existingProduct.expireson;
lineitem["new_ortfirma@odata.bind"] = "/accounts(" + existingProduct._new_ortfirma_value + ")";
lineitem.quantity = existingProduct.initialquantity;
lineitem["invoiceid@odata.bind"] = "/invoices("+ ID +")";
createRecords(lineitem);
}
}
function setStatus(ID) {
var entity = {};
entity.statecode = 1;
entity.statuscode = 2;
var req = new XMLHttpRequest();
req.open("PATCH", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/contracts(ED9C4959-A951-EB11-BC99-00155DB20709)", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 204) {
//Success - No Return Data - Do Something
} else {
parent.Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(entity));
}
function createRecords(data) {
var req = new XMLHttpRequest();
req.open("POST", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/invoicedetails", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 204) {
var uri = this.getResponseHeader("OData-EntityId");
var regExp = /\(([^)]+)\)/;
var matches = regExp.exec(uri);
var newEntityId = matches[1];
} else {
parent.Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(data));
}
//info from contact that is going to be used in the invoice
function getContractInfo(data) {
var ID = parent.Xrm.Page.data.entity.getId().substring(1, 37);
var req = new XMLHttpRequest();
req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/contracts(" + ID + ")?$select=activeon,_customerid_value,expireson,_serviceaddress_value,title&$expand=contract_line_items($select=activeon,expireson,initialquantity,price,title)", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var result = JSON.parse(this.response);
var activeon = result["activeon"];
var _customerid_value = result["_customerid_value"];
var expireson = result["expireson"];
var title = result["title"];
createInvoice(_customerid_value, title, data, activeon, expireson);
} else {
parent.Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send();
}
//create the invoice
function createInvoice(customer, title, data, activeon, expireson) {
var entity = {};
entity["customerid_account@odata.bind"] = "/accounts(" + customer + ")";
entity["pricelevelid@odata.bind"] = "/pricelevels(be2084c3-1e50-eb11-bc99-00155db20709)";
entity.name = title;
entity["transactioncurrencyid@odata.bind"] = "/transactioncurrencies(59f3fa86-385a-ea11-bc6a-00155db20709)";
entity.new_contractactiveon = activeon;
entity.new_contractexpireson = expireson;
var req = new XMLHttpRequest();
req.open("POST", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/invoices", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 204) {
var uri = this.getResponseHeader("OData-EntityId");
var regExp = /\(([^)]+)\)/;
var matches = regExp.exec(uri);
var newEntityId = matches[1];
var ID = this.getResponseHeader("OData-EntityId").substring(67,103);
retrieveProducts(data, ID);
} else {
parent.Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(entity));
}