I create data from the account.reconciliation.act model into the direct.statistics model
Then I want to change some data in account.reconciliation.act. and it does not change in the direct.statistics model. I have written a write method with which I would like to update the data in the direct.statistic model.
But it doesn't work. What did I do wrong?
I get the error TypeError: write() takes 2 positional arguments but 3 were given
1.py
class AccountReconciliationAct(models.Model):
_name = "account.reconciliation.act"
direct_statistics_id = fields.Many2one(comodel_name="direct.statistics", string="Direct Statistics")
#api.model
def create(self, values):
....
else:
self.env["direct.statistics"].create({
"direct_advertiser_id": record_id.partner_id.id,
"direct_payment_net_id": record_id.payment_net_id.id,
"direct_currency_id": record_id.currency_id.id,
"direct_last_act_date": record_id.reconciliation_act_date,
"direct_total_amount": record_id.amount_total,
"direct_department_ids": record_id.reconciliation_act_line_ids.department_id
})
return record_id
#api.model
def write(self, values):
res = super().write(values)
self.env["direct.statistics"].update({
"direct_advertiser_id": self.partner_id.id,
"direct_payment_net_id": self.payment_net_id.id,
"direct_currency_id": values.get('currency_id.id'),
"direct_last_act_date": values.get('reconciliation_act_date'),
"direct_total_amount": values.get('amount_total'),
"direct_department_ids": values.get('reconciliation_act_line_ids.department_id'),
})
return res
2.py
class DirectStatistics(models.Model):
_name = "direct.statistics"
_description = "Direct statistics"
_rec_name = "direct_advertiser_id"
direct_advertiser_id = fields.Many2one(comodel_name="res.partner", string="Advertiser")
direct_manager_id = fields.Many2one(related="direct_advertiser_id.manager_id", string="Manager")
direct_payment_net_id = fields.Many2one(related="direct_advertiser_id.payment_net_id", string="Net")
direct_currency_id = fields.Many2one(comodel_name="res.currency", string="Currency")
direct_conversion_ids = fields.Many2many(comodel_name="affise.conversion", string="Conversions")
direct_last_act_date = fields.Date(string="Last Act Date", compute="_compute_direct_last_act_date", store=True)
direct_first_conversion_date = fields.Date(
string="First Conversion Date", compute="_compute_direct_first_conversion_date", store=True
)
direct_department_ids = fields.Many2many(
comodel_name="affise.department", compute="_compute_direct_department_ids", string="Department"
)
direct_reconciliation_act_ids = fields.Many2many(
comodel_name="account.reconciliation.act", string="Created Acts", domain=[("state", "!=", "cancel")]
)
direct_total_amount = fields.Monetary(
currency_field="direct_currency_id", string="Total Acts")
class AccountReconciliationAct(models.Model):
_name = "account.reconciliation.act"
direct_statistics_id = fields.Many2one(comodel_name="direct.statistics", string="Direct Statistics")
#api.model
def create(self, values):
record_id = super(AccountReconciliationAct, self).create(values)
....
else:
record_id.direct_statistics_id = self.env["direct.statistics"].create({
"direct_advertiser_id": record_id.partner_id.id,
"direct_payment_net_id": record_id.payment_net_id.id,
"direct_currency_id": record_id.currency_id.id,
"direct_last_act_date": record_id.reconciliation_act_date,
"direct_total_amount": record_id.amount_total,
"direct_department_ids": record_id.reconciliation_act_line_ids.department_id
})
return record_id
def write(self, values):
res = super(AccountReconciliationAct, self).write(values)
self.direct_statistics_id.update({
"direct_advertiser_id": self.partner_id.id,
"direct_payment_net_id": self.payment_net_id.id,
"direct_currency_id": values.get('currency_id.id'),
"direct_last_act_date": values.get('reconciliation_act_date'),
"direct_total_amount": values.get('amount_total'),
"direct_department_ids": values.get('reconciliation_act_line_ids.department_id'),
})
return res
The first thing you need to do is write the created object to direct_statistics_id field. This is done so that you can update the value in write method. Also don't need to call #api.model for write methods.
Related
I create sequence in customer module sale, and _inherit to res.partner but I get fill 'New' in my sequence field when I create new customer
group_id = fields.Many2one(
'group.customer',
string="Group"
)
#api.model
def create(self, value):
if self.group_id.name == 'Dealer':
if value.get('code_customer', _('New')) == _('New'):
value['code_customer'] = self.env['ir.sequence'].next_by_code('code.customer.dealer') or _('New')
result = super(res_partner, self).create(value)
return result
That is a wrong way to inherit create function. Here is the correct one:
#api.model
def create(self, value):
group_id = value.get('group_id')
if group_id:
group = self.env['group.customer'].browse(group_id)
if group.name=='Dealer' and value.get('code_customer', _('New')) == _('New'):
value['code_customer'] = self.env['ir.sequence'].next_by_code('code.customer.dealer') or _('New')
result = super(res_partner, self).create(value)
return result
I know my object type is not matching to compare. I tried on #api.onchange but it says:
NullObject is not iterable for selection fields.
Code:
from odoo import models,api,fields
class semester(models.Model):
_name = 'module2_semester'
_description = 'Semester_Info'
_rec_name = 'sem_id'
sub = fields.Many2many('module2_subject')
cou_id = fields.Many2one('module2_course',"Course Name",required=True)
sem_id = fields.Char("Semester ID")
sem_name = fields.Selection(selection='_getSem_value',string="Semester")
reg_no = fields.Integer("Registration Number",size=20)
#api.model
def _getSem_value(self):
print("hello")
print(self.cou_id)
if self.cou_id=='BTECH':
return [('1','1'),
('2','2'),
('3','3'),
('4','4'),
('5','5'),
('6','6'),
('7','7'),
('8','8')]
if self.cou_id=='MCA':
return [('1','1'),
('2','2'),
('3','3'),
('4','4'),
('5','5'),
('6','6')]
if self.cou_id=='MTECH':
return [('1','1'),
('2','2'),
('3','3'),
('4','4')]
You can change the Semester field type to many2one and set the attribute widget to selection in the view definition.
When the value of cou_id changes you have just to filter the records shown in the selection field by returning a custom domain.
class Semester(models.Model):
_name = 'semester'
_description = 'Semester'
name = fields.Integer()
class semester(models.Model):
_name = 'module2_semester'
_description = 'Semester_Info'
_rec_name = 'sem_id'
sub = fields.Many2many('module2_subject')
cou_id = fields.Many2one('module2_course',"Course Name",required=True)
sem_id = fields.Char("Semester ID")
# sem_name = fields.Selection(selection='_getSem_value',string="Semester")
reg_no = fields.Integer("Registration Number",size=20)
sem_name = fields.Many2one('semester', string="Semester")
#api.onchange('cou_id')
def _course_changed(self):
self.sem_name = False
if self.cou_id:
# Initialize `semesters` in case `cou_id.name` is not listed below
semesters = 0
if self.cou_id.name == 'BTECH':
semesters = 8
if self.cou_id.name == 'MCA':
semesters = 6
if self.cou_id.name == 'MTECH':
semesters = 4
sem_ids = self.env['semester'].search([('name', '<=', semesters )])
return {'domain': {'sem_name': [('id', 'in', sem_ids.ids)]}}
In the view definition:
<field name="sem_name" widget="selection"/>
I'm trying to override the create and write method from Odoo.
My code (below) hits the error indicated:
class sms(models.Model):
_description = "Module d'envoi et de reception SMS"
contenu = fields.Text("Contenu", required=True)
date_sms = fields.Datetime(string="Date", default=lambda *a: datetime.now(), required=True)
type = fields.Char(string="Type", readonly=True, default="envoi")
status = fields.Char(string="Status", required=True, default="brouillon", readonly=True)
destinataire_ids = fields.Many2one(
comodel_name='hr.employee',
relation="m2m_mission_employee_relation",
column1="m2m_id",
column2="id",
string="Destinataire", required=True)
num = fields.Char(string="Numero")
#api.onchange('destinataire_ids')
def _set_number(self):
for record in self:
record.num = self.destinataire_ids.mobile_phone
self.num = self.destinataire_ids.mobile_phone
def get_user_id(self):
context = self._context
current_uid = context.get('uid')
user = self.env['res.users'].browse(current_uid)
return user
#api.multi
def write(self, vals):
res = super(sms, self).write(vals)
#api.model
def create(self,values):
campus_create = super(sms, self).create(values)
return campus_create
The error hit was:
File "C:\Python35\lib\site-packages\odoo-11.0.post20180130-py3.5.egg\odoo\models.py", line 1536, in _add_missing_default_values
defaults.update(values)
TypeError: cannot convert dictionary update sequence element #0 to a sequence
***TypeError: cannot convert dictionary update sequence element #0 to a sequence***
Where did you say what model you are overriding?
Try put _inherit = 'model' on start of your class
I tried to create a table using a class that is not related to my database in django and this class is stored in models.py as shown below (InfoServer is the class). What I wanted to do is to use this class to populate my table using django_tables2. Add models.Model as a parameter is not an option because I don't want to save this class in the database.
Whenever I define the model = InfoServer in tables.py I got this error and I suppose it's because InfoServer did not take models.Model as a parameter.
TypeError: descriptor 'repr' of 'object' object needs an argument
Any help is appreciated.
models.py
class TestServeur(models.Model):
nom = models.CharField(max_length=200)
pid = models.CharField(max_length=200)
memoire = models.IntegerField(null=True)
class InfoServer:
# "This is a class to test my knowledge of python"
def __init__(self,p = '',c = 0,m = 0):
self.pid = p
self.cpu = c
self.memoire = m
def getData(self):
return ("A server with %s memory and %s cpu" % (self.cpu,self.memoire))
views.py
def index(request):
return HttpResponse("Hello, world. You're at the index.")
def cpu_view(request):
liste = []
proc1 = Popen(['ps','-eo','pid,%cpu,%mem,comm'], stdout=PIPE, stderr=PIPE)
proc2 = Popen(['grep','java'], stdin=proc1.stdout, stdout=PIPE)
proc1.stdout.close()
for line in iter(proc2.stdout.readlines()):
clean_line = line.decode("utf-8")
info_utiles = clean_line.split()
pid,cpu,mem,*rest = info_utiles
i1 = InfoServer(pid,cpu,mem)
liste.append(i1)
table = TestServeur(liste)
RequestConfig(request).configure(table)
return render(request, 'server/cpu.html', {'output': table})
tables.py
class TableServeur(tables.Table):
class Meta:
# model = InfoServer
fields = ['pid', 'memory', 'cpu']
template_name = 'django_tables2/bootstrap4.html'
As I can see, InfoServer class is not a Django Model. Also I don't think you need to use that directly anyway. So, you can simply provide a list with dictionary, and render it in template with table.
First, we need to update Table class and remove Meta class from it, as we are not going to use any django models.
class TableServeur(tables.Table):
pid = tables.Column()
memory = tables.Column()
cpu = tables.Column()
Now, adding a new object method to return dictionary from InfoServer class:
class InfoServer:
# "This is a class to test my knowledge of python"
def __init__(self,p = '',c = 0,m = 0):
self.pid = p
self.cpu = c
self.memoire = m
def getData(self):
return ("A server with %s memory and %s cpu" % (self.cpu,self.memoire))
def get_dict_data(self):
return {'pid': self.pid, 'cpu': self.cpu, 'memory': self.memoire}
Finally, update the view:
for line in iter(proc2.stdout.readlines()):
clean_line = line.decode("utf-8")
info_utiles = clean_line.split()
pid,cpu,mem,*rest = info_utiles
i1 = InfoServer(pid,cpu,mem)
liste.append(i1.get_dict_data())
table = TestServeur(liste)
return render(request, 'server/cpu.html', {'output': table})
More info can be found in documentation on how you can populate table with data.
I want to create recordset with product in my custom class from sale order after calling an event. I will create a record in sale.order and like creating invoice, I will create record in my custom module.
What I have done is:
In my custom class:
class LoadingSlip(models.Model):
_name = 'loading.slip'
_description = 'loading information'
partner_id = fields.Char("Customer Name")
order_date = fields.Date("Order Date")
expiration_date = fields.Date("Expiration Date")
# order_line = fields.One2many('sale.order.line', 'order_id', string="Order Lines")
product_line = fields.One2many('loading.product.line', 'loading_product', string="Loading Products")
class LoadingProduct(models.Model):
_name = 'loading.product.line'
_description = "Loading Product Informations"
products_id = fields.Many2one('product.product', string='Product',
ondelete='restrict', index=True)
quantity = fields.Float(string='Quantity', default=1)
loading_product = fields.Many2one('loading.slip', string="Loading Reference", ondelete='cascade', index='True')
In sale.order
class sale_func(models.Model):
_inherit = 'sale.order'
#api.multi
def _prepare_slip(self):
test.set_trace()
self.ensure_one()
slip = {
'partner_id': self.partner_id.name,
'order_date': self.date_order,
'expiration_date': self.validity_date,
}
return slip
#api.multi
def action_slip_create(self, grouped=False, final=False):
test.set_trace() # debug point
pprint(self)
inv_obj = self.env['loading.slip']
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
slips={}
pprint(slips)
slipReferences={}
test.set_trace()
for order in self:
group_key = order.id
test.set_trace()
for line in order.order_line:
if group_key not in slips:
inv_data = order._prepare_slip()
loadingslip = inv_obj.create(inv_data)
slipReferences[loadingslip] = order
slips[group_key] = loadingslip
if line.product_uom_qty > 0:
line.slip_line_create(slips[group_key].id)
if not slips:
raise UserError(_('There is no loading slip line.'))
#api.multi
def create_slip(self):
test.set_trace()
pprint(self)
sale_orders = self.env['sale.order'].browse(self._context.get('active_ids', []))
self.action_slip_create(sale_orders)
In sale.order.line
class sales_order(models.Model):
_inherit="sale.order.line"
#api.multi
def _prepare_slip_line(self):
test.set_trace()
self.ensure_one()
res={}
pprint(res)
res={
'products_id': self.product_id.id or False,
'quantity': self.product_uom_qty
}
pprint(res)
#api.multi
def slip_line_create(self, loading_product):
test.set_trace()
prdct_order = self.env['loading.product.line']
for line in self:
vals = line._prepare_slip_line()
prdct_order.create(vals)
My error is:
> /home/diwap/odoo-dev/custom-addons/sales_ext_agni/models/models.py(196)slip_line_create()
195 vals = line._prepare_slip_line()
--> 196 prdct_order.create(vals)
197
ipdb> n
TypeError: "argument of type 'NoneType' is not iterable"
I have tried update and write method instead of create in line 196 but I could not get any result it's just come up with an empty field and also no error. However when I try the real thing and i.e. write() I get this error. Is there any wrong somewhere in my code or its just an horrible thing I am doing.