bzr revid: fp@tinyerp.com-20100825181010-2f9j481tx4bay0kk
This commit is contained in:
Fabien Pinckaers 2010-08-25 20:10:10 +02:00
commit e93799e69f
22 changed files with 341 additions and 156 deletions

View File

@ -401,9 +401,6 @@ class account_account(osv.osv):
'manage this. So if you import from another software system you may have to use the rate at date. ' \
'Incoming transactions always use the rate at date.', \
required=True),
'check_history': fields.boolean('Display History',
help="Check this box if you want to print all entries when printing the General Ledger, "\
"otherwise it will only print its balance."),
'level': fields.function(_get_level, string='Level', method=True, store=True, type='integer'),
}
@ -411,7 +408,6 @@ class account_account(osv.osv):
'type': lambda *a : 'view',
'reconcile': lambda *a: False,
'active': lambda *a: True,
'check_history': lambda *a: True,
'currency_mode': lambda *a: 'current',
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<assert model="account.move" search="[]" string="For all Ledger Postings, the state is valid implies that the sum of credits equals the sum of debits">
<assert model="account.move" search="[]" string="For all Journal Items, the state is valid implies that the sum of credits equals the sum of debits">
<test expr="not len(line_id) or line_id[0].state != 'valid' or (sum([l.debit - l.credit for l in line_id]) &lt;= 0.00001)"/>
</assert>
</data>

View File

@ -338,7 +338,7 @@ class account_bank_statement(osv.osv):
context=context):
if line.state <> 'valid':
raise osv.except_osv(_('Error !'),
_('Ledger Posting line "%s" is not valid') % line.name)
_('Journal Item "%s" is not valid') % line.name)
if move.reconcile_id and move.reconcile_id.line_ids:
## Search if move has already a partial reconciliation
@ -687,4 +687,4 @@ class account_bank_statement_line(osv.osv):
account_bank_statement_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -482,7 +482,7 @@ class account_cash_statement(osv.osv):
context=context):
if line.state <> 'valid':
raise osv.except_osv(_('Error !'),
_('Ledger Posting line "%s" is not valid') % line.name)
_('Journal Item "%s" is not valid') % line.name)
if move.reconcile_id and move.reconcile_id.line_ids:
torec += map(lambda x: x.id, move.reconcile_id.line_ids)

View File

@ -302,13 +302,14 @@
<field name="state"/>
<field name="residual"/>
<group col="7" colspan="4" groups="base.group_user">
<button name="invoice_proforma2" states="draft" string="PRO-FORMA" icon="terp-check" groups="account.group_account_user"/>
<button name="invoice_open" states="draft,proforma2" string="Create" icon="terp-document-new"/>
<button name="invoice_cancel" states="draft,proforma2,sale,open" string="Cancel" icon="gtk-cancel"/>
<button name="action_cancel_draft" states="cancel" string="Reset to Draft" type="object" icon="terp-stock_effects-object-colorize"/>
<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="Create" icon="terp-camera_test"/>
<button name="%(action_account_invoice_refund)d" type='action' string='Refund' states='open,paid' icon="gtk-execute"/>
<button name="%(action_account_invoice_pay)d" type='action' string='Pay Invoice' states='open' icon="terp-dolar_ok!"/>
<button name='%(action_account_state_open)d' type='action' string='Re-Open' states='paid' icon="gtk-convert" groups="base.group_no_one"/>
<button name="invoice_cancel" states="draft,proforma2,sale,open" string="Cancel" icon="gtk-cancel"/>
<button name="action_cancel_draft" states="cancel" string="Set to Draft" type="object" icon="terp-stock_effects-object-colorize"/>
</group>
</group>
</page>
@ -354,15 +355,15 @@
<search string="Search Invoice">
<group col="10" colspan="4">
<filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Invoices"/>
<filter icon="terp-check" string="Proforma" domain="[('state','=','proforma2')]" help="Proforma Invoices"/>
<filter icon="terp-check" string="Invoices" domain="[('state','not in',['draft','cancel'])]" help="Invoices"/>
<filter icon="terp-gtk-media-pause" string="Proforma" domain="[('state','=','proforma2')]" help="Proforma Invoices"/>
<filter icon="terp-camera_test" string="Invoices" domain="[('state','not in',['draft','cancel'])]" help="Invoices"/>
<separator orientation="vertical"/>
<filter icon="terp-dolar_ok!" string="Unpaid" domain="[('state','=','open')]" help="Unpaid Invoices"/>
<separator orientation="vertical"/>
<field name="number"/>
<field name="partner_id"/>
<field name="user_id" select="1" default="uid" widget="selection" string="Responsible">
<filter domain="[('user_id','=',uid)]" help="Responsible" icon="terp-partner" separator="1"/>
<field name="user_id" select="1" default="uid" widget="selection" string="Salesman">
<filter domain="[('user_id','=',uid)]" help="My invoices" icon="terp-personal" separator="1"/>
</field>
<field name="origin"/>
<field name="amount_total"/>
@ -370,14 +371,14 @@
<newline/>
<group col="10" colspan="4">
<field name="journal_id" widget="selection" select='1'/>
<field name="period_id" select='1'/>
<field name="period_id" select='1' string="Period"/>
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="Journal" icon="terp-folder-orange" domain="[]" context="{'group_by':'journal_id'}"/>
<filter string="Period" icon="terp-go-month" domain="[]" context="{'group_by':'period_id'}"/>
<separator orientation="vertical"/>
<filter string="Partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>

View File

@ -105,14 +105,6 @@ write({'state':'cancel'})</field>
<field name="signal">invoice_open</field>
</record>
<record id="pro2_to_paid" model="workflow.transition">
<field name="act_from" ref="act_proforma2"/>
<field name="act_to" ref="account.act_paid"/>
<field name="trigger_model">account.move.line</field>
<field name="trigger_expr_id">move_line_id_payment_get()</field>
<field name="condition">test_paid()</field>
</record>
<record id="pro2_to_cancel" model="workflow.transition">
<field name="act_from" ref="act_proforma2"/>
<field name="act_to" ref="account.act_cancel"/>

View File

@ -426,7 +426,7 @@ class account_move_line(osv.osv):
'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),
'narration': fields.related('move_id','narration', type='text', relation='account.move', string='Narration'),
'ref': fields.char('Ref.', size=64),
'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),
@ -435,10 +435,10 @@ class account_move_line(osv.osv):
'period_id': fields.many2one('account.period', 'Period', required=True, select=2),
'journal_id': fields.many2one('account.journal', 'Journal', required=True, select=1),
'blocked': fields.boolean('Litigation', help="You can check this box to mark the entry line as a litigation with the associated partner"),
'blocked': fields.boolean('Litigation', 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'),
'date_maturity': fields.date('Maturity date', help="This field is used for payable and receivable entries. You can put the limit date for the payment of this entry line."),
'date_maturity': fields.date('Maturity date', 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,
store={
'account.move': (_get_move_lines, ['date'], 20)
@ -864,7 +864,7 @@ class account_move_line(osv.osv):
fields = {}
flds = []
title = "Accounting Entries" #self.view_header_get(cr, uid, view_id, view_type, context)
xml = '''<?xml version="1.0"?>\n<tree string="%s" editable="top" refresh="5" on_write="on_create_write">\n\t''' % (title)
xml = '''<?xml version="1.0"?>\n<tree string="%s" editable="top" refresh="5" on_write="on_create_write" colors="red:state==\'draft\';black:state==\'valid\'">\n\t''' % (title)
ids = journal_pool.search(cr, uid, [])
journals = journal_pool.browse(cr, uid, ids)
@ -907,8 +907,8 @@ class account_move_line(osv.osv):
if common_fields.get(field) == total:
fields.get(field).append(None)
if field=='state':
state = 'colors="red:state==\'draft\'"'
# if field=='state':
# state = 'colors="red:state==\'draft\'"'
attrs = []
if field == 'debit':
@ -996,7 +996,7 @@ class account_move_line(osv.osv):
if journal.allow_date and period_id:
period = self.pool.get('account.period').browse(cr, uid, [period_id])[0]
if not time.strptime(vals['date'][:10],'%Y-%m-%d')>=time.strptime(period.date_start,'%Y-%m-%d') or not time.strptime(vals['date'][:10],'%Y-%m-%d')<=time.strptime(period.date_stop,'%Y-%m-%d'):
raise osv.except_osv(_('Error'),_('The date of your Ledger Posting is not in the defined period !'))
raise osv.except_osv(_('Error'),_('The date of your Journal Entry is not in the defined period!'))
else:
return True

View File

@ -874,7 +874,7 @@
<field name="type">tree</field>
<field eval="4" name="priority"/>
<field name="arch" type="xml">
<tree colors="blue:state in ('draft');black:state in ('valid')" string="Account Entry Line" editable="top" on_write="on_create_write">
<tree colors="red:state in ('draft');black:state in ('valid')" string="Account Entry Line" editable="top" on_write="on_create_write">
<field name="date"/>
<field name="period_id"/>
<field name="move_id"/>
@ -926,7 +926,7 @@
<group col="2" colspan="2">
<separator colspan="2" string="Accounting Documents"/>
<field name="invoice" readonly="True"/>
<field name="move_id" readonly="True"/>
<field name="move_id" required="False"/>
<field name="statement_id" readonly="True"/>
</group>
@ -1059,7 +1059,7 @@
<field name="date" select='1'/>
<field name="account_id" select='1'/>
<field name="partner_id" select='1'>
<filter help="Next Partner Entries to reconcile" name="next_partner" string="Next Partner to reconcile" context="{'next_partner_only': 1}" icon="terp-partner" domain="[('account_id.reconcile','=',True),('reconcile_id','=',False)]"/>
<filter help="Next Partner Entries to reconcile" name="next_partner" string="Next Partner to reconcile" context="{'next_partner_only': 1}" icon="terp-gtk-jump-to-ltr" domain="[('account_id.reconcile','=',True),('reconcile_id','=',False)]"/>
</field>
</group>
<newline/>
@ -1775,7 +1775,7 @@
<field name="type">tree</field>
<field eval="4" name="priority"/>
<field name="arch" type="xml">
<tree colors="blue:state in ('draft');black:state in ('valid')" string="Account Entry Line">
<tree colors="red:state in ('draft');black:state in ('valid')" string="Account Entry Line">
<field name="date"/>
<field name="move_id"/>
<field name="statement_id" string="St."/>

View File

@ -268,7 +268,7 @@ class account_invoice(osv.osv):
'invoice_line': fields.one2many('account.invoice.line', 'invoice_id', 'Invoice Lines', readonly=True, states={'draft':[('readonly',False)]}),
'tax_line': fields.one2many('account.invoice.tax', 'invoice_id', 'Tax Lines', readonly=True, states={'draft':[('readonly',False)]}),
'move_id': fields.many2one('account.move', 'Invoice Movement', readonly=True, help="Links to the automatically generated Ledger Postings."),
'move_id': fields.many2one('account.move', 'Journal Entry', readonly=True, help="Link to the automatically generated Journal Items."),
'amount_untaxed': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Account'), string='Untaxed',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 20),
@ -299,7 +299,7 @@ class account_invoice(osv.osv):
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, None, 50), # Check if we can remove ?
'account.move.line': (_get_invoice_from_line, None, 50),
'account.move.reconcile': (_get_invoice_from_reconcile, None, 50),
}, help="The Ledger Postings of the invoice have been reconciled with Ledger Postings of the payment(s)."),
}, help="The Journal Entry of the invoice have been totally reconciled with one or several Journal Entries of payment."),
'partner_bank_id': fields.many2one('res.partner.bank', 'Bank Account',
help='Bank Account Number, Company bank account if Invoice is customer or supplier refund, otherwise Partner bank account number.', readonly=True, states={'draft':[('readonly',False)]}),
'move_lines':fields.function(_get_lines , method=True, type='many2many', relation='account.move.line', string='Entry Lines'),
@ -313,7 +313,7 @@ class account_invoice(osv.osv):
},
help="Remaining amount due."),
'payment_ids': fields.function(_compute_lines, method=True, relation='account.move.line', type="many2many", string='Payments'),
'move_name': fields.char('Ledger Posting', size=64, readonly=True, states={'draft':[('readonly',False)]}),
'move_name': fields.char('Journal Entry', size=64, readonly=True, states={'draft':[('readonly',False)]}),
'user_id': fields.many2one('res.users', 'Salesman', readonly=True, states={'draft':[('readonly',False)]}),
'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position', readonly=True, states={'draft':[('readonly',False)]})
}
@ -883,7 +883,7 @@ class account_invoice(osv.osv):
line = self.finalize_invoice_move_lines(cr, uid, inv, line)
move = {
'ref': inv.number,
'ref': inv.reference and inv.reference or inv.name,
'line_id': line,
'journal_id': journal_id,
'date': date,

View File

@ -47,7 +47,7 @@
-
!assert {model: account.invoice, id: account_invoice_customer0}:
- state == 'open'
-
I check that now there is a move attached to the invoice
-
@ -126,7 +126,7 @@
acc_id=self.browse(cr, uid, ref("account_invoice_customer0"))
assert(acc_id.move_id)
-
I refund the invoice Using Credit Note
I refund the invoice Using Refund Button
-
!record {model: account.invoice.refund, id: account_invoice_refund_0}:
description: Refund To China Export

View File

@ -1,5 +1,5 @@
-
In order to test Validate Ledger Postings wizard in OpenERP I created a account move
In order to test the 'Validate Journal Entries' wizard in OpenERP, I created an account move
-
!record {model: account.move, id: account_move_0}:
@ -40,7 +40,7 @@
!assert {model: account.move, id: account_move_0}:
- state == 'draft'
-
I validate this account move by using Validate Ledger Postings
I validate this account move by using the 'Validate Journal Entries' wizard
-
!record {model: validate.account.move, id: validate_account_move_0}:
journal_id: account.bank_journal

View File

@ -34,8 +34,9 @@ class account_invoice_refund(osv.osv_memory):
_columns = {
'date': fields.date('Operation date', help='This date will be used as the invoice date for Refund Invoice and Period will be chosen accordingly!'),
'period': fields.many2one('account.period', 'Force period'),
'journal_id': fields.many2one('account.journal', 'Journal'),
'journal_id': fields.many2one('account.journal', 'Refund Journal', help='You can select here the journal to use for the refund invoice that will be created. If you leave that field empty, it will use the same journal as the current invoice.'),
'description': fields.char('Description', size=128, required=True),
'filter_refund': fields.selection([('modify', 'Modify'), ('refund', 'Refund'), ('cancel', 'Cancel')], "Refund Type", required=True, help='Refund invoice base on this type'),
}
def _get_journal(self, cr, uid, context=None):
@ -50,7 +51,8 @@ class account_invoice_refund(osv.osv_memory):
_defaults = {
'date': time.strftime('%Y-%m-%d'),
'journal_id': _get_journal
'journal_id': _get_journal,
'filter_refund': 'modify',
}
def compute_refund(self, cr, uid, ids, mode='refund', context=None):
@ -66,6 +68,8 @@ class account_invoice_refund(osv.osv_memory):
mod_obj = self.pool.get('ir.model.data')
act_obj = self.pool.get('ir.actions.act_window')
wf_service = netsvc.LocalService('workflow')
inv_tax_obj = self.pool.get('account.invoice.tax')
inv_line_obj = self.pool.get('account.invoice.line')
if context is None:
context = {}
@ -76,6 +80,7 @@ class account_invoice_refund(osv.osv_memory):
period = False
description = False
company = self.pool.get('res.users').browse(cr, uid, uid).company_id
journal_id = form.get('journal_id', False)
for inv in inv_obj.browse(cr, uid, context.get('active_ids'), context=context):
if inv.state in ['draft', 'proforma2', 'cancel']:
raise osv.except_osv(_('Error !'), _('Can not %s draft/proforma/cancel invoice.') % (mode))
@ -84,7 +89,8 @@ class account_invoice_refund(osv.osv_memory):
else:
period = inv.period_id and inv.period_id.id or False
journal_id = form.get('journal_id', False)
if not journal_id:
journal_id = inv.journal_id.id
if form['date'] :
date = form['date']
@ -153,10 +159,9 @@ class account_invoice_refund(osv.osv_memory):
'journal_id', 'period_id'], context=context)
invoice = invoice[0]
del invoice['id']
invoice_lines = self.pool.get('account.invoice.line').read(cr, uid, invoice['invoice_line'], context=context)
invoice_lines = inv_line_obj.read(cr, uid, invoice['invoice_line'], context=context)
invoice_lines = inv_obj._refund_cleanup_lines(cr, uid, invoice_lines)
tax_lines = self.pool.get('account.invoice.tax').read(
cr, uid, invoice['tax_line'], context=context)
tax_lines = inv_tax_obj.read(cr, uid, invoice['tax_line'], context=context)
tax_lines = inv_obj._refund_cleanup_lines(cr, uid, tax_lines)
invoice.update({
@ -196,13 +201,8 @@ class account_invoice_refund(osv.osv_memory):
return result
def invoice_refund(self, cr, uid, ids, context=None):
return self.compute_refund(cr, uid, ids, 'refund', context=context)
def invoice_cancel(self, cr, uid, ids, context=None):
return self.compute_refund(cr, uid, ids, 'cancel', context=context)
def invoice_modify(self, cr, uid, ids, context=None):
return self.compute_refund(cr, uid, ids, 'modify', context=context)
data_refund = self.read(cr, uid, ids, [] ,context=context)[0]['filter_refund']
return self.compute_refund(cr, uid, ids, data_refund, context=context)
account_invoice_refund()

View File

@ -7,29 +7,25 @@
<field name="model">account.invoice.refund</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Refund">
<separator string="This wizard is used to refund the invoice" colspan="4"/>
<form string="Refund Invoice">
<separator string="Refund Invoice Options" colspan="4"/>
<group colspan="4" >
<label string="Are you sure you want to refund this invoice ?" colspan="2"/>
<newline/>
<field name="description"/>
<field name="journal_id"/>
<field name="date"/>
<field name="period"/>
<field name="journal_id" />
<field name="filter_refund"/>
</group>
<separator colspan="4"/>
<group col="4" colspan="4" fill="1">
<label align="0.0" width="300" string="Refund Invoice: creates a refund invoice"/>
<label align="0.0" width="500" colspan="4" string="Cancel Invoice: creates a reverse accounting entries to cancel the invoice"/>
<label align="0.0" width="550" colspan="4" string="Modify Invoice: creates a refund invoice, and new copy of the same invoice ready for editing"/>
<label align="0.0" width="550" colspan="4" string="Modify Invoice: Cancels the current invoice and creates a new copy of it ready for editing."/>
<label align="0.0" width="300" string="Refund Invoice: Creates the refund invoice, ready for editing."/>
<label align="0.0" width="500" colspan="4" string="Cancel Invoice: Creates the refund invoice, validate and reconcile it to cancel the current invoice."/>
</group>
<separator colspan="4"/>
<group colspan="4" col="6">
<label string ="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-redo" string="Refund Invoice" name="invoice_refund" type="object"/>
<button icon="gtk-ok" string="Cancel Invoice" name="invoice_cancel" type="object"/>
<button icon="gtk-undo" string="Modify Invoice" name="invoice_modify" type="object"/>
<button string='Refund' icon="gtk-execute" name="invoice_refund" type="object"/>
</group>
</form>
</field>

View File

@ -161,6 +161,7 @@ class account_invoice_pay(osv.osv_memory):
writeoff_account_id = context['write_off']['writeoff_acc_id']
writeoff_journal_id = context['write_off']['writeoff_journal_id']
comment = context['write_off']['comment']
context['analytic_id'] = context['write_off']['analytic_id']
amount = data['amount']

View File

@ -15,7 +15,7 @@
<newline/>
<group colspan="4" col="4">
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="next_partner" icon="gtk-go-forward" type="object" string="Go to next partner" />
<button name="next_partner" icon="terp-gtk-jump-to-ltr" type="object" string="Go to next partner" />
</group>
</form>
</field>

View File

@ -9,7 +9,7 @@
<field name="arch" type="xml">
<form string="Unreconciliation">
<separator string="Unreconciliate transactions" colspan="4"/>
<image name="gtk-dialog-info"/>
<image name="terp-referer"/>
<label string="If you unreconciliate transactions, you must also verify all the actions that are linked to those transactions because they will not be disabled" colspan="2"/>
<separator colspan="4"/>
<group colspan="4" col="6">

View File

@ -14,6 +14,7 @@
<field name="journal_id"/>
<newline/>
<field name="period_id"/>
<separator colspan="4"/>
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="terp-camera_test" string="Approve" name="validate_move" type="object"/>
@ -29,11 +30,11 @@
<field name="view_mode">form</field>
<field name="view_id" ref="validate_account_move_view"/>
<field name="target">new</field>
<field name="help">The process of ledger is the process of transferring debit and credit amounts from a journal of original entry to a ledger book.</field>
<field name="help">The validation of journal entries process is also called 'ledger posting' and is the process of transferring debit and credit amounts from a journal of original entry to a ledger book.</field>
</record>
<menuitem
name="Validate Ledger Postings"
name="Validate Journal Entries"
parent="periodical_processing_journal_entries_validation"
action="action_validate_account_move"
id="menu_validate_account_moves"
@ -41,14 +42,14 @@
<!--Account Move lines-->
<record id="validate_account_move_line_view" model="ir.ui.view">
<field name="name">Validate Ledger Postings</field>
<field name="name">Validate Journal Entries</field>
<field name="model">validate.account.move.lines</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Validate Ledger Posting">
<separator string="Post Entry Lines" colspan="4"/>
<image name="gtk-dialog-info"/>
<label string="All selected entry lines will be posted. It means you won't be able to modify their accouting fields." colspan="2"/>
<form string="Validate Journal Entries">
<separator string="Post Journal Entries" colspan="4"/>
<image name="terp-referer"/>
<label string="All selected journal entries will be validated and posted. It means you won't be able to modify their accouting fields." colspan="2"/>
<separator colspan="4"/>
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
@ -59,7 +60,7 @@
</record>
<record id="action_validate_account_move_line" model="ir.actions.act_window">
<field name="name">Validate Ledger Postings</field>
<field name="name">Validate Journal Entries</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">validate.account.move.lines</field>
<field name="view_type">form</field>
@ -72,7 +73,7 @@
<record model="ir.values" id="validate_account_move_line_values">
<field name="model_id" ref="account.model_account_move_line" />
<field name="object" eval="1" />
<field name="name">Validate Ledger Postings</field>
<field name="name">Validate Journal Entries</field>
<field name="key2">client_action_multi</field>
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_validate_account_move_line'))" />
<field name="key">action</field>

View File

@ -95,7 +95,7 @@
<field name="type">tree</field>
<field eval="32" name="priority"/>
<field name="arch" type="xml">
<tree colors="blue:state in ('draft');black:state in ('validate')" editable="bottom" string="Partner entries">
<tree colors="red:state in ('draft');black:state in ('validate')" editable="bottom" string="Partner entries">
<field name="date"/>
<field name="move_id"/>
<field name="ref"/>

View File

@ -144,7 +144,26 @@ class account_voucher(osv.osv):
def _get_type(self, cr, uid, context={}):
return context.get('type')
def _get_tax(self, cr, uid, context={}):
journal_pool = self.pool.get('account.journal')
journal_id = context.get('journal_id', False)
journal = journal_pool.browse(cr, uid, journal_id)
tax_id = False
account_id = False
if journal.type == 'sale':
account_id = journal.default_credit_account_id
elif journal.type == 'purchase':
account_id = journal.default_debit_account_id
if account_id and account_id.tax_ids:
tax_id = account_id.tax_ids[0].id
return tax_id
def _get_pay_journal(self, cr, uid, context={}):
journal_pool = self.pool.get('account.journal')
@ -178,6 +197,10 @@ class account_voucher(osv.osv):
'journal_id':fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'account_id':fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'payment_ids':fields.one2many('account.voucher.line','voucher_id','Voucher Lines', readonly=True, states={'draft':[('readonly',False)]}),
'line_cr_ids':fields.one2many('account.voucher.line','voucher_cr_id','Credit Lines', domain=[('type','=','cr')], readonly=True),
'line_dr_ids':fields.one2many('account.voucher.line','voucher_dr_id','Debit Lines', domain=[('type','=','dr')], readonly=True),
'period_id': fields.many2one('account.period', 'Period', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'narration':fields.text('Narration', readonly=True, states={'draft':[('readonly',False)]}),
'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}),
@ -195,7 +218,7 @@ class account_voucher(osv.osv):
\n* The \'Posted\' state is used when user create voucher,a voucher number is generated and voucher entries are created in account \
\n* The \'Cancelled\' state is used when user cancel voucher.'),
#'amount': fields.function(_compute_total, method=True, type='float', digits=(14,2), string='Total', store=True),
'amount': fields.float('Total', digits=(16, 2), readonly=True, states={'draft':[('readonly',False)]}),
'amount': fields.float('Total', digits=(16, 2), required=True, readonly=True, states={'draft':[('readonly',False)]}),
'tax_amount':fields.float('Tax Amount', digits=(14,2), readonly=True, states={'draft':[('readonly',False)]}),
'reference': fields.char('Ref #', size=64, readonly=True, states={'draft':[('readonly',False)]}, help="Payment or Receipt transaction number, i.e. Bank cheque number or payorder number or Wire transfer number or Acknowledge number."),
'number': fields.related('move_id', 'name', type="char", readonly=True, string='Number'),
@ -208,6 +231,7 @@ class account_voucher(osv.osv):
('pay_later','Pay Later or Group Funds'),
],'Payment', select=True, readonly=True, states={'draft':[('readonly',False)]}),
'tax_id':fields.many2one('account.tax', 'Tax', readonly=True, states={'draft':[('readonly',False)]}),
'pre_line':fields.boolean('Previous Payments ?', required=False),
}
_defaults = {
@ -221,67 +245,117 @@ class account_voucher(osv.osv):
'date' : lambda *a: time.strftime('%Y-%m-%d'),
'audit': lambda *a: False,
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.voucher',context=c),
'tax_id': _get_tax,
}
def compute_tax(self, cr, uid, ids, context={}):
# def compute_tax(self, cr, uid, ids, context={}):
# tax_pool = self.pool.get('account.tax')
# partner_pool = self.pool.get('res.partner')
# position_pool = self.pool.get('account.fiscal.position')
# voucher_line_pool = self.pool.get('account.voucher.line')
# for voucher in self.browse(cr, uid, ids):
# total = 0.0
# for line in voucher.payment_ids:
# total += line.amount
# if voucher.tax_id:
# tax_id = voucher.tax_id.id
# tax = [tax_pool.browse(cr, uid, tax_id)]
#
# if voucher.partner_id:
# partner = partner_pool.browse(cr, uid, voucher.partner_id) or False
# taxes = position_pool.map_tax(cr, uid, partner and partner.property_account_position or False, tax)
# tax = tax_pool.browse(cr, uid, taxes)
# voucher_total_tax = 0.0
# voucher_total_amount = 0.0
# if voucher.tax_id.price_include:
# for line in voucher.payment_ids:
# total_amount = 0.0
# total_tax = 0.0
# for tax_line in tax_pool.compute_all(cr, uid, tax, line.amount, 1).get('taxes'):
# total_tax += tax_line.get('amount')
# total_amount += tax_line.get('price_unit')
# voucher_total_tax += total_tax
# voucher_line_pool.write(cr, uid, [line.id], {'amount':total_amount})
# voucher_total_amount = total
# else:
# for tax_line in tax_pool.compute_all(cr, uid, tax, total, 1).get('taxes'):
# voucher_total_tax += tax_line.get('amount')
# voucher_total_amount = total + voucher_total_tax
# self.write(cr, uid, [voucher.id], {'tax_amount':voucher_total_tax, 'amount':voucher_total_amount})
# return True
def onchange_price(self, cr, uid, ids, payment_ids, tax_id, partner_id=False, context={}):
tax_pool = self.pool.get('account.tax')
partner_pool = self.pool.get('res.partner')
position_pool = self.pool.get('account.fiscal.position')
voucher_line_pool = self.pool.get('account.voucher.line')
for voucher in self.browse(cr, uid, ids):
total = 0.0
for line in voucher.payment_ids:
total += line.amount
if voucher.tax_id:
tax_id = voucher.tax_id.id
tax = [tax_pool.browse(cr, uid, tax_id)]
if voucher.partner_id:
partner = partner_pool.browse(cr, uid, voucher.partner_id) or False
taxes = position_pool.map_tax(cr, uid, partner and partner.property_account_position or False, tax)
tax = tax_pool.browse(cr, uid, taxes)
voucher_total_tax = 0.0
voucher_total_amount = 0.0
if voucher.tax_id.price_include:
for line in voucher.payment_ids:
total_amount = 0.0
total_tax = 0.0
for tax_line in tax_pool.compute_all(cr, uid, tax, line.amount, 1).get('taxes'):
total_tax += tax_line.get('amount')
total_amount += tax_line.get('price_unit')
voucher_total_tax += total_tax
voucher_line_pool.write(cr, uid, [line.id], {'amount':total_amount})
voucher_total_amount = total
else:
for tax_line in tax_pool.compute_all(cr, uid, tax, total, 1).get('taxes'):
voucher_total_tax += tax_line.get('amount')
voucher_total_amount = total + voucher_total_tax
self.write(cr, uid, [voucher.id], {'tax_amount':voucher_total_tax, 'amount':voucher_total_amount})
return True
def onchange_price(self, cr, uid, ids, payment_ids, tax_id, partner_id=False, context={}):
tax_pool = self.pool.get('account.tax')
partner_pool = self.pool.get('res.partner')
position_pool = self.pool.get('account.fiscal.position')
res = {
'tax_amount':False,
'amount':False
'amount':False,
}
tax_amount = 0.0
voucher_total_tax = 0.0
voucher_total = 0.0
voucher_payment_ids = []
total = 0.0
total_tax = 0.0
for line in payment_ids:
total += line[2].get('amount')
voucher_payment_ids += [line[1]]
voucher_total += line[2].get('amount')
total = voucher_total
if tax_id:
tax = [tax_pool.browse(cr, uid, tax_id)]
if partner_id:
partner = partner_pool.browse(cr, uid, partner_id) or False
taxes = position_pool.map_tax(cr, uid, partner and partner.property_account_position or False, tax)
tax = tax_pool.browse(cr, uid, taxes)
if not tax[0].price_include:
for tax_line in tax_pool.compute_all(cr, uid, tax, voucher_total, 1).get('taxes'):
total_tax += tax_line.get('amount')
total += total_tax
else:
line_ids = []
for line in payment_ids:
line_total = 0.0
line_tax = 0.0
operation = line[0]
rec_id = line[1]
rec = line[2]
for tax_line in tax_pool.compute_all(cr, uid, tax, rec.get('amount'), 1).get('taxes'):
line_tax += tax_line.get('amount')
line_total += tax_line.get('price_unit')
total_tax += line_tax
if rec_id:
voucher_line_pool.write(cr, uid, [rec_id], {'amount':line_total})
line_ids += [rec_id]
else:
rec.update({
'amount':line_total
})
line_id = voucher_line_pool.create(cr, uid, rec)
line_ids += [line_id]
res.update({
'payment_ids':line_ids
})
res.update({
'amount':total,
'tax_amount':tax_amount
'tax_amount':total_tax
})
return {
@ -427,12 +501,14 @@ class account_voucher(osv.osv):
if ttype == 'payment':
rs.update({
'account_id':line.account_id, #line.move_id.partner_id.property_account_payable.id,
'type':'dr'
#'amount':line.credit
})
amount = line.credit
elif ttype == 'receipt':
rs.update({
'account_id':line.move_id.partner_id.property_account_receivable.id,
'account_id':line.account_id,
'type':'cr'
#'amount':line.debit
})
amount = line.debit
@ -440,12 +516,56 @@ class account_voucher(osv.osv):
total += amount
line_id = line_pool.create(cr, uid, rs, context=context)
res += [line_id]
if search_type == 'debit':
search_type = 'credit'
else:
search_type = 'debit'
ids = move_line_pool.search(cr, uid, [('account_id.type','=', account_type), ('reconcile_id','=', False), ('partner_id','=',partner_id), (search_type,'>',0)], context=context)
total = 0.0
res_cr = []
for line in move_line_pool.browse(cr, uid, ids):
amount = 0.0
rs = move_line_pool.default_get(cr, uid, move_line_pool._columns.keys(), context=context)
rs.update({
'name':line.move_id.name,
'ref':line.ref or '/',
'move_id':line.move_id.id,
'move_line_id':line.id,
'voucher_cr_id':voucher_id,
'amount':amount,
})
if ttype == 'payment':
rs.update({
'account_id':line.account_id, #line.move_id.partner_id.property_account_payable.id,
'type':'dr',
})
amount = line.debit
elif ttype == 'receipt':
rs.update({
'account_id':line.account_id,
'type':'cr',
})
amount = line.credit
rs.update({
'amount':amount
})
line_id = line_pool.create(cr, uid, rs, context=context)
res_cr += [line_id]
res = {
'payment_ids':res,
'account_id':account_id,
'amount':total
}
if res_cr:
res.update({
'pre_line':True,
'line_cr_ids':res_cr
})
return {
'value':res,
'context':context,
@ -568,7 +688,7 @@ class account_voucher(osv.osv):
invoice_pool = self.pool.get('account.invoice')
for inv in self.browse(cr, uid, ids):
if inv.move_id:
continue
@ -639,12 +759,41 @@ class account_voucher(osv.osv):
})
line_ids = []
master_line = move_line_pool.create(cr, uid, move_line)
line_ids += [master_line]
rec_list_ids = []
partial_rec = []
line_total = 0.0
if inv.pre_line and inv.line_cr_ids:
for line in inv.line_cr_ids:
move_line = {
'name':line.name and line.name or '/',
'debit':False,
'credit':False,
'account_id':line.account_id.id,
'move_id':move_id,
'journal_id':inv.journal_id.id,
'period_id':inv.period_id.id,
'partner_id':inv.partner_id.id,
'ref':ref,
'date':inv.date
}
total_amount = inv.amount
line_total -= line.amount
if inv.type in ('sale', 'receipt'):
move_line.update({
'debit':line.amount
})
elif inv.type == 'purchase':
move_line.update({
'credit':line.amount
})
master_line = move_line_pool.create(cr, uid, move_line)
line_ids += [master_line]
rec_ids = [master_line, line.move_line_id.id]
rec_list_ids.append(rec_ids)
for line in inv.payment_ids:
rec_ids = []
amount=0.0
@ -689,7 +838,7 @@ class account_voucher(osv.osv):
move_line.update({
'debit': line.amount or False
})
move_line_id = move_line_pool.create(cr, uid, move_line)
line_ids += [move_line_id]
@ -718,7 +867,7 @@ class account_voucher(osv.osv):
account_id = False
if inv.tax_id and inv.tax_id.account_collected_id:
account_id = inv.tax_id.account_collected_id.id
if inv.type == 'sale':
move_line.update({
'credit':inv.tax_amount,
@ -733,10 +882,12 @@ class account_voucher(osv.osv):
move_line_id = move_line_pool.create(cr, uid, move_line)
line_ids += [move_line_id]
if line_total != inv.amount and inv.type in ('payment', 'receipt'):
name = '/'
name = 'Adjustment'
diff = line_total - inv.amount
if diff < 0:
diff = -diff
move_line = {
'name':name,
'account_id':False,
@ -748,6 +899,18 @@ class account_voucher(osv.osv):
'date':inv.date
}
account_id = False
if inv.type == 'receipt':
move_line.update({
'account_id':inv.partner_id.property_account_receivable.id,
'credit':diff
})
elif inv.type == 'payment':
move_line.update({
'account_id':inv.partner_id.property_account_payable.id,
'debit':diff
})
move_line_id = move_line_pool.create(cr, uid, move_line)
line_ids += [move_line_id]
rec = {
'move_id': move_id,
@ -757,7 +920,8 @@ class account_voucher(osv.osv):
self.write(cr, uid, [inv.id], rec)
move_pool.post(cr, uid, [move_id], context={})
for rec_ids in rec_list_ids:
move_line_pool.reconcile_partial(cr, uid, rec_ids)
if len(rec_ids) >= 2:
move_line_pool.reconcile_partial(cr, uid, rec_ids)
inv = self.browse(cr, uid, inv.id)
name = inv.name and inv.name or inv.number
@ -820,14 +984,32 @@ account_voucher()
class account_voucher_line(osv.osv):
_name = 'account.voucher.line'
_description = 'Voucher Line'
def _compute_balance(self, cr, uid, ids, name, args, context=None):
res = {}
for line in self.browse(cr, uid, ids):
move_line = False
if line.move_line_id:
move_line = line.move_line_id
if move_line and move_line.credit > 0:
res[line.id] = move_line.credit
elif move_line and move_line.debit > 0:
res[line.id] = move_line.debit
return res
_columns = {
'voucher_id':fields.many2one('account.voucher', 'Voucher'),
'voucher_cr_id':fields.many2one('account.voucher', 'Voucher'),
'voucher_dr_id':fields.many2one('account.voucher', 'Voucher'),
'name':fields.char('Description', size=256),
'account_id':fields.many2one('account.account','Account', required=True, domain=[('type','<>','view')]),
'partner_id':fields.related('voucher_id', 'partner_id', type='many2one', relation='res.partner', string='Partner'),
'amount':fields.float('Amount'),
# 'type':fields.selection([('dr','Debit'),('cr','Credit')], 'Cr/Dr'),
'untax_amount':fields.float('UnTax Amount'),
'type':fields.selection([('dr','Debit'),('cr','Credit')], 'Cr/Dr'),
'ref':fields.char('Reference', size=32),
'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic Account'),
'stype':fields.selection([('service','Service'),('other','Other')], 'Product Type'),
@ -836,7 +1018,8 @@ class account_voucher_line(osv.osv):
# 'date_original': fields.date('Date', readonly="1"), #fields.related account.move.line
'date_due': fields.related('move_line_id','date_maturity', type='date', relation='account.move.line', string='Due Date', readonly="1"),
# 'date_due': fields.date('Due Date', readonly="1"), #fields.related account.move.line
'amount_original': fields.float('Originial Amount', readonly="1"), #fields.related account.move.line
'amount_original': fields.function(_compute_balance, method=True, type='float', string='Originial Amount', store=True),
# 'amount_original': fields.float('Originial Amount', readonly="1"), #fields.related account.move.line
'amount_unreconciled': fields.related('move_line_id','balance', type='float', relation='account.move.line', string='Open Balance', readonly="1"),
# 'amount_unreconciled': fields.float('Open Balance', readonly="1"), #fields.related account.move.line
'move_id' : fields.many2one('account.move','Bill / Invoice'),
@ -894,6 +1077,7 @@ class account_voucher_line(osv.osv):
journal_pool = self.pool.get('account.journal')
partner_pool = self.pool.get('res.partner')
account_id = False
ttype = 'cr'
values = super(account_voucher_line, self).default_get(cr, user, fields_list, context=context)
journal_id = context.get('journal_id', False)
@ -904,19 +1088,25 @@ class account_voucher_line(osv.osv):
journal = journal_pool.browse(cr, user, journal_id)
if ttype == 'sale' and journal:
account_id = journal.default_credit_account_id and journal.default_credit_account_id.id or False
ttype = 'cr'
elif ttype == 'purchase' and journal:
account_id = journal.default_credit_account_id and journal.default_debit_account_id.id or False
ttype = 'dr'
elif ttype and partner_id and ttype in ('payment', 'receipt'):
partner = partner_pool.browse(cr, user, partner_id)
if ttype == 'receipt' and partner:
account_id = partner.property_account_receivable and partner.property_account_receivable.id or False
ttype = 'cr'
elif ttype == 'payment' and partner:
account_id = partner.property_account_receivable and partner.property_account_payable.id or False
ttype = 'dr'
if not account_id:
raise osv.except_osv(_('Invalid Error !'), _('Please change partner and try again !'))
values.update({
'account_id':account_id
'account_id':account_id,
'type':ttype
})
return values
account_voucher_line()

View File

@ -96,8 +96,21 @@
<notebook colspan="4">
<page string="Payment Information">
<!-- <field name="payment_ids" on_change="onchange_price(payment_ids, 0.0, False)" default_get="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" colspan="4" nolabel="1" height="180">-->
<field name="payment_ids" default_get="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" colspan="4" nolabel="1" height="180">
<tree string="Payment Lines" editable="bottom">
<field name="payment_ids" on_change="onchange_price(payment_ids, 0.0, False)" default_get="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" colspan="4" nolabel="1" height="180">
<tree string="Invoices and outstanding payments" editable="bottom">
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'type':parent.type, 'partner_id':parent.partner_id}" on_change="onchange_move_line_id(move_line_id)" domain="[('account_id.type','=','receivable'), ('reconcile_id','=', False), ('partner_id','=',parent.partner_id), ('debit','>',0)]"/>
<field name="account_id" domain="[('type','=','receivable')]"/>
<field name="date_original"/>
<field name="date_due"/>
<field name="amount_original"/>
<field name="amount_unreconciled" sum="Open Balance"/>
<field name="amount" sum="Payment"/>
</tree>
</field>
<separator string="Previous Unreconcile balance" colspan="4"/>
<field name="pre_line"/>
<field name="line_cr_ids" colspan="4" nolabel="1" readonly="1" attrs="{'invisible': [('pre_line','=',False)]}">
<tree string="Credits" editable="bottom">
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'type':parent.type, 'partner_id':parent.partner_id}" on_change="onchange_move_line_id(move_line_id)" domain="[('account_id.type','=','receivable'), ('reconcile_id','=', False), ('partner_id','=',parent.partner_id), ('debit','>',0)]"/>
<field name="account_id" domain="[('type','=','receivable')]"/>
<field name="date_original"/>

View File

@ -44,7 +44,7 @@
<group col="3" colspan="1">
<separator string="Total" colspan="3"/>
<field name="tax_id" on_change="onchange_price(payment_ids, tax_id, partner_id)" widget="selection" domain="[('type_tax_use','in',('sale','all'))]"/><field name="tax_amount" on_change="onchange_price(payment_ids, tax_id, partner_id)" nolabel="1"/>
<field name="amount" string="Total"/><button icon="terp-stock_format-scientific" name="compute_tax" attrs="{'invisible':[('state','!=','draft')]}" colspan="1" string="Compute TAX" type="object"/>
<label colspan="1" string=""/><field name="amount" string="Total"/>
</group>
</group>
</page>
@ -60,7 +60,7 @@
</notebook>
<group col="10" colspan="4">
<field name="state"/>
<button name="proforma_voucher" string="Create" states="draft" icon="terp-document-new"/>
<button name="proforma_voucher" string="Post" states="draft" icon="terp-document-new"/>
<button name="recheck_voucher" string="Approve" states="recheck" icon="terp-check"/>
<button name="cancel_voucher" string="Cancel" states="draft,proforma,recheck" icon="gtk-cancel"/>
<button name="action_cancel_draft" type="object" states="cancel" string="Set to Draft" icon="terp-stock_effects-object-colorize"/>

View File

@ -12,13 +12,10 @@
<field name="reference"/>
<field name="partner_id"/>
<field name="journal_id"/>
<field name="account_id"/>
<field name="period_id" invisible="context.get('visible', False)"/>
<field name="amount" sum="Total Amount"/>
<field name="period_id"/>
<field name="state"/>
<button name="proforma_voucher" string="Create" states="draft" icon="terp-document-new"/>
<button name="recheck_voucher" string="Approve" states="recheck" icon="terp-check"/>
<button name="action_cancel_draft" type="object" states="cancel" string="Set to Draft" icon="terp-stock_effects-object-colorize"/>
<button name="proforma_voucher" string="Post" states="draft" icon="terp-document-new"/>
</tree>
</field>
</record>
@ -131,6 +128,7 @@
</search>
</field>
</record>
<record id="view_voucher_filter_new" model="ir.ui.view">
<field name="name">account.voucher.select</field>
<field name="model">account.voucher</field>
@ -139,16 +137,14 @@
<search string="Search Vouchers">
<group col='8' colspan='4'>
<filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Vouchers"/>
<filter icon="terp-check" string="Proforma" domain="[('state','=','proforma')]" help="Proforma Vouchers"/>
<filter icon="terp-camera_test" string="Posted" domain="[('state','=','posted')]" help="Posted Vouchers"/>
<separator orientation="vertical"/>
<filter icon="terp-stock_effects-object-colorize" string="To Review" domain="[('state','=','posted')]" groups="base.group_extended" help="To Review"/>
<filter icon="gtk-cancel" string="Cancel" domain="[('state','=','cancel')]" help="Cancel Vouchers" groups="base.group_extended"/>
<separator orientation="vertical"/>
<field name="number" select='1'/>
<field name="account_id" select="1"/>
<field name="partner_id" select='1'/>
<field name="date" select='1'/>
<field name="number" select='1'/>
<field name="partner_id" select='1'/>
</group>
<newline/>
<group col='8' colspan='4'>
@ -159,8 +155,7 @@
<group expand="0" string="Group By..." colspan="12" col="10">
<filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Journal" icon="terp-folder-orange" domain="[]" context="{'group_by':'journal_id'}"/>
<filter string="Period" icon="terp-go-month" domain="[]" context="{'group_by':'period_id'}"/>
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type', 'set_visible':True}"/>
<filter string="Period" icon="terp-go-month" domain="[]" context="{'group_by':'period_id','visible':True}"/>
<filter string="States" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
</group>
<newline/>