Add table name to each select field in query, in agile tookit - atk4

I have a problem with certain generated query, the query does an inner join with a table that has some same field.
How can I have the query with the table name in each field, basically what i want is that:
Convert this:
select "list_id", "date_time","plate"...
TO:
select register."list_id", register."date_time",register."plate"...
I think with alias to the field name also could be accomplished but i dont know how to add the alias in atk4
If someone wants to see the full query and atk error:
Application Error: Database Query Failed
Exception_DB, code: 0
Additional information:
pdo_error: SQLSTATE[42702]: Ambiguous column: 7 ERROR: column reference "date_time" is ambiguous LINE 1: select "date_time","plate",(select "name" from "lane" whe... ^
mode: select
params:
query: select "date_time","plate",(select "name" from "lane" where "register"."lane_id" = "lane"."id" ) "lane",(select "name" from "camera" where "register"."camera_id" = "camera"."id" ) "camera",(select "detail"."id" from "detail" where "register"."detail_id" = "detail"."id" ) "detail","id","lane_id","camera_id","detail_id" from "register" inner join "detail" on "detail"."id" = "register"."detail_id" order by (select "detail"."id" from "detail" where "register"."detail_id" = "detail"."id" )
This is how im making the model. This model has 3 related fields in other tables, with those, all is OK. But i want to have one more field (field name from table List), and List is not directly related to Register, is only related throught Detail. So i have to get it throught Register->Detail->List..
table Register(id, plate, detail_id,..)---->hasOne(detail_id)-->table Detail(id, list_id, date..)---->hasOne(list_id)---->table List(id,name,..)
model class:
class Model_Register extends Model_Table {
public $table='register';
function init(){
parent::init();
$this->addField('date_time')->sortable(true)->defaultValue(date('Y-m-d H:m:i'))->type('date')->mandatory(true);
$this->addField('plate')->sortable(true)->mandatory(true);
$this->hasOne('Lane', 'lane_id')->sortable(true)->system(true);
$this->hasOne('Camera', 'camera_id')->sortable(true);
$this->hasOne('Detail', 'detail_id')->sortable(true);
}
}
And after in the page class i do the join, yes I know is detail at this moment is redudant im only trying...
$register = $crud->setModel('Register');
$q = $register->_dsql();
$q->join('detail', 'detail_id', 'inner');
$q->join('list', 'list_id', 'inner');
How can I have this field from the List field?? Any solution will be welcomed..
Thanks in advice!! Im breaking my head with this! ;)

Thanks for your time guys, finally I found the solution with the called: Chained joins
Example from documentation:
$perm = $this->join('permission');
$res = $perm->join('resource');
Belive or not that was my real problem! Thanks all anyway

try to add 'table_alias' property for your Models
class Model_Yours extends Model_Table {
public $table_alias = '_alias';
}
Default value for this property is null - link
So if you add any value it can be used here
Not sure if this will help :(
$t1 = $this->add('Main_Table');
$t2 = $t1->leftJoin('joined_table_name');
$t2->addField('joined_table_field_ALIAS','joined_table_field_REALNAME');
check SQL_Model::addField() method here

Related

odoo iterate over all product

I wanted to iterate over all products and calculate list_price from another field.
this is the code that I wrote:
class AedPriceCalculator(models.TransientModel):
_name = "aed.pricecalculator"
_inherit = ['product.template']
aed_current_price = fields.Monetary('current AED price in IRR', required=True, translate=True)
currency_id = fields.Many2one(
'res.currency', 'Currency',default=lambda self: self.env['res.currency'].search([('name', '=', 'AED')]).id,readonly=True)
#api.multi
def price_calculate_ae(self):
products = self.env['product.template'].search(['sale_ok', '=' ,True])
for product in products:
if product.amount_in_aed:
product.list_price = self.aed_current_price * product.amount_in_aed
else:
pass
but when I call the related button.
this error will appear:
The operation cannot be completed:
- Create/update: a mandatory field is not set.
- Delete: another model requires the record being deleted. If possible, archive it instead.
Model: aed.pricecalculator (aed.pricecalculator), Field: Name(name)
aed.pricecalculator model inherit from product.template and the name field is required in product template (copied as-is).
When you click on the button and call price_calculate_ae method, Odoo will try to call the create method without providing a value for name field and that's why you see this error message.
You don't need to inherit product.template to iterate over all products and calculate list_price

Creating an array of SelectOption Lists

Im trying to set up an online test, using a visualforce page that pulls data from 3 objects in salesforce COPE_Tests__C, COPE_Questions__C, and COPE_Options__c. Once the user selects the specific test, I thought I would be able to make a call like this to get all the other data:
questions = [select id, name, question_body__c,
(select id, name, option_body__c from COPE_options__r order by name ASC)
from COPE_questions__c where COPE_test__c = :tid];
And then use apex:repeat and apex:selectRadio/apex:selectOption to generate the actual test form. But for some reason it would not render the radioboxes. So it would seem I need to create selectOption lists and then use apex:selectOptions. But im not sure how to set this up . How can I have it create a public list<selectOption> automatically for each question?
Is there a way to set up an array of list<selectOption>?
I don't know about creating it automatically but going over your question object in a loop should be pretty easy, something over the lines of
List<List<SelectOption> options = new List<List<SelectOption>;
for(COPE_Questions__C q : questions){
List<SelectOption> list = new List<SelectOption>();
for(COPE_options__r op : q.COPE_options__r){
list.add(new SelectOption(op.id, op.option_body__c);
}
options.add(list);
}
Hope it helps.

Still stuck in update row cakephp

I have posted a question and got help but I still dont make it.
Im trying to update a row in cakePHP 2.3.1.I have class Test extend AppModel with $validates array, and the Controller( simplified ) :
public function editstudent() {
if($this->request->data) {
$this->Test->stuId= $this->data['Test']['stuId'];
if ($this->Test->save($this->request->data)) {
$this->set('state',1);
}
}
My view after edit with suggestion from a user :D :
class Test extends AppModel {
var $name= 'Test';
var $primaryKey= 'stuId';
public $validate= array(.......);
}
I've set $primaryKey in View,set $this->Test->$primaryKey in controller but still got the error :
Database Error Error: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'PRIMARY' SQL Query: INSERT INTO cakePhp.tests (stuName, stuDoB, stuAdd) VALUES ('Đào Đức Anh', '2013-03-25', 'Kim Liên')
Can anyone help me out,I really need help,I'm stuck at this for 2 day and cant figure it out :(
I think you have to change the following line
$this->Test->stuId = $this->data['Test']['stuId'];
to
$this->Test->id = $this->data['Test']['stuId'];
because it is the id property that contains the primary key value.
Quick attempt:
Try changing $this->data to $this->request->data in your controller code.
More things:
Bottom line, your primary key isn't getting set.
Try using (per the CakePHP book) this syntax:
public $primaryKey = 'stuId'; //notice "public" instead of "var"
check to find out why 'studId' isn't in the data being saved.
debug($this->request->data);
My assumption is, it's not in the request data - if it were, you'd be fine.
add the studId into the form that's being submitted or
get theID into the request data any other way you see fit
Side note:
you keep saying "view", but you really mean "model".
Add Your primary key in AppModel.php
public $primaryKey='username';

MVCGrid w/Expander (parent) invoking an MVC Form(child) and loading child record - UPDATED

My multi-level MVCGrid/MVCForm/MVCGrid saga continues....
I am using nested MVCGrids with expander buttons that invoke MVCForms to perform different data operations. ALL mySQL tables in this process have an "id" data element and that is the primary key for each table. Each mySQL table also has a point to its parent when necessary using _id naming convention. All of the foreign-keys have been setup in mySQL to work this way as well.
The model for the parent is like this:
class Model_uidcontrol extends Model_Table {
public $entity_code='uidcontrol';
public $table_alias='uc';
function init(){
parent::init();
The model for the child is like this:
class Model_uiddetails extends Model_Table {
public $entity_code='uiddetails';
public $table_alias='ud';
function init(){
parent::init();
Each model has its own "id" and a pointer to its parent.
The expander column in the MVCGrid (parent) invokes this child function:
$um=$this->add('MVCForm');
$um->setModel('uiddetails')
->loadData(($_GET['uidcontrol_id']));
I have tried this in the child model:
$this->addRelatedEntity('uc','uidcontrol','uidcontrol_ID');
and this as well:
$this->addField('uidcontrol_id')
->refModel('Model_uidcontrol')
->caption('System Info')
->visible(true);
I've tried each technique separately and together to get child records to be coordinated with the proper parent.
debug() shows this
where
ud.id = '121'
ud.uidcontrol_id = '121'
OK, I understand the $GET and how it works and how that relates to dsql - at least I think I do.
What I can't figure out is how to tell MVCForm to use "ud.uidcontrol_id = '121 " that come
via the $GET when building the dsql for data loading and not use 'ud.id'
In the above example, there is a parent record "uidcontrol" with that id. I forced the 'id' of the child record to be 121 to see if it would pull data and display it in the form. OK, data displays as it should.
When I try this parent whose 'id' = 10, debug() produces this
ud.id = '10'
ud.uidcontrol_id = '10'
and no data is returned. There is a uidcontrol record with id = 10 but the dsql is trying to match to ud.id = 10 as well.
I can post more of what I am working to clarify what I am trying to do if that helps.
Ideally, I would like to tell MVCForm "Hey! Don't use the 'id' data element when building the dsql, use the one I am supplying instead. Problem is, I can't figure out how to do that... but I've learned a bunch along the way. Me thinks that I am probably "over thinking" something here.
Thanks for any suggestions!
Monday Feb 6th Notes:
var_dump($_GET); says:
'id' => string '10' (length=2) <=== uidcontrol.id
'uidcontrol_id' => string '10' (length=2) <=== uidcontrol.id
I write this:
$um->setModel('uiddetails')
->addCondition('uidcontrol_id',($_GET['id']))
->loadData(($_GET['id']));
And the SQL debug shows this being built:
where
ud.id = '10'
ud.uidcontrol_id = '10'
The issue is that I want ONLY " ud.uidcontrol_id = '10' ". Table uiddetails has its own id of 125 and a uidcontrol_id value of 10. As a result of that, the query doesn't return a record.
The loadData method only loads records by their id. To link the "child" model through his referenced record you must use setMasterField or addCondition to instruct the model to filter on the relationship.

Loading a Child (Navigation Property) Entity not working

I am having a very tough time with this one. I have a Navigation property called Attachment that is part of an entity called ContentChannel. ContentChannel is a many to one relationship with KioskType.
In my domain service extension class, I have the following query:
public IQueryable<ContentChannel> GetContentChannelFromKioskType( long kioskTypeID )
{
var returnSet = (from cc in ObjectContext.ContentChannels.Include( "Attachment" )
join pcc in ObjectContext.PublishedContentChannels on cc.ContentChannelID equals pcc.ContentChannelID
where pcc.KioskTypeID == kioskTypeID
select cc);
return returnSet;
}
And this works just fine for returning the list of ContentChannels. But the Attachment in each ContentChannel is null.
I have tried [Include] on the attachment property in my ContentChannel metadata class, in conjuction with ContentChannels.Include("Attachment") in the above query- no luck, Attachment is always null.
I dug more and then found something to explicitly load my child item:
ObjectContext.LoadProperty( returnSet, "Attachment" );
But this generates the following error:
Cannot explicitly load property for entities that are detached. Objects loaded using the NoTracking merge option are always detached.
Is it because I'm doing a join that things are wonky and the Include doesnt work? What do I need to do? These attachments need to get loaded when I get a ContentChannel!
Any thoughts?
By including the join in your query, you've changed the shape of the query, after the Include. So the Include is discarded. But you don't need the join:
public IQueryable<ContentChannel> GetContentChannelFromKioskType( long kioskTypeID )
{
var returnSet = (from cc in ObjectContext.ContentChannels.Include( "Attachment" )
where cc.PublishedContentChannels.Any(pcc => pcc.KioskTypeID == kioskTypeID)
select cc);
return returnSet;
}

Resources