Odoo Currency conversion - currency

These are the fields in my import_payment.py
transaction_date = fields.Date(string="Transaction Date",
required=True)
facts_id = fields.Char(string="Student ID",
required=True)
paid_in_lei = fields.Float(string="Amount Paid in LEI")
paid_in_euro = fields.Float(string="Amount Paid in EURO")
amount = fields.Float(string="Amount")
error_msg = fields.Char(string="Error Msg")
invoice_number = fields.Char(string="Invoice No")
invoice_id = fields.Many2one(string="Invoice",
comodel_name="account.move")
payment_id = fields.Many2one(string="Payment",
comodel_name="account.payment")
company_id = fields.Many2one('res.company', default=lambda self: self.env.company.id)
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True, store=True)
Can somebody help me to convert the "paid_in_euro" field based on the "exchange rate" of the "transaction_date" and insert it to "amount" field in "RON(Base currency)"
Sorry I am new at Odoo. Any help would be very much appreciated

You can use odoo's currency conversion function
from_currency._convert(from_amount, to_currency, company, date)

First of all convert your amount field into compute field like and make it dependable on paid_in_euro
amount = fields.Float(string="Amount", compute='_amount_in_base')
#api.depends('paid_in_euro')
def _amount_in_base(self):
if self.paid_in_euro:
amount_convert = company_currency.with_context(date=self.date).compute(self.paid_in_euro, convert_currency)

Related

Function return error in clause having ruby on rails

Good afternoon!
I have a function where she does the bank reconciliation with a .txt of the bank with the system, where she shows the number of the launch whose value is exactly equal to the one launched in the system, the problem is that there is 1 debit in the .txt that corresponds to ha several launches in the system of the same client id, in .txt I do not have the client id but the sum of the values ​​launched corresponds exactly to the debit, is there any way to do this query? ... I am trying to use the in the variable sum_lancamentos having for me returns the ids but is generating synthase error. and I believe that all this function could be improved, I just don’t know how, I’m a new RoR and I’m still getting used to good practices.
Any help is very life and thank you in advance!
def conciliacao
#conciliacao = session[:conciliacao_file]
comparacao = {}
#conciliacao.each do |key, line|
data = line[:data]
valor = line[:valor].to_f.round(2)
if line[:mov] == "D"
despesa = true
else
despesa = false
end
lancamentos = Lancamento.ativos.pagos.where(conta_id: params[:conta_id], despesa: despesa).where("lancamentos.data_pagamento BETWEEN '#{data.to_date.beginning_of_day.to_s(:db)}' AND '#{data.to_date.end_of_day.to_s(:db)}'").where(["cast(lancamentos.valor AS NUMERIC(15,2) ) = :value or
cast(lancamentos.valor_pago AS NUMERIC(15,2)) = :value ",
{ value: line[:valor] }])
unless lancamentos.blank?
lancamentos.each do |lancamento|
#puts line
#conciliacao[key][:lancamentos] = "#{lancamento.id}"
#conciliacao[key][:status] = 1
#conciliacao[key][:color] = "green lighten-4"
end
else
sum_lancamentos = Lancamento.ativos.pagos.group(:cliente_id).where(conta_id: params[:conta_id], despesa: despesa).where("lancamentos.data_pagamento BETWEEN '#{data.to_date.beginning_of_day.to_s(:db)}' AND '#{data.to_date.end_of_day.to_s(:db)}'").having(["sum(cast(lancamentos.valor AS NUMERIC(15,2) )) = :value or sum(cast(lancamentos.valor_pago AS NUMERIC(15,2))) = :value ", { value: line[:valor] }])
unless sumlancamentos.blank?
#conciliacao[key][:lancamentos] = "#{sum_lancamentos.ids}"
#conciliacao[key][:status] = 1
#conciliacao[key][:color] = "green lighten-4"
end
end
end
session.delete(:conciliacao_file)
end

Rails Import: "No Implicit conversion of string into array"

I'm attempting to import values from a spreadsheet into a table. I am adding new records for each row to an array, and then importing that array. My Code is below:
def import(path)
spreadsheet = Roo::Spreadsheet.open(path+"Data.xlsx")
sales = spreadsheet.sheet('Accounts')
sales = sales.parse(headers: true)
accounts = []
sales.each do |row|
a = HM::NewBusiness.new
a.dealer_id = row["Dlr #"]
a.dealer_name = row["Dealer Name"]
a.duns = row["Duns Name"]
a.industry = row["Type"]
a.volume_2016 = row["volume_2016"]
a.volume_2017 = row["volume_2017"]
a.volume_2018 = row["volume_2018"]
a.volume_2019 = row["volume_2019"]
accounts << a
end
pp accounts
HM::NewBusiness.import(accounts)
end
However when I run import, I get:
TypeError: no implicit conversion of String into Array
I can't figure out where I'm going wrong. Any help would be appreciated.
Figured it out. The problem was that I coincidentally named the method itself "import". In short a 1d10t error.

Conditionally add OR condition in query

The orders table have a few columns, say email, tel and address.
User provides email/tel/address, and any of them can be nil or empty string (EDITED).
How to generate an OR query, so if any of the columns match, the record is returned?
The only catch is that if any value provided is nil or empty, that will be ignored instead.
I was able to do the following using Arel:
email = params[:email]
tel = params[:tel]
address = params[:address]
t = Order.arel_table
sq = t[:email].eq(email) if email.present?
sq = sq.or(t[:phone].eq(phone)) if phone.present?
sq = sq.or(t[:phone].eq(address)) if address.present?
Order.where( sq )
However it will err if email is nil, because sq will not instantiate.
I want to prevent constructing sql string, and I use Squeel gem.
you can put
Order.where("email=? or tel= ? or address=?", params[:email], params[:tel], params[:address])
You can check whether your params are nil or not by Ick's maybe. So read about Ick gem and follow the steps given there and then you can use it in your case like :
params[:email].maybe
params[:tel].maybe
params[:address].maybe
Hope, this is what you were looking for.
Please have a try with
where_condition = "true"
where_condition += "OR email = '#{params[:email]}'" if params[:email].present?
where_condition += "OR tel = '#{params[:tel]}'" if params[:tel].present?
where_condition += "OR address = '#{params[:address]}'" if params[:address].present?
Order.where(where_condition)
In order to prevent nil or empty string, I finally got the following:
t = Order.arel_table
conditions = [:email, :phone, :address].map{|attr|
attr_value = params[attr]
if attr_value.present?
t[attr].eq(attr_value)
else
nil
end
}.compact
if conditions.empty?
Order.where('1=0')
else
Order.where( conditions.inject{|c, cc| c.or(cc).expr} )
end
Ugly, but flexible.

Wrong Number of Arguments

I understand what causes the wrong number of arguments error but my code doesn't pass any parameters to initialize any of the classes so I'm not sure at all why my code is giving me this error. I'm also pretty new to Ruby on Rails so that doesn't help things. My code is below:
def create_google_file
#products = Product.find(:all)
file = File.new('dir.xml','w')
doc = REXML::Document.new
root = REXML::Element.new "rss"
root.add_attribute("xmlns:g", "http://base.google.com/ns/1.0")
root.add_attribute("version", "2.0")
channel = REXML::Element.new "channel"
root.add_element channel
title = REXML::Element.new "title"
title.text = "Sample Google Base"
channel.add_element title
link = REXML::Element.new "link"
link.text = "http://base.google.com/base/"
channel.add_element link
description = REXML::Element.new "description"
description.text = "Information about products"
channel.add_element description
#products.each do |y|
item = channel.add_element("item")
id = item.add_element("g:id")
id.text = y.id
title = item.add_element("title")
title.text = y.title
description = item.add_element("description")
description.text = y.description
googlecategory = item.add_element("g:google_product_category")
googlecategory.text = y.googlecategory
producttype = item.add_element("g:product_type")
producttype.text = y.producttype
link = item.add_element("link")
link.text = y.link
imglink = item.add_element("g:image_link")
imglink.text = y.imglink
condition = item.add_element("condition")
condition.text = y.condition
availability = item.add_element("g:availability")
availability.text = y.availability
price = item.add_element("g:price")
price.text = y.price "USD"
gtin = item.add_element("g:gtin")
gtin.text = y.gtin
brand = item.add_element("g:brand")
brand.text = y.brand
mpn = item.add_element("g:mpn")
mpn.text = y.mpn
expirationdate = item.add_element("g:expiration_date")
expirationdate.text = y.salepricedate
end
doc.add_element root
file.puts doc
file.close
end
The error I'm getting is:
ArgumentError in ProductsController#create_google_file
wrong number of arguments (1 for 0)
At the request of the poster, I am putting my comments in to an answer:
Based purely on the consistency of the other lines, but without knowing which line is actually failing, it may be this part: price.text = y.price "USD". Is y.price a method that takes in a parameter? Is it defined as def price(type) or something? If not, if it doesn't take any parameters, then it's because you're not supposed to send any parameters to that method. It looks like it's just a getter.
#FranklinJosephMoormann As I suspected, that's the line. Were you trying to make a string like "4.50 USD"? Then you probably wanted: price.text = "#{y.price} USD". That will take the result of y.price and put it in a string, and allow you to keep typing more in the string. It's called string interpolation.

Order Django admin change list column by output of __unicode()__ method

Here's part of my Django app's models.py:
class Person(models.Model):
birth_year = WideYear(null=True, blank=True)
birth_year_uncertain = models.BooleanField()
death_year = WideYear(null=True, blank=True)
death_year_uncertain = models.BooleanField()
flourit_year = WideYear(null=True, blank=True)
flourit_year_uncertain = models.BooleanField()
FLOURIT_CHOICES = (
(u'D', u'Birth and death dates'),
(u'F', u'Flourit date'),
)
use_flourit = models.CharField('Date(s) to use', max_length=2, choices=FLOURIT_CHOICES)
index_entries = models.ManyToManyField(IndexEntry, null=True, blank=True)
def __unicode__(self):
if self.personname_set.filter(default_name__exact=True):
name = z(self.personname_set.filter(default_name__exact=True)[0])
else:
name = u'[Unnamed person]'
if self.use_flourit == u'D':
dates = '%s - %s' % (z(self.birth_year), z(self.death_year))
else:
dates = 'fl. ' + z(self.flourit_year)
return '%s (%s)' % (name, dates)
class PersonName(models.Model):
titles = models.CharField(max_length=65535, null=True, blank=True)
surname = models.CharField(max_length=255, null=True, blank=True)
first_name = models.CharField(max_length=255, null=True, blank=True)
middle_names = models.CharField(max_length=255, null=True, blank=True)
post_nominals = models.CharField(max_length=65535, null=True, blank=True)
default_name = models.BooleanField()
person = models.ForeignKey(Person, null=True, blank=True)
def __unicode__(self):
return '%s, %s %s' % (self.surname, self.first_name, self.middle_names)
class Meta:
unique_together = ("titles", "surname", "first_name", "middle_names", "post_nominals", "person")
unique_together = ("default_name", "person")
and here are the corresponding parts of my app's admin.py:
from reversion.admin import VersionAdmin
class PersonNameInline(admin.TabularInline):
model = PersonName
extra = 1
class PersonAdmin(VersionAdmin):
radio_fields = {"use_flourit": admin.HORIZONTAL}
inlines = [PersonNameInline]
admin.site.register(Person, PersonAdmin)
In the admin, this produces a change list as follows:
(source: sampablokuper.com)
As you can see, although the change list populates each row of the Person column with the output of the __unicode()__ method of the Person class, it does not order the rows of that column by the __unicode()__ method of the Person class.
How can I make it do so?
Many thanks in advance!
Django ordering is done in the database level. Unless you store the result of your unicode function in the DB, django is not going to be able to natively return results ordered in that fashion.
Storing an ordering value in the DB is probably the most expedient way to solve this problem.
Just hit the same problem, and I found the following link useful. Instead of sorting by unicode, it tries to sort by multiple columns, which may help solve the problem:
http://djangosnippets.org/snippets/2110/
Following Paul McMillan's suggestion, I added the following line to the class definition of Person:
ordering_string = models.CharField(max_length=255, null=True, blank=True)
I also put the this above the PersonName definition in models.py:
def post_save_person_and_person_name(sender, **kwargs):
person_name = kwargs['instance']
person = person_name.person
if person.ordering_string != unicode(person)[0:254]:
person.ordering_string = unicode(person)[0:254]
super(Person, person).save()
and put this below the PersonName definition in models.py:
post_save.connect(post_save_person_and_person_name, sender=PersonName)
So far, so good.
I think I might be able to improve on it by replacing the save() call above with a queryset update() . I'd welcome suggestions on that front!

Resources