I have a field amount on the Journal Entries (account move form) and I need to define an onChange event which automatically inserts the lines once I fill in the amount. But I am not sure how.
Yesterday I had to do something similar to your requirement. I had a salo order(m2o) field in purchase ...on_change of sale_order I had to fill the purchase order lines ...see hope it can help you.
class purchase_order(osv.osv):
_inherit = 'purchase.order'
_columns = {
'sale_order':fields.many2one('sale.order','Sale Order'),
'purchase_type':
fields.selection([
('order','Purchase Order'),
('job','Job Order')
],
'Purchase Type',
required=True,
states={
'confirmed':[('readonly',True)],
'approved':[('readonly',True)],
},
select=True,
help="Define type of purchase order.",
),
}
def onchange_saleorder(self,cr,uid,ids,order,context=None):
res={}
lis=[]
sorder_id=self.pool.get('sale.order').browse(cr,uid,order)
for line in sorder_id.order_line:
print "uom",line.product_id.uom_id.id
res={'product_id':line.product_id.id,
'name':line.product_id.name,
'product_qty':1,
'product_uom':line.product_id.uom_id.id,
'price_unit':line.price_unit,
'date_planned':time.strftime('%Y-%m-%d'),}
lis.append(res)
print "list is .........",lis
res={'value':{'order_line':lis}} // here order_line is o2m field of purchase.
return res
Your on_change method has to return a list of dictionaries made of line values.
For instance:
res['value']['line_ids'] = [
{
'account_id': 1,
'debit': 100,
},
{
'account_id': 2,
'credit': 100,
}]
Also, see the recompute_voucher_lines method of account.voucher as example.
sometimes error '0' will be generate so we have to write a code with like this.
In case of above Example
lis.append((0,0,res))
Related
i added a document to marqo add_documents() but i didn't pass an id and now i am trying to get the document but i don't know what the document_id is?
Here is what my code look like:
mq = marqo.Client(url='http://localhost:8882')
mq.index("my-first-index").add_documents([
{
"Title": title,
"Description": document_body
}]
)
i tried to check whether the document got added or not but ;
no_of_docs = mq.index("my-first-index").get_stats()
print(no_of_docs)
i got;
{'numberOfDocuments': 1}
meaning it was added.
if you don't add the "_id" as part of key/value then by default marqo will generate a random id for you, to access it you can search the document using the document's Title,
doc = mq.index("my-first-index").search(title_of_your_document, searchable_attributes=['Title'])
you should get a dictionary as the result something like this;
{'hits': [{'Description': your_description,
'Title': title_of_your_document,
'_highlights': relevant part of the doc,
'_id': 'ac14f87e-50b8-43e7-91de-ee72e1469bd3',
'_score': 1.0}],
'limit': 10,
'processingTimeMs': 122,
'query': 'The Premier League'}
the part that says _id is the id of your document.
can't figure out how to add a line to sale.subscription using the create function from another model
subscription_pak = self.env['product.template'].search([('name', '=', pak_name),('recurring_invoice', '=', True)], limit=1)
subscription_info = {
'partner_id': vals['name'],
}
add_subscription = self.env['sale.subscription'].create(subscription_info)
print('ssssss',subscription_pak)
#works
add_subscription_pak = {
'product_id': subscription_pak.id,
'partner_id': add_subscription.id,
}
link_user_to_subscription = self.env['sale.subscription.line'].create(add_subscription_pak)
I am creating the subscription but can't find the field to use add product to the lines
can you please help
Thanks to odoo Mates on YouTube, this video his from odoo Mates channel How To Update One2many Field From OnChange Of Field in Odoo and #bigbear3001
this is what worked for me
supsctiption_pak = self.env['product.product'].search([('name', '=', pak_name),('recurring_invoice', '=', True)], limit=1)
supsctiption_info = {
'partner_id': vals['name'],
}
add_supsctiption = self.env['sale.subscription'].create(supsctiption_info)
supsctiption_to_pak = self.env['sale.subscription'].search([('partner_id', '=', vals['name'])], limit=1)
add_supsctiption_pak = {
'product_id': supsctiption_pak.product_variant_id.id,
'uom_id': supsctiption_pak.uom_id.id,
'price_unit': supsctiption_pak.list_price,
}
supsctiption_to_pak.write({'recurring_invoice_line_ids':[(5, 0, 0),(0,0,add_supsctiption_pak)]})
your subscription_pak is of type product.template (Product Template) but the product_id field of sale.subscription.line requires a product.product (Product (Variant)) (can't link to it as it's Odoo Enterprise)
so this should work (if you only have one variant on the Product):
...
add_subscription_pak = {
'product_id': subscription_pak.product_variant_id.id,
'partner_id': add_subscription.id,
}
...
for multiple variants:
...
add_subscription_pak = {
'product_id': subscription_pak.product_variant_ids.filter(lambda pv: pv.attribute == 'value')[0].id,
'partner_id': add_subscription.id,
}
...
I have this method:
#api.multi
def create_printy(self):
copy_record = self.env['stock.picking']
for record in self:
order_lines = []
for rec in record.order_lines:
order_lines.append(
(0,0,
{
'product_id': rec.isbn.id,
'product_qty': rec.qty,
}
))
sp_types = self.env['stock.picking.type'].search([
('code', '=', 'outgoing')
])
if len(sp_types) > 0:
copy_record.create({
'origin': record.name,
'picking_type_id': sp_types[0].id,
'move_lines': order_lines,
'move_type': 'direct',
'priority': '1',
'company_id': record.company_id.id,
})
I'm trying to create a stock.picking from another model.
But, with this method, I have problems for move_lines which on stock.picking is related to stock.move.
Right now, it throws me this:
Integrity Error
The operation cannot be completed, probably due to the following:
- deletion: you may be trying to delete a record while other records still reference it
- creation/update: a mandatory field is not correctly set
[object with reference: Product Unit of Measure - product.uom]
I know there are a few stock.move required fields which aren't present in my order_lines field.
So, my question is, how can I pass for example product.uom or date_expected which are required from my model?
Is there some similar way as it is done with picking_type_id in my example. for One2many field?
You could take a look of what happens when you do not fill these fields in the interface (and look what they get by default). For example, in stock.move Odoo takes the product_uom from product_id field (through an onchange method). And the date_expected is filled in by default with the current date. So:
#api.multi
def create_printy(self):
copy_record = self.env['stock.picking']
for record in self:
order_lines = []
for rec in record.order_lines:
order_lines.append(
(0,0,
{
'product_id': rec.isbn.id,
'product_uom': rec.isbn.uom_id.id,
'date_expected': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'product_qty': rec.qty,
}
))
sp_types = self.env['stock.picking.type'].search([
('code', '=', 'outgoing')
])
if len(sp_types) > 0:
copy_record.create({
'origin': record.name,
'picking_type_id': sp_types[0].id,
'move_lines': order_lines,
'move_type': 'direct',
'priority': '1',
'company_id': record.company_id.id,
})
For date_expected you will have to import in your .py file (out of your classes) the following:
import time
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
So I've just started using the google calendar api and I've had good results so far. I add attendees with their name and email in the events dictionary, like so
events = {
# other stuff here and then this
'items': [
# lots of stuff here, followed by
'attendees': [
{
'email': email1,
'displayName': name1
},
{
'email': email2,
'displayName': name2
},
],
###
]
}
Adding them goes fine, but when I access them, I'm never guaranteed of their order. I thought I could just access the emails like this
for event in events['items']:
print "email1 = " + str(event['attendees'][0]['email'])
print "email2 = " + str(event['attendees'][1]['email'])
and I can. And I've learned that lists in python always have their order preserved, which is convenient because I wanted to access the dictionaries inside the list with the index of the list. But what I've learned is that sometimes the 0 index refers to email1 and sometimes it refers to email2. Why the inconsistency? Is it inherent to the google calendar api or is there something about having dictionary objects within a python list that relaxes the order preservation assumption? Or is it something else I'm missing?
So, as #Colonel Thirty Two pointed out, while lists preserve order, how google return data into a list may not be in the same order as it was submitted to them. This order inconsistency with attendees is inconvenient if you are wanting to count on that order for the retrieval of attendees with something like
for event in events['items']:
print "email1 = " + str(event['attendees'][0]['email'])
print "email2 = " + str(event['attendees'][1]['email'])
What's more is that very few fields are writable with the google calendar api. What is writable, however, is comments. So, I added a value to that field to make the attendees identifiable. Like so
'attendees': [
{
'email': agent_email,
'displayName': agent_name,
'comment': 'agent'
},
{
'email': event_attendee_email,
'displayName': event_attendee_name,
'comment': 'client'
},
Using comment as an identifier helped me in retrieving the email and displayName of each attendee with a simple if-statement.
for i in range(len(event['attendees'])):
if event['attendees'][i]['comment'] == 'client':
event['attendees'][i]['displayName'] = event_attendee_name
event['attendees'][i]['email'] = event_attendee_email
Now it doesn't matter that the google calendar api submits my attendees back to me in a different order than the one in which I added them. I can now retrieve the attendees so I can change them. Problem solved.
I am trying to run the following query:
data = {
'user_id':1,
'text':'Lorem ipsum',
'$inc':{'count':1},
'$set':{'updated':datetime.now()},
}
self.db.collection('collection').update({'user_id':1}, data, upsert=True)
but the two '$' queries cause it to fail. Is it possible to do this within one statement?
First of all, when you ask a question like this it's very helpful to add information on why it's failing (e.g. copy the error).
Your query fails because you're mixing $ operators with document overrides. You should use the $set operator for the user_id and text fields as well (although the user_id part in your update is irrelevant at this example).
So convert this to pymongo query:
db.test.update({user_id:1},
{$set:{text:"Lorem ipsum", updated:new Date()}, $inc:{count:1}},
true,
false)
I've removed the user_id in the update because that isn't necessary. If the document exists this value will already be 1. If it doesn't exist the upsert will copy the query part of your update into the new document.
If you're trying to do the following:
If the doc doesn't exist, insert a new doc.
If it exists, then only increment one field.
Then you can use a combo of $setOnInsert and $inc. If the song exists then $setOnInsert won't do anything and $inc will increase the value of "listened". If the song doesn't exist, then it will create a new doc with the fields "songId" and "songName". Then $inc will create the field and set the value to be 1.
let songsSchema = new mongoose.Schema({
songId: String,
songName: String,
listened: Number
})
let Song = mongoose.model('Song', songsSchema);
let saveSong = (song) => {
return Song.updateOne(
{songId: song.songId},
{
$inc: {listened: 1},
$setOnInsert: {
songId: song.songId,
songName: song.songName,
}
},
{upsert: true}
)
.then((savedSong) => {
return savedSong;
})
.catch((err) => {
console.log('ERROR SAVING SONG IN DB', err);
})