[MERGE] Upgrade to v7.0. Make the dates visible to everyone - if you don't want to see them, just uninstall the module.

bzr revid: ls@numerigraphe.com-20130717103317-cf22a6614c4wzmv9
This commit is contained in:
Lionel Sausin 2013-07-17 12:33:17 +02:00
commit eafd60ebd4
10481 changed files with 2608342 additions and 2403148 deletions

View File

@ -19,10 +19,10 @@
#
##############################################################################
import partner
import account
import installer
import project
import partner
import account_invoice
import account_bank_statement
import account_bank
@ -37,4 +37,6 @@ import ir_sequence
import company
import res_currency
import edi
import res_config
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -19,42 +19,38 @@
#
##############################################################################
{
"name" : "eInvoicing",
"version" : "1.1",
"author" : "OpenERP SA",
"category": 'Accounting & Finance',
'complexity': "easy",
"description": """
'name' : 'eInvoicing',
'version' : '1.1',
'author' : 'OpenERP SA',
'category' : 'Accounting & Finance',
'description' : """
Accounting and Financial Management.
====================================
Financial and accounting module that covers:
--------------------------------------------
General accountings
Cost / Analytic accounting
Third party accounting
Taxes management
Budgets
Customer and Supplier Invoices
Bank statements
Reconciliation process by partner
* General Accounting
* Cost/Analytic accounting
* Third party accounting
* Taxes management
* Budgets
* Customer and Supplier Invoices
* Bank statements
* Reconciliation process by partner
Creates a dashboard for accountants that includes:
--------------------------------------------------
* List of Customer Invoice to Approve
* Company Analysis
* Graph of Aged Receivables
* Graph of Treasury
* List of Customer Invoice to Approve
* Company Analysis
* Graph of Treasury
The processes like maintaining of general ledger is done through the defined financial Journals (entry move line or
grouping is maintained through journal) for a particular financial year and for preparation of vouchers there is a
module named account_voucher.
The processes like maintaining of general ledger is done through the defined financial Journals (entry move line orgrouping is maintained through journal)
for a particular financial year and for preparation of vouchers there is a module named account_voucher.
""",
'website': 'http://www.openerp.com',
'images' : ['images/accounts.jpeg','images/bank_statement.jpeg','images/cash_register.jpeg','images/chart_of_accounts.jpeg','images/customer_invoice.jpeg','images/journal_entries.jpeg'],
'init_xml': [],
"depends" : ["base_setup", "product", "analytic", "process", "board", "edi"],
'update_xml': [
'depends' : ['base_setup', 'product', 'analytic', 'process', 'board', 'edi'],
'data': [
'security/account_security.xml',
'security/ir.model.access.csv',
'account_menuitem.xml',
@ -67,6 +63,8 @@ module named account_voucher.
'wizard/account_use_model_view.xml',
'account_installer.xml',
'wizard/account_period_close_view.xml',
'wizard/account_reconcile_view.xml',
'wizard/account_unreconcile_view.xml',
'account_view.xml',
'account_report.xml',
'account_financial_report_data.xml',
@ -75,7 +73,6 @@ module named account_voucher.
'wizard/account_fiscalyear_close_state.xml',
'wizard/account_chart_view.xml',
'wizard/account_tax_chart_view.xml',
'wizard/account_move_journal_view.xml',
'wizard/account_move_line_reconcile_select_view.xml',
'wizard/account_open_closed_fiscalyear_view.xml',
'wizard/account_move_line_unreconcile_select_view.xml',
@ -89,23 +86,23 @@ module named account_voucher.
'wizard/account_journal_select_view.xml',
'wizard/account_change_currency_view.xml',
'wizard/account_validate_move_view.xml',
'wizard/account_unreconcile_view.xml',
'wizard/account_report_general_ledger_view.xml',
'wizard/account_invoice_state_view.xml',
'wizard/account_report_partner_balance_view.xml',
'wizard/account_report_account_balance_view.xml',
'wizard/account_report_aged_partner_balance_view.xml',
'wizard/account_report_partner_ledger_view.xml',
'wizard/account_reconcile_view.xml',
'wizard/account_reconcile_partner_process_view.xml',
'wizard/account_automatic_reconcile_view.xml',
'wizard/account_financial_report_view.xml',
'wizard/pos_box.xml',
'project/wizard/project_account_analytic_line_view.xml',
'account_end_fy.xml',
'account_invoice_view.xml',
'partner_view.xml',
'data/account_data.xml',
'data/data_account_type.xml',
'data/configurable_account_chart.xml',
'account_invoice_workflow.xml',
'project/project_view.xml',
'project/project_report.xml',
@ -123,17 +120,30 @@ module named account_voucher.
'ir_sequence_view.xml',
'company_view.xml',
'board_account_view.xml',
"edi/invoice_action_data.xml",
"account_bank_view.xml",
"account_pre_install.yml"
'edi/invoice_action_data.xml',
'account_bank_view.xml',
'res_config_view.xml',
'account_pre_install.yml'
],
'demo_xml': [
'js': [
'static/src/js/account_move_reconciliation.js',
'static/src/js/account_move_line_quickadd.js',
],
'qweb' : [
"static/src/xml/account_move_reconciliation.xml",
"static/src/xml/account_move_line_quickadd.xml",
],
'css':[
'static/src/css/account_move_reconciliation.css',
'static/src/css/account_move_line_quickadd.css'
],
'demo': [
'demo/account_demo.xml',
'project/project_demo.xml',
'project/analytic_account_demo.xml',
'demo/account_minimal.xml',
'demo/account_invoice_demo.xml',
# 'account_unit_test.xml',
'account_unit_test.xml',
],
'test': [
'test/account_customer_invoice.yml',
@ -144,14 +154,13 @@ module named account_voucher.
'test/account_use_model.yml',
'test/account_validate_account_move.yml',
'test/account_fiscalyear_close.yml',
'test/account_bank_statement.yml',
'test/account_cash_statement.yml',
#'test/account_bank_statement.yml',
#'test/account_cash_statement.yml',
'test/test_edi_invoice.yml',
'test/account_report.yml',
'test/account_fiscalyear_close_state.yml', #last test, as it will definitively close the demo fiscalyear
],
'installable': True,
'active': False,
'certificate': '0080331923549',
'auto_install': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

File diff suppressed because it is too large Load Diff

View File

@ -19,29 +19,26 @@
#
##############################################################################
import time
from osv import fields
from osv import osv
from tools.translate import _
from openerp.osv import fields
from openerp.osv import osv
from openerp.tools.translate import _
class account_analytic_line(osv.osv):
_inherit = 'account.analytic.line'
_description = 'Analytic Line'
_columns = {
'product_uom_id': fields.many2one('product.uom', 'UoM'),
'product_uom_id': fields.many2one('product.uom', 'Unit of Measure'),
'product_id': fields.many2one('product.product', 'Product'),
'general_account_id': fields.many2one('account.account', 'General Account', required=True, ondelete='restrict'),
'move_id': fields.many2one('account.move.line', 'Move Line', ondelete='cascade', select=True),
'journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal', required=True, ondelete='restrict', select=True),
'code': fields.char('Code', size=8),
'ref': fields.char('Ref.', size=64),
'currency_id': fields.related('move_id', 'currency_id', type='many2one', relation='res.currency', string='Account currency', store=True, help="The related account currency if not equal to the company one.", readonly=True),
'amount_currency': fields.related('move_id', 'amount_currency', type='float', string='Amount currency', store=True, help="The amount expressed in the related account currency if not equal to the company one.", readonly=True),
'currency_id': fields.related('move_id', 'currency_id', type='many2one', relation='res.currency', string='Account Currency', store=True, help="The related account currency if not equal to the company one.", readonly=True),
'amount_currency': fields.related('move_id', 'amount_currency', type='float', string='Amount Currency', store=True, help="The amount expressed in the related account currency if not equal to the company one.", readonly=True),
}
_defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d'),
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.analytic.line', context=c),
}
_order = 'date desc'
@ -85,22 +82,22 @@ class account_analytic_line(osv.osv):
if j_id.type == 'purchase':
unit = prod.uom_po_id.id
if j_id.type <> 'sale':
a = prod.product_tmpl_id.property_account_expense.id
a = prod.property_account_expense.id
if not a:
a = prod.categ_id.property_account_expense_categ.id
if not a:
raise osv.except_osv(_('Error !'),
raise osv.except_osv(_('Error!'),
_('There is no expense account defined ' \
'for this product: "%s" (id:%d)') % \
'for this product: "%s" (id:%d).') % \
(prod.name, prod.id,))
else:
a = prod.product_tmpl_id.property_account_income.id
a = prod.property_account_income.id
if not a:
a = prod.categ_id.property_account_income_categ.id
if not a:
raise osv.except_osv(_('Error !'),
raise osv.except_osv(_('Error!'),
_('There is no income account defined ' \
'for this product: "%s" (id:%d)') % \
'for this product: "%s" (id:%d).') % \
(prod.name, prod_id,))
flag = False
@ -110,7 +107,7 @@ class account_analytic_line(osv.osv):
if journal_id:
journal = analytic_journal_obj.browse(cr, uid, journal_id, context=context)
if journal.type == 'sale':
product_price_type_ids = product_price_type_obj.search(cr, uid, [('field','=','list_price')], context)
product_price_type_ids = product_price_type_obj.search(cr, uid, [('field','=','list_price')], context=context)
if product_price_type_ids:
pricetype = product_price_type_obj.browse(cr, uid, product_price_type_ids, context=context)[0]
# Take the company currency as the reference one

View File

@ -19,20 +19,22 @@
#
##############################################################################
from tools.translate import _
from osv import fields, osv
from openerp.tools.translate import _
from openerp.osv import fields, osv
class bank(osv.osv):
_inherit = "res.partner.bank"
_columns = {
'journal_id': fields.many2one('account.journal', 'Account Journal', help="This journal will be created automatically for this bank account when you save the record"),
'currency_id': fields.related('journal_id', 'currency', type="many2one", relation='res.currency', readonly=True,
string="Currency", help="Currency of the related account journal."),
}
def create(self, cr, uid, data, context={}):
def create(self, cr, uid, data, context=None):
result = super(bank, self).create(cr, uid, data, context=context)
self.post_write(cr, uid, [result], context=context)
return result
def write(self, cr, uid, ids, data, context={}):
def write(self, cr, uid, ids, data, context=None):
result = super(bank, self).write(cr, uid, ids, data, context=context)
self.post_write(cr, uid, ids, context=context)
return result
@ -41,7 +43,17 @@ class bank(osv.osv):
"Return the name to use when creating a bank journal"
return (bank.bank_name or '') + ' ' + bank.acc_number
def post_write(self, cr, uid, ids, context={}):
def _prepare_name_get(self, cr, uid, bank_dicts, context=None):
"""Add ability to have %(currency_name)s in the format_layout of res.partner.bank.type"""
currency_ids = list(set(data['currency_id'][0] for data in bank_dicts if data.get('currency_id')))
currencies = self.pool.get('res.currency').browse(cr, uid, currency_ids, context=context)
currency_name = dict((currency.id, currency.name) for currency in currencies)
for data in bank_dicts:
data['currency_name'] = data.get('currency_id') and currency_name[data['currency_id'][0]] or ''
return super(bank, self)._prepare_name_get(cr, uid, bank_dicts, context=context)
def post_write(self, cr, uid, ids, context=None):
if isinstance(ids, (int, long)):
ids = [ids]
@ -53,7 +65,7 @@ class bank(osv.osv):
# Find the code and parent of the bank account to create
dig = 6
current_num = 1
ids = obj_acc.search(cr, uid, [('type','=','liquidity')], context=context)
ids = obj_acc.search(cr, uid, [('type','=','liquidity'), ('company_id', '=', bank.company_id.id)], context=context)
# No liquidity account exists, no template available
if not ids: continue
@ -77,11 +89,6 @@ class bank(osv.osv):
}
acc_bank_id = obj_acc.create(cr,uid,acc,context=context)
# Get the journal view id
data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view')])
data = obj_data.browse(cr, uid, data_id[0], context=context)
view_id_cash = data.res_id
jour_obj = self.pool.get('account.journal')
new_code = 1
while True:
@ -100,7 +107,6 @@ class bank(osv.osv):
'analytic_journal_id': False,
'default_credit_account_id': acc_bank_id,
'default_debit_account_id': acc_bank_id,
'view_id': view_id_cash
}
journal_id = jour_obj.create(cr, uid, vals_journal, context=context)

View File

@ -21,29 +21,23 @@
import time
from osv import fields, osv
from tools.translate import _
import decimal_precision as dp
from openerp.osv import fields, osv
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp
class account_bank_statement(osv.osv):
def create(self, cr, uid, vals, context=None):
seq = 0
if 'line_ids' in vals:
new_line_ids = []
for line in vals['line_ids']:
seq += 1
line[2]['sequence'] = seq
for idx, line in enumerate(vals['line_ids']):
line[2]['sequence'] = idx + 1
return super(account_bank_statement, self).create(cr, uid, vals, context=context)
def write(self, cr, uid, ids, vals, context=None):
res = super(account_bank_statement, self).write(cr, uid, ids, vals, context=context)
account_bank_statement_line_obj = self.pool.get('account.bank.statement.line')
for statement in self.browse(cr, uid, ids, context):
seq = 0
for line in statement.line_ids:
seq += 1
account_bank_statement_line_obj.write(cr, uid, [line.id], {'sequence': seq}, context=context)
for idx, line in enumerate(statement.line_ids):
account_bank_statement_line_obj.write(cr, uid, [line.id], {'sequence': idx + 1}, context=context)
return res
def _default_journal_id(self, cr, uid, context=None):
@ -51,48 +45,23 @@ class account_bank_statement(osv.osv):
context = {}
journal_pool = self.pool.get('account.journal')
journal_type = context.get('journal_type', False)
journal_id = False
company_id = self.pool.get('res.company')._company_default_get(cr, uid, 'account.bank.statement',context=context)
if journal_type:
ids = journal_pool.search(cr, uid, [('type', '=', journal_type)])
ids = journal_pool.search(cr, uid, [('type', '=', journal_type),('company_id','=',company_id)])
if ids:
journal_id = ids[0]
return journal_id
return ids[0]
return False
def _end_balance(self, cursor, user, ids, name, attr, context=None):
res_currency_obj = self.pool.get('res.currency')
res_users_obj = self.pool.get('res.users')
res = {}
company_currency_id = res_users_obj.browse(cursor, user, user,
context=context).company_id.currency_id.id
statements = self.browse(cursor, user, ids, context=context)
for statement in statements:
for statement in self.browse(cursor, user, ids, context=context):
res[statement.id] = statement.balance_start
currency_id = statement.currency.id
for line in statement.move_line_ids:
if line.debit > 0:
if line.account_id.id == \
statement.journal_id.default_debit_account_id.id:
res[statement.id] += res_currency_obj.compute(cursor,
user, company_currency_id, currency_id,
line.debit, context=context)
else:
if line.account_id.id == \
statement.journal_id.default_credit_account_id.id:
res[statement.id] -= res_currency_obj.compute(cursor,
user, company_currency_id, currency_id,
line.credit, context=context)
if statement.state in ('draft', 'open'):
for line in statement.line_ids:
res[statement.id] += line.amount
for r in res:
res[r] = round(res[r], 2)
for line in statement.line_ids:
res[statement.id] += line.amount
return res
def _get_period(self, cr, uid, context=None):
periods = self.pool.get('account.period').find(cr, uid)
periods = self.pool.get('account.period').find(cr, uid,context=context)
if periods:
return periods[0]
return False
@ -126,8 +95,9 @@ class account_bank_statement(osv.osv):
_order = "date desc, id desc"
_name = "account.bank.statement"
_description = "Bank Statement"
_inherit = ['mail.thread']
_columns = {
'name': fields.char('Name', size=64, required=True, states={'draft': [('readonly', False)]}, readonly=True, help='if you give the Name other then /, its created Accounting Entries Move will be with same name as statement name. This allows the statement entries to have the same references than the statement itself'), # readonly for account_cash_statement
'name': fields.char('Reference', size=64, required=True, states={'draft': [('readonly', False)]}, readonly=True, help='if you give the Name other then /, its created Accounting Entries Move will be with same name as statement name. This allows the statement entries to have the same references than the statement itself'), # readonly for account_cash_statement
'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}, select=True),
'journal_id': fields.many2one('account.journal', 'Journal', required=True,
readonly=True, states={'draft':[('readonly',False)]}),
@ -139,7 +109,7 @@ class account_bank_statement(osv.osv):
states={'confirm': [('readonly', True)]}),
'balance_end': fields.function(_end_balance,
store = {
'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids'], 10),
'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids','balance_start'], 10),
'account.bank.statement.line': (_get_statement, ['amount'], 10),
},
string="Computed Balance", help='Balance as calculated based on Starting Balance and transaction lines'),
@ -152,9 +122,9 @@ class account_bank_statement(osv.osv):
'state': fields.selection([('draft', 'New'),
('open','Open'), # used by cash statements
('confirm', 'Closed')],
'State', required=True, readonly="1",
help='When new statement is created the state will be \'Draft\'.\n'
'And after getting confirmation from the bank it will be in \'Confirmed\' state.'),
'Status', required=True, readonly="1",
help='When new statement is created the status will be \'Draft\'.\n'
'And after getting confirmation from the bank it will be in \'Confirmed\' status.'),
'currency': fields.function(_currency, string='Currency',
type='many2one', relation='res.currency'),
'account_id': fields.related('journal_id', 'default_debit_account_id', type='many2one', relation='account.account', string='Account used in this journal', readonly=True, help='used in statement reconciliation domain, but shouldn\'t be used elswhere.'),
@ -162,37 +132,38 @@ class account_bank_statement(osv.osv):
_defaults = {
'name': "/",
'date': lambda *a: time.strftime('%Y-%m-%d'),
'date': fields.date.context_today,
'state': 'draft',
'journal_id': _default_journal_id,
'period_id': _get_period,
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.bank.statement',context=c),
}
def onchange_date(self, cr, user, ids, date, context=None):
def _check_company_id(self, cr, uid, ids, context=None):
for statement in self.browse(cr, uid, ids, context=context):
if statement.company_id.id != statement.period_id.company_id.id:
return False
return True
_constraints = [
(_check_company_id, 'The journal and period chosen have to belong to the same company.', ['journal_id','period_id']),
]
def onchange_date(self, cr, uid, ids, date, company_id, context=None):
"""
Returns a dict that contains new values and context
@param cr: A database cursor
@param user: ID of the user currently logged in
@param date: latest value from user input for field date
@param args: other arguments
@param context: context arguments, like lang, time zone
@return: Returns a dict which contains new values, and context
Find the correct period to use for the given date and company_id, return it and set it in the context
"""
res = {}
period_pool = self.pool.get('account.period')
if context is None:
context = {}
pids = period_pool.search(cr, user, [('date_start','<=',date), ('date_stop','>=',date)])
ctx = context.copy()
ctx.update({'company_id': company_id})
pids = period_pool.find(cr, uid, dt=date, context=ctx)
if pids:
res.update({
'period_id':pids[0]
})
context.update({
'period_id':pids[0]
})
res.update({'period_id': pids[0]})
context.update({'period_id': pids[0]})
return {
'value':res,
@ -202,7 +173,158 @@ class account_bank_statement(osv.osv):
def button_dummy(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {}, context=context)
def _prepare_move(self, cr, uid, st_line, st_line_number, context=None):
"""Prepare the dict of values to create the move from a
statement line. This method may be overridden to implement custom
move generation (making sure to call super() to establish
a clean extension chain).
:param browse_record st_line: account.bank.statement.line record to
create the move from.
:param char st_line_number: will be used as the name of the generated account move
:return: dict of value to create() the account.move
"""
return {
'journal_id': st_line.statement_id.journal_id.id,
'period_id': st_line.statement_id.period_id.id,
'date': st_line.date,
'name': st_line_number,
'ref': st_line.ref,
}
def _prepare_bank_move_line(self, cr, uid, st_line, move_id, amount, company_currency_id,
context=None):
"""Compute the args to build the dict of values to create the bank move line from a
statement line by calling the _prepare_move_line_vals. This method may be
overridden to implement custom move generation (making sure to call super() to
establish a clean extension chain).
:param browse_record st_line: account.bank.statement.line record to
create the move from.
:param int/long move_id: ID of the account.move to link the move line
:param float amount: amount of the move line
:param int/long company_currency_id: ID of currency of the concerned company
:return: dict of value to create() the bank account.move.line
"""
anl_id = st_line.analytic_account_id and st_line.analytic_account_id.id or False
debit = ((amount<0) and -amount) or 0.0
credit = ((amount>0) and amount) or 0.0
cur_id = False
amt_cur = False
if st_line.statement_id.currency.id <> company_currency_id:
cur_id = st_line.statement_id.currency.id
if st_line.account_id and st_line.account_id.currency_id and st_line.account_id.currency_id.id <> company_currency_id:
cur_id = st_line.account_id.currency_id.id
if cur_id:
res_currency_obj = self.pool.get('res.currency')
amt_cur = -res_currency_obj.compute(cr, uid, company_currency_id, cur_id, amount, context=context)
res = self._prepare_move_line_vals(cr, uid, st_line, move_id, debit, credit,
amount_currency=amt_cur, currency_id=cur_id, analytic_id=anl_id, context=context)
return res
def _get_counter_part_account(sefl, cr, uid, st_line, context=None):
"""Retrieve the account to use in the counterpart move.
This method may be overridden to implement custom move generation (making sure to
call super() to establish a clean extension chain).
:param browse_record st_line: account.bank.statement.line record to
create the move from.
:return: int/long of the account.account to use as counterpart
"""
if st_line.amount >= 0:
return st_line.statement_id.journal_id.default_credit_account_id.id
return st_line.statement_id.journal_id.default_debit_account_id.id
def _get_counter_part_partner(sefl, cr, uid, st_line, context=None):
"""Retrieve the partner to use in the counterpart move.
This method may be overridden to implement custom move generation (making sure to
call super() to establish a clean extension chain).
:param browse_record st_line: account.bank.statement.line record to
create the move from.
:return: int/long of the res.partner to use as counterpart
"""
return st_line.partner_id and st_line.partner_id.id or False
def _prepare_counterpart_move_line(self, cr, uid, st_line, move_id, amount, company_currency_id,
context=None):
"""Compute the args to build the dict of values to create the counter part move line from a
statement line by calling the _prepare_move_line_vals. This method may be
overridden to implement custom move generation (making sure to call super() to
establish a clean extension chain).
:param browse_record st_line: account.bank.statement.line record to
create the move from.
:param int/long move_id: ID of the account.move to link the move line
:param float amount: amount of the move line
:param int/long account_id: ID of account to use as counter part
:param int/long company_currency_id: ID of currency of the concerned company
:return: dict of value to create() the bank account.move.line
"""
account_id = self._get_counter_part_account(cr, uid, st_line, context=context)
partner_id = self._get_counter_part_partner(cr, uid, st_line, context=context)
debit = ((amount > 0) and amount) or 0.0
credit = ((amount < 0) and -amount) or 0.0
cur_id = False
amt_cur = False
if st_line.statement_id.currency.id <> company_currency_id:
amt_cur = st_line.amount
cur_id = st_line.statement_id.currency.id
return self._prepare_move_line_vals(cr, uid, st_line, move_id, debit, credit,
amount_currency = amt_cur, currency_id = cur_id, account_id = account_id,
partner_id = partner_id, context=context)
def _prepare_move_line_vals(self, cr, uid, st_line, move_id, debit, credit, currency_id = False,
amount_currency= False, account_id = False, analytic_id = False,
partner_id = False, context=None):
"""Prepare the dict of values to create the move line from a
statement line. All non-mandatory args will replace the default computed one.
This method may be overridden to implement custom move generation (making sure to
call super() to establish a clean extension chain).
:param browse_record st_line: account.bank.statement.line record to
create the move from.
:param int/long move_id: ID of the account.move to link the move line
:param float debit: debit amount of the move line
:param float credit: credit amount of the move line
:param int/long currency_id: ID of currency of the move line to create
:param float amount_currency: amount of the debit/credit expressed in the currency_id
:param int/long account_id: ID of the account to use in the move line if different
from the statement line account ID
:param int/long analytic_id: ID of analytic account to put on the move line
:param int/long partner_id: ID of the partner to put on the move line
:return: dict of value to create() the account.move.line
"""
acc_id = account_id or st_line.account_id.id
cur_id = currency_id or st_line.statement_id.currency.id
par_id = partner_id or (((st_line.partner_id) and st_line.partner_id.id) or False)
return {
'name': st_line.name,
'date': st_line.date,
'ref': st_line.ref,
'move_id': move_id,
'partner_id': par_id,
'account_id': acc_id,
'credit': credit,
'debit': debit,
'statement_id': st_line.statement_id.id,
'journal_id': st_line.statement_id.journal_id.id,
'period_id': st_line.statement_id.period_id.id,
'currency_id': amount_currency and cur_id,
'amount_currency': amount_currency,
'analytic_account_id': analytic_id,
}
def create_move_from_st_line(self, cr, uid, st_line_id, company_currency_id, st_line_number, context=None):
"""Create the account move from the statement line.
:param int/long st_line_id: ID of the account.bank.statement.line to create the move from.
:param int/long company_currency_id: ID of the res.currency of the company
:param char st_line_number: will be used as the name of the generated account move
:return: ID of the account.move created
"""
if context is None:
context = {}
res_currency_obj = self.pool.get('res.currency')
@ -214,89 +336,35 @@ class account_bank_statement(osv.osv):
context.update({'date': st_line.date})
move_id = account_move_obj.create(cr, uid, {
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
'date': st_line.date,
'name': st_line_number,
'ref': st_line.ref,
}, context=context)
move_vals = self._prepare_move(cr, uid, st_line, st_line_number, context=context)
move_id = account_move_obj.create(cr, uid, move_vals, context=context)
account_bank_statement_line_obj.write(cr, uid, [st_line.id], {
'move_ids': [(4, move_id, False)]
})
torec = []
if st_line.amount >= 0:
account_id = st.journal_id.default_credit_account_id.id
else:
account_id = st.journal_id.default_debit_account_id.id
acc_cur = ((st_line.amount<=0) and st.journal_id.default_debit_account_id) or st_line.account_id
context.update({
'res.currency.compute.account': acc_cur,
})
amount = res_currency_obj.compute(cr, uid, st.currency.id,
company_currency_id, st_line.amount, context=context)
val = {
'name': st_line.name,
'date': st_line.date,
'ref': st_line.ref,
'move_id': move_id,
'partner_id': ((st_line.partner_id) and st_line.partner_id.id) or False,
'account_id': (st_line.account_id) and st_line.account_id.id,
'credit': ((amount>0) and amount) or 0.0,
'debit': ((amount<0) and -amount) or 0.0,
'statement_id': st.id,
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
'currency_id': st.currency.id,
'analytic_account_id': st_line.analytic_account_id and st_line.analytic_account_id.id or False
}
if st.currency.id <> company_currency_id:
amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
st.currency.id, amount, context=context)
val['amount_currency'] = -amount_cur
if st_line.account_id and st_line.account_id.currency_id and st_line.account_id.currency_id.id <> company_currency_id:
val['currency_id'] = st_line.account_id.currency_id.id
amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
st_line.account_id.currency_id.id, amount, context=context)
val['amount_currency'] = -amount_cur
move_line_id = account_move_line_obj.create(cr, uid, val, context=context)
bank_move_vals = self._prepare_bank_move_line(cr, uid, st_line, move_id, amount,
company_currency_id, context=context)
move_line_id = account_move_line_obj.create(cr, uid, bank_move_vals, context=context)
torec.append(move_line_id)
# Fill the secondary amount/currency
# if currency is not the same than the company
amount_currency = False
currency_id = False
if st.currency.id <> company_currency_id:
amount_currency = st_line.amount
currency_id = st.currency.id
account_move_line_obj.create(cr, uid, {
'name': st_line.name,
'date': st_line.date,
'ref': st_line.ref,
'move_id': move_id,
'partner_id': ((st_line.partner_id) and st_line.partner_id.id) or False,
'account_id': account_id,
'credit': ((amount < 0) and -amount) or 0.0,
'debit': ((amount > 0) and amount) or 0.0,
'statement_id': st.id,
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
'amount_currency': amount_currency,
'currency_id': currency_id,
}, context=context)
counterpart_move_vals = self._prepare_counterpart_move_line(cr, uid, st_line, move_id,
amount, company_currency_id, context=context)
account_move_line_obj.create(cr, uid, counterpart_move_vals, context=context)
for line in account_move_line_obj.browse(cr, uid, [x.id for x in
account_move_obj.browse(cr, uid, move_id,
context=context).line_id],
context=context):
if line.state <> 'valid':
raise osv.except_osv(_('Error !'),
raise osv.except_osv(_('Error!'),
_('Journal item "%s" is not valid.') % line.name)
# Bank statements will not consider boolean on journal entry_posted
@ -308,8 +376,8 @@ class account_bank_statement(osv.osv):
def balance_check(self, cr, uid, st_id, journal_type='bank', context=None):
st = self.browse(cr, uid, st_id, context=context)
if not ((abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001) or (abs((st.balance_end or 0.0) - st.balance_end_cash) < 0.0001)):
raise osv.except_osv(_('Error !'),
if not ((abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001) or (abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001)):
raise osv.except_osv(_('Error!'),
_('The statement balance is incorrect !\nThe expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end))
return True
@ -333,21 +401,21 @@ class account_bank_statement(osv.osv):
self.balance_check(cr, uid, st.id, journal_type=j_type, context=context)
if (not st.journal_id.default_credit_account_id) \
or (not st.journal_id.default_debit_account_id):
raise osv.except_osv(_('Configuration Error !'),
raise osv.except_osv(_('Configuration Error!'),
_('Please verify that an account is defined in the journal.'))
if not st.name == '/':
st_number = st.name
else:
c = {'fiscalyear_id': st.period_id.fiscalyear_id.id}
if st.journal_id.sequence_id:
c = {'fiscalyear_id': st.period_id.fiscalyear_id.id}
st_number = obj_seq.next_by_id(cr, uid, st.journal_id.sequence_id.id, context=c)
else:
st_number = obj_seq.next_by_code(cr, uid, 'account.bank.statement')
st_number = obj_seq.next_by_code(cr, uid, 'account.bank.statement', context=c)
for line in st.move_line_ids:
if line.state <> 'valid':
raise osv.except_osv(_('Error !'),
raise osv.except_osv(_('Error!'),
_('The account entries lines are not in valid state.'))
for st_line in st.line_ids:
if st_line.analytic_account_id:
@ -362,7 +430,7 @@ class account_bank_statement(osv.osv):
'name': st_number,
'balance_end_real': st.balance_end
}, context=context)
self.log(cr, uid, st.id, _('Statement %s is confirmed, journal items are created.') % (st_number,))
self.message_post(cr, uid, [st.id], body=_('Statement %s confirmed, journal items were created.') % (st_number,), context=context)
return self.write(cr, uid, ids, {'state':'confirm'}, context=context)
def button_cancel(self, cr, uid, ids, context=None):
@ -371,22 +439,33 @@ class account_bank_statement(osv.osv):
for st in self.browse(cr, uid, ids, context=context):
if st.state=='draft':
continue
ids = []
move_ids = []
for line in st.line_ids:
ids += [x.id for x in line.move_ids]
account_move_obj.unlink(cr, uid, ids, context)
move_ids += [x.id for x in line.move_ids]
account_move_obj.button_cancel(cr, uid, move_ids, context=context)
account_move_obj.unlink(cr, uid, move_ids, context)
done.append(st.id)
return self.write(cr, uid, done, {'state':'draft'}, context=context)
def _compute_balance_end_real(self, cr, uid, journal_id, context=None):
res = False
if journal_id:
cr.execute('SELECT balance_end_real \
FROM account_bank_statement \
WHERE journal_id = %s AND NOT state = %s \
ORDER BY date DESC,id DESC LIMIT 1', (journal_id, 'draft'))
res = cr.fetchone()
return res and res[0] or 0.0
def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
cr.execute('SELECT balance_end_real \
FROM account_bank_statement \
WHERE journal_id = %s AND NOT state = %s \
ORDER BY date DESC,id DESC LIMIT 1', (journal_id, 'draft'))
res = cr.fetchone()
balance_start = res and res[0] or 0.0
account_id = self.pool.get('account.journal').read(cr, uid, journal_id, ['default_debit_account_id'], context=context)['default_debit_account_id']
return {'value': {'balance_start': balance_start, 'account_id': account_id}}
if not journal_id:
return {}
balance_start = self._compute_balance_end_real(cr, uid, journal_id, context=context)
journal_data = self.pool.get('account.journal').read(cr, uid, journal_id, ['company_id', 'currency'], context=context)
company_id = journal_data['company_id']
currency_id = journal_data['currency'] or self.pool.get('res.company').browse(cr, uid, company_id[0], context=context).currency_id.id
return {'value': {'balance_start': balance_start, 'company_id': company_id, 'currency': currency_id}}
def unlink(self, cr, uid, ids, context=None):
stat = self.read(cr, uid, ids, ['state'], context=context)
@ -395,7 +474,7 @@ class account_bank_statement(osv.osv):
if t['state'] in ('draft'):
unlink_ids.append(t['id'])
else:
raise osv.except_osv(_('Invalid action !'), _('In order to delete a bank statement, you must first cancel it to delete related journal items.'))
raise osv.except_osv(_('Invalid Action!'), _('In order to delete a bank statement, you must first cancel it to delete related journal items.'))
osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
return True
@ -408,6 +487,19 @@ class account_bank_statement(osv.osv):
default['move_line_ids'] = []
return super(account_bank_statement, self).copy(cr, uid, id, default, context=context)
def button_journal_entries(self, cr, uid, ids, context=None):
ctx = (context or {}).copy()
ctx['journal_id'] = self.browse(cr, uid, ids[0], context=context).journal_id.id
return {
'view_type':'form',
'view_mode':'tree',
'res_model':'account.move.line',
'view_id':False,
'type':'ir.actions.act_window',
'domain':[('statement_id','in',ids)],
'context':ctx,
}
account_bank_statement()
class account_bank_statement_line(osv.osv):
@ -455,7 +547,7 @@ class account_bank_statement_line(osv.osv):
_name = "account.bank.statement.line"
_description = "Bank Statement Line"
_columns = {
'name': fields.char('Communication', size=64, required=True),
'name': fields.char('OBI', required=True, help="Originator to Beneficiary Information"),
'date': fields.date('Date', required=True),
'amount': fields.float('Amount', digits_compute=dp.get_precision('Account')),
'type': fields.selection([
@ -468,6 +560,7 @@ class account_bank_statement_line(osv.osv):
required=True),
'statement_id': fields.many2one('account.bank.statement', 'Statement',
select=True, required=True, ondelete='cascade'),
'journal_id': fields.related('statement_id', 'journal_id', type='many2one', relation='account.journal', string='Journal', store=True, readonly=True),
'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account'),
'move_ids': fields.many2many('account.move',
'account_bank_statement_line_move_rel', 'statement_line_id','move_id',
@ -479,7 +572,7 @@ class account_bank_statement_line(osv.osv):
}
_defaults = {
'name': lambda self,cr,uid,context={}: self.pool.get('ir.sequence').get(cr, uid, 'account.bank.statement.line'),
'date': lambda self,cr,uid,context={}: context.get('date', time.strftime('%Y-%m-%d')),
'date': lambda self,cr,uid,context={}: context.get('date', fields.date.context_today(self,cr,uid,context=context)),
'type': 'general',
}

View File

@ -9,26 +9,48 @@
<record id="view_partner_bank_form_inherit" model="ir.ui.view">
<field name="name">Partner Bank Accounts - Journal</field>
<field name="model">res.partner.bank</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_partner_bank_form"/>
<field name="arch" type="xml">
<group name="bank" position="after">
<group name="accounting" col="2" colspan="2" attrs="{'invisible': [('company_id','=', False)]}" groups="base.group_extended">
<group name="accounting" col="2" colspan="2" attrs="{'invisible': [('company_id','=', False)]}">
<separator string="Accounting Information" colspan="2"/>
<field name="journal_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</group>
</group>
</field>
</record>
<record id="view_partner_bank_tree_add_currency" model="ir.ui.view">
<field name="name">Partner Bank Accounts - Add currency on tree</field>
<field name="model">res.partner.bank</field>
<field name="inherit_id" ref="base.view_partner_bank_tree"/>
<field name="arch" type="xml">
<field name="acc_number" position="after">
<field name="currency_id" groups="base.group_multi_currency"/>
</field>
</field>
</record>
<record id="action_bank_tree" model="ir.actions.act_window">
<field name="name">Setup your Bank Accounts</field>
<field name="res_model">res.partner.bank</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context" eval="{'default_partner_id':ref('base.main_partner'), 'company_hide':False, 'default_company_id':ref('base.main_company'), 'search_default_my_bank':1}"/>
<field name="help">Configure your company's bank account and select those that must appear on the report footer. You can reorder banks in the list view. If you use the accounting application of OpenERP, journals and accounts will be created automatically based on these data.</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to setup a new bank account.
</p><p>
Configure your company's bank account and select those that must
appear on the report footer.
</p><p>
If you use the accounting application of OpenERP, journals and
accounts will be created automatically based on these data.
</p>
</field>
</record>
<menuitem
sequence="0"
@ -36,13 +58,5 @@
id="menu_action_bank_tree"
action="action_bank_tree"/>
<record id="account_configuration_bank_todo" model="ir.actions.todo">
<field name="action_id" ref="action_bank_tree"/>
<field name="category_id" ref="category_accounting_configuration"/>
<field name="sequence">4</field>
</record>
</data>
</openerp>

View File

@ -22,9 +22,9 @@
import time
from osv import osv, fields
from tools.translate import _
import decimal_precision as dp
from openerp.osv import fields, osv
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp
class account_cashbox_line(osv.osv):
@ -32,7 +32,7 @@ class account_cashbox_line(osv.osv):
_name = 'account.cashbox.line'
_description = 'CashBox Line'
_rec_name = 'number'
_rec_name = 'pieces'
def _sub_total(self, cr, uid, ids, name, arg, context=None):
@ -43,24 +43,27 @@ class account_cashbox_line(osv.osv):
"""
res = {}
for obj in self.browse(cr, uid, ids, context=context):
res[obj.id] = obj.pieces * obj.number
res[obj.id] = {
'subtotal_opening' : obj.pieces * obj.number_opening,
'subtotal_closing' : obj.pieces * obj.number_closing,
}
return res
def on_change_sub(self, cr, uid, ids, pieces, number, *a):
def on_change_sub_opening(self, cr, uid, ids, pieces, number, *a):
""" Compute the subtotal for the opening """
return {'value' : {'subtotal_opening' : (pieces * number) or 0.0 }}
""" Calculates Sub total on change of number
@param pieces: Names of fields.
@param number:
"""
sub = pieces * number
return {'value': {'subtotal': sub or 0.0}}
def on_change_sub_closing(self, cr, uid, ids, pieces, number, *a):
""" Compute the subtotal for the closing """
return {'value' : {'subtotal_closing' : (pieces * number) or 0.0 }}
_columns = {
'pieces': fields.float('Values', digits_compute=dp.get_precision('Account')),
'number': fields.integer('Number'),
'subtotal': fields.function(_sub_total, string='Sub Total', type='float', digits_compute=dp.get_precision('Account')),
'starting_id': fields.many2one('account.bank.statement', ondelete='cascade'),
'ending_id': fields.many2one('account.bank.statement', ondelete='cascade'),
'pieces': fields.float('Unit of Currency', digits_compute=dp.get_precision('Account')),
'number_opening' : fields.integer('Number of Units', help='Opening Unit Numbers'),
'number_closing' : fields.integer('Number of Units', help='Closing Unit Numbers'),
'subtotal_opening': fields.function(_sub_total, string='Opening Subtotal', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'),
'subtotal_closing': fields.function(_sub_total, string='Closing Subtotal', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'),
'bank_statement_id' : fields.many2one('account.bank.statement', ondelete='cascade'),
}
account_cashbox_line()
@ -69,39 +72,24 @@ class account_cash_statement(osv.osv):
_inherit = 'account.bank.statement'
def _get_starting_balance(self, cr, uid, ids, context=None):
""" Find starting balance
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
def _update_balances(self, cr, uid, ids, context=None):
"""
Set starting and ending balances according to pieces count
"""
res = {}
for statement in self.browse(cr, uid, ids, context=context):
amount_total = 0.0
if statement.journal_id.type not in('cash'):
if (statement.journal_id.type not in ('cash',)) or (not statement.journal_id.cash_control):
continue
for line in statement.starting_details_ids:
amount_total+= line.pieces * line.number
res[statement.id] = {
'balance_start': amount_total
start = end = 0
for line in statement.details_ids:
start += line.subtotal_opening
end += line.subtotal_closing
data = {
'balance_start': start,
'balance_end_real': end,
}
return res
def _balance_end_cash(self, cr, uid, ids, name, arg, context=None):
""" Find ending balance "
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
res = {}
for statement in self.browse(cr, uid, ids, context=context):
amount_total = 0.0
for line in statement.ending_details_ids:
amount_total += line.pieces * line.number
res[statement.id] = amount_total
res[statement.id] = data
super(account_cash_statement, self).write(cr, uid, [statement.id], data, context=context)
return res
def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None):
@ -111,13 +99,10 @@ class account_cash_statement(osv.osv):
@param arg: User defined arguments
@return: Dictionary of values.
"""
res2 = {}
res = {}
for statement in self.browse(cr, uid, ids, context=context):
encoding_total=0.0
for line in statement.line_ids:
encoding_total += line.amount
res2[statement.id] = encoding_total
return res2
res[statement.id] = sum((line.amount for line in statement.line_ids), 0.0)
return res
def _get_company(self, cr, uid, context=None):
user_pool = self.pool.get('res.users')
@ -128,108 +113,112 @@ class account_cash_statement(osv.osv):
company_id = company_pool.search(cr, uid, [])
return company_id and company_id[0] or False
def _get_cash_open_box_lines(self, cr, uid, context=None):
res = []
curr = [1, 2, 5, 10, 20, 50, 100, 500]
for rs in curr:
dct = {
'pieces': rs,
'number': 0
}
res.append(dct)
journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash')], context=context)
if journal_ids:
results = self.search(cr, uid, [('journal_id', 'in', journal_ids),('state', '=', 'confirm')], context=context)
if results:
cash_st = self.browse(cr, uid, results, context=context)[0]
for cash_line in cash_st.ending_details_ids:
for r in res:
if cash_line.pieces == r['pieces']:
r['number'] = cash_line.number
return res
def _get_default_cash_close_box_lines(self, cr, uid, context=None):
res = []
curr = [1, 2, 5, 10, 20, 50, 100, 500]
for rs in curr:
dct = {
'pieces': rs,
'number': 0
}
res.append(dct)
return res
def _get_cash_close_box_lines(self, cr, uid, context=None):
res = []
curr = [1, 2, 5, 10, 20, 50, 100, 500]
for rs in curr:
dct = {
'pieces': rs,
'number': 0
}
res.append((0, 0, dct))
return res
def _get_cash_open_close_box_lines(self, cr, uid, context=None):
res = {}
start_l = []
end_l = []
starting_details = self._get_cash_open_box_lines(cr, uid, context=context)
ending_details = self._get_default_cash_close_box_lines(cr, uid, context)
for start in starting_details:
start_l.append((0, 0, start))
for end in ending_details:
end_l.append((0, 0, end))
res['start'] = start_l
res['end'] = end_l
return res
def _get_statement(self, cr, uid, ids, context=None):
def _get_statement_from_line(self, cr, uid, ids, context=None):
result = {}
for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context):
result[line.statement_id.id] = True
return result.keys()
def _compute_difference(self, cr, uid, ids, fieldnames, args, context=None):
result = dict.fromkeys(ids, 0.0)
for obj in self.browse(cr, uid, ids, context=context):
result[obj.id] = obj.balance_end_real - obj.balance_end
return result
def _compute_last_closing_balance(self, cr, uid, ids, fieldnames, args, context=None):
result = dict.fromkeys(ids, 0.0)
for obj in self.browse(cr, uid, ids, context=context):
if obj.state == 'draft':
statement_ids = self.search(cr, uid,
[('journal_id', '=', obj.journal_id.id),('state', '=', 'confirm')],
order='create_date desc',
limit=1,
context=context
)
if not statement_ids:
continue
else:
st = self.browse(cr, uid, statement_ids[0], context=context)
result[obj.id] = st.balance_end_real
return result
def onchange_journal_id(self, cr, uid, ids, journal_id, context=None):
result = super(account_cash_statement, self).onchange_journal_id(cr, uid, ids, journal_id)
if not journal_id:
return result
statement_ids = self.search(cr, uid,
[('journal_id', '=', journal_id),('state', '=', 'confirm')],
order='create_date desc',
limit=1,
context=context
)
if not statement_ids:
return result
st = self.browse(cr, uid, statement_ids[0], context=context)
result.setdefault('value', {}).update({'last_closing_balance' : st.balance_end_real})
return result
_columns = {
'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Cash Transaction", help="Total cash transactions",
'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Total Transactions",
store = {
'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids'], 10),
'account.bank.statement.line': (_get_statement, ['amount'], 10),
'account.bank.statement': (lambda self, cr, uid, ids, context=None: ids, ['line_ids','move_line_ids'], 10),
'account.bank.statement.line': (_get_statement_from_line, ['amount'], 10),
}),
'closing_date': fields.datetime("Closed On"),
'balance_end_cash': fields.function(_balance_end_cash, store=True, string='Closing Balance', help="Closing balance based on cashBox"),
'starting_details_ids': fields.one2many('account.cashbox.line', 'starting_id', string='Opening Cashbox'),
'ending_details_ids': fields.one2many('account.cashbox.line', 'ending_id', string='Closing Cashbox'),
'details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='CashBox Lines'),
'opening_details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='Opening Cashbox Lines'),
'closing_details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='Closing Cashbox Lines'),
'user_id': fields.many2one('res.users', 'Responsible', required=False),
'difference' : fields.function(_compute_difference, method=True, string="Difference", type="float"),
'last_closing_balance' : fields.function(_compute_last_closing_balance, method=True, string='Last Closing Balance', type='float'),
}
_defaults = {
'state': 'draft',
'date': lambda self,cr,uid,context={}: context.get('date', time.strftime("%Y-%m-%d %H:%M:%S")),
'date': lambda self, cr, uid, context={}: context.get('date', time.strftime("%Y-%m-%d %H:%M:%S")),
'user_id': lambda self, cr, uid, context=None: uid,
'starting_details_ids': _get_cash_open_box_lines,
'ending_details_ids': _get_default_cash_close_box_lines
}
}
def create(self, cr, uid, vals, context=None):
if self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context).type == 'cash':
open_close = self._get_cash_open_close_box_lines(cr, uid, context)
if vals.get('starting_details_ids', False):
for start in vals.get('starting_details_ids'):
dict_val = start[2]
for end in open_close['end']:
if end[2]['pieces'] == dict_val['pieces']:
end[2]['number'] += dict_val['number']
vals.update({
# 'ending_details_ids': open_close['start'],
'starting_details_ids': open_close['end']
})
else:
vals.update({
'ending_details_ids': False,
'starting_details_ids': False
})
journal = False
if vals.get('journal_id'):
journal = self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context)
if journal and (journal.type == 'cash') and not vals.get('details_ids'):
vals['details_ids'] = []
last_pieces = None
if journal.with_last_closing_balance == True:
domain = [('journal_id', '=', journal.id),
('state', '=', 'confirm')]
last_bank_statement_ids = self.search(cr, uid, domain, limit=1, order='create_date desc', context=context)
if last_bank_statement_ids:
last_bank_statement = self.browse(cr, uid, last_bank_statement_ids[0], context=context)
last_pieces = dict(
(line.pieces, line.number_closing) for line in last_bank_statement.details_ids
)
for value in journal.cashbox_line_ids:
nested_values = {
'number_closing' : 0,
'number_opening' : last_pieces.get(value.pieces, 0) if isinstance(last_pieces, dict) else 0,
'pieces' : value.pieces
}
vals['details_ids'].append([0, False, nested_values])
res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context)
self.write(cr, uid, [res_id], {})
self._update_balances(cr, uid, [res_id], context)
return res_id
def write(self, cr, uid, ids, vals, context=None):
@ -246,34 +235,9 @@ class account_cash_statement(osv.osv):
@return: True on success, False otherwise
"""
super(account_cash_statement, self).write(cr, uid, ids, vals, context=context)
res = self._get_starting_balance(cr, uid, ids)
for rs in res:
super(account_cash_statement, self).write(cr, uid, [rs], res.get(rs))
return True
def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
""" Changes balance start and starting details if journal_id changes"
@param statement_id: Changed statement_id
@param journal_id: Changed journal_id
@return: Dictionary of changed values
"""
res = {}
balance_start = 0.0
if not journal_id:
res.update({
'balance_start': balance_start
})
return res
return super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context=context)
def _equal_balance(self, cr, uid, cash_id, context=None):
statement = self.browse(cr, uid, cash_id, context=context)
self.write(cr, uid, [cash_id], {'balance_end_real': statement.balance_end})
statement.balance_end_real = statement.balance_end
if statement.balance_end != statement.balance_end_cash:
return False
return True
res = super(account_cash_statement, self).write(cr, uid, ids, vals, context=context)
self._update_balances(cr, uid, ids, context)
return res
def _user_allow(self, cr, uid, statement_id, context=None):
return True
@ -289,14 +253,14 @@ class account_cash_statement(osv.osv):
for statement in statement_pool.browse(cr, uid, ids, context=context):
vals = {}
if not self._user_allow(cr, uid, statement.id, context=context):
raise osv.except_osv(_('Error !'), (_('User %s does not have rights to access %s journal !') % (statement.user_id.name, statement.journal_id.name)))
raise osv.except_osv(_('Error!'), (_('You do not have rights to open this %s journal !') % (statement.journal_id.name, )))
if statement.name and statement.name == '/':
c = {'fiscalyear_id': statement.period_id.fiscalyear_id.id}
if statement.journal_id.sequence_id:
c = {'fiscalyear_id': statement.period_id.fiscalyear_id.id}
st_number = obj_seq.next_by_id(cr, uid, statement.journal_id.sequence_id.id, context=c)
else:
st_number = obj_seq.next_by_code(cr, uid, 'account.cash.statement')
st_number = obj_seq.next_by_code(cr, uid, 'account.cash.statement', context=c)
vals.update({
'name': st_number
})
@ -307,13 +271,6 @@ class account_cash_statement(osv.osv):
self.write(cr, uid, [statement.id], vals, context=context)
return True
def balance_check(self, cr, uid, cash_id, journal_type='bank', context=None):
if journal_type == 'bank':
return super(account_cash_statement, self).balance_check(cr, uid, cash_id, journal_type, context)
if not self._equal_balance(cr, uid, cash_id, context):
raise osv.except_osv(_('Error !'), _('The closing balance should be the same than the computed balance!'))
return True
def statement_close(self, cr, uid, ids, journal_type='bank', context=None):
if journal_type == 'bank':
return super(account_cash_statement, self).statement_close(cr, uid, ids, journal_type, context)
@ -330,16 +287,67 @@ class account_cash_statement(osv.osv):
def button_confirm_cash(self, cr, uid, ids, context=None):
super(account_cash_statement, self).button_confirm_bank(cr, uid, ids, context=context)
return self.write(cr, uid, ids, {'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")}, context=context)
absl_proxy = self.pool.get('account.bank.statement.line')
def button_cancel(self, cr, uid, ids, context=None):
cash_box_line_pool = self.pool.get('account.cashbox.line')
super(account_cash_statement, self).button_cancel(cr, uid, ids, context=context)
for st in self.browse(cr, uid, ids, context):
for end in st.ending_details_ids:
cash_box_line_pool.write(cr, uid, [end.id], {'number': 0})
return True
TABLES = ((_('Profit'), 'profit_account_id'), (_('Loss'), 'loss_account_id'),)
for obj in self.browse(cr, uid, ids, context=context):
if obj.difference == 0.0:
continue
for item_label, item_account in TABLES:
if getattr(obj.journal_id, item_account):
raise osv.except_osv(_('Error!'),
_('There is no %s Account on the journal %s.') % (item_label, obj.journal_id.name,))
is_profit = obj.difference < 0.0
account = getattr(obj.journal_id, TABLES[is_profit][1])
values = {
'statement_id' : obj.id,
'journal_id' : obj.journal_id.id,
'account_id' : account.id,
'amount' : obj.difference,
'name' : 'Exceptional %s' % TABLES[is_profit][0],
}
absl_proxy.create(cr, uid, values, context=context)
return self.write(cr, uid, ids, {'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")}, context=context)
account_cash_statement()
class account_journal(osv.osv):
_inherit = 'account.journal'
def _default_cashbox_line_ids(self, cr, uid, context=None):
# Return a list of coins in Euros.
result = [
dict(pieces=value) for value in [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500]
]
return result
_columns = {
'cashbox_line_ids' : fields.one2many('account.journal.cashbox.line', 'journal_id', 'CashBox'),
}
_defaults = {
'cashbox_line_ids' : _default_cashbox_line_ids,
}
account_journal()
class account_journal_cashbox_line(osv.osv):
_name = 'account.journal.cashbox.line'
_rec_name = 'pieces'
_columns = {
'pieces': fields.float('Values', digits_compute=dp.get_precision('Account')),
'journal_id' : fields.many2one('account.journal', 'Journal', required=True, select=1),
}
_order = 'pieces asc'
account_journal_cashbox_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -14,7 +14,7 @@
action="action_account_period_tree"
id="menu_action_account_period_close_tree"
parent="account.menu_account_end_year_treatments"
sequence="0" groups="base.group_extended"/>
sequence="0"/>
</data>
</openerp>

View File

@ -24,11 +24,11 @@ from datetime import datetime
from dateutil.relativedelta import relativedelta
from operator import itemgetter
import netsvc
import pooler
from osv import fields, osv
import decimal_precision as dp
from tools.translate import _
from openerp import netsvc
from openerp import pooler
from openerp.osv import fields, osv
import openerp.addons.decimal_precision as dp
from openerp.tools.translate import _
# ---------------------------------------------------------
# Account Financial Report
@ -55,39 +55,37 @@ class account_financial_report(osv.osv):
res += self._get_children_by_order(cr, uid, ids2, context=context)
return res
def _get_balance(self, cr, uid, ids, name, args, context=None):
def _get_balance(self, cr, uid, ids, field_names, args, context=None):
account_obj = self.pool.get('account.account')
res = {}
res_all = {}
for report in self.browse(cr, uid, ids, context=context):
balance = 0.0
if report.id in res_all:
balance = res_all[report.id]
elif report.type == 'accounts':
# it's the sum of balance of the linked accounts
if report.id in res:
continue
res[report.id] = dict((fn, 0.0) for fn in field_names)
if report.type == 'accounts':
# it's the sum of the linked accounts
for a in report.account_ids:
balance += a.balance
for field in field_names:
res[report.id][field] += getattr(a, field)
elif report.type == 'account_type':
# it's the sum of balance of the leaf accounts with such an account type
# it's the sum the leaf accounts with such an account type
report_types = [x.id for x in report.account_type_ids]
account_ids = account_obj.search(cr, uid, [('user_type','in', report_types), ('type','!=','view')], context=context)
for a in account_obj.browse(cr, uid, account_ids, context=context):
balance += a.balance
for field in field_names:
res[report.id][field] += getattr(a, field)
elif report.type == 'account_report' and report.account_report_id:
# it's the amount of the linked report
res2 = self._get_balance(cr, uid, [report.account_report_id.id], 'balance', False, context=context)
res_all.update(res2)
res2 = self._get_balance(cr, uid, [report.account_report_id.id], field_names, False, context=context)
for key, value in res2.items():
balance += value
for field in field_names:
res[report.id][field] += value[field]
elif report.type == 'sum':
# it's the sum of balance of the children of this account.report
#for child in report.children_ids:
res2 = self._get_balance(cr, uid, [rec.id for rec in report.children_ids], 'balance', False, context=context)
res_all.update(res2)
# it's the sum of the children of this account.report
res2 = self._get_balance(cr, uid, [rec.id for rec in report.children_ids], field_names, False, context=context)
for key, value in res2.items():
balance += value
res[report.id] = balance
res_all[report.id] = balance
for field in field_names:
res[report.id][field] += value[field]
return res
_columns = {
@ -95,7 +93,9 @@ class account_financial_report(osv.osv):
'parent_id': fields.many2one('account.financial.report', 'Parent'),
'children_ids': fields.one2many('account.financial.report', 'parent_id', 'Account Report'),
'sequence': fields.integer('Sequence'),
'balance': fields.function(_get_balance, 'Balance'),
'balance': fields.function(_get_balance, 'Balance', multi='balance'),
'debit': fields.function(_get_balance, 'Debit', multi='balance'),
'credit': fields.function(_get_balance, 'Credit', multi="balance"),
'level': fields.function(_get_level, string='Level', store=True, type='integer'),
'type': fields.selection([
('sum','View'),
@ -104,20 +104,30 @@ class account_financial_report(osv.osv):
('account_report','Report Value'),
],'Type'),
'account_ids': fields.many2many('account.account', 'account_account_financial_report', 'report_line_id', 'account_id', 'Accounts'),
'account_report_id': fields.many2one('account.financial.report', 'Report Value'),
'account_type_ids': fields.many2many('account.account.type', 'account_account_financial_report_type', 'report_id', 'account_type_id', 'Account Types'),
'sign': fields.selection([(-1, 'Reverse balance sign'), (1, 'Preserve balance sign')], 'Sign on Reports', required=True, help='For accounts that are typically more debited than credited and that you would like to print as negative amounts in your reports, you should reverse the sign of the balance; e.g.: Expense account. The same applies for accounts that are typically more credited than debited and that you would like to print as positive amounts in your reports; e.g.: Income account.'),
'display_detail': fields.selection([
('no_detail','No detail'),
('detail_flat','Display children flat'),
('detail_with_hierarchy','Display children with hierarchy')
], 'Display details'),
'account_report_id': fields.many2one('account.financial.report', 'Report Value'),
'account_type_ids': fields.many2many('account.account.type', 'account_account_financial_report_type', 'report_id', 'account_type_id', 'Account Types'),
'sign': fields.selection([(-1, 'Reverse balance sign'), (1, 'Preserve balance sign')], 'Sign on Reports', required=True, help='For accounts that are typically more debited than credited and that you would like to print as negative amounts in your reports, you should reverse the sign of the balance; e.g.: Expense account. The same applies for accounts that are typically more credited than debited and that you would like to print as positive amounts in your reports; e.g.: Income account.'),
'style_overwrite': fields.selection([
(0, 'Automatic formatting'),
(1,'Main Title 1 (bold, underlined)'),
(2,'Title 2 (bold)'),
(3,'Title 3 (bold, smaller)'),
(4,'Normal Text'),
(5,'Italic Text (smaller)'),
(6,'Smallest Text'),
],'Financial Report Style', help="You can set up here the format you want this record to be displayed. If you leave the automatic formatting, it will be computed based on the financial reports hierarchy (auto-computed field 'level')."),
}
_defaults = {
'type': 'sum',
'display_detail': 'detail_flat',
'sign': 1,
'style_overwrite': 0,
}
account_financial_report()

View File

@ -4,23 +4,6 @@
<!--
Financial Reports
-->
<record id="account_financial_report_balancesheet0" model="account.financial.report">
<field name="name">Balance Sheet</field>
<field name="type">sum</field>
</record>
<record id="account_financial_report_assets0" model="account.financial.report">
<field name="name">Assets</field>
<field name="parent_id" ref="account_financial_report_balancesheet0"/>
<field name="display_detail">detail_with_hierarchy</field>
<field name="type">account_type</field>
</record>
<record id="account_financial_report_liability0" model="account.financial.report">
<field name="name">Liability</field>
<field name="parent_id" ref="account_financial_report_balancesheet0"/>
<field name="display_detail">detail_with_hierarchy</field>
<field name="type">account_type</field>
</record>
<record id="account_financial_report_profitandloss0" model="account.financial.report">
<field name="name">Profit and Loss</field>
<field name="type">sum</field>
@ -38,6 +21,35 @@
<field name="type">account_type</field>
</record>
<record id="account_financial_report_balancesheet0" model="account.financial.report">
<field name="name">Balance Sheet</field>
<field name="type">sum</field>
</record>
<record id="account_financial_report_assets0" model="account.financial.report">
<field name="name">Assets</field>
<field name="parent_id" ref="account_financial_report_balancesheet0"/>
<field name="display_detail">detail_with_hierarchy</field>
<field name="type">account_type</field>
</record>
<record id="account_financial_report_liabilitysum0" model="account.financial.report">
<field name="name">Liability</field>
<field name="parent_id" ref="account_financial_report_balancesheet0"/>
<field name="display_detail">no_detail</field>
<field name="type">sum</field>
</record>
<record id="account_financial_report_liability0" model="account.financial.report">
<field name="name">Liability</field>
<field name="parent_id" ref="account_financial_report_liabilitysum0"/>
<field name="display_detail">detail_with_hierarchy</field>
<field name="type">account_type</field>
</record>
<record id="account_financial_report_profitloss_toreport0" model="account.financial.report">
<field name="name">Profit (Loss) to report</field>
<field name="parent_id" ref="account_financial_report_liabilitysum0"/>
<field name="display_detail">no_detail</field>
<field name="type">account_report</field>
<field name="account_report_id" ref="account_financial_report_profitandloss0"/>
</record>
</data>
</openerp>

View File

@ -3,45 +3,40 @@
<record id="view_account_configuration_installer" model="ir.ui.view">
<field name="name">account.installer.form</field>
<field name="model">account.installer</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.res_config_installer"/>
<field name="arch" type="xml">
<data>
<form position="attributes">
<form position="attributes" version="7.0">
<attribute name="string">Accounting Application Configuration</attribute>
</form>
<separator string="title" position="attributes">
<attribute name="string">Configure Your Chart of Accounts</attribute>
</separator>
<xpath expr="//label[@string='description']" position="attributes">
<attribute name="string">The default Chart of Accounts is matching your country selection. If no certified Chart of Accounts exists for your specified country, a generic one can be installed and will be selected by default.</attribute>
</xpath>
<xpath expr="//button[@string='Install Modules']" position="attributes">
<attribute name="string">Configure</attribute>
</xpath>
<xpath expr="//separator[@string=&quot;vsep&quot;]" position="attributes">
<attribute name="rowspan">23</attribute>
<attribute name="string"/>
</xpath>
<group colspan="8" position="inside">
<group colspan="4" width="600">
<field name="charts"/>
<group colspan="4" groups="account.group_account_user">
<separator col="4" colspan="4" string="Configure Fiscal Year"/>
<field name="has_default_company" invisible="1" />
<field name="company_id" colspan="4" widget="selection" attrs="{'invisible' : [('has_default_company', '=', True)]}"/><!-- we assume that this wizard will be run only by administrators and as this field may cause problem if hidden (because of the default company of the user removed from the selection because already configured), we simply choosed to remove the group "multi company" of it -->
<field name="date_start" on_change="on_change_start_date(date_start)"/>
<field name="date_stop"/>
<field name="period" colspan="4"/>
</group>
</group>
<footer position="replace">
<footer>
<button name="action_next" type="object" string="Continue" class="oe_highlight"/>
</footer>
</footer>
<separator string="title" position="replace">
<p class="oe_grey">
Select a configuration package to setup automatically your
taxes and chart of accounts.
</p>
<group>
<field name="charts" class="oe_inline"/>
</group>
</data>
<group string="Configure your Fiscal Year" groups="account.group_account_user">
<field name="has_default_company" invisible="1" />
<field name="company_id" colspan="4" widget="selection" attrs="{'invisible' : [('has_default_company', '=', True)]}"/><!-- we assume that this wizard will be run only by administrators and as this field may cause problem if hidden (because of the default company of the user removed from the selection because already configured), we simply choosed to remove the group "multi company" of it -->
<label for="date_start" string="Date Range"/>
<div>
<field name="date_start" on_change="on_change_start_date(date_start)" class="oe_inline"/> -
<field name="date_stop" class="oe_inline"/>
</div>
<field name="period"/>
</group>
</separator>
</field>
</record>
<record id="action_account_configuration_installer" model="ir.actions.act_window">
<field name="name">Install your Chart of Accounts</field>
<field name="name">Configure Accounting Data</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.installer</field>
<field name="view_id" ref="view_account_configuration_installer"/>
@ -50,60 +45,11 @@
<field name="target">new</field>
</record>
<record id="category_accounting_configuration" model="ir.actions.todo.category">
<field name="name">Accounting</field>
<field name="sequence">5</field>
</record>
<record id="account_configuration_installer_todo" model="ir.actions.todo">
<field name="action_id" ref="action_account_configuration_installer"/>
<field name="category_id" ref="category_accounting_configuration"/>
<field name="sequence">3</field>
<field name="type">automatic</field>
</record>
<record id="action_view_financial_accounts_installer" model="ir.actions.act_window">
<field name="name">Review your Financial Accounts</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.account</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context">{'config_invisible': False}</field>
</record>
<record id="view_financial_accounts_todo" model="ir.actions.todo">
<field name="action_id" ref="action_view_financial_accounts_installer" />
<field name="category_id" ref="category_accounting_configuration" />
<field name="groups_id" eval="[(6, 0, [ref('account.group_account_user')])]" />
</record>
<record id="action_review_financial_journals_installer" model="ir.actions.act_window">
<field name="name">Review your Financial Journals</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.journal</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help">Setup your accounting journals. For bank accounts, it's better to use the 'Setup Your Bank Accounts' tool that will automatically create the accounts and journals for you.</field>
</record>
<record id="review_financial_journals_todo" model="ir.actions.todo">
<field name="action_id" ref="action_review_financial_journals_installer" />
<field name="category_id" ref="category_accounting_configuration" />
<field name="groups_id" eval="[(6, 0, [ref('account.group_account_user')])]" />
</record>
<record id="action_review_payment_terms_installer" model="ir.actions.act_window">
<field name="name">Review your Payment Terms</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.payment.term</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help">Payment terms define the conditions to pay a customer or supplier invoice in one or several payments. Customers periodic reminders will use the payment terms for each letter. Each customer or supplier can be assigned to one of these payment terms.</field>
</record>
<record id="review_payment_terms_todo" model="ir.actions.todo">
<field name="action_id" ref="action_review_payment_terms_installer" />
<field name="category_id" ref="category_accounting_configuration" />
<field name="groups_id" eval="[(6, 0, [ref('account.group_account_user')])]" />
</record>
</data>
</openerp>

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--
Invoices
-->
<!-- Invoices -->
<record id="view_invoice_line_calendar" model="ir.ui.view">
<field name="name">account.invoice.calendar</field>
<field name="model">account.invoice</field>
<field name="type">calendar</field>
<field name="arch" type="xml">
<calendar string="Invoices" color="journal_id" date_start="date_invoice">
<field name="partner_id"/>
@ -19,7 +17,6 @@
<record model="ir.ui.view" id="view_invoice_graph">
<field name="name">account.invoice.graph</field>
<field name="model">account.invoice</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Invoices" type="bar">
<field name="partner_id"/>
@ -31,15 +28,14 @@
<record id="view_invoice_line_tree" model="ir.ui.view">
<field name="name">account.invoice.line.tree</field>
<field name="model">account.invoice.line</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Invoice Line">
<field name="name"/>
<field name="account_id" groups="account.group_account_user"/>
<field name="quantity"/>
<field name="uos_id"/>
<field name="uos_id" groups="product.group_uom"/>
<field name="price_unit"/>
<field name="discount" groups="base.group_extended"/>
<field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="price_subtotal"/>
</tree>
</field>
@ -48,25 +44,29 @@
<record id="view_invoice_line_form" model="ir.ui.view">
<field name="name">account.invoice.line.form</field>
<field name="model">account.invoice.line</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Invoice Line">
<field name="product_id" on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.address_invoice_id, parent.currency_id, context, parent.company_id)"/>
<field colspan="2" name="name"/>
<label string="Quantity :" align="1.0"/>
<group colspan="1" col="2">
<field name="quantity" nolabel="1"/>
<field name="uos_id" on_change="uos_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.address_invoice_id, parent.currency_id, context, parent.company_id)" nolabel="1"/>
<form string="Invoice Line" version="7.0">
<group>
<group>
<field name="product_id" on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/>
<label for="quantity"/>
<div>
<field name="quantity" class="oe_inline"/>
<field name="uos_id" class="oe_inline" groups="product.group_uom"
on_change="uos_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/>
</div>
<field name="price_unit"/>
<field name="discount" groups="sale.group_discount_per_so_line"/>
</group>
<group>
<field domain="[('company_id', '=', parent.company_id), ('journal_id', '=', parent.journal_id), ('type', '&lt;&gt;', 'view')]" name="account_id" on_change="onchange_account_id(product_id, parent.partner_id, parent.type, parent.fiscal_position,account_id)" groups="account.group_account_user"/>
<field name="invoice_line_tax_id" context="{'type':parent.type}" domain="[('parent_id','=',False),('company_id', '=', parent.company_id)]" widget="many2many_tags"/>
<field domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id)]" name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
</group>
</group>
<field name="price_unit"/>
<field domain="[('company_id', '=', parent.company_id), ('journal_id', '=', parent.journal_id), ('type', '&lt;&gt;', 'view')]" name="account_id" on_change="onchange_account_id(parent.fiscal_position,account_id)"/>
<field name="discount" groups="base.group_extended"/>
<field domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id), ('parent_id', '!=', False)]" name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
<separator string="Notes" colspan="4"/>
<field colspan="4" name="note" nolabel="1"/>
<separator colspan="4" string="Taxes"/>
<field colspan="4" name="invoice_line_tax_id" context="{'type':parent.type}" domain="[('parent_id','=',False),('company_id', '=', parent.company_id)]" nolabel="1"/>
<label for="name"/>
<field name="name"/>
</form>
</field>
</record>
@ -74,7 +74,6 @@
<record id="view_invoice_tax_tree" model="ir.ui.view">
<field name="name">account.invoice.tax.tree</field>
<field name="model">account.invoice.tax</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Manual Invoice Taxes">
<field name="sequence"/>
@ -90,22 +89,24 @@
<record id="view_invoice_tax_form" model="ir.ui.view">
<field name="name">account.invoice.tax.form</field>
<field name="model">account.invoice.tax</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Manual Invoice Taxes">
<field name="name"/>
<field name="sequence"/>
<field name="account_id"/>
<field name="manual"/>
<field name="amount"/>
<field name="base" readonly="0"/>
<separator colspan="4" string="Tax codes"/>
<field name="base_code_id"/>
<field name="base_amount"/>
<field name="tax_code_id"/>
<field name="tax_amount"/>
<field name="factor_base" invisible="True"/>
<field name="factor_tax" invisible="True"/>
<form string="Manual Invoice Taxes" version="7.0">
<group col="4">
<field name="name"/>
<field name="sequence"/>
<field name="account_id" groups="account.group_account_user"/>
<field name="account_analytic_id" domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id)]" groups="analytic.group_analytic_accounting"/>
<field name="manual"/>
<field name="amount"/>
<field name="base" readonly="0"/>
<separator colspan="4" string="Tax Codes"/>
<field name="base_code_id"/>
<field name="base_amount"/>
<field name="tax_code_id"/>
<field name="tax_amount"/>
<field name="factor_base" invisible="True"/>
<field name="factor_tax" invisible="True"/>
</group>
</form>
</field>
</record>
@ -113,12 +114,11 @@
<record id="invoice_tree" model="ir.ui.view">
<field name="name">account.invoice.tree</field>
<field name="model">account.invoice</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="blue:state == 'draft';black:state in ('proforma','proforma2','open');gray:state == 'cancel'" string="Invoice">
<field name="partner_id" groups="base.group_user"/>
<field name="date_invoice"/>
<field name="number"/>
<field name="partner_id" groups="base.group_user"/>
<field name="reference" invisible="1"/>
<field name="name" invisible="1"/>
<field name="journal_id" invisible="1"/>
@ -127,13 +127,11 @@
<field name="user_id"/>
<field name="date_due"/>
<field name="origin"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="residual" sum="Residual Amount"/>
<field name="amount_untaxed" sum="Untaxed Amount"/>
<field name="amount_total" sum="Total Amount"/>
<field name="state"/>
<button name="invoice_open" states="draft,proforma2" string="Approve" icon="terp-camera_test"/>
</tree>
</field>
</record>
@ -141,53 +139,98 @@
<record id="invoice_supplier_form" model="ir.ui.view">
<field name="name">account.invoice.supplier.form</field>
<field name="model">account.invoice</field>
<field name="type">form</field>
<field name="priority">2</field>
<field name="arch" type="xml">
<form string="Supplier Invoice">
<group col="8" colspan="4">
<field name="journal_id" on_change="onchange_journal_id(journal_id)" widget="selection"/>
<field name="number" readonly="1"/>
<field name="type" invisible="1"/>
<field name="currency_id" width="50"/>
<button name="%(action_account_change_currency)d" type="action" icon="terp-stock_effects-object-colorize" string="Change" attrs="{'invisible':[('state','!=','draft')]}" groups="account.group_account_user"/>
<newline/>
<field string="Supplier" name="partner_id" on_change="onchange_partner_id(type,partner_id,date_invoice,payment_term, partner_bank_id,company_id)" context="{'default_customer': 0, 'search_default_supplier': 1, 'default_supplier': 1}" options='{"quick_create": false}'/>
<field domain="[('partner_id','=',partner_id)]" name="address_invoice_id" context="{'default_partner_id': partner_id}" options='{"quick_create": false}'/>
<field name="fiscal_position" groups="base.group_extended" widget="selection"/>
<newline/>
<field name="date_invoice"/>
<field name="period_id" domain="[('state', '=', 'draft')]" groups="account.group_account_user" widget="selection"/>
<group colspan="2" col="1" groups="account.group_account_user">
<label align="0.0" string="(keep empty to use the current period)"/>
<form string="Supplier Invoice" version="7.0">
<header>
<button name="invoice_open" states="draft,proforma2" string="Validate" class="oe_highlight" groups="account.group_account_invoice"/>
<button name="%(action_account_invoice_refund)d" type='action' string='Ask Refund' states='open,paid' groups="account.group_account_invoice"/>
<button name="invoice_cancel" states="draft,proforma2" string="Cancel" groups="account.group_account_invoice"/>
<button name="invoice_cancel" states="sale,open" string="Cancel" groups="base.group_no_one"/>
<button name="action_cancel_draft" states="cancel" string="Set to Draft" type="object" groups="account.group_account_invoice"/>
<button name='%(action_account_state_open)d' type='action' string='Re-Open' groups="account.group_account_invoice" attrs="{'invisible':['|', ('state','&lt;&gt;','paid'), ('reconciled', '=', True)]}" help="This button only appears when the state of the invoice is 'paid' (showing that it has been fully reconciled) and auto-computed boolean 'reconciled' is False (depicting that it's not the case anymore). In other words, the invoice has been dereconciled and it does not fit anymore the 'paid' state. You should press this button to re-open it and let it continue its normal process after having resolved the eventual exceptions it may have created."/>
<field name="state" widget="statusbar" statusbar_visible="draft,open,paid" statusbar_colors='{"proforma":"blue","proforma2":"blue"}'/>
</header>
<sheet string="Supplier Invoice">
<div class="oe_title">
<h1>
<label string="Draft Invoice" attrs="{'invisible': ['|',('state','&lt;&gt;','draft'), ('type','&lt;&gt;','in_invoice')]}"/>
<label string="Draft Refund" attrs="{'invisible': ['|',('state','&lt;&gt;','draft'), ('type','&lt;&gt;','in_refund')]}"/>
<label string="Invoice" attrs="{'invisible': ['|',('state', '=', 'draft'), ('type','&lt;&gt;','in_invoice')]}"/>
<label string="Refund" attrs="{'invisible': ['|',('state', '=', 'draft'), ('type','&lt;&gt;','in_refund')]}"/>
<field name="number" class="oe_inline" attrs="{'invisible': [('state', '=', 'draft')]}"/>
</h1>
</div>
<field name="type" invisible="1"/>
<group>
<group>
<field string="Supplier" name="partner_id"
on_change="onchange_partner_id(type,partner_id,date_invoice,payment_term, partner_bank_id,company_id)"
context="{'default_customer': 0, 'search_default_supplier': 1, 'default_supplier': 1}"
domain="[('supplier', '=', True)]"/>
<field name="fiscal_position" widget="selection"/>
<field name="origin"/>
<field name="supplier_invoice_number"/>
<label for="reference_type"/>
<div>
<field name="reference_type" class="oe_inline oe_edit_only"/>
<field name="reference" class="oe_inline"/>
</div>
</group>
<group>
<field name="date_invoice"/>
<field name="date_due"/>
<field domain="[('company_id', '=', company_id), ('type', '=', 'payable')]"
name="account_id" groups="account.group_account_user"/>
<field name="journal_id" groups="account.group_account_user"
on_change="onchange_journal_id(journal_id, context)" widget="selection"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="check_total" groups="account.group_supplier_inv_check_total"/>
</group>
</group>
<notebook colspan="4">
<notebook>
<page string="Invoice">
<field domain="[('company_id', '=', company_id), ('type', '=', 'payable')]" name="account_id" groups="account.group_account_user"/>
<field name="reference_type" nolabel="1" size="0"/>
<field name="reference" nolabel="1"/>
<field name="date_due"/>
<field name="check_total" invisible="1"/>
<field colspan="4" default_get="{'check_total': check_total, 'invoice_line': invoice_line, 'address_invoice_id': address_invoice_id, 'partner_id': partner_id, 'price_type': 'price_type' in dir() and price_type or False}" name="invoice_line" context="{'type': type}" nolabel="1">
<tree string="Invoice lines">
<field name="product_id" on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.address_invoice_id, parent.currency_id, context, parent.company_id)"/>
<field domain="[('company_id', '=', parent.company_id), ('journal_id', '=', parent.journal_id), ('type', '&lt;&gt;', 'view')]" name="account_id" on_change="onchange_account_id(parent.fiscal_position,account_id)"/>
<field name="invoice_line_tax_id" view_mode="2" context="{'type':parent.type}" domain="[('parent_id','=',False)]"/>
<field domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id), ('parent_id', '!=', False)]" name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
<field context="{'partner_id': partner_id, 'price_type': context.get('price_type') or False, 'type': type}" name="invoice_line">
<tree string="Invoice lines" editable="bottom">
<field name="product_id"
on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/>
<field name="name"/>
<field name="company_id" invisible="1"/>
<field name="account_id" groups="account.group_account_user"
domain="[('company_id', '=', parent.company_id), ('journal_id', '=', parent.journal_id), ('type', '!=', 'view')]"
on_change="onchange_account_id(product_id, parent.partner_id, parent.type, parent.fiscal_position,account_id)"/>
<field name="account_analytic_id" groups="analytic.group_analytic_accounting"
domain="[('type','!=','view'), ('company_id', '=', parent.company_id)]"/>
<field name="quantity"/>
<field name="uos_id" groups="product.group_uom"
on_change="uos_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/>
<field name="price_unit"/>
<!-- Removed if subtotal is set -->
<field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="invoice_line_tax_id" widget="many2many_tags" context="{'type':parent.type}"
domain="[('parent_id','=',False),('company_id', '=', parent.company_id)]"/>
<field name="price_subtotal"/>
<field invisible="True" name="name"/>
<field invisible="True" name="uos_id"/>
</tree>
</field>
<group col="1" colspan="2">
<field name="tax_line" nolabel="1">
<group class="oe_subtotal_footer oe_right">
<field name="amount_untaxed" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<div>
<label for="amount_tax"/>
<button name="button_reset_taxes" states="draft,proforma2"
string="(update)" class="oe_link oe_edit_only"
type="object" help="Recompute taxes and total"/>
</div>
<field name="amount_tax" nolabel="1" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="amount_total" class="oe_subtotal_footer_separator" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="residual" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="reconciled" invisible="1"/>
</group>
<div style="width: 50%%">
<field name="tax_line">
<tree editable="bottom" string="Taxes">
<field name="name"/>
<field name="account_id" groups="account.group_account_invoice"/>
<field name="account_analytic_id" domain="[('type','&lt;&gt;','view'), ('company_id', '=', parent.company_id)]" groups="analytic.group_analytic_accounting"/>
<field name="base" on_change="base_change(base,parent.currency_id,parent.company_id,parent.date_invoice)" readonly="1"/>
<field name="amount" on_change="amount_change(amount,parent.currency_id,parent.company_id,parent.date_invoice)"/>
@ -197,55 +240,48 @@
<field name="factor_tax" invisible="True"/>
</tree>
</field>
</group>
<group col="4" colspan="2">
<button colspan="2" name="button_reset_taxes" states="draft" string="Compute Taxes" type="object" icon="terp-stock_format-scientific" help="This action will erase taxes"/>
<field name="amount_untaxed"/>
<label string="" colspan="2"/>
<field name="amount_tax"/>
<field name="reconciled"/>
<field name="amount_total"/>
<field name="state" widget="statusbar" statusbar_visible="draft,open,paid" statusbar_colors='{"proforma":"blue","proforma2":"blue"}'/>
<field name="residual"/>
<group col="6" colspan="4">
<button name="invoice_cancel" states="draft,proforma2,sale,open" string="Cancel" icon="gtk-cancel" groups="base.group_no_one"/>
<button name="action_cancel_draft" states="cancel" string="Set to Draft" type="object" icon="terp-stock_effects-object-colorize"/>
<button name="%(action_account_invoice_refund)d" type='action' string='Refund' states='open,paid' icon="gtk-execute"/>
<button name='%(action_account_state_open)d' type='action' string='Re-Open' groups="account.group_account_invoice" attrs="{'invisible':['|', ('state','&lt;&gt;','paid'), ('reconciled', '=', True)]}" icon="gtk-convert" help="This button only appears when the state of the invoice is 'paid' (showing that it has been fully reconciled) and auto-computed boolean 'reconciled' is False (depicting that it's not the case anymore). In other words, the invoice has been dereconciled and it does not fit anymore the 'paid' state. You should press this button to re-open it and let it continue its normal process after having resolved the eventual exceptions it may have created."/>
<button name="invoice_open" states="draft,proforma2" string="Approve" icon="terp-camera_test"/>
</div>
<div class="oe_clear">
<label for="comment"/>
</div>
<field name="comment"/>
</page>
<page string="Other Info">
<group>
<group>
<field domain="[('partner_id', '=', partner_id)]" name="partner_bank_id" on_change="onchange_partner_bank(partner_bank_id)"/>
<field name="user_id"/>
<field name="name" invisible="1"/>
<field name="payment_term" widget="selection"/>
</group>
<group>
<field name="move_id" groups="account.group_account_user"/>
<field name="period_id" domain="[('state', '=', 'draft')]" groups="account.group_account_user" widget="selection"/>
<field name="company_id" on_change="onchange_company_id(company_id,partner_id,type,invoice_line,currency_id)" widget="selection" groups="base.group_multi_company"/>
</group>
</group>
</page>
<page string="Other Info">
<field domain="[('partner_id', '=', partner_id)]" name="partner_bank_id" on_change="onchange_partner_bank(partner_bank_id)"/>
<field name="company_id" on_change="onchange_company_id(company_id,partner_id,type,invoice_line,currency_id)" widget="selection" groups="base.group_multi_company"/>
<newline/>
<field name="payment_term" widget="selection"/>
<field name="name"/>
<newline/>
<field name="origin" groups="base.group_extended"/>
<field domain="[('partner_id','=',partner_id)]" name="address_contact_id" groups="base.group_extended"/>
<field name="user_id"/>
<field name="move_id" groups="account.group_account_user"/>
<separator colspan="4" string="Additional Information"/>
<field colspan="4" name="comment" nolabel="1"/>
</page>
<page string="Payments" groups="base.group_extended">
<field name="payment_ids" colspan="4" nolabel="1" >
<page string="Payments">
<field name="payment_ids">
<tree string="Payments">
<field name="date" string="Payment Date"/>
<field name="move_id"/>
<field name="ref"/>
<field name="name" groups="base.group_extended"/>
<field name="name"/>
<field name="journal_id"/>
<field name="debit"/>
<field name="credit"/>
<field name="amount_currency" groups="base.group_extended"/>
<field name="currency_id" groups="base.group_extended"/>
<field name="amount_currency"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
@ -253,81 +289,137 @@
<record id="invoice_form" model="ir.ui.view">
<field name="name">account.invoice.form</field>
<field name="model">account.invoice</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Invoice">
<group colspan="4" col="8">
<field name="journal_id" groups="base.group_user" on_change="onchange_journal_id(journal_id)" widget="selection"/>
<field name="number"/>
<form string="Invoice" version="7.0">
<header>
<button name="action_invoice_sent" type="object" string="Send by Email" attrs="{'invisible':['|',('sent','=',True), ('state', '!=', 'open')]}" class="oe_highlight" groups="base.group_user"/>
<button name="invoice_print" string="Print" type="object" attrs="{'invisible':['|',('sent','=',True), ('state', '!=', 'open')]}" class="oe_highlight" groups="base.group_user"/>
<button name="action_invoice_sent" type="object" string="Send by Email" attrs="{'invisible':['|',('sent','=',False), ('state', '!=', 'open')]}" groups="base.group_user"/>
<button name="invoice_print" string="Print Invoice" type="object" attrs="{'invisible':['|',('sent','=',False), ('state', '!=', 'open')]}" groups="base.group_user"/>
<button name="invoice_open" states="draft" string="Validate" class="oe_highlight" groups="base.group_user"/>
<button name="invoice_open" states="proforma2" string="Validate" groups="base.group_user"/>
<button name="invoice_proforma2" states="draft" string="PRO-FORMA" groups="account.group_proforma_invoices"/>
<button name="%(action_account_invoice_refund)d" type='action' string='Refund Invoice' states='open,proforma2,paid' groups="base.group_user"/>
<button name="invoice_cancel" states="draft,proforma2,open" string="Cancel" groups="base.group_no_one"/>
<button name="action_cancel_draft" states="cancel" string="Reset to Draft" type="object" groups="base.group_user"/>
<button name='%(action_account_state_open)d' type='action' string='Re-Open' groups="account.group_account_invoice" attrs="{'invisible':['|', ('state','&lt;&gt;','paid'), ('reconciled', '=', True)]}" help="This button only appears when the state of the invoice is 'paid' (showing that it has been fully reconciled) and auto-computed boolean 'reconciled' is False (depicting that it's not the case anymore). In other words, the invoice has been dereconciled and it does not fit anymore the 'paid' state. You should press this button to re-open it and let it continue its normal process after having resolved the eventual exceptions it may have created."/>
<!--button name="%(account_invoices)d" string="Print Invoice" type="action" states="open,paid,proforma,sale,proforma2"/-->
<field name="state" widget="statusbar" nolabel="1" statusbar_visible="draft,open,paid" statusbar_colors='{"proforma":"blue","proforma2":"blue"}'/>
</header>
<sheet string="Invoice">
<h1>
<label string="Draft Invoice " attrs="{'invisible': ['|',('state','not in',('draft',)), ('type','&lt;&gt;','out_invoice')]}"/>
<label string="Draft Refund " attrs="{'invisible': ['|',('state','not in',('draft',)), ('type','&lt;&gt;','out_refund')]}"/>
<label string="Pro Forma Invoice " attrs="{'invisible': [('state','not in',('proforma','proforma2'))]}"/>
<label string="Invoice " attrs="{'invisible': ['|',('state','in',('draft','proforma','proforma2')), ('type','&lt;&gt;','out_invoice')]}"/>
<label string="Refund " attrs="{'invisible': ['|',('state','in',('draft','proforma','proforma2')), ('type','&lt;&gt;','out_refund')]}"/>
<field name="number" readonly="1" class="oe_inline"/>
</h1>
<field name="type" invisible="1"/>
<field name="currency_id" width="50"/>
<button name="%(action_account_change_currency)d" type="action" icon="terp-stock_effects-object-colorize" string="Change" attrs="{'invisible':[('state','!=','draft')]}" groups="account.group_account_user"/>
<newline/>
<field string="Customer" name="partner_id" on_change="onchange_partner_id(type,partner_id,date_invoice,payment_term, partner_bank_id,company_id)" groups="base.group_user" context="{'search_default_customer': 1}" options='{"quick_create": false}'/>
<field domain="[('partner_id','=',partner_id)]" name="address_invoice_id" context="{'default_partner_id': partner_id}" options='{"quick_create": false}'/>
<field name="fiscal_position" groups="base.group_extended" widget="selection" options='{"quick_create": false}'/>
<newline/>
<field name="date_invoice"/>
<field name="period_id" domain="[('state', '=', 'draft')]" groups="account.group_account_user" widget="selection"/>
<field name="payment_term" widget="selection"/>
<newline/>
<field domain="[('company_id', '=', company_id),('type','=', 'receivable')]" name="account_id" groups="account.group_account_user"/>
<field name="name" groups="base.group_extended"/>
<group>
<group>
<field string="Customer" name="partner_id"
on_change="onchange_partner_id(type,partner_id,date_invoice,payment_term, partner_bank_id,company_id)"
groups="base.group_user" context="{'search_default_customer':1, 'show_address': 1}"
options='{"always_reload": True}'/>
<field name="fiscal_position" widget="selection" />
</group>
<group>
<field name="date_invoice"/>
<field name="journal_id" groups="account.group_account_user"
on_change="onchange_journal_id(journal_id, context)" widget="selection"/>
<field domain="[('company_id', '=', company_id),('type','=', 'receivable')]"
name="account_id" groups="account.group_account_user"/>
<label for="currency_id" groups="base.group_multi_currency"/>
<div groups="base.group_multi_currency">
<field name="currency_id" class="oe_inline"/>
<!-- note fp: I don't think we need this feature ?
<button name="%(action_account_change_currency)d" type="action"
icon="terp-stock_effects-object-colorize"
attrs="{'invisible':[('state','!=','draft')]}"
groups="account.group_account_user"/> -->
</div>
</group>
</group>
<field name="sent" invisible="1"/>
<notebook colspan="4">
<page string="Invoice">
<field colspan="4" name="invoice_line" nolabel="1" widget="one2many_list" context="{'type': type}"/>
<group col="1" colspan="2">
<field name="tax_line" nolabel="1">
<tree editable="bottom" string="Taxes">
<field name="name"/>
<field name="account_id" groups="account.group_account_invoice"/>
<field name="base" on_change="base_change(base,parent.currency_id,parent.company_id,parent.date_invoice)" readonly="1"/>
<field name="amount" on_change="amount_change(amount,parent.currency_id,parent.company_id,parent.date_invoice)"/>
<field invisible="True" name="base_amount"/>
<field invisible="True" name="tax_amount"/>
<field name="factor_base" invisible="True"/>
<field name="factor_tax" invisible="True"/>
</tree>
</field>
<page string="Invoice Lines">
<field name="invoice_line" nolabel="1" widget="one2many_list" context="{'type': type}">
<tree string="Invoice Lines" editable="bottom">
<field name="product_id"
on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/>
<field name="name"/>
<field name="company_id" invisible="1"/>
<field name="account_id" groups="account.group_account_user"
domain="[('company_id', '=', parent.company_id), ('journal_id', '=', parent.journal_id), ('type', '!=', 'view')]"
on_change="onchange_account_id(product_id, parent.partner_id, parent.type, parent.fiscal_position,account_id)"/>
<field name="account_analytic_id" groups="analytic.group_analytic_accounting"
domain="[('type','!=','view'), ('company_id', '=', parent.company_id)]"/>
<field name="quantity"/>
<field name="uos_id" groups="product.group_uom"
on_change="uos_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/>
<field name="price_unit"/>
<field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="invoice_line_tax_id" widget="many2many_tags" context="{'type':parent.type}"
domain="[('parent_id','=',False),('company_id', '=', parent.company_id)]"/>
<field name="price_subtotal"/>
</tree>
</field>
<group class="oe_subtotal_footer oe_right">
<field name="amount_untaxed" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<div>
<label for="amount_tax"/>
<button name="button_reset_taxes" states="draft,proforma2"
string="(update)" class="oe_link oe_edit_only"
type="object" help="Recompute taxes and total"/>
</div>
<field name="amount_tax" nolabel="1" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="amount_total" class="oe_subtotal_footer_separator" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="residual" groups="account.group_account_user" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="reconciled" invisible="1"/>
</group>
<group col="4" colspan="2">
<button colspan="2" name="button_reset_taxes" states="draft,proforma2" string="Compute Taxes" type="object" groups="base.group_user" icon="terp-stock_format-scientific" help="This action will erase taxes"/>
<field name="amount_untaxed"/>
<label string="" colspan="2"/>
<field name="amount_tax"/>
<field name="reconciled"/>
<field name="amount_total"/>
<field name="state" widget="statusbar" statusbar_visible="draft,open,paid" statusbar_colors='{"proforma":"blue","proforma2":"blue"}'/>
<field name="residual"/>
<group col="8" colspan="4" groups="base.group_user">
<button name="invoice_cancel" states="draft,proforma2,sale,open" string="Cancel" icon="gtk-cancel" groups="base.group_no_one"/>
<button name="action_cancel_draft" states="cancel" string="Reset to Draft" type="object" icon="terp-stock_effects-object-colorize"/>
<button name='%(action_account_state_open)d' type='action' string='Re-Open' groups="account.group_account_invoice" attrs="{'invisible':['|', ('state','&lt;&gt;','paid'), ('reconciled', '=', True)]}" icon="gtk-convert" help="This button only appears when the state of the invoice is 'paid' (showing that it has been fully reconciled) and auto-computed boolean 'reconciled' is False (depicting that it's not the case anymore). In other words, the invoice has been dereconciled and it does not fit anymore the 'paid' state. You should press this button to re-open it and let it continue its normal process after having resolved the eventual exceptions it may have created."/>
<button name="%(action_account_invoice_refund)d" type='action' string='Refund' states='open,paid' icon="gtk-execute"/>
<button name="invoice_proforma2" states="draft" string="PRO-FORMA" icon="terp-gtk-media-pause" groups="account.group_account_user"/>
<button name="invoice_open" states="draft,proforma2" string="Validate" icon="gtk-go-forward"/>
<button name="%(account_invoices)d" string="Print Invoice" type="action" icon="gtk-print" states="open,paid,proforma,sale,proforma2"/>
</group>
<group>
<field name="payment_term" class="oe_inline"/>
</group>
<div class="oe_clear">
<label for="comment"/>
</div>
<field name="comment" class="oe_inline" placeholder="Additional notes..."/>
</page>
<page string="Other Info">
<field name="company_id" on_change="onchange_company_id(company_id,partner_id,type,invoice_line,currency_id)" widget="selection" groups="base.group_multi_company"/>
<newline/>
<field name="date_due"/>
<field name="user_id"/>
<newline/>
<field domain="[('partner_id.ref_companies', 'in', [company_id])]" name="partner_bank_id"
groups="base.group_extended"/>
<field name="origin"/>
<field colspan="4" domain="[('partner_id','=',partner_id)]" name="address_contact_id"
groups="base.group_extended"/>
<field name="move_id" groups="account.group_account_user"/>
<separator colspan="4" string="Additional Information"/>
<field colspan="4" name="comment" nolabel="1"/>
<group col="4">
<group>
<field name="company_id" on_change="onchange_company_id(company_id,partner_id,type,invoice_line,currency_id)" widget="selection" groups="base.group_multi_company"/>
<field name="user_id" groups="base.group_user"/>
<field domain="[('partner_id.ref_companies', 'in', [company_id])]" name="partner_bank_id"/>
<field name="period_id" domain="[('state', '=', 'draft')]"
groups="account.group_account_manager"
string="Accounting Period"
placeholder="force period"/>
<field name="date_due"/>
</group>
<group>
<field name="origin" groups="base.group_user"/>
<field name="name" string="Customer Reference"/>
<field name="move_id" groups="account.group_account_user"/>
</group>
</group>
<field name="tax_line">
<tree editable="bottom" string="Taxes">
<field name="name"/>
<field name="account_id" groups="account.group_account_user"/>
<field name="base" on_change="base_change(base,parent.currency_id,parent.company_id,parent.date_invoice)" readonly="1"/>
<field name="amount" on_change="amount_change(amount,parent.currency_id,parent.company_id,parent.date_invoice)"/>
<field invisible="True" name="base_amount"/>
<field invisible="True" name="tax_amount"/>
<field name="factor_base" invisible="True"/>
<field name="factor_tax" invisible="True"/>
</tree>
</field>
</page>
<page string="Payments">
<field name="payment_ids" colspan="4" nolabel="1">
<page string="Payments" groups="base.group_user">
<field name="payment_ids">
<tree string="Payments">
<field name="date"/>
<field name="move_id"/>
@ -336,12 +428,17 @@
<field name="journal_id" groups="base.group_user"/>
<field name="debit"/>
<field name="credit"/>
<field name="amount_currency"/>
<field name="currency_id"/>
<field name="amount_currency" groups="base.group_multi_currency"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" groups="base.group_user"/>
<field name="message_ids" widget="mail_thread" placeholder="Share a note..."/>
</div>
</form>
</field>
</record>
@ -349,37 +446,23 @@
<record id="view_account_invoice_filter" model="ir.ui.view">
<field name="name">account.invoice.select</field>
<field name="model">account.invoice</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Invoice">
<group>
<filter name="draft" icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Invoices"/>
<filter name="proforma" icon="terp-gtk-media-pause" string="Proforma" domain="[('state','=','proforma2')]" help="Proforma Invoices"/>
<filter name="invoices" icon="terp-dolar" string="Invoices" domain="[('state','not in',['draft','cancel'])]" help="Proforma/Open/Paid Invoices"/>
<separator orientation="vertical"/>
<filter name="unpaid" icon="terp-dolar_ok!" string="Unpaid" domain="[('state','=','open')]" help="Unpaid Invoices"/>
<separator orientation="vertical"/>
<field name="number"
string="Reference"
filter_domain="['|', ('number','ilike',self),('origin','ilike',self)]"/>
<field name="partner_id"/>
<field name="user_id" widget="selection" string="Salesman">
<filter domain="[('user_id','=',uid)]" help="My invoices" icon="terp-personal" />
</field>
</group>
<newline/>
<group>
<field name="journal_id" widget="selection"/>
<field name="period_id" string="Period"/>
</group>
<newline/>
<field name="number" string="Invoice" filter_domain="['|','|', ('number','ilike',self), ('origin','ilike',self), ('supplier_invoice_number', 'ilike', self)]"/>
<filter name="draft" icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Invoices"/>
<filter name="proforma" icon="terp-gtk-media-pause" string="Proforma" domain="[('state','=','proforma2')]" help="Proforma Invoices" groups="account.group_proforma_invoices"/>
<filter name="invoices" icon="terp-dolar" string="Invoices" domain="[('state','not in',['draft','cancel'])]" help="Proforma/Open/Paid Invoices"/>
<filter name="unpaid" icon="terp-dolar_ok!" string="Unpaid" domain="[('state','=','open')]" help="Unpaid Invoices"/>
<separator/>
<filter domain="[('user_id','=',uid)]" help="My Invoices" icon="terp-personal"/>
<field name="partner_id"/>
<field name="user_id" string="Salesperson"/>
<field name="period_id" string="Period"/>
<group expand="0" string="Group By...">
<filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<separator orientation="vertical"/>
<filter string="Journal" icon="terp-folder-orange" domain="[]" context="{'group_by':'journal_id'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<filter string="Period" icon="terp-go-month" domain="[]" context="{'group_by':'period_id'}"/>
<filter string="Invoice Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_invoice'}"/>
<filter string="Due Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_due'}"/>
@ -431,7 +514,19 @@
<field name="domain">[('type','=','out_invoice')]</field>
<field name="context">{'default_type':'out_invoice', 'type':'out_invoice', 'journal_type': 'sale'}</field>
<field name="search_view_id" ref="view_account_invoice_filter"/>
<field name="help">With Customer Invoices you can create and manage sales invoices issued to your customers. OpenERP can also generate draft invoices automatically from sales orders or deliveries. You should only confirm them before sending them to your customers.</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a customer invoice.
</p><p>
OpenERP's electronic invoicing allows to ease and fasten the
collection of customer payments. Your customer receives the
invoice by email and he can pay online and/or import it
in his own system.
</p><p>
The discussions with your customer are automatically displayed at
the bottom of each invoice.
</p>
</field>
</record>
@ -459,7 +554,15 @@
<field name="domain">[('type','=','in_invoice')]</field>
<field name="context">{'default_type': 'in_invoice', 'type': 'in_invoice', 'journal_type': 'purchase'}</field>
<field name="search_view_id" ref="view_account_invoice_filter"/>
<field name="help">With Supplier Invoices you can enter and manage invoices issued by your suppliers. OpenERP can also generate draft invoices automatically from purchase orders or receipts. This way, you can control the invoice from your supplier according to what you purchased or received.</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to record a new supplier invoice.
</p><p>
You can control the invoice from your supplier according to
what you purchased or received. OpenERP can also generate
draft invoices automatically from purchase orders or receipts.
</p>
</field>
</record>
<menuitem action="action_invoice_tree2" id="menu_action_invoice_tree2" parent="menu_finance_payables"/>
@ -472,7 +575,17 @@
<field name="domain">[('type','=','out_refund')]</field>
<field name="context">{'default_type':'out_refund', 'type':'out_refund', 'journal_type': 'sale_refund'}</field>
<field name="search_view_id" ref="view_account_invoice_filter"/>
<field name="help">With Customer Refunds you can manage the credit notes for your customers. A refund is a document that credits an invoice completely or partially. You can easily generate refunds and reconcile them directly from the invoice form.</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a customer refund.
</p><p>
A refund is a document that credits an invoice completely or
partially.
</p><p>
Instead of manually creating a customer refund, you
can generate it directly from the related customer invoice.
</p>
</field>
</record>
<record id="action_invoice_tree3_view1" model="ir.actions.act_window.view">
@ -498,7 +611,14 @@
<field name="domain">[('type','=','in_refund')]</field>
<field name="context">{'default_type': 'in_refund', 'type': 'in_refund', 'journal_type': 'purchase_refund'}</field>
<field name="search_view_id" ref="view_account_invoice_filter"/>
<field name="help">With Supplier Refunds you can manage the credit notes you receive from your suppliers. A refund is a document that credits an invoice completely or partially. You can easily generate refunds and reconcile them directly from the invoice form.</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to register a refund you received from a supplier.
</p><p>
Instead of creating the supplier refund manually, you can generate
refunds and reconcile them directly from the related supplier invoice.
</p>
</field>
</record>
<menuitem action="action_invoice_tree4" id="menu_action_invoice_tree4" parent="menu_finance_payables"/>
@ -508,6 +628,7 @@
id="act_account_journal_2_account_invoice_opened"
name="Unpaid Invoices"
context="{'search_default_journal_id': [active_id], 'search_default_unpaid':1, 'default_journal_id': active_id}"
domain="[('journal_id','=', active_id)]"
res_model="account.invoice"
src_model="account.journal"/>

View File

@ -27,7 +27,7 @@
<field name="action">action_date_assign()
action_move_create()
action_number()
write({'state':'open'})</field>
invoice_validate()</field>
<field name="kind">function</field>
</record>
<record model="workflow.activity" id="act_open_test">

View File

@ -2,48 +2,49 @@
<openerp>
<data>
<menuitem icon="terp-account" id="menu_finance" name="Accounting" sequence="13"
<!-- Top menu item -->
<menuitem name="Invoicing"
id="menu_finance"
groups="group_account_user,group_account_manager,group_account_invoice"
web_icon="images/accounting.png"
web_icon_hover="images/accounting-hover.png"/>
sequence="50"/>
<menuitem id="menu_finance_receivables" name="Customers" parent="menu_finance" sequence="2"/>
<menuitem id="menu_finance_payables" name="Suppliers" parent="menu_finance" sequence="3"/>
<menuitem id="menu_finance_bank_and_cash" name="Bank and Cash" parent="menu_finance" sequence="4"
groups="group_account_user,group_account_manager"/>
<menuitem id="menu_finance_periodical_processing" name="Periodical Processing" parent="menu_finance" sequence="9" groups="group_account_user,group_account_manager"/>
<menuitem id="menu_finance_periodical_processing" name="Periodic Processing" parent="menu_finance" sequence="13" groups="group_account_user,group_account_manager"/>
<!-- This menu is used in account_code module -->
<menuitem id="menu_account_pp_statements" name="Statements" parent="menu_finance_periodical_processing" sequence="12"/>
<menuitem id="periodical_processing_journal_entries_validation" name="Draft Entries" parent="menu_finance_periodical_processing"/>
<menuitem id="periodical_processing_reconciliation" name="Reconciliation" parent="menu_finance_periodical_processing"/>
<menuitem id="periodical_processing_invoicing" name="Invoicing" parent="menu_finance_periodical_processing"/>
<menuitem id="menu_finance_charts" name="Charts" parent="menu_finance" groups="account.group_account_user" sequence="6"/>
<menuitem id="menu_finance_reporting" name="Reporting" parent="account.menu_finance" sequence="13"/>
<menuitem id="menu_finance_reporting" name="Accounting" parent="base.menu_reporting" sequence="35"/>
<menuitem id="menu_finance_reporting_budgets" name="Budgets" parent="menu_finance_reporting" groups="group_account_user"/>
<menuitem id="menu_finance_legal_statement" name="Legal Reports" parent="menu_finance_reporting"/>
<menuitem id="menu_finance_reports" name="Reporting" parent="menu_finance" sequence="14" groups="group_account_user,group_account_manager"/>
<menuitem id="menu_finance_legal_statement" name="Legal Reports" parent="menu_finance_reports"/>
<menuitem id="menu_finance_management_belgian_reports" name="Belgian Reports" parent="menu_finance_reporting"/>
<menuitem id="menu_finance_configuration" name="Configuration" parent="menu_finance" sequence="14" groups="group_account_manager"/>
<menuitem id="menu_finance_accounting" name="Financial Accounting" parent="menu_finance_configuration"/>
<menuitem id="menu_analytic_accounting" name="Analytic Accounting" parent="menu_finance_configuration" groups="analytic.group_analytic_accounting"/>
<menuitem id="menu_finance_configuration" name="Configuration" parent="menu_finance" sequence="15" groups="group_account_manager"/>
<menuitem id="menu_finance_accounting" name="Financial Accounting" parent="menu_finance_configuration" sequence="1"/>
<menuitem id="menu_analytic_accounting" name="Analytic Accounting" parent="menu_finance_configuration" groups="analytic.group_analytic_accounting" sequence="40"/>
<menuitem id="menu_analytic" parent="menu_analytic_accounting" name="Accounts" groups="analytic.group_analytic_accounting"/>
<menuitem id="menu_journals" sequence="9" name="Journals" parent="menu_finance_accounting" groups="group_account_manager"/>
<menuitem id="menu_configuration_misc" name="Miscellaneous" parent="menu_finance_configuration" sequence="30"/>
<menuitem id="base.menu_action_currency_form" parent="menu_configuration_misc" sequence="20"/>
<menuitem id="menu_finance_generic_reporting" name="Generic Reporting" parent="menu_finance_reporting" sequence="100"/>
<menuitem id="menu_journals" sequence="15" name="Journals" parent="menu_finance_configuration" groups="group_account_manager"/>
<menuitem id="menu_configuration_misc" name="Miscellaneous" parent="menu_finance_configuration" sequence="55"/>
<menuitem id="base.menu_action_currency_form" name="Currencies" parent="menu_configuration_misc" sequence="20" groups="base.group_no_one"/>
<menuitem id="menu_finance_generic_reporting" name="Generic Reporting" parent="menu_finance_reports" sequence="100"/>
<menuitem id="menu_finance_entries" name="Journal Entries" parent="menu_finance" sequence="5" groups="group_account_user,group_account_manager"/>
<menuitem id="menu_account_reports" name="Financial Reports" parent="menu_finance_accounting" sequence="18"/>
<menuitem id="menu_account_reports" name="Financial Reports" parent="menu_finance_configuration" sequence="30" />
<menuitem id="account.menu_finance_recurrent_entries" name="Recurring Entries"
parent="menu_finance_periodical_processing" sequence="15"
groups="base.group_extended"/>
parent="menu_finance_periodical_processing" sequence="15"/>
<menuitem id="menu_account_end_year_treatments"
name="End of Period" parent="menu_finance_periodical_processing"
sequence="25"/>
<menuitem id="menu_finance_periodical_processing_billing" name="Billing" parent="menu_finance_periodical_processing" sequence="35"/>
<menuitem id="menu_finance_statistic_report_statement" name="Statistic Reports" parent="menu_finance_reporting" sequence="300"/>
<menuitem id="next_id_22" name="Partners" parent="menu_finance_generic_reporting" sequence="1"/>
<menuitem id="menu_multi_currency" name="Multi-Currencies" parent="menu_finance_generic_reporting" sequence="10"/>
<menuitem id="menu_multi_currency" name="Multi-Currencies" parent="menu_finance_generic_reporting" sequence="10" groups="base.group_multi_currency"/>
<menuitem
parent="account.menu_finance_legal_statement"
id="final_accounting_reports"

View File

@ -19,17 +19,18 @@
#
##############################################################################
import sys
import time
from datetime import datetime
from operator import itemgetter
from lxml import etree
import netsvc
from osv import fields, osv, orm
from tools.translate import _
import decimal_precision as dp
import tools
from openerp import netsvc
from openerp.osv import fields, osv, orm
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp
from openerp import tools
class account_move_line(osv.osv):
_name = "account.move.line"
@ -94,7 +95,7 @@ class account_move_line(osv.osv):
if initial_bal and not context.get('periods', False) and not where_move_lines_by_date:
#we didn't pass any filter in the context, and the initial balance can't be computed using only the fiscalyear otherwise entries will be summed twice
#so we have to invalidate this query
raise osv.except_osv(_('Warning !'),_("You haven't supplied enough argument to compute the initial balance, please select a period and journal in the context."))
raise osv.except_osv(_('Warning!'),_("You have not supplied enough arguments to compute the initial balance, please select a period and a journal in the context."))
if context.get('journal_ids', False):
@ -165,28 +166,35 @@ class account_move_line(osv.osv):
del data[f]
return data
def _prepare_analytic_line(self, cr, uid, obj_line, context=None):
"""
Prepare the values given at the create() of account.analytic.line upon the validation of a journal item having
an analytic account. This method is intended to be extended in other modules.
:param obj_line: browse record of the account.move.line that triggered the analytic line creation
"""
return {'name': obj_line.name,
'date': obj_line.date,
'account_id': obj_line.analytic_account_id.id,
'unit_amount': obj_line.quantity,
'product_id': obj_line.product_id and obj_line.product_id.id or False,
'product_uom_id': obj_line.product_uom_id and obj_line.product_uom_id.id or False,
'amount': (obj_line.credit or 0.0) - (obj_line.debit or 0.0),
'general_account_id': obj_line.account_id.id,
'journal_id': obj_line.journal_id.analytic_journal_id.id,
'ref': obj_line.ref,
'move_id': obj_line.id,
'user_id': uid,
}
def create_analytic_lines(self, cr, uid, ids, context=None):
acc_ana_line_obj = self.pool.get('account.analytic.line')
for obj_line in self.browse(cr, uid, ids, context=context):
if obj_line.analytic_account_id:
if not obj_line.journal_id.analytic_journal_id:
raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (obj_line.journal_id.name, ))
amt = (obj_line.credit or 0.0) - (obj_line.debit or 0.0)
vals_lines = {
'name': obj_line.name,
'date': obj_line.date,
'account_id': obj_line.analytic_account_id.id,
'unit_amount': obj_line.quantity,
'product_id': obj_line.product_id and obj_line.product_id.id or False,
'product_uom_id': obj_line.product_uom_id and obj_line.product_uom_id.id or False,
'amount': amt,
'general_account_id': obj_line.account_id.id,
'journal_id': obj_line.journal_id.analytic_journal_id.id,
'ref': obj_line.ref,
'move_id': obj_line.id,
'user_id': uid
}
acc_ana_line_obj.create(cr, uid, vals_lines)
vals_line = self._prepare_analytic_line(cr, uid, obj_line, context=context)
acc_ana_line_obj.create(cr, uid, vals_line)
return True
def _default_get_move_form_hook(self, cursor, user, data):
@ -207,15 +215,16 @@ class account_move_line(osv.osv):
if type(period_id) == str:
ids = period_obj.search(cr, uid, [('name', 'ilike', period_id)])
context.update({
'period_id': ids[0]
'period_id': ids and ids[0] or False
})
return context
def _default_get(self, cr, uid, fields, context=None):
#default_get should only do the following:
# -propose the next amount in debit/credit in order to balance the move
# -propose the next account from the journal (default debit/credit account) accordingly
if context is None:
context = {}
if not context.get('journal_id', False) and context.get('search_default_journal_id', False):
context['journal_id'] = context.get('search_default_journal_id')
account_obj = self.pool.get('account.account')
period_obj = self.pool.get('account.period')
journal_obj = self.pool.get('account.journal')
@ -224,136 +233,71 @@ class account_move_line(osv.osv):
fiscal_pos_obj = self.pool.get('account.fiscal.position')
partner_obj = self.pool.get('res.partner')
currency_obj = self.pool.get('res.currency')
if not context.get('journal_id', False):
context['journal_id'] = context.get('search_default_journal_id', False)
if not context.get('period_id', False):
context['period_id'] = context.get('search_default_period_id', False)
context = self.convert_to_period(cr, uid, context)
# Compute simple values
data = super(account_move_line, self).default_get(cr, uid, fields, context=context)
# Starts: Manual entry from account.move form
if context.get('lines',[]):
total_new = 0.00
for i in context['lines']:
if i[2]:
total_new += (i[2]['debit'] or 0.00)- (i[2]['credit'] or 0.00)
for item in i[2]:
data[item] = i[2][item]
if context['journal']:
journal_data = journal_obj.browse(cr, uid, context['journal'], context=context)
if journal_data.type == 'purchase':
if total_new > 0:
account = journal_data.default_credit_account_id
else:
account = journal_data.default_debit_account_id
else:
if total_new > 0:
account = journal_data.default_credit_account_id
else:
account = journal_data.default_debit_account_id
if account and ((not fields) or ('debit' in fields) or ('credit' in fields)) and 'partner_id' in data and (data['partner_id']):
part = partner_obj.browse(cr, uid, data['partner_id'], context=context)
account = fiscal_pos_obj.map_account(cr, uid, part and part.property_account_position or False, account.id)
account = account_obj.browse(cr, uid, account, context=context)
data['account_id'] = account.id
s = -total_new
data['debit'] = s > 0 and s or 0.0
data['credit'] = s < 0 and -s or 0.0
data = self._default_get_move_form_hook(cr, uid, data)
return data
# Ends: Manual entry from account.move form
if not 'move_id' in fields: #we are not in manual entry
return data
# Compute the current move
move_id = False
partner_id = False
if context.get('journal_id', False) and context.get('period_id', False):
if 'move_id' in fields:
cr.execute('SELECT move_id \
FROM \
account_move_line \
WHERE \
journal_id = %s and period_id = %s AND create_uid = %s AND state = %s \
ORDER BY id DESC limit 1',
(context['journal_id'], context['period_id'], uid, 'draft'))
if context.get('journal_id'):
total = 0.0
#in account.move form view, it is not possible to compute total debit and credit using
#a browse record. So we must use the context to pass the whole one2many field and compute the total
if context.get('line_id'):
for move_line_dict in move_obj.resolve_2many_commands(cr, uid, 'line_id', context.get('line_id'), context=context):
data['name'] = data.get('name') or move_line_dict.get('name')
data['partner_id'] = data.get('partner_id') or move_line_dict.get('partner_id')
total += move_line_dict.get('debit', 0.0) - move_line_dict.get('credit', 0.0)
elif context.get('period_id'):
#find the date and the ID of the last unbalanced account.move encoded by the current user in that journal and period
move_id = False
cr.execute('''SELECT move_id, date FROM account_move_line
WHERE journal_id = %s AND period_id = %s AND create_uid = %s AND state = %s
ORDER BY id DESC limit 1''', (context['journal_id'], context['period_id'], uid, 'draft'))
res = cr.fetchone()
move_id = (res and res[0]) or False
if not move_id:
return data
else:
data['move_id'] = move_id
if 'date' in fields:
cr.execute('SELECT date \
FROM \
account_move_line \
WHERE \
journal_id = %s AND period_id = %s AND create_uid = %s \
ORDER BY id DESC',
(context['journal_id'], context['period_id'], uid))
res = cr.fetchone()
if res:
data['date'] = res[0]
else:
period = period_obj.browse(cr, uid, context['period_id'],
context=context)
data['date'] = period.date_start
if not move_id:
return data
total = 0
ref_id = False
move = move_obj.browse(cr, uid, move_id, context=context)
if 'name' in fields:
data.setdefault('name', move.line_id[-1].name)
acc1 = False
for l in move.line_id:
acc1 = l.account_id
partner_id = partner_id or l.partner_id.id
ref_id = ref_id or l.ref
total += (l.debit or 0.0) - (l.credit or 0.0)
move_id = res and res[0] or False
data['date'] = res and res[1] or period_obj.browse(cr, uid, context['period_id'], context=context).date_start
data['move_id'] = move_id
if move_id:
#if there exist some unbalanced accounting entries that match the journal and the period,
#we propose to continue the same move by copying the ref, the name, the partner...
move = move_obj.browse(cr, uid, move_id, context=context)
data.setdefault('name', move.line_id[-1].name)
for l in move.line_id:
data['partner_id'] = data.get('partner_id') or l.partner_id.id
data['ref'] = data.get('ref') or l.ref
total += (l.debit or 0.0) - (l.credit or 0.0)
if 'ref' in fields:
data['ref'] = ref_id
if 'partner_id' in fields:
data['partner_id'] = partner_id
if move.journal_id.type == 'purchase':
if total > 0:
account = move.journal_id.default_credit_account_id
else:
account = move.journal_id.default_debit_account_id
else:
if total > 0:
account = move.journal_id.default_credit_account_id
else:
account = move.journal_id.default_debit_account_id
part = partner_id and partner_obj.browse(cr, uid, partner_id) or False
# part = False is acceptable for fiscal position.
account = fiscal_pos_obj.map_account(cr, uid, part and part.property_account_position or False, account.id)
if account:
account = account_obj.browse(cr, uid, account, context=context)
if account and ((not fields) or ('debit' in fields) or ('credit' in fields)):
data['account_id'] = account.id
# Propose the price VAT excluded, the VAT will be added when confirming line
if account.tax_ids:
taxes = fiscal_pos_obj.map_tax(cr, uid, part and part.property_account_position or False, account.tax_ids)
tax = tax_obj.browse(cr, uid, taxes)
for t in tax_obj.compute_inv(cr, uid, tax, total, 1):
total -= t['amount']
s = -total
data['debit'] = s > 0 and s or 0.0
data['credit'] = s < 0 and -s or 0.0
if account and account.currency_id:
data['currency_id'] = account.currency_id.id
acc = account
if s>0:
acc = acc1
compute_ctx = context.copy()
compute_ctx.update({
'res.currency.compute.account': acc,
'res.currency.compute.account_invert': True,
})
v = currency_obj.compute(cr, uid, account.company_id.currency_id.id, data['currency_id'], s, context=compute_ctx)
data['amount_currency'] = v
#compute the total of current move
data['debit'] = total < 0 and -total or 0.0
data['credit'] = total > 0 and total or 0.0
#pick the good account on the journal accordingly if the next proposed line will be a debit or a credit
journal_data = journal_obj.browse(cr, uid, context['journal_id'], context=context)
account = total > 0 and journal_data.default_credit_account_id or journal_data.default_debit_account_id
#map the account using the fiscal position of the partner, if needed
part = data.get('partner_id') and partner_obj.browse(cr, uid, data['partner_id'], context=context) or False
if account and data.get('partner_id'):
account = fiscal_pos_obj.map_account(cr, uid, part and part.property_account_position or False, account.id)
account = account_obj.browse(cr, uid, account, context=context)
data['account_id'] = account and account.id or False
#compute the amount in secondary currency of the account, if needed
if account and account.currency_id:
data['currency_id'] = account.currency_id.id
#set the context for the multi currency change
compute_ctx = context.copy()
compute_ctx.update({
#the following 2 parameters are used to choose the currency rate, in case where the account
#doesn't work with an outgoing currency rate method 'at date' but 'average'
'res.currency.compute.account': account,
'res.currency.compute.account_invert': True,
})
if data.get('date'):
compute_ctx.update({'date': data['date']})
data['amount_currency'] = currency_obj.compute(cr, uid, account.company_id.currency_id.id, data['currency_id'], -total, context=compute_ctx)
data = self._default_get_move_form_hook(cr, uid, data)
return data
def on_create_write(self, cr, uid, id, context=None):
@ -476,33 +420,43 @@ class account_move_line(osv.osv):
result.append(line.id)
return result
def _get_reconcile(self, cr, uid, ids,name, unknow_none, context=None):
res = dict.fromkeys(ids, False)
for line in self.browse(cr, uid, ids, context=context):
if line.reconcile_id:
res[line.id] = str(line.reconcile_id.name)
elif line.reconcile_partial_id:
res[line.id] = str(line.reconcile_partial_id.name)
return res
_columns = {
'name': fields.char('Name', size=64, required=True),
'quantity': fields.float('Quantity', digits=(16,2), help="The optional quantity expressed by this line, eg: number of product sold. The quantity is not a legal requirement but is very useful for some reports."),
'product_uom_id': fields.many2one('product.uom', 'UoM'),
'product_uom_id': fields.many2one('product.uom', 'Unit of Measure'),
'product_id': fields.many2one('product.product', 'Product'),
'debit': fields.float('Debit', digits_compute=dp.get_precision('Account')),
'credit': fields.float('Credit', digits_compute=dp.get_precision('Account')),
'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade", domain=[('type','<>','view'), ('type', '<>', 'closed')], select=2),
'move_id': fields.many2one('account.move', 'Move', ondelete="cascade", help="The move of this entry line.", select=2, required=True),
'move_id': fields.many2one('account.move', 'Journal Entry', ondelete="cascade", help="The move of this entry line.", select=2, required=True),
'narration': fields.related('move_id','narration', type='text', relation='account.move', string='Internal Note'),
'ref': fields.related('move_id', 'ref', string='Reference', type='char', size=64, store=True),
'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1),
'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2),
'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2),
'reconcile': fields.function(_get_reconcile, type='char', string='Reconcile Ref'),
'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency if it is a multi-currency entry.", digits_compute=dp.get_precision('Account')),
'amount_residual_currency': fields.function(_amount_residual, string='Residual Amount', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in its currency (maybe different of the company currency)."),
'amount_residual_currency': fields.function(_amount_residual, string='Residual Amount in Currency', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in its currency (maybe different of the company currency)."),
'amount_residual': fields.function(_amount_residual, string='Residual Amount', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in the company currency."),
'currency_id': fields.many2one('res.currency', 'Currency', help="The optional other currency if it is a multi-currency entry."),
'journal_id': fields.related('move_id', 'journal_id', string='Journal', type='many2one', relation='account.journal', required=True, select=True, readonly=True,
'journal_id': fields.related('move_id', 'journal_id', string='Journal', type='many2one', relation='account.journal', required=True, select=True,
store = {
'account.move': (_get_move_lines, ['journal_id'], 20)
}),
'period_id': fields.related('move_id', 'period_id', string='Period', type='many2one', relation='account.period', required=True, select=True, readonly=True,
'period_id': fields.related('move_id', 'period_id', string='Period', type='many2one', relation='account.period', required=True, select=True,
store = {
'account.move': (_get_move_lines, ['period_id'], 20)
}),
'blocked': fields.boolean('Litigation', help="You can check this box to mark this journal item as a litigation with the associated partner"),
'blocked': fields.boolean('No Follow-up', help="You can check this box to mark this journal item as a litigation with the associated partner"),
'partner_id': fields.many2one('res.partner', 'Partner', select=1, ondelete='restrict'),
'date_maturity': fields.date('Due date', select=True ,help="This field is used for payable and receivable journal entries. You can put the limit date for the payment of this line."),
'date': fields.related('move_id','date', string='Effective date', type='date', required=True, select=True,
@ -513,8 +467,7 @@ class account_move_line(osv.osv):
'analytic_lines': fields.one2many('account.analytic.line', 'move_id', 'Analytic lines'),
'centralisation': fields.selection([('normal','Normal'),('credit','Credit Centralisation'),('debit','Debit Centralisation'),('currency','Currency Adjustment')], 'Centralisation', size=8),
'balance': fields.function(_balance, fnct_search=_balance_search, string='Balance'),
'state': fields.selection([('draft','Unbalanced'), ('valid','Valid')], 'State', readonly=True,
help='When new move line is created the state will be \'Draft\'.\n* When all the payments are done it will be in \'Valid\' state.'),
'state': fields.selection([('draft','Unbalanced'), ('valid','Balanced')], 'Status', readonly=True),
'tax_code_id': fields.many2one('account.tax.code', 'Tax Account', help="The Account can either be a base tax code or a tax code account."),
'tax_amount': fields.float('Tax/Base Amount', digits_compute=dp.get_precision('Account'), select=True, help="If the Tax account is a tax code account, this field will contain the taxed amount.If the tax account is base tax code, "\
"this field will contain the basic amount(without tax)."),
@ -522,7 +475,8 @@ class account_move_line(osv.osv):
type='many2one', relation='account.invoice', fnct_search=_invoice_search),
'account_tax_id':fields.many2one('account.tax', 'Tax'),
'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account'),
'company_id': fields.related('account_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True)
'company_id': fields.related('account_id', 'company_id', type='many2one', relation='res.company',
string='Company', store=True, readonly=True)
}
def _get_date(self, cr, uid, context=None):
@ -530,7 +484,7 @@ class account_move_line(osv.osv):
context or {}
period_obj = self.pool.get('account.period')
dt = time.strftime('%Y-%m-%d')
if ('journal_id' in context) and ('period_id' in context):
if context.get('journal_id') and context.get('period_id'):
cr.execute('SELECT date FROM account_move_line ' \
'WHERE journal_id = %s AND period_id = %s ' \
'ORDER BY id DESC limit 1',
@ -551,18 +505,51 @@ class account_move_line(osv.osv):
cur = self.pool.get('account.journal').browse(cr, uid, context['journal_id']).currency
return cur and cur.id or False
def _get_period(self, cr, uid, context=None):
"""
Return default account period value
"""
context = context or {}
if context.get('period_id', False):
return context['period_id']
account_period_obj = self.pool.get('account.period')
ids = account_period_obj.find(cr, uid, context=context)
period_id = False
if ids:
period_id = ids[0]
return period_id
def _get_journal(self, cr, uid, context=None):
"""
Return journal based on the journal type
"""
context = context or {}
if context.get('journal_id', False):
return context['journal_id']
journal_id = False
journal_pool = self.pool.get('account.journal')
if context.get('journal_type', False):
jids = journal_pool.search(cr, uid, [('type','=', context.get('journal_type'))])
if not jids:
raise osv.except_osv(_('Configuration Error!'), _('Cannot find any account journal of %s type for this company.\n\nYou can create one in the menu: \nConfiguration/Journals/Journals.') % context.get('journal_type'))
journal_id = jids[0]
return journal_id
_defaults = {
'blocked': False,
'centralisation': 'normal',
'date': _get_date,
'date_created': lambda *a: time.strftime('%Y-%m-%d'),
'date_created': fields.date.context_today,
'state': 'draft',
'currency_id': _get_currency,
'journal_id': lambda self, cr, uid, c: c.get('journal_id', False),
'journal_id': _get_journal,
'credit': 0.0,
'debit': 0.0,
'amount_currency': 0.0,
'account_id': lambda self, cr, uid, c: c.get('account_id', False),
'period_id': lambda self, cr, uid, c: c.get('period_id', False),
'period_id': _get_period,
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.move.line', context=c)
}
_order = "date desc, id desc"
@ -581,14 +568,14 @@ class account_move_line(osv.osv):
lines = self.browse(cr, uid, ids, context=context)
for l in lines:
if l.account_id.type == 'view':
raise osv.except_osv(_('Error :'), _('You can not create journal items on a "view" account %s %s') % (l.account_id.code, l.account_id.name))
return False
return True
def _check_no_closed(self, cr, uid, ids, context=None):
lines = self.browse(cr, uid, ids, context=context)
for l in lines:
if l.account_id.type == 'closed':
raise osv.except_osv(_('Error :'), _('You can not create journal items on a closed account %s %s') % (l.account_id.code, l.account_id.name))
raise osv.except_osv(_('Error!'), _('You cannot create journal items on a closed account %s %s.') % (l.account_id.code, l.account_id.name))
return True
def _check_company_id(self, cr, uid, ids, context=None):
@ -612,12 +599,34 @@ class account_move_line(osv.osv):
return False
return True
def _check_currency_and_amount(self, cr, uid, ids, context=None):
for l in self.browse(cr, uid, ids, context=context):
if (l.amount_currency and not l.currency_id):
return False
return True
def _check_currency_amount(self, cr, uid, ids, context=None):
for l in self.browse(cr, uid, ids, context=context):
if l.amount_currency:
if (l.amount_currency > 0.0 and l.credit > 0.0) or (l.amount_currency < 0.0 and l.debit > 0.0):
return False
return True
def _check_currency_company(self, cr, uid, ids, context=None):
for l in self.browse(cr, uid, ids, context=context):
if l.currency_id.id == l.company_id.currency_id.id:
return False
return True
_constraints = [
(_check_no_view, 'You can not create journal items on an account of type view.', ['account_id']),
(_check_no_closed, 'You can not create journal items on closed account.', ['account_id']),
(_check_company_id, 'Company must be the same for its related account and period.', ['company_id']),
(_check_no_view, 'You cannot create journal items on an account of type view.', ['account_id']),
(_check_no_closed, 'You cannot create journal items on closed account.', ['account_id']),
(_check_company_id, 'Account and Period must belong to the same company.', ['company_id']),
(_check_date, 'The date of your Journal Entry is not in the defined period! You should change the date or remove this constraint from the journal.', ['date']),
(_check_currency, 'The selected account of your Journal Entry forces to provide a secondary currency. You should remove the secondary currency on the account or select a multi-currency view on the journal.', ['currency_id']),
(_check_currency_and_amount, "You cannot create journal items with a secondary currency without recording both 'currency' and 'amount currency' field.", ['currency_id','amount_currency']),
(_check_currency_amount, 'The amount expressed in the secondary currency must be positif when journal item are debit and negatif when journal item are credit.', ['amount_currency']),
(_check_currency_company, "You cannot provide a secondary currency if it is the same than the company one." , ['currency_id']),
]
#TODO: ONCHANGE_ACCOUNT_ID: set account_tax_id
@ -645,6 +654,12 @@ class account_move_line(osv.osv):
}
return result
def onchange_account_id(self, cr, uid, ids, account_id, context=None):
res = {'value': {}}
if account_id:
res['value']['account_tax_id'] = [x.id for x in self.pool.get('account.account').browse(cr, uid, account_id, context=context).tax_ids]
return res
def onchange_partner_id(self, cr, uid, ids, move_id, partner_id, account_id=None, debit=0, credit=0, date=False, journal=False):
partner_obj = self.pool.get('res.partner')
payment_term_obj = self.pool.get('account.payment.term')
@ -657,17 +672,24 @@ class account_move_line(osv.osv):
return {'value':val}
if not date:
date = datetime.now().strftime('%Y-%m-%d')
jt = False
if journal:
jt = journal_obj.browse(cr, uid, journal).type
part = partner_obj.browse(cr, uid, partner_id)
if part.property_payment_term:
res = payment_term_obj.compute(cr, uid, part.property_payment_term.id, 100, date)
payment_term_id = False
if jt and jt in ('purchase', 'purchase_refund') and part.property_supplier_payment_term:
payment_term_id = part.property_supplier_payment_term.id
elif jt and part.property_payment_term:
payment_term_id = part.property_payment_term.id
if payment_term_id:
res = payment_term_obj.compute(cr, uid, payment_term_id, 100, date)
if res:
val['date_maturity'] = res[0][0]
if not account_id:
id1 = part.property_account_payable.id
id2 = part.property_account_receivable.id
if journal:
jt = journal_obj.browse(cr, uid, journal).type
if jt:
if jt in ('sale', 'purchase_refund'):
val['account_id'] = fiscal_pos_obj.map_account(cr, uid, part and part.property_account_position or False, id2)
elif jt in ('purchase', 'sale_refund'):
@ -707,7 +729,9 @@ class account_move_line(osv.osv):
context = {}
if context and context.get('next_partner_only', False):
if not context.get('partner_id', False):
partner = self.get_next_partner_only(cr, uid, offset, context)
partner = self.list_partners_to_reconcile(cr, uid, context=context)
if partner:
partner = partner[0]
else:
partner = context.get('partner_id', False)
if not partner:
@ -715,26 +739,26 @@ class account_move_line(osv.osv):
args.append(('partner_id', '=', partner[0]))
return super(account_move_line, self).search(cr, uid, args, offset, limit, order, context, count)
def get_next_partner_only(self, cr, uid, offset=0, context=None):
def list_partners_to_reconcile(self, cr, uid, context=None):
cr.execute(
"""
SELECT p.id
FROM res_partner p
RIGHT JOIN (
SELECT l.partner_id AS partner_id, SUM(l.debit) AS debit, SUM(l.credit) AS credit
SELECT partner_id
FROM (
SELECT l.partner_id, p.last_reconciliation_date, SUM(l.debit) AS debit, SUM(l.credit) AS credit
FROM account_move_line l
LEFT JOIN account_account a ON (a.id = l.account_id)
LEFT JOIN res_partner p ON (l.partner_id = p.id)
RIGHT JOIN account_account a ON (a.id = l.account_id)
RIGHT JOIN res_partner p ON (l.partner_id = p.id)
WHERE a.reconcile IS TRUE
AND l.reconcile_id IS NULL
AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date)
AND l.state <> 'draft'
GROUP BY l.partner_id
) AS s ON (p.id = s.partner_id)
GROUP BY l.partner_id, p.last_reconciliation_date
) AS s
WHERE debit > 0 AND credit > 0
ORDER BY p.last_reconciliation_date LIMIT 1 OFFSET %s""", (offset, )
)
return cr.fetchone()
ORDER BY last_reconciliation_date""")
ids = cr.fetchall()
ids = len(ids) and [x[0] for x in ids] or []
return self.pool.get('res.partner').name_get(cr, uid, ids, context=context)
def reconcile_partial(self, cr, uid, ids, type='auto', context=None, writeoff_acc_id=False, writeoff_period_id=False, writeoff_journal_id=False):
move_rec_obj = self.pool.get('account.move.reconcile')
@ -747,7 +771,7 @@ class account_move_line(osv.osv):
context = {}
for line in self.browse(cr, uid, ids, context=context):
if company_list and not line.company_id.id in company_list:
raise osv.except_osv(_('Warning !'), _('To reconcile the entries company should be the same for all entries'))
raise osv.except_osv(_('Warning!'), _('To reconcile the entries company should be the same for all entries.'))
company_list.append(line.company_id.id)
for line in self.browse(cr, uid, ids, context=context):
@ -756,7 +780,7 @@ class account_move_line(osv.osv):
else:
currency_id = line.company_id.currency_id
if line.reconcile_id:
raise osv.except_osv(_('Warning'), _('Already Reconciled!'))
raise osv.except_osv(_('Warning!'), _('Already reconciled.'))
if line.reconcile_partial_id:
for line2 in line.reconcile_partial_id.line_partial_ids:
if not line2.reconcile_id:
@ -800,11 +824,11 @@ class account_move_line(osv.osv):
company_list = []
for line in self.browse(cr, uid, ids, context=context):
if company_list and not line.company_id.id in company_list:
raise osv.except_osv(_('Warning !'), _('To reconcile the entries company should be the same for all entries'))
raise osv.except_osv(_('Warning!'), _('To reconcile the entries company should be the same for all entries.'))
company_list.append(line.company_id.id)
for line in unrec_lines:
if line.state <> 'valid':
raise osv.except_osv(_('Error'),
raise osv.except_osv(_('Error!'),
_('Entry "%s" is not valid !') % line.name)
credit += line['credit']
debit += line['debit']
@ -826,20 +850,21 @@ class account_move_line(osv.osv):
(tuple(ids), ))
r = cr.fetchall()
#TODO: move this check to a constraint in the account_move_reconcile object
if (len(r) != 1) and not context.get('fy_closing', False):
raise osv.except_osv(_('Error'), _('Entries are not of the same account or already reconciled ! '))
if not unrec_lines:
raise osv.except_osv(_('Error'), _('Entry is already reconciled'))
raise osv.except_osv(_('Error!'), _('Entry is already reconciled.'))
account = account_obj.browse(cr, uid, account_id, context=context)
if not context.get('fy_closing', False) and not account.reconcile:
raise osv.except_osv(_('Error'), _('This account does not allow reconciliation! You should update the account definition to change this.'))
if r[0][1] != None:
raise osv.except_osv(_('Error'), _('Some entries are already reconciled !'))
raise osv.except_osv(_('Error!'), _('Some entries are already reconciled.'))
if (not currency_obj.is_zero(cr, uid, account.company_id.currency_id, writeoff)) or \
if context.get('fy_closing'):
# We don't want to generate any write-off when being called from the
# wizard used to close a fiscal year (and it doesn't give us any
# writeoff_acc_id).
pass
elif (not currency_obj.is_zero(cr, uid, account.company_id.currency_id, writeoff)) or \
(account.currency_id and (not currency_obj.is_zero(cr, uid, account.currency_id, currency))):
if not writeoff_acc_id:
raise osv.except_osv(_('Warning'), _('You have to provide an account for the write off/exchange difference entry !'))
raise osv.except_osv(_('Warning!'), _('You have to provide an account for the write off/exchange difference entry.'))
if writeoff > 0:
debit = writeoff
credit = 0.0
@ -918,8 +943,8 @@ class account_move_line(osv.osv):
if lines and lines[0]:
partner_id = lines[0].partner_id and lines[0].partner_id.id or False
if partner_id and context and context.get('stop_reconcile', False):
partner_obj.write(cr, uid, [partner_id], {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')})
if partner_id and not partner_obj.has_something_to_reconcile(cr, uid, partner_id, context=context):
partner_obj.mark_as_reconciled(cr, uid, [partner_id], context=context)
return r_id
def view_header_get(self, cr, user, view_id, view_type, context=None):
@ -934,6 +959,8 @@ class account_move_line(osv.osv):
return res
if (not context.get('journal_id', False)) or (not context.get('period_id', False)):
return False
if context.get('search_default_journal_id', False):
context['journal_id'] = context.get('search_default_journal_id')
cr.execute('SELECT code FROM account_journal WHERE id = %s', (context['journal_id'], ))
j = cr.fetchone()[0] or ''
cr.execute('SELECT code FROM account_period WHERE id = %s', (context['period_id'], ))
@ -956,7 +983,8 @@ class account_move_line(osv.osv):
if context is None:
context = {}
period_pool = self.pool.get('account.period')
pids = period_pool.search(cr, user, [('date_start','<=',date), ('date_stop','>=',date)])
ctx = dict(context, account_period_prefer_normal=True)
pids = period_pool.find(cr, user, date, context=ctx)
if pids:
res.update({
'period_id':pids[0]
@ -969,129 +997,6 @@ class account_move_line(osv.osv):
'context':context,
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
journal_pool = self.pool.get('account.journal')
if context is None:
context = {}
result = super(account_move_line, self).fields_view_get(cr, uid, view_id, view_type, context=context, toolbar=toolbar, submenu=submenu)
if view_type != 'tree':
#Remove the toolbar from the form view
if view_type == 'form':
if result.get('toolbar', False):
result['toolbar']['action'] = []
#Restrict the list of journal view in search view
if view_type == 'search' and result['fields'].get('journal_id', False):
result['fields']['journal_id']['selection'] = journal_pool.name_search(cr, uid, '', [], context=context)
ctx = context.copy()
#we add the refunds journal in the selection field of journal
if context.get('journal_type', False) == 'sale':
ctx.update({'journal_type': 'sale_refund'})
result['fields']['journal_id']['selection'] += journal_pool.name_search(cr, uid, '', [], context=ctx)
elif context.get('journal_type', False) == 'purchase':
ctx.update({'journal_type': 'purchase_refund'})
result['fields']['journal_id']['selection'] += journal_pool.name_search(cr, uid, '', [], context=ctx)
return result
if context.get('view_mode', False):
return result
fld = []
fields = {}
flds = []
title = _("Accounting Entries") #self.view_header_get(cr, uid, view_id, view_type, context)
ids = journal_pool.search(cr, uid, [])
journals = journal_pool.browse(cr, uid, ids, context=context)
all_journal = [None]
common_fields = {}
total = len(journals)
for journal in journals:
all_journal.append(journal.id)
for field in journal.view_id.columns_id:
if not field.field in fields:
fields[field.field] = [journal.id]
fld.append((field.field, field.sequence))
flds.append(field.field)
common_fields[field.field] = 1
else:
fields.get(field.field).append(journal.id)
common_fields[field.field] = common_fields[field.field] + 1
fld.append(('period_id', 3))
fld.append(('journal_id', 10))
flds.append('period_id')
flds.append('journal_id')
fields['period_id'] = all_journal
fields['journal_id'] = all_journal
fld = sorted(fld, key=itemgetter(1))
widths = {
'statement_id': 50,
'state': 60,
'tax_code_id': 50,
'move_id': 40,
}
document = etree.Element('tree', string=title, editable="top",
refresh="5", on_write="on_create_write",
colors="red:state=='draft';black:state=='valid'")
fields_get = self.fields_get(cr, uid, flds, context)
for field, _seq in fld:
if common_fields.get(field) == total:
fields.get(field).append(None)
# if field=='state':
# state = 'colors="red:state==\'draft\'"'
f = etree.SubElement(document, 'field', name=field)
if field == 'debit':
f.set('sum', _("Total debit"))
elif field == 'credit':
f.set('sum', _("Total credit"))
elif field == 'move_id':
f.set('required', 'False')
elif field == 'account_tax_id':
f.set('domain', "[('parent_id', '=' ,False)]")
f.set('context', "{'journal_id': journal_id}")
elif field == 'account_id' and journal.id:
f.set('domain', "[('journal_id', '=', journal_id),('type','!=','view'), ('type','!=','closed')]")
f.set('on_change', 'onchange_account_id(account_id, partner_id)')
elif field == 'partner_id':
f.set('on_change', 'onchange_partner_id(move_id, partner_id, account_id, debit, credit, date, journal_id)')
elif field == 'journal_id':
f.set('context', "{'journal_id': journal_id}")
elif field == 'statement_id':
f.set('domain', "[('state', '!=', 'confirm'),('journal_id.type', '=', 'bank')]")
elif field == 'date':
f.set('on_change', 'onchange_date(date)')
elif field == 'analytic_account_id':
# Currently it is not working due to being executed by superclass's fields_view_get
# f.set('groups', 'analytic.group_analytic_accounting')
pass
if field in ('amount_currency', 'currency_id'):
f.set('on_change', 'onchange_currency(account_id, amount_currency, currency_id, date, journal_id)')
f.set('attrs', "{'readonly': [('state', '=', 'valid')]}")
if field in widths:
f.set('width', str(widths[field]))
if field in ('journal_id',):
f.set("invisible", "context.get('journal_id', False)")
elif field in ('period_id',):
f.set("invisible", "context.get('period_id', False)")
orm.setup_modifiers(f, fields_get[field], context=context,
in_tree_view=True)
result['arch'] = etree.tostring(document, pretty_print=True)
result['fields'] = fields_get
return result
def _check_moves(self, cr, uid, context=None):
# use the first move ever created for this journal and period
if context is None:
@ -1100,12 +1005,12 @@ class account_move_line(osv.osv):
res = cr.fetchone()
if res:
if res[1] != 'draft':
raise osv.except_osv(_('UserError'),
raise osv.except_osv(_('User Error!'),
_('The account move (%s) for centralisation ' \
'has been confirmed!') % res[2])
'has been confirmed.') % res[2])
return res
def _remove_move_reconcile(self, cr, uid, move_ids=[], context=None):
def _remove_move_reconcile(self, cr, uid, move_ids=None, opening_reconciliation=False, context=None):
# Function remove move rencocile ids related with moves
obj_move_line = self.pool.get('account.move.line')
obj_move_rec = self.pool.get('account.move.reconcile')
@ -1120,6 +1025,8 @@ class account_move_line(osv.osv):
unlink_ids += rec_ids
unlink_ids += part_rec_ids
if unlink_ids:
if opening_reconciliation:
obj_move_rec.write(cr, uid, unlink_ids, {'opening_reconciliation': False})
obj_move_rec.unlink(cr, uid, unlink_ids)
return True
@ -1149,9 +1056,9 @@ class account_move_line(osv.osv):
if isinstance(ids, (int, long)):
ids = [ids]
if vals.get('account_tax_id', False):
raise osv.except_osv(_('Unable to change tax !'), _('You can not change the tax, you should remove and recreate lines !'))
raise osv.except_osv(_('Unable to change tax!'), _('You cannot change the tax, you should remove and recreate lines.'))
if ('account_id' in vals) and not account_obj.read(cr, uid, vals['account_id'], ['active'])['active']:
raise osv.except_osv(_('Bad account!'), _('You can not use an inactive account!'))
raise osv.except_osv(_('Bad Account!'), _('You cannot use an inactive account.'))
if update_check:
if ('account_id' in vals) or ('journal_id' in vals) or ('period_id' in vals) or ('move_id' in vals) or ('debit' in vals) or ('credit' in vals) or ('date' in vals):
self._update_check(cr, uid, ids, context)
@ -1194,12 +1101,12 @@ class account_move_line(osv.osv):
jour_period_obj = self.pool.get('account.journal.period')
cr.execute('SELECT state FROM account_journal_period WHERE journal_id = %s AND period_id = %s', (journal_id, period_id))
result = cr.fetchall()
journal = journal_obj.browse(cr, uid, journal_id, context=context)
period = period_obj.browse(cr, uid, period_id, context=context)
for (state,) in result:
if state == 'done':
raise osv.except_osv(_('Error !'), _('You can not add/modify entries in a closed journal.'))
raise osv.except_osv(_('Error !'), _('You can not add/modify entries in a closed period %s of journal %s.' % (period.name,journal.name)))
if not result:
journal = journal_obj.browse(cr, uid, journal_id, context=context)
period = period_obj.browse(cr, uid, period_id, context=context)
jour_period_obj.create(cr, uid, {
'name': (journal.code or journal.name)+':'+(period.name or ''),
'journal_id': journal.id,
@ -1212,9 +1119,9 @@ class account_move_line(osv.osv):
for line in self.browse(cr, uid, ids, context=context):
err_msg = _('Move name (id): %s (%s)') % (line.move_id.name, str(line.move_id.id))
if line.move_id.state <> 'draft' and (not line.journal_id.entry_posted):
raise osv.except_osv(_('Error !'), _('You can not do this modification on a confirmed entry! You can just change some non legal fields or you must unconfirm the journal entry first! \n%s') % err_msg)
raise osv.except_osv(_('Error!'), _('You cannot do this modification on a confirmed entry. You can just change some non legal fields or you must unconfirm the journal entry first.\n%s.') % err_msg)
if line.reconcile_id:
raise osv.except_osv(_('Error !'), _('You can not do this modification on a reconciled entry! You can just change some non legal fields or you must unreconcile first!\n%s') % err_msg)
raise osv.except_osv(_('Error!'), _('You cannot do this modification on a reconciled entry. You can just change some non legal fields or you must unreconcile first.\n%s.') % err_msg)
t = (line.journal_id.id, line.period_id.id)
if t not in done:
self._update_journal_check(cr, uid, line.journal_id.id, line.period_id.id, context)
@ -1230,30 +1137,35 @@ class account_move_line(osv.osv):
if context is None:
context = {}
if vals.get('move_id', False):
company_id = self.pool.get('account.move').read(cr, uid, vals['move_id'], ['company_id']).get('company_id', False)
if company_id:
vals['company_id'] = company_id[0]
move = self.pool.get('account.move').browse(cr, uid, vals['move_id'], context=context)
if move.company_id:
vals['company_id'] = move.company_id.id
if move.date and not vals.get('date'):
vals['date'] = move.date
if ('account_id' in vals) and not account_obj.read(cr, uid, vals['account_id'], ['active'])['active']:
raise osv.except_osv(_('Bad account!'), _('You can not use an inactive account!'))
if 'journal_id' in vals:
raise osv.except_osv(_('Bad Account!'), _('You cannot use an inactive account.'))
if 'journal_id' in vals and vals['journal_id']:
context['journal_id'] = vals['journal_id']
if 'period_id' in vals:
if 'period_id' in vals and vals['period_id']:
context['period_id'] = vals['period_id']
if ('journal_id' not in context) and ('move_id' in vals) and vals['move_id']:
m = move_obj.browse(cr, uid, vals['move_id'])
context['journal_id'] = m.journal_id.id
context['period_id'] = m.period_id.id
#we need to treat the case where a value is given in the context for period_id as a string
if 'period_id' not in context or not isinstance(context.get('period_id', ''), (int, long)):
if 'period_id' in context and not isinstance(context.get('period_id', ''), (int, long)):
period_candidate_ids = self.pool.get('account.period').name_search(cr, uid, name=context.get('period_id',''))
if len(period_candidate_ids) != 1:
raise osv.except_osv(_('Encoding error'), _('No period found or more than one period found for the given date.'))
raise osv.except_osv(_('Error!'), _('No period found or more than one period found for the given date.'))
context['period_id'] = period_candidate_ids[0][0]
if not context.get('journal_id', False) and context.get('search_default_journal_id', False):
context['journal_id'] = context.get('search_default_journal_id')
context['journal_id'] = context.get('search_default_journal_id')
self._update_journal_check(cr, uid, context['journal_id'], context['period_id'], context)
move_id = vals.get('move_id', False)
journal = journal_obj.browse(cr, uid, context['journal_id'], context=context)
vals['journal_id'] = vals.get('journal_id') or context.get('journal_id')
vals['period_id'] = vals.get('period_id') or context.get('period_id')
vals['date'] = vals.get('date') or context.get('date')
if not move_id:
if journal.centralisation:
#Check for centralisation
@ -1273,7 +1185,7 @@ class account_move_line(osv.osv):
move_id = move_obj.create(cr, uid, v, context)
vals['move_id'] = move_id
else:
raise osv.except_osv(_('No piece number !'), _('Can not create an automatic sequence for this piece!\nPut a sequence in the journal definition for automatic numbering or create a sequence manually for this piece.'))
raise osv.except_osv(_('No piece number !'), _('Cannot create an automatic sequence for this piece.\nPut a sequence in the journal definition for automatic numbering or create a sequence manually for this piece.'))
ok = not (journal.type_control_ids or journal.account_control_ids)
if ('account_id' in vals):
account = account_obj.browse(cr, uid, vals['account_id'], context=context)
@ -1298,7 +1210,7 @@ class account_move_line(osv.osv):
vals['amount_currency'] = cur_obj.compute(cr, uid, account.company_id.currency_id.id,
account.currency_id.id, vals.get('debit', 0.0)-vals.get('credit', 0.0), context=ctx)
if not ok:
raise osv.except_osv(_('Bad account !'), _('You can not use this general account in this journal, check the tab \'Entry Controls\' on the related journal !'))
raise osv.except_osv(_('Bad Account!'), _('You cannot use this general account in this journal, check the tab \'Entry Controls\' on the related journal.'))
if vals.get('analytic_account_id',False):
if journal.analytic_journal_id:
@ -1357,7 +1269,7 @@ class account_move_line(osv.osv):
}
if data['tax_code_id']:
self.create(cr, uid, data, context)
#create the VAT movement
#create the Tax movement
data = {
'move_id': vals['move_id'],
'name': tools.ustr(vals['name'] or '') + ' ' + tools.ustr(tax['name'] or ''),
@ -1381,6 +1293,19 @@ class account_move_line(osv.osv):
move_obj.button_validate(cr,uid, [vals['move_id']], context)
return result
def list_periods(self, cr, uid, context=None):
ids = self.pool.get('account.period').search(cr,uid,[])
return self.pool.get('account.period').name_get(cr, uid, ids, context=context)
def list_journals(self, cr, uid, context=None):
ng = dict(self.pool.get('account.journal').name_search(cr,uid,'',[]))
ids = ng.keys()
result = []
for journal in self.pool.get('account.journal').browse(cr, uid, ids, context=context):
result.append((journal.id,ng[journal.id],journal.type,
bool(journal.currency),bool(journal.analytic_journal_id)))
return result
account_move_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -7,8 +7,8 @@
wiz = wizards.browse(cr, uid, ref('account.account_configuration_installer_todo'))
part = self.pool.get('res.partner').browse(cr, uid, ref('base.main_partner'))
# if we know the country and the wizard has not yet been executed, we do it
if (part.country.id) and (wiz.state=='open'):
mod = 'l10n_'+part.country.code.lower()
if (part.country_id.id) and (wiz.state=='open'):
mod = 'l10n_'+part.country_id.code.lower()
ids = modules.search(cr, uid, [ ('name','=',mod) ], context=context)
if ids:
wizards.write(cr, uid, [ref('account.account_configuration_installer_todo')], {

View File

@ -10,6 +10,7 @@
<report auto="False" id="account_central_journal" model="account.journal.period" name="account.central.journal" rml="account/report/account_central_journal.rml" string="Central Journal" header="False"/>
<report auto="False" id="account_general_journal" model="account.journal.period" name="account.general.journal" rml="account/report/account_general_journal.rml" string="General Journal" header="False"/>
<report auto="False" id="account_journal" model="account.journal.period" name="account.journal.period.print" rml="account/report/account_journal.rml" string="Journal" header="False"/>
<report auto="False" id="account_journal_sale_purchase" model="account.journal.period" name="account.journal.period.print.sale.purchase" rml="account/report/account_journal_sale_purchase.rml" string="Sale/Purchase Journal" header="False"/>
<report auto="False" id="account_overdue" model="res.partner" name="account.overdue" rml="account/report/account_print_overdue.rml" string="Overdue Payments"/>
<report
auto="False"
@ -19,8 +20,9 @@
rml="account/report/account_print_invoice.rml"
string="Invoices"
attachment="(object.state in ('open','paid')) and ('INV'+(object.number or '').replace('/','')+'.pdf')"
attachment_use="True"
usage="default"
multi="True"/>
/>
<report id="account_transfers" model="account.transfer" name="account.transfer" string="Transfers" xml="account/report/transfer.xml" xsl="account/report/transfer.xsl"/>
<report auto="False" id="account_intracom" menu="False" model="account.move.line" name="account.intracom" string="IntraCom"/>
@ -39,13 +41,5 @@
groups="group_account_user,group_account_manager"
parent="account.menu_finance_generic_reporting" sequence="3"/>
<report id="account_account_balance_landscape"
string="Account balance"
model="account.account"
name="account.account.balance.landscape"
rml="account/report/account_balance_landscape.rml"
auto="False"
menu="False"/>
</data>
</openerp>

View File

@ -5,14 +5,12 @@
<record id="test_invoice_1" model="account.invoice">
<field name="currency_id" ref="base.EUR"/>
<field name="company_id" ref="base.main_company"/>
<field name="address_invoice_id" ref="base.res_partner_address_tang"/>
<field name="partner_id" ref="base.res_partner_asus"/>
<field name="partner_id" ref="base.res_partner_1"/>
<field name="journal_id" ref="account.sales_journal"/>
<field name="state">draft</field>
<field name="type">out_invoice</field>
<field name="account_id" ref="account.a_recv"/>
<field name="name">Test invoice 1</field>
<field name="address_contact_id" ref="base.res_partner_address_tang"/>
</record>
<record id="test_tax_line" model="account.invoice.tax">
<field name="name">Test Tax</field>

File diff suppressed because it is too large Load Diff

View File

@ -1,59 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="action_aged_receivable" model="ir.actions.act_window">
<field name="name">Receivable Accounts</field>
<field name="res_model">report.account.receivable</field>
<record id="action_company_analysis_tree" model="ir.actions.act_window">
<field name="name">Company Analysis</field>
<field name="res_model">account.entries.report</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="domain">[('type','=','receivable')]</field>
<field name="view_mode">tree,graph</field>
<field name="context">{'group_by':['user_type'], 'group_by_no_leaf':1}</field>
<field name="view_id" ref="account.view_account_entries_report_tree"/>
<field name="domain">[('year','=',time.strftime('%Y'))]</field>
</record>
<record id="action_aged_income" model="ir.actions.act_window">
<field name="name">Income Accounts</field>
<field name="res_model">report.account.receivable</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="domain">[('type','=','income')]</field>
</record>
<record id="action_company_analysis_tree" model="ir.actions.act_window">
<field name="name">Company Analysis</field>
<field name="res_model">account.entries.report</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="context">{'group_by':['user_type'], 'group_by_no_leaf':1}</field>
<field name="view_id" ref="account.view_account_entries_report_tree"/>
<field name="domain">[('year','=',time.strftime('%Y'))]</field>
</record>
<record id="action_treasory_graph" model="ir.actions.act_window">
<field name="name">Treasury</field>
<field name="res_model">account.account</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="domain">[('type','=','liquidity')]</field>
<field name="context">{'default_type': 'liquidity'}</field>
<field name="view_id" ref="account.view_treasory_graph"/>
</record>
<record id="board_account_form" model="ir.ui.view">
<field name="name">board.account.form</field>
<field name="model">board.board</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Account Board">
<form string="Account Board" version="7.0">
<board style="2-1">
<column>
<action name="%(account.action_invoice_tree1)d" creatable="true" string="Draft Customer Invoices" domain="[('state','in',('draft','proforma2')), ('type','=','out_invoice')]"/>
<action name="%(action_company_analysis_tree)d" string="Company Analysis"/>
</column>
<column>
<action name="%(action_treasory_graph)d" string="Treasury"/> <!--groups="account.group_account_manager,account.group_account_user"-->
</column>
</board>
</form>
</field>
</record>
<record id="open_board_account" model="ir.actions.act_window">
<field name="name">Accounting Dashboard</field>
<field name="name">Accounting</field>
<field name="res_model">board.board</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
@ -61,10 +35,12 @@
<field name="view_id" ref="board_account_form"/>
</record>
<menuitem id="menu_dashboard_acc" name="Dashboard" sequence="2" parent="account.menu_finance_reporting" groups="group_account_user,group_account_manager"/>
<menuitem action="open_board_account" icon="terp-graph" id="menu_board_account" parent="menu_dashboard_acc" sequence="1"/>
<menuitem icon="terp-account" id="account.menu_finance" name="Accounting" sequence="14" action="open_board_account"/>
<menuitem id="menu_board_account"
action="open_board_account"
icon="terp-graph"
parent="base.menu_reporting_dashboard"
groups="group_account_user,group_account_manager"
sequence="45"/>
</data>
</openerp>

View File

@ -19,29 +19,32 @@
#
##############################################################################
from osv import fields, osv
from openerp.osv import fields, osv
class res_company(osv.osv):
_inherit = "res.company"
_columns = {
'expects_chart_of_accounts': fields.boolean('Expects a Chart of Accounts'),
'tax_calculation_rounding_method': fields.selection([
('round_per_line', 'Round per Line'),
('round_globally', 'Round Globally'),
], 'Tax Calculation Rounding Method',
help="If you select 'Round per Line' : for each tax, the tax amount will first be computed and rounded for each PO/SO/invoice line and then these rounded amounts will be summed, leading to the total amount for that tax. If you select 'Round Globally': for each tax, the tax amount will be computed for each PO/SO/invoice line, then these amounts will be summed and eventually this total tax amount will be rounded. If you sell with tax included, you should choose 'Round per line' because you certainly want the sum of your tax-included line subtotals to be equal to the total amount with taxes."),
'paypal_account': fields.char("Paypal Account", size=128, help="Paypal username (usually email) for receiving online payments."),
'overdue_msg': fields.text('Overdue Payments Message', translate=True),
'property_reserve_and_surplus_account': fields.property(
'account.account',
type='many2one',
relation='account.account',
string="Reserve and Profit/Loss Account",
view_load=True,
domain="[('type', '=', 'other')]",
help="This account is used for transferring Profit/Loss (If It is Profit: Amount will be added, Loss : Amount will be deducted.), as calculated in Profit & Loss Report"),
}
_defaults = {
'overdue_msg': '''Our records indicate that the following payments are still due. If the amount
has already been paid, please disregard this notice. However, if you have any
queries regarding your account, please contact us.
Thank you in advance.
'''
'expects_chart_of_accounts': True,
'tax_calculation_rounding_method': 'round_per_line',
'overdue_msg': '''Dear Sir/Madam,
Our records indicate that some payments on your account are still due. Please find details below.
If the amount has already been paid, please disregard this notice. Otherwise, please forward us the total amount stated below.
If you have any queries regarding your account, Please contact us.
Thank you in advance for your cooperation.
Best Regards,'''
}
res_company()

View File

@ -5,7 +5,6 @@
<field name="name">res.company.form.inherit</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="model">res.company</field>
<field name="type">form</field>
<field name="arch" type="xml">
<notebook position="inside">
<page string="Overdue Payments" position="inside">
@ -16,18 +15,5 @@
</field>
</record>
<record model="ir.ui.view" id="view_company_inherit_1_form">
<field name="name">res.company.form.inherit</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="model">res.company</field>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="currency_id" position="after">
<field name="property_reserve_and_surplus_account" colspan="2"/>
<field name="paypal_account" />
</field>
</field>
</record>
</data>
</openerp>

View File

@ -10,17 +10,33 @@
<!--
Payment term
-->
<record id="account_payment_term" model="account.payment.term">
<field name="name">30 Days End of Month</field>
<field name="note">30 Days End of Month</field>
<record id="account_payment_term_immediate" model="account.payment.term">
<field name="name">Immediate Payment</field>
<field name="note">Immediate Payment</field>
</record>
<record id="account_payment_term_line" model="account.payment.term.line">
<field name="name">30 Days End of Month</field>
<record id="account_payment_term_line_immediate" model="account.payment.term.line">
<field name="name">Immediate Payment</field>
<field name="value">balance</field>
<field eval="30" name="days"/>
<field eval="-1" name="days2"/>
<field eval="account_payment_term" name="payment_id"/>
<field eval="0" name="days"/>
<field eval="0" name="days2"/>
<field eval="account_payment_term_immediate" name="payment_id"/>
</record>
<record id="account_payment_term_15days" model="account.payment.term">
<field name="name">15 Days</field>
<field name="note">15 Days</field>
</record>
<record id="account_payment_term_line_15days" model="account.payment.term.line">
<field name="name">15 Days</field>
<field name="value">balance</field>
<field eval="15" name="days"/>
<field eval="0" name="days2"/>
<field eval="account_payment_term_15days" name="payment_id"/>
</record>
<record forcecreate="True" id="decimal_payment" model="decimal.precision">
<field name="name">Payment Term</field>
<field name="digits">6</field>
@ -30,6 +46,7 @@
<field name="name">30 Net Days</field>
<field name="note">30 Net Days</field>
</record>
<record id="account_payment_term_line_net" model="account.payment.term.line">
<field name="name">30 Net Days</field>
<field name="value">balance</field>
@ -37,434 +54,7 @@
<field eval="0" name="days2"/>
<field eval="account_payment_term_net" name="payment_id"/>
</record>
<record id="account_payment_term_advance" model="account.payment.term">
<field name="name">30% Advance End 30 Days</field>
<field name="note">30% Advance End 30 Days</field>
</record>
<record id="account_payment_term_line_advance1" model="account.payment.term.line">
<field name="name">30% Advance</field>
<field name="value">procent</field>
<field eval="3" name="sequence"/>
<field eval="0.300000" name="value_amount"/>
<field eval="0" name="days"/>
<field eval="0" name="days2"/>
<field eval="account_payment_term_advance" name="payment_id"/>
</record>
<record id="account_payment_term_line_advance2" model="account.payment.term.line">
<field name="name">Remaining Balance</field>
<field name="value">balance</field>
<field eval="30" name="days"/>
<field eval="-1" name="days2"/>
<field eval="account_payment_term_advance" name="payment_id"/>
</record>
<!--
Account Journal View
-->
<record id="account_journal_bank_view" model="account.journal.view">
<field name="name">Bank/Cash Journal View</field>
</record>
<record id="bank_col1" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Date</field>
<field name="field">date</field>
<field eval="True" name="required"/>
<field eval="3" name="sequence"/>
</record>
<record id="bank_col2" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Journal Entry</field>
<field name="field">move_id</field>
<field eval="False" name="required"/>
<field eval="1" name="sequence"/>
</record>
<record id="bank_col7" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Name</field>
<field name="field">name</field>
<field eval="7" name="sequence"/>
<field eval="True" name="required"/>
</record>
<record id="bank_col4" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Statement</field>
<field name="field">statement_id</field>
<field eval="4" name="sequence"/>
</record>
<record id="bank_col6" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Partner</field>
<field name="field">partner_id</field>
<field eval="5" name="sequence"/>
</record>
<record id="bank_col5" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Account</field>
<field name="field">account_id</field>
<field eval="True" name="required"/>
<field eval="6" name="sequence"/>
</record>
<record id="bank_col9" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Debit</field>
<field name="field">debit</field>
<field eval="11" name="sequence"/>
</record>
<record id="bank_col10" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Credit</field>
<field name="field">credit</field>
<field eval="12" name="sequence"/>
</record>
<record id="bank_col3" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Ref</field>
<field name="field">ref</field>
<field eval="2" name="sequence"/>
</record>
<record id="bank_col23" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">State</field>
<field name="field">state</field>
<field eval="19" name="sequence"/>
</record>
<record id="bank_col20" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view"/>
<field name="name">Reconcile</field>
<field name="field">reconcile_id</field>
<field eval="20" name="sequence"/>
</record>
<record id="account_journal_bank_view_multi" model="account.journal.view">
<field name="name">Bank/Cash Journal (Multi-Currency) View</field>
</record>
<record id="bank_col1_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Date</field>
<field name="field">date</field>
<field eval="True" name="required"/>
<field eval="3" name="sequence"/>
</record>
<record id="bank_col2_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Journal Entry</field>
<field name="field">move_id</field>
<field eval="False" name="required"/>
<field eval="1" name="sequence"/>
</record>
<record id="bank_col7_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Name</field>
<field name="field">name</field>
<field eval="7" name="sequence"/>
<field eval="True" name="required"/>
</record>
<record id="bank_col4_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Statement</field>
<field name="field">statement_id</field>
<field eval="4" name="sequence"/>
</record>
<record id="bank_col6_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Partner</field>
<field name="field">partner_id</field>
<field eval="5" name="sequence"/>
</record>
<record id="bank_col5_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Account</field>
<field name="field">account_id</field>
<field eval="True" name="required"/>
<field eval="6" name="sequence"/>
</record>
<record id="bank_col17_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Currency Amt.</field>
<field name="field">amount_currency</field>
<field eval="9" name="sequence"/>
</record>
<record id="bank_col18_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Currency</field>
<field name="field">currency_id</field>
<field eval="10" name="sequence"/>
</record>
<record id="bank_col9_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Debit</field>
<field name="field">debit</field>
<field eval="11" name="sequence"/>
</record>
<record id="bank_col10_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Credit</field>
<field name="field">credit</field>
<field eval="12" name="sequence"/>
</record>
<record id="bank_col3_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Ref</field>
<field name="field">ref</field>
<field eval="2" name="sequence"/>
</record>
<record id="bank_col23_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">State</field>
<field name="field">state</field>
<field eval="19" name="sequence"/>
</record>
<record id="bank_col20_multi" model="account.journal.column">
<field name="view_id" ref="account_journal_bank_view_multi"/>
<field name="name">Reconcile</field>
<field name="field">reconcile_id</field>
<field eval="20" name="sequence"/>
</record>
<record id="account_journal_view" model="account.journal.view">
<field name="name">Journal View</field>
</record>
<record id="journal_col1" model="account.journal.column">
<field name="view_id" ref="account_journal_view"/>
<field name="name">Date</field>
<field name="field">date</field>
<field eval="True" name="required"/>
<field eval="3" name="sequence"/>
</record>
<record id="journal_col2" model="account.journal.column">
<field name="view_id" ref="account_journal_view"/>
<field name="name">Journal Entry</field>
<field name="field">move_id</field>
<field eval="False" name="required"/>
<field eval="1" name="sequence"/>
</record>
<record id="journal_col3" model="account.journal.column">
<field name="view_id" ref="account_journal_view"/>
<field name="name">Ref</field>
<field name="field">ref</field>
<field eval="2" name="sequence"/>
</record>
<record id="journal_col5" model="account.journal.column">
<field name="view_id" ref="account_journal_view"/>
<field name="name">Partner</field>
<field name="field">partner_id</field>
<field eval="5" name="sequence"/>
</record>
<record id="journal_col4" model="account.journal.column">
<field name="view_id" ref="account_journal_view"/>
<field name="name">Account</field>
<field name="field">account_id</field>
<field eval="True" name="required"/>
<field eval="6" name="sequence"/>
</record>
<record id="journal_col6" model="account.journal.column">
<field name="view_id" ref="account_journal_view"/>
<field name="name">Name</field>
<field name="field">name</field>
<field eval="7" name="sequence"/>
<field eval="True" name="required"/>
</record>
<record id="journal_col8" model="account.journal.column">
<field name="view_id" ref="account_journal_view"/>
<field name="name">Debit</field>
<field name="field">debit</field>
<field eval="11" name="sequence"/>
</record>
<record id="journal_col9" model="account.journal.column">
<field name="view_id" ref="account_journal_view"/>
<field name="name">Credit</field>
<field name="field">credit</field>
<field eval="12" name="sequence"/>
</record>
<record id="journal_col11" model="account.journal.column">
<field name="view_id" ref="account_journal_view"/>
<field name="name">Analytic Account</field>
<field name="field">analytic_account_id</field>
<field eval="14" name="sequence"/>
</record>
<record id="journal_col24" model="account.journal.column">
<field name="view_id" ref="account_journal_view"/>
<field name="name">State</field>
<field name="field">state</field>
<field eval="19" name="sequence"/>
</record>
<record id="account_sp_journal_view" model="account.journal.view">
<field name="name">Sale/Purchase Journal View</field>
</record>
<record id="sp_journal_col1" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Date</field>
<field name="field">date</field>
<field eval="True" name="required"/>
<field eval="3" name="sequence"/>
</record>
<record id="sp_journal_col2" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Journal Entry</field>
<field name="field">move_id</field>
<field eval="False" name="required"/>
<field eval="1" name="sequence"/>
</record>
<record id="sp_journal_col3" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Ref</field>
<field name="field">ref</field>
<field eval="2" name="sequence"/>
</record>
<record id="sp_journal_col4" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Account</field>
<field name="field">account_id</field>
<field eval="True" name="required"/>
<field eval="6" name="sequence"/>
</record>
<record id="sp_journal_col5" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Partner</field>
<field name="field">partner_id</field>
<field eval="5" name="sequence"/>
</record>
<record id="sp_journal_col6" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Name</field>
<field name="field">name</field>
<field eval="7" name="sequence"/>
<field eval="True" name="required"/>
</record>
<record id="sp_journal_col7" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Due Date</field>
<field name="field">date_maturity</field>
<field eval="8" name="sequence"/>
</record>
<record id="sp_journal_col8" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Debit</field>
<field name="field">debit</field>
<field eval="11" name="sequence"/>
</record>
<record id="sp_journal_col9" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Credit</field>
<field name="field">credit</field>
<field eval="12" name="sequence"/>
</record>
<record id="sp_journal_col10" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Tax</field>
<field name="field">account_tax_id</field>
<field eval="13" name="sequence"/>
</record>
<record id="sp_journal_col11" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Analytic Account</field>
<field name="field">analytic_account_id</field>
<field eval="14" name="sequence"/>
</record>
<record id="sp_journal_col24" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">State</field>
<field name="field">state</field>
<field eval="19" name="sequence"/>
</record>
<record id="sp_journal_col20" model="account.journal.column">
<field name="view_id" ref="account_sp_journal_view"/>
<field name="name">Reconcile</field>
<field name="field">reconcile_id</field>
<field eval="20" name="sequence"/>
</record>
<record id="account_sp_refund_journal_view" model="account.journal.view">
<field name="name">Sale/Purchase Refund Journal View</field>
</record>
<record id="sp_refund_journal_col1" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Date</field>
<field name="field">date</field>
<field eval="True" name="required"/>
<field eval="3" name="sequence"/>
</record>
<record id="sp_refund_journal_col2" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Journal Entry</field>
<field name="field">move_id</field>
<field eval="False" name="required"/>
<field eval="1" name="sequence"/>
</record>
<record id="sp_refund_journal_col3" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Ref</field>
<field name="field">ref</field>
<field eval="2" name="sequence"/>
</record>
<record id="sp_refund_journal_col4" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Account</field>
<field name="field">account_id</field>
<field eval="True" name="required"/>
<field eval="6" name="sequence"/>
</record>
<record id="sp_refund_journal_col5" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Partner</field>
<field name="field">partner_id</field>
<field eval="5" name="sequence"/>
</record>
<record id="sp_refund_journal_col6" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Name</field>
<field name="field">name</field>
<field eval="7" name="sequence"/>
<field eval="True" name="required"/>
</record>
<record id="sp_refund_journal_col7" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Due Date</field>
<field name="field">date_maturity</field>
<field eval="8" name="sequence"/>
</record>
<record id="sp_refund_journal_col8" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Debit</field>
<field name="field">debit</field>
<field eval="11" name="sequence"/>
</record>
<record id="sp_refund_journal_col9" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Credit</field>
<field name="field">credit</field>
<field eval="12" name="sequence"/>
</record>
<record id="sp_refund_journal_col10" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Tax</field>
<field name="field">account_tax_id</field>
<field eval="13" name="sequence"/>
</record>
<record id="sp_refund_journal_col11" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Analytic Account</field>
<field name="field">analytic_account_id</field>
<field eval="14" name="sequence"/>
</record>
<record id="sp_refund_journal_col24" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">State</field>
<field name="field">state</field>
<field eval="19" name="sequence"/>
</record>
<record id="sp_refund_journal_col20" model="account.journal.column">
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="name">Reconcile</field>
<field name="field">reconcile_id</field>
<field eval="20" name="sequence"/>
</record>
<!--
Account Journal Sequences
-->
@ -518,7 +108,6 @@
<!--
Account Statement Sequences
-->
<record id="sequence_reconcile" model="ir.sequence.type">
<field name="name">Account Reconcile</field>
<field name="code">account.reconcile</field>
@ -554,21 +143,6 @@
<field eval="1" name="number_next"/>
<field eval="1" name="number_increment"/>
</record>
<!--
Sequence for analytic account
-->
<record id="seq_type_analytic_account" model="ir.sequence.type">
<field name="name">Analytic account</field>
<field name="code">account.analytic.account</field>
</record>
<record id="seq_analytic_account" model="ir.sequence">
<field name="name">Analytic account sequence</field>
<field name="code">account.analytic.account</field>
<field eval="3" name="padding"/>
<field eval="2708" name="number_next"/>
</record>
<!--
Invoice requests (deprecated)
-->
@ -577,7 +151,16 @@
<field name="object">account.invoice</field>
</record>
<!-- Account-related subtypes for messaging / Chatter -->
<record id="mt_invoice_validated" model="mail.message.subtype">
<field name="name">Validated</field>
<field name="res_model">account.invoice</field>
<field name="description">Invoice validated</field>
</record>
<record id="mt_invoice_paid" model="mail.message.subtype">
<field name="name">Paid</field>
<field name="res_model">account.invoice</field>
<field name="description">Invoice paid</field>
</record>
</data>
</openerp>

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<!-- Types -->
@ -44,7 +45,6 @@
<record id="conf_chart0" model="account.account.template">
<field name="code">0</field>
<field name="name">Configurable Account Chart</field>
<field eval="0" name="parent_id"/>
<field name="type">view</field>
<field name="user_type" ref="data_account_type_view"/>
</record>
@ -381,7 +381,6 @@
<field name="property_account_income_categ" ref="conf_a_sale"/>
<field name="property_account_income_opening" ref="conf_o_income"/>
<field name="property_account_expense_opening" ref="conf_o_expense"/>
<field name="property_reserve_and_surplus_account" ref="conf_a_reserve_and_surplus"/>
<field name="complete_tax_set" eval="False"/>
</record>
@ -548,9 +547,8 @@
</record>
<record id="action_wizard_multi_chart_todo" model="ir.actions.todo">
<field name="name">Generate Chart of Accounts from a Chart Template</field>
<field name="name">Set Your Accounting Options</field>
<field name="action_id" ref="account.action_wizard_multi_chart"/>
<field name="category_id" ref="account.category_accounting_configuration"/>
<field name="type">automatic</field>
</record>

View File

@ -2,7 +2,7 @@
<openerp>
<data noupdate="1">
<record model="account.account.type" id="data_account_type_view">
<field name="name">View</field>
<field name="name">Root/View</field>
<field name="code">view</field>
<field name="close_method">none</field>
</record>
@ -10,21 +10,25 @@
<field name="name">Receivable</field>
<field name="code">receivable</field>
<field name="close_method">unreconciled</field>
<field name="report_type">asset</field>
</record>
<record model="account.account.type" id="data_account_type_payable">
<field name="name">Payable</field>
<field name="code">payable</field>
<field name="close_method">unreconciled</field>
<field name="report_type">liability</field>
</record>
<record model="account.account.type" id="data_account_type_bank">
<field name="name">Bank</field>
<field name="code">bank</field>
<field name="close_method">balance</field>
<field name="report_type">asset</field>
</record>
<record model="account.account.type" id="data_account_type_cash">
<field name="name">Cash</field>
<field name="code">cash</field>
<field name="close_method">balance</field>
<field name="report_type">asset</field>
</record>
<record model="account.account.type" id="data_account_type_asset">
<field name="name">Asset</field>

View File

@ -33,7 +33,8 @@
<field eval="True" name="special"/>
<field name="fiscalyear_id" ref="data_fiscalyear"/>
<field eval="time.strftime('%Y')+'-02-01'" name="date_start"/>
<field eval="time.strftime('%Y')+'-02-28'" name="date_stop"/>
<!-- for the last day of February, we have to compute the day before March 1st -->
<field eval="(DateTime.today().replace(month=3, day=1) - timedelta(days=1)).strftime('%Y-%m-%d')" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_3" model="account.period">
@ -126,9 +127,60 @@
<field eval="time.strftime('%Y')+'-12-31'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<!-- Payment Term -->
<record id="account_payment_term" model="account.payment.term">
<field name="name">30 Days End of Month</field>
<field name="note">30 Days End of Month</field>
</record>
<record id="account_payment_term_line" model="account.payment.term.line">
<field name="name">30 Days End of Month</field>
<field name="value">balance</field>
<field eval="30" name="days"/>
<field eval="-1" name="days2"/>
<field eval="account_payment_term" name="payment_id"/>
</record>
<record id="account_payment_term_advance" model="account.payment.term">
<field name="name">30% Advance End 30 Days</field>
<field name="note">30% Advance End 30 Days</field>
</record>
<record id="account_payment_term_line_advance1" model="account.payment.term.line">
<field name="name">30% Advance</field>
<field name="value">procent</field>
<field eval="3" name="sequence"/>
<field eval="0.300000" name="value_amount"/>
<field eval="0" name="days"/>
<field eval="0" name="days2"/>
<field eval="account_payment_term_advance" name="payment_id"/>
</record>
<record id="account_payment_term_line_advance2" model="account.payment.term.line">
<field name="name">Remaining Balance</field>
<field name="value">balance</field>
<field eval="30" name="days"/>
<field eval="-1" name="days2"/>
<field eval="account_payment_term_advance" name="payment_id"/>
</record>
<record id="base.user_demo" model="res.users">
<field name="groups_id" eval="[(4,ref('account.group_account_user'))]"/>
</record>
<!-- Add payment term on some demo partners -->
<record id="base.res_partner_2" model="res.partner">
<field name="property_payment_term" ref="account_payment_term_net"/>
</record>
<record id="base.res_partner_12" model="res.partner">
<field name="property_payment_term" ref="account_payment_term"/>
<field name="property_supplier_payment_term" ref="account_payment_term"/>
</record>
<record id="base.res_partner_4" model="res.partner">
<field name="property_supplier_payment_term" ref="account_payment_term_net"/>
</record>
<record id="base.res_partner_1" model="res.partner">
<field name="property_supplier_payment_term" ref="account_payment_term"/>
</record>
</data>
</openerp>

View File

@ -1,50 +1,48 @@
<?xml version="1.0" ?>
<openerp>
<data noupdate="1">
<record id="demo_invoice_0" model="account.invoice">
<field name="date_due" eval="time.strftime('%Y')+'-01-30'"/>
<field name="payment_term" ref="account.account_payment_term"/>
<field name="journal_id" ref="account.expenses_journal"/>
<field name="currency_id" ref="base.EUR"/>
<field name="address_invoice_id" ref="base.res_partner_address_wong"/>
<field name="user_id" ref="base.user_demo"/>
<field name="address_contact_id" ref="base.res_partner_address_wong"/>
<field name="reference_type">none</field>
<field name="company_id" ref="base.main_company"/>
<field name="state">draft</field>
<field name="type">in_invoice</field>
<field name="account_id" ref="account.a_pay"/>
<field eval="0" name="reconciled"/>
<field name="date_invoice" eval="time.strftime('%Y')+'-01-01'"/>
<field eval="14.0" name="amount_untaxed"/>
<field eval="14.0" name="amount_total"/>
<field name="partner_id" ref="base.res_partner_maxtor"/>
</record>
<record id="demo_invoice_0_line_rpanrearpanelshe0" model="account.invoice.line">
<field name="invoice_id" ref="demo_invoice_0"/>
<field name="account_id" ref="account.a_expense"/>
<field name="uos_id" ref="product.product_uom_unit"/>
<field name="price_unit" eval="10.0" />
<field name="price_subtotal" eval="10.0" />
<field name="company_id" ref="base.main_company"/>
<field name="invoice_line_tax_id" eval="[(6,0,[])]"/>
<field name="product_id" ref="product.product_product_rearpanelarm0"/>
<field name="quantity" eval="1.0" />
<field name="partner_id" ref="base.res_partner_maxtor"/>
<field name="name">[RPAN100] Rear Panel SHE100</field>
</record>
<record id="demo_invoice_0_line_rckrackcm0" model="account.invoice.line">
<field name="invoice_id" ref="demo_invoice_0"/>
<field name="account_id" ref="account.a_expense"/>
<field name="uos_id" ref="product.product_uom_unit"/>
<field name="price_unit" eval="4.0"/>
<field name="price_subtotal" eval="4.0"/>
<field name="company_id" ref="base.main_company"/>
<field name="invoice_line_tax_id" eval="[(6,0,[])]"/>
<field name="product_id" ref="product.product_product_shelf1"/>
<field name="quantity" eval="1.0" />
<field name="partner_id" ref="base.res_partner_maxtor"/>
<field name="name">[RCK200] Rack 200cm</field>
</record>
</data>
<data noupdate="1">
<record id="demo_invoice_0" model="account.invoice">
<field name="date_due" eval="time.strftime('%Y')+'-01-30'"/>
<field name="payment_term" ref="account.account_payment_term"/>
<field name="journal_id" ref="account.expenses_journal"/>
<field name="currency_id" ref="base.EUR"/>
<field name="user_id" ref="base.user_demo"/>
<field name="reference_type">none</field>
<field name="company_id" ref="base.main_company"/>
<field name="state">draft</field>
<field name="type">in_invoice</field>
<field name="account_id" ref="account.a_pay"/>
<field eval="0" name="reconciled"/>
<field name="date_invoice" eval="time.strftime('%Y')+'-01-01'"/>
<field eval="14.0" name="amount_untaxed"/>
<field eval="14.0" name="amount_total"/>
<field name="partner_id" ref="base.res_partner_17"/>
</record>
<record id="demo_invoice_0_line_rpanrearpanelshe0" model="account.invoice.line">
<field name="invoice_id" ref="demo_invoice_0"/>
<field name="account_id" ref="account.a_expense"/>
<field name="uos_id" ref="product.product_uom_unit"/>
<field name="price_unit" eval="10.0" />
<field name="price_subtotal" eval="10.0" />
<field name="company_id" ref="base.main_company"/>
<field name="invoice_line_tax_id" eval="[(6,0,[])]"/>
<field name="product_id" ref="product.product_product_39"/>
<field name="quantity" eval="1.0" />
<field name="partner_id" ref="base.res_partner_16"/>
<field name="name">Toner Cartridge</field>
</record>
<record id="demo_invoice_0_line_rckrackcm0" model="account.invoice.line">
<field name="invoice_id" ref="demo_invoice_0"/>
<field name="account_id" ref="account.a_expense"/>
<field name="uos_id" ref="product.product_uom_unit"/>
<field name="price_unit" eval="4.0"/>
<field name="price_subtotal" eval="4.0"/>
<field name="company_id" ref="base.main_company"/>
<field name="invoice_line_tax_id" eval="[(6,0,[])]"/>
<field name="product_id" ref="product.product_product_43"/>
<field name="quantity" eval="1.0" />
<field name="partner_id" ref="base.res_partner_17"/>
<field name="name">Zed+ Antivirus</field>
</record>
</data>
</openerp>

View File

@ -19,7 +19,6 @@
<record id="chart0" model="account.account">
<field name="code">X0</field>
<field name="name">Chart For Automated Tests</field>
<field eval="0" name="parent_id"/>
<field name="type">view</field>
<field name="user_type" ref="data_account_type_view"/>
</record>
@ -123,6 +122,14 @@
<field name="type">other</field>
<field name="user_type" ref="data_account_type_income"/>
</record>
<record id="usd_bnk" model="account.account">
<field name="code">X11007</field>
<field name="name">USD Bank Account - (test)</field>
<field ref="cas" name="parent_id"/>
<field name="type">liquidity</field>
<field name="user_type" ref="data_account_type_asset"/>
<field name="currency_id" ref="base.USD"/>
</record>
<record model="account.account" id="liabilities_view">
<field name="name">Liabilities - (test)</field>
@ -297,14 +304,6 @@
<field name="company_id" ref="base.main_company"/>
</record>
<record forcecreate="True" id="property_reserve_and_surplus_account" model="ir.property">
<field name="name">property_account_receivable</field>
<field name="fields_id" search="[('model','=','res.company'),('name','=','property_reserve_and_surplus_account')]"/>
<field eval="'account.account,'+str(rsa)" name="value"/>
<field name="company_id" ref="base.main_company"/>
</record>
<!--
Account Journal
-->
@ -313,7 +312,6 @@
<field name="name">Sales Journal - (test)</field>
<field name="code">TSAJ</field>
<field name="type">sale</field>
<field name="view_id" ref="account_sp_journal_view"/>
<field name="sequence_id" ref="sequence_sale_journal"/>
<field model="account.account" name="default_credit_account_id" ref="a_sale"/>
<field model="account.account" name="default_debit_account_id" ref="a_sale"/>
@ -324,7 +322,6 @@
<field name="name">Sales Credit Note Journal - (test)</field>
<field name="code">TSCNJ</field>
<field name="type">sale_refund</field>
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="sequence_id" ref="sequence_refund_sales_journal"/>
<field model="account.account" name="default_credit_account_id" ref="a_sale"/>
<field model="account.account" name="default_debit_account_id" ref="a_sale"/>
@ -336,7 +333,6 @@
<field name="name">Expenses Journal - (test)</field>
<field name="code">TEXJ</field>
<field name="type">purchase</field>
<field name="view_id" ref="account_sp_journal_view"/>
<field name="sequence_id" ref="sequence_purchase_journal"/>
<field model="account.account" name="default_debit_account_id" ref="a_expense"/>
<field model="account.account" name="default_credit_account_id" ref="a_expense"/>
@ -347,7 +343,6 @@
<field name="name">Expenses Credit Notes Journal - (test)</field>
<field name="code">TECNJ</field>
<field name="type">purchase_refund</field>
<field name="view_id" ref="account_sp_refund_journal_view"/>
<field name="sequence_id" ref="sequence_refund_purchase_journal"/>
<field model="account.account" name="default_debit_account_id" ref="a_expense"/>
<field model="account.account" name="default_credit_account_id" ref="a_expense"/>
@ -359,10 +354,9 @@
<field name="name">Bank Journal - (test)</field>
<field name="code">TBNK</field>
<field name="type">bank</field>
<field name="view_id" ref="account_journal_bank_view"/>
<field name="sequence_id" ref="sequence_bank_journal"/>
<field model="account.account" name="default_debit_account_id" ref="cash"/>
<field model="account.account" name="default_credit_account_id" ref="cash"/>
<field model="account.account" name="default_debit_account_id" ref="bnk"/>
<field model="account.account" name="default_credit_account_id" ref="bnk"/>
<field name="analytic_journal_id" ref="sit"/>
<field name="user_id" ref="base.user_root"/>
</record>
@ -370,7 +364,6 @@
<field name="name">Checks Journal - (test)</field>
<field name="code">TCHK</field>
<field name="type">bank</field>
<field name="view_id" ref="account_journal_bank_view"/>
<field name="sequence_id" ref="sequence_check_journal"/>
<field model="account.account" name="default_debit_account_id" ref="cash"/>
<field model="account.account" name="default_credit_account_id" ref="cash"/>
@ -381,7 +374,16 @@
<field name="name">Cash Journal - (test)</field>
<field name="code">TCSH</field>
<field name="type">cash</field>
<field name="view_id" ref="account_journal_bank_view"/>
<field name="profit_account_id" model="account.account" ref="rsa" />
<field name="loss_account_id" model="account.account" ref="rsa" />
<field name="internal_account_id" model="account.account" ref="rsa" />
<field name="with_last_closing_balance" eval="True" />
<!--
Usually, cash payment methods requires a control at opening and closing.
Bot for demo data, it's better to avoid the control step so that people
that test OpenERP arrive directly in the touchscreen UI.
-->
<field name="cash_control" eval="False"/>
<field name="sequence_id" ref="sequence_cash_journal"/>
<field model="account.account" name="default_debit_account_id" ref="cash"/>
<field model="account.account" name="default_credit_account_id" ref="cash"/>
@ -392,7 +394,6 @@
<field name="name">Miscellaneous Journal - (test)</field>
<field name="code">TMIS</field>
<field name="type">general</field>
<field name="view_id" ref="account_journal_view"/>
<field name="sequence_id" ref="sequence_miscellaneous_journal"/>
<field name="analytic_journal_id" ref="sit"/>
<field name="user_id" ref="base.user_root"/>
@ -401,13 +402,21 @@
<field name="name">Opening Entries Journal - (test)</field>
<field name="code">TOEJ</field>
<field name="type">situation</field>
<field name="view_id" ref="account_journal_view"/>
<field name="sequence_id" ref="sequence_opening_journal"/>
<field model="account.account" name="default_debit_account_id" ref="o_income"/>
<field model="account.account" name="default_credit_account_id" ref="o_expense"/>
<field eval="True" name="centralisation"/>
<field name="user_id" ref="base.user_root"/>
</record>
<record id="bank_journal_usd" model="account.journal">
<field name="name">USD Bank Journal - (test)</field>
<field name="code">TUBK</field>
<field name="type">bank</field>
<field model="account.account" name="default_debit_account_id" ref="usd_bnk"/>
<field model="account.account" name="default_credit_account_id" ref="usd_bnk"/>
<field name="currency" ref="base.USD"/>
</record>
<!--
Product income and expense accounts, default parameters
-->

View File

@ -2,7 +2,7 @@
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
# Copyright (c) 2011-2012 OpenERP S.A. <http://openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@ -18,9 +18,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import osv, fields
from openerp.addons.edi import EDIMixin
from osv import fields, osv, orm
from edi import EDIMixin
from urllib import urlencode
INVOICE_LINE_EDI_STRUCT = {
'name': True,
@ -30,7 +31,6 @@ INVOICE_LINE_EDI_STRUCT = {
'price_unit': True,
'quantity': True,
'discount': True,
'note': True,
# fields used for web preview only - discarded on import
'price_subtotal': True,
@ -75,7 +75,7 @@ class account_invoice(osv.osv, EDIMixin):
"""Exports a supplier or customer invoice"""
edi_struct = dict(edi_struct or INVOICE_EDI_STRUCT)
res_company = self.pool.get('res.company')
res_partner_address = self.pool.get('res.partner.address')
res_partner = self.pool.get('res.partner')
edi_doc_list = []
for invoice in records:
# generate the main report
@ -84,8 +84,7 @@ class account_invoice(osv.osv, EDIMixin):
edi_doc.update({
'company_address': res_company.edi_export_address(cr, uid, invoice.company_id, context=context),
'company_paypal_account': invoice.company_id.paypal_account,
'partner_address': res_partner_address.edi_export(cr, uid, [invoice.address_invoice_id], context=context)[0],
'partner_address': res_partner.edi_export(cr, uid, [invoice.partner_id], context=context)[0],
'currency': self.pool.get('res.currency').edi_export(cr, uid, [invoice.currency_id], context=context)[0],
'partner_ref': invoice.reference or False,
})
@ -102,8 +101,8 @@ class account_invoice(osv.osv, EDIMixin):
return tax_account
def _edi_invoice_account(self, cr, uid, partner_id, invoice_type, context=None):
partner_pool = self.pool.get('res.partner')
partner = partner_pool.browse(cr, uid, partner_id, context=context)
res_partner = self.pool.get('res.partner')
partner = res_partner.browse(cr, uid, partner_id, context=context)
if invoice_type in ('out_invoice', 'out_refund'):
invoice_account = partner.property_account_receivable
else:
@ -125,36 +124,33 @@ class account_invoice(osv.osv, EDIMixin):
# the desired company among the user's allowed companies
self._edi_requires_attributes(('company_id','company_address','type'), edi_document)
res_partner_address = self.pool.get('res.partner.address')
res_partner = self.pool.get('res.partner')
# imported company = new partner
src_company_id, src_company_name = edi_document.pop('company_id')
partner_id = self.edi_import_relation(cr, uid, 'res.partner', src_company_name,
src_company_id, context=context)
invoice_type = edi_document['type']
partner_value = {}
if invoice_type in ('out_invoice', 'out_refund'):
partner_value.update({'customer': True})
if invoice_type in ('in_invoice', 'in_refund'):
partner_value.update({'supplier': True})
res_partner.write(cr, uid, [partner_id], partner_value, context=context)
xid, company_name = edi_document.pop('company_id')
# Retrofit address info into a unified partner info (changed in v7 - used to keep them separate)
company_address_edi = edi_document.pop('company_address')
company_address_edi['name'] = company_name
company_address_edi['is_company'] = True
company_address_edi['__import_model'] = 'res.partner'
company_address_edi['__id'] = xid # override address ID, as of v7 they should be the same anyway
if company_address_edi.get('logo'):
company_address_edi['image'] = company_address_edi.pop('logo')
# imported company_address = new partner address
address_info = edi_document.pop('company_address')
address_info['partner_id'] = (src_company_id, src_company_name)
address_info['type'] = 'invoice'
address_id = res_partner_address.edi_import(cr, uid, address_info, context=context)
invoice_type = edi_document['type']
if invoice_type.startswith('out_'):
company_address_edi['customer'] = True
else:
company_address_edi['supplier'] = True
partner_id = res_partner.edi_import(cr, uid, company_address_edi, context=context)
# modify edi_document to refer to new partner
partner_address = res_partner_address.browse(cr, uid, address_id, context=context)
edi_document['partner_id'] = (src_company_id, src_company_name)
edi_document.pop('partner_address', False) # ignored
edi_document['address_invoice_id'] = self.edi_m2o(cr, uid, partner_address, context=context)
partner = res_partner.browse(cr, uid, partner_id, context=context)
partner_edi_m2o = self.edi_m2o(cr, uid, partner, context=context)
edi_document['partner_id'] = partner_edi_m2o
edi_document.pop('partner_address', None) # ignored, that's supposed to be our own address!
return partner_id
def edi_import(self, cr, uid, edi_document, context=None):
""" During import, invoices will import the company that is provided in the invoice as
a new partner (e.g. supplier company for a customer invoice will be come a supplier
@ -193,7 +189,7 @@ class account_invoice(osv.osv, EDIMixin):
invoice_type = invoice_type.startswith('in_') and invoice_type.replace('in_','out_') or invoice_type.replace('out_','in_')
edi_document['type'] = invoice_type
#import company as a new partner
# import company as a new partner
partner_id = self._edi_import_company(cr, uid, edi_document, context=context)
# Set Account
@ -263,6 +259,28 @@ class account_invoice(osv.osv, EDIMixin):
pass
return action
def _edi_paypal_url(self, cr, uid, ids, field, arg, context=None):
res = dict.fromkeys(ids, False)
for inv in self.browse(cr, uid, ids, context=context):
if inv.type == 'out_invoice' and inv.company_id.paypal_account:
params = {
"cmd": "_xclick",
"business": inv.company_id.paypal_account,
"item_name": inv.company_id.name + " Invoice " + inv.number,
"invoice": inv.number,
"amount": inv.residual,
"currency_code": inv.currency_id.name,
"button_subtype": "services",
"no_note": "1",
"bn": "OpenERP_Invoice_PayNow_" + inv.currency_id.name,
}
res[inv.id] = "https://www.paypal.com/cgi-bin/webscr?" + urlencode(params)
return res
_columns = {
'paypal_url': fields.function(_edi_paypal_url, type='char', string='Paypal Url'),
}
class account_invoice_line(osv.osv, EDIMixin):
_inherit='account.invoice.line'

View File

@ -1,17 +1,6 @@
<?xml version="1.0" ?>
<openerp>
<data>
<!-- EDI Export + Send email Action -->
<record id="ir_actions_server_edi_invoice" model="ir.actions.server">
<field name="code">if (object.type in ('out_invoice', 'out_refund')) and not object.partner_id.opt_out: object.edi_export_and_email(template_ext_id='account.email_template_edi_invoice', context=context)</field>
<field eval="6" name="sequence"/>
<field name="state">code</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="account.model_account_invoice"/>
<field name="condition">True</field>
<field name="name">Auto-email confirmed invoices</field>
</record>
<!-- EDI related Email Templates menu -->
<record model="ir.actions.act_window" id="action_email_templates">
<field name="name">Email Templates</field>
@ -23,32 +12,30 @@
<field name="context">{'search_default_model_id':'account.invoice'}</field>
<field name="context" eval="{'search_default_model_id': ref('account.model_account_invoice')}"/>
</record>
<menuitem id="menu_email_templates" parent="menu_configuration_misc" action="action_email_templates" sequence="30"/>
<menuitem id="menu_email_templates" parent="menu_configuration_misc" action="action_email_templates" sequence="30" groups="base.group_no_one"/>
</data>
<!-- Mail template and workflow bindings are done in a NOUPDATE block
<!-- Mail template are declared in a NOUPDATE block
so users can freely customize/delete them -->
<data noupdate="1">
<!-- bind the mailing server action to invoice open activity -->
<record id="account.act_open" model="workflow.activity">
<field name="action_id" ref="ir_actions_server_edi_invoice"/>
</record>
<!--Email template -->
<record id="email_template_edi_invoice" model="email.template">
<field name="name">Automated Invoice Notification Mail</field>
<field name="email_from">${object.user_id.user_email or object.company_id.email or 'noreply@localhost'}</field>
<field name="subject">${object.company_id.name} Invoice (Ref ${object.number or 'n/a' })</field>
<field name="email_to">${object.address_invoice_id.email or ''}</field>
<field name="name">Invoice - Send by Email</field>
<field name="email_from">${object.user_id.email or object.company_id.email or 'noreply@localhost'}</field>
<field name="subject">${object.company_id.name} Invoice (Ref ${object.number or 'n/a'})</field>
<field name="email_recipients">${object.partner_id.id}</field>
<field name="model_id" ref="account.model_account_invoice"/>
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="account_invoices"/>
<field name="report_name">Invoice_${(object.number or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: rgb(255, 255, 255); ">
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello${object.address_invoice_id.name and ' ' or ''}${object.address_invoice_id.name or ''},</p>
<p>A new invoice is available for ${object.partner_id.name}: </p>
<p>Hello ${object.partner_id.name},</p>
<p>A new invoice is available for you: </p>
<p style="border-left: 1px solid #8e0000; margin-left: 30px;">
&nbsp;&nbsp;<strong>REFERENCES</strong><br />
@ -58,29 +45,15 @@
% if object.origin:
&nbsp;&nbsp;Order reference: ${object.origin}<br />
% endif
&nbsp;&nbsp;Your contact: <a href="mailto:${object.user_id.user_email or ''}?subject=Invoice%20${object.number}">${object.user_id.name}</a>
% if object.user_id:
&nbsp;&nbsp;Your contact: <a href="mailto:${object.user_id.email or ''}?subject=Invoice%20${object.number}">${object.user_id.name}</a>
% endif
</p>
<p>
You can view the invoice document, download it and pay online using the following link:
</p>
<a style="display:block; width: 150px; height:20px; margin-left: 120px; color: #FFF; font-family: 'Lucida Grande', Helvetica, Arial, sans-serif; font-size: 13px; font-weight: bold; text-align: center; text-decoration: none !important; line-height: 1; padding: 5px 0px 0px 0px; background-color: #8E0000; border-radius: 5px 5px; background-repeat: repeat no-repeat;"
href="${ctx.get('edi_web_url_view') or ''}">View Invoice</a>
% if object.company_id.paypal_account and object.type in ('out_invoice', 'in_refund'):
<%
comp_name = quote(object.company_id.name)
inv_number = quote(object.number)
paypal_account = quote(object.company_id.paypal_account)
inv_amount = quote(str(object.amount_total))
cur_name = quote(object.currency_id.name)
paypal_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=%s&amp;item_name=%s%%20Invoice%%20%s&amp;" \
"invoice=%s&amp;amount=%s&amp;currency_code=%s&amp;button_subtype=services&amp;no_note=1&amp;bn=OpenERP_Invoice_PayNow_%s" % \
(paypal_account,comp_name,inv_number,inv_number,inv_amount,cur_name,cur_name)
%>
% if object.paypal_url:
<br/>
<p>It is also possible to directly pay with Paypal:</p>
<a style="margin-left: 120px;" href="${paypal_url}">
<a style="margin-left: 120px;" href="${object.paypal_url}">
<img class="oe_edi_paypal_button" src="https://www.paypal.com/en_US/i/btn/btn_paynowCC_LG.gif"/>
</a>
% endif
@ -91,7 +64,7 @@
<br/>
<br/>
<div style="width: 375px; margin: 0px; padding: 0px; background-color: #8E0000; border-top-left-radius: 5px 5px; border-top-right-radius: 5px 5px; background-repeat: repeat no-repeat;">
<h3 style="margin: 0px; padding: 2px 14px; font-size: 12px; color: #FFF;">
<h3 style="margin: 0px; padding: 2px 14px; font-size: 12px; color: #DDD;">
<strong style="text-transform:uppercase;">${object.company_id.name}</strong></h3>
</div>
<div style="width: 347px; margin: 0px; padding: 5px 14px; line-height: 16px; background-color: #F2F2F2;">
@ -123,64 +96,6 @@
</div>
</div>
]]></field>
<field name="body_text"><![CDATA[
Hello${object.address_invoice_id.name and ' ' or ''}${object.address_invoice_id.name or ''},
A new invoice is available for ${object.partner_id.name}:
| Invoice number: *${object.number}*
| Invoice total: *${object.amount_total} ${object.currency_id.name}*
| Invoice date: ${object.date_invoice}
% if object.origin:
| Order reference: ${object.origin}
% endif
| Your contact: ${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''}
You can view the invoice document, download it and pay online using the following link:
${ctx.get('edi_web_url_view') or 'n/a'}
% if object.company_id.paypal_account and object.type in ('out_invoice', 'in_refund'):
<%
comp_name = quote(object.company_id.name)
inv_number = quote(object.number)
paypal_account = quote(object.company_id.paypal_account)
inv_amount = quote(str(object.amount_total))
cur_name = quote(object.currency_id.name)
paypal_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=%s%%20Invoice%%20%s"\
"&invoice=%s&amount=%s&currency_code=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s" % \
(paypal_account,comp_name,inv_number,inv_number,inv_amount,cur_name,cur_name)
%>
It is also possible to directly pay with Paypal:
${paypal_url}
% endif
If you have any question, do not hesitate to contact us.
Thank you for choosing ${object.company_id.name}!
--
${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''}
${object.company_id.name}
% if object.company_id.street:
${object.company_id.street or ''}
% endif
% if object.company_id.street2:
${object.company_id.street2}
% endif
% if object.company_id.city or object.company_id.zip:
${object.company_id.zip or ''} ${object.company_id.city or ''}
% endif
% if object.company_id.country_id:
${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}
% endif
% if object.company_id.phone:
Phone: ${object.company_id.phone}
% endif
% if object.company_id.website:
${object.company_id.website or ''}
% endif
]]></field>
</record>
</data>
</openerp>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

11130
addons/account/i18n/es_CR.po Normal file

File diff suppressed because it is too large Load Diff

10826
addons/account/i18n/es_DO.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

10846
addons/account/i18n/es_UY.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

10916
addons/account/i18n/ja.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More