On my list below I have all my categories displayed, but the sub categories do not display name. The sub category names should display like
Example
Example > Some Example 1
Example > Some Example 2
PHP
PHP > Functions
Question: On my model I should be able to retrieve the sub category name and the parent category name. But not working. Can only display parent name as shown in image I use group concat but it not show up in list group concat should display with > when sub cat name is there.
Why is it not working and what is the best solution?
As shown on image not display the > Some Example 1.
On my model I am using multiple join tables and I use for example .c1 and .cd1 get's parent categories and .cd2 .c2 gets sub categories.
But when I use my db->select with Group Concat it does not work and only gets the parent category name.
public function get_categories() {
$language_id = '1';
$this->db->select('cp.category_id AS category_id, GROUP_CONCAT(cd1.name SEPARATOR " > ") as name');
$this->db->from('category_path cp', 'LEFT');
// Parent Cat
$this->db->join('category c1', 'c1.category_id = cp.category_id', 'LEFT');
// Sub Cat
$this->db->join('category c2', 'c2.category_id = cp.path_id', 'LEFT');
// Parent Cat
$this->db->join('category_description cd1', 'cd1.category_id = cp.path_id', 'LEFT');
// Sub Cat
$this->db->join('category_description cd2', 'cd2.category_id = cp.category_id', 'LEFT');
$this->db->group_by('cp.category_id');
$this->db->order_by('name', 'ASC');
$this->db->where('cd1.language_id', (int)$language_id);
$this->db->where('cd2.language_id', (int)$language_id);
$query = $this->db->get();
return $query->result_array();
}
Tried with false below not worked same result
$this->db->select('cp.category_id AS category_id, GROUP_CONCAT(cd1.name SEPARATOR " > ") as name', false);
Var dump of results
array(5) { [0]=> array(2) { ["category_id"]=> string(2) "19" ["name"]=> string(7) "Example" } [1]=> array(2) { ["category_id"]=> string(2) "22" ["name"]=> string(7) "Example" } [2]=> array(2) { ["category_id"]=> string(2) "25" ["name"]=> string(7) "Example" } [3]=> array(2) { ["category_id"]=> string(2) "23" ["name"]=> string(3) "PHP" } [4]=> array(2) { ["category_id"]=> string(2) "24" ["name"]=> string(3) "PHP" } }
LAST QUERY
SELECT `cp`.`category_id` AS `category_id`, GROUP_CONCAT(cd1.name ORDER BY level SEPARATOR " > ") as name FROM `category_path` `cp` LEFT JOIN `category` `c1` ON `c1`.`category_id` = `cp`.`category_id` LEFT JOIN `category` `c2` ON `c2`.`category_id` = `cp`.`path_id` LEFT JOIN `category_description` `cd1` ON `cd1`.`category_id` = `cp`.`path_id` LEFT JOIN `category_description` `cd2` ON `cd2`.`category_id` = `cp`.`category_id` WHERE `cd1`.`language_id` = 1 AND `cd2`.`language_id` = 1 GROUP BY `cp`.`category_id` ORDER BY `name` ASC
Category Table
Category Desc Table
Category Path Table
Try this :
$this->db->select("cp.category_id AS category_id, GROUP_CONCAT(cd1.name ORDER BY cp.level SEPARATOR ' > ') AS name, c1.parent_id, c1.sort_order", FALSE);
$this->db->select() accepts an optional second parameter. If you set it to FALSE, CodeIgniter will not try to protect your field or table names with backticks. This is useful if you need a compound select statement.
Thanks to all who shared idea's to help.
I have found the cause of the issue is on my add category function.
When ever I create a category if it is a sub category in my category_path table
If sub category id is lets say 22 and parent id 19
Then on category_path table row should have two row should of inserted two rows like below.
category_id path_id level
22 19 0
22 22 1
For some reason on my model add category function it's not inserting the path id correct
Now I know what need to fix on model function.
Full Working Model
<?php
class Model_category extends CI_Model {
public function add() {
$data = array(
'parent_id' => (int)$this->input->post('parent_id'),
'status' => $this->input->post('status'),
'date_edited' => mdate('%Y-%m-%d %H:%i:%s', now()),
'date_added' => mdate('%Y-%m-%d %H:%i:%s', now())
);
$this->db->insert($this->db->dbprefix . 'category', $data);
$category_id = $this->db->insert_id();
$data = array(
'category_id' => (int)$category_id,
'language_id' => (int)'1',
'name' => $this->input->post('name'),
'meta_title' => $this->input->post('meta_title'),
'meta_description' => $this->input->post('meta_description'),
'meta_keyword' => $this->input->post('meta_keyword'),
'date_edited' => mdate('%Y-%m-%d %H:%i:%s', now()),
'date_added' => mdate('%Y-%m-%d %H:%i:%s', now())
);
$this->db->insert($this->db->dbprefix . 'category_description', $data);
// MySQL Hierarchical Data Closure Table Pattern
$level = 0;
$this->db->select('*');
$this->db->from($this->db->dbprefix . 'category_path');
$this->db->where('category_id', (int)$this->input->post('parent_id'));
$this->db->order_by('level', 'ASC');
$query = $this->db->get();
foreach ($query->result_array() as $result) {
$data = array(
'category_id' => (int)$category_id,
'path_id' => (int)$result['path_id'],
'level' => (int)$level,
);
$this->db->insert($this->db->dbprefix . 'category_path', $data);
$level++;
}
// The problem was here was not adding category into model but now
// All Fixed.
$data = array(
'category_id' => (int)$category_id,
'path_id' => (int)$category_id,
'level' => (int)$level
);
$this->db->insert($this->db->dbprefix . 'category_path', $data);
if (isset($data['keyword'])) {
$data = array(
'category_id' => 'category_id=' . (int)$category_id,
'keyword' => $this->input->post('keyword'),
'date_edited' => mdate('%Y-%m-%d %H:%i:%s', now()),
'date_added' => mdate('%Y-%m-%d %H:%i:%s', now())
);
$this->db->insert($this->db->dbprefix . 'url_alias', $data);
$this->db->query("INSERT INTO " . $this->db->dbprefix . "url_alias SET query = 'category_id=" . (int)$category_id . "', keyword = '" . $this->db->escape($data['keyword']) . "'");
}
}
public function edit() {
}
public function get_categories($data = array()) {
$language_id = '1';
$this->db->select('cp.category_id AS category_id, GROUP_CONCAT(cd1.name ORDER BY level SEPARATOR " > ") as name, c1.parent_id, c1.sort_order');
$this->db->distinct();
$this->db->from($this->db->dbprefix . 'category_path cp', 'LEFT');
$this->db->join($this->db->dbprefix . 'category c1', 'cp.category_id = c1.category_id', 'LEFT');
$this->db->join($this->db->dbprefix . 'category c2', 'cp.path_id = c2.category_id', 'LEFT');
$this->db->join($this->db->dbprefix . 'category_description cd1', 'cp.path_id = cd1.category_id', 'LEFT');
$this->db->join($this->db->dbprefix . 'category_description cd2', 'cp.category_id = cd2.category_id', 'LEFT');
$this->db->where('cd1.language_id', '1');
$this->db->where('cd2.language_id', '1');
$this->db->group_by('cp.category_id');
$this->db->order_by('name', 'ASC');
$query = $this->db->get();
if ($query->num_rows() > 0) {
return $query->result_array();
} else {
return FALSE;
}
}
}
Related
I have 2 collections as below:
$unpaid = WhmcsClientsInvoice::join('quotations', 'quotations.id', 'whmcs_clients_invoices.quotation_id')
->select('whmcs_clients_invoices.invoice_id AS id', 'whmcs_clients_invoices.invoice_date AS date', 'quotations.total AS amount', 'whmcs_clients_invoices.payment_due_date AS due_date')
->where('whmcs_clients_invoices.whmcs_client_id', $client_id)
->where('whmcs_clients_invoices.status', '!=', 'Cancel')
->whereBetween('whmcs_clients_invoices.invoice_date', [$start, $end])
->orderBy('date', 'asc')
->get();
foreach($unpaid as $un) { $un['type'] = "invoice"; }
$paid = InvoiceHistory::join('whmcs_clients_invoices', 'whmcs_clients_invoices.id', 'invoice_history.whmcs_clients_invoices_id')
->select('invoice_history.id', 'invoice_history.date_paid AS date', 'invoice_history.amount_paid AS amount', 'invoice_history.created_at AS due_date')
->where('whmcs_clients_invoices.whmcs_client_id', $client_id)
->where('whmcs_clients_invoices.status', '!=', 'Cancel')
->whereBetween('invoice_history.date_paid', [$start, $end])
->orderBy('date', 'asc')
->get();
foreach ($paid as $paid) { $paid['type'] = 'payment'; }
$trans = $unpaid->merge($paid);
dd($trans);
But when I try to merge these 2 collections, an error will occur.
I tried $transaction = $unpaid->union($paid)->sortBy('date'); but to no avail. Vardump of the merged collection shows:
error_log the $transaction would show something like this:
{"date":"2021-01-26
00:00:00","id":12,"amount":111.3,"due_date":"2021-01-26
09:00:05","type":"payment","0":{"id":1,"date":"2021-01-07","amount":222.6,"due_date":"2021-01-14","type":"invoice"},"1":{"id":3,"date":"2021-01-09","amount":6572,"due_date":"2021-01-16","type":"invoice"},"2":{"id":4,"date":"2021-01-12","amount":148.4,"due_date":"2021-01-19","type":"invoice"},"3":{"id":5,"date":"2021-01-12","amount":144.16,"due_date":"2021-01-19","type":"invoice"},"4":{"id":6,"date":"2021-01-16","amount":24.38,"due_date":"2021-01-23","type":"invoice"},"5":{"id":2,"date":"2021-01-29","amount":222.6,"due_date":"2021-01-14","type":"invoice"},"6":{"id":24,"date":"2021-02-23","amount":190.8,"due_date":"2021-03-02","type":"invoice"}}
Apparently the union merge the 2 collections, but couldn't assign key to the first item...
How do I merge 2 collections without missing any records in both collections? The expected output should be from this:
Collection {#595 ▼
#items: array:3 [▼
0 => WhmcsClientsInvoice {
"id" = 37
"date" => "2021-02-07 00:00:00"
"amount" => 50.0
"due_date" => "2021-02-07 14:19:20"
"type" => "payment"
}
2 => InvoiceHistory {
"id" = 37
"date" => "2021-02-07 00:00:00"
"amount" => 50.0
"due_date" => "2021-02-07 14:19:20"
"type" => "payment"
}
1 => WhmcsClientsInvoice {
"id" = 37
"date" => "2021-02-07 00:00:00"
"amount" => 50.0
"due_date" => "2021-02-07 14:19:20"
"type" => "payment"
}
]
}
This happens sometimes,
Try this
$trans = $unpaid->concat($paid);
After a few days of painstaking research, I found a way that works for me. This is my updated code:
$transaction = collect(new WhmcsClientsInvoice);
$unpaid = WhmcsClientsInvoice::join('quotations', 'quotations.id', 'whmcs_clients_invoices.quotation_id')
->select('whmcs_clients_invoices.invoice_id', 'whmcs_clients_invoices.invoice_num', 'whmcs_clients_invoices.invoice_date AS date', 'quotations.total AS amount', 'whmcs_clients_invoices.payment_due_date AS due_date')
->where('whmcs_clients_invoices.whmcs_client_id', $client_id)
->where('whmcs_clients_invoices.status', '!=', 'Cancel')
->whereBetween('whmcs_clients_invoices.invoice_date', [$start, $end])
->orderBy('date', 'asc')
->get();
foreach($unpaid as $un) {
$un['type'] = "invoice";
$transaction->push($un);
}
$paid = InvoiceHistory::join('whmcs_clients_invoices', 'whmcs_clients_invoices.id', 'invoice_history.whmcs_clients_invoices_id')
->select('invoice_history.date_paid AS date', 'invoice_history.remark', 'invoice_history.amount_paid AS amount', 'invoice_history.created_at AS due_date')
->where('whmcs_clients_invoices.whmcs_client_id', $client_id)
->where('whmcs_clients_invoices.status', '!=', 'Cancel')
->whereBetween('invoice_history.date_paid', [$start, $end])
->orderBy('date', 'asc')
->get();
foreach ($paid as $pa) {
$pa['type'] = "payment";
$transaction->push($pa);
}
$transaction = $transaction->sortBy('date');
First, I make an empty collection based on WhmcsClientInvoices called Transaction. Basically, my idea is to create 2 separate collections, then merge them into Transaction. So, I made 2 eloquents to get 2 different collections. Then, during the foreach, I added a new item with key call type, to differentiate whether each record is invoice or payment. Then, I take each individual record in collection and push it to Transaction. I repeat the process with $paid collection. Lastly, I sort the collection by date.
I filter and list the products listed with the code samples on my model page below with some data from the user.
I want to sort the listed products according to their prices. However, as it is seen in the minprice-maxprice sample code block, relation depends on several conditions.
From the period consisting of postFrom and postTo dates received by the user, if the daily is 0, it should be listed according to the old_daily price, if the daily is not 0, it should be listed according to the daily price.
How can I do that?
my model page
public $belongsTo = [
'price' => [
'ac\prices\models\Price',
'key' => 'id',
'otherKey' => 'pro_id',
],
]
public static $allowedSortingOptions = array (
'name desc' => 'Name - desc',
'name asc' => 'Name - asc',
'price desc' => 'Price - desc',
'price asc' => 'Price - asc',
);
public function scopeListFrontEnd($query, $options = []){
extract(array_merge([
'page' => 1,
'perPage' => 10,
'sort' => 'created_at desc',
'postFrom' => null,
'postTo' => null,
'minPrice' => null,
'maxPrice' => null,
], $options));
if(!is_array ($sort)){
$sort = [$sort];
}
foreach ($sort as $_sort){
if(in_array($_sort, array_keys(self::$allowedSortingOptions))){
$parts = explode(' ', $_sort);
if(count($parts) < 2){
array_push($parts, 'desc');
}
list($sortField, $sortDirection) = $parts;
$query->orderBy($sortField, $sortDirection);
}
}
if($minPrice != null) {
if(!is_array($minPrice)){
$minPrice = [$minPrice];
}
foreach ($minPrice as $mnPrice){
$query->whereHas('price', function($q) use ($mnPrice,$maxPrice,$postFrom,$postTo){
$q->where('daily', '==', '0')
->where(function( $query ) use ( $mnPrice, $maxPrice ) {
$query->where('old_daily', '>=', $mnPrice);
$query->where('old_daily', '<=', $maxPrice[0]);
});
$q->orWhere('daily', '!=', '0')
->where(function( $query ) use ( $mnPrice, $maxPrice ) {
$query->where('daily', '>=', $mnPrice);
$query->where('daily', '<=', $maxPrice[0]);
});
$q->when($postFrom == '0', function ($sq) {
$sq->where('id', '>', '0');
}, function ($ssq) use ($postFrom, $postTo) {
$ssq->where(function($q) use ($postFrom) {
$q->whereDate('start_date', '<=', $postFrom[0])
->whereDate('end_date', '>=', $postFrom[0]);
})->orWhere(function($q) use ($postTo) {
$q->whereDate('start_date', '<=', $postTo[0])
->whereDate('end_date', '>=', $postTo[0]);
});
});
});
}
}
$lastPage = $query->paginate($perPage, $page)->lastPage();
if($lastPage < $page){
$page = 1;
}
return $query->paginate($perPage, $page);
}
Without trying to decode exactly what you are trying to do here, I would be adding a sub-query select that pulls a sort_price field into the results that you can then orderBy.
$query->selectRaw('CASE WHEN daily = 0 THEN old_daily ELSE daily END as sort_price');
$query->orderByRaw('(SELECT sort_price)');
You can also do this directly in the sort condition as per MYSQL ORDER BY CASE Issue if you don't need this price in your result.
You can do this in the orderByRaw builder method.
Im having a weird problem.
Im using laravel backpack for an admin panel. There i use select2_from_ajax to list a values according to another field in create operation. It is showing up correctly as expected & i can select one too.
But after selection when i click save & back it gives me an error
That means my column doesn't allow to update to null right.
So when i go back & check the column it has saved the correct value.
But when default value of my column was null this error will not showup & db value would be changed to null.
This is my select2_from_ajax part.
$this->crud->addField([ // Select
'label' => "Link Type",
'type' => 'select_from_array',
'name' => 'link_type', // the db column for the foreign key
'options' => [1 => 'Product',0 => 'Collection'],
'allows_null' => false,
]);
$this->crud->addField([ // Select
'label' => "Link To", // Table column heading
'type' => "select2_from_ajax",
'name' => "link_to",
'entity' => 'link',
'attribute' => "name",
'data_source' => url('admin/itemtype'),
'placeholder' => "Select a item",
'minimum_input_length' => 0,
'include_all_form_fields' => true,
'dependencies' => ['link_type'],
]);
So why is it trying to set null value after the correct value?
Any help would be appreciated. Thanks.
My admin/itemtype function:
$search_term = $request->input('q');
$form = collect($request->input('form'))->pluck('value', 'name');
if ($search_term) {
if ($form['link_type'] == 0) {
$items = Collection::where('name', 'LIKE', '%' . $search_term . '%')->paginate(10);
} else {
$items = Product::where('title', 'LIKE', '%' . $search_term . '%')->paginate(10);
}
} else {
if ($form['link_type'] == 0) {
$items = Collection::paginate(10);
} else {
$items = Product::paginate(10);
}
}
return $items;
I need to add a join to my order collection with my custom table.
For this I have use this below code:
$collection = Mage::getResourceModel($this->_getCollectionClass());
$collection->getSelect()
->joinLeft(array(
"t1" => 'fp_sellecrcommision_data'),
"main_table.increment_id = t1.store_order_id",
array("commiisiion_status" => "t1.commiisiion_status")
);
$collection->addFieldToFilter("store_id",$storeid )
->addAttributeToFilter("status","complete");
Which is working fine. But when I am applying filter it is throwing below error
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'commiisiion_status' in 'where clause', query was: SELECT COUNT(*) FROM `sales_flat_order_grid` AS `main_table` WHERE (`store_id` = '1') AND (`status` = 'complete') AND (`commiisiion_status` = '0')
This is the structure of my custom table:
And below is my custom column in grid:
$this->addColumn('commiisiion_status', array(
'header' => Mage::helper('sellercommision')->__('Commision Status'),
'index' => 'commiisiion_status',
'type' => 'options',
'options' => XYZ_Sellercommision_Block_Adminhtml_Sellercommision_Storeorders::commisionsStatusesArray(),
));
How can I fix this?
Hi i have solved this by using below _commissionFilterCallBack function
protected function _commissionFilterCallBack($collection, $column)
{
//Put your logic here..!!
$value = $column->getFilter()->getValue();
$comission_paid_orders = array();
$commissionstatus_model = Mage::getModel("commissionstatus/commissionstatus")->getCollection();
foreach($commissionstatus_model as $commissionstatus){
$comission_paid_orders[] = $commissionstatus['order_imcrement_id'];
}
if ($value=="pending")
{
if(count($comission_paid_orders)==0){
return $this;
}
else{
$this->getCollection()->addAttributeToFilter("increment_id",array("nin"=>$comission_paid_orders));
return $this;
}
}
$this->getCollection()->getSelect()->where("t1.commission_status like ?", "%$value%");
return $this;
}
I have followed How to create a custom grid from scratch to create custom Sales Orders. Admin is creating vendors and vendors will be uploading product. I want to restrict vendors such that they can see orders placed on their own product only.
There is one new model jbmarketplace/jbmarketplaceproducts in which vendors user_id and product_id is being stored when vendor creates product. But when I'm filtering it gives SQLSTATE[42S22]: Column not found: 1054 Unknown column 'product_id' in 'where clause'. But product_id is available in sales_flat_order_item table.
This problem is Fixed. Updated Code
protected function _prepareCollection()
{
// Get current logged in user
$current_user = Mage::getSingleton( 'admin/session' )->getUser();
// Limit only for vendors
if ( $current_user->getRole()->getRoleId() == Mage::getStoreConfig( 'jbmarketplace/jbmarketplace/vendors_role' ) ) {
// echo( $current_user->getUserId());
$my_products = Mage::getModel( 'jbmarketplace/jbmarketplaceproducts' )
->getCollection()
->addFieldToSelect( 'product_id' )
->addFieldToFilter( 'user_id', $current_user->getUserId() )
->load();
$my_product_array = array();
foreach ( $my_products as $product ) {
$my_product_array[] = $product->getProductId();
$entity = Mage::getModel('sales/order_item')
->getCollection()
->addFieldToSelect('order_id')
->addFieldToFilter('product_id',$my_product_array)
->load();
// echo $entity->getSelect();// will print sql query
}
$d=$entity->getData();
if($d){
$collection = Mage::getResourceModel('sales/order_collection')
// My code
->addFieldToFilter('entity_id', $d)
->join(array('a' => 'sales/order_address'), 'main_table.entity_id = a.parent_id AND a.address_type != \'billing\'', array(
'city' => 'city',
'country_id' => 'country_id'
))
// ->join(Mage::getConfig()->getTablePrefix().'catalog_product_entity_varchar', 'main_table.products_id ='.Mage::getConfig()->getTablePrefix().'catalog_product_entity_varchar.entity_id',array('value'))
->join(array('c' => 'customer/customer_group'), 'main_table.customer_group_id = c.customer_group_id', array(
'customer_group_code' => 'customer_group_code'
))
->addExpressionFieldToSelect(
'fullname',
'CONCAT({{customer_firstname}}, \' \', {{customer_lastname}})',
array('customer_firstname' => 'main_table.customer_firstname', 'customer_lastname' => 'main_table.customer_lastname'))
->addExpressionFieldToSelect(
'products',
'(SELECT GROUP_CONCAT(\' \', x.name)
FROM sales_flat_order_item x
WHERE {{entity_id}} = x.order_id
AND x.product_type != \'configurable\')',
array('entity_id' => 'main_table.entity_id')
)
;
parent::_prepareCollection();
$this->setCollection($collection);
return $this;
}
else
{
echo("Current there are no purchases on your product. Thank you");
}
}
else{
echo("Please Login as Vendor and you will see orders on your products.<br>");
// $current_user = Mage::getSingleton( 'admin/session' )->getUser()->getUserId();
// echo($current_user);
}
}
Here is the code which worked for me.
protected function _prepareCollection()
{
// Get current logged in user
$current_user = Mage::getSingleton( 'admin/session' )->getUser();
// Limit only for vendors
if ( $current_user->getRole()->getRoleId() == Mage::getStoreConfig( 'jbmarketplace/jbmarketplace/vendors_role' ) ) {
// echo( $current_user->getUserId());
$my_products = Mage::getModel( 'jbmarketplace/jbmarketplaceproducts' )
->getCollection()
->addFieldToSelect( 'product_id' )
->addFieldToFilter( 'user_id', $current_user->getUserId() )
->load();
$my_product_array = array();
foreach ( $my_products as $product ) {
$my_product_array[] = $product->getProductId();
$entity = Mage::getModel('sales/order_item')
->getCollection()
->addFieldToSelect('order_id')
->addFieldToFilter('product_id',$my_product_array)
->load();
// echo $entity->getSelect();// will print sql query
}
$d=$entity->getData();
if($d){
$collection = Mage::getResourceModel('sales/order_collection')
// My code
->addFieldToFilter('entity_id', $d)
->join(array('a' => 'sales/order_address'), 'main_table.entity_id = a.parent_id AND a.address_type != \'billing\'', array(
'city' => 'city',
'country_id' => 'country_id'
))
// ->join(Mage::getConfig()->getTablePrefix().'catalog_product_entity_varchar', 'main_table.products_id ='.Mage::getConfig()->getTablePrefix().'catalog_product_entity_varchar.entity_id',array('value'))
->join(array('c' => 'customer/customer_group'), 'main_table.customer_group_id = c.customer_group_id', array(
'customer_group_code' => 'customer_group_code'
))
->addExpressionFieldToSelect(
'fullname',
'CONCAT({{customer_firstname}}, \' \', {{customer_lastname}})',
array('customer_firstname' => 'main_table.customer_firstname', 'customer_lastname' => 'main_table.customer_lastname'))
->addExpressionFieldToSelect(
'products',
'(SELECT GROUP_CONCAT(\' \', x.name)
FROM sales_flat_order_item x
WHERE {{entity_id}} = x.order_id
AND x.product_type != \'configurable\')',
array('entity_id' => 'main_table.entity_id')
)
;
parent::_prepareCollection();
$this->setCollection($collection);
return $this;
}
else
{
echo("Current there are no purchases on your product. Thank you");
}
}
else{
echo("Please Login as Vendor and you will see orders on your products.<br>");
// $current_user = Mage::getSingleton( 'admin/session' )->getUser()->getUserId();
// echo($current_user);
}
}