update One2many Record using Write function called from Onchange (Odoo10) - eclipse

I am trying to update my One2many record when Onchange method is called. I am fetching the exact value but its not updating the field. Neither I am getting any error.
class abc_1(models.Model):
_name = 'abc.1'
field_a1 = fields.Many2one('crm.team',required=True)
field_a2 = fields.One2many('abc.2', 'field_b1')
#api.onchange('field_a1')
#api.depends('field_a1')
def get_records(self):
for res in self.field_a1.member_ids:
print res.name
self.write({'field_a2':(0,0,'field_b2':res.name})]})
class abc_2(models.Model):
_name = 'abc.2'
field_b1 = fields.Many2one("abc.1")
field_b2 = fields.Char(string='Sales Person')
I am trying to update records fetched but its not doing anything.

First #api.depends trigger onchange event so you don't need
#api.onchange.
Second don't update the database in onchange event because you will commit
changes to the database what if the user click on cancel button the changes
all ready saved in database.
Third if this code works your querying a lot the database, because any call to write will execute update in database. don't query the database inside a loop only if there is no other solution
Four self.write do not work in #api.onchange because the self is not the record is not the real record it's just a dummy record that holds the data passed from
the client side you can check the id you find is always NewID object even if the record is saved in database. usually you find the real record in self._origin (in new API, or list of ids in old API) in
this you can call write and change the values in database a danger thing to do.
#api.depends('field_a1')
def get_records(self):
# when you use depends, best thing you do is to loop so won't get
# singleton error
for rec in self
# create a list to hold the cammands to create the records
res_ids = []
for res in self.field_a1.member_ids:
# now just add the cammand to the list
res_ids.append((0,0,{
'field_b2':res.name,
})
# if you will affect only one element just
# but if more use rec.update() works like rec.write()
# but with onchange it don't save data in database.
rec.field_a2 = res_ids

Related

How can i declear a function/method in one time but use this multiple query Laravel

This is my users table
1.id
2.name
3......
My branches table
1.id
2.branch_name
3....
members table
1.id
2.branch_id
3.user_id
4.member_name
5......
One Pivot table name branch-users
1.id
2.user_id
3.branch_id
permitted branch id of an user store in this branch_user pivot table, when this user entry any member he can only see his assign branch list in <select></select> field or if want to see the member list. he can only see his assign branch member list.I have implement this such query in Laravel controller
My index method section
public function index(){
$my = Auth::user()->branches;// branches is a many to many relation method in user model
foreach($my as $my){
$myBranch[] = $my->id;
}
$member = Member::whereIn('branch_id',$myBranch)->get();
return view('member.create',compact('member'))
}
My create method section
public function create(){
// i have to check every where this section...from.......
$my = Auth::user()->branches;
foreach($my as $my){
$myBranch[] = $my->id;
}
//.......to here
$branch = Branch::whereIn('id',$myBranch)->get();
return view('member.create',compact('branch'))
}
My problem is that i want to use this ::whereIn('branch_id',$myBranch)->.... where condition to display branch list and branch member list, everywhere i have to declare and check user assign branch list that is not good in Laravel framework , i know there have thus opportunities where i can declare any function one time and possible to use that function/method/variable multiple time. i want to check, one time authenticated user assign branch id and use multiple time where i need. but unfortunately i don't understand how can i do that. If any body understand what i have tried to say ,please help me.
You probably want to write yourself a local scope query. You put part of the query logic on the model, then you can call it anywhere you are trying to query that model.
https://laravel.com/docs/5.7/eloquent#local-scopes

Apex Trigger on Case Object

I was trying out a simple trigger on Case Object.There is a field Hiring_Manager__c (looks up to User) in Case .On update or insert of a case, this field has to be populated with the Case Owner's Manager.I created the trigger as follows.It is not bulkified as I was just trying out for a single record.
I could see the value getting populated correctly in debug statements.But it is not updated on the record.
trigger HiringManagerupdate_case on Case (before insert,before update) {
Case updatedCaseRec= [select id,ownerId,Hiring_Manager__c,CaseNumber from case where id in :Trigger.new];
system.debug('Case Number'+updatedCaseRec.CaseNumber);
system.debug('Manager before updation'+updatedCaseRec.Hiring_Manager__c);
try{
User caseOwner = [Select Id,Name, ManagerId, Manager.Email From User Where Id = :updatedCaseRec.ownerId];
updatedCaseRec.Hiring_Manager__c=caseOwner.ManagerId;
}
Catch(DMLException de){
system.debug('Could not find Manager');
}
system.debug('Manager'+updatedCaseRec.Hiring_Manager__c);
}
I got a reply for this in developer's forum with a code that works fine.
trigger HiringManagerupdate_case on Case (before insert,before update) {
for(Case cas :Trigger.new){
try{
User caseOwner = [Select Id,Name, ManagerId, Manager.Email From User Where Id = :cas.ownerId];
cas.Hiring_Manager__c=caseOwner.ManagerId;
}
Catch(DMLException de){
system.debug('Could not find Manager');
}
system.debug('Manager'+cas.Hiring_Manager__c);
}
I would like to know
1)Difference in logic in both the approaches if I am trying to update only a single record?Mine is populating the value in debug statement but not on screen.
2)Will the select statement inside the loop (of second approach)affect governor limit?
3)Do we need to explicitly call update for before triggers? My understanding is the save and commit happens after the field update for before triggers and hence the changes will be saved automatically without calling update statement.?
Thank in advance.
Nisha
1) If you are trying to access the record(s) for the object which fired a before trigger, you must iterate over Trigger.new. You cannot query for it because the record(s) may not be in the database yet.
2) Yes it could. The query executes for every Case record being inserted or updated. If you have 1,000 such Cases, the query executes a 1,000 times.
3) No, we do not need to call update for before triggers. Your understanding is correct.

How to save one value of Parse object without overwriting entire object?

I have two users accessing the same object. If userA saves without first fetching the object to refresh their version, data that userB has already successfully saved would be overwritten. Is there any way(perhaps cloud code?) to access and update one, and only one, data value of a PFObject?
I was thinking about pushing the save out to the cloud, refreshing the object once it gets there, updating the value in the cloud, and then saving it back. However that's a pain and still not without it's faults.
This seems easy enough, but to me was more difficult than it should have been. Intuitively, you should be able to filter out the fields you don't want in beforeSave. Indeed, this was the advice given in several posts on Parse.com. In my experience though, it would actually treat the filtering as deletions.
My goal was a bit different - I was trying to filter out a few fields and not only save a few fields, but translating to your context, you could try querying the existing matching record, and override the new object. You can't abort via response.failure(), and I don't know what would happen if you immediately save the existing record with the field of interest and null out the request.object property - you could experiment on your own with that:
Parse.Cloud.beforeSave("Foo", function(request, response) {
// check for master key if client is not end user etc (and option you may not need)
if (!request.master) {
var query = new Parse.Query("Foo");
query.get(request.object.id).then(function(existing) {
exiting.set("some_field", request.object.get("some_field"));
request.object = exiting; // haven't tried this, otherwise, set all fields from existing to new
response.success();
}, function(error) {
response.success();
});
}
});

How to programmatically refresh a screen from onFinished callback function?

e.g. we have this one guy calling server function for creating a new entity:
function loadData() {
var vServerController = mobileController.serverController();
var vJSONRequest = vServerController.createJSONRPCRequest();
vJSONRequest.setQueryMethod("createSomeNewElementBasedOnTwoIds");
vJSONRequest.addParameter("firstID", 1);
vJSONRequest.addParameter("secondID", 2);
vJSONRequest.setOnFinish(callBackOnFinish);
vServerController.addToQueue(vJSONRequest);
}
function callBackOnFinish() {
var vController = mobileController.activeController();
vController.showView(Screens.SomeScreen, true);
}
So how we can refresh a Screen after this call? The server will return not a full set of data but just a new one.
What is the best approach to doing this?
Assuming you want to update the currently displayed data, you have two options - and you propably don't need to use a callback for this
Replace the displayed dataset
Update the displayed record
(if you had user input or created a new entry) merge the entries
1: just return the data from the server with foundset.setDataMode(DataMode.REPLACE) - it will automatically refresh the displayed data. But In case you are working with multiple records for one entity and you only want to update one of them, use option 2.
2: Return only the specific record you want to update without datamode replace. The record is identified by it's key/id elements. You can find those marked with a little key symbol in the entity editor. So just make sure that those key elments and any additionaly elements you want are returned. The AppConKit will automatically merge the existing record with the data and display that.
3: If you created a new record on the device, that record will have a value called client_uuid. If you now return a record from the server that contains both the client_uuid AND the key element, the record created on the device will be merged with the server created record and the new record will displayed
Hope this helps!

atk4.2 form submit-how to get new record id before insert to pass in arguments

I am referencing the 2 step newsletter example at http://agiletoolkit.org/codepad/newsletter. I modified the example into a 4 step process. The following page class is step 1, and it works to insert a new record and get the new record id. The problem is I don't want to insert this record into the database until the final step. I am not sure how to retrieve this id without using the save() function. Any ideas would be helpful.
class page_Ssp_Step1 extends Page {
function init(){
parent::init();
$p=$this;
$m=$p->add(Model_Publishers);
$form=$p->add('Form');
$form->setModel($m);
$form->addSubmit();
if($form->isSubmitted()){
$m->save();//inserts new record into db.
$new_id=$m->get('id');//gets id of new record
$this->api->memorize('new_id',$new_id);//carries id across pages
$this->js()->atk4_load($this->api->url('./Step2'))->execute();
}
}
}
There are several ways you could do this, either using atk4 functionality, mysql transactions or as a part of the design of your application.
1) Manage the id column yourself
I assume you are using an auto increment column in MySQL so one option would be to not make this auto increment but use a sequence and select the next value and save this in your memorize statement and add it in the model as a defaultValue using ->defaultValue($this->api->recall('new_id')
2) Turn off autocommit and create a transaction around the inserts
I'm from an oracle background rather than MySQL but MySQL also allows you to wrap several statements in a transaction which either saves everything or rollsback so this would also be an option if you can create a transaction, then you might still be able to save but only a complete transaction populating several tables would be committed if all steps complete.
In atk 4.1, the DBlite/mysql.php class contains some functions for transaction support but the documentation on agiletoolkit.org is incomplete and it's unclear how you change the dbConnect being used as currently you connect to a database in lib/Frontend.php using $this->dbConnect() but there is no option to pass a parameter.
It looks like you may be able to do the needed transaction commands using this at the start of the first page
$this->api->db->query('SET AUTOCOMMIT=0');
$this->api->db->query('START TRANSACTION');
then do inserts in various pages as needed. Note that everything done will be contained in a transaccion so if the user doesnt complete the process, nothing will be saved.
On the last insert,
$this->api->db->query('COMMIT');
Then if you want to, turn back on autocommit so each SQL statement is committed
$this->api->db->query('SET AUTOCOMMIT=1');
I havent tried this but hopefully that helps.
3) use beforeInsert or afterInsert
You can also look at overriding the beforeInsert function on your model which has an array of the data but I think if your id is an auto increment column, it won't have a value until the afterInsert function which has a parameter of the Id inserted.
4) use a status to indicate complete record
Finally you could use a status column on your record to indicate it is only at the first stage and this only gets updated to a complete status when the final stage is completed. Then you can have a housekeeping job that runs at intervals to remove records that didn't complete all stages. Any grid or crud where you display these records would be limited with AddCondition('status','C') in the model or added in the page so that incomplete ones never get shown.
5) Manage the transaction as non sql
As suggested by Romans, you could store the result of the form processing in session variables instead of directly into the database and then use a SQL to insert it once the last step is completed.