Statement module: initial commit
This commit is contained in:
+29
@@ -0,0 +1,29 @@
|
||||
# Copyright (c) 2004-2006 Tiny SPRL. (http://tiny.be)
|
||||
# Copyright (c) 2007-2008 Cedric Krier.
|
||||
# Copyright (c) 2007-2008 Bertrand Chenal.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contact a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from journal import *
|
||||
from statement import *
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
'name': 'Bank Statement',
|
||||
'version': '0.1',
|
||||
'author': 'B2CK',
|
||||
'email': 'info@b2ck.com',
|
||||
'website': 'http://www.tryton.org/',
|
||||
'category': 'Accounting',
|
||||
'description': 'Bank Statement Module',
|
||||
'depends': [
|
||||
'account',
|
||||
'company',
|
||||
'currency',
|
||||
'relationship',
|
||||
'company',
|
||||
],
|
||||
'xml': [
|
||||
'statement.xml',
|
||||
'journal.xml',
|
||||
],
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
"Statement Journal"
|
||||
|
||||
from trytond.osv import fields, OSV
|
||||
from trytond.wizard import Wizard, WizardOSV
|
||||
from decimal import Decimal
|
||||
import datetime
|
||||
|
||||
class Journal(OSV):
|
||||
'Statement Journal'
|
||||
_name = 'statement.journal'
|
||||
_description = __doc__
|
||||
|
||||
name = fields.Char('Name', size=None, required=True,)
|
||||
journal = fields.Many2One(
|
||||
'account.journal', 'Bank Journal', required=True,
|
||||
domain="[('type','=','bank')]")
|
||||
balance = fields.Numeric('Balance', digits=(12, 6),)
|
||||
currency = fields.Many2One('currency.currency', 'Currency', required=True)
|
||||
company = fields.Many2One('company.company', 'Company', required=True)
|
||||
|
||||
def default_currency(self, cursor, user, context=None):
|
||||
if context and context.get('company'):
|
||||
company_obj = self.pool.get('company.company')
|
||||
currency_obj = self.pool.get('currency.currency')
|
||||
company = company_obj.browse(cursor, user, context['company'],
|
||||
context=context)
|
||||
return currency_obj.name_get(cursor, user, company.currency.id,
|
||||
context=context)[0]
|
||||
return False
|
||||
|
||||
def default_company(self, cursor, user, context=None):
|
||||
company_obj = self.pool.get('company.company')
|
||||
if context and context.get('company'):
|
||||
return company_obj.name_get(cursor, user, context['company'],
|
||||
context=context)[0]
|
||||
return False
|
||||
|
||||
Journal()
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0"?>
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="statement_journal_view_form">
|
||||
<field name="model">statement.journal</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Statement Journal">
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="journal"/>
|
||||
<field name="journal"/>
|
||||
<label name="balance"/>
|
||||
<field name="balance"/>
|
||||
<label name="currency"/>
|
||||
<field name="currency"/>
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="statement_journal_view_tree">
|
||||
<field name="model">statement.journal</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Statement Journals">
|
||||
<field name="name"/>
|
||||
<field name="journal"/>
|
||||
<field name="balance"/>
|
||||
<field name="currency"/>
|
||||
<field name="company"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="account.journal.type" id="journal_type_bank">
|
||||
<field name="name">Bank</field>
|
||||
<field name="code">bank</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
"Statement"
|
||||
|
||||
from trytond.osv import fields, OSV, ExceptORM
|
||||
from trytond.wizard import Wizard, WizardOSV
|
||||
from decimal import Decimal
|
||||
import datetime
|
||||
|
||||
_STATES = {'readonly': 'state != "draft"'}
|
||||
|
||||
class Statement(OSV):
|
||||
'Bank Statement'
|
||||
_name = 'statement.statement'
|
||||
_description = __doc__
|
||||
|
||||
journal = fields.Many2One(
|
||||
'statement.journal', 'Journal', required=True, states=_STATES,
|
||||
on_change=['journal'])
|
||||
date = fields.Date('date', required=True, states=_STATES, select=True)
|
||||
start_balance = fields.Numeric('Start Balance', digits=(16, 2),)
|
||||
end_balance = fields.Function(
|
||||
'get_end_balance', string='End Balance', type='numeric',)
|
||||
company = fields.Many2One(
|
||||
'company.company', 'Company', required=True, select=True)
|
||||
currency = fields.Many2One('currency.currency', 'Currency', required=True)
|
||||
lines = fields.One2Many(
|
||||
'statement.statement.line', 'statement', 'Transactions',
|
||||
states=_STATES,)
|
||||
move = fields.Many2One(
|
||||
'account.move', 'Move', readonly=True,)
|
||||
state = fields.Selection(
|
||||
[('draft', 'Draft'), ('waiting','Waiting'), ('done', 'Done'),],'State',
|
||||
readonly=True, select=True)
|
||||
|
||||
def __init__(self):
|
||||
super(Statement, self).__init__()
|
||||
self._constraints += [
|
||||
('check_unique_waiting_statement',
|
||||
'Error: You can only have one waiting statement '\
|
||||
'for the same journal.',
|
||||
['journal']),
|
||||
]
|
||||
|
||||
def check_unique_waiting_statement(self, cursor, user, ids, parent=None):
|
||||
cursor.execute('SELECT max(nb_waiting) AS max_nb_waiting '\
|
||||
'FROM (SELECT count(\'\') AS nb_waiting '\
|
||||
'FROM statement_statement WHERE state = \'waiting\' '\
|
||||
'GROUP BY company, journal) AS sub_query')
|
||||
if cursor.rowcount and cursor.fetchone()[0] > 1:
|
||||
return False
|
||||
return True
|
||||
|
||||
def default_state(self, cursor, user, context=None):
|
||||
return 'draft'
|
||||
|
||||
def on_change_journal(self, cursor, user, ids, value, context=None):
|
||||
if not value.get('journal'):
|
||||
return {}
|
||||
journal_obj = self.pool.get('statement.journal')
|
||||
currency_obj = self.pool.get('currency.currency')
|
||||
company_obj = self.pool.get('company.company')
|
||||
journal= journal_obj.browse(cursor, user, value['journal'],
|
||||
context=context)
|
||||
return {'currency': currency_obj.name_get(
|
||||
cursor, user, journal.currency.id, context=context)[0],
|
||||
'company': company_obj.name_get(
|
||||
cursor, user, journal.company.id, context=context)[0],
|
||||
'start_balance': journal.balance}
|
||||
|
||||
def get_end_balance(self, cursor, user, ids, name, arg, context=None):
|
||||
statements = self.browse(cursor, user, ids, context=context)
|
||||
res = {}
|
||||
for statement in statements:
|
||||
res[statement.id] = statement.start_balance
|
||||
for line in statement.lines:
|
||||
res[statement.id] += line.amount
|
||||
return res
|
||||
|
||||
def set_state_waiting(self, cursor, user, statement_id, context=None):
|
||||
move_obj = self.pool.get('account.move')
|
||||
move_line_obj = self.pool.get('account.move.line')
|
||||
period_obj = self.pool.get('account.period')
|
||||
statement = self.browse(cursor, user, statement_id, context=context)
|
||||
|
||||
period = period_obj.find(cursor, user, date=statement.date,
|
||||
context=context)
|
||||
move_id = move_obj.create(
|
||||
cursor, user,
|
||||
{'name': statement.date, #XXX
|
||||
'period': period,
|
||||
'journal': statement.journal.journal.id,
|
||||
'date': statement.date,
|
||||
},
|
||||
context=context)
|
||||
|
||||
for line in statement.lines:
|
||||
move_line_obj.create(
|
||||
cursor, user,
|
||||
{'name': '?',
|
||||
'debit': line.amount>=0 and line.amount,
|
||||
'credit': line.amount<0 and -line.amount,
|
||||
'account': line.account.id,
|
||||
'move': move_id,
|
||||
'party': line.party and line.party.id,
|
||||
}, # second currency?
|
||||
context=context)
|
||||
|
||||
journal = line.statement.journal.journal
|
||||
if line.amount < 0:
|
||||
account = journal.credit_account
|
||||
else:
|
||||
account = journal.debit_account
|
||||
if not account:
|
||||
raise ExceptORM('Error:', 'Please provide debit and '\
|
||||
'credit account on bank journal.')
|
||||
|
||||
move_line_obj.create(
|
||||
cursor, user,
|
||||
{'name': '?',
|
||||
'debit': line.amount < 0 and -line.amount or 0.0,
|
||||
'credit': line.amount >= 0 and line.amount or 0.0,
|
||||
'account': account.id,
|
||||
'move': move_id,
|
||||
'party': line.party and line.party.id,
|
||||
}, # second currency?
|
||||
context=context)
|
||||
|
||||
self.write(cursor, user, statement_id,
|
||||
{'state':'waiting',
|
||||
'start_balance': statement.journal.balance,
|
||||
'move': move_id,},
|
||||
context=context)
|
||||
|
||||
def set_state_done(self, cursor, user, statement_id, context=None):
|
||||
move_obj = self.pool.get('account.move')
|
||||
statement = self.browse(cursor, user, statement_id, context=context)
|
||||
move_obj.write(
|
||||
cursor, user, statement.move.id, {'state': 'posted'},
|
||||
context=context)
|
||||
self.write(
|
||||
cursor, user, statement_id, {'state':'done'}, context=context)
|
||||
|
||||
Statement()
|
||||
|
||||
class Line(OSV):
|
||||
'Bank Statement Line'
|
||||
_name = 'statement.statement.line'
|
||||
_description = __doc__
|
||||
|
||||
statement = fields.Many2One(
|
||||
'statement.statement','Statement', required=True)
|
||||
date = fields.Date('Date', required=True)
|
||||
amount = fields.Numeric(
|
||||
'Amount', digits=(16,2), required=True, on_change=['amount','party'])
|
||||
party = fields.Many2One(
|
||||
'relationship.party', 'Party', on_change=['amount','party'])
|
||||
account = fields.Many2One(
|
||||
'account.account', 'Account', required=True,)
|
||||
description = fields.Char('Description', size=None)
|
||||
|
||||
def on_change_party(self, cursor, user, ids, value, context=None):
|
||||
if not (value.get('party') and value.get('amount')):
|
||||
return {}
|
||||
party_obj = self.pool.get('relationship.party')
|
||||
account_obj = self.pool.get('account.account')
|
||||
party = party_obj.browse(cursor, user, value['party'], context=context)
|
||||
if value['amount'] > 0:
|
||||
account = party.account_receivable
|
||||
else:
|
||||
account = party.account_payable
|
||||
return {'account': account_obj.name_get(
|
||||
cursor, user, account.id, context=context)[0]}
|
||||
|
||||
def on_change_amount(self, cursor, user, ids, value, context=None):
|
||||
return self.on_change_party(cursor, user, ids, value, context=context)
|
||||
Line()
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0"?>
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="statement_view_form">
|
||||
<field name="model">statement.statement</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Bank Statement">
|
||||
<label name="journal"/>
|
||||
<field name="journal"/>
|
||||
<label name="date"/>
|
||||
<field name="date"/>
|
||||
<label name="start_balance"/>
|
||||
<field name="start_balance"/>
|
||||
<label name="end_balance"/>
|
||||
<field name="end_balance"/>
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
<label name="currency"/>
|
||||
<field name="currency"/>
|
||||
<label name="move"/>
|
||||
<field name="move"/>
|
||||
<field name="lines" colspan="4">
|
||||
<tree string="Bank Statement Lines" editable="bottom">
|
||||
<field name="date"/>
|
||||
<field name="amount"/>
|
||||
<field name="party"/>
|
||||
<field name="account"/>
|
||||
<field name="description"/>
|
||||
</tree>
|
||||
</field>
|
||||
<group col="5" colspan="4">
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
<button string="Set Waiting" name="waiting"
|
||||
states="{'invisible': '''state != 'draft' '''}"/>
|
||||
<button string="Set Done" name="done"
|
||||
states="{'invisible': '''state != 'waiting' '''}"/>
|
||||
</group>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="statement_view_tree">
|
||||
<field name="model">statement.statement</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Bank Statements">
|
||||
<field name="journal"/>
|
||||
<field name="date"/>
|
||||
<field name="start_balance"/>
|
||||
<field name="end_balance"/>
|
||||
<field name="company"/>
|
||||
<field name="currency"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_statement_form">
|
||||
<field name="name">Bank Statement</field>
|
||||
<field name="res_model">statement.statement</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_statement_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="statement_view_tree"/>
|
||||
<field name="act_window" ref="act_statement_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_statement_form_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="statement_view_form"/>
|
||||
<field name="act_window" ref="act_statement_form"/>
|
||||
</record>
|
||||
<menuitem parent="account.menu_entries"
|
||||
action="act_statement_form" id="menu_statement_form"/>
|
||||
|
||||
<record model="ir.ui.view" id="statement_line_view_form">
|
||||
<field name="model">statement.statement.line</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Bank Statement Line">
|
||||
<label name="date"/>
|
||||
<field name="date"/>
|
||||
<label name="amount"/>
|
||||
<field name="amount"/>
|
||||
<label name="party"/>
|
||||
<field name="party"/>
|
||||
<label name="account"/>
|
||||
<field name="account"/>
|
||||
<label name="description"/>
|
||||
<field name="description"/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="statement_line_view_tree">
|
||||
<field name="model">statement.statement.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Bank Statement Lines">
|
||||
<field name="date"/>
|
||||
<field name="amount"/>
|
||||
<field name="party"/>
|
||||
<field name="account"/>
|
||||
<field name="description"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Statement workflow -->
|
||||
<record model="workflow" id="wkf_statement">
|
||||
<field name="name">Statement</field>
|
||||
<field name="osv">statement.statement</field>
|
||||
<field name="on_create">True</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="statement_act_draft">
|
||||
<field name="workflow" ref="wkf_statement"/>
|
||||
<field name="flow_start">True</field>
|
||||
<field name="name">Draft</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="statement_act_waiting">
|
||||
<field name="workflow" ref="wkf_statement"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">set_state_waiting()</field>
|
||||
<field name="name">Waiting</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="statement_act_done">
|
||||
<field name="workflow" ref="wkf_statement"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">set_state_done()</field>
|
||||
<field name="name">Done</field>
|
||||
<field name="flow_stop" eval="True"/>
|
||||
</record>
|
||||
<record model="workflow.transition" id="statement_trans_draft_waiting">
|
||||
<field name="act_from" ref="statement_act_draft"/>
|
||||
<field name="act_to" ref="statement_act_waiting"/>
|
||||
<field name="signal">waiting</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="statement_trans_waiting_done">
|
||||
<field name="act_from" ref="statement_act_waiting"/>
|
||||
<field name="act_to" ref="statement_act_done"/>
|
||||
<field name="signal">done</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
Reference in New Issue
Block a user