Restricting a category for a certain country in Prestashop 1.5 - prestashop

I need to restrict a category to a set of countries in Prestashop 1.5.
This restriction would prevent the shipping of a product belonging to such a category; as such, the users would still be able to see the products but they would not be able to buy them.
Ideally, I wanted to develop a module that would insert a list of countries (checkbox style, as in the Modules -> Payment page (AdminPayment)) inside a category's edit page, but I haven't been able to do so.
Why can't i simply paste the following code inside the renderForm() function?
Only the description is visible if i do so...
array(
'items' =>Country::getCountries(Context::getContext()->language->id),
'title' => $this->l('Country restrictions'),
'desc' => $this->l('Please mark the checkbox(es) for the country or countries for which you want to block the shipping.'),
'name_id' => 'country',
'identifier' => 'id_country',
'icon' => 'world',
),
EDIT:
I managed to get the list of countries working:
array(
'type' => 'checkbox',
'label' => $this->l('Restricted Countries').':',
'class' => 'sel_country',
'name' => 'restricted_countries',
'values' => array(
'query' => Country::getCountries(Context::getContext()->language->id),
'id' => 'id_country',
'name' => 'name'
),
'desc' => $this->l('Mark all the countries you want to block the selling to. The restrictions will always be applied to every subcategory as well')
),
Now, I can save these values by checking if the value "submitAddcategory" is being submitted in the postProcess function and by running an insert query there. Similarly, I can also load the IDs of the blocked countries from the database, but how can I tick the respective select boxes in the list of countries?
My initial "quick and dirty" idea was to use jQuery selectors inside a document.ready(), but the code gets inserted before everything else and, as such, it won't work because jQuery isn't even loaded yet.
How can this be done?
Cheers

I solved it by using the following code right before the end of the renderForm() function.
The Pièce de résistance was $this->fields_value, as sadly I didn't known of its existence.
public function getRestrictedCountries($obj)
{
// Loading blacklisted countries
$country = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT DISTINCT id_country
FROM `'._DB_PREFIX_.'category_country_restriction`
WHERE id_category = ' . (int)Tools::getValue('id_category') . ';');
$blacklisted_countries = array();
if (is_array($country))
foreach ($country as $cnt)
$blacklisted_countries[] = $cnt['id_country'];
// Global country list
$c_todos = Country::getCountries(Context::getContext()->language->id);
// Crossmatching everything
foreach ($c_todos as $c)
$this->fields_value['restricted_countries_'.$c['id_country']] = Tools::getValue('restricted_countries_'.$c['id_country'], (in_array($c['id_country'], $blacklisted_countries)));
}
PS: The table I am reading from is basically an associative table between 'category' and 'country'

Related

Pardot API: Add new prospect to certain list

$prospectData = array(
'user_key' => $user_key,
'api_key' => $api_key,
'first_name' => $firstName,
'last_name' => $lastName,
'city' => $city,
'state' => $state,
'comments' => $comments
);
callPardotApi('https://pi.pardot.com/api/prospect/version/4/do/create/email/'.$email, $prospectData);
I'm able to create a new prospect with a form that I have. It inserts all the data I supplied it (name, city, state, etc), but I need to also add this prospect to a list.
I tried adding to my $prospectData things like list => '1234' or "list_id" => '1234', but that doesn't seem to be working.
Is this possible to do? I know I can assign a prospect to a list via another api route using their ID, but I need this prospect to be added immediately upon form submit
Well it's not exactly ideal, but I had to do a new api call after creating the user.
$addprospect = callPardotApi('https://pi.pardot.com/api/prospect/version/4/do/create/email/'.$email, $prospectData);
$addprospectxml = new SimpleXMLElement($addprospect);
$id = $addprospectxml->prospect->id;
$listData = array(
'user_key' => $user_key,
'api_key' => $api_key,
'list_32106' => "1"
);
$updateProspect = callPardotApi('https://pi.pardot.com/api/prospect/version/4/do/update/id/'.(String)$id[0], $listData);
When creating a prospect, it will return XML with the newly crated prospect's ID. that ID can be used in a new api update call where you can set the list.

Magento API: Set dropdown attribute option for a storeview

I am working with magento API and need to create dropdown options for different storeviews.
I found a function to to create a dropdown option for default storeview:
public function addAttributeOption($arg_attribute, $arg_value)
{
$attribute_model = Mage::getModel('eav/entity_attribute');
$attribute_options_model= Mage::getModel('eav/entity_attribute_source_table');
$attribute_code = $attribute_model->getIdByCode('catalog_product', $arg_attribute);
$attribute = $attribute_model->load($attribute_code);
$attribute_table = $attribute_options_model->setAttribute($attribute);
$options = $attribute_options_model->getAllOptions(false);
$value['option'] = array($arg_value,$arg_value);
$result = array('value' => $value);
$attribute->setData('option',$result);
$attribute->save();
}
This functions works fine, I can add a new attribut value for default storeview.
Example:
I have the attribute "mycolor" and call the function like
addAttributeOption("mycolor", "black")
Now I have a storeview for a german shop and like to set the german color. I would need something like
addAttributeOption("mycolor", "black", "schwarz", $storeview)
Means set the color option of storeview to schwarz where the color of the default value is black.
Does anybody has an Idea how can I do that?
Best regards
I figure you alreay found your solution but perhaps I can help someone else who's new to Magento like I am. Today I had to find a way to import attributes (Product Attributes only that is) from an external Products-Managing-System into Magento running with multiple store views, too. I don't know where the questioner's addAttributeOption function came from but the Magento installer script offers its very own addAttributeOption(). So I took a look into Setup.php where Magento's addAttributeOption() is defined:
{Your Magento Path}/app/code/core/Mage/Eav/Model/Entity/Setup.php
Now, in the Magento Version i'm working with (1.9.1.0) addAttributeOption() expects one argument, an array called $option. It's architecture looks as follows:
Array (
'attribute_id' => '{attributeId}',
'value' => array(
'{optionId}' => array(
'{storeId}' => '{labelName}',
),
),
'delete' => array(
//...
),
'order' => array(
//...
)
);
As you can see, 'value' expects an array and this array's key determines the storeID. In most addAttributeOption()-introductions I found on the web, the storeID is hard coded to 0 with no further explanation - 0 makes it the required default admin value. So, quite obviously by now, for adding Options with StoreView-dependent labels we simply have to add an extra array value for each StoreView like this:
Array (
'attribute_id' => $attribute_id,
'value' => array(
'option1' => array(
'0' => 'black', // required admin value
'1' => 'Schwarz (RAL 9005)', // if storeId = 1 is German
'2' => 'Black (RAL 9005)', // if storeId = 2 is English
),
'option2' => array(
'0' => 'blue',
'1' => 'Blau (RAL 5015)',
'2' => 'Blue (RAL 5015)',
),
// And so on...
)
);
Note: If your option's array-index is a number addAttributeOption() expects it to be the ID-Number of an already existing Option. This is great in case you want to update already existing options but this also means a new Option musn't be numeric. Hence I named them 'option1' & 'option2'.
You can call addAttributeOption() like this:
Mage::app();
$installer = Mage::getResourceModel('catalog/setup','catalog_setup');
$installer->startSetup();
// ...
// generate your Options-Array
// I called it $newOptions
$installer->addAttributeOption($newOptions);
$installer->endSetup();

Remove empty option from listData at CGridView filter

I would like to remove the empty or first option of list data value.
I have Bankaccount model and it has a list, so I need to prevent from users to select all.
I already selected the first one of that list as a default, but now the problem is the empty option that can let user to select all Bankaccount still exist, so how can I remove.
This is my code
array(
'name' => 'bank_account_id',
'type' => 'raw',
'value' => '$data->bankaccount->BankAccountName',
'filter' => Chtml::listData(Bankaccount::model()->findAll(array('order' => 'name DESC')), "id", "BankAccountName"),
),
If you look at this method that generates filter, you will see that it always adds empty option when it gets an array on input. So, the only way to hide empty option is to generate selectbox manually:
'filter' => CHtml::activeDropDownList(Bank::model(), 'bank_account_id',
Chtml::listData(Bankaccount::model()->findAll(array('order' => 'name DESC')), "id", "BankAccountName"),
),
),
Using CHtml::activeDropDownList will give you Bank[bank_account_id] in the selectbox name.
for the filter part,
'filter' => Chtml::dropdownList('Bank[bank_account_id]' , 'selectedDefault',
Chtml::listData(Bankaccount::model()->findAll(array('order' => 'name DESC')), "id", "BankAccountName"),
),
),

Bigcommerce API Tracking Number Create PHP

I am trying to update the tracking number of an order in Bigcommerce using the API. This is the code I am using:
//update BC of order status
$filter = array('status_id' => 2);
$order_status_update = BigCommerce::updateResource('/orders/' . 105, $filter);
$order = Bigcommerce::getOrder(105);
foreach($order->products as $shipment)
{
$filter = array(
'order_address_id' => $shipment->order_address_id,
'items'=> array(
'order_product_id' => $shipment->product_id,
'quantity' => $shipment->quantity
),
'tracking_number' => 'tracking number'
);
$add_tracking = BigCommerce::createResource('/orders/105/shipments', $filter);
var_dump($add_tracking);
}
I have followed the instructions from here:
https://developer.bigcommerce.com/api/stores/v2/orders/shipments#list-shipments
BigCommerce Uploading Tracking Numbers
But I can't seem to get it to work. Can someone help?
In advance, thanks for your help!
Akshay
The payload for creating a shipment is invalid due to the items field needing to be formatted as an object array and the use of the product_id as opposed to the ID of the product within the order.
The code provided is attempting to create one shipment per product in the order, is this intended? Ideally you would ship all items in one shipment, which is why the items field is meant to be an array of product objects.
Additionally, by creating a shipment for an order the order status will automatically change to "Shipped", so the first PUT request is unnecessary.
If you were trying to create a single shipment per order and are assuming no orders will have multiple addresses then this code should work.
$order = Bigcommerce::getOrder(105);
$filter = array(
'order_address_id' => $order->shipping_addresses[0]->id,
'tracking_number' => '123456'
);
foreach($order->products as $product) {
$items[] = array(
'order_product_id' => $product->id,
'quantity' => $product->quantity
);
}
$filter['items'] => $items;
$add_tracking = BigCommerce::createResource('/orders/105/shipments', $filter);
var_dump($add_tracking);

Changing CForm dropdown name attribute in Yii

I'm using Yii and I'm having a little problem with some dropdowns.
Basically I'm using CForm to display some dropdown menus of courses. A student can select up to two courses and for each course choice the student can select a 1st choice and second. It is a requirement that each course choice is inserted separately into the database. For example, it a student wants to study 2 courses and wants to have a 1st and 2nd priority course, they would choose like this:
Course one - 1st Priority
Course one - 2nd Priority
Course two - 1st Priority
Course two - 2nd Priority
This would put 4 new rows into the database. The administrators of the courses want this displayed as 4 dropdown menus containing the courses.
At the moment, I'm testing with just the 1st and 2nd priorities of course one, but the problem is that course one - priority one is always empty unless a value is selected for priority two. Then priority one gets the same value as priority two, even though two different courses are selected. I've been following this tutorial Form Builder as I am using the Wizard Behavior which uses CForm to build the forms.
Here is my code so far, again only dealing with "course one":
This is a snippet of the relevant code from the controller:
// inside controller
$model = new CourseChoice();
$form = new CForm('application.views.wizard.ccForm', $model);
$form['courseOneP1']->model = new CourseChoice();
$form['courseOneP2']->model = new CourseChoice();
$c1p1 = $form['courseOneP1']->model;
$c1p2 = $form['courseOneP2']->model;
// Here I am just reading the attributes and exiting for testing
if ($form->submitted()&& $form->validate()) {
echo '<pre>';
print_r($c1p1->attributes);
print_r($c1p2->attributes);
echo '</pre>';
exit;
..........
And here is code in the form in ccForm
return array(
'showErrorSummary' => true,
'title' => 'Course Choice 1',
'elements' => array(
// Course 1 - 1st Priority
'courseOneP1' => array(
'type' => 'form',
'elements' => array(
'course' => array(
'label' => '1st Priority',
'type' => 'dropdownlist',
'id' => 'c1p1',
'prompt' => 'Select 1st Priority Course',
'items' => CHtml::listData(CoursePeriod::model()->with('course')->findAll("year = 2014"), 'id', 'course.course_name'),
)
),
),
// Course 1 - 2nd Priority
'courseOneP2' => array(
'type' => 'form',
'elements' => array(
'course' => array(
'label' => '2nd Priority',
'type' => 'dropdownlist',
'id' => 'c1p2',
'prompt' => 'Select 2nd Priority Course',
'items' => CHtml::listData(CoursePeriod::model()->with('course')->findAll("year = 2014"), 'id', 'course.course_name'),
)
),
),
),
'buttons' => array(
'previous' => array(
'type' => 'submit',
'label' => 'Previous'
),
'submit' => array(
'type' => 'submit',
'label' => 'Next'
)
)
);
So lets say I choose 2 courses, one with an id of 15 and the other with an id of 86, I get the following when I print_r() both dropdowns:
Array // Dropdown 1
(
[course] => 86
.... // other irrelevant attributes
)
Array // Dropdown 2
(
[course] => 86
.... // other irrelevant attributes
)
Update
I've been looking further into this and when I look at firebug, I see that both dropdowns have the same name:
<div class="row field_course">
<label for="c1p1">1st Priority</label>
<select id="c1p1" name="CourseChoice[course]">
</div>
<div class="row field_course">
<label for="c1p2">2nd Priority</label>
<select id="c1p2" name="CourseChoice[course]">
</div>
So the 2nd menu is overwriting the first. But how can I change this? If I change 'course'=>array(.... in the CForm for either subform, the applicable dropdown does not render. I have already tried adding 'name'=>'course1' in the form but it makes no difference.
Couldn't you just set the name of the 2nd priority input element?
'course' => array(
'label' => '2nd Priority',
'name' => 'course2',
'type' => 'dropdownlist',
'id' => 'c1p2',
'prompt' => 'Select 2nd Priority Course',
'items' => CHtml::listData(CoursePeriod::model()->with('course')->findAll("year = 2014"), 'id', 'course.course_name'),
)
Just to answer my own question and close it as it is pretty old now, CForm does not support tabular input and would need to extended to achieve this. Probably not a big job but in the end I convinced management that the four dropdowns design was horrible. :-) I went with a more flexible design showing a gridview of courses in a pop-up to choose courses instead which works well and is less confusing for the user.
Anyone interested in this issue can see the open issue here. There is a link in there to view a possible implementation of extending CForm, though this was posted at the end of 2009.