these are my 1st model, method, and fields
class overtime(models.Model):
_name = 'overtime'
def calc_overtime(self, start_date, end_date):
#import pdb;pdb.set_trace()
f = '%Y-%m-%d %H:%M:%S'
d1 = datetime.strptime(start_date, f)
d2 = datetime.strptime(end_date, f)
timeDiff = d2-d1
hours = float(timeDiff.total_seconds()/3600)
return hours
start_date = fields.Datetime('Start Date', required=True, default=lambda *a : time.strftime("%Y-%m-%d"+" "+"%H:%M:%S")
, readonly=True, states={'draft': [('readonly', False)]})
end_date = fields.Datetime('End Date', required=True, default=lambda *a : time.strftime("%Y-%m-%d"+" "+"%H:%M%S")
, readonly=True, states={'draft': [('readonly', False)]})
and these are my 2nd model, method and field
class overtime_details(models.Model):
_name='overtime_details'
def function(self):
"calling calc_overtime"
ovrtm = fields.Float('Overtime Hour(s)')
how do i call the calc_overtime method, start_date and end_date as parameters, in the overtime details class by using "self.pool.get"
or "self.env". and make the result as ovrtm field's value. Thanks before
I think you don't need to calculate the nb of hours in the first class, The function sould be in the second class, and add a One2many field.
class overtime(models.Model):
_name = 'overtime'
start_date = fields.Datetime('Start Date', required=True, default=lambda *a : time.strftime("%Y-%m-%d"+" "+"%H:%M:%S")
, readonly=True, states={'draft': [('readonly', False)]})
end_date = fields.Datetime('End Date', required=True, default=lambda *a : time.strftime("%Y-%m-%d"+" "+"%H:%M%S")
, readonly=True, states={'draft': [('readonly', False)]})
class overtime_details(models.Model):
_name='overtime_details'
def compute_houres(self, start_date, end_date):
d1 = self.overtime_id.end_date
d2 = self.overtime_id.start_date
f = '%Y-%m-%d %H:%M:%S'
d1 = datetime.strptime(start_date, f)
d2 = datetime.strptime(end_date, f)
timeDiff = d2-d1
hours = float(timeDiff.total_seconds()/3600)
self.ovrtm = hours
overtime_id = fields.Many2one('overtime', 'Réference', ondelete='cascade'),
ovrtm = fields.Float(compute='compute_houres')
Related
how to make field become auto fill when i create new record from bank_account.py field to account_account.py field.
bank_account.py
class BankAccounAccount(models.Model):
_name = 'bank.account.account'
_description = "Bank Account Account"
_rec_name = 'acc_number'
acc_number = fields.Char(string="Account Number", required=True)
bank_id = fields.Many2one('res.bank', string="Bank")
bank_bic = fields.Char(string="Bank Identifier Code")
company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.user.company_id.id)
branch_id = fields.Many2one('res.branch', string="Branch")
account_account.py
class AccountJournal(models.Model):
_inherit = "account.journal"
name = fields.Char(string='Journal Name', required=True,
tracking=True)
company_partner_id = fields.Many2one('res.partner', related='company_id.partner_id', string='Account Holder', readonly=True, store=False)
bank_account_id = fields.Many2one('res.partner.bank',
string="Bank Account",
ondelete='restrict', copy=False,
check_company=True,
domain="[('partner_id','=', company_partner_id), '|', ('company_id', '=', False), ('company_id', '=', company_id)]",
tracking=True)
company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True, index=True, default=lambda self: self.env.company,
help="Company related to this journal",
tracking=True)
bank_statements_source = fields.Selection(selection=_get_bank_statements_available_sources, string='Bank Feeds', default='undefined', help="Defines how the bank statements will be registered",
tracking=True)``
bank_acc_number = fields.Char(related='bank_account_id.acc_number', readonly=False,
tracking=True)
bank_id = fields.Many2one('res.bank', related='bank_account_id.bank_id', readonly=False,
tracking=True)
`
when created new account 'acc_number' record auto filled into name field and company_id to company id
I have inherited account.move model and added job_card_id field(many2one) in it, as shown as below :
Image
Below given is Image of Selected Job Card :
Image
Below given is code of my model and I also tried creating function below fields :
class JobCard(models.Model):
_name = "job.card"
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "Job Card Master"
_rec_name = 'job_card_number'
job_card_number = fields.Char(string='Job Card No.', readonly=True)
customer_id = fields.Many2one('res.partner', string="Customer Name", tracking=True)
vehicle_id = fields.Many2one('res.partner.line', string="Vehicle", tracking=True,
domain="[('x_customer_id','=',customer_id)]")
date_time_of_invoice = fields.Datetime(string='Date & Time of Invoice', tracking=True, default=fields.Datetime.now)
start_date_time = fields.Datetime(string='Start Date & Time', tracking=True)
end_date_time = fields.Datetime(string='End Date & Time', tracking=True)
priority = fields.Selection([
('0', 'Normal'),
('1', 'Low'),
('2', 'High'),
('3', 'Very High')], string="Priority") # priority widget
state = fields.Selection([
('draft', 'Draft'),
('in_progress', 'In Progress'),
('done', 'Done'),
('cancel', 'Cancelled')], string="Status", default='draft', required=True) # status bar
active = fields.Boolean(string="Active", default=True, tracking=True)
x_product_ids = fields.Many2many('job.card.line', 'product_id', string="Job Card Details")
x_quantity_ids = fields.One2many('job.card.line', 'quantity', string="Job Card Details")
x_price_ids = fields.One2many('job.card.line', 'price', string="Job Card Details")
x_total_ids = fields.One2many('job.card.line', 'total', string="Job Card Details")
x_employee_ids = fields.One2many('job.card.line', 'employee_id', string="Job Card Details")
x_job_card_ids = fields.One2many('job.card.line', 'job_card_id', string="Job Card Details")
job_card_count = fields.Integer(compute='compute_job_card_count', string='Job Card Count')
def get_invoice_line_vals(self):
vals_list = []
for job_card_line in self.x_product_ids:
vals_list.append({
' price_unit': job_card_line.price_unit,
'quantity': job_card_line.quantity
})
return vals_list
Below given is code of inherited model and also added onchange function :
class CustomInvoice(models.Model):
_inherit = "account.move"
job_card_id = fields.Many2one('job.card', string="Job Card", domain="[('customer_id','=',partner_id)]",
tracking=True)
#api.onchange('job_card_id')
def _onchange_job_card_id(self):
# creates your invoice lines vals according to your values
invoice_lines_vals = self.job_card_id.get_invoice_line_vals()
self.update({'invoice_line_ids': [(5, 0)] + [(0, 0, vals) for vals in invoice_lines_vals]})
Below given is code of my job card line :
class JobCardLine(models.Model):
_name = "job.card.line"
job_card_id = fields.Many2one('job.card', string="Job Card Id", tracking=True)
product_id = fields.Many2one('product.template', string="Product", tracking=True)
quantity = fields.Integer(string="Quantity", tracking=True)
# price = fields.Char(string="Price")
price = fields.Float(string="Price")
total = fields.Integer(string='Total', compute='_compute_total', tracking=True,
help="This field will be calculated from quantity and price !")
employee_id = fields.Many2one('hr.employee', string="Employee", tracking=True)
x_job_card_id = fields.Many2one('res.partner', string="Vehicle Details")
#api.onchange('product_id')
def _on_change_product_id(self):
self.price = self.product_id.list_price
#api.depends('quantity', 'price')
def _compute_total(self):
print("self........", self)
for rec in self:
rec.total = rec.quantity * rec.price
Actually I wanted to add product line of selected job card into Invoice product line automatically when I select the job card.
But I am getting error as shown below :
Error
You got that error because you have no field named line_ids in job.card model. Maybe you need to change it to x_product_ids.
The TyprError (int object is not iterable) is caused by the first tuple passed to the write method :
(6, 0, 0)
Odoo expects the third parameter to be iterable. If you need to clear the list, use (5,0)
Avoid calling the write method inside an onchange function. You can read the following danger notice in the official onchange documentation:
DangerSince #onchange returns a recordset of pseudo-records, calling any one of the CRUD methods (create(), read(), write(), unlink()) on the aforementioned recordset is undefined behaviour, as they potentially do not exist in the database yet.Instead, simply set the record’s field like shown in the example above or call the update() method.
Edit:
You have two errors in get_invoice_line_vals function
1/ ValueError:
Invalid field ' price_unit' on model 'account.move.line'
You need to remove the space at the beginning.
2/ AttributeError:
'job.card.line' object has no attribute 'price_unit'.
Use the price field instead.
my problem is that when i saved the fields in model's from B , i did't saw the result in model's view A execept the name of empoyee and department becuse declared in the same model, some freinds suggeste me to use onchnage function but how !!
class FeuilleTemps(models.Model): # A
_name = 'tbrh.feuilletemps'
_rec_name = 'name_emp'
name_emp = fields.Many2one('hr.employee', string="Employé")
name_dep = fields.Many2one('hr.department', string="Département")
abscence_ids = fields.One2many('tbrh.abscences', 'feuille_id', string="ma liste ")
relation_id = fields.Many2one('tbrh.abscences')
date2 = fields.Date(related='relation_id.date', store=True, use_parent_address=False)
statut = fields.Selection(related='relation_id.statut', store=True)
class Abscences(models.Model): # B
_name = 'tbrh.abscences'
statut = fields.Selection([('abscent', 'Abscent'), ('present', 'Présent')], string="Statut")
date = fields.Date()
feuille_id = fields.Many2one('tbrh.feuilletemps',
ondelete='cascade', string="feuille ", required=True)
I have this wizard where I select date :
<record id="wizard_forecast_invoice_date_form" model="ir.ui.view">
<field name="name">wizard.forecast.invoice.date.form</field>
<field name="model">custom_accounting.wizard_forecast_due_collection</field>
<field name="arch" type="xml">
<form string="Date for Forecast Due Collection">
<separator string="Date for Forecast Due Collection"/>
<label string="This will list all open customer invoices that are on or before the Due Date selected"/>
<group>
<field name="before_date"/>
</group>
<footer>
<button name="forecast_due_collection" string="Okay" type="object" class="btn-primary" context="{'before_date': before_date}"/>
<button special="cancel" string="Cancel" class="btn-default"/>
</footer>
</form>
</field>
</record>
Where I want send this date value to new class like this :
class WizardForecastDueCollection(models.TransientModel):
_name='custom_accounting.wizard_forecast_due_collection'
before_date = fields.Date(string='Before Date', required=True, default=fields.Date.context_today)
#api.multi
def forecast_due_collection(self):
ac = self.env['ir.model.data'].xmlid_to_res_id('custom_accounting.view_forecast_invoice_date_report_pivot')
return {
'name': 'ForecastInvoiceDateReport',
'view_type': 'form',
'res_model': 'custom_accounting.forecast_invoice_date_report',
'view_id': ac,
'context': {'default_before_date': self.before_date},
'type': 'ir.actions.act_window',
'view_mode': 'pivot',
'domain': [('date_invoice', '<=', self.before_date)]
}
And here's the class which should receive the value to execute the query :
class ForecastInvoiceDateReport(models.Model):
_name = "custom_accounting.forecast_invoice_date_report"
_description = "Forecast Invoices Date Report"
date_maturity = fields.Date(string='Due Date', readonly=True)
date_invoice = fields.Date(string='Invoice Date', readonly=True)
before_date = fields.Date(store=False, default=lambda s: fields.Date.context_today(s))
# account_id = fields.Many2one('account.account', string='Account', readonly=True, domain=[('deprecated', '=', False)])
country = fields.Char('Country', readonly=True)
sales_person_name = fields.Char('Sales Person', readonly=True)
partner_name = fields.Char('Customer', readonly=True)
state = fields.Char('State', readonly=True)
city = fields.Char('City', readonly=True)
debit = fields.Float("Debit", readonly=True)
credit = fields.Float("Credit", readonly=True)
amount_residual = fields.Float("Balance", digits_compute=dp.get_precision('accounting_financial_report_dp'),
readonly=True)
duration = fields.Char('Duration', readonly=True)
invoice_number = fields.Char('Invoice Number', readonly=True)
_auto = False
_rec_name = 'date_maturity'
_depends = {
'account.move': ['id', 'name'],
'account.move.line': ['move_id', 'date_maturity'],
'res.currency.rate': ['currency_id', 'name'],
'res.partner': ['country_id', 'state_id', 'city'],
'account.invoice': ['date_invoice'],
}
def _select(self):
select_str = """
SELECT
row_number() OVER () as id, duration, date_invoice, date_maturity,
country,state,city, sales_person_name, concat(partner_name,'(', Payment_Term, ')') partner_name ,
balance,amount_residual, debit,credit,invoice_number
From
(
SELECT
case
when "account_move_line".date_maturity is null Then 'No Date'
when (%s-ai.date_invoice) <30 then 'b# 0-30 days'
else 'Older'
END as duration, ai.date_invoice as date_invoice, "account_move_line".date_maturity as date_maturity,
res_country.name as country,res_country_state.name as state,res_partner.city as city,
new_rp.name as "sales_person_name", res_partner.name as "partner_name", res_partner.id as "partner_id1",
COALESCE(SUM("account_move_line".balance), 0) AS balance,
COALESCE(SUM("account_move_line".amount_residual), 0) AS amount_residual,
COALESCE(SUM("account_move_line".debit), 0) AS debit,
COALESCE(SUM("account_move_line".credit), 0) AS credit,
"account_move_line__move_id".name AS invoice_number
FROM "account_move" as "account_move_line__move_id","account_move_line"
LEFT JOIN res_partner on "account_move_line".partner_id = res_partner.id
LEFT JOIN res_country on res_partner.country_id = res_country.id
LEFT JOIN res_country_state on res_partner.state_id = res_country_state.id
LEFT JOIN res_users on res_partner.user_id = res_users.id
LEFT JOIN res_partner as new_rp on res_users.partner_id = new_rp.id
INNER JOIN account_account as aa on "account_move_line"."account_id"=aa.id
INNER JOIN account_invoice as ai on "account_move_line"."invoice_id"=ai.id
INNER JOIN account_account_type as aat on aat.id = aa.user_type_id
WHERE ("account_move_line"."move_id"="account_move_line__move_id"."id")
AND ((((
(aat.type = 'receivable') and account_move_line__move_id.state='posted' and
("account_move_line"."reconciled" IS NULL or "account_move_line"."reconciled" = false ))
) AND ("account_move_line__move_id"."state" = 'posted'))
) GROUP BY
case
when "account_move_line".date_maturity is null Then 'No Date'
when (%s-ai.date_invoice) <30 then 'b# 0-30 days'
else 'Older'
END
, new_rp.name , res_partner.name, res_country.name,res_country_state.name,res_partner.city,res_users.login,
"account_move_line".date_maturity,"account_move_line__move_id".name,ai.date_invoice,res_partner.id
order by 3
) as q1
left join
(
SELECT Substr(res_id,13) partner_id2,Substr(value_reference,22) Payment_Term_Id,pt.name Payment_Term
FROM public.ir_property ir join account_payment_term pt on pt.id = cast(Substr(value_reference,22) as integer)
where ir.name ='property_payment_term_id'
) as q2 on q1.partner_id1 = cast(q2.partner_id2 as integer)
""" %(self.before_date, self.before_date)
return select_str
_table = 'custom_forecast_invoices_date_view'
def init(self, cr):
# self._table = account_invoice_report
tools.drop_view_if_exists(cr, self._table)
cr.execute("""CREATE or REPLACE VIEW %s as (
WITH currency_rate AS (%s)
%s
)""" % (
self._table, self.pool['res.currency']._select_companies_rates(),
self._select()))
It works fine if I replace the field before_date by current_date in sql query, But if I set parameters instead, I can't get the expected value.
I got it,
Just run the query in the first class of wizard, that's all :)
this is the first code
class timetable_timetable(osv.osv):
_name='timetable.timetable'
_columns={
'name': fields.char('Name',size="64",required=True),
'course': fields.many2one('college.course','Course'),
'semester': fields.many2one('course.semester','Semester'),
'subject' : fields.one2many('timetable.subjects','timetable_id','Subject')
}
timetable_timetable()
this is the second code
class timetable_subjects(osv.osv):
_name = 'timetable.subjects'
_columns ={
'timetable_id' : fields.many2one('timetable.timetable','Time Table'),
'subject_id': fields.many2one('semester.subject','Subject'),
'start_date': fields.datetime('Start Date',store=True),
'duration' : fields.float('Duration',size=64,required=True),
'end_date' : fields.datetime('End Date',store=True),
'professor' : fields.many2one('professor.professor','Professor')
}
timetable_subjects()
i want to make a function on_change which returns me end_date from start_date & duration. So how can i make that function.
def on_change(self, cr, uid, ids, t_date, duration):
res = {'end_date': False}
if t_date:
now = datetime.strptime(t_date, '%Y-%m-%d %H:%M:%S')
e_date = now + timedelta(hours=duration)
print e_date
f_date = datetime.strftime(e_date, '%Y-%m-%d %H:%M:%S')
res['end_date'] = f_date
return {'value': res}
Write this code in your onchange method for end_date,
from datetime import datetime
from dateutil.relativedelta import relativedelta
def my_onchange(self, cr, uid, ids, s_date, duration):
return {'value': {'end_date': (datetime.strptime(s_date,'%Y-%m-%d %H:%M:%S') + relativedelta(days=duration)).strftime('%Y-%m-%d %H:%M:%S')}}
If your duration is in terms of months or years, write relativedelta(months=duration) for months and relativedelta(years=duration) for years and same way for hours or minutes or seconds.