Hey guys!
I’m new to Cuba and i would like your help in a bottleneck i am facing.
I have two entities Invoice and InvoiceLineItems that have a composition relation.
On the Invoice screen, when the user selects the client for the invoice , the InvoiceLineItems will be created automatically, with default values, from the client’s subscribed services. Then the user will edit the InvoiceLineItems and add the actual values.
I successfully implemented the functionality of summing the total field of the InvoiceLineItems and adding it to the amount field of the Invoice before committing, only when the Invoice is saved first then the lineitems edited.
What i would like to achieve, is the ability to loop through invoiceLineItems before the invoice is saved. Because the user will create the invoice set the client which will generate the invoicelineitems and then edit each line to set the appropriate values and after that he save the invoice.
I understand that in a composition relation the child entity will be committed when the parent entity is committed which is why the list in the precommit() method is empty in my code below in the case where the user did not save first the invoice.
Is there a way to loop through the child entity list before they are being committed ?
Invoice edit screen Controller:
script
package com.company.ccpay.web.invoice;
import com.haulmont.bali.util.ParamsMap;
import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.core.global.DataManager;
import com.haulmont.cuba.core.global.LoadContext;
import com.haulmont.cuba.core.global.Metadata;
import com.haulmont.cuba.gui.components.AbstractEditor;
import com.haulmont.cuba.gui.components.actions.EditAction;
import com.haulmont.cuba.gui.data.CollectionDatasource;
import com.haulmont.cuba.gui.data.Datasource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import com.company.ccpay.entity.Invoice;
import com.company.ccpay.entity.SubscribedServices;
import com.company.ccpay.entity.InvoiceLineitems;
import com.company.ccpay.entity.Invoicestatus;
public class InvoiceEdit extends AbstractEditor<Invoice> {
@Named("invoicelineTable.edit")
private EditAction InvoiceLineEdit;
private DataManager dataManager = AppBeans.get(DataManager.class);
@Inject
private Datasource<Invoice> invoiceDs;
@Inject
private CollectionDatasource<InvoiceLineitems, Integer> invoicelineDs;
@Inject
private Metadata metadata;
@Override
protected void postInit() {
super.postInit();
Map<String, Object> params = ParamsMap.of("invoice", getItem());
InvoiceLineEdit.setWindowParams(params);
invoiceDs.addItemPropertyChangeListener(e -> {
Invoice curinvoice = (Invoice) e.getItem();
if (e.getProperty().equals("client")) {
LoadContext<SubscribedServices> loadContext = LoadContext.create(SubscribedServices.class)
.setQuery(LoadContext.createQuery("select i from ccpay$SubscribedServices i where i.client.id = :client")
.setParameter("client", curinvoice.getClient().getId()));
List<SubscribedServices> subservice = dataManager.loadList(loadContext);
for (SubscribedServices line : subservice) {
InvoiceLineitems invoiceline= metadata.create(InvoiceLineitems.class);
invoiceline.setInvoice(curinvoice);
invoiceline.setServiceName(line.getServiceName());
invoiceline.setQuantity(BigDecimal.ONE);
invoiceline.setUniteprice(BigDecimal.ONE);
invoiceline.setTotal(BigDecimal.ONE);
invoiceline.setDescription(line.getDescription());
invoicelineDs.addItem(invoiceline);
}
invoicelineDs.commit();
invoicelineDs.refresh();
}
});
Invoice inv = invoiceDs.getItem();
inv.setStatus(Invoicestatus.UnderProcess);
invoiceDs.setItem(inv);
}
}
InvoiceLinItems edit screen controller:
script
package com.company.ccpay.web.invoicelineitems;
import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.core.global.DataManager;
import com.haulmont.cuba.core.global.LoadContext;
import com.haulmont.cuba.gui.WindowParam;
import com.haulmont.cuba.gui.components.AbstractEditor;
import com.haulmont.cuba.gui.data.Datasource;
import java.math.BigDecimal;
import java.util.List;
import javax.inject.Inject;
import com.company.ccpay.entity.Invoice;
import com.company.ccpay.entity.InvoiceLineitems;
public class InvoiceLineitemsEdit extends AbstractEditor<InvoiceLineitems> {
@Inject
private Datasource<InvoiceLineitems> invoiceLineitemsDs;
private DataManager dataManager = AppBeans.get(DataManager.class);
@WindowParam(required = true)
private Invoice invoice;
@Override
protected boolean preCommit() {
InvoiceLineitems lineitem = getItem();
BigDecimal total = new BigDecimal(0);
LoadContext<InvoiceLineitems> loadContext = LoadContext.create(InvoiceLineitems.class)
.setQuery(LoadContext.createQuery("select i from ccpay$InvoiceLineitems i where i.invoice.id = :invoice")
.setParameter("invoice", lineitem.getInvoice().getId()));
List<InvoiceLineitems> lineservice = dataManager.loadList(loadContext);
if(lineservice != null)
{
for (InvoiceLineitems line : lineservice) {
total= total.add((BigDecimal)line.getTotal());
}
}
invoice.setAmount(total);
return true;
}
@Override
protected void postInit() {
super.postInit();
invoiceLineitemsDs.addItemPropertyChangeListener(e-> {
InvoiceLineitems curInvLine = (InvoiceLineitems) e.getItem();
if (e.getProperty().equals("quantity")) {
if (invoiceLineitemsDs.getItem().getUniteprice() !=null)
{
curInvLine.setTotal(curInvLine.getUniteprice().multiply(curInvLine.getQuantity()));
invoiceLineitemsDs.setItem(curInvLine);
}
} else if (e.getProperty().equals("uniteprice")){
if(invoiceLineitemsDs.getItem().getQuantity() !=null) {
curInvLine.setTotal(curInvLine.getUniteprice().multiply(curInvLine.getQuantity()));
invoiceLineitemsDs.setItem(curInvLine);
}
}
invoiceLineitemsDs.commit();
});
}
}
Thanks in Advance!