Odoo 9 : How to pass parameters to query (display result in tree view) via wizard - odoo

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 :)

Related

Odoo 15 Search non-stored compute value that depends on search_count of many2one field

I'm trying to display a view with certain products that have multiple BoM's. I've created a computed field that labels which records should be displayed. I'm trying to create a search function so that the records in interest can be displayed as a filter but am having trouble creating the function.
Currently trying to append record.id's of interest into a list and returning the list within the search domain but that is not working. Any help would be much appreciated. Please see code below and thanks in advance!
I tried the following code but it returns an empty data list. I think there's something wrong with how I'm getting the id of the current record and appending it to the list that is returned.
class products_ppa_bom_check(models.Model):
_inherit = ['product.template']
ppa_multi_bom = fields.Selection([
('true', 'True'),
('false', 'False'),
('na', 'Not Applicable')],
string="PPA Multi BOM Check", compute='_compute_ppa_multi_bom',
search='_search_ppa_multi_bom')
def _compute_ppa_multi_bom(self):
for record in self:
count = record.env['mrp.bom'].search_count(['|', ('product_tmpl_id', '=', record.id), ('byproduct_ids.product_id.product_tmpl_id', '=', record.id)])
if (count > 1) and ('PPA' in str(record.default_code)):
record.ppa_multi_bom = 'true'
elif (count == 1) and ('PPA' in str(record.default_code)):
record.ppa_multi_bom = 'false'
else: record.ppa_multi_bom = 'na'
def _search_ppa_multi_bom(self, operator, value):
ids = []
for record in self:
count = record.env['mrp.bom'].search_count(['|', ('product_tmpl_id', '=', record.id), ('byproduct_ids.product_id.product_tmpl_id', '=', record.id)])
if (count > 1) and ('PPA' in str(record.default_code)):
ids = ids.append(record.id)
return[('id', 'in', ids)]
If you want to use a filter in products with = operator, you can use the below code which I already tested:
You can use bom_count field rather than use search_count method
from odoo import api, fields, models, _
class products_ppa_bom_check(models.Model):
_inherit = ['product.template']
ppa_multi_bom = fields.Selection([
('true', 'True'),
('false', 'False'),
('na', 'Not Applicable')],
string="PPA Multi BOM Check", compute='_compute_ppa_multi_bom',
search='_search_ppa_multi_bom')
def _compute_ppa_multi_bom(self):
for record in self:
if (record.bom_count > 1) and ('PPA' in str(record.default_code)):
record.ppa_multi_bom = 'true'
elif (record.bom_count == 1) and ('PPA' in str(record.default_code)):
record.ppa_multi_bom = 'false'
else:
record.ppa_multi_bom = 'na'
def _search_ppa_multi_bom(self, operator, value):
true_ids = self.env['product.template'].search([]).filtered(
lambda x: x.bom_count > 1 and 'PPA' in str(x.default_code)).ids
false_ids = self.env['product.template'].search([]).filtered(
lambda x: x.bom_count == 1 and x.default_code and 'PPA' in x.default_code).ids
if value == 'true':
ids = true_ids
elif value == 'false':
ids = false_ids
else:
all_ids = self.env['product.template'].search([]).ids
ids = list(set(all_ids) - set(true_ids + false_ids))
return [('id', 'in', ids)]
To add filter to search view:
<record id="product_template_search_view_inherit_bom" model="ir.ui.view">
<field name="name">product.template.search.inherit.bom</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_search_view"/>
<field name="arch" type="xml">
<xpath expr="//filter[#name='consumable']" position="after">
<separator/>
<filter string="Multi BOM" name="ppa_multi_bom" domain="[('ppa_multi_bom', '=', 'true')]"/>
<filter string="One BOM" name="ppa_one_bom" domain="[('ppa_multi_bom', '=', 'false')]"/>
<filter string="NA BOM" name="ppa_na_bom" domain="[('ppa_multi_bom', '=', 'na')]"/>
</xpath>
</field>
</record>

auto filled field to different field in odoo

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

How to create sample sale order and sale order line in odoo?

I am trying to create a sample order in sales order.In the sample order form, products are sold to customers as complimentary copy(books in my case) without charging any money so I have created a separate sub-menu in sales menu.Here I take only product and quantity as input. Sample order number will be the next number from the sales order(like SO360).So I am fetching sales order number as parent_id in my inherited module.I am not able to create sale order line(data in order lines tab)
class SaleOrder(models.Model):
_inherit = 'sale.order'
# Fields
is_sample = fields.Boolean(string="Sample Order", default=False)
parent_id = fields.Many2one('sale.order', string="Parent Sales Order")
sample_ids = fields.One2many('sale.order', 'parent_id',
string="Sample Orders")
# Methods
#api.model
#api.returns('sale.order')
def create(self, vals):
if vals.get('is_sample', False) and vals.get('name', '/') == '/':
IrSeq = self.env['ir.sequence']
ref = IrSeq.next_by_code('sale.order.sample.ref') or '/'
parent = self.search([('id', '=', vals.get('parent_id'))])
vals['name'] = parent.name + ref
vals['user_id'] = parent.user_id.id
return super(SaleOrder, self).create(vals)
class SampleOrderWizard(models.TransientModel):
_name = 'sale.order.sample.wizard'
_description = 'Sample Sale Order Wizard'
# Field default values
#
def _get_parent(self):
res = False
if self.env.context \
and 'active_id' in list(self.env.context.iterkeys()):
res = self.env.context['active_id']
return res
def _get_new_sale_line(self, orig_sale, orig_sale_line, wizard_line):
"""Internal function to get the fields of the sale order line. Modules
enhancing this one should add their own fields to the return value."""
res = {
'order_id': orig_sale.id,
'product_id': orig_sale_line.product_id.id,
'name': orig_sale_line.name,
'sequence': orig_sale_line.sequence,
'price_unit': orig_sale_line.price_unit,
'product_uom': orig_sale_line.product_uom.id,
'product_uom_qty': wizard_line and wizard_line.qty or 0,
'product_uos_qty': wizard_line and wizard_line.qty or 0,
}
# Simple check for installation of sale_line_code module
if hasattr(orig_sale_line, 'order_line_ref'):
res.update({'order_line_ref': orig_sale_line.order_line_ref})
return res
def _get_order_lines(self, sale):
res = []
for line in sale.order_line:
wizard_line = False
for wzline in self.wizard_lines:
if wzline.product == line.product_id:
wizard_line = wzline
break
if wizard_line:
res.append(
(0, 0, self._get_new_sale_line(sale, line, wizard_line))
)
return res
def _get_wizard_lines(self):
res = []
if self._get_parent():
SaleOrder = self.env['sale.order']
parent = SaleOrder.search([('id', '=', self._get_parent())])
for line in parent.order_line:
res.append((0, 0,
{
'product': line.product_id,
'qty': 1,
}))
return res
# Fields
#
order = fields.Many2one('sale.order', default=_get_parent, readonly=True)
wizard_lines = fields.One2many('sale.order.sample.wizard.line', 'wizard',
default=_get_wizard_lines)
order_date = fields.Datetime(default=fields.Datetime.now())
# Methods
#
#api.one
def create_order(self):
sale_vals = {
'user_id': self.order.user_id.id,
'partner_id': self.order.partner_id.id,
'parent_id': self.order.id,
'date_order': self.order_date,
'client_order_ref': self.order.client_order_ref,
'company_id': self.order.company_id.id,
'is_sample': True,
'order_line': self._get_order_lines(self.order)
}
self.env['sale.order'].create(sale_vals)
return {'type': 'ir.actions.act_window_close'}
class SampleOrderWizardLine(models.TransientModel):
_name = 'sale.order.sample.wizard.line'
_description = 'Sample Order Wizard Line'
wizard = fields.Many2one('sale.order.sample.wizard')
product = fields.Many2one('product.product',
domain=[('sale_ok', '=', True)])
qty = fields.Float(string="Quantity", default=1.0,
digits_compute=dp.get_precision('Product UoS'))

Calling method and field from other model in odoo

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')

how to fil result fetchall into columns?

I used command fetchall()
cr.execute('select a.name, a.state, a.amount_total, a.date_confirm, b.product_uom_qty from sale_order a, sale_order_line b where a.id = b.order_id')
temp = cr.fetchall()
so it take all SO in table SO, and I want fill all result into here :
class sales_items_line(osv.osv_memory):
_name = "sales.items.line"
_description = "Sales Items Line"
_columns = {
'name': fields.char('Name', size=64),
'qty': fields.char('Quantity', size=64),
'date': fields.date('Date', required=True),
'amount': fields.float('Amount', digits_compute=dp.get_precision('Account')),
'draft_assigned': fields.boolean('Select'),
'sale_items_id': fields.many2one('add.sales.items', 'Deposit Items ID'),
}
but how ? please help me..., the cr.execute is different class
you have to override the default_get() method and fill your columns.
Here is the code:
def default_get(self, cr, uid, fields, context=None):
fields = super(sales_items_line, self).default_get(cr, uid, fields, context=context)
cr.execute('select a.name as "name", a.state as "state", a.amount_total as "total", a.date_confirm as "date", b.product_uom_qty as "qty" from sale_order a, sale_order_line b where a.id = b.order_id')
data = cr.dictfetchall()
for rec in data:
fields['name'] = rec.get('name', '')
fields['qty'] = rec.get('qty', 0.00)
fields['amount'] = rec.get('total', 0.00)
return data
Hope this will solve your problem.
Thank you.