How can I add From date to To date to print a set of records in report in odoo 10? - odoo

I am creating a Bank module, where the customers can buy loans from the bank. In that I want to print a report statement. Before printing the records of a particular customer, i want to filter the dates. I want to filter it by giving From date to To date. So the loan amounts where the customer bought from the bank in that given dates should print.
Thank You,
Hope I will gain some knowledge.

below code for wizard
class BankCustomer(models.TransientModel):
_name = 'bank.customer'
_description = 'Bank Customer Report'
date_from = fields.Date(string='From date', required=True,default=lambda *a: time.strftime('%Y-%m-01'))
date_to = fields.Date(string='To date', required=True,default=lambda *a: str(datetime.now() + relativedelta.relativedelta(months=+1, day=1, days=-1))[:10])
#api.multi
def pdf_bank_customer_report(self):
data = self.read()[0]
datas = {
'ids': [],
'model': 'bank.customer',
'form': data
}
return self.env['report'].with_context(landscape=True).get_action(self, 'module_name.template_name', data=datas)
class BankCustomerReport(models.AbstractModel):
_name = 'report.module_name.template_name
def get(self):
self.env.cr.execute(""" you query """+ datas['date_from'],datas['date_to'] ))
line_list = [i for i in self.env.cr.dictfetchall()]
finallist = []
import datetime
for fin in line_list:
#sale_date = datetime.datetime.strptime(fin['date'], '%Y-%m-%d').strftime('%d-%m-%y')
finallist.append({
'date': fin['date'],
'here gat you requirened field from query'
})
finally pass thislist to report template
return finallist
#api.model
def render_html(self, docids, data=None):
Report = self.env['report']
sale_report = Report._get_report_from_name('module_name.report_template_name')
context = dict(self._context or {})
active_ids = context.get('active_ids', [])
register = self.env['bank.customer'].browse(active_ids)
docargs = {
'doc_ids': self.ids,
'doc_model': sale_report.model,
'docs': register,
'details':self.get_det,
}
return Report.render('module_name.report_template_name', docargs)

Related

I have inherited Invoicing module and added one field in it. How can I fetch the product line from that field and add in invoice field line?

I have inherited account.move model and added job_card_id field(many2one) in it, as shown as below :
Below given is Image of Selected Job Card :
Below given is code of inherited model :
class CustomInvoice(models.Model):
_inherit = "account.move"
job_card_id = fields.Many2one('job.card', string="Job Card", domain="[('customer_id','=',partner_id)]", tracking=True)
Below given is code of 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.Float(
'Sales Price',
digits='Product Price')
total = fields.Integer(string='Total', compute='_compute_total', tracking=True,
help="This field will be calculated from dob !")
employee_id = fields.Many2one('hr.employee', string="Employee", tracking=True)
Now I wanted to add product line of selected job card into Invoice product line automatically when I select the job card.
You need to create an onchange method depending on the job_card_id.
In this onchange, you will add a line to invoice_line_ids.
This will triggers all the other onchange and compute methods and set ups everything needed.
Here is a small example:
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.write({'invoice_line_ids': [(6, 0, 0)] + [(0, 0, vals) for vals in invoice_lines_vals]})
The 6 is a command that will deletes all previous invoice_line and the 0 is a creation command.
more info on ORM command
Now, you just need to create the get_invoice_line_vals method in your JobCard class.
It should return a list of vals.
Each vals should be a dict containing some information such as the quantity and the price_unit.
It depends mostly on how you want your data to be calculate.
You just need to return a list like this:
def get_invoice_line_vals(self):
vals_list = []
for job_card_line in self.line_ids:
vals_list.append({
'price_unit': job_card_line.price_unit,
'quantity': job_card_line.quantity
})
return vals_list

How to get a product's multiple locations in odoo?

I want to get a product's location and display it on a custom report table:
and on the "Warehouse" cell it should be all the product's location, so if that product has multiple it should be displayed there. Just for clarification this is the location I'm talking about:
In order to put that there I tried this code:
class StockInventoryValuationReport(models.TransientModel):
_name = 'report.stock.inventory.valuation.report'
_description = 'Stock Inventory Valuation Report'
location_id = fields.Many2one('stock.location')
# filter domain wizard
#api.multi
def _compute_results(self):
self.ensure_one()
stockquant_obj = self.env['stock.quant'].search([("location_id", "=", self.location_id.id)])
print(stockquant_obj.location_id)
line = {
'name': product.name,
'reference': product.default_code,
'barcode': product.barcode,
'qty_at_date': product.qty_at_date,
'uom_id': product.uom_id,
'currency_id': product.currency_id,
'cost_currency_id': product.cost_currency_id,
'standard_price': standard_price,
'stock_value': product.qty_at_date * standard_price,
'cost_method': product.cost_method,
'taxes_id': product.taxes_id,
'location_id': stockquant_obj.location_id,
}
if product.qty_at_date != 0:
self.results += ReportLine.new(line)
but when I'm printing stockquant_obj.location_id it is an empty recordset basically its not finding any locations. Can someone please hint me on anything?
I actually managed to get the product's locations using this code:
class StockInventoryValuationReport(models.TransientModel):
_name = 'report.stock.inventory.valuation.report'
_description = 'Stock Inventory Valuation Report'
location_id = fields.Many2one('stock.location')
# filter domain wizard
#api.multi
def _compute_results(self):
self.ensure_one()
stockquant_obj = self.env['stock.quant'].search([("location_id", "=", self.location_id.id)])
for xyz in stockquant_obj:
line = {
'name': product.name,
'reference': product.default_code,
'barcode': product.barcode,
'qty_at_date': product.qty_at_date,
'uom_id': product.uom_id,
'currency_id': product.currency_id,
'cost_currency_id': product.cost_currency_id,
'standard_price': standard_price,
'stock_value': product.qty_at_date * standard_price,
'cost_method': product.cost_method,
'taxes_id': product.taxes_id,
'location_id': xyz.location_id,
}
if product.qty_at_date != 0:
self.results += ReportLine.new(line)
I debugged further discovering that now stock.quant() could get some record-set but odoo was expecting a singleton when on my old code was stockquant_obj.location_id so since I have seen from other people that the solution to singleton is a for loop and for that reason I added it.
The problem with this is that now not only the warehouse would be added but the same product would repeat as times as long the recordset is. How can I dodge this? How to tell python that I only need to loop through stockquant_obj and xyz should be inside the line variable?

Generate xlsx report from wizard in odoo 11

i am trying to create an xlsx report using a wizard.
Here is the code.
wizard.py
def button_export_excel(self):
print('Print')// It prints
datas={}
datas['form']=self.read()[0]
return {'type': 'ir.actions.report',
'report_name': 'my_module.partner_sts_xlsx',
'datas': datas,
'name': 'Report Name'
}
report.py
class PartnerOUTStatementXlsx(models.AbstractModel):
_name = 'report.my_module.partner_sts_xlsx'
_inherit = 'report.report_xlsx.abstract'
def generate_xlsx_report(self, workbook, datas, partners):
print('data',datas)
print('partners',partners)
for obj in partners:
report_name = obj.name
# One sheet by partner
sheet = workbook.add_worksheet(report_name[:31])
bold = workbook.add_format({'bold': True})
sheet.write(0, 0, obj.name, bold)
It doesn't call generate_xlsx_report function.
How can i achieve this?
Finally found the solution.
i returned the function like this.
return self.env.ref(
'my_module'
'.partner_stat_xlsx').report_action(
self, data=datas)

How to display external information on Odoo 11?

I'm working on Weather application using Odoo11, I have a Python script that fetches weather information from this API: https://openweathermap.org/api
The script works fine but I have no idea how to integrate it with Odoo.
Can you give guidelines about how to achieve this, for example how to show this information in a form view, tree or Kanban?
Any example will be very helpful for me.
If you only want to show some text that´s always updated you can use a computed field
from odoo import api
weather = fields.Text( # this can be an image or any other field type
string='Weather',
compute='_compute_weather'
)
#api.depends() # leave this empty, so this is executed always when the view with this field is loaded
def _compute_weather(self):
for record in self:
# retrieve the weather information here
record.weather = weather_information # assign the weather information to the variable
Show it in a form view as any other field
<field name="weather" />
Note: If you want to store the information on the database you can just create a button or a atomate task, for instance, to store or update the values in the fields (without compute method).
Note2: Check the source code of the user_weather_map module from Cybrosis, it may be helpful
You can use the module User Weather Notification.
This module uses external API.
def get_weather(self, user_id):
rec = self.env['user.weather.map.config'].search([('user_id', '=', user_id)], limit=1)
if rec:
weather_path = 'http://api.openweathermap.org/data/2.5/weather?'
if rec.u_longitude and rec.u_latitude:
params = urllib.urlencode(
{'lat': rec.u_latitude, 'lon': rec.u_longitude, 'APPID': rec.appid})
elif rec.city:
params = urllib.urlencode(
{'q': rec.city, 'APPID': rec.appid})
else:
return {
'issue': 'localization'
}
url = weather_path + params
try:
f = urllib.urlopen(url)
except Exception:
f = False
if f:
ret = f.read().decode('utf-8')
result = json.loads(ret)
if result:
if "cod" in result.keys():
if result['cod'] == 200:
city = False
city2 = False
if "name" in result.keys():
city = result['name']
if not city:
if rec.method == 'address':
city = rec.city
if rec.method == 'address':
city2 = rec.city
temp = pytemperature.k2c(result['main']['temp'])
min_temp = pytemperature.k2c(result['main']['temp_min'])
max_temp = pytemperature.k2c(result['main']['temp_max'])
weather_rec = self.search([('user_id', '=', rec.user_id.id)])
now_utc = datetime.now(timezone('UTC'))
user_list = self.env['res.users'].search([('id', '=', user_id)])
if user_list.partner_id.tz:
tz = pytz.timezone(user_list.partner_id.tz)
now_pacific = now_utc.astimezone(timezone(str(tz)))
current_time = now_pacific.strftime('%d %B %Y, %I:%M%p')
vals = {
'date_weather_update': current_time,
'name': city,
'city': city2,
'user_id': user_id,
'weather': result['weather'][0]['main'],
'description': result['weather'][0]['description'],
'temp': temp,
'pressure': result['main']['pressure'],
'humidity': result['main']['humidity'],
'min_temp': min_temp,
'max_temp': max_temp,
}
if weather_rec:
weather_rec.write(vals)
return {
'issue': ''
}
else:
weather_rec.create(vals)
return {
'issue': ''
}
else:
return {
'issue': 'timezone'
}
else:
return {
'issue': 'localization'
}
else:
return {
'issue': 'bad_request'
}
else:
return {
'issue': 'internet'
}
else:
return {
'issue': 'config'
}
This is the code that I use in that module. you can just convert it into odoo11.
Thank you.

Custom data in one2many field in Odoo

I am working on this Odoo assignment. I have to make a custom module in which the requirement is like this.
There is a form say "Notebook" it contains a field that comes from 'hr.employee' i.e. Many2one. Next thing this form will contain is a table which 3 columns (Quality, Score, Comment). Now Qualities must be a master table which contains many qualities name.
I have achieved this task in the way SalesOrder form works i.e. for a particular sales order there are multiple sales lines.
But I want all the qualities to be there on form with default score value of 0.
Here is the code
Please tell me the resolution
class qualities_fields(models.Model):
_name = "ayda.qualities.fields"
_description = "Contains only Attributes"
#api.multi
def name_get(self):
data = []
for rows in self:
value = ''
value += rows.quality_name
data.append((rows.id, value))
return data
quality_name = fields.Char(string="Quality Name")
class qualities_data(models.Model):
_name = "qualities.data"
_description = "All points mandatory to be filled"
quality_id = fields.Many2one('notebook', string="Quality IDs")
quality_name = fields.Many2one('qualities.fields', string="Quality Name")
score = fields.Integer(string="Score")
comment = fields.Char(string="Comment")
class notebook(models.Model):
_name = "notebook"
_description = "Checking one2many of qualities"
def createRecords(self):
cr = self.pool.cursor()
quantity_fields = self.pool.get('qualities.fields').search(cr, self.env.uid, [])
quantity_lines = []
for field in quantity_fields:
quality_data = {
'quality_id' : self.id,
'quality_name' : field.id,
'score' : 0,
'comment' : ''
}
quantity_lines.append(quality_data)
return quantity_lines
name = fields.Many2one('hr.employee', string="Name")
qualities_line = fields.One2many('qualities.data', 'quality_id', string="Qualities Line", default=createRecords)
There's an easier way to do this, on the field definition just set the default score to 0
score = fields.Integer(string="Score", default=0)
That way all scores would be zero when they're created