Grand child details setup

18 views
Skip to first unread message

Juan Jose Pablos

unread,
Jun 18, 2026, 12:27:12 PM (5 days ago) Jun 18
to Jam.py Users Mailing List
Hi,

I am creating an app using jampy to control our purchases. I would like
to control what stuff gets in the warehouse.

Because the purchase is based on weight, I need to control each purchase
line, combining both the item and the packaging (boxes, wooden pallets)

The packaging bit is used to subtract weight and to control how many of
those I have to return to the supplier.

So I have set up a main invoice form with  *invoice_items* as "jampy
Details". That bit works fine.

Then I create a *packaging_items* as child of the *invoice_items*
because each item could have packaging, and I need to do some
calculations for the weigh independent for each line.

So i am guessing that this is a Parent -> Child -> Grandchild setup.

I can see:

invoice -> invoice_items

invoice_items  -> packaging_items

But I am unable to see:

invoice -> invoice_items  -> packaging_items

I saw a relative question here:

https://www.reddit.com/r/Jampy/comments/zxatdy/view_form_with_detail_view_forms/

Can anyone tell me where I can find more information to trouble shoot
this issue?


Thank you!


Danijel Kaurin

unread,
Jun 18, 2026, 4:44:37 PM (5 days ago) Jun 18
to Juan Jose Pablos, Jam.py Users Mailing List
Hi Juan.

You can easily implement that with Jam.py:

Screenshot 2026-06-18 223631.png

Firstly, you need to add a custom view-form template for your invoice (templates.html). Something like this:

<div class="invoices-view">
    <div class="form-header">
        <div class="mx-auto">
            <div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
                <div class="btn-group me-2" role="group" aria-label="First group">
                    <button id="new-btn" class="btn btn-light" type="button">
                        <i class="bi-plus-square"></i>&nbsp; New
                    </button>
                    <button id="edit-btn" class="btn btn-light" type="button">
                        <i class="bi-pencil-square"></i>&nbsp; Edit
                    </button>
                    <div id="report-btn" class="btn-group dropdown">
                        <a class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" href="#">
                            <i class="bi bi-printer"></i> Reports
                            <span class="caret"></span>
                        </a>
                        <ul class="dropdown-menu bottom-up">
                        </ul>
                    </div>
                    <button id="delete-btn" class="btn btn-light" type="button">
                        <i class="bi-trash"></i>&nbsp; Delete
                    </button>
                </div>
            </div>
        </div>
    </div>
    <div class="card-body form-body">
        <div class="view-table"></div>
        <div class="row">
            <div class="col mt-6">
                <h5><span class="badge text-bg-info text-wrap">Invoice details</span></h5>
                <div class="first_table"></div>
            </div>
            <div class="col mt-6">
                <h5><span class="badge text-bg-info text-wrap">Product movement</span></h5>
                <div class="second_table"></div>
            </div>
        </div>
    </div>
</div>

...

Then, add this javascript code in the client module of the inovices item:

function on_view_form_created(item) {
    item.table_options.on_click = function() {
        let first_detail = task.invoice_items.copy();
            first_detail.set_where({invoice_id: item.id.value});
            first_detail.table_options.height = 300;
            first_detail.view_options.form_header = false;
            first_detail.view_options.form_border =  false;
            first_detail.table_options.fields = ['product_id', 'unit_price', 'quantity', 'discount', 'total_price'];
            first_detail.table_options.on_click = function() {
                setTimeout(() => {
                    let second_detail = task.stock_movements.copy();
                        second_detail.set_where({reference_invoice_id: item.id.value, product_id: first_detail.product_id.value});
                        second_detail.table_options.height = 300;
                        second_detail.view_options.form_header = false;
                        second_detail.view_options.form_border =  false;
                        second_detail.table_options.fields = ['product_id', 'movement_date', 'movement_type', 'warehouse_id', 'quantity'];                        //first_detail.table_options.on_click = function() {
                        second_detail.view(item.view_form.find('.second_table'));

                        second_detail.view_form.find('#new-btn, #edit-btn, #delete-btn').hide();
                }, 200);
            };

            first_detail.view(item.view_form.find('.first_table'));
            first_detail.view_form.find('#new-btn, #edit-btn, #delete-btn').hide();
    }
}

...

As you can see, you can even add more details if you want: catch the item data in the variable, create a view for that item and place it in the proper div class.

Regards

Danijel

--
You received this message because you are subscribed to the Google Groups "Jam.py Users Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jam-py+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/jam-py/91eb90de-92c0-4cef-a4a7-020c5624a96d%40gmail.com.

Dean D. Babic

unread,
Jun 18, 2026, 10:26:28 PM (5 days ago) Jun 18
to Jam.py Users Mailing List
To add on Dan reply, it also depends on how you implemented packaging_items.
When you say:

" Then I create a *packaging_items* as child of the *invoice_items*
because each item could have packaging, and I need to do some
calculations for the weigh independent for each line."

This does not really says how this two tables were linked. For example, it could be with a field Type Keys.
Which is this example from Django where I used Keys. Why? Because there was no direct Detail in Django application,
and introducing it would break Django app. But adding a Keys column does not.
 
https://billsofmaterials.pythonanywhere.com/
https://billsofmaterials.pythonanywhere.com/static/bom.html

carparts.pythonanywhere is lost I'm afraid. PA deleted it and I have no copy any more.
The export for this app is here, search for  billsofmaterials.

D.

Dean D. Babic

unread,
Jun 19, 2026, 1:35:44 AM (4 days ago) Jun 19
to Jam.py Users Mailing List
This:

" But I am unable to see:
invoice -> invoice_items  -> packaging_items"


Is purely because you did not add Details to Master.
No code needed if there is a LINK field in packaging_items.




Screenshot 2026-06-19 130441.png
Reply all
Reply to author
Forward
0 new messages