Magento 2: Get Product, Sku and Manufacturer name from database - sql

I use this query to get Product Name and Sku.
I would to add "brand name" that is stored in Manufacturer attributes . Is it possible to expand this query to get manufacturer name by product?
SELECT nametable.value,
nametable.store_id,
m2_catalog_product_entity.sku
FROM `m2_catalog_product_entity_varchar` AS nametable
LEFT JOIN m2_catalog_product_entity
ON nametable.entity_id = m2_catalog_product_entity.entity_id
WHERE nametable.attribute_id = (SELECT attribute_id
FROM `m2_eav_attribute`
WHERE `entity_type_id` = 4 and store_id = 0
AND `attribute_code` LIKE 'name');

I would highly recommend leveraging Magento 2 product object for retrieving the information instead of building queries yourself.
Inside a php class you can retrieve it like this using factory method:
<?php
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Catalog\Model\ProductFactory $product
) {
$this->product = $product;
parent::__construct($context);
}
public function getProduct($id)
{
$product = $this->product->create()->load($entity_id);
$sku = $product->getSku(); // get SKU
$name = $product->getName(); // get name
$manufacturer = $product->getManufacturer(); // get manufacturer
}
}
Or via Object Manager
$entity_id = "your product id";
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($entity_id);
$sku = $product->getSku(); // get SKU
$name = $product->getName(); // get name
$manufacturer = $product->getManufacturer(); // get manufacturer
To retrieve any attribute you want, you can use
$attribute = $product->getData("attribute_code"); // get any attribute

Related

.Net Core 5 Create Order and OrderDetail

I am creating Order including OrderDetail. When I have a Cart consisting of many Products, I create an Order, I want each product ID to be added to the OrderDetail including the OrderID.
But currently, I only get a ProductID (OrderID) in the first loop added to the OrderDetail. When I debug, the loop still executes enough times quantity of Product in Cart but is not added to OrderDetail.
So what is the problem that I am facing here?
Repository
public bool CreateOrder(CartViewModel invoiceVM, string userId)
{
invoiceVM.Invoices.CreateAt = DateTime.Now;
_dbContext.Invoice.Add(invoiceVM.Invoices);
_dbContext.SaveChanges();
decimal orderTotal = 0;
var cartItems = GetCartItem(userId);
foreach (var item in cartItems)
{
var invoiceDetail = new InvoiceDetails
{
ProductId = item.Products.Id,
InvoiceId = invoiceVM.Invoices.Id,
Price = item.Products.Price * item.Quantity,
Quantity = item.Quantity,
};
orderTotal += (item.Quantity * item.Products.Price);
_dbContext.InvoiceDetails.Add(invoiceDetail);
}
invoiceVM.Invoices.OrderTotal = orderTotal;
_dbContext.SaveChanges();
return true;
}
"but is not added to OrderDetail" You mean that the Order is created in your database, But you can't see any OrderDetail in your database ?
if
_dbContext.InvoiceDetails.Add(invoiceDetail);
.
.
_dbContext.SaveChanges();
are successfully pass with no errors, It save data in your database and I think it's your CartViewModel that is not updating.
you can add your data to CartViewModel in you loop or run another GetInvoice() from your dbContext.

Prestashop 1.7 module : Need to get "Country" and "State" names, "Products" and "Order message"

I am developing a module, it gets order details when order statut is changed to "shipped" by admin, to post them to a third party application with api. I am using Prestashop V 1.7.7.0.
I still need to get "country" and "state" names, "products" and "order message". How can i do that please?
Also, the module can't be installed in prestashop. Is my code right?
Need help please. Thanks
public function hookActionOrderStatusPostUpdate($params)
{
if($params['newOrderStatus']->id == 13)
{
$order = new Order((int)$params['id_order']);
$address = new Address((int)$order->id_address_delivery);
$customer = new Customer((int)($address->id_customer));
$country = new Country((int)($address->id_country));
$state = new Country((int)($address->id_state));
$tel_cl = $address->phone;
$name_lastname_cl = $address->lastname . ' ' . $address->firstname;
$country_cl = **Not yet**;
$state_cl = **Not yet**;
$adress_cl = $address->address1 . ' ' . $address->address2;
$tel_2_cl = $address->phone_mobile
$products = **Not yet**;
$quantity = "1"
$cod = $order->total_paid
$note = **Not yet(order message)**;
$Url_str = 'http://example.com/api/set_parcel_post.php?id=123&tel_cl='.$tel_cl.'&name_lastname_cl='.$name_lastname_cl.'&country_cl='.$country_cl.'&state_cl='.$state_cl.'&address_cl='.$address_cl.'&tel_2_cl='.$tel_2_cl.'&products='.$products.'&cod='.$cod.'&Quantity='.$Quantity.'&note='.$note;
$json = file_get_contents($Url_str);
$result = json_decode($json);
}
}
You can't instantiate a Country object using an id_state so this:
$state = new Country((int)($address->id_state));
is wrong and should be
$state = new State((int) $address->id_state);
So you can get the state name like $state->name,
To get the product orders you can use $order->getProducts(); which will return an array filled with the order products and its information(name,price,etc..)

Yii DataProvider with two tables

I have two tables
User:
id | name | gender(boolean)
Gender:
gender_id (boolean) | gender_name (text)
I want to display the text representation of gender through DataProvider
UserController:
public function actionIndex()
{
$crt = new CDbCriteria();
$crt->alias = 'so';
$crt->select = 'so.id, so.name, so.gender, fl.Gender_name';
$crt->join = " left join " . Gender::model()->tableName() . " as fl on fl.Gender_id = so.Gender";
$dataProvider=new CActiveDataProvider('User', array('criteria' => $crt));
$this->render('index',array(dataProvider'=>$dataProvider,));
}
As a result, I can not pass through dataProvider table gender
You can beter create a relation in the models. This way you dont have to use the criteria, and the value canbe accessed through $model->gender->gender_name for example

Yii: adding custom fields

Is there a simple way of adding custom fields to a model? Say I have a table "user" with 3 fields: id, name and surname. I want this:
$user = User::model()->findByPk(1);
$echo $user->fullName; // echoes name and surname
Please note: I want this custom field to be added via sql, smth like
$c = new CDbCriteria();
$c->select = 'CONCAT("user".name, "user".surname) as fullName';
$user = User::model()->find($c);
Problem is that fullName property is not set.
UPD:
here is the code for a little bit trickier problem -- custom field from another table. This is how it's done:
$model = Application::model();
$model->getMetaData()->columns = array_merge($model->getMetaData()->columns, array('fullName' => 'CONCAT("u".name, "u".surname)'));
$c = new CDbCriteria();
$c->select = 'CONCAT("u".name, "u".surname) as fullName';
$c->join = ' left join "user" "u" on "t".responsible_manager_id = "u".id';
$model->getDbCriteria()->mergeWith($c);
foreach ($model->findAll() as $o) {
echo '<pre>';
print_r($o->fullName);
echo '</pre>';
}
You can add a function to the User class:
public function getFullName() { return $this->name.' '.$this->surname; }
This will return the full name as if it were an attribute from the database. This is much easier than adding a calculated column to the SQL.
In model
public function getMetaData(){
$data = parent::getMetaData();
$data->columns['fullName'] = array('name' => 'fullName');
return $data;
}
Thus not recommended

Joining tables in LINQ/SQL

I have below a collection of rows and each row consists of productid, unitid, countryid.
I need to find the details for each row in the corresponding tables (products, units, country)
for product - select product name, updatedby
for unitid - select unit name , updatedby
for countryid - select countryname, uploadby
and returning the rows which has the same format
Id = product id or unitid or countryid
name = proudct name or unit name or countryname
modified = product updatedby or unit updated by or country uploadby
So, in summary -
1. For a Collection of rows
a. use the id to get the extra details from the respective table
b. return the same type of collection for the results
2. do step 1 for
2.a For RegularToys (Run this logic on TableBigA)
2.b For CustomToys(Run this logic on TableB)
3. Return all the rows
by adding 2.a and 2.b
How to write an sql/linq query for this? thanks
If I'm understanding correctly, you want to use a given ID to find either a product, a unit or a country but you're not sure which. If that's the case, then you can build out deferred queries like this to find the given entity:
var prod = from p in db.Products
where p.ProductId = id
select new { Id = p.ProductId, Name = p.ProductName, Modified = p.UpdatedBy };
var unit = from u in db.Units
where p.UnitId = id
select new { Id = u.UnitId, Name = u.UnitName, Modified = p.UpdatedBy };
var ctry = from c in db.Countries
where c.CountryId = id
select new { Id = c.CountryId, Name = c.CountryName, Modified = c.UploadBy };
And then execute the queries until you find an entity that matches (with ?? being the null-coalesce operator that returns the right value if the left result is null).
var res = prod.SingleOrDefault() ??
unit.SingleOrDefault() ??
ctry.SingleOrDefault() ??
new { Id = id, Name = null, Modifed = null };
Without any further details I can't be more specific about the condition below, but I think you are asking for something along these lines. I'm assuming your Id's are int's (but this can be easily changed if not) and you already have an Entity Data Model for the tables you describe.
Create a class for your common data:
class RowDetail
{
public int Id { get; set; }
public string Name { get; set; }
public string Modified { get; set; }
}
Pull the information out of each of the sub tables into a new record:
IEnumerable<RowDetail> products =
from p in db.Products
where <<CONDITION>>
select
new RowDetail()
{
Id = p.ProductId,
Name = p.ProductName,
Modified = p.UpdatedBy
};
IEnumerable<RowDetail> units =
from u in db.Units
where <<CONDITION>>
select
new RowDetail()
{
Id = u.UnitId,
Name = u.UnitName,
Modified = u.UpdatedBy
};
IEnumerable<RowDetail> countries =
from c in db.Countries
where <<CONDITION>>
select
new RowDetail()
{
Id = c.CountryId,
Name = c.CountryName,
Modified = c.UploadBy
};
Finally pull all the records together in a single collection:
IEnumerable<RowDetail> results = products.Union(units).Union(countries);
I'm not sure if this is exactly what you are looking for, so feel free to give feedback and/or more details if further assistance is required.