More fieldGroups in the same edit view

Hello there,

I have 3 entities: Transaction, Invoice and PurchaseOrder.
I need to have all three in the same (transaction-edit.xml) view. After I generated transaction-edit.xml view I added two new fieldGroups and two new datasources (for Invoice and PurchaseOrder).
Unfortunately for invoice and PurchaseOrder fields I connot insert (save) data. Why?
see below screens:
image
image
image

Have you created a relationship between the 3 entities?

It’s mandatory?
I tried to create an ONE-TO-ONE relationship (but still not works). Maybe you can give me more details pls.
Another question: it’s ok to create datasource for (invoice and order) or needs collectionDatasource?

Hi,
It’s OK to have single-value datasources for invoice and order, but how do you suppose to load them (by what criteria)? Or do you want to always create and save new instances?

1 Like

HI Konstantin,
Thank you for your answer.
Basically for each transaction I have only one Invoice and only one order so I need to insert their attributes just once.
Invoice and order are some kind of attributes of transaction but are separate Entities.
The solution that I found is to declare them One to Many Composition from transaction but the problem is that now is possible to insert more that one registration. Is it possible somehow to limit number of registration to one?
See below:
image

You should use one-to-one association in this case, but it will require some manual work on the screen - not everything can be generated automatically.

First, add associations to your Transaction entity:

@Table(name = "SAMPLE_TRANSACTION")
@Entity(name = "sample$Transaction")
public class Transaction extends StandardEntity {
// ...
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "INVOICE_ID")
    protected Invoice invoice;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ORDER_ID")
    protected Order order;

Then create a view that includes these references:

<views xmlns="http://schemas.haulmont.com/cuba/view.xsd">
    <view class="com.company.sample.entity.Transaction"
          extends="_local"
          name="transaction-edit">
        <property name="invoice"
                  view="_local"/>
        <property name="order"
                  view="_local"/>
    </view>
</views>

In the transaction edit screen, create nested datasources and attach field groups to them:

<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://editorCaption"
        class="com.company.sample.web.transaction.TransactionEdit"
        datasource="transactionDs"
        focusComponent="fieldGroup"
        messagesPack="com.company.sample.web.transaction">
    <dsContext>
        <datasource id="transactionDs"
                    class="com.company.sample.entity.Transaction"
                    view="transaction-edit">
            <datasource id="invoiceDs"
                        property="invoice"/>
            <datasource id="orderDs"
                        property="order"/>
        </datasource>
    </dsContext>
    <dialogMode height="600"
                width="800"/>
    <layout spacing="true">
        <fieldGroup id="fieldGroup"
                    caption="Transaction"
                    datasource="transactionDs">
            <column width="250px">
                <field property="name"/>
            </column>
        </fieldGroup>
        <fieldGroup caption="Invoice"
                    datasource="invoiceDs">
            <column width="250px">
                <field property="name"/>
            </column>
        </fieldGroup>
        <fieldGroup caption="Order"
                    datasource="orderDs">
            <column width="250px">
                <field property="name"/>
            </column>
        </fieldGroup>
        <frame id="windowActions"
               height="100%"
               screen="editWindowActions"/>
    </layout>
</window>

In the edit screen controller, initialize references when creating new Transaction:

public class TransactionEdit extends AbstractEditor<Transaction> {

    @Inject
    private Metadata metadata;

    @Override
    protected void initNewItem(Transaction item) {
        item.setInvoice(metadata.create(Invoice.class));
        item.setOrder(metadata.create(Order.class));
    }
}

That’s it. See the sample project attached.
sample.zip (82.1 KB)

Hello Konstantin,

I really appreciate your support. You are very professional.
So the clue was to initialize references. But how could I have realized this? Maybe you can indicate me some (literature/tutorials). :slight_smile:

However, meantime, I found a new solution: I keep it the COMPOSITION nested classes and add the following code in order to have only one (invoice) record:

public class TransactionEdit extends AbstractEditor<Transaction> {


    @Named("invoiceTable.create")
    private CreateAction invoiceTableCreate;

    private boolean hasNoInvoice()
    {
        return getItem() == null || getItem().getInvoice() == null || getItem().getInvoice().size() == 0;
    }

    @Override
    public void init(Map<String, Object> params) {

        boolean ok = hasNoInvoice();
        invoiceTableCreate.setVisible( ok );


        invoiceTableCreate.setBeforeActionPerformedHandler(() -> {
            boolean ok1 = hasNoInvoice();
            invoiceTableCreate.setVisible( ok1 );
            return ok1;


        });
        //    super.init(params);


    }


}

Another short question please.
ONE-TO-ONE associations generates a PickerField and ONE TO MANY will create a table. Why this approach?
Another question is why / when should we create inverse attribute? I saw that (for ONE-TO-ONE at least) it works with (or without) create it.

(No appropriate inverse attribute found. Would you like to create one?)

To-one is an association with one reference and to-many is a collection of references. Hence the difference in generated screens.

Always for one-to-many collections. This type of association is maintained by the back-reference to the master object. For example, to have an Order - OrderLines relationship, the OrderLine entity must have a ORDER_ID column in the database to hold the Order’s ID.

1 Like