77
88import jakarta .persistence .EntityManager ;
99import jakarta .persistence .EntityManagerFactory ;
10+ import jakarta .persistence .Tuple ;
11+ import jakarta .persistence .criteria .CriteriaBuilder ;
12+ import jakarta .persistence .criteria .Predicate ;
13+ import jakarta .persistence .criteria .Root ;
1014import jakarta .servlet .http .HttpServletRequest ;
15+ import lombok .RequiredArgsConstructor ;
1116import me .agno .demo .model .Order ;
17+ import me .agno .demo .model .OrderDetail ;
18+ import me .agno .demo .repositories .CustomerRepository ;
19+ import me .agno .demo .repositories .EmployeeRepository ;
20+ import me .agno .demo .repositories .ProductRepository ;
21+ import me .agno .demo .repositories .ShipperRepository ;
1222import me .agno .gridcore .IGridColumnCollection ;
23+ import me .agno .gridcore .SelectItem ;
1324import me .agno .gridcore .server .GridServer ;
1425import me .agno .gridcore .server .IGridServer ;
1526import me .agno .gridcore .utils .ItemsDTO ;
27+ import org .hibernate .query .criteria .HibernateCriteriaBuilder ;
28+ import org .hibernate .query .sqm .tree .SqmCopyContext ;
29+ import org .hibernate .query .sqm .tree .select .SqmSelectStatement ;
30+ import org .hibernate .query .sqm .tree .select .SqmSubQuery ;
1631import org .springframework .beans .factory .annotation .Autowired ;
1732import org .springframework .http .MediaType ;
1833import org .springframework .http .ResponseEntity ;
1934import org .springframework .web .bind .annotation .GetMapping ;
2035import org .springframework .web .bind .annotation .RequestMapping ;
36+ import org .springframework .web .bind .annotation .RequestParam ;
2137import org .springframework .web .bind .annotation .RestController ;
2238
2339@ RestController
40+ @ RequiredArgsConstructor
2441@ RequestMapping (value = {"/api/sampledata" , "/api/SampleData" })
2542public class SampleDataController {
2643
44+ private final CustomerRepository customerRepository ;
45+ private final EmployeeRepository employeeRepository ;
46+ private final ProductRepository productRepository ;
47+ private final ShipperRepository shipperRepository ;
48+
2749 @ Autowired
2850 EntityManagerFactory entityManagerFactory ;
2951
@@ -32,9 +54,8 @@ public ResponseEntity<ItemsDTO<Order>> getOrdersGrid(HttpServletRequest request)
3254
3355 EntityManager em = entityManagerFactory .createEntityManager ();
3456
35- Consumer <IGridColumnCollection <Order >> columns = c ->
36- {
37- c .add ("orderID" ,Integer .class );
57+ Consumer <IGridColumnCollection <Order >> columns = c -> {
58+ c .add ("orderID" , Integer .class );
3859 c .add ("orderDate" , Instant .class , "orderCustomDate" );
3960 c .add ("customer.companyName" , String .class );
4061 c .add ("customer.contactName" , String .class );
@@ -43,8 +64,7 @@ public ResponseEntity<ItemsDTO<Order>> getOrdersGrid(HttpServletRequest request)
4364 c .add ("customer.isVip" ,Boolean .class );
4465 };
4566
46- IGridServer <Order > server = new GridServer <Order >(em , Order .class , null , null ,
47- request .getParameterMap (), columns )
67+ IGridServer <Order > server = new GridServer <Order >(em , Order .class , request .getParameterMap (), columns )
4868 .withPaging (10 )
4969 .sortable ()
5070 .filterable ();
@@ -58,8 +78,7 @@ public ResponseEntity<ItemsDTO<Order>> getOrdersGridordersAutoGenerateColumns(Ht
5878
5979 EntityManager em = entityManagerFactory .createEntityManager ();
6080
61- IGridServer <Order > server = new GridServer <Order >(em , Order .class , null , null ,
62- request .getParameterMap (), null )
81+ IGridServer <Order > server = new GridServer <Order >(em , Order .class , request .getParameterMap (), null )
6382 .autoGenerateColumns ()
6483 .sortable ()
6584 .filterable ();
@@ -73,9 +92,8 @@ public ResponseEntity<ItemsDTO<Order>> getOrdersGridWithTotals(HttpServletReques
7392
7493 EntityManager em = entityManagerFactory .createEntityManager ();
7594
76- Consumer <IGridColumnCollection <Order >> columns = c ->
77- {
78- c .add ("orderID" ,Integer .class ).sum (true );
95+ Consumer <IGridColumnCollection <Order >> columns = c -> {
96+ c .add ("orderID" , Integer .class ).sum (true );
7997 c .add ("orderDate" , Instant .class , "orderCustomDate" ).max (true ).min (true );
8098 c .add ("customer.companyName" , String .class ).max (true ).min (true );
8199 c .add ("customer.contactName" , String .class ).max (true ).min (true );
@@ -94,13 +112,248 @@ public ResponseEntity<ItemsDTO<Order>> getOrdersGridWithTotals(HttpServletReques
94112 c .add ("customer.isVip" ,Boolean .class );
95113 };
96114
97- IGridServer <Order > server = new GridServer <Order >(em , Order .class , null , null ,
98- request .getParameterMap (), columns )
115+ IGridServer <Order > server = new GridServer <Order >(em , Order .class , request .getParameterMap (), columns )
116+ .withPaging (10 )
117+ .sortable ()
118+ .filterable ();
119+
120+ var items = server .getItemsToDisplay ();
121+ return ResponseEntity .ok (items );
122+ }
123+
124+ @ GetMapping (value = {"getordersgridsearchable" , "GetOrdersGridSearchable" }, produces = MediaType .APPLICATION_JSON_VALUE )
125+ public ResponseEntity <ItemsDTO <Order >> getOrdersGridSearchable (HttpServletRequest request ) {
126+
127+ EntityManager em = entityManagerFactory .createEntityManager ();
128+
129+ Consumer <IGridColumnCollection <Order >> columns = c -> {
130+ c .add ("orderID" , Integer .class );
131+ c .add ("orderDate" , Instant .class , "orderCustomDate" );
132+ c .add ("customer.companyName" , String .class );
133+ c .add ("customer.contactName" , String .class );
134+ c .add ("customer.country" , String .class , true );
135+ c .add ("freight" , BigDecimal .class );
136+ c .add ("customer.isVip" ,Boolean .class );
137+ };
138+
139+ IGridServer <Order > server = new GridServer <Order >(em , Order .class , request .getParameterMap (), columns )
140+ .withPaging (10 )
141+ .sortable ()
142+ .filterable ()
143+ .searchable (true , false , false );
144+
145+ var items = server .getItemsToDisplay ();
146+ return ResponseEntity .ok (items );
147+ }
148+
149+ @ GetMapping (value = {"getordersgridEextsorting" , "GetOrdersGridExtSorting" }, produces = MediaType .APPLICATION_JSON_VALUE )
150+
151+ public ResponseEntity <ItemsDTO <Order >> getOrdersGridExtSorting (HttpServletRequest request ) {
152+
153+ EntityManager em = entityManagerFactory .createEntityManager ();
154+
155+ Consumer <IGridColumnCollection <Order >> columns = c -> {
156+ c .add ("orderID" , Integer .class );
157+ c .add ("orderDate" , Instant .class , "orderCustomDate" );
158+ c .add ("customer.companyName" , String .class )
159+ .thenSortBy ("shipVia" ).thenSortByDescending ("freight" );
160+ c .add ("customer.contactName" , String .class );
161+ c .add ("shipVia" , String .class );
162+ c .add ("freight" , BigDecimal .class );
163+ c .add ("customer.isVip" ,Boolean .class );
164+ };
165+
166+ IGridServer <Order > server = new GridServer <Order >(em , Order .class , request .getParameterMap (), columns )
99167 .withPaging (10 )
100168 .sortable ()
101169 .filterable ();
102170
103171 var items = server .getItemsToDisplay ();
104172 return ResponseEntity .ok (items );
105173 }
174+
175+ @ GetMapping (value = {"getordersgridgroupable" , "GetOrdersGridGroupable" }, produces = MediaType .APPLICATION_JSON_VALUE )
176+
177+ public ResponseEntity <ItemsDTO <Order >> getOrdersGridGroupable (HttpServletRequest request ) {
178+
179+ EntityManager em = entityManagerFactory .createEntityManager ();
180+
181+ Consumer <IGridColumnCollection <Order >> columns = c -> {
182+ c .add ("orderID" , Integer .class );
183+ c .add ("orderDate" , Instant .class , "orderCustomDate" );
184+ c .add ("customer.companyName" , String .class )
185+ .thenSortBy ("shipVia" ).thenSortByDescending ("freight" );
186+ c .add ("customer.contactName" , String .class );
187+ c .add ("shipVia" , String .class );
188+ c .add ("freight" , BigDecimal .class );
189+ c .add ("customer.isVip" ,Boolean .class );
190+ };
191+
192+ IGridServer <Order > server = new GridServer <Order >(em , Order .class , request .getParameterMap (), columns )
193+ .withPaging (10 )
194+ .sortable ()
195+ .filterable ();
196+
197+ var items = server .getItemsToDisplay ();
198+ return ResponseEntity .ok (items );
199+ }
200+
201+ @ GetMapping (value = {"ordercolumnslistfilter" , "OrderColumnsListFilter" }, produces = MediaType .APPLICATION_JSON_VALUE )
202+ public ResponseEntity <ItemsDTO <Order >> orderColumnsListFilter (HttpServletRequest request ) {
203+
204+ EntityManager em = entityManagerFactory .createEntityManager ();
205+
206+ Consumer <IGridColumnCollection <Order >> columns = c -> {
207+ c .add ("orderID" , Integer .class );
208+ c .add ("orderDate" , Instant .class , "orderCustomDate" );
209+ c .add ("customer.companyName" , String .class );
210+ c .add ("customer.contactName" , String .class );
211+ c .add ("customer.country" , String .class , true );
212+ c .add ("shipVia" , String .class );
213+ c .add ("freight" , BigDecimal .class );
214+ c .add ("customer.isVip" ,Boolean .class );
215+ };
216+
217+ IGridServer <Order > server = new GridServer <Order >(em , Order .class , request .getParameterMap (), columns )
218+ .withPaging (10 )
219+ .sortable ()
220+ .filterable ();
221+
222+ var items = server .getItemsToDisplay ();
223+ return ResponseEntity .ok (items );
224+ }
225+
226+ @ GetMapping (value = {"getcustomersnames" , "GetCustomersNames" }, produces = MediaType .APPLICATION_JSON_VALUE )
227+ public ResponseEntity getCustomersNames (HttpServletRequest request ) {
228+
229+ EntityManager em = entityManagerFactory .createEntityManager ();
230+
231+ Consumer <IGridColumnCollection <Order >> columns = c -> {
232+ c .add ("orderID" , Integer .class );
233+ c .add ("orderDate" , Instant .class , "orderCustomDate" );
234+ c .add ("customer.companyName" , String .class );
235+ c .add ("customer.contactName" , String .class );
236+ c .add ("customer.country" , String .class , true );
237+ c .add ("freight" , BigDecimal .class );
238+ c .add ("customer.isVip" ,Boolean .class );
239+ };
240+
241+ // get all customer ids in the grid with the current filters
242+ var server = new GridServer <Order >(em , Order .class , request .getParameterMap (), columns );
243+
244+ // add new predicate to filter records with orderID null or empty
245+ CriteriaBuilder cb = server .getGrid ().getCriteriaBuilder ();
246+ Root <Order > root = server .getGrid ().getRoot ();
247+ Predicate predicate = cb .isNotNull (root .get ("orderID" ));
248+ predicate = cb .and (cb .equal (cb .trim (root .get ("orderID" )),"" ));
249+ server .setPredicate (predicate );
250+
251+ // get the full predicate (after pre-process)
252+ var grid = server .getGrid ();
253+ predicate = grid .getPredicate ();
254+
255+ // create a query spec to copy the predicate to a new query
256+ var gridQuery = (SqmSelectStatement ) grid .getCriteriaQuery ();
257+ var gridQuerySpec = gridQuery .getQuerySpec ();
258+ var gridSubQuerySpec = gridQuerySpec .copy (SqmCopyContext .simpleContext ());
259+
260+ // create a new query to get company names
261+ var newBuilder = (HibernateCriteriaBuilder ) grid .getCriteriaBuilder ();
262+ var columnNameQuery = newBuilder .createQuery (String .class );
263+
264+ // copy the former predicate using its spec to a subquery of the new query to get distinct company names
265+ var subQuery = (SqmSubQuery <Tuple >) columnNameQuery .subquery (Tuple .class );
266+ subQuery .setQueryPart (gridSubQuerySpec );
267+ Root <?> subQueryRoot = subQuery .getRootList ().get (0 );
268+ subQuery .multiselect (subQueryRoot .get ("customer.companyName" ).alias ("companyName" ))
269+ .distinct (true );
270+
271+ // configure the new query from the copied subquery
272+ columnNameQuery .from (subQuery );
273+ Root <?> columnNameRoot = columnNameQuery .getRootList ().get (0 );
274+ columnNameQuery .select (columnNameRoot .get ("companyName" ));
275+
276+ var customerNames = grid .getEntityManager ().createQuery (columnNameQuery ).getResultList ();
277+ return ResponseEntity .ok (customerNames );
278+ }
279+
280+ @ GetMapping (value = {"getallcustomers" , "GetAllCustomers" }, produces = MediaType .APPLICATION_JSON_VALUE )
281+ public ResponseEntity getAllCustomers () {
282+
283+ return ResponseEntity .ok (customerRepository .findAll ().stream ()
284+ .map (r -> new SelectItem (r .getCustomerID (), r .getCustomerID () + " - " + r .getCompanyName ()))
285+ .toList ());
286+ }
287+
288+ @ GetMapping (value = {"getallcustomers2" , "GetAllCustomers2" }, produces = MediaType .APPLICATION_JSON_VALUE )
289+ public ResponseEntity getAllCustomers2 () {
290+
291+ return ResponseEntity .ok (customerRepository .findAll ().stream ()
292+ .map (r -> new SelectItem (r .getCompanyName (), r .getCompanyName ()))
293+ .toList ());
294+ }
295+
296+ @ GetMapping (value = {"getallcontacts" , "GetAllContacts" }, produces = MediaType .APPLICATION_JSON_VALUE )
297+ public ResponseEntity getAllContacts () {
298+
299+ return ResponseEntity .ok (customerRepository .findAll ().stream ()
300+ .map (r -> new SelectItem (r .getContactName (), r .getContactName ()))
301+ .toList ());
302+ }
303+
304+ @ GetMapping (value = {"getallemployees" , "GetAllEmployees" }, produces = MediaType .APPLICATION_JSON_VALUE )
305+ public ResponseEntity getAllEmployees () {
306+
307+ return ResponseEntity .ok (employeeRepository .findAll ().stream ()
308+ .map (r -> new SelectItem (r .getEmployeeID ().toString (), r .getEmployeeID ().toString () + " - "
309+ + r .getFirstName () + " " + r .getLastName ()))
310+ .toList ());
311+ }
312+
313+ @ GetMapping (value = {"getallshippers" , "GetAllShippers" }, produces = MediaType .APPLICATION_JSON_VALUE )
314+ public ResponseEntity getAllShippers () {
315+
316+ return ResponseEntity .ok (shipperRepository .findAll ().stream ()
317+ .map (r -> new SelectItem (r .getShipperID ().toString (), r .getShipperID ().toString () + " - "
318+ + r .getCompanyName ()))
319+ .toList ());
320+ }
321+
322+ @ GetMapping (value = {"getallproducts" , "GetAllProducts" }, produces = MediaType .APPLICATION_JSON_VALUE )
323+ public ResponseEntity getAllProducts () {
324+
325+ return ResponseEntity .ok (productRepository .findAll ().stream ()
326+ .map (r -> new SelectItem (r .getProductID ().toString (), r .getProductID ().toString () + " - "
327+ + r .getProductName ()))
328+ .toList ());
329+ }
330+
331+ @ GetMapping (value = {"getorderdetailsgridwithcrud" , "GetOrderDetailsGridWithCrud" }, produces = MediaType .APPLICATION_JSON_VALUE )
332+ public ResponseEntity <?> getOrderDetailsGridWithCrud (HttpServletRequest request ,
333+ @ RequestParam (value = "OrderId" ) int orderId ) {
334+
335+ EntityManager em = entityManagerFactory .createEntityManager ();
336+
337+ Consumer <IGridColumnCollection <OrderDetail >> columns = c -> {
338+ c .add ("orderID" , Integer .class , true ).setPrimaryKey (true );
339+ c .add ("productID" , Integer .class ).setPrimaryKey (true );
340+ c .add ("product.productName" , String .class );
341+ c .add ("quantity" , Short .class );
342+ c .add ("unitPrice" , BigDecimal .class );
343+ c .add ("discount" , Float .class );
344+ };
345+
346+ var server = new GridServer <OrderDetail >(em , OrderDetail .class , request .getParameterMap (), columns )
347+ .withPaging (10 )
348+ .sortable ()
349+ .filterable ();
350+
351+ CriteriaBuilder cb = server .getGrid ().getCriteriaBuilder ();
352+ Root <OrderDetail > root = server .getGrid ().getRoot ();
353+ Predicate predicate = cb .equal (root .get ("orderID" ), orderId );
354+ server .setPredicate (predicate );
355+
356+ var items = server .getItemsToDisplay ();
357+ return ResponseEntity .ok (items );
358+ }
106359}
0 commit comments