Initial commit with currency
This commit is contained in:
commit
6a19f057ec
7 files changed
+402
No files matched your search
+27
@@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2007 Cedric Krier.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contact a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from currency import *
|
||||
from account import *
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
'name': 'Account',
|
||||
'version': '0.1',
|
||||
'author': 'B2CK',
|
||||
'email': 'info@b2ck.com',
|
||||
'website': 'http://www.tryton.org/',
|
||||
'category': 'Generic Modules',
|
||||
'description': 'Financial and Accounting Module',
|
||||
'depends': [
|
||||
'ir',
|
||||
'res',
|
||||
'company',
|
||||
],
|
||||
'xml': [
|
||||
'account.xml',
|
||||
'currency.xml',
|
||||
],
|
||||
}
|
||||
Whitespace-only changes.
+18
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="res.group" id="group_account">
|
||||
<field name="name">Account</field>
|
||||
</record>
|
||||
<record model="res.group" id="group_account_admin">
|
||||
<field name="name">Account admin</field>
|
||||
</record>
|
||||
<record model="res.user" id="res.user_admin">
|
||||
<field name="groups" eval="[(4, ref('group_account')), (4, ref('group_account_admin'))]"/>
|
||||
</record>
|
||||
<menuitem name="Financial Management" id="menu_account" sequence="2"
|
||||
groups="group_account,group_account_admin"/>
|
||||
<menuitem name="Configuration" parent="menu_account"
|
||||
id="menu_account_configuration" groups="group_account_admin"/>
|
||||
</data>
|
||||
</tryton>
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
"Currency"
|
||||
|
||||
from trytond.osv import fields, OSV, ExceptOSV
|
||||
import time
|
||||
|
||||
|
||||
class Currency(OSV):
|
||||
'Currency'
|
||||
_name = 'account.currency'
|
||||
_description = __doc__
|
||||
_order = 'code'
|
||||
name = fields.Char('Name', size=128, required=True, translate=True)
|
||||
code = fields.Char('Code', size=3, required=True)
|
||||
rate = fields.Function('get_rate', string='Current rate', digits=(12, 6))
|
||||
rates = fields.One2Many('account.currency.rate', 'currency', 'Rates')
|
||||
rounding = fields.Numeric('Rounding factor', digits=(12, 6))
|
||||
active = fields.Boolean('Active')
|
||||
|
||||
def default_active(self, cursor, user, context=None):
|
||||
return True
|
||||
|
||||
def default_rounding(self, cursor, user, context=None):
|
||||
return 0.01
|
||||
|
||||
def name_search(self, cursor, user, name, args=None, operator='ilike',
|
||||
context=None, limit=None):
|
||||
if args is None:
|
||||
args = []
|
||||
args_name = args[:]
|
||||
args_code = args[:]
|
||||
if name:
|
||||
args_name += [(self._rec_name, operator, name)]
|
||||
args_code += [('code', operator, name)]
|
||||
ids = self.search(cursor, user, args_code, limit=limit, context=context)
|
||||
if len(ids) != 1:
|
||||
ids += self.search(cursor, user, args_name, limit=limit,
|
||||
context=context)
|
||||
res = self.name_get(cursor, user, ids, context=context)
|
||||
return res
|
||||
|
||||
def get_rate(self, cursor, user, ids, name, arg, context=None):
|
||||
'''
|
||||
Return the rate at the date from the context or the current date
|
||||
'''
|
||||
res = {}
|
||||
rate_obj = self.pool.get('account.currency.rate')
|
||||
if context is None:
|
||||
context = {}
|
||||
date = context.get('date', time.strftime('%Y-%m-%d'))
|
||||
for currency_id in ids:
|
||||
rate_ids = rate_obj.search(cursor, user, [
|
||||
('currency', '=', currency_id),
|
||||
('date', '<=', date),
|
||||
], limit=1, order='date DESC')
|
||||
if rate_ids:
|
||||
res[currency_id] = rate_ids[0]
|
||||
else:
|
||||
res[currency_id] = 0.0
|
||||
rate_ids = [x for x in res.values() if x]
|
||||
rates = rate_obj.browse(cursor, user, rate_ids, context=context)
|
||||
id2rate = {}
|
||||
for rate in rates:
|
||||
id2rate[rate.id] = rate
|
||||
for currency_id in res.keys():
|
||||
if res[currency_id]:
|
||||
res[currency_id] = id2rate[res[currency_id]].rate
|
||||
return res
|
||||
|
||||
def round(self, cursor, user, currency, amount):
|
||||
'Round the amount depending of the currency'
|
||||
return round(amount / currency.rounding) * currency.rounding
|
||||
|
||||
def is_zero(self, cursor, user, currency, amount):
|
||||
'Return True if the amount can be considered as zero for the currency'
|
||||
return abs(self.round(cursor, user, currency, amount)) < currency.rounding
|
||||
|
||||
def compute(self, cursor, user, from_currency_id, amount, to_currency_id,
|
||||
round=True, context=None):
|
||||
'''
|
||||
Take a currency id and an amount
|
||||
Return the amount to the new currency
|
||||
Use the rate of the date of the context or the current date
|
||||
'''
|
||||
from_currency = self.browse(cursor, user, from_currency_id, context=context)
|
||||
to_currency = self.browse(cursor, user, to_currency_id, context=context)
|
||||
if (not from_currency.rate) or (not to_currency.rate):
|
||||
date = context.get('date', time.strftime('%Y-%m-%d'))
|
||||
if not from_currency.rate:
|
||||
name = from_currency.name
|
||||
else:
|
||||
name = to_currency.name
|
||||
raise ExceptOSV('UserError', 'No rate found \n' \
|
||||
'for the currency: %s \n' \
|
||||
'at the date: %s' % (name, date))
|
||||
if to_currency == from_currency:
|
||||
if round:
|
||||
return self.round(cursor, user, to_currency, amount)
|
||||
else:
|
||||
return amount
|
||||
else:
|
||||
if round:
|
||||
return self.round(cursor, user, to_currency,
|
||||
amount * to_currency.rate / from_currency.rate)
|
||||
else:
|
||||
return amount * to_currency.rate / from_currency.rate
|
||||
|
||||
Currency()
|
||||
|
||||
|
||||
class Rate(OSV):
|
||||
'Rate'
|
||||
_name = 'account.currency.rate'
|
||||
_description = __doc__
|
||||
_rec_name = 'date'
|
||||
_order = 'date DESC'
|
||||
date = fields.Date('Date', required=True, select=1)
|
||||
rate = fields.Numeric('Rate', digits=(12, 6), required=1)
|
||||
currency = fields.Many2One('account.currency', 'Currency')
|
||||
|
||||
def __init__(self):
|
||||
super(Rate, self).__init__()
|
||||
self._sql_constraints = [
|
||||
('date_currency_uniq', 'UNIQUE(date, currency)',
|
||||
'A currency can only have one rate by date!'),
|
||||
]
|
||||
|
||||
def default_date(self, cursor, user, context=None):
|
||||
return time.strftime('%Y-%m-%d')
|
||||
|
||||
Rate()
|
||||
|
||||
|
||||
class Company(OSV):
|
||||
_name = 'company.company'
|
||||
currency = fields.Many2One('account.currency', 'Currency', required=True)
|
||||
|
||||
Company()
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
<?xml version="1.0"?>
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="currency_view_form">
|
||||
<field name="model">account.currency</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Currency" col="6">
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<label name="active"/>
|
||||
<field name="active" xexpand="0" width="100"/>
|
||||
<label name="rounding"/>
|
||||
<field name="rounding"/>
|
||||
<label name="rate"/>
|
||||
<field name="rate"/>
|
||||
<field name="rates" colspan="6" mode="tree,form">
|
||||
<tree string="Rates">
|
||||
<field name="date"/>
|
||||
<field name="rate"/>
|
||||
</tree>
|
||||
<form string="Rate">
|
||||
<label name="date"/>
|
||||
<field name="date"/>
|
||||
<label name="rate"/>
|
||||
<field name="rate"/>
|
||||
</form>
|
||||
</field>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="currency_view_tree">
|
||||
<field name="model">account.currency</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Currencies">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="rate"/>
|
||||
<field name="active" tree_invisible="1" select="2"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_currency_form">
|
||||
<field name="name">Currencies</field>
|
||||
<field name="res_model">account.currency</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_currency_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="currency_view_tree"/>
|
||||
<field name="act_window" ref="act_currency_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_currency_form_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="currency_view_form"/>
|
||||
<field name="act_window" ref="act_currency_form"/>
|
||||
</record>
|
||||
<menuitem parent="menu_account_configuration" action="act_currency_form"
|
||||
id="menu_currency_form"/>
|
||||
<record model="ir.model.access" id="access_currency">
|
||||
<field name="model" search="[('model', '=', 'account.currency')]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_currency_account_admin">
|
||||
<field name="model" search="[('model', '=', 'account.currency')]"/>
|
||||
<field name="group" ref="group_account_admin"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="company_view_form">
|
||||
<field name="model">company.company</field>
|
||||
<field name="inherit" ref="company.company_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<data>
|
||||
<xpath
|
||||
expr="/form/field[@name="parent"]"
|
||||
position="after">
|
||||
<label name="currency"/>
|
||||
<field name="currency"/>
|
||||
</xpath>
|
||||
</data>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="company_view_tree">
|
||||
<field name="model">company.company</field>
|
||||
<field name="inherit" ref="company.company_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<data>
|
||||
<xpath
|
||||
expr="/tree/field[@name="partner"]"
|
||||
position="after">
|
||||
<field name="currency" select="1"/>
|
||||
</xpath>
|
||||
</data>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_currency_rate">
|
||||
<field name="model" search="[('model', '=', 'account.currency.rate')]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_currency_rate_account_admin">
|
||||
<field name="model" search="[('model', '=', 'account.currency.rate')]"/>
|
||||
<field name="group" ref="group_account_admin"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
</record>
|
||||
<record model="account.currency" id="eur">
|
||||
<field name="name">Euro</field>
|
||||
<field name="code">EUR</field>
|
||||
<field name="rounding" eval="0.01"/>
|
||||
</record>
|
||||
<record model="account.currency.rate" id="eur_rate">
|
||||
<field name="date" eval="time.strftime('%Y-01-01')"/>
|
||||
<field name="rate" eval="1.0"/>
|
||||
<field name="currency" ref="eur"/>
|
||||
</record>
|
||||
<record model="account.currency" id="usd">
|
||||
<field name="name">United States dollar</field>
|
||||
<field name="code">USD</field>
|
||||
<field name="rounding" eval="0.01"/>
|
||||
</record>
|
||||
<record model="account.currency" id="chf">
|
||||
<field name="name">Swiss franc</field>
|
||||
<field name="code">CHF</field>
|
||||
<field name="rounding" eval="0.01"/>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from distutils.core import setup
|
||||
from distutils.command import sdist
|
||||
|
||||
|
||||
class mysdist(sdist.sdist):
|
||||
|
||||
def add_defaults(self):
|
||||
sdist.sdist.add_defaults(self)
|
||||
if self.distribution.has_pure_modules():
|
||||
build_py = self.get_finalized_command('build_py')
|
||||
data = []
|
||||
for package in build_py.packages:
|
||||
src_dir = build_py.get_package_dir(package)
|
||||
data.extend(build_py.find_data_files(package, src_dir))
|
||||
self.filelist.extend(data)
|
||||
|
||||
info = eval(file('__tryton__.py').read())
|
||||
|
||||
requires = ['trytond'] + ['trytond-' + x for x in info.get('depends', [])]
|
||||
|
||||
setup(name='trytond-' + info['name'].lower(),
|
||||
version=info.get('version', '0'),
|
||||
description=info.get('description', ''),
|
||||
author=info.get('author', ''),
|
||||
author_email=info.get('email', ''),
|
||||
url=info.get('website', ''),
|
||||
package_dir={'trytond.modules.' + info['name'].lower(): '.'},
|
||||
packages=[
|
||||
'trytond.modules.' + info['name'].lower(),
|
||||
],
|
||||
package_data={
|
||||
'trytond.modules.' + info['name'].lower(): info.get('xml', []),
|
||||
},
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
'Intended Audience :: Developers',
|
||||
'Intended Audience :: Financial and Insurance Industry',
|
||||
'Intended Audience :: Legal Industry',
|
||||
'Natural Language :: English',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Topic :: Office/Business',
|
||||
'Topic :: Office/Business :: Financial :: Accounting',
|
||||
],
|
||||
license=info.get('license', 'GPL-2'),
|
||||
#requires=requires,
|
||||
cmdclass={
|
||||
'sdist': mysdist,
|
||||
},
|
||||
)
|
||||
Reference in new issue
Block a user