Magento 2 pagination is not working in join with product collection and custom table - pagination

$page=($this->getRequest()->getParam('p'))? $this->getRequest()->getParam('p') : 1;
$pageSize=($this->getRequest()->getParam('limit'))? $this->getRequest()->getParam('limit') : 4;
$collection = $this->productcollection->create()->addAttributeToSelect(array('group_name','name','status'));
$collection->addAttributeToFilter('status',1);
$collection->getSelect()
->join(['firmware_product' => $collection->getTable('firmware_product')],'firmware_product.product_id = e.entity_id',[]);
$collection->getSelect()
->join(['firmware' => $collection->getTable('firmware')],'firmware.entity_id = firmware_product.firmware_id',[])
->columns(array("firmware.version_no","firmware.build_date","firmware.is_active"));
$collection->getSelect()->where("firmware.is_active = ?",1);
$collection->getSelect()->order('firmware.entity_id', 'DESC');
$collection->setPageSize($pageSize);$collection->setCurPage($page);
The code above gives me the same entity_id as already exists. I reset the column and fetch only the firmware records and it still gives me the same error in the firmware entity_id. If I use this code
$collection->getSelect()->group('e.entity_id');
then the pagination does not work. Can anyone tell me what the solution for this is?

Related

How can I setup Pagination in Excel Power Query?

I am importing financial data using JSON from the web into excel, but as the source uses pagination (giving 50 results per page I need to implement pagination in order to import all the results.
The data source is JSON:
https://localbitcoins.com//sell-bitcoins-online/VES/.json?page=1
or https://localbitcoins.com//sell-bitcoins-online/VES/.json?page=2
?page=1, ?page=2, ?page=3
I use the following code to implement pagination, but receive an error:
= (page as number) as table =>
let
Source = Json.Document(Web.Contents("https://localbitcoins.com//sell-bitcoins-online/VES/.json?page=" & Number.ToText(page) )),
Data1 = Source{1}[Data],
RemoveBottom = Table.RemoveLastN(Data1,3)
in
RemoveBottom
When I envoke a parameter (1 for page 1) to test it I get the following error and I can't seem to find out why?
An error occurred in the ‘GetData’ query. Expression.
Error: We cannot convert a value of type Record to type List.
Details:
Value=Record
Type=Type
For the record, I try to include page handling using ListGenerate:
= List.Generate( ()=>
[Result= try GetData(1) otherwise null, page = 1],
each [Result] <> null,
each [Result = try GetData([page]+1) otherwise null, Page = [Page]+1],
each [Result])
What is the default way to implement pagination using Power Query in MS Excel?
I realise you asked this nearly a month ago and may have since found an answer, but will respond anyway in case it helps someone else.
This line Data1 = Source{1}[Data] doesn't make sense to me, since I think Source will be a record and you can't use {1} positional lookup syntax with records.
The code below returns 7 pages for me. You may want to check if it's getting all the pages you need/expect.
let
getPageOfData = (pageNumber as number) =>
let
options = [
Query = [page = Number.ToText(pageNumber)]
],
url = "https://localbitcoins.com/sell-bitcoins-online/VES/.json",
response = Web.Contents(url, options),
deserialised = Json.Document(response)
in deserialised,
responses = List.Generate(
() => [page = 1, response = getPageOfData(page), lastPage = null],
each [lastPage] = null or [page] <= [lastPage],
each [
page = [page] + 1,
response = getPageOfData(page),
lastPage = if [lastPage] = null then if Record.HasFields(response[pagination], "next") then null else page else [lastPage]
],
each [response]
)
in
responses
In List.Generate, my selector only picks the [response] field to keep things simple. You could drill deeper into the data either within selector itself (e.g. each [response][data][ad_list]) or create a new step/expression and use List.Transform to do so.
After a certain amount of drilling down and transforming, you might see some data like:
but that depends on what you need the data to look like (and which columns you're interested in).
By the way, I used getPageOfData in the query above, but this particular API was including the URL for the next page in its responses. So pages 2 and thereafter could have just requested the URL in the response (rather than calling getPageOfData).

Getting pagination to work with one to many join

I'm currently working on a database with several one-to-many and many-to-many relationships and I am struggling getting ormlite to work nicely.
I have a one-to-many relationship like so:
var q2 = Db.From<GardnerRecord>()
.LeftJoin<GardnerRecord, GardnerEBookRecord>((x, y) => x.EanNumber == y.PhysicalEditionEan)
I need to return a collection of ProductDto that has a nested list of GardnerEBookRecord.
Using the SelectMult() technique it doesn't work because the pagination breaks as I am condensing the left joined results to a smaller collection so the page size and offsets are all wrong (This method: How to return nested objects of many-to-many relationship with autoquery)
To get the paging right I need to be able to do something like:
select r.*, count(e) as ebook_count, array_agg(e.*)
from gardner_record r
left join gardner_e_book_record e
on r.ean_number = e.physical_edition_ean
group by r.id
There are no examples of this in the docs and I have been struggling to figure it out. I can't see anything that would function like array_agg in the Sql object of OrmLite.
I have tried variations of:
var q2 = Db.From<GardnerRecord>()
.LeftJoin<GardnerRecord, GardnerEBookRecord>((x, y) => x.EanNumber == y.PhysicalEditionEan)
.GroupBy(x => x.Id).Limit(100)
.Select<GardnerRecord, GardnerEBookRecord>((x, y) => new { x, EbookCount = Sql.Count(y), y }) //how to aggregate y?
var res2 = Db.SelectMulti<GardnerRecord, GardnerEBookRecord>(q2);
and
var q2 = Db.From<GardnerRecord>()
.LeftJoin<GardnerRecord, GardnerEBookRecord>((x, y) => x.EanNumber == y.PhysicalEditionEan)
.GroupBy(x => x.Id).Limit(100)
.Select<GardnerRecord, List<GardnerEBookRecord>>((x, y) => new { x, y });
var res = Db.SqlList<object>(q2);
But I can't work out how to aggregate the GardnerEBookRecord to a list and keep the paging and offset correct.
Is this possible? Any workaround?
edit:
I made project you can run to see issue:
https://github.com/GuerrillaCoder/OneToManyIssue
Database added as a docker you can run docker-compose up. Hopefully this shows what I am trying to do
Npgsql doesn't support reading an unknown array or records column type, e.g array_agg(e.*) which fails with:
Unhandled Exception: System.NotSupportedException: The field 'ebooks' has a type currently unknown to Npgsql (OID 347129).
But it does support reading an array of integers with array_agg(e.id) which you can query instead:
var q = #"select b.*, array_agg(e.id) ids from book b
left join e_book e on e.physical_book_ean = b.ean_number
group by b.id";
var results = db.SqlList<Dictionary<string,object>>(q);
This will return a Dictionary Dynamic Result Set which you'll need to combine into a distinct id collection to query all ebooks referenced, e.g:
//Select All referenced EBooks in a single query
var allIds = new HashSet<int>();
results.Each(x => (x["ids"] as int[])?.Each(id => allIds.Add(id)));
var ebooks = db.SelectByIds<EBook>(allIds);
Then you can create a dictionary mapping of id => Ebook and use it to populate a collection of ebooks entities using the ids for each row:
var ebooksMap = ebooks.ToDictionary(x => x.Id);
results.Each(x => x[nameof(ProductDto.Ebooks)] = (x["ids"] as int[])?
.Where(id => id != 0).Map(id => ebooksMap[id]) );
You can then use ServiceStack AutoMapping Utils to convert each Object Dictionary into your Product DTO:
var dtos = results.Map(x => x.ConvertTo<ProductDto>());

Opencart: how to change item price when adding it into the cart

I am trying to implement a functionality in opencart where it will be possible to enter a custom price at the product page via text area and when item is added to the cart if custom price entered it will apply the price specified in the custom price field.
Similar question was asked here someone kindly provided a good solution which applies to OpenCart 1.5.x. However I have tried to follow this approach on OpenCart 2 without any success. I have checked everything over and over for the last few days but I don't seem to be able to get this working as I am a newbie in programming world
I wondering if anyone is able to point me to right direction to what I may be missing.
I have search the web but unable to find any relevant information
I have checked and noticed that AJAX request is changed to #product div in 2.x, so I have enter my price input within this div underneath the quantity
<input name="custom_price" id="custom_price" value="" title="custom_price" class="input-text custom_price" type="textarea">
I have than moved on to the controller checkout/cart/add within the Add() method I have added this code
if(isset($this->request->post['custom_price'])) {
$custom_price = $this->request->post['custom_price'];
} else {
$custom_price = false;
}
Further down, I have changed this line
$this->cart->add($this->request->post['product_id'], $this->request->post['quantity'], $option, $recurring_id);
to:
$this->cart->add($this->request->post['product_id'], $this->request->post['quantity'], $option, $custom_price, $recurring_id);
Next, in the system/library/cart.php I have change the definition of the Add() method to the following
public function add($product_id, $qty = 1, $option = array(), $recurring_id = 0, $custom_price = false) {
Before the end of the Add()method I have added the following
if($custom_price) {
if(!isset($this->session->data['cart']['custom_price'])) {
$this->session->data['cart']['custom_price'] = array();
}
$this->session->data['cart']['custom_price'][$key] = $custom_price;
}
Within the GetProduct() I have added these lines
if(isset($this->session->data['cart']['custom_price'][$key])) {
$price = $this->session->data['cart']['custom_price'][$key];
}
right after this line:
$price = $product_query->row['price'];
Finally at after the array where product price is set to price + option price
'price' => ($price + $option_price),
I have added the following
if(isset($this->session->data['custom_price'][$key])) {
$this->data[$key]['price'] = $this->session->data['custom_price'][$key];
}

complex entityframework query

I have two tables:
NewsRooms ( NrID[int] , NrName [string]);
RawNews( RnID [int], NrID[string]);
realtion is RawNews 1 * NewsRooms
so i use checkboxes for NewsRooms and save the ids as a string in RawNews like this ';1;2;'
now for example i have a list which contains some NrIDs . i want to select every RawNew which it's NrID contains any of the ids inside that list.
here is my code:
var temp = Util.GetAvailibleNewsRooms("ViewRawNews");
List<string> ids = new List<string>();
foreach (var item in temp)
ids.Add(";" + item.NrID.ToString() + ";");
model = db.RawNews.Where(r => r.NrID.Any(ids));
the line model = db.RawNews.Where(r => r.NrID.Any(ids)); is wrong and i don't know how to write this code. please guide me. thanks
ok guys, i found the solution myself so i post it here maybe some other guy need it some day!!
model = model.Where(r => ids.Any(i => r.NrID.Contains(i)));

Get an object from ObservableColelction with condition

I have an ObservableColection totalsCol and want to retrieve an object whose id matches the specified id. I coded as :
IEnumerable<Totals> ie = totalsCol.Where(a => a.IdCTS == ct1.TOR_Id);
if (ie.Count() > 1)
{
// Update the TotalCts of Totals object
ie.ElementAt(0).TotalCTS = ct1.TotalCts;
CalculateTotalsPercent();
}
I get ie.count as null. Whereas it has 3 records. And on debugging, I can see that under Source of base.
Where am I wrong here ? I beleive the way am updating the the value with ie.ElementAt will reflect changes in totalsCol observableCollection.
Kindly help me out.
I implemented :
totalsCol.First(a => a.IdCTS == ct1.TOR_Id);
and solved the issue.

Resources