I am trying to add Service Contracts and the Contract Line Items from Order Products. Also I am adding Entitlements and Referencing Proforma Invoices at same time. Following is my Code...
public class GenerateServiceContract {
@InvocableMethod
public static void fetchOrderItems(List<Id> orderId) {
List<Order> relatedOrder = [SELECT Id, AccountId, Account.Name, Opportunity__c, Order_Name__c, PriceBook2Id FROM Order WHERE Id = :orderId FOR UPDATE];
List<OrderItem> oproduct = [SELECT Id, PriceBookEntryId, Product2Id, Product_Name__c, Quantity, Contact_Name__c, UnitPrice, Department__c, Deposit_Amount__c FROM OrderItem WHERE OrderId = :orderId ORDER BY UnitPrice DESC];
Set<String> itemDepartment = new Set<String>();
Map<String, Id> contractIds = new Map<String, Id>();
Id singleContractId;
Integer indexOf = 1;
for (OrderItem oitem: oproduct) {
if (oitem.Deposit_Amount__c != 0) {
addContractLineItems(singleContractId, relatedOrder[0].AccountId, oitem.Id);
updateProformaInvoices(singleContractId, contractIds.get(oitem.Department__c), oitem.Id);
}
if (itemDepartment.contains(oitem.Department__c) && oitem.Deposit_Amount__c == 0) {
addContractLineItems(contractIds.get(oitem.Department__c), relatedOrder[0].AccountId, oitem.Id);
updateProformaInvoices(relatedOrder[0].Id, contractIds.get(oitem.Department__c), oitem.Id);
} else {
if (oitem.Deposit_Amount__c == 0) {
ServiceContract scontract = new ServiceContract(
OpportunityId__c = relatedOrder[0].Opportunity__c,
Name = oitem.Product_Name__c +' - '+ relatedOrder[0].Account.Name,
AccountId = relatedOrder[0].AccountId,
PriceBook2Id = relatedOrder[0].PriceBook2Id
);
insert scontract;
itemDepartment.add(oitem.Department__c);
contractIds.put(oitem.Department__c, scontract.id);
addContractLineItems(scontract.id, scontract.AccountId, oitem.Id);
updateProformaInvoices(relatedOrder[0].Id, scontract.id, oitem.Id);
if (indexOf == 1) {
singleContractId = scontract.id;
}
}
}
indexOf++;
}
}
public static void addContractLineItems(Id contractId, Id accountId, Id orderItemId) {
List<OrderItem> oproduct = [SELECT Id, PriceBookEntryId, Product2Id, Quantity, Contact_Name__c, UnitPrice, Deposit_Amount__c, Department__c FROM OrderItem WHERE Id = :orderItemId LIMIT 1];
ContractLineItem citems = new ContractLineItem(
ServiceContractId = contractId,
PriceBookEntryId = oproduct[0].PriceBookEntryId,
Quantity = oproduct[0].Quantity,
UnitPrice = oproduct[0].UnitPrice,
Deposit_Amount__c = oproduct[0].Deposit_Amount__c
);
try {
insert citems;
addEntitlements(contractId, accountId, citems.Id);
} catch (Exception e) {}
}
public static void addEntitlements(Id serviceContractId, Id accountId, Id contractItemId) {
List<ContractLineItem> cproducts = [SELECT Id FROM ContractLineItem WHERE ServiceContractId = :serviceContractId AND Id = :contractItemId];
Entitlement entitlement = new Entitlement(
AccountId = accountId,
ServiceContractId = serviceContractId,
ContractLineItemId = contractItemId,
Name = 'Need to visit the Client'
);
try {
insert entitlement;
} catch (Exception e) {}
}
public static void updateProformaInvoices(Id orderId, Id serviceContractId, Id orderItemId) {
List<Proforma_Invoice__c> pinvoice = [SELECT Id, Service_Contract__c FROM Proforma_Invoice__c WHERE Order__c = :orderId AND Order_Product__c = :orderItemId];
Proforma_Invoice__c[] recordsToUpdate = new Proforma_Invoice__c[0];
for (Proforma_Invoice__c pinv: pinvoice) {
recordsToUpdate.add(new Proforma_Invoice__c(
Id = pinv.Id,
Service_Contract__c = serviceContractId
));
}
update recordsToUpdate;
}
}
Before this code was working fine and even now on production it is working fine, but in Sandbox now it is giving this error "Insert failed first error: UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record or 1 records: 01s4J000002l5eqQAA: []".
The error it shows on line where Service Contract is adding "insert scontract".
Can anyone please help me with this issue as I tried the solutions online but no luck.