Sugarcrm : how to auto-populate field with related fields in QUICKCREATE view? - standards

My configuration :
Sugar Entreprise 6.5.16
What i want to achieve :
When creating a contact by the quickcreate view (ie by clicking on "Create" in the Contact subpanel), i want to bring back any address informations from the related account chosen.
IE : I'm in my dashlet "My Contacts" on my home, i want to edit a contact. Sugar opens the popup, and i change the Account related to the contact. I chose, ie Microsoft. So, now that this account is chosen, i want Sugar to auto-fill the contact's address fields with the related account's address information.
What i've tested :
I saw this one :
How to autopopulate a field in SugarCRM form
and johndope's blog article (which is reaaaally helpful)
http://johndopenotes.wordpress.com/2013/03/18/sugarcrm-populating-fields-using-a-relate-field/
So i've created my SugarRoot/custom/Extension/modules/Contacts/Ext/Vardefs/sugarfield_account_name.php
and added this :
$dictionary['Contacts']['fields']['account_name']['populate_list'] = array('id','name','Accounts');
$dictionary['Contacts']['fields']['account_name']['field_list'] = array('account_id','account_name','primary_address_street');
And then, i edited my SugarRoot/custom/modules/Contacts/metadata/quickcreatedefs.php
and added this :
array (
'name' => 'account_name',
'displayParams' =>
array (
'key' => 'billing',
'copy' => 'primary',
'billingKey' => 'primary',
'additionalFields' =>
array (
'phone_office' => 'phone_work',
),
),
),
After a quick Rebuild and Repair, i've tested it, and nothing is happening.
I have to say that i've already done the exactly same thing for editviewdefs.php and it works...
So please, help me with this! :)

Recommendation from https://community.sugarcrm.com/sugarcrm/topics/auto_fill_related_field_from_parent_module_to_child_module
Example for Companies. Try adapt this code for your needs.
In custom/modules//views/view.quickcreate.php
Extend ViewQuickCreate class to set the corresponding $_REQUEST variable in preDisplay.
Remember that this is used by the + at the top right as well in case you have Contracts there so check that there is a parent and that it's a Company first.
class ContractViewQuickcreate extends ViewQuickcreate
function preDisplay(){
parent::preDisplay();
if (isset($_REQUEST['parent_id']) && $_REQUEST['parent_id'] != '' && isset($_REQUEST['parent_type']) && $_REQUEST['parent_type'] == 'Companies'){
$comp = new Company();
$comp->retrieve($_REQUEST['parent_id']);
//say the fields are company_id and company_name in Companies
//and company_id_c and company_name_c in Contracts
//assuming company is a relate field you'll need to map both
$_REQUEST['company_id_c'] = $comp->company_id;
$_REQUEST['company_name_c'] = $comp->company_name;
}
}
}

Related

Drupal - Importing a taxonomy with migrate module from a table and creating/updating existing terms

I need to import a list of terms into my taxonomy from a source I loaded in the database.
The problem is I allready have this taxonomy on my site (loaded wihtout migrate) with terms that are used by reference in other content, so I got to keep existing term and update them or create the new ones.
To link my taxonomy source and the existing taxonomy I have an unique code for each term, so I added a code field to my vocabulary and filled it for each existing term.
I am currently able to create and update terms with my current Migration class, but if the name of my term on the site and the name of the term in my source is different, the import will create a new term instead of updating its name even if the code is the same.
Here my Migration Class :
class TotoMigration extends Migration {
private $list_term = array();
public function __construct($arguments) {
parent::__construct();
$this->softDependencies = array('TotoParent');
// get data from the custom table containing the new terms to create or update
$query = db_select('toto', 'f')
->fields('f', array(
'CODE', // code
'LIBLONG', // name
'PARENT', // parent
)
);
$this->source = new MigrateSourceSQL($query);
$this->destination = new MigrateDestinationTerm('toto_tax');
$this->map = new MigrateSQLMap($this->machineName,
array(
'CODE' => array('type' => 'varchar',
'length' => 5,
'not null' => TRUE,
'description' => 'Code',
)
),
MigrateDestinationTerm::getKeySchema()
);
$this->addFieldMapping('name', 'LIBLONG');
$this->addFieldMapping('field_code', 'CODE');
$this->addFieldMapping('parent', 'PARENT')
->arguments(array('source_type' => 'tid'))
->sourceMigration('TotoParent');
// create a list of existing toto terms with code => tid
$list_term = db_query("select fc.field_code_value, ttd.tid
from taxonomy_term_data ttd
left join taxonomy_term_hierarchy tth on tth.tid=ttd.tid
left join field_data_field_code fc on fc.entity_id = ttd.tid
where ttd.vid=10
and tth.parent!=0;")->fetchAllKeyed();
}
public function prepareRow($row) {
// Always include this fragment at the beginning of every prepareRow()
// implementation, so parent classes can ignore rows.
if (parent::prepareRow($row) === FALSE) {
return FALSE;
}
// if the destination is not mapped in migrate we tell him where to go
if (!isset($row->migrate_map_destid1) && isset($list_term[$row->CODE])) {
$row->migrate_map_destid1 = $list_term[$row->CODE];
}
}
}
I then load the import with drush (and --update option).
I must be missing something, if anyone got a clue it will be welcome.
After many tries, the problem reside in the fact the module Migrate does not support Creating content and Updating content in the same migration class (I even read it will sometime claim to update content and just do nothing).
So the solution is pretty simple, create 2 classes :
One for Creating content
One for Updating content
Your Creating class will be the same.
Your Updating class will need to have a systemeOfRecord set to DESTINATION :
$this->systemOfRecord = Migration::DESTINATION;
So it knows to only update and not recreate the content, it will keep current fields not mapped and update fields mapped that are not part of the MigrateSQLMap :
$this->map = new MigrateSQLMap($this->machineName,array(...));
The tricky part will be to find corresponding nid/tid of your content so you can map it to your imported data and then to separate data used to update or create content.

Prestashop: disable add-to-cart button depending on user group and product

I use Prestashop 1.6.2 and I have a problem trying to add this function.
I am a little bit new trying to mod prestashop, the thing is that I have some products that can be bought only for professionals. Everytime a user registers it's assigned to a user group (professional and no-professional).
I know I can hide the categories for specific user groups, but this method is not perfect, due to if they know the name of the product or search it, they can still access the product page and buy it.
Is there any smarty variable to edit the product.tpl so it displays the button with the conditions above? Or a module or another way to do this?
I don't know exactly is there is a variable already set in smarty or not, but your can define your customer variable with object of customer:
Find controllers/front/ProductController.php file, find method assignPriceAndTax and in the end of it you will find something similar to this:
$this->context->smarty->assign(array(
'quantity_discounts' => $this->formatQuantityDiscounts($quantity_discounts, $product_price, (float)$tax, $ecotax_tax_amount),
'ecotax_tax_inc' => $ecotax_tax_amount,
'ecotax_tax_exc' => Tools::ps_round($this->product->ecotax, 2),
'ecotaxTax_rate' => $ecotax_rate,
'productPriceWithoutEcoTax' => (float)$product_price_without_eco_tax,
'group_reduction' => $group_reduction,
'no_tax' => Tax::excludeTaxeOption() || !$this->product->getTaxesRate($address),
'ecotax' => (!count($this->errors) && $this->product->ecotax > 0 ? Tools::convertPrice((float)$this->product->ecotax) : 0),
'tax_enabled' => Configuration::get('PS_TAX') && !Configuration::get('AEUC_LABEL_TAX_INC_EXC'),
'customer_group_without_tax' => Group::getPriceDisplayMethod($this->context->customer->id_default_group),
));
Add to this array
'customer_object' => $this->context->customer,
This variable you can use on the product page.
You can use the same way to close those buttons for all 'buy-windows' on your site.

Symfony2 get validation message

I have a few validation messages in the file validators.en.yml:
soporte.nombre.not_blank: The name cannot be empty
soporte.price.is_integer: The price should be integer
soporte.not_repeat: soporte cannot be repeat
I valid making a query to the database:
$validarPorNombreAndTipo = $this->crud->findOneBy(
$soporte, array('nombre' => $soporte->getNombre(),
'tipo' => $object->tipo
)
);
if ($validarPorNombreAndTipo){
$error= //here i need to get soporte.not_repeat that is on file validators.en.yml;
}
excuse me for my bad English, I used the translator.
If you just want to get the translation, this code should work :
$validarPorNombreAndTipo = $this->crud->findOneBy(
$soporte, array('nombre' => $soporte->getNombre(),
'tipo' => $object->tipo
)
);
if ($validarPorNombreAndTipo){
$error= $this->get('translator')->trans('soporte.not_repeat', array(), 'validators');
// Third param is the translation domain (first part of the translation file)
}
However, i suggest you to read this : http://symfony.com/doc/2.3/cookbook/validation/custom_constraint.html
If you want to follow Symfony best practices, you should create a custom constraint class/Validator and move your validation logic into it.
Best regards

One to one relationship in Silverstripe

I'll try and put this as simply as possible but basically what I am trying to achieve is this.
There are two page types with a one to one relationship, car and owner. I want to be able te be able to select an owner through a dropdown on the car page. If an owner is already linked to another car I don't want it to appear in the dropdown.
I know that I'll need an if statement but I I'm finding it hard to puzzle out how it should go. I followed this tutorial to create the dropdown and it worked quite well.
Thanks in advance.
You can modify the function that gives you the dropdown values. Your DataObject::get() call
can have a filter for the second argument. Simply select all owners that have a CarID of 0.
So, from the tutorial you provided, you can use this modified code:
new DropdownField(
'OwnerID',
'Please choose an owner',
Dataobject::get("Owner","CarID='0'")->map("ID", "Title", "Please Select")
);
2 things to note:
This assumes your DataObjects are called Car and Owner (change as necessary, but keep the ID at the end of the name as it is written above)
This may not work depending how you set up the relationships with the $has_one assignments on your DataObjects. If there is no CarID field on the Owner table, then this code won't help you (you may have it set up vice-versa). In that case, you'll have to create a function that loops through all cars, and then removes the DataObjects from that DataObjectSet that have an OwnerID of 0. Add a comment if this isn't making sense.
Benjamin Smith' answer is perfectly valid for the dropdown you were asking for, just wanted to point to another approach: instead of taking care of the one-to-one relation yourself, there's the 'HasOneComplexTableField' handling this for you.
use the following code for your Car class:
class Car extends Page {
public static $has_one = array(
'Owner' => 'Owner'
);
function getCMSFields() {
$fields = parent::getCMSFields();
$tablefield = new HasOneComplexTableField(
$this,
'Owner',
'Owner',
array(
'Title' => 'Title'
)
);
$tablefield->setParentClass('Car');
$tablefield->setOneToOne();
$tablefield->setPermissions(array());
$fields->addFieldToTab('Root.Content.Owner', $tablefield);
return $fields;
}
}
note the 'setOneToOne()' call, telling the tablefield to only let you select Owners which aren't already selected on another car.
you'll find more information on this in the silverstripe tutorial: http://doc.silverstripe.org/framework/en/tutorials/5-dataobject-relationship-management

Setting a drupal view to a random page number

I have views 2 installed and I have created a view that is displayed in the front page.
The view displays some page links ( 1 | 2 | 3 | 4 | ... etc). I want to know if it's possible to make the view start at a random page instead of always starting at page 1.
Note: I don't want to randomize the display I really just want to randomize the page it loads.
Thanks
Possible Solution:
In the views_pre_execute hook I used this:
$view->query->pager->set_current_page([random value]);
I am not sure I can determine the number of total pages in the pager at this time but I am going to keep investigating (The $view object given in the hook has tons of properties with arrays and other objects which makes this complicated)
I do not know how to do this from the Views UI, but you should be able to achieve this using one of the views module hooks, in this case probably hook_views_pre_execute. Unfortunately, the documentation for these is practically non existing, so you'd need to implement the hook in a custom module and inspect the passed in view object via the debugger (or print, var_dump, etc. statements).
You should look for $view->pager['current_page'], which you can set to a random page. Unfortunately, if I read the code correctly, the count query that determines the possible number of pages is not yet run at this point, so you'll either have to use a 'best guess', or come up with a different way to determine the proper range to select from...
NOTE: This is in no way meant as an 'authoritative' answer - just a pointer where I'd start looking, since nobody else has answered this so far. I might well be missing a more obvious/easy solution :/
Another option would be to randomize the entries in your views. So your page would always be page 1 but it achieves your objective of seeing something different every time come on your site.
In your sort criteria (in the Global Group) add
Global: Random -- Randomize the display order.
(Inspired by suggestion at http://mydrupal.com/random_node_or_front_page_in_drupal_like_stumbleupon )
I have just created a custom pager that goes automatically to last page and I think it is related to what your are trying to do :
In project.info :
files[] = plugins/views_plugin_pager_last.inc
In project.module :
function cvoxm_views_plugins(){
return array(
'pager' => array(
'last' => array(
'title' => t('Paged output, full pager and last by default'),
'short title' => t('Full & Last'),
'help' => t('Paged output, full Drupal style and last by default'),
'handler' => 'views_plugin_pager_last',
'help topic' => 'pager-last',
'uses options' => TRUE,
),
)
);
}
And the content of plugins/views_plugin_pager_last.inc is :
class views_plugin_pager_last extends views_plugin_pager_full {
function pre_execute(&$query) {
if(!isset($_GET['page'])){ // TODO: Should use pager_id
// Go to last page
$this->set_current_page($this->get_total_items() / $this->get_items_per_page() - 1 );
$this->query(); // Rebuild query
$this->update_page_info(); // Update info
}
}
}

Resources