magento Integrity Constraint Violation during product creation/update - php

I'm currently trying to integrate magento into an ERP System using an self written middleware.
I get this message:
Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`magento`.`catalog_product_entity`, CONSTRAINT `FK_CAT_PRD_ENTT_ATTR_SET_ID_EAV_ATTR_SET_ATTR_SET_ID` FOREIGN KEY (`attribute_set_id`) REFERENCES `eav_attribute_set` (`a)
I don't really know where the problem lies.
The result Object of a Product get and Product write look similar.
I checked the web already for help, but couldn't find an solution for it.
I also don't really know where to search, because the message on top is the only one I get.
Any help is appreceated.
Well the code itself is split up into multiple sections
but I'll try to show as much as possible
$this->product = Mage::getModel('catalog/product')->loadByAttribute('sku',$this->handler['art_nr']);
if($this->product===false || $this->product->getId()<1){
$this->product = Mage::getModel('catalog/product');
$this->product->setSku($this->handler['art_nr']);
$this->newProduct = true;
}
$this->product->setStatus($this->shoparticle['products_status']);
$this->product->setName($this->handler['art_name']);
$categories = array();
if(!$this->isNewProduct()){
$categories = $this->product->getCategoryIds();
}
$categories = $this->handler['all_categories'];
$this->product->setCategoryIds($categories);
$crosssellingSet = array();
$upsellingSet = array();
$relatedSet = array();
if(is_array($this->handler['xselling']) && count($this->handler['xselling'])>0){
foreach($this->handler['xselling'] as $valueSet){
$product = Mage::getModel('catalog/product')->loadBySku($valueSet['art_nr']);
if((int)$valueSet['group']===1){
$crossselling[$product->getId()] = array('position'=>$valueSet['sort_oder']);
}else if((int)$valueSet['group']===2){
$upsellingSet[$product->getId()] = array('position'=>$valueSet['sort_oder']);
}else if((int)$valueSet['group']===3){
$relatedSet[$product->getId()] = array('position'=>$valueSet['sort_oder']);
}
}
}
$this->product->setCrossSellProductsData($crosssellingSet);
$this->product->setUpsellingProductsData($upsellingSet);
$this->product->setRelatedProductsData($relatedSet);
$importDir = Mage::getBaseDir('media') . DS . 'import' . DS;
//check if exists and add .htaccess file for protection
if(!is_dir($importDir)){
#mkdir($importDir,0775,true);
#chmod($importDir,0775);
}
if(!is_dir($importDir)){
throw new Connector_Model_Exception_Error('Could not create import Directory!');
}
if(!file_exists($importDir.'.htaccess')){
file_put_contents($importDir.'.htaccess','Order deny,allow'."\n".'Deny from all'."\n");
}
//clean direcotry
$dir = dir($importDir);
while(($e=$dir->read())!==false){
if(strpos($e,'.jpg')||strpos($e,'.png')||strpos($e,'.jepg')||strpos($e,'.gif')||strpos($e,'.tif')){
#unlink($importDir.$e);
}
}
//write images into directory
//and run Import
foreach($this->handler['images'] as $image){
file_put_contents($importDir.$image['image_name'],$image['image']);
$this->product->addImageToMediaGallery($importDir.$image['image_name'], array('image', 'small_image', 'thumbnail'), false, false);
}
$groups = Mage::getModel('customer/group')->getCollection()->getAllIds();
if((float)$this->handler['Bpreis'] > 0.00){
$this->product->setPrice((float)$this->handler['Bpreis']);
}
if((float)$this->handler['art']['products_pprices'] > 0.00){
$this->product->setMsrp((float)$this->handler['art']['products_pprices']);
}
//preapre the price data for ranges
$groupsets = array();
if(count($this->handler['PGROUP'])){
foreach($this->handler['PGROUP'] as $group){
if(in_array(((int)$group['gruppe']-250),$groups)){
$groupsets[((int)$group['gruppe']-250)][(float)$group['marge']] = (float)$group['PGPRICE'];
}
}
}
//Now run ageanst groupsets to set price range etc
$storeid = Mage::app()->getStore()->getWebsiteId();
foreach($groupsets as $groupid=>$rangeset){
if(count($rangeset)>0){
foreach($rangeset as $key=>$value){
if(count($rangeset)===1 && $key === (float)0){
$this->product->setData(
'group_price',
array(
'website_id'=>$storeid,
'cust_group'=>$groupid,
'price'=>$value,
)
);
}else{
$this->product->setData(
'tier_price',array(
'website_id'=>$storeid,
'cust_group'=>$groupid,
'price'=>$value,
'price_qty'=>$key
)
);
}
}
}
}
Mage::app()->getStore()->setId(Mage_Core_Model_App::ADMIN_STORE_ID);
if($this->isNewProduct()){
$this->product->setCreatedAt(strtotime('now'));
}
$this->product->save();

The error is telling you exactly what the problem is. You are trying to save a product with an incorrect attribute set id. By that it means that the attribute set id you have set or not set in this case is not in the eav_attribute_set table. I think it's because if you create a new product you are not setting it. If you are updating an existing one you dont need to set it.
if($this->product===false || $this->product->getId()<1){
$this->product = Mage::getModel('catalog/product');
$this->product->setSku($this->handler['art_nr']);
// Set Attribute Set. Should be numeric for simple, bundle, configurable, grouped etc
$this->product->setAttributeSetId($this->handler['art_attribute_set_id']);
$this->newProduct = true;
}

Please check are you using right Attribute set id with your code. Please share the code where you have written the code to update/save the product.

Related

Verify if a category already exist, if exists save() if doesn't exist add() PrestaShop

My project is with Webservices add categories and when I refresh the file of categories it creates the same categories I had before.
foreach ($XMLRSString->Families->Family as $family)
{
$categories = $family->Code;
$exists = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('select id_category from ps_category where id_category = "'.$categories['id_category'].'"');
$category = new Category((int)$categories);
$category->id= (int)$categories;
$category->id_category_default=(int)$family->Code;
$category->force_id = true;
$category->is_root_category = false;
$category->name = array((int)Configuration::get('PS_LANG_DEFAULT') => $family->Designation);
$category->link_rewrite = array((int)Configuration::get('PS_LANG_DEFAULT') => $family->Code);
$category->id_parent = Configuration::get('PS_HOME_CATEGORY');
if($exists){
$category->add();
echo "created ".$family->Code."<br>";
}
else{
$category->save();
echo "already exists ".$family->Code."<br>";
}
}
It doesn't appear any error but it doesn't show up on PrestaShop categories
No need to use if ($exists), as $category->save(); will already check if the category exists, if so it will update it, otherwise it will create it.
You can refer to your previous question on this topic:
How to test if a category already exists? PrestaShop
I think your issue comes from the fact your forgot to set the category as active:
$category->active = 1;
Also, you should check the return value of $category->save();.
I hope this helps!

Database error 1452

I'm working on this project that have foreign keys on two tables. By using a form I'm trying to insert a new record to the database. And there's also an image path in the db and I'm inserting the image path via the form. I'm using codeigniter file upload library. Other fields of the database table get updated when i submit the form even the foreign key field. But the image path is not updating. When I submit the form it shows this error.
A Database Error Occurred
Error Number: 1452
Cannot add or update a child row: a foreign key constraint fails (`bfh`.`products`, CONSTRAINT `category_fk` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`))
INSERT INTO `products` (`img`) VALUES ('assets/img//sakya.PNG')
Filename: C:/xampp/htdocs/CI-skeleton/system/database/DB_driver.php
Line Number: 691
Controller
public function add_product()
{
$result = 0;
$cat_id = $this->input->post("category_id");
$type_id = $this->input->post("type_id");
$pname = $this->input->post("p_name");
$images = $this->input->post("images");
$images = $_FILES['images']['name'];
$price = $this->input->post("price");
$this->load->model("Products_Model");
$product_id = $this->Products_Model->add_product( $cat_id, $type_id, $pname, $price);
if ($product_id != 0) {
$result = $this->Products_Model->add_product_images($images);
}
if ($result && $_FILES['images']['name'][0] != "") {
$this->load->model('Image_Upload');
$result = $this->Image_Upload->upload("assets/img");
}
$this->session->set_flashdata('result', $result);
redirect('Products');
}
Model
public function add_product( $cat_id, $type_id, $pname, $price)
{
$result = $this->db->get_where("products", array('name' => $pname));
if ($result->num_rows() != 0) {
return 0; // record already exists
} else {
$data = array(
'category_id' => $cat_id,
'type_id' => $type_id,
'name' => $pname,
'price' => $price
);
if( !$this->db->insert('products', $data)) {
return -1; // error
}else{
return $this->db->insert_id();
}
return 1; // success
}
}
public function add_product_images($images)
{
$path = "assets/img/";
foreach ($images as $image) {
// if no images were given for the item
if ($image == "") {
return 1;
}
$data = array(
'img' => $path."/".$image
);
if ( ! $this->db->insert('products', $data)) {
return 0; // if something goes wrong
}
}
return 1;
}
You should use "update" query on the behalf of insert in add_product_images().
Because "insert" will add a new record of the product and there is no any category id(Foreign Key) with this that's why shows this error.
So try to update image.
you have two variables with the same name and thats the problem.
You need have different variable name.
I hope this will help you.
there are some problems in this script
if model you wrote, function add product. if your query failed, returns -1 otherwise return product Id
but if product was in database it returns 0, then in controller: you check if product_id != 0 then insert images. so you don't care if product didn't exists in database, you failed you insert that in table or not
in add_product_images you check if ($image == "") . I don't understand how you get that image array ($images) is empty if this statement is true. you can check if (sizeof($images) == 0) before foreach to check emptiness of image array ($images)

Sylius add to cart via CartItemController gives 0,00 total

We are currently developing an ERP-based webshop with Sylius. One of the features is that a customer can select multiple sizes and quantities and add them to their cart in one action.
Normally Sylius would work with a request-based ItemResolver for only one variant. We've tried to override the CartItemController so that we would be able to loop the request variables and add all the items to the cart.
We tried to use this code:
try {
// When we have multiple
$reqSize = $request->request->get('size');
$reqQuantity = $request->request->get('quantity');
$reqProductID = $request->request->get('product_id');
$reqColorID = $request->request->get('variant_color_id');
if (null !== $reqSize && null !== $reqQuantity && null !== $reqProductID && null !== $reqColorID && count($reqSize) === count($reqQuantity)) {
$provider = $this->get('sylius.cart_provider'); // Implements the CartProviderInterface.
$currentCart = $provider->getCart();
$priceCalculator = $this->get('sylius.price_calculator');
$availabilityChecker = $this->get('sylius.availability_checker');
$productRepo = $this->get('sylius.repository.product');
$variantRepo = $this->get('sylius.repository.product_variant');
$sizeRepo = $this->get('jartazi.repository.sizegrid_size');
$colorRepo = $this->get('jartazi.repository.color');
$product = $productRepo->find(intval($reqProductID));
$color = $colorRepo->find(intval($reqColorID));
for ($i = 0; $i < count($reqSize); $i++) {
$size = $sizeRepo->find(intval($reqSize[$i]));
$variant = $variantRepo->findOneBy(['object' => $product, 'size' => $size, 'color' => $color]);
$quantity = intval($reqQuantity[$i]);
if (null === $variant) {
throw new ItemResolvingException('Selected item is out of stock.');
}
if (null !== $product && null !== $color && null !== $size && null !== $variant) {
// Make a cart item
$item = $this->get('sylius.factory.cart_item')->createNew();
$item->setSize($size);
$item->setVariant($variant);
$item->setQuantity($quantity);
$context = ['quantity' => $quantity];
if (null !== $customer = $cart->getCustomer()) {
$context['groups'] = $customer->getGroups()->toArray();
}
$item->setUnitPrice($priceCalculator->calculate($variant, $context));
// Check for equal products
foreach ($currentCart->getItems() as $cartItem) {
if ($cartItem->equals($item)) {
$quantity += $cartItem->getQuantity();
break;
}
}
if (!$availabilityChecker->isStockSufficient($variant, $quantity)) {
throw new ItemResolvingException('Selected item is out of stock.');
}
$event = new CartItemEvent($cart, $item);
// Update models
$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_INITIALIZE, $event);
$eventDispatcher->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($cart));
$eventDispatcher->dispatch(SyliusCartEvents::CART_SAVE_INITIALIZE, $event);
// Write flash message
$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_COMPLETED, new FlashEvent());
}
}
return $this->redirectAfterAdd($configuration);
}
} catch (ItemResolvingException $exception) {
// Write flash message
$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_ERROR, new FlashEvent($exception->getMessage()));
return $this->redirectAfterAdd($configuration);
}
But when we add one to the cart, the cart total stays 0,00
Are we missing something in order to have the correct totals when adding a CartItem without an ItemResolver?
Thanks in advance.
Yes, with use of this service we were able to correctly modify the quantity and the unit prices. Thanks, we clearly overlooked this service. Our modification of the CartItem ($item->setQuantity($quantity);) we also deleted as this was a custom method, the setter was normally not available.
As specified by Coudenysj you probably need to call the OrderItemQuantityModifier somewhere in your code.
I think you need to manually call the modifier before you set the quantity
$this->get('sylius.order_item_quantity_modifier')->modify($item, $quantity);
// $item->setQuantity($quantity);
Actually it appears you just need to call the modify function and it updates the quantity to the correct value
I had a lot of trouble making my own add to cart code for this reason. I ended up modifying the CartItemType. But now i do need to be able to add multiple to the cart at once. So i would be very interested to hear if this solves your issues.
Please post an update
Take a look at the sylius.order_item_quantity_modifier service: http://docs.sylius.org/en/latest/bundles/SyliusOrderBundle/services.html#orderitemquantitymodifier.

Cakephp update or add new record

I have an image upload that adds the filename to a table called attachments. If the id already exists then I want it to update and if not then create a new record. At the moment it creates a new record so I have multiple records forthe one id. The id's are from a table called Addon's.
I am not sure how to do this in cakephp.
if (!empty($this->data)) {
$this->layout = null;
//if(empty($this->data['AddOn']['id'])){unset($this->data['AddOn']);}
// restructure data for uploader plugin // NEED TO GET RID OF THIS ? MOVE IT
$tmp_file = $this->data['Attachment'][0]['file'];
$tmp_file['extension'] = array_reverse(explode('.', $tmp_file['name']));
$tmp_file['extension'] = $tmp_file['extension'][0];
$tmp_file['title'] = strtolower(substr($tmp_file['name'],0,(0-strlen('.'.$tmp_file['extension']))));
$this->data['Attachment'][0]['alternative'] = ucwords(str_replace('_',' ', $tmp_file['title']));
$previous = $this->AddOn->Attachment->find('first', array('conditions'=> array('model'=>'AddOn', 'foreign_key'=>$id)));
if( !empty( $previous ) ) {
$this->AddOn->Attachment->id = $previous[ 'Attachment' ][ 'id' ];
}
if ($this->AddOn->save($this->data, array('validate' => 'first'))) {
$id = $this->AddOn->Attachment->getLastInsertID();
$att = $this->AddOn->Attachment->query("SELECT * from attachments WHERE id = ".$id);
$this->set('attachment',$att[0]['attachments']);
} else {
$tmp_file['name'] = 'INVALID FILE TYPE';
}
//debug($this->data);
$this->set('file', $tmp_file);
$this->RequestHandler->renderAs($this, 'ajax');
$this->render('../elements/ajax');
}
save() and saveAll() automatically update an existing row if the id has been set. You can do something like:
$previous = $this->AddOn->Attachment->find( /* whatever conditions you need */ );
if( !empty( $previous ) ) {
$this->AddOn->Attachment->id = $previous[ 'Attachment' ][ 'id' ];
}
Now the old record will be updated if it exists.
As a side note, the code after a successful saveAll() doesn't make much sense: first you're saving data to the database, then immediately retrieving it again. You can just keep using $this->data that already has the same content.
And another side note: you should use query() only as a last resort when you can't use Cake's other methods. query("SELECT * from attachments WHERE id = ".$id) is a trivial case that can be rewritten as $this->Model->id = $id; $this->Model->read(); or using a simple $this->Model->find() query.

Sort by price not working in Magento Product List

I am unable to sort product by price in product list page.
Sort by name works fine there.
Any idea guys?
I googled and tried some solution but they didn't solve my problem.
I tried: System->Cache Management->Layered Navigation Indices->Refresh now
Also tried this link: http://www.miromedia.co.uk/blog/300/fixing-the-magento-price-sort-issue.htm
Magento version: 1.3.2.4
There seems to be some kind of bug in this version of Magento, the product catalog index price not updating on product save. So what you can do is by pass the price condition like described below.
Update addAttributeToSort function of Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection class.
Comment out the following code:-
// if ($attribute == 'price' && $storeId != 0) {
// $websiteId = Mage::app()->getStore()->getWebsiteId();
// $customerGroup = Mage::getSingleton('customer/session')->getCustomerGroupId();
//
// if ($this->isEnabledFlat()) {
// $priceColumn = 'e.display_price_group_' . $customerGroup;
// $this->getSelect()->order("{$priceColumn} {$dir}");
// }
// else {
// $priceAttributeId = $this->getAttribute('price')->getId();
//
// $entityCondition = '_price_order_table.entity_id = e.entity_id';
// $storeCondition = $this->getConnection()->quoteInto(
// '_price_order_table.website_id = ?',
// $websiteId
// );
// $groupCondition = $this->getConnection()->quoteInto(
// '_price_order_table.customer_group_id = ?',
// $customerGroup
// );
// $attributeCondition = $this->getConnection()->quoteInto(
// '_price_order_table.attribute_id = ?',
// $priceAttributeId
// );
//
// $this->getSelect()->joinLeft(
// array('_price_order_table'=>$this->getTable('catalogindex/price')),
// "{$entityCondition} AND {$storeCondition} AND {$groupCondition} AND {$attributeCondition}",
// array()
// );
// $this->getSelect()->order('_price_order_table.value ' . $dir);
//
// /**
// * Distinct we are using for remove duplicates of products which have
// * several rows in price index (like grouped products)
// */
// $this->getSelect()->distinct(true);
// }
//
// return $this;
// }
You can do this in Magento standard way other than commenting out the core code. Hope this helps.
You need to configure the price attribute correctly in Magento admin.
Go to attribute management, find the price attribute and ensure that you tick the box on "sortable in frontend"
that should resolve this for you.

Categories