bzr revid: apa@tinyerp.com-20100406051920-rb8xi7w8n8gfxhgs
This commit is contained in:
apa-tiny 2010-04-06 10:49:20 +05:30
commit 58e9e09874
400 changed files with 19005 additions and 12080 deletions

View File

@ -46,7 +46,17 @@ module named account_voucherss
'security/account_security.xml',
'security/ir.model.access.csv',
'account_menuitem.xml',
'wizard/account_invoice_refund_view.xml',
'wizard/account_period_close_view.xml',
'wizard/account_fiscalyear_close_state.xml',
'wizard/account_chart_view.xml',
'wizard/account_move_bank_reconcile_view.xml',
'wizard/account_move_line_reconcile_select_view.xml',
'wizard/account_move_journal_view.xml',
'account_wizard.xml',
'wizard/account_move_line_unreconcile_select_view.xml',
'wizard/account_subscription_generate_view.xml',
'project/wizard/project_account_analytic_line_view.xml',
'account_view.xml',
'account_end_fy.xml',
'account_invoice_view.xml',

View File

@ -153,7 +153,7 @@
<field name="period_id" groups="base.group_user"/>
<group colspan="2" col="1" groups="base.group_user">
<label align="0.0" string="(keep empty to use the current period)"/>
</group>
</group>
</group>
<notebook colspan="4">
<page string="Invoice">

View File

@ -24,3 +24,4 @@
</data>
</openerp>

View File

@ -668,9 +668,9 @@
<field eval="True" name="object"/>
</record>
<wizard id="action_move_journal_line_form" menu="False" model="account.move.line" name="account.move.journal" string="Entries by Line"/>
<!-- <wizard id="action_move_journal_line_form" menu="False" model="account.move.line" name="account.move.journal" string="Entries by Line"/>
<menuitem icon="STOCK_JUSTIFY_FILL" action="action_move_journal_line_form" id="menu_action_move_journal_line_form" parent="account.menu_finance_entries" type="wizard" sequence="5"/>
-->
<!--
Entries lines
-->
@ -1007,9 +1007,9 @@
<menuitem action="action_move_line_search" id="menu_action_move_line_search" parent="account.next_id_29"/>
<menuitem id="menu_finance_charts" name="Charts" parent="account.menu_finance" sequence="4"/>
<wizard id="wizard_account_chart" menu="False" model="account.account" name="account.chart" string="Chart of Accounts"/>
<!-- <wizard id="wizard_account_chart" menu="False" model="account.account" name="account.chart" string="Chart of Accounts"/>
<menuitem icon="STOCK_INDENT" action="wizard_account_chart" id="menu_action_account_tree2" parent="account.menu_finance_charts" type="wizard"/>
-->
<record id="view_bank_statement_reconcile_form" model="ir.ui.view">
@ -1079,8 +1079,14 @@
groups="group_account_user"/>
<menuitem action="action_bank_statement_reconciliation_form" id="menu_action_account_bank_reconcile_tree" parent="next_id_30"/>
<wizard id="action_account_bank_reconcile_tree" menu="False" model="account.move.line" name="account.move.bank.reconcile" string="Bank reconciliation"/>
<menuitem action="action_account_bank_reconcile_tree" id="menu_action_account_bank_reconcile_check_tree" parent="account.next_id_30" type="wizard"/>
<!-- <wizard id="action_account_bank_reconcile_tree" menu="False" model="account.move.line" name="account.move.bank.reconcile" string="Bank reconciliation"/> -->
<!-- <menuitem action="action_account_bank_reconcile_tree" id="menu_action_account_bank_reconcile_check_tree" parent="account.next_id_30" type="wizard"/> -->
<!-- bank reconsilation -->
<menuitem action="action_account_bank_reconcile_tree"
id="menu_action_account_bank_reconcile_check_tree"
parent="account.next_id_30" />
<act_window
domain="[('account_id', '=', active_id)]"

View File

@ -7,7 +7,14 @@
name="account.balance.account.balance.report"
keyword="client_print_multi"
id="wizard_account_balance_compare_report"/>
<wizard id="wizard_invoice_refund" model="account.invoice" name="account.invoice.refund" string="Credit Note" groups="base.group_user"/>
<!-- <wizard id="wizard_invoice_refund" model="account.invoice" name="account.invoice.refund" string="Credit Note" groups="base.group_user"/> -->
<!-- <wizard id="wizard_invoice_refund" model="account.invoice" name="account.invoice.refund" string="Credit Note" groups="base.group_user"/>-->
<!-- for test only -->
<wizard id="wizard_invoice_pay" model="account.invoice" name="account.invoice.pay" string="Pay invoice" groups="base.group_user"/>
@ -21,8 +28,9 @@
type="wizard"
sequence="1"/>
<wizard id="wizard_fiscalyear_close_state" menu="False" model="account.fiscalyear" name="account.fiscalyear.close.state" string="Close a Fiscal Year"/>
<!-- <wizard id="wizard_fiscalyear_close_state" menu="False" model="account.fiscalyear" name="account.fiscalyear.close.state" string="Close a Fiscal Year"/>
<menuitem action="wizard_fiscalyear_close_state" id="menu_wizard_fy_close_state" parent="menu_account_end_year_treatments" type="wizard"/>
-->
<wizard
id="wizard_open_closed_fiscalyear"
@ -35,12 +43,19 @@
id="menu_wizard_open_closed_fy"
sequence="2"
parent="account.menu_account_end_year_treatments" type="wizard"/>
<!-- period close
<wizard id="wizard_period_close" model="account.period" name="account.period.close" string="Close a Period"/>
<wizard id="wizard_period_close" model="account.period" name="account.period.close" string="Close a Period"/>
<wizard id="action_account_period_close" model="account.period" name="account.period.close" string="Close a Period"/>
-->
<!-- automatic reconcile -->
<wizard id="wizard_automatic_reconcile" menu="False" model="account.account" name="account.automatic.reconcile" string="Automatic reconciliation"/>
<menuitem id="next_id_20" name="Reconciliation" parent="menu_finance_periodical_processing"/><menuitem action="wizard_automatic_reconcile" id="menu_automatic_reconcile" parent="next_id_20" type="wizard"/>
<menuitem id="next_id_20" name="Reconciliation" parent="menu_finance_periodical_processing"/>
<menuitem action="wizard_automatic_reconcile" id="menu_automatic_reconcile" parent="next_id_20" type="wizard"/>
<!-- Import entry in statement -->
@ -57,19 +72,24 @@
<wizard id="wizard_reconcile_unreconcile" model="account.move.reconcile" name="account.reconcile.unreconcile" string="Unreconcile Entries"/>
<wizard id="wizard_reconcile_select" menu="False" model="account.move.line" name="account.move.line.reconcile.select" string="Reconcile entries"/>
<!-- <wizard id="wizard_reconcile_select" menu="False" model="account.move.line" name="account.move.line.reconcile.select" string="Reconcile entries"/>
<menuitem action="wizard_reconcile_select" id="menu_reconcile_select" parent="account.next_id_20" type="wizard"/>
-->
<!-- unreconcile -->
<wizard id="wizard_unreconcile" model="account.move.line" name="account.move.line.unreconcile" string="Unreconcile Entries"/>
<!-- unreconcile
<wizard id="wizard_unreconcile_select" menu="False" model="account.move.line" name="account.move.line.unreconcile.select" string="Unreconcile entries"/>
<menuitem action="wizard_unreconcile_select" id="menu_unreconcile_select" parent="account.next_id_20" type="wizard"/>
-->
<!-- subscriptions -->
<!--
<wizard id="wizard_generate_subscription" menu="False" model="account.subscription" name="account.subscription.generate" string="Create subscription entries"/>
<menuitem action="wizard_generate_subscription" id="menu_generate_subscription" parent="account.menu_finance_periodical_processing" type="wizard"/>
-->
<!-- Aged partner balance -->
<wizard id="wizard_aged_trial_balance" menu="False" model="res.partner" name="account.aged.trial.balance" string="Aged Partner Balance"/>
<menuitem id="next_id_22" name="Partner Accounts" parent="menu_finance_generic_reporting" sequence="1"/>

View File

@ -204,10 +204,14 @@
<field name="view_type">form</field>
<field name="view_id" ref="view_account_analytic_line_tree"/>
</record>
<wizard id="action_account_analytic_line" menu="False" model="account.analytic.line" name="account.analytic.line" string="Entries by Line"/>
<wizard id="action_account_analytic_line" menu="False" model="account.analytic.line" name="account.analytic.line" string="Entries by Line"/>
<menuitem id="next_id_41" name="Analytic Entries" parent="account.menu_finance_entries"/>
<menuitem type="wizard" icon="STOCK_JUSTIFY_FILL" action="action_account_analytic_line" id="account_entries_analytic_entries" parent="next_id_41"/>
<!-- Entries by Line -->
<menuitem icon="STOCK_JUSTIFY_FILL"
action="action_project_account_analytic_line_form"
id="account_entries_analytic_entries"
parent="next_id_41"/>
<record id="action_account_tree1" model="ir.actions.act_window">
<field name="name">Analytic Entries</field>

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@ -25,7 +25,7 @@ import wizard_account_analytic_inverted_balance_report
import wizard_account_analytic_cost_ledger_report
import wizard_account_analytic_cost_ledger_for_journal_report
import wizard_account_analytic_analytic_check
import wizard_account_analytic_line
import project_account_analytic_line
import wizard_analytic_account_chart
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
class project_account_analytic_line(osv.osv_memory):
_name = "project.account.analytic.line"
_description = "Analytic Entries by line"
_columns = {
'from_date': fields.date('From'),
'to_date': fields.date('To'),
}
def action_open_window(self, cr, uid, ids, context={}):
mod_obj =self.pool.get('ir.model.data')
domain = []
for data in self.read(cr, uid, ids, context=context):
from_date = data['from_date']
to_date = data['to_date']
if from_date and to_date:
domain = [('date','>=',from_date), ('date','<=',to_date)]
elif from_date:
domain = [('date','>=',from_date)]
elif to_date:
domain = [('date','<=',to_date)]
result = mod_obj._get_id(cr, uid, 'account', 'view_account_analytic_line_filter')
id = mod_obj.read(cr, uid, result, ['res_id'], context=context)
return {
'name': _('Analytic Entries by line'),
'view_type': 'form',
"view_mode": 'tree,form',
'res_model': 'account.analytic.line',
'type': 'ir.actions.act_window',
'domain': domain,
'search_view_id': id['res_id'],
}
project_account_analytic_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_project_account_analytic_line_form" model="ir.ui.view">
<field name="name">project.account.analytic.line.form</field>
<field name="model">project.account.analytic.line</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="View Account Analytic Lines">
<group colspan="4" >
<field name="from_date"/>
<newline/>
<field name="to_date" />
</group>
<label string ="(Keep empty to open the current situation)" />
<separator string="" colspan="4" />
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-execute" string="Open Entries" name="action_open_window" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_project_account_analytic_line_form" model="ir.actions.act_window">
<field name="name">Entries By Line</field>
<field name="res_model">project.account.analytic.line</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_project_account_analytic_line_form"/>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -1,84 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
import pooler
import time
from tools.translate import _
def _action_open_window(self, cr, uid, data, context):
domain = []
from_date = data['form']['from_date']
to_date = data['form']['to_date']
if from_date and to_date:
domain = [('date','>=',from_date),('date','<=',to_date)]
elif from_date:
domain = [('date','>=',from_date)]
elif to_date:
domain = [('date','<=',to_date)]
mod_obj = pooler.get_pool(cr.dbname).get('ir.model.data')
result = mod_obj._get_id(cr, uid, 'account', 'view_account_analytic_line_filter')
id = mod_obj.read(cr, uid, result, ['res_id'])
return {
'name': _('Analytic Entries by line'),
'view_type': 'form',
"view_mode": 'tree,form',
'res_model': 'account.analytic.line',
'type': 'ir.actions.act_window',
'domain': domain,
'search_view_id': id['res_id'],}
class account_analytic_line(wizard.interface):
form1 = '''<?xml version="1.0"?>
<form string="View Account Analytic Lines">
<separator string="Account Analytic Lines Analysis" colspan="4"/>
<field name="from_date"/>
<newline/>
<field name="to_date"/>
<newline/>
<label string=""/>
<label string="(Keep empty to open the current situation)" align="0.0" colspan="3"/>
</form>'''
form1_fields = {
'from_date': {
'string': 'From',
'type': 'date',
},
'to_date': {
'string': 'To',
'type': 'date',
},
}
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', 'Cancel','gtk-cancel'),('open', 'Open Entries','gtk-ok')]}
},
'open': {
'actions': [],
'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
}
}
account_analytic_line('account.analytic.line')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@ -15,40 +15,36 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard_automatic_reconcile
import wizard_reconcile_select
import wizard_unreconcile_select
import account_move_line_reconcile_select
import account_move_line_unreconcile_select
import wizard_reconcile
import wizard_unreconcile
import wizard_refund
import account_invoice_refund
import wizard_pay_invoice
import wizard_journal
import account_move_journal
import wizard_journal_select
import wizard_bank_reconcile
import wizard_subscription_generate
import account_move_bank_reconcile
import account_subscription_generate
import wizard_aged_trial_balance
import wizard_general_ledger_report
import wizard_third_party_ledger
import wizard_account_balance_report
import wizard_partner_balance_report
import wizard_period_close
import account_period_close
import wizard_fiscalyear_close
import wizard_fiscalyear_close_state
import account_fiscalyear_close_state
import wizard_open_closed_fiscalyear
import wizard_vat
import wizard_compare_account_balance_report
import wizard_invoice_state
import wizard_account_duplicate
import wizard_account_chart
import account_chart
import wizard_move_line_select
import wizard_validate_account_move
@ -64,5 +60,4 @@ import wizard_change_currency
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
import tools
class account_chart(osv.osv_memory):
"""
For Chart of Accounrs
"""
_name = "account.chart"
_description = "chart"
_columns = {
'fiscalyear': fields.many2one('account.fiscalyear', \
'Fiscal year', \
help = 'Keep empty for all open fiscal years'),
'target_move': fields.selection([
('all', 'All Entries'),
('posted', 'All Posted Entries'),
], 'Target Moves', required = True),
}
def _get_defaults(self, cr, uid, context={}):
"""Return default Fiscalyear value"""
fiscalyear_obj = self.pool.get('account.fiscalyear')
fiscalyear = fiscalyear_obj.find(cr, uid)
return fiscalyear
def account_chart_open_window(self, cr, uid, ids, context={}):
"""
Opens chart of Accounts
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of account charts IDs
@return: dictionary of Open account chart window on given fiscalyear and all Entries or posted entries
"""
mod_obj = self.pool.get('ir.model.data')
act_obj = self.pool.get('ir.actions.act_window')
for data in self.read(cr, uid, ids,context=context):
result = mod_obj._get_id(cr, uid, 'account', 'action_account_tree')
id = mod_obj.read(cr, uid, [result], ['res_id'],context=context)[0]['res_id']
result = act_obj.read(cr, uid, [id], context=context)[0]
result['context'] = str({'fiscalyear': data['fiscalyear'], \
'state': data['target_move']})
if data['fiscalyear']:
result['name'] += ':' + self.pool.get('account.fiscalyear').read(cr, uid, [data['fiscalyear']],context=context)[0]['code']
return result
_defaults = {
'fiscalyear': _get_defaults,
'target_move': lambda * a: 'all'
}
account_chart()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_account_chart" model="ir.ui.view">
<field name="name">account.chart.form</field>
<field name="model">account.chart</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Account charts">
<group colspan="4" >
<field name="fiscalyear"/>
<label align="0.7" colspan="6" string="(If you do not select Fiscal year it will take all open fiscal years)"/>
<field name="target_move"/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<label string ="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Cancel" />
<button icon="gtk-open" string="Open Charts"
name="account_chart_open_window" type="object" />
</group>
</form>
</field>
</record>
<record id="action_account_chart" model="ir.actions.act_window">
<field name="name">Chart of Accounts</field>
<field name="res_model">account.chart</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_account_chart"/>
<field name="target">new</field>
</record>
<menuitem icon="STOCK_INDENT" action="action_account_chart"
id="menu_action_account_tree2"
parent="account.menu_finance_charts" />
</data>
</openerp>

View File

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
import tools
class account_fiscalyear_close_state(osv.osv_memory):
"""
Closes Account Fiscalyear
"""
_name = "account.fiscalyear.close.state"
_description = "Fiscalyear Close state"
_columns = {
'fy_id': fields.many2one('account.fiscalyear', \
'Fiscal Year to close', required=True),
'sure': fields.boolean('Check this box', required=False)
}
def data_save(self, cr, uid, ids, context={}):
"""
This function close account fiscalyear
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Account fiscalyear close states IDs
"""
for data in self.read(cr, uid, ids,context=context):
if not data['sure']:
raise osv.except_osv(_('UserError'), _('Closing of states \
cancelled, please check the box !'))
fy_id = data['fy_id']
cr.execute('UPDATE account_journal_period ' \
'SET state = %s ' \
'WHERE period_id IN (SELECT id FROM account_period \
WHERE fiscalyear_id = %s)',
('done', fy_id))
cr.execute('UPDATE account_period SET state = %s ' \
'WHERE fiscalyear_id = %s', ('done', fy_id))
cr.execute('UPDATE account_fiscalyear ' \
'SET state = %s WHERE id = %s', ('done', fy_id))
return {}
account_fiscalyear_close_state()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_account_fiscalyear_close_state" model="ir.ui.view">
<field name="name">account.fiscalyear.close.state.form</field>
<field name="model">account.fiscalyear.close.state</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Close states of Fiscal year and periods">
<group colspan="4" >
<field name="fy_id" domain = "[('state','=','draft')]"/>
<separator string="Are you sure you want to close the fiscal year ?" colspan="4"/>
<field name="sure"/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<label string ="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-close" string="Close states" name="data_save" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_account_fiscalyear_close_state" model="ir.actions.act_window">
<field name="name">Close a Fiscal Year</field>
<field name="res_model">account.fiscalyear.close.state</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_account_fiscalyear_close_state"/>
<field name="target">new</field>
</record>
<menuitem action="action_account_fiscalyear_close_state"
id="menu_wizard_fy_close_state"
parent="menu_account_end_year_treatments" />
</data>
</openerp>

View File

@ -0,0 +1,191 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
import tools
import netsvc
class account_invoice_refund(osv.osv_memory):
"""Refunds invoice."""
_name = "account.invoice.refund"
_description = "Invoice Refund"
_columns = {
'date': fields.date('Operation date', required=False),
'period': fields.many2one('account.period', 'Force period', required=False),
'description': fields.char('Description', size=150, required=True),
}
def compute_refund(self, cr, uid, ids, mode, context={}):
"""
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: the account invoice refunds ID or list of IDs
"""
inv_obj = self.pool.get('account.invoice')
reconcile_obj = self.pool.get('account.move.reconcile')
account_m_line_obj = self.pool.get('account.move.line')
mod_obj = self.pool.get('ir.model.data')
act_obj = self.pool.get('ir.actions.act_window')
for form in self.read(cr, uid, ids,context=context):
created_inv = []
date = False
period = False
description = False
for inv in inv_obj.browse(cr, uid, context['active_ids'],context=context):
if inv.state in ['draft', 'proforma2', 'cancel']:
raise osv.except_osv(_('Error !'), _('Can not %s draft/proforma/cancel invoice.') % (mode))
if form['period'] :
period = form['period']
else:
period = inv.period_id and inv.period_id.id or False
if form['date'] :
date = form['date']
if not form['period'] :
cr.execute("select name from ir_model_fields \
where model = 'account.period' \
and name = 'company_id'")
result_query = cr.fetchone()
if result_query:
cr.execute("""SELECT id
from account_period where date('%s')
between date_start AND date_stop \
and company_id = %s limit 1 """,
(form['date'], self.pool.get('res.users').browse(cr, uid, uid,context=context).company_id.id,))
else:
cr.execute("""SELECT id
from account_period where date('%s')
between date_start AND date_stop \
limit 1 """, (form['date'],))
res = cr.fetchone()
if res:
period = res[0]
else:
date = inv.date_invoice
if form['description'] :
description = form['description']
else:
description = inv.name
if not period:
raise osv.except_osv(_('Data Insufficient !'), \
_('No Period found on Invoice!'))
refund_id = inv_obj.refund(cr, uid, [inv.id], date, period, description)
refund = inv_obj.browse(cr, uid, refund_id[0],context=context)
inv_obj.write(cr, uid, [refund.id], {'date_due': date,
'check_total': inv.check_total})
inv_obj.button_compute(cr, uid, refund_id)
created_inv.append(refund_id[0])
if mode in ('cancel', 'modify'):
movelines = inv.move_id.line_id
to_reconcile_ids = {}
for line in movelines :
if line.account_id.id == inv.account_id.id :
to_reconcile_ids[line.account_id.id] = [line.id]
if type(line.reconcile_id) != osv.orm.browse_null :
reconcile_obj.unlink(cr, uid, line.reconcile_id.id)
wf_service = netsvc.LocalService('workflow')
wf_service.trg_validate(uid, 'account.invoice', \
refund.id, 'invoice_open', cr)
refund = inv_obj.browse(cr, uid, refund_id[0],context=context)
for tmpline in refund.move_id.line_id :
if tmpline.account_id.id == inv.account_id.id :
to_reconcile_ids[tmpline.account_id.id].append(tmpline.id)
for account in to_reconcile_ids :
account_m_line_obj.reconcile(cr, uid, to_reconcile_ids[account],
writeoff_period_id=period,
writeoff_journal_id=inv.journal_id.id,
writeoff_acc_id=inv.account_id.id
)
if mode == 'modify' :
invoice = inv_obj.read(cr, uid, [inv.id],
['name', 'type', 'number', 'reference',
'comment', 'date_due', 'partner_id',
'address_contact_id', 'address_invoice_id',
'partner_insite', 'partner_contact',
'partner_ref', 'payment_term', 'account_id',
'currency_id', 'invoice_line', 'tax_line',
'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_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_obj._refund_cleanup_lines(cr, uid, tax_lines)
invoice.update({
'type': inv.type,
'date_invoice': date,
'state': 'draft',
'number': False,
'invoice_line': invoice_lines,
'tax_line': tax_lines,
'period_id': period,
'name': description
})
for field in ('address_contact_id', 'address_invoice_id', 'partner_id',
'account_id', 'currency_id', 'payment_term', 'journal_id'):
invoice[field] = invoice[field] and invoice[field][0]
inv_id = inv_obj.create(cr, uid, invoice, {})
if inv.payment_term.id:
data = inv_obj.onchange_payment_term_date_invoice(cr, uid, [inv_id], inv.payment_term.id, date)
if 'value' in data and data['value']:
inv_obj.write(cr, uid, [inv_id], data['value'])
created_inv.append(inv_id)
if inv.type == 'out_invoice':
xml_id = 'action_invoice_tree1'
elif inv.type == 'in_invoice':
xml_id = 'action_invoice_tree2'
elif type == 'out_refund':
xml_id = 'action_invoice_tree3'
else:
xml_id = 'action_invoice_tree4'
result = mod_obj._get_id(cr, uid, 'account', xml_id)
id = mod_obj.read(cr, uid, result, ['res_id'],context=context)['res_id']
result = act_obj.read(cr, uid, id,context=context)
result['res_id'] = created_inv
return result
def invoice_refund(self, cr, uid, ids, context={}):
return self.compute_refund(cr, uid, ids, 'refund', context=context)
def invoice_cancel(self, cr, uid, ids, context={}):
return self.compute_refund(cr, uid, ids, 'cancel', context=context)
def invoice_modify(self, cr, uid, ids, context={}):
return self.compute_refund(cr, uid, ids, 'modify', context=context)
account_invoice_refund()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_account_invoice_refund" model="ir.ui.view">
<field name="name">account.invoice.refund.form</field>
<field name="model">account.invoice.refund</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Credit Note">
<group colspan="4" >
<label string="Are you sure you want to refund this invoice ?" colspan="2"/>
<newline/>
<field name="date"/>
<field name="period"/>
<field name="description"/>
</group>
<separator string="" 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"/>
</group>
</form>
</field>
</record>
<record id="action_account_invoice_refund" model="ir.actions.act_window">
<field name="name">Credit Note</field>
<field name="res_model">account.invoice.refund</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_account_invoice_refund"/>
<field name="target">new</field>
</record>
<act_window id="action_account_invoice_refund"
key2 = "client_action_multi" name="Credit Note"
res_model="account.invoice.refund" src_model="account.invoice"
view_mode="form" target="new" view_type="form" />
</data>
</openerp>

View File

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import tools
from osv import fields, osv
from tools.translate import _
class account_move_bank_reconcile(osv.osv_memory):
"""
Bank Reconciliation
"""
_name = "account.move.bank.reconcile"
_description = "Move bank reconcile"
_columns = {
'journal_id': fields.many2one('account.journal', 'Journal', required=True),
}
def action_open_window(self, cr, uid, ids, context={}):
"""
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: account move bank reconciles ID or list of IDs
@return: dictionary of Open account move line on given journal_id.
"""
for data in self.read(cr, uid, ids,context=context):
cr.execute('select default_credit_account_id \
from account_journal where id=%s', (data['journal_id'],))
account_id = cr.fetchone()[0]
if not account_id:
raise osv.except_osv(_('Error'), _('You have to define \
the bank account\nin the journal definition for reconciliation.'))
return {
'domain': "[('journal_id','=',%d), ('account_id','=',%d), ('state','<>','draft')]" % (data['journal_id'], account_id),
'name': _('Standard Encoding'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.move.line',
'view_id': False,
'context': "{'journal_id': %d}" % (data['journal_id'],),
'type': 'ir.actions.act_window'
}
account_move_bank_reconcile()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_account_move_bank_reconcile" model="ir.ui.view">
<field name="name">account.move.bank.reconcile.form</field>
<field name="model">account.move.bank.reconcile</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Bank reconciliation">
<group colspan="4" >
<field name="journal_id"/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<label string ="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-open" string="Open for bank reconciliation" name="action_open_window" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_account_bank_reconcile_tree" model="ir.actions.act_window">
<field name="name">Bank reconciliation</field>
<field name="res_model">account.move.bank.reconcile</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_account_move_bank_reconcile"/>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
import tools
class account_move_journal(osv.osv_memory):
_name = "account.move.journal"
_description = "Move journal"
_columns = {
'journal_id': fields.many2one('account.journal', 'Journal', required=True),
'period_id': fields.many2one('account.period', 'Period', required=True),
}
def _get_period(self, cr, uid, context={}):
"""Return default account period value"""
ids = self.pool.get('account.period').find(cr, uid, context=context)
period_id = False
if len(ids):
period_id = ids[0]
return period_id
def action_open_window(self, cr, uid, ids, context={}):
"""
This function Open action move line window on given period and Journal/Payment Mode
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: account move journals ID or list of IDs
@return: dictionary of Open action move line window on given period and Journal/Payment Mode
"""
jp = self.pool.get('account.journal.period')
mod_obj = self.pool.get('ir.model.data')
for data in self.read(cr, uid, ids, ['journal_id', 'period_id'],context=context):
cr.execute('select id,name from ir_ui_view where model=%s and type=%s', ('account.move.line', 'form'))
view_res = cr.fetchone()
journal_id = data['journal_id']
period_id = data['period_id']
ids = jp.search(cr, uid, [('journal_id', '=', journal_id), \
('period_id', '=', period_id)],context=context)
if not len(ids):
name = self.pool.get('account.journal').read(cr, uid, [journal_id])[0]['name']
state = self.pool.get('account.period').read(cr, uid, [period_id])[0]['state']
if state == 'done':
raise osv.except_osv(_('UserError'), _('This period is already closed !'))
company = self.pool.get('account.period').read(cr, uid, [period_id])[0]['company_id'][0]
jp.create(cr, uid, {'name': name, 'period_id': period_id, 'journal_id': journal_id, 'company_id': company},context=context)
ids = jp.search(cr, uid, [('journal_id', '=', journal_id), ('period_id', '=', period_id)],context=context)
jp = jp.browse(cr, uid, ids, context=context)[0]
name = (jp.journal_id.code or '') + ':' + (jp.period_id.code or '')
result = mod_obj._get_id(cr, uid, 'account', 'view_account_move_line_filter')
res = mod_obj.read(cr, uid, result, ['res_id'],context=context)
return {
'domain': "[('journal_id','=',%d), ('period_id','=',%d)]" % (journal_id, period_id),
'name': name,
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.move.line',
'view_id': view_res,
'context': "{'journal_id': %d, 'period_id': %d}" % (journal_id, period_id),
'type': 'ir.actions.act_window',
'search_view_id': res['res_id']
}
_defaults = {
'period_id': _get_period
}
account_move_journal()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_account_move_journal_form" model="ir.ui.view">
<field name="name">account.move.journal.form</field>
<field name="model">account.move.journal</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Standard entries">
<group colspan="4" >
<field name="journal_id"/>
<newline/>
<field name="period_id" />
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<label string ="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-open" string="Open Journal" name="action_open_window" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_account_move_journal_line_form" model="ir.actions.act_window">
<field name="name">Entries by Line</field>
<field name="res_model">account.move.journal</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_account_move_journal_form"/>
<field name="target">new</field>
</record>
<menuitem icon="STOCK_JUSTIFY_FILL"
action="action_account_move_journal_line_form"
id="menu_action_move_journal_line_form"
parent="account.menu_finance_entries" sequence="5" />
</data>
</openerp>

View File

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
import tools
class account_move_line_reconcile_select(osv.osv_memory):
_name = "account.move.line.reconcile.select"
_description = "Move line reconcile select"
_columns = {
'account_id': fields.many2one('account.account', 'Account', \
domain = [('reconcile', '=', 1)], required=True),
}
def action_open_window(self, cr, uid, ids, context={}):
"""
This function Open account move line window for reconcile on given account id
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: account move line reconcile selects ID or list of IDs
@return: dictionary of Open account move line window for reconcile on given account id
"""
for data in self.read(cr, uid, ids,context=context):
return {
'domain': "[('account_id','=',%d),('reconcile_id','=',False),('state','<>','draft')]" % data['account_id'],
'name': _('Reconciliation'),
'view_type': 'form',
'view_mode': 'tree,form',
'view_id': False,
'res_model': 'account.move.line',
'type': 'ir.actions.act_window'
}
account_move_line_reconcile_select()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_account_move_line_reconcile_select" model="ir.ui.view">
<field name="name">account.move.line.reconcile.select.form</field>
<field name="model">account.move.line.reconcile.select</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Reconciliation">
<group colspan="4" >
<field name="account_id"/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<label string ="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Cancel" />
<button icon="gtk-open"
string="Open for reconciliation" name="action_open_window"
type="object" />
</group>
</form>
</field>
</record>
<record id="action_account_reconcile_select" model="ir.actions.act_window">
<field name="name">Reconcile entries</field>
<field name="res_model">account.move.line.reconcile.select</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_account_move_line_reconcile_select"/>
<field name="target">new</field>
</record>
<menuitem id="next_id_20" name="Reconciliation"
parent="menu_finance_periodical_processing" />
<menuitem action="action_account_reconcile_select"
id="menu_reconcile_select" parent="account.next_id_20" />
</data>
</openerp>

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
import tools
class account_move_line_unreconcile_select(osv.osv_memory):
_name = "account.move.line.unreconcile.select"
_description = "Unreconciliation"
_columns ={
'account_id': fields.many2one('account.account','Account',required=True),
}
def action_open_window(self, cr, uid, ids, context={}):
for data in self.read(cr, uid, ids):
return {
'domain': "[('account_id','=',%d),('reconcile_id','<>',False),('state','<>','draft')]" % data['account_id'],
'name': 'Unreconciliation',
'view_type': 'form',
'view_mode': 'tree,form',
'view_id': False,
'res_model': 'account.move.line',
'type': 'ir.actions.act_window'
}
account_move_line_unreconcile_select()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_account_move_line_unreconcile_select" model="ir.ui.view">
<field name="name">account.move.line.unreconcile.select.form</field>
<field name="model">account.move.line.unreconcile.select</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Unreconciliation">
<group colspan="4" >
<field name="account_id"/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<label string ="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Cancel" />
<button icon="gtk-open"
string="Open for Unreconciliation" name="action_open_window"
type="object" />
</group>
</form>
</field>
</record>
<record id="action_account_unreconcile_select" model="ir.actions.act_window">
<field name="name">Unreconcile entries</field>
<field name="res_model">account.move.line.unreconcile.select</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_account_move_line_unreconcile_select"/>
<field name="target">new</field>
</record>
<menuitem action="action_account_unreconcile_select"
id="menu_unreconcile_select" parent="account.next_id_20" />
</data>
</openerp>

View File

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
import tools
class account_period_close(osv.osv_memory):
"""
close period
"""
_name = "account.period.close"
_description = "period close"
_columns = {
'sure': fields.boolean('Check this box', required=False),
}
def data_save(self, cr, uid, ids, context={}):
"""
This function close period
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: account period closes ID or list of IDs
"""
mode = 'done'
for form in self.read(cr, uid, ids,context=context):
if form['sure']:
for id in context['active_ids']:
cr.execute('update account_journal_period set state=%s where period_id=%s', (mode, id))
cr.execute('update account_period set state=%s where id=%s', (mode, id))
return {}
account_period_close()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_account_period_close" model="ir.ui.view">
<field name="name">account.period.close.form</field>
<field name="model">account.period.close</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Close Period">
<group colspan="4" >
<separator string="Are you sure ?" colspan="4"/>
<field name="sure"/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<label string ="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-close" string="Close Period" name="data_save" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_account_period_close" model="ir.actions.act_window">
<field name="name">Close a Period</field>
<field name="res_model">account.period.close</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_account_period_close"/>
<field name="target">new</field>
</record>
<record id="action_idea_post_vote_values" model="ir.values">
<field name="model_id" ref="model_account_period" />
<field name="object" eval="1" />
<field name="name"></field>
<field name="key2">client_action_multi</field>
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_account_period_close'))"/>
<field name="key">action</field>
<field name="model">account.period</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import time
from osv import fields, osv
class account_subscription_generate(osv.osv_memory):
_name = "account.subscription.generate"
_description = "Subscription Compute"
_columns = {
'date': fields.date('Date', required=True),
}
_defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d'),
}
def action_generate(self, cr, uid, ids, context={}):
for data in self.read(cr, uid, ids, context=context):
cr.execute('select id from account_subscription_line where date<%s and move_id is null', (data['date'],))
ids = map(lambda x: x[0], cr.fetchall())
self.pool.get('account.subscription.line').move_create(cr, uid, ids, context=context)
return {}
account_subscription_generate()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_account_subscription_generate" model="ir.ui.view">
<field name="name">account.subscription.generate.form</field>
<field name="model">account.subscription.generate</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Subscription Compute">
<group colspan="4" >
<separator string="Generate entries before:" colspan="4"/>
<field name="date"/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<label string ="" colspan="2"/>
<button icon="gtk-cancel" special="cancel" string="Cancel" />
<button icon="gtk-execute" string="Compute Entry Dates"
name="action_generate" type="object" />
</group>
</form>
</field>
</record>
<record id="action_account_subscription_generate" model="ir.actions.act_window">
<field name="name">Create Subscription Entries</field>
<field name="res_model">account.subscription.generate</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_account_subscription_generate"/>
<field name="target">new</field>
</record>
<menuitem action="action_account_subscription_generate" id="menu_generate_subscription" parent="account.menu_finance_periodical_processing" />
</data>
</openerp>

View File

@ -1,80 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
import pooler
class wizard_account_chart(wizard.interface):
_account_chart_arch = '''<?xml version="1.0"?>
<form string="Open account charts">
<field name="fiscalyear"/>
<label align="0.7" colspan="6" string="(If you do not select Fiscal year it will take all open fiscal years)"/>
<field name="target_move"/>
</form>'''
_account_chart_fields = {
'fiscalyear': {
'string': 'Fiscal year',
'type': 'many2one',
'relation': 'account.fiscalyear',
'help': 'Keep empty for all open fiscal years',
},
'target_move': {
'string': 'Target Moves',
'type': 'selection',
'selection': [('all','All Entries'),('posted','All Posted Entries')],
'required': True,
'default': lambda *a:"all",
},
}
def _get_defaults(self, cr, uid, data, context):
fiscalyear_obj = pooler.get_pool(cr.dbname).get('account.fiscalyear')
data['form']['fiscalyear'] = fiscalyear_obj.find(cr, uid)
return data['form']
def _account_chart_open_window(self, cr, uid, data, context):
mod_obj = pooler.get_pool(cr.dbname).get('ir.model.data')
act_obj = pooler.get_pool(cr.dbname).get('ir.actions.act_window')
result = mod_obj._get_id(cr, uid, 'account', 'action_account_tree')
id = mod_obj.read(cr, uid, [result], ['res_id'])[0]['res_id']
result = act_obj.read(cr, uid, [id], context=context)[0]
result['context'] = str({'fiscalyear': data['form']['fiscalyear'],'state':data['form']['target_move']})
if data['form']['fiscalyear']:
result['name']+=':'+pooler.get_pool(cr.dbname).get('account.fiscalyear').read(cr,uid,[data['form']['fiscalyear']])[0]['code']
return result
states = {
'init': {
'actions': [_get_defaults],
'result': {'type': 'form', 'arch':_account_chart_arch, 'fields':_account_chart_fields, 'state': [('end', 'Cancel', 'gtk-cancel'), ('open', 'Open', 'gtk-ok')]}
},
'open': {
'actions': [],
'result': {'type': 'action', 'action':_account_chart_open_window, 'state':'end'}
}
}
wizard_account_chart('account.chart')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,67 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
from tools.translate import _
_journal_form = '''<?xml version="1.0"?>
<form string="%s">
<field name="journal_id"/>
</form>''' % ('Open Bank reconciliation',)
_journal_fields = {
'journal_id': {'string':'Journal', 'type':'many2one', 'relation':'account.journal', 'required':True},
}
def _action_open_window(self, cr, uid, data, context):
form = data['form']
cr.execute('select default_credit_account_id from account_journal where id=%s', (form['journal_id'],))
account_id = cr.fetchone()[0]
if not account_id:
raise wizard.except_wizard(_('Error'), _('You have to define the bank account\nin the journal definition for reconciliation.'))
return {
'domain': "[('journal_id','=',%d), ('account_id','=',%d), ('state','<>','draft')]" % (form['journal_id'],account_id),
'name': _('Standard Encoding'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.move.line',
'view_id': False,
'context': "{'journal_id':%d}" % (form['journal_id'],),
'type': 'ir.actions.act_window'
}
class wiz_journal(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':_journal_form, 'fields':_journal_fields, 'state':[('end','Cancel', 'gtk-cancel'),('open','Open', 'gtk-ok')]}
},
'open': {
'actions': [],
'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
}
}
wiz_journal('account.move.bank.reconcile')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,71 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
import osv
import pooler
from tools.translate import _
_transaction_form = '''<?xml version="1.0"?>
<form string=" Close states of Fiscal year and periods">
<field name="fy_id"/>
<separator string="Are you sure you want to close the fiscal year ?" colspan="4"/>
<field name="sure"/>
</form>'''
_transaction_fields = {
'fy_id': {'string':'Fiscal Year to close', 'type':'many2one', 'relation': 'account.fiscalyear','required':True, 'domain':[('state','=','draft')]},
'sure': {'string':'Check this box', 'type':'boolean'},
}
def _data_save(self, cr, uid, data, context):
if not data['form']['sure']:
raise wizard.except_wizard(_('UserError'), _('Closing of states cancelled, please check the box !'))
pool = pooler.get_pool(cr.dbname)
fy_id = data['form']['fy_id']
cr.execute('UPDATE account_journal_period ' \
'SET state = %s ' \
'WHERE period_id IN (SELECT id FROM account_period WHERE fiscalyear_id = %s)',
('done',fy_id))
cr.execute('UPDATE account_period SET state = %s ' \
'WHERE fiscalyear_id = %s', ('done',fy_id))
cr.execute('UPDATE account_fiscalyear ' \
'SET state = %s WHERE id = %s', ('done', fy_id))
return {}
class wiz_journal_close_state(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':_transaction_form, 'fields':_transaction_fields, 'state':[('end','Cancel', 'gtk-cancel'),('close','Close states', 'gtk-ok')]}
},
'close': {
'actions': [_data_save],
'result': {'type': 'state', 'state':'end'}
}
}
wiz_journal_close_state('account.fiscalyear.close.state')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,99 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
from osv import osv
import pooler
from tools.translate import _
_journal_form = '''<?xml version="1.0"?>
<form string="Standard entries">
<field name="journal_id"/>
<newline/>
<field name="period_id"/>
</form>'''
def _period_get(self, cr, uid, datas, ctx={}):
try:
pool = pooler.get_pool(cr.dbname)
ids = pool.get('account.period').find(cr, uid, context=ctx)
return {'period_id': ids[0]}
except:
return {}
_journal_fields = {
'journal_id': {'string':'Journal', 'type':'many2one', 'relation':'account.journal', 'required':True},
'period_id': {
'string':'Period',
'type':'many2one',
'relation':'account.period',
'required':True,
}
}
def _action_open_window(self, cr, uid, data, context):
form = data['form']
cr.execute('select id,name from ir_ui_view where model=%s and type=%s', ('account.move.line', 'form'))
view_res = cr.fetchone()
jp = pooler.get_pool(cr.dbname).get('account.journal.period')
ids = jp.search(cr, uid, [('journal_id','=',form['journal_id']), ('period_id','=',form['period_id'])])
if not len(ids):
name = pooler.get_pool(cr.dbname).get('account.journal').read(cr, uid, [form['journal_id']])[0]['name']
state = pooler.get_pool(cr.dbname).get('account.period').read(cr, uid, [form['period_id']])[0]['state']
if state == 'done':
raise wizard.except_wizard(_('UserError'), _('This period is already closed !'))
company = pooler.get_pool(cr.dbname).get('account.period').read(cr, uid, [form['period_id']])[0]['company_id'][0]
jp.create(cr, uid, {'name':name, 'period_id': form['period_id'], 'journal_id':form['journal_id'], 'company_id':company})
ids = jp.search(cr, uid, [('journal_id','=',form['journal_id']), ('period_id','=',form['period_id'])])
jp = jp.browse(cr, uid, ids, context=context)[0]
name = (jp.journal_id.code or '') + ':' + (jp.period_id.code or '')
mod_obj = pooler.get_pool(cr.dbname).get('ir.model.data')
result = mod_obj._get_id(cr, uid, 'account', 'view_account_move_line_filter')
id = mod_obj.read(cr, uid, result, ['res_id'])
return {
'domain': "[('journal_id','=',%d), ('period_id','=',%d)]" % (form['journal_id'],form['period_id']),
'name': name,
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.move.line',
'view_id': view_res,
'context': "{'journal_id':%d, 'period_id':%d}" % (form['journal_id'],form['period_id']),
'type': 'ir.actions.act_window',
'search_view_id': id['res_id']
}
class wiz_journal(wizard.interface):
states = {
'init': {
'actions': [_period_get],
'result': {'type': 'form', 'arch':_journal_form, 'fields':_journal_fields, 'state':[('end','Cancel', 'gtk-cancel'),('open','Open Journal', 'gtk-ok')]}
},
'open': {
'actions': [],
'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
}
}
wiz_journal('account.move.journal')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,61 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
from tools.translate import _
_journal_form = '''<?xml version="1.0"?>
<form string="%s">
<field name="account_id"/>
</form>''' % ('Reconciliation',)
_journal_fields = {
'account_id': {'string':'Account', 'type':'many2one', 'relation':'account.account','domain': [('reconcile','=',1)], 'required':True},
}
def _action_open_window(self, cr, uid, data, context):
return {
'domain': "[('account_id','=',%d),('reconcile_id','=',False),('state','<>','draft')]" % data['form']['account_id'],
'name': _('Reconciliation'),
'view_type': 'form',
'view_mode': 'tree,form',
'view_id': False,
'res_model': 'account.move.line',
'type': 'ir.actions.act_window'
}
class wiz_rec_select(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':_journal_form, 'fields':_journal_fields, 'state':[('end','Cancel'),('open','Open for reconciliation')]}
},
'open': {
'actions': [],
'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
}
}
wiz_rec_select('account.move.line.reconcile.select')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,226 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
import pooler
import osv
import netsvc
import time
from tools.translate import _
sur_form = '''<?xml version="1.0"?>
<form string="Credit Note">
<label string="Are you sure you want to refund this invoice ?" colspan="2"/>
<newline />
<field name="date" />
<field name="period" />
<field name="description" width="150" />
</form>'''
sur_fields = {
'date': {'string':'Operation date','type':'date', 'required':'False'},
'period':{'string': 'Force period', 'type': 'many2one',
'relation': 'account.period', 'required': False},
'description':{'string':'Description', 'type':'char', 'required':'True'},
}
class wiz_refund(wizard.interface):
def _invoice_refund(self, cr, uid, data, context):
return self._compute_refund(cr, uid, data, 'refund', context)
def _invoice_cancel(self, cr, uid, data, context):
return self._compute_refund(cr, uid, data, 'cancel', context)
def _invoice_modify(self, cr, uid, data, context):
return self._compute_refund(cr, uid, data, 'modify', context)
def _compute_refund(self, cr, uid, data, mode, context):
form = data['form']
pool = pooler.get_pool(cr.dbname)
reconcile_obj = pool.get('account.move.reconcile')
account_m_line_obj = pool.get('account.move.line')
created_inv = []
date = False
period = False
description = False
for inv in pool.get('account.invoice').browse(cr, uid, data['ids']):
if inv.state in ['draft', 'proforma2', 'cancel']:
raise wizard.except_wizard(_('Error !'), _('Can not %s draft/proforma/cancel invoice.') % (mode))
if form['period'] :
period = form['period']
else:
period = inv.period_id and inv.period_id.id or False
if form['date'] :
date = form['date']
if not form['period'] :
cr.execute("select name from ir_model_fields where model='account.period' and name='company_id'")
result_query = cr.fetchone()
if result_query:
#in multi company mode
cr.execute("""SELECT id
from account_period where date('%s')
between date_start AND date_stop and company_id = %s limit 1 """,
(form['date'],pool.get('res.users').browse(cr,uid,uid).company_id.id,))
else:
#in mono company mode
cr.execute("""SELECT id
from account_period where date('%s')
between date_start AND date_stop limit 1 """,
(form['date'],))
res = cr.fetchone()
if res:
period = res[0]
else:
date = inv.date_invoice
if form['description'] :
description = form['description']
else:
description = inv.name
if not period:
raise wizard.except_wizard(_('Data Insufficient !'), _('No Period found on Invoice!'))
refund_id = pool.get('account.invoice').refund(cr, uid, [inv.id],date, period, description)
refund = pool.get('account.invoice').browse(cr, uid, refund_id[0])
# we compute due date
#!!!due date = date inv date on formdate
pool.get('account.invoice').write(cr, uid, [refund.id],{'date_due':date,'check_total':inv.check_total})
# to make the taxes calculated
pool.get('account.invoice').button_compute(cr, uid, refund_id)
created_inv.append(refund_id[0])
#if inv is paid we unreconcile
if mode in ('cancel','modify'):
movelines = inv.move_id.line_id
#we unreconcile the lines
to_reconcile_ids = {}
for line in movelines :
#if the account of the line is the as the one in the invoice
#we reconcile
if line.account_id.id == inv.account_id.id :
to_reconcile_ids[line.account_id.id] =[line.id]
if type(line.reconcile_id) != osv.orm.browse_null :
reconcile_obj.unlink(cr,uid, line.reconcile_id.id)
#we advance the workflow of the refund to open
wf_service = netsvc.LocalService('workflow')
wf_service.trg_validate(uid, 'account.invoice', refund.id, 'invoice_open', cr)
#we reload the browse record
refund = pool.get('account.invoice').browse(cr, uid, refund_id[0])
#we match the line to reconcile
for tmpline in refund.move_id.line_id :
if tmpline.account_id.id == inv.account_id.id :
to_reconcile_ids[tmpline.account_id.id].append(tmpline.id)
for account in to_reconcile_ids :
account_m_line_obj.reconcile(cr, uid, to_reconcile_ids[account],
writeoff_period_id=period,
writeoff_journal_id=inv.journal_id.id,
writeoff_acc_id=inv.account_id.id
)
#we create a new invoice that is the copy of the original
if mode == 'modify' :
invoice = pool.get('account.invoice').read(cr, uid, [inv.id],
['name', 'type', 'number', 'reference',
'comment', 'date_due', 'partner_id', 'address_contact_id',
'address_invoice_id', 'partner_insite','partner_contact',
'partner_ref', 'payment_term', 'account_id', 'currency_id',
'invoice_line', 'tax_line', 'journal_id','period_id'
]
)
invoice = invoice[0]
del invoice['id']
invoice_lines = pool.get('account.invoice.line').read(cr, uid, invoice['invoice_line'])
invoice_lines = pool.get('account.invoice')._refund_cleanup_lines(cr, uid, invoice_lines)
tax_lines = pool.get('account.invoice.tax').read(
cr, uid, invoice['tax_line'])
tax_lines = pool.get('account.invoice')._refund_cleanup_lines(cr, uid, tax_lines)
invoice.update({
'type': inv.type,
'date_invoice': date,
'state': 'draft',
'number': False,
'invoice_line': invoice_lines,
'tax_line': tax_lines,
'period_id': period,
'name':description
})
#take the id part of the tuple returned for many2one fields
for field in ('address_contact_id', 'address_invoice_id', 'partner_id',
'account_id', 'currency_id', 'payment_term', 'journal_id'):
invoice[field] = invoice[field] and invoice[field][0]
# create the new invoice
inv_id = pool.get('account.invoice').create(cr, uid, invoice,{})
# we compute due date
if inv.payment_term.id:
data = pool.get('account.invoice').onchange_payment_term_date_invoice(cr, uid, [inv_id],inv.payment_term.id,date)
if 'value' in data and data['value']:
pool.get('account.invoice').write(cr, uid, [inv_id],data['value'])
created_inv.append(inv_id)
#we get the view id
mod_obj = pool.get('ir.model.data')
act_obj = pool.get('ir.actions.act_window')
if inv.type == 'out_invoice':
xml_id = 'action_invoice_tree5'
elif inv.type == 'in_invoice':
xml_id = 'action_invoice_tree8'
elif type == 'out_refund':
xml_id = 'action_invoice_tree10'
else:
xml_id = 'action_invoice_tree12'
#we get the model
result = mod_obj._get_id(cr, uid, 'account', xml_id)
id = mod_obj.read(cr, uid, result, ['res_id'])['res_id']
# we read the act window
result = act_obj.read(cr, uid, id)
result['res_id'] = created_inv
return result
states = {
'init': {
'actions': [],
'result': {'type':'form', 'arch':sur_form, 'fields':sur_fields, 'state':[('end','Cancel'),('refund','Refund Invoice'),('cancel_invoice','Cancel Invoice'),('modify_invoice','Modify Invoice')]}
},
'refund': {
'actions': [],
'result': {'type':'action', 'action':_invoice_refund, 'state':'end'},
},
'cancel_invoice': {
'actions': [],
'result': {'type':'action', 'action':_invoice_cancel, 'state':'end'},
},
'modify_invoice': {
'actions': [],
'result': {'type':'action', 'action':_invoice_modify, 'state':'end'},
},
}
wiz_refund('account.invoice.refund')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,61 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import time
import wizard
import pooler
#
# TODO: add an intermediate screen for checks
#
_subscription_form = '''<?xml version="1.0"?>
<form string="%s">
<separator string="Generate entries before:" colspan="4"/>
<field name="date"/>
</form>''' % ('Subscription Compute',)
_subscription_fields = {
'date': {'string':'Date', 'type':'date', 'default':lambda *a: time.strftime('%Y-%m-%d'), 'required':True},
}
class wiz_subscription(wizard.interface):
def _action_generate(self, cr, uid, data, context={}):
cr.execute('select id from account_subscription_line where date<%s and move_id is null', (data['form']['date'],))
ids = map(lambda x: x[0], cr.fetchall())
pooler.get_pool(cr.dbname).get('account.subscription.line').move_create(cr, uid, ids)
return {}
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':_subscription_form, 'fields':_subscription_fields, 'state':[('end','Cancel', 'gtk-cancel'),('generate','Compute', 'gtk-ok')]}
},
'generate': {
'actions': [_action_generate],
'result': {'type': 'state', 'state':'end'}
}
}
wiz_subscription('account.subscription.generate')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,59 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
_journal_form = '''<?xml version="1.0"?>
<form string="%s">
<field name="account_id"/>
</form>''' % ('Unreconciliation',)
_journal_fields = {
'account_id': {'string':'Account', 'type':'many2one', 'relation':'account.account', 'required':True},
}
def _action_open_window(self, cr, uid, data, context):
return {
'domain': "[('account_id','=',%d),('reconcile_id','<>',False),('state','<>','draft')]" % data['form']['account_id'],
'name': 'Unreconciliation',
'view_type': 'form',
'view_mode': 'tree,form',
'view_id': False,
'res_model': 'account.move.line',
'type': 'ir.actions.act_window'
}
class wiz_unrec_select(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':_journal_form, 'fields':_journal_fields, 'state':[('end','Cancel', 'gtk-cancel'),('open','Open for unreconciliation', 'gtk-ok')]}
},
'open': {
'actions': [],
'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
}
}
wiz_unrec_select('account.move.line.unreconcile.select')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -38,6 +38,8 @@
'init_xml': ['auction_sequence.xml'],
'update_xml': [
'security/ir.model.access.csv',
# 'wizard/auction_lots_cancel_view.xml',
# 'wizard/auction_transfer_unsold_object_view.xml',
'wizard/auction_lots_able_view.xml',
'wizard/auction_lots_enable_view.xml',
'wizard/auction_lots_make_invoice_buyer_view.xml',

View File

@ -95,15 +95,17 @@ class auction_dates(osv.osv):
RETURN: True
"""
# objects vendus mais non factures
#TODO: convert this query to tiny API
lots_obj = self.pool.get('auction.lots')
cr.execute('select count(*) as c from auction_lots where auction_id =ANY(%s) and state=%s and obj_price>0', (ids,'draft',))
nbr = cr.fetchone()[0]
ach_uids = {}
cr.execute('select id from auction_lots where auction_id =ANY(%s) and state=%s and obj_price>0', (ids,'draft',))
r=self.pool.get('auction.lots').lots_invoice(cr, uid, [x[0] for x in cr.fetchall()],{},None)
r = lots_obj.lots_invoice(cr, uid, [x[0] for x in cr.fetchall()],{},None)
cr.execute('select id from auction_lots where auction_id =ANY(%s) and obj_price>0',(ids,))
ids2 = [x[0] for x in cr.fetchall()]
# for auction in auction_ids:
c=self.pool.get('auction.lots').seller_trans_create(cr, uid, ids2,{})
c = lots_obj.seller_trans_create(cr, uid, ids2,{})
self.write(cr, uid, ids, {'state':'closed'}) #close the auction
return True
auction_dates()
@ -508,14 +510,14 @@ class auction_lots(osv.osv):
##CHECKME: est-ce que ca vaudrait la peine de faire des groupes de lots qui ont les memes couts pour passer des listes de lots a compute?
taxes = []
amount=0.0
# pt_tax=pool.get('account.tax')
pt_tax = self.pool.get('account.tax')
for lot in lots:
taxes = lot.product_id.taxes_id
if lot.author_right:
taxes.append(lot.author_right)
elif lot.auction_id:
taxes += lot.auction_id.buyer_costs
tax=self.pool.get('account.tax').compute(cr,uid,taxes,lot.obj_price,1)
tax=pt_tax.compute(cr,uid,taxes,lot.obj_price,1)
for t in tax:
amount+=t['amount']
#amount+=lot.obj_price*0.2
@ -630,18 +632,20 @@ class auction_lots(osv.osv):
def buyer_proforma(self,cr,uid,ids,context):
invoices = {}
inv_ref=self.pool.get('account.invoice')
inv_ref = self.pool.get('account.invoice')
partner_r = self.pool.get('res.partner')
inv_line_obj = self.pool.get('account.invoice.line')
wf_service = netsvc.LocalService('workflow')
# acc_receiv=self.pool.get('account.account').search([cr,uid,[('code','=','4010')]])
for lot in self.browse(cr,uid,ids,context):
if not lot.obj_price>0:
continue
partner_r=self.pool.get('res.partner')
if not lot.ach_uid.id:
raise orm.except_orm(_('Missed buyer !'), _('The object "%s" has no buyer assigned.') % (lot.name,))
else:
partner_ref =lot.ach_uid.id
lot_name = lot.obj_num
res = self.pool.get('res.partner').address_get(cr, uid, [partner_ref], ['contact', 'invoice'])
res = partner_r.address_get(cr, uid, [partner_ref], ['contact', 'invoice'])
contact_addr_id = res['contact']
invoice_addr_id = res['invoice']
if not invoice_addr_id:
@ -675,12 +679,11 @@ class auction_lots(osv.osv):
'account_id': lot.auction_id.acc_income.id,
'price_unit': lot.obj_price,
}
self.pool.get('account.invoice.line').create(cr, uid, inv_line,context)
inv_line_obj.create(cr, uid, inv_line,context)
# inv_ref.button_compute(cr, uid, [inv_id])
# wf_service = netsvc.LocalService('workflow')
# wf_service.trg_validate(uid, 'account.invoice', inv_id, 'invoice_open', cr)
inv_ref.button_compute(cr, uid, invoice.values())
wf_service = netsvc.LocalService('workflow')
wf_service.trg_validate(uid, 'account.invoice', inv_id, 'invoice_proforma', cr)
return invoices.values()
@ -694,6 +697,9 @@ class auction_lots(osv.osv):
# use each list of object in turn
invoices = {}
inv_ref=self.pool.get('account.invoice')
partner_obj = self.pool.get('res.partner')
inv_line_obj = self.pool.get('account.invoice.line')
wf_service = netsvc.LocalService('workflow')
for lot in self.browse(cr,uid,ids,context):
partner_id = lot.bord_vnd_id.partner_id.id
if not lot.auction_id.id:
@ -702,7 +708,7 @@ class auction_lots(osv.osv):
if lot.bord_vnd_id.id in invoices:
inv_id = invoices[lot.bord_vnd_id.id]
else:
res = self.pool.get('res.partner').address_get(cr, uid, [lot.bord_vnd_id.partner_id.id], ['contact', 'invoice'])
res = partner_obj.address_get(cr, uid, [lot.bord_vnd_id.partner_id.id], ['contact', 'invoice'])
contact_addr_id = res['contact']
invoice_addr_id = res['invoice']
inv = {
@ -734,13 +740,12 @@ class auction_lots(osv.osv):
'account_id': lot.auction_id.acc_expense.id,
'price_unit': lot.obj_price,
}
self.pool.get('account.invoice.line').create(cr, uid, inv_line,context)
inv_line_obj.create(cr, uid, inv_line,context)
inv_ref.button_compute(cr, uid, invoices.values())
for inv in inv_ref.browse(cr, uid, invoices.values(), context):
inv_ref.write(cr, uid, [inv.id], {
'check_total': inv.amount_total
})
wf_service = netsvc.LocalService('workflow')
wf_service.trg_validate(uid, 'account.invoice', inv.id, 'invoice_open', cr)
return invoices.values()
@ -756,13 +761,15 @@ class auction_lots(osv.osv):
RETURN: id of generated invoice
"""
dt = time.strftime('%Y-%m-%d')
inv_ref=self.pool.get('account.invoice')
inv_ref = self.pool.get('account.invoice')
partner_r = self.pool.get('res.partner')
inv_line_obj = self.pool.get('account.invoice.line')
wf_service = netsvc.LocalService('workflow')
invoices={}
for lot in self.browse(cr, uid, ids,context):
# partner_ref = lot.ach_uid.id
if not lot.auction_id.id:
continue
partner_r=self.pool.get('res.partner')
if not lot.ach_uid.id:
raise orm.except_orm(_('Missed buyer !'), _('The object "%s" has no buyer assigned.') % (lot.name,))
if (lot.auction_id.id,lot.ach_uid.id) in invoices:
@ -773,13 +780,12 @@ class auction_lots(osv.osv):
raise orm.except_orm(_('Missed Address !'), _('The Buyer has no Invoice Address.'))
price = lot.obj_price or 0.0
lot_name =lot.obj_num
inv={
inv = {
'name':lot.auction_id.name or '',
'reference': lot.ach_login,
'journal_id': lot.auction_id.journal_id.id,
'partner_id': lot.ach_uid.id,
'type': 'out_invoice',
}
if invoice_number:
inv['number'] = invoice_number
@ -804,12 +810,11 @@ class auction_lots(osv.osv):
'account_id': lot.auction_id.acc_income.id,
'price_unit': lot.obj_price,
}
self.pool.get('account.invoice.line').create(cr, uid, inv_line,context)
inv_line_obj.create(cr, uid, inv_line,context)
# inv_ref.button_compute(cr, uid, [inpq tu dis cav_id])
# inv_ref.button_compute(cr, uid, [inv_id])
inv_ref.button_compute(cr, uid, [inv_id])
for l in inv_ref.browse(cr, uid, invoices.values(), context):
wf_service = netsvc.LocalService('workflow')
# wf_service.trg_validate(uid, 'account.invoice',l.id, 'invoice_proforma', cr)
wf_service.trg_validate(uid, 'account.invoice',l.id, 'invoice_open', cr)
return invoices.values()

View File

@ -29,7 +29,8 @@ import auction_pay_buy
import auction_payer_sel
import auction_lots_sms_send
import auction_catalog_flagey_report
#import auction_lots_cancel
#import auction_transfer_unsold_object
#import auction_aie_send_result
import auction_lots_buyer_map

View File

@ -40,9 +40,21 @@ class auction_catalog_flagey(osv.osv_memory):
return res
def view_init(self, cr, uid, fields, context):
current_auction = self.pool.get('auction.dates').browse(cr,uid,context.get('active_ids', []))
v_lots = self.pool.get('auction.lots').search(cr,uid,[('auction_id','=',current_auction.id)])
v_ids = self.pool.get('auction.lots').browse(cr,uid,v_lots)
"""
Creates view dynamically, adding fields at runtime, raises exception
at the time of initialization of view.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: New arch of view with new columns.
"""
lots_obj = self.pool.get('auction.lots')
auc_dates_obj = self.pool.get('auction.dates')
current_auction = auc_dates_obj.browse(cr,uid,context.get('active_ids', []))
v_lots = lots_obj.search(cr,uid,[('auction_id','=',current_auction.id)])
v_ids = lots_obj.browse(cr,uid,v_lots)
for ab in v_ids:
if not ab.auction_id :
raise osv.except_osv('Error!','No Lots belong to this Auction Date')

View File

@ -32,16 +32,16 @@ class auction_lots_auction_move(osv.osv_memory):
_name = "auction.lots.auction.move"
_description = "Auction move "
_columns= {
'auction_id':fields.many2one('auction.dates', 'Auction Date', required=True),
}
'auction_id':fields.many2one('auction.dates', 'Auction Date', required=True),
}
def _top(self, cr, uid, ids, context={}):
refs = self.pool.get('auction.lots')
rec_ids = refs.browse(cr, uid, context['active_ids'])
for rec in rec_ids:
if not rec.auction_id:
raise osv.except_osv('Error !', 'You can not move a lot that has no auction date')
return {}
# def _top(self, cr, uid, ids, context={}):
# refs = self.pool.get('auction.lots')
# rec_ids = refs.browse(cr, uid, context['active_ids'])
# for rec in rec_ids:
# if not rec.auction_id:
# raise osv.except_osv('Error !', 'You can not move a lot that has no auction date')
# return {}
def auction_move_set(self, cr, uid, ids, context={}):
"""
@ -56,13 +56,13 @@ class auction_lots_auction_move(osv.osv_memory):
auction_bid_line_obj = self.pool.get('auction.bid_line')
auction_lot_history_obj = self.pool.get('auction.lot.history')
auction_lots_obj = self.pool.get('auction.lots')
rec_ids = refs.browse(cr, uid, context['active_ids'])
for datas in self.read(cr, uid, ids):
if not (datas['auction_id'] and len(context['active_ids'])) :
return {}
rec_ids = refs.browse(cr, uid, context['active_ids'])
line_ids = auction_bid_line_obj.search(cr, uid, [('lot_id', 'in', context['active_ids'])])
# pooler.get_pool(cr.dbname).get('auction.bid_line').unlink(cr, uid, line_ids)
# line_ids = auction_bid_line_obj.search(cr, uid, [('lot_id', 'in', context['active_ids'])])
# pooler.get_pool(cr.dbname).get('auction.bid_line').unlink(cr, uid, line_ids)
for rec in rec_ids:
new_id = auction_lot_history_obj.create(cr, uid, {
'auction_id': rec.auction_id.id,

View File

@ -107,18 +107,21 @@ class wiz_auc_lots_buyer_map(osv.osv_memory):
res = super(wiz_auc_lots_buyer_map, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False)
lots_obj = self.pool.get('auction.lots')
if record_ids:
for lots in lots_obj.browse(cr, uid, record_ids):
if lots.ach_uid:
res['arch'] = """
<form title="Mapping Result">
<group col="2" colspan="2">
<label string="All objects are assigned to buyers !"/>
<newline/>
<button icon='gtk-cancel' special="cancel"
string="Done" />
</group>
</form>
"""
try:
for lots in lots_obj.browse(cr, uid, record_ids):
if lots.ach_uid:
res['arch'] = """
<form title="Mapping Result">
<group col="2" colspan="2">
<label string="All objects are assigned to buyers !"/>
<newline/>
<button icon='gtk-cancel' special="cancel"
string="Done" />
</group>
</form>
"""
except:
return res
return res
wiz_auc_lots_buyer_map()

View File

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv
from osv import fields
class auction_lots_cancel(osv.osv):
'''
Open ERP Model
'''
_name = 'auction.lots.cancel'
_description = 'To cancel auction lots.'
def cancel(self, cr, uid, ids, context):
"""
To cancel the auction lot
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return:
"""
lots_obj = self.pool.get('auction.lots')
invoice_obj = self.pool.get('account.invoice')
lot = lots_obj.browse(cr,uid,context['active_id'],context)
if lot.ach_inv_id:
supplier_refund_inv_id = invoice_obj.refund(cr, uid,[lot.ach_inv_id.id])
if lot.sel_inv_id:
customer_refund_inv_id = invoice_obj.refund(cr, uid,[lot.sel_inv_id.id])
return {}
_columns = {
}
auction_lots_cancel()

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="name_form" model="ir.ui.view">
<field name="name">auction.lots.cancel.form</field>
<field name="model">auction.lots.cancel</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Cancel Payment">
<label string="Are you sure you want to refund this invoice ?"/>
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="cancel" string="Cancel Payment"
colspan="1" type="object" icon="gtk-ok" />
</form>
</field>
</record>
<act_window name="Cancel ittttttt"
res_model="auction.lots.cancel"
src_model="auction.lots"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_auction_lots_cancel"/>
</data>
</openerp>

View File

@ -19,20 +19,14 @@
#
##############################################################################
from osv import fields, osv
from tools.translate import _
import netsvc
import pooler
import time
import tools
import wizard
class auction_lots_enable(osv.osv_memory):
_name = "auction.lots.enable"
_description = "Lots Enable"
_columns= {
'confirm_en':fields.integer('Catalog Number')
}
'confirm_en':fields.integer('Catalog Number')
}
def confirm_enable(self, cr, uid, ids, context={}):
"""

View File

@ -27,20 +27,29 @@ import tools
import wizard
class auction_lots_make_invoice(osv.osv_memory):
_name = "auction.lots.make.invoice"
_description = "Make invoice"
_columns = {
'amount': fields.float('Invoiced Amount', required =True, readonly=True),
'objects':fields.integer('# of objects', required =True, readonly=True),
'number':fields.char('Invoice Number', size=64),
}
_defaults = {
'number': lambda *a: False,
}
def default_get(self, cr, uid, fields, context):
"""
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
res = super(auction_lots_make_invoice, self).default_get(cr, uid, fields, context=context)
for lot in self.pool.get('auction.lots').browse(cr, uid, context.get('active_ids', [])):
@ -53,7 +62,7 @@ class auction_lots_make_invoice(osv.osv_memory):
def makeInvoices(self, cr, uid, ids, context):
"""
seller invoice :Create an invoice.
Seller invoice :Create an invoice.
@param cr: the current row, from the database cursor.
@param uid: the current users ID for security checks.
@param ids: List of Auction lots make invoices IDs
@ -61,36 +70,20 @@ class auction_lots_make_invoice(osv.osv_memory):
"""
order_obj = self.pool.get('auction.lots')
mod_obj = self.pool.get('ir.model.data')
for data in self.read(cr, uid, ids):
result = mod_obj._get_id(cr, uid, 'account', 'view_account_invoice_filter')
id = mod_obj.read(cr, uid, result, ['res_id'])
newinv = []
ids = order_obj.seller_trans_create(cr, uid, context['active_ids'], context)
cr.commit()
return {
'domain': "[('id','in', ["+','.join(map(str, ids))+"])]",
'name': 'Seller invoices',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.invoice',
'view_id': False,
'context': "{'type':'out_refund'}",
'type': 'ir.actions.act_window',
'search_view_id': id['res_id']
}
result = mod_obj._get_id(cr, uid, 'account', 'view_account_invoice_filter')
id = mod_obj.read(cr, uid, result, ['res_id'])
lots_ids = order_obj.seller_trans_create(cr, uid, context['active_ids'], context)
cr.commit()
return {
'domain': "[('id','in', ["+','.join(map(str, lots_ids))+"])]",
'name': 'Seller invoices',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.invoice',
'view_id': False,
'context': "{'type':'out_refund'}",
'type': 'ir.actions.act_window',
'search_view_id': id['res_id']
}
_name = "auction.lots.make.invoice"
_description = "Make invoice"
_columns= {
'amount': fields.float('Invoiced Amount', required =True, readonly=True),
'objects':fields.integer('# of objects', required =True, readonly=True),
'number':fields.char('Invoice Number', size=64),
}
_defaults={
'number':lambda *a: False,
}
auction_lots_make_invoice()

View File

@ -19,27 +19,31 @@
#
##############################################################################
from osv import fields, osv
from tools.translate import _
import netsvc
import pooler
import time
import tools
import wizard
class auction_lots_make_invoice_buyer(osv.osv_memory):
_name = "auction.lots.make.invoice.buyer"
_description = "Make invoice buyer "
_columns= {
'amount': fields.float('Invoiced Amount', required =True, readonly=True),
'objects':fields.integer('# of objects', required =True, readonly=True),
'number':fields.char('Invoice Number', size=64),
'buyer_id':fields.many2one('res.partner', 'Buyer', required=True),
}
_defaults={
'number': lambda *a: False,
}
def default_get(self, cr, uid, fields, context):
"""
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
res = super(auction_lots_make_invoice_buyer, self).default_get(cr, uid, fields, context=context)
for lot in self.pool.get('auction.lots').browse(cr, uid, context.get('active_ids', [])):
@ -59,22 +63,19 @@ class auction_lots_make_invoice_buyer(osv.osv_memory):
@param ids: List of Auction lots make invoice buyers IDs
@return: dictionary of account invoice form.
"""
newinv = []
order_obj = self.pool.get('auction.lots')
mod_obj = self.pool.get('ir.model.data')
result = mod_obj._get_id(cr, uid, 'account', 'view_account_invoice_filter')
id = mod_obj.read(cr, uid, result, ['res_id'])
lots = order_obj.browse(cr, uid, context['active_ids'])
for data in self.read(cr, uid, ids):
result = mod_obj._get_id(cr, uid, 'account', 'view_account_invoice_filter')
id = mod_obj.read(cr, uid, result, ['res_id'])
lots = order_obj.browse(cr, uid, context['active_ids'])
invoice_number = data['number']
for lot in lots:
up_auction = order_obj.write(cr, uid, [lot.id], {'ach_uid':data['buyer_id']})
ids = order_obj.lots_invoice(cr, uid, context['active_ids'], context, data['number'])
up_auction = order_obj.write(cr, uid, [lot.id], {'ach_uid': data['buyer_id']})
lots_ids = order_obj.lots_invoice(cr, uid, context['active_ids'], context, data['number'])
cr.commit()
return {
'domain': "[('id','in', ["+','.join(map(str, ids))+"])]",
'domain': "[('id','in', ["+','.join(map(str, lots_ids))+"])]",
'name': 'Buyer invoices',
'view_type': 'form',
'view_mode': 'tree,form',
@ -84,17 +85,5 @@ class auction_lots_make_invoice_buyer(osv.osv_memory):
'type': 'ir.actions.act_window',
'search_view_id': id['res_id']
}
_name = "auction.lots.make.invoice.buyer"
_description = "Make invoice buyer "
_columns= {
'amount': fields.float('Invoiced Amount', required =True, readonly=True),
'objects':fields.integer('# of objects', required =True, readonly=True),
'number':fields.char('Invoice Number', size=64),
'buyer_id':fields.many2one('res.partner', 'Buyer', required=True),
}
_defaults={
'number':lambda *a: False,
}
auction_lots_make_invoice_buyer()

View File

@ -21,26 +21,33 @@
from osv import fields, osv
from tools.translate import _
import netsvc
import pooler
import time
import tools
import wizard
class auction_pay_buy(osv.osv_memory):
_name = "auction.pay.buy"
_description = "Pay buy"
_columns= {
'amount': fields.float('Amount paid', digits= (16, int(tools.config['price_accuracy']))),
'buyer_id':fields.many2one('res.partner', 'Buyer'),
'statement_id1':fields.many2one('account.bank.statement', 'Statement', required=True),
'amount2': fields.float('Amount paid', digits= (16, int(tools.config['price_accuracy']))),
'statement_id2':fields.many2one('account.bank.statement', 'Statement'),
'amount3': fields.float('Amount paid', digits = (16, int(tools.config['price_accuracy']))),
'statement_id3':fields.many2one('account.bank.statement', 'Statement'),
'total': fields.float('Amount paid', digits = (16, int(tools.config['price_accuracy'])), readonly =True),
}
def default_get(self, cr, uid, fields, context):
"""
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
res = super(auction_pay_buy, self).default_get(cr, uid, fields, context=context)
for lot in self.pool.get('auction.lots').browse(cr, uid, context.get('active_ids', [])):
@ -54,13 +61,12 @@ class auction_pay_buy(osv.osv_memory):
def pay_and_reconcile(self, cr, uid, ids, context):
"""
Pay and Reconcile
@param cr: the current row, from the database cursor.
@param uid: the current users ID for security checks.
@param ids: the ID or list of IDs
@param context: A standard dictionary
@return:
Pay and Reconcile
@param cr: the current row, from the database cursor.
@param uid: the current users ID for security checks.
@param ids: the ID or list of IDs
@param context: A standard dictionary
@return:
"""
lot_obj = self.pool.get('auction.lots')
bank_statement_line_obj = self.pool.get('account.bank.statement.line')
@ -94,22 +100,8 @@ class auction_pay_buy(osv.osv_memory):
for lot in lots:
lot_obj.write(cr, uid, [lot.id], {'statement_id':[(4, new_id)]})
return {}
_name = "auction.pay.buy"
_description = "Pay buy"
_columns= {
'amount': fields.float('Amount paid', digits= (16, int(tools.config['price_accuracy']))),
'buyer_id':fields.many2one('res.partner', 'Buyer'),
'statement_id1':fields.many2one('account.bank.statement', 'Statement', required=True),
'amount2': fields.float('Amount paid', digits= (16, int(tools.config['price_accuracy']))),
'statement_id2':fields.many2one('account.bank.statement', 'Statement'),
'amount3': fields.float('Amount paid', digits = (16, int(tools.config['price_accuracy']))),
'statement_id3':fields.many2one('account.bank.statement', 'Statement'),
'total': fields.float('Amount paid', digits = (16, int(tools.config['price_accuracy'])), readonly =True),
}
auction_pay_buy()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -20,33 +20,27 @@
##############################################################################
from osv import fields, osv
from tools.translate import _
import netsvc
import pooler
import time
import tools
import wizard
class auction_pay_sel(osv.osv_memory):
_name = "auction.pay.sel"
_description = "Pay Invoice"
_columns= {
'amount': fields.float('Amount paid', digits= (16, int(tools.config['price_accuracy'])), required=True),
'dest_account_id':fields.many2one('account.account', 'Payment to Account', required=True, domain= [('type', '=', 'cash')]),
'journal_id':fields.many2one('account.journal', 'Journal', required=True),
'period_id':fields.many2one('account.period', 'Period', required=True),
}
'amount': fields.float('Amount paid', digits= (16, int(tools.config['price_accuracy'])), required=True),
'dest_account_id':fields.many2one('account.account', 'Payment to Account', required=True, domain= [('type', '=', 'cash')]),
'journal_id':fields.many2one('account.journal', 'Journal', required=True),
'period_id':fields.many2one('account.period', 'Period', required=True),
}
def pay_and_reconcile(self, cr, uid, ids, context):
"""
Pay and Reconcile
@param cr: the current row, from the database cursor.
@param uid: the current users ID for security checks.
@param ids: the ID or list of IDs
@param context: A standard dictionary
@return:
Pay and Reconcile
@param cr: the current row, from the database cursor.
@param uid: the current users ID for security checks.
@param ids: the ID or list of IDs
@param context: A standard dictionary
@return:
"""
lot = self.pool.get('auction.lots').browse(cr, uid, context['active_id'], context)
invoice_obj = self.pool.get('account.invoice')

View File

@ -20,15 +20,8 @@
##############################################################################
from osv import fields, osv
from tools.translate import _
import netsvc
import pooler
import time
import tools
import wizard
class auction_payer(osv.osv_memory):
_name = "auction.payer"
_description = "Auction payer"

View File

@ -32,10 +32,10 @@ class auction_taken(osv.osv_memory):
"""
_name = "auction.taken"
_description = "Auction taken"
_columns = {
'lot_ids':fields.many2many('auction.lots', 'auction_taken_rel', 'taken_id', 'lot_id', 'Lots Emportes'),
}
'lot_ids':fields.many2many('auction.lots', 'auction_taken_rel', 'taken_id', 'lot_id', 'Lots Emportes'),
}
def _to_xml(s):
return s.replace('&','&amp;').replace('<','&lt;').replace('>','&gt;')

View File

@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv
from osv import fields
class auction_transfer_unsold_object(osv.osv):
'''
Open ERP Model
'''
_name = 'auction.transfer.unsold.object'
_description = 'To transfer unsold objects'
_columns = {
'auction_id_from':fields.many2one('auction.dates', 'From Auction Date', required=True),
'auction_id_to':fields.many2one('auction.dates', 'To Auction Date', required=True),
}
_defaults = {
'auction_id_from': _start,
}
def _start(self, cr, uid, context):
"""
To initialize auction_id_from
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return: auction_id_from
"""
lots_obj = self.pool.get('auction.lots')
rec = lots_obj.browse(cr, uid, context['active_id'], context)
auction_from = rec and rec.auction_id.id or False
return auction_from
def transfer_unsold_object(self, cr, uid, ids, context):
"""
To Transfer the unsold object
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return:
"""
bid_line_obj = self.pool.get('auction.bid_line')
lots_obj = self.pool.get('auction.lots')
lot_history_obj = self.pool.get('auction.lot.history')
line_ids= bid_line_obj.search(cr,uid,[('lot_id','in',context['active_ids'])])
bid_line_obj.unlink(cr, uid, line_ids)
res = self.browse(cr, uid, ids)
unsold_ids = lots_obj.search(cr,uid,[('auction_id','=',res[0].auction_id_from.id),('state','=','unsold')])
for rec in lots_obj.browse(cr, uid, unsold_ids, context):
new_id = lot_history_obj.create(cr,uid,{'auction_id':rec.auction_id.id,'lot_id':rec.id,'price': rec.obj_ret, 'name': rec.auction_id.auction1})
up_auction = lots_obj.write(cr,uid,[rec.id],{'auction_id': res[0].auction_id_to.id,
'obj_ret':None,
'obj_price':None,
'ach_login':None,
'ach_uid':None,
'ach_inv_id':None,
'sel_inv_id':None,
'state':'draft'})
return {}
auction_transfer_unsold_object()

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="name_form" model="ir.ui.view">
<field name="name">auction.transfer.unsold.object.form</field>
<field name="model">auction.transfer.unsold.object</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Draft To Posted">
<group col="1" colspan="2">
<separator colspan="4" string="Transfer unsold Object: Current auction date to another " />
</group>
<newline/>
<field name="auction_id_from" select="1"/>
<newline/>
<field name="auction_id_to" select="1"/>
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="transfer_unsold_object" string="Transfer"
colspan="1" type="object" icon="gtk-ok" />
</form>
</field>
</record>
</data>
</openerp>

View File

@ -1,91 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
import netsvc
import pooler
paid_form = '''<?xml version="1.0"?>
<form string="Cancel Payment">
<label string="Are you sure you want to refund this invoice ?"/>
</form>'''
fields_ask = {
}
#
#def _get_value(self,cr,uid, datas,context={}):
## service = netsvc.LocalService("object_proxy")
# lots=pool.get('auction.lots').browse(cr,uid,data['id'],context)
#
#
## lots = service.execute(cr.dbname,uid, 'auction.lots', 'read', datas['ids'])
#
# ids = []
# pay_ids = {}
# price = 0.0
# price_paid = 0.0
# uid = False
#
##TODO: refuse if several payments?
# for lot in lots:
# price += lot['obj_price']
#
# # add all the buyer costs
# costs = service.execute(cr.dbname,uid, 'auction.lots', 'compute_buyer_costs', [lot['id']])
# for cost in costs:
# price += cost['amount']
#
##TODO: pr bien faire, faudrait leur poser la question: continue anyway?
# if len(ids)<len(datas['ids']):
# raise wizard.except_wizard('UserError', ('Some object(s) are not paid !', 'init'))
#
# return {'objects':len(ids), 'amount_total':price, 'amount_paid':price_paid}
#
#def _cancel(self, uid, datas):
# service = netsvc.LocalService("object_proxy")
# lots = service.execute(cr.dbname,uid, 'auction.lots', 'lots_cancel_payment', datas['ids'])
# return {}
#
def _cancel(self,cr,uid,data,context):
pool = pooler.get_pool(cr.dbname)
lot = pool.get('auction.lots').browse(cr,uid,data['id'],context)
if lot.ach_inv_id:
p=pool.get('account.invoice').refund(['lot.ach_inv_id.id'],context)
if lot.vnd_inv_id:
p=pool.get('account.invoice').refund(['lot.vnd_inv_id.id'],context)
return {}
class wiz_auc_lots_cancel(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':paid_form, 'fields': fields_ask, 'state':[('make_cancel','Cancel Payment'), ('end','Cancel')]}
},
'make_cancel': {
'actions': [_cancel],
'result': {'type': 'state', 'state':'end'}
}
}
wiz_auc_lots_cancel('auction.lots.cancel');
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,92 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import time
import wizard
import netsvc
import pooler
from osv.orm import browse_record
import sql_db
transfer_unsold_object_form = """<?xml version="1.0"?>
<form string="Draft To Posted">
<group col="1" colspan="2">
<separator colspan="4" string="Transfer unsold Object: Current auction date to another " />
</group>
<newline/>
<field name="auction_id_from"/>
<newline/>
<field name="auction_id_to"/>
</form>
"""
transfer_unsold_object_fields = {
'auction_id_from': {'string':'From Auction Date', 'type':'many2one', 'required':True, 'relation':'auction.dates'},
'auction_id_to': {'string':'To Auction Date', 'type':'many2one', 'required':True, 'relation':'auction.dates'},
}
def _start(self,cr,uid,data,context):
pool = pooler.get_pool(cr.dbname)
rec=pool.get('auction.lots').browse(cr,uid,data['id'],context)
auction_from= rec and rec.auction_id.id or False
return {'auction_id_from':auction_from}
def _transfer_unsold_object(self, cr, uid, data, context):
#if not (data['form']['auction_id_to']) :
# return {}
#Historique de l objet + changement de l auction date + supp des bid line
line_ids= pooler.get_pool(cr.dbname).get('auction.bid_line').search(cr,uid,[('lot_id','in',data['ids'])])
pooler.get_pool(cr.dbname).get('auction.bid_line').unlink(cr, uid, line_ids)
obj_pool = pooler.get_pool(cr.dbname).get('auction.lots')
ids= obj_pool.search(cr,uid,[('auction_id','=',data['form']['auction_id_from']),('state','=','unsold')])
for rec in obj_pool.browse(cr, uid, ids, context):
new_id=pooler.get_pool(cr.dbname).get('auction.lot.history').create(cr,uid,{'auction_id':rec.auction_id.id,'lot_id':rec.id,'price': rec.obj_ret, 'name': 'reasons'+rec.auction_id.auction1})
up_auction=pooler.get_pool(cr.dbname).get('auction.lots').write(cr,uid,[rec.id],{'auction_id':data['form']['auction_id_to'],
'obj_ret':None,
'obj_price':None,
'ach_login':None,
'ach_uid':None,
'ach_inv_id':None,
'sel_inv_id':None,
'state':'draft'})
# new_id = self.pool.get('auction.lot.history').copy(cr, uid, m.id, {'price': recs.obj_ret, 'name': 'reasons'+recs.auction_id.name})
# new_id=pooler.get_pool(cr.dbname).get('auction.lot.history').create(cr,uid,{'auction_id':rec.auction_id,'lot_id':rec.name,'price': rec.obj_ret, 'name': 'reasons'+rec.auction_id.auction1})
return {}
class transfer_object(wizard.interface):
states = {
'init' : {
'actions' : [_start],
'result' : {'type' : 'form',
'arch' : transfer_unsold_object_form,
'fields' :transfer_unsold_object_fields,
'state' : [('transfer', 'Transfer'),('end', 'Cancel') ]}
},
'transfer' : {
'actions' : [_transfer_unsold_object],
'result' : {'type' : 'state','state' : 'end'}
},
}
transfer_object('auction.lots.transfer.unsold.object')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -37,6 +37,7 @@
'depends': ['base'],
'init_xml': [],
'update_xml': [
'wizard/audittrail_view_log_view.xml',
'audittrail_view.xml',
'security/ir.model.access.csv',
'security/audittrail_security.xml'

View File

@ -19,35 +19,39 @@
#
##############################################################################
from osv import fields, osv
from osv.osv import osv_pool
from tools.translate import _
import ir
import netsvc
import pooler
import string
import time, copy
import time
class audittrail_rule(osv.osv):
"""
For Auddittrail Rule
"""
_name = 'audittrail.rule'
_description = "Audittrail Rule"
_columns = {
"name": fields.char("Rule Name", size=32, required=True),
"object_id": fields.many2one('ir.model', 'Object', required=True),
"user_id": fields.many2many('res.users', 'audittail_rules_users', 'user_id', 'rule_id', 'Users'),
"log_read": fields.boolean("Log reads"),
"log_write": fields.boolean("Log writes"),
"log_unlink": fields.boolean("Log deletes"),
"log_create": fields.boolean("Log creates"),
"state": fields.selection((("draft", "Draft"), ("subscribed", "Subscribed")), "State", required=True),
"action_id":fields.many2one('ir.actions.act_window', "Action ID"),
"name": fields.char("Rule Name", size=32, required=True),
"object_id": fields.many2one('ir.model', 'Object', required=True),
"user_id": fields.many2many('res.users', 'audittail_rules_users',
'user_id', 'rule_id', 'Users'),
"log_read": fields.boolean("Log reads"),
"log_write": fields.boolean("Log writes"),
"log_unlink": fields.boolean("Log deletes"),
"log_create": fields.boolean("Log creates"),
"state": fields.selection((("draft", "Draft"),
("subscribed", "Subscribed")),
"State", required=True),
"action_id": fields.many2one('ir.actions.act_window', "Action ID"),
}
_defaults = {
'state': lambda *a: 'draft',
'log_create': lambda *a: 1,
'log_unlink': lambda *a: 1,
'log_write': lambda *a: 1,
'state': lambda *a: 'draft',
'log_create': lambda *a: 1,
'log_unlink': lambda *a: 1,
'log_write': lambda *a: 1,
}
_sql_constraints = [
@ -56,59 +60,86 @@ class audittrail_rule(osv.osv):
__functions = {}
def subscribe(self, cr, uid, ids, *args):
"""
Subscribe Rule for auditing changes on object and apply shortcut for logs on that object.
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Auddittrail Rules IDs.
@return: True
"""
obj_action = self.pool.get('ir.actions.act_window')
obj_model = self.pool.get('ir.model.data')
#start Loop
for thisrule in self.browse(cr, uid, ids):
obj = self.pool.get(thisrule.object_id.model)
if not obj:
raise osv.except_osv(
_('WARNING:audittrail is not part of the pool'),
_('WARNING: audittrail is not part of the pool'),
_('Change audittrail depends -- Setting rule as DRAFT'))
self.write(cr, uid, [thisrule.id], {"state": "draft"})
val={
"name":'View Log',
"res_model":'audittrail.log',
"src_model":thisrule.object_id.model,
"domain":"[('object_id','=',"+str(thisrule.object_id.id)+"),('res_id', '=', active_id)]"
val = {
"name": 'View Log',
"res_model": 'audittrail.log',
"src_model": thisrule.object_id.model,
"domain": "[('object_id','=', " + str(thisrule.object_id.id) + "), ('res_id', '=', active_id)]"
}
id=self.pool.get('ir.actions.act_window').create(cr, uid, val)
self.write(cr, uid, [thisrule.id], {"state": "subscribed", "action_id":id})
id = obj_action.create(cr, uid, val)
self.write(cr, uid, [thisrule.id], {"state": "subscribed", "action_id": id})
keyword = 'client_action_relate'
value = 'ir.actions.act_window,'+str(id)
res=self.pool.get('ir.model.data').ir_set(cr, uid, 'action', keyword, 'View_log_'+thisrule.object_id.model, [thisrule.object_id.model], value, replace=True, isobject=True, xml_id=False)
value = 'ir.actions.act_window,' + str(id)
res = obj_model.ir_set(cr, uid, 'action', keyword, 'View_log_' + thisrule.object_id.model, [thisrule.object_id.model], value, replace=True, isobject=True, xml_id=False)
#End Loop
return True
def unsubscribe(self, cr, uid, ids, *args):
"""
Unsubscribe Auditing Rule on object
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Auddittrail Rules IDs.
@return: True
"""
obj_action = self.pool.get('ir.actions.act_window')
val_obj = self.pool.get('ir.values')
#start Loop
for thisrule in self.browse(cr, uid, ids):
if thisrule.id in self.__functions :
if thisrule.id in self.__functions:
for function in self.__functions[thisrule.id]:
setattr(function[0], function[1], function[2])
w_id=self.pool.get('ir.actions.act_window').search(cr, uid, [('name', '=', 'View Log'), ('res_model', '=', 'audittrail.log'), ('src_model', '=', thisrule.object_id.model)])
self.pool.get('ir.actions.act_window').unlink(cr, uid, w_id)
val_obj=self.pool.get('ir.values')
value="ir.actions.act_window"+','+str(w_id[0])
val_id=val_obj.search(cr, uid, [('model', '=', thisrule.object_id.model), ('value', '=', value)])
w_id = obj_action.search(cr, uid, [('name', '=', 'View Log'), ('res_model', '=', 'audittrail.log'), ('src_model', '=', thisrule.object_id.model)])
obj_action.unlink(cr, uid, w_id)
value = "ir.actions.act_window" + ',' + str(w_id[0])
val_id = val_obj.search(cr, uid, [('model', '=', thisrule.object_id.model), ('value', '=', value)])
if val_id:
res = ir.ir_del(cr, uid, val_id[0])
self.write(cr, uid, [thisrule.id], {"state": "draft"})
#End Loop
return True
audittrail_rule()
class audittrail_log(osv.osv):
"""
For Audittrail Log
"""
_name = 'audittrail.log'
_description = "Audittrail Log"
_columns = {
"name": fields.char("Name", size=32),
"object_id": fields.many2one('ir.model', 'Object'),
"user_id": fields.many2one('res.users', 'User'),
"method": fields.selection((('read', 'Read'), ('write', 'Write'), ('unlink', 'Delete'), ('create', 'Create')), "Method"),
"timestamp": fields.datetime("Date"),
"res_id":fields.integer('Resource Id'),
"line_ids":fields.one2many('audittrail.log.line', 'log_id', 'Log lines'),
"name": fields.char("Name", size=32),
"object_id": fields.many2one('ir.model', 'Object'),
"user_id": fields.many2one('res.users', 'User'),
"method": fields.selection((('read', 'Read'),
('write', 'Write'),
('unlink', 'Delete'),
('create', 'Create')), "Method"),
"timestamp": fields.datetime("Date"),
"res_id": fields.integer('Resource Id'),
"line_ids": fields.one2many('audittrail.log.line', 'log_id', 'Log lines'),
}
_defaults = {
"timestamp": lambda *a: time.strftime("%Y-%m-%d %H:%M:%S")
}
@ -116,235 +147,293 @@ class audittrail_log(osv.osv):
audittrail_log()
class audittrail_log_line(osv.osv):
_name='audittrail.log.line'
_columns={
'field_id': fields.many2one('ir.model.fields', 'Fields', required=True),
'log_id':fields.many2one('audittrail.log', 'Log'),
'log':fields.integer("Log ID"),
'old_value':fields.text("Old Value"),
'new_value':fields.text("New Value"),
'old_value_text':fields.text('Old value Text'),
'new_value_text':fields.text('New value Text'),
'field_description':fields.char('Field Description' , size=64),
}
"""
Audittrail Log Line.
"""
_name = 'audittrail.log.line'
_description = "Log Line"
_columns = {
'field_id': fields.many2one('ir.model.fields', 'Fields', required=True),
'log_id': fields.many2one('audittrail.log', 'Log'),
'log': fields.integer("Log ID"),
'old_value': fields.text("Old Value"),
'new_value': fields.text("New Value"),
'old_value_text': fields.text('Old value Text'),
'new_value_text': fields.text('New value Text'),
'field_description': fields.char('Field Description', size=64),
}
audittrail_log_line()
class audittrail_objects_proxy(osv_pool):
def get_value_text(self, cr, uid, field_name, values, object, context={}):
pool = pooler.get_pool(cr.dbname)
obj=pool.get(object.model)
obj_ids= pool.get('ir.model').search(cr, uid, [('model', '=', object.model)])
model_object=pool.get('ir.model').browse(cr, uid, obj_ids)[0]
f_id= pool.get('ir.model.fields').search(cr, uid, [('name', '=', field_name), ('model_id', '=', object.id)])
if f_id:
field=pool.get('ir.model.fields').read(cr, uid, f_id)[0]
model=field['relation']
""" Uses Object proxy for auditing changes on object of subscribed Rules"""
def get_value_text(self, cr, uid, field_name, values, object, context=None):
"""
Gets textual values for the fields
e.g.: For field of type many2one it gives its name value instead of id
if field['ttype']=='many2one':
if values:
if type(values)==tuple:
values=values[0]
val=pool.get(model).read(cr, uid, [values], [pool.get(model)._rec_name])
if len(val):
return val[0][pool.get(model)._rec_name]
elif field['ttype'] == 'many2many':
value=[]
if values:
for id in values:
val=pool.get(model).read(cr, uid, [id], [pool.get(model)._rec_name])
if len(val):
value.append(val[0][pool.get(model)._rec_name])
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param field_name: List of fields for text values
@param values: Values for field to be converted into textual values
@return: values: List of textual values for given fields
"""
if not context:
context = {}
pool = pooler.get_pool(cr.dbname)
f_id = pool.get('ir.model.fields').search(cr, uid, [('name', '=', field_name), ('model_id', '=', object.id)])
if f_id:
field = pool.get('ir.model.fields').read(cr, uid, f_id)[0]
model = field['relation']
if field['ttype'] == 'many2one':
if values:
if type(values) == tuple:
values = values[0]
val = pool.get(model).read(cr, uid, [values], [pool.get(model)._rec_name])
if val:
return val[0][pool.get(model)._rec_name]
elif field['ttype'] == 'many2many':
value = []
if values:
for id in values:
val = pool.get(model).read(cr, uid, [id], [pool.get(model)._rec_name])
if val:
value.append(val[0][pool.get(model)._rec_name])
return value
elif field['ttype'] == 'one2many':
if values:
value = []
for id in values:
val = pool.get(model).read(cr, uid, [id], [pool.get(model)._rec_name])
if val:
value.append(val[0][pool.get(model)._rec_name])
return value
elif field['ttype'] == 'one2many':
if values:
value=[]
for id in values:
val=pool.get(model).read(cr, uid, [id], [pool.get(model)._rec_name])
if len(val):
value.append(val[0][pool.get(model)._rec_name])
return value
return values
def create_log_line(self, cr, uid, id, object, lines=[]):
"""
Creates lines for changed fields with its old and new values
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param object: Object who's values are being changed
@param lines: List of values for line is to be created
"""
pool = pooler.get_pool(cr.dbname)
obj=pool.get(object.model)
obj_ids= pool.get('ir.model').search(cr, uid, [('model', '=', object.model)])
model_object=pool.get('ir.model').browse(cr, uid, obj_ids)[0]
obj = pool.get(object.model)
#start Loop
for line in lines:
if obj._inherits:
inherits_ids= pool.get('ir.model').search(cr, uid, [('model', '=', obj._inherits.keys()[0])])
f_id= pool.get('ir.model.fields').search(cr, uid, [('name', '=', line['name']), ('model_id', 'in', (object.id, inherits_ids[0]))])
inherits_ids = pool.get('ir.model').search(cr, uid, [('model', '=', obj._inherits.keys()[0])])
f_id = pool.get('ir.model.fields').search(cr, uid, [('name', '=', line['name']), ('model_id', 'in', (object.id, inherits_ids[0]))])
else:
f_id= pool.get('ir.model.fields').search(cr, uid, [('name', '=', line['name']), ('model_id', '=', object.id)])
if len(f_id):
fields=pool.get('ir.model.fields').read(cr, uid, f_id)
old_value='old_value' in line and line['old_value'] or ''
new_value='new_value' in line and line['new_value'] or ''
old_value_text='old_value_text' in line and line['old_value_text'] or ''
new_value_text='new_value_text' in line and line['new_value_text'] or ''
f_id = pool.get('ir.model.fields').search(cr, uid, [('name', '=', line['name']), ('model_id', '=', object.id)])
if f_id:
fields = pool.get('ir.model.fields').read(cr, uid, f_id)
old_value = 'old_value' in line and line['old_value'] or ''
new_value = 'new_value' in line and line['new_value'] or ''
old_value_text = 'old_value_text' in line and line['old_value_text'] or ''
new_value_text = 'new_value_text' in line and line['new_value_text'] or ''
if old_value_text == new_value_text:
continue
if fields[0]['ttype']== 'many2one':
if type(old_value)==tuple:
old_value=old_value[0]
if type(new_value)==tuple:
new_value=new_value[0]
log_line_id = pool.get('audittrail.log.line').create(cr, uid, {"log_id": id, "field_id": f_id[0] , "old_value":old_value , "new_value":new_value, "old_value_text":old_value_text , "new_value_text":new_value_text, "field_description":fields[0]['field_description']})
if fields[0]['ttype'] == 'many2one':
if type(old_value) == tuple:
old_value = old_value[0]
if type(new_value) == tuple:
new_value = new_value[0]
vals = {
"log_id": id,
"field_id": f_id[0],
"old_value": old_value,
"new_value": new_value,
"old_value_text": old_value_text,
"new_value_text": new_value_text,
"field_description": fields[0]['field_description']
}
line_id = pool.get('audittrail.log.line').create(cr, uid, vals)
cr.commit()
#End Loop
return True
def log_fct(self, db, uid, object, method, fct_src, *args):
logged_uids = []
pool = pooler.get_pool(db)
cr = pooler.get_db(db).cursor()
obj=pool.get(object)
obj_ids= pool.get('ir.model').search(cr, uid, [('model', '=', object)])
model_object=pool.get('ir.model').browse(cr, uid, obj_ids)[0]
if method in ('create'):
res_id = fct_src(db, uid, object, method, *args)
"""
Logging function: This function is performs logging oprations according to method
@param db: the current database
@param uid: the current users ID for security checks,
@param object: Object who's values are being changed
@param method: method to log: create, read, write, unlink
@param fct_src: execute method of Object proxy
@return: Returns result as per method of Object proxy
"""
logged_uids = []
pool = pooler.get_pool(db)
cr = pooler.get_db(db).cursor()
obj_ids = pool.get('ir.model').search(cr, uid, [('model', '=', object)])
model_object = pool.get('ir.model').browse(cr, uid, obj_ids)[0]
if method in ('create'):
res_id = fct_src(db, uid, object, method, *args)
cr.commit()
new_value = pool.get(model_object.model).read(cr, uid, [res_id], args[0].keys())[0]
if 'id' in new_value:
del new_value['id']
if not logged_uids or uid in logged_uids:
resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
resource_name = resource_name and resource_name[0][1] or ''
vals = {
"method": method,
"object_id": model_object.id,
"user_id": uid, "res_id": res_id,
"name": resource_name
}
id = pool.get('audittrail.log').create(cr, uid, vals)
lines = []
for field in new_value:
if new_value[field]:
line = {
'name': field,
'new_value': new_value[field],
'new_value_text': self.get_value_text(cr, uid, field, new_value[field], model_object)
}
lines.append(line)
self.create_log_line(cr, uid, id, model_object, lines)
cr.commit()
cr.close()
return res_id
if method in ('write'):
res_ids = args[0]
for res_id in res_ids:
old_values = pool.get(model_object.model).read(cr, uid, res_id, args[1].keys())
old_values_text = {}
for field in args[1].keys():
old_values_text[field] = self.get_value_text(cr, uid, field, old_values[field], model_object)
res = fct_src(db, uid, object, method, *args)
cr.commit()
new_value=pool.get(model_object.model).read(cr, uid, [res_id], args[0].keys())[0]
if 'id' in new_value:
del new_value['id']
if not len(logged_uids) or uid in logged_uids:
resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
resource_name = resource_name and resource_name[0][1] or ''
id=pool.get('audittrail.log').create(cr, uid, {"method": method , "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name})
lines=[]
for field in new_value:
if new_value[field]:
line={
'name':field,
'new_value':new_value[field],
'new_value_text': self.get_value_text(cr, uid, field, new_value[field], model_object)
}
lines.append(line)
self.create_log_line(cr, uid, id, model_object, lines)
cr.commit()
cr.close()
return res_id
if method in ('write'):
res_ids=args[0]
for res_id in res_ids:
old_values=pool.get(model_object.model).read(cr, uid, res_id, args[1].keys())
old_values_text={}
for field in args[1].keys():
old_values_text[field] = self.get_value_text(cr, uid, field, old_values[field], model_object)
res =fct_src(db, uid, object, method, *args)
cr.commit()
if res:
new_values=pool.get(model_object.model).read(cr, uid, res_ids, args[1].keys())[0]
if not len(logged_uids) or uid in logged_uids:
resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
resource_name = resource_name and resource_name[0][1] or ''
id=pool.get('audittrail.log').create(cr, uid, {"method": method, "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name})
lines=[]
for field in args[1].keys():
if args[1].keys():
line={
'name':field,
'new_value':field in new_values and new_values[field] or '',
'old_value':field in old_values and old_values[field] or '',
'new_value_text': self.get_value_text(cr, uid, field, new_values[field], model_object),
'old_value_text':old_values_text[field]
}
lines.append(line)
cr.commit()
self.create_log_line(cr, uid, id, model_object, lines)
cr.close()
return res
if method in ('read'):
res_ids=args[0]
old_values={}
res =fct_src(db, uid, object, method, *args)
if type(res)==list:
for v in res:
old_values[v['id']]=v
else:
old_values[res['id']]=res
for res_id in old_values:
if not len(logged_uids) or uid in logged_uids:
if res:
new_values = pool.get(model_object.model).read(cr, uid, res_ids, args[1].keys())[0]
if not logged_uids or uid in logged_uids:
resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
resource_name = resource_name and resource_name[0][1] or ''
id=pool.get('audittrail.log').create(cr, uid, {"method": method , "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name})
lines=[]
for field in old_values[res_id]:
if old_values[res_id][field]:
line={
'name':field,
'old_value':old_values[res_id][field],
'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model_object)
}
lines.append(line)
cr.commit()
self.create_log_line(cr, uid, id, model_object, lines)
cr.close()
return res
if method in ('unlink'):
res_ids=args[0]
old_values={}
for res_id in res_ids:
old_values[res_id]=pool.get(model_object.model).read(cr, uid, res_id, [])
for res_id in res_ids:
if not len(logged_uids) or uid in logged_uids:
resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
resource_name = resource_name and resource_name[0][1] or ''
id=pool.get('audittrail.log').create(cr, uid, {"method": method , "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name})
lines=[]
for field in old_values[res_id]:
if old_values[res_id][field]:
line={
'name':field,
'old_value':old_values[res_id][field],
'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model_object)
id = pool.get('audittrail.log').create(cr, uid, {"method": method, "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name})
lines = []
for field in args[1].keys():
if args[1].keys():
line = {
'name': field,
'new_value': field in new_values and new_values[field] or '',
'old_value': field in old_values and old_values[field] or '',
'new_value_text': self.get_value_text(cr, uid, field, new_values[field], model_object),
'old_value_text': old_values_text[field]
}
lines.append(line)
cr.commit()
self.create_log_line(cr, uid, id, model_object, lines)
res =fct_src(db, uid, object, method, *args)
cr.close()
return res
if method in ('read'):
res_ids = args[0]
old_values = {}
res = fct_src(db, uid, object, method, *args)
if type(res) == list:
for v in res:
old_values[v['id']] = v
else:
old_values[res['id']] = res
for res_id in old_values:
if not logged_uids or uid in logged_uids:
resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
resource_name = resource_name and resource_name[0][1] or ''
id = pool.get('audittrail.log').create(cr, uid, {"method": method, "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name})
lines = []
for field in old_values[res_id]:
if old_values[res_id][field]:
line = {
'name': field,
'old_value': old_values[res_id][field],
'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model_object)
}
lines.append(line)
cr.commit()
self.create_log_line(cr, uid, id, model_object, lines)
cr.close()
return res
if method in ('unlink'):
res_ids = args[0]
old_values = {}
for res_id in res_ids:
old_values[res_id] = pool.get(model_object.model).read(cr, uid, res_id, [])
for res_id in res_ids:
if not logged_uids or uid in logged_uids:
resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id])
resource_name = resource_name and resource_name[0][1] or ''
id = pool.get('audittrail.log').create(cr, uid, {"method": method, "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name})
lines = []
for field in old_values[res_id]:
if old_values[res_id][field]:
line = {
'name': field,
'old_value': old_values[res_id][field],
'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model_object)
}
lines.append(line)
cr.commit()
self.create_log_line(cr, uid, id, model_object, lines)
res = fct_src(db, uid, object, method, *args)
cr.close()
return res
cr.close()
def execute(self, db, uid, object, method, *args, **kw):
"""
Overrides Object Proxy execute method
@param db: the current database
@param uid: the current users ID for security checks,
@param object: Object who's values are being changed
@param method: method to log: create, read, write, unlink
@return: Returns result as per method of Object proxy
"""
pool = pooler.get_pool(db)
cr = pooler.get_db(db).cursor()
cr.autocommit(True)
obj=pool.get(object)
logged_uids = []
fct_src = super(audittrail_objects_proxy, self).execute
def my_fct(db, uid, object, method, *args):
field = method
rule = False
obj_ids= pool.get('ir.model').search(cr, uid, [('model', '=', object)])
obj_ids = pool.get('ir.model').search(cr, uid, [('model', '=', object)])
for obj_name in pool.obj_list():
if obj_name == 'audittrail.rule':
rule = True
if not rule:
return fct_src(db, uid, object, method, *args)
if not len(obj_ids):
if not obj_ids:
return fct_src(db, uid, object, method, *args)
rule_ids=pool.get('audittrail.rule').search(cr, uid, [('object_id', '=', obj_ids[0]), ('state', '=', 'subscribed')])
if not len(rule_ids):
rule_ids = pool.get('audittrail.rule').search(cr, uid, [('object_id', '=', obj_ids[0]), ('state', '=', 'subscribed')])
if not rule_ids:
return fct_src(db, uid, object, method, *args)
for thisrule in pool.get('audittrail.rule').browse(cr, uid, rule_ids):
for user in thisrule.user_id:
logged_uids.append(user.id)
if not len(logged_uids) or uid in logged_uids:
if not logged_uids or uid in logged_uids:
if field in ('read', 'write', 'create', 'unlink'):
if getattr(thisrule, 'log_'+field):
if getattr(thisrule, 'log_' + field):
return self.log_fct(db, uid, object, method, fct_src, *args)
return fct_src(db, uid, object, method, *args)
res = my_fct(db, uid, object, method, *args)

View File

@ -1,6 +1,9 @@
<?xml version="1.0" ?>
<openerp>
<data>
<!-- Audittrail Rule form -->
<record model="ir.ui.view" id="view_audittrail_rule_form">
<field name="name">audittrail.rule.form</field>
<field name="model">audittrail.rule</field>
@ -17,12 +20,15 @@
<field name="user_id" select="1" colspan="4"/>
<field name="state" select="1" readonly="1" />
<group colspan="2" col="2">
<button string="Subscribe" name="subscribe" type="object" states="draft"/>
<button string="UnSubscribe" name="unsubscribe" type="object" states="subscribed"/>
<button string="Subscribe" name="subscribe"
type="object" states="draft" />
<button string="UnSubscribe" name="unsubscribe"
type="object" states="subscribed" />
</group>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_audittrail_rule_tree">
<field name="name">audittrail.rule.tree</field>
<field name="model">audittrail.rule</field>
@ -40,6 +46,9 @@
</tree>
</field>
</record>
<!-- Action for audittrail rule -->
<record model="ir.actions.act_window" id="action_audittrail_rule_tree">
<field name="name">Rules</field>
<field name="res_model">audittrail.rule</field>
@ -48,8 +57,11 @@
<field name="view_mode">tree,form</field>
<!--<field name="view_id" ref="view_audittrail_rule_form" />-->
</record>
<menuitem name="Audittrails" id="menu_action_audittrail" parent="base.menu_administration"/>
<menuitem name="Rules" id="menu_action_audittrail_rule_tree" action="action_audittrail_rule_tree" parent="menu_action_audittrail"/>
<menuitem name="Audittrails" id="menu_action_audittrail"
parent="base.menu_administration" />
<menuitem name="Rules" id="menu_action_audittrail_rule_tree"
action="action_audittrail_rule_tree" parent="menu_action_audittrail" />
<record model="ir.actions.act_window" id="action_audittrail_rule_tree_sub">
@ -60,6 +72,8 @@
<field name="domain">[('state','=','subscribed')]</field>
<field name="filter" eval="True"/>
</record>
<!-- AuditTrail Log form -->
<record model="ir.ui.view" id="view_audittrail_log_form">
<field name="name">audittrail.log.form</field>
@ -73,23 +87,34 @@
<field name="user_id" select="1" readonly="1"/>
<field name="res_id" readonly="1"/>
<field name="name" readonly="1" select="1"/>
<field name="line_ids" colspan="4" mode="tree,form" widget="one2many_list" readonly="1">
<field name="line_ids" colspan="4" mode="tree,form"
widget="one2many_list" readonly="1">
<form string="Log Lines">
<field name="field_id" colspan="4" readonly="1"/>
<newline/>
<field name="field_description" colspan="4" readonly="1"/>
<newline/>
<separator string="Old Value : " colspan="2"/>
<separator string="New Value : " colspan="2"/>
<newline/>
<field name="old_value" nolabel="1" colspan="2" readonly="1"/>
<field name="new_value" nolabel="1" colspan="2" readonly="1"/>
<newline/>
<separator string="Old Value Text : " colspan="2"/>
<separator string="New Value Text: " colspan="2"/>
<newline/>
<field name="old_value_text" nolabel="1" colspan="2" readonly="1"/>
<field name="new_value_text" nolabel="1" colspan="2" readonly="1"/>
<field name="field_id" colspan="4"
readonly="1" />
<newline />
<field name="field_description" colspan="4"
readonly="1" />
<newline />
<separator string="Old Value : "
colspan="2" />
<separator string="New Value : "
colspan="2" />
<newline />
<field name="old_value" nolabel="1"
colspan="2" readonly="1" />
<field name="new_value" nolabel="1"
colspan="2" readonly="1" />
<newline />
<separator string="Old Value Text : "
colspan="2" />
<separator string="New Value Text: "
colspan="2" />
<newline />
<field name="old_value_text" nolabel="1"
colspan="2" readonly="1" />
<field name="new_value_text" nolabel="1"
colspan="2" readonly="1" />
</form>
<tree string="Log Lines">
@ -117,15 +142,19 @@
</field>
</record>
<!-- Action for Audittrail Log -->
<record model="ir.actions.act_window" id="action_audittrail_log_tree">
<field name="name">Logs</field>
<field name="res_model">audittrail.log</field>
<field name="view_type">form</field>
</record>
<menuitem name="Logs" id="menu_action_audittrail_log_tree" action="action_audittrail_log_tree" parent="menu_action_audittrail"/>
<menuitem name="Logs" id="menu_action_audittrail_log_tree"
action="action_audittrail_log_tree" parent="menu_action_audittrail" />
<wizard string="View log" menu="False" model="audittrail.log" name="audittrail.view.log" id="wizard_audittrail_log"/>
<menuitem name="View Logs" id="menu_action_log_tree2" action="wizard_audittrail_log" type="wizard" parent="menu_action_audittrail"/>
<!-- <wizard string="View log" menu="False" model="audittrail.log" name="audittrail.view.log" id="wizard_audittrail_log"/>-->
<menuitem name="View Logs" id="menu_action_log_tree2"
action="action_audittrail_view_log" parent="menu_action_audittrail" />
</data>
</data>
</openerp>

View File

@ -5,3 +5,4 @@
"access_audittrail_rule_all_users","audittrail rule all","model_audittrail_rule","base.group_user",1,0,0,0
"access_audittrail_log_all_users","audittrail log all","model_audittrail_log","base.group_user",1,0,1,0
"access_audittrail_log_line_all_users","audittrail log line all","model_audittrail_log_line","base.group_user",1,0,1,0
"access_audittrail_view_log","audittrail.view.log","model_audittrail_view_log","base.group_user",1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
5 access_audittrail_rule_all_users audittrail rule all model_audittrail_rule base.group_user 1 0 0 0
6 access_audittrail_log_all_users audittrail log all model_audittrail_log base.group_user 1 0 1 0
7 access_audittrail_log_line_all_users audittrail log line all model_audittrail_log_line base.group_user 1 0 1 0
8 access_audittrail_view_log audittrail.view.log model_audittrail_view_log base.group_user 1 1 1 1

View File

@ -19,6 +19,6 @@
#
##############################################################################
import wizard_view_log
import audittrail_view_log
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
import time
class audittrail_view_log(osv.osv_memory):
_name = "audittrail.view.log"
_description = "View Log"
_columns = {
'from':fields.datetime('Log From'),
'to':fields.datetime('Log To', required = True)
}
_defaults = {
'to': lambda *a: time.strftime("%Y-%m-%d %H:%M:%S"),
}
def log_open_window(self, cr, uid, ids, context=None):
"""
Open Log form from given date range..
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of audittrail view logs IDs.
@return: Dictionary of audittrail log form on given date range.
"""
if not context:
context = {}
mod_obj = self.pool.get('ir.model.data')
act_obj = self.pool.get('ir.actions.act_window')
result = mod_obj._get_id(cr, uid, 'audittrail', 'action_audittrail_log_tree')
id = mod_obj.read(cr, uid, [result], ['res_id'])[0]['res_id']
result = act_obj.read(cr, uid, [id])[0]
#log_obj = self.pool.get(result['res_model'])
#log_id = log_obj.search(cr, uid, [])
#log_model = log_obj.read(cr, uid, log_id, ['object_id'])
#start Loop
for datas in self.read(cr, uid, ids):
if not datas.get('from', None):
if datas.get('to') <> time.strftime("%Y-%m-%d %H:%M:%S"):
result['domain'] = str([('timestamp', '<', datas.get('to'))])
else:
pass
else:
result['domain'] = str([('timestamp', '>', datas.get('from', None)), ('timestamp', '<', datas.get('to'))])
#End Loop
return result
audittrail_view_log()

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Audittrail View Log wizard-->
<record id="view_audittrail_view_log" model="ir.ui.view">
<field name="name">audittrail.view.log.form</field>
<field name="model">audittrail.view.log</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Audit Logs">
<group colspan="4" >
<field name="from" colspan="4"/>
<newline/>
<field name="to" colspan="4"/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel"
string="Cancel" />
<button icon="gtk-open" string="Open Logs"
name="log_open_window" type="object" />
</group>
</form>
</field>
</record>
<!-- action for audittrail view log wizard -->
<record id="action_audittrail_view_log" model="ir.actions.act_window">
<field name="name">View log</field>
<field name="res_model">audittrail.view.log</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_audittrail_view_log"/>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -1,81 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
import pooler
import time
class wizard_view_log(wizard.interface):
form1 = '''<?xml version="1.0"?>
<form string="Audit Logs">
<field name="from" colspan="4"/>
<newline/>
<field name="to" colspan="4"/>
</form>'''
form1_fields = {
'from': {
'string': 'Log From',
'type': 'datetime',
},
'to': {
'string': 'Log To',
'type': 'datetime',
'default': lambda *a: time.strftime("%Y-%m-%d %H:%M:%S"),
'required':True
},
}
def _log_open_window(self, cr, uid, data, context):
mod_obj = pooler.get_pool(cr.dbname).get('ir.model.data')
act_obj = pooler.get_pool(cr.dbname).get('ir.actions.act_window')
result = mod_obj._get_id(cr, uid, 'audittrail', 'action_audittrail_log_tree')
id = mod_obj.read(cr, uid, [result], ['res_id'])[0]['res_id']
result = act_obj.read(cr, uid, [id])[0]
log_obj= pooler.get_pool(cr.dbname).get(result['res_model'])
log_id = log_obj.search(cr, uid, [])
log_model=log_obj.read(cr, uid,log_id,['object_id'])
if not data['form']['from']:
if data['form']['to'] <> time.strftime("%Y-%m-%d %H:%M:%S"):
result['domain'] = str([('timestamp', '<',data['form']['to'])])
else:
pass
else:
result['domain'] = str([('timestamp', '>',data['form']['from']),('timestamp', '<',data['form']['to'])])
return result
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', 'Cancel'), ('open', 'Open Logs')]}
},
'open': {
'actions': [],
'result': {'type': 'action', 'action':_log_open_window, 'state':'end'}
}
}
wizard_view_log('audittrail.view.log')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -29,61 +29,86 @@ from osv.orm import except_orm
from tools.translate import _
class base_action_rule(osv.osv):
""" Base Action Rules """
_name = 'base.action.rule'
_description = 'Action Rules'
_description = 'Action Rules'
_columns = {
'name': fields.many2one('ir.model', 'Model', required=True),
'max_level': fields.integer('Max Level', help='Specifies maximum level.'),
'max_level': fields.integer('Max Level', help='Specifies maximum level.'),
'rule_lines': fields.one2many('base.action.rule.line','rule_id','Rule Lines'),
'create_date': fields.datetime('Create Date', readonly=1),
'active': fields.boolean('Active')
}
_defaults = {
'active': lambda *a: True,
'max_level': lambda *a: 15,
}
def format_body(self, body):
""" Foramat Action rule's body
@param self: The object pointer """
return body and tools.ustr(body) or ''
def format_mail(self, obj, body):
""" Foramat Mail
@param self: The object pointer """
data = {
'object_id': obj.id,
'object_subject': hasattr(obj, 'name') and obj.name or False,
'object_date': hasattr(obj, 'date') and obj.date or False,
'object_description': hasattr(obj, 'description') and obj.description or False,
'object_user': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.name) or '/',
'object_user_email': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.address_id and obj.user_id.address_id.email) or '/',
'object_user_phone': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.address_id and obj.user_id.address_id.phone) or '/',
'object_user_email': hasattr(obj, 'user_id') and (obj.user_id and \
obj.user_id.address_id and obj.user_id.address_id.email) or '/',
'object_user_phone': hasattr(obj, 'user_id') and (obj.user_id and\
obj.user_id.address_id and obj.user_id.address_id.phone) or '/',
'partner': hasattr(obj, 'partner_id') and (obj.partner_id and obj.partner_id.name) or '/',
'partner_email': hasattr(obj, 'partner_address_id') and (obj.partner_address_id and obj.partner_address_id.email) or '/',
'partner_email': hasattr(obj, 'partner_address_id') and (obj.partner_address_id and\
obj.partner_address_id.email) or '/',
}
return self.format_body(body % data)
def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from',False), context={}):
""" send email
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param email: pass the emails
@param emailfrom: Pass name the email From else False
@param context: A standard dictionary for contextual values """
body = self.format_mail(obj, body)
if not emailfrom:
if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.address_id and obj.user_id.address_id.email:
if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.address_id and\
obj.user_id.address_id.email:
emailfrom = obj.user_id.address_id.email
name = '[%d] %s' % (obj.id, tools.ustr(obj.name))
emailfrom = tools.ustr(emailfrom)
reply_to = emailfrom
reply_to = emailfrom
if not emailfrom:
raise osv.except_osv(_('Error!'),
_("No E-Mail ID Found for your Company address!"))
return tools.email_send(emailfrom, emails, name, body, reply_to=reply_to, openobject_id=str(obj.id))
def do_check(self, cr, uid, action, obj, context={}):
ok = True
if hasattr(obj, 'user_id'):
""" check Action
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values """
ok = True
if hasattr(obj, 'user_id'):
ok = ok and (not action.trg_user_id.id or action.trg_user_id.id==obj.user_id.id)
if hasattr(obj, 'partner_id'):
ok = ok and (not action.trg_partner_id.id or action.trg_partner_id.id==obj.partner_id.id)
ok = ok and (not action.trg_partner_id.id or action.trg_partner_id.id==obj.partner_id.id)
ok = ok and (
not action.trg_partner_categ_id.id or
(
@ -113,14 +138,22 @@ class base_action_rule(osv.osv):
return ok
def do_action(self, cr, uid, action, model_obj, obj, context={}):
""" Do Action
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param action: pass action
@param model_obj: pass Model object
@param context: A standard dictionary for contextual values """
if action.server_action_id:
context.update({'active_id':obj.id,'active_ids':[obj.id]})
self.pool.get('ir.actions.server').run(cr, uid, [action.server_action_id.id], context)
write = {}
write = {}
if hasattr(obj, 'user_id') and action.act_user_id:
obj.user_id = action.act_user_id
write['user_id'] = action.act_user_id.id
if hasattr(obj, 'date_action_last'):
if hasattr(obj, 'date_action_last'):
write['date_action_last'] = time.strftime('%Y-%m-%d %H:%M:%S')
if hasattr(obj, 'state') and action.act_state:
obj.state = action.act_state
@ -135,7 +168,7 @@ class base_action_rule(osv.osv):
write['priority'] = action.act_priority
model_obj.write(cr, uid, [obj.id], write, context)
if hasattr(model_obj, 'remind_user') and action.act_remind_user:
model_obj.remind_user(cr, uid, [obj.id], context, attach=action.act_remind_attach)
if hasattr(model_obj, 'remind_partner') and action.act_remind_partner:
@ -146,7 +179,7 @@ class base_action_rule(osv.osv):
if hasattr(obj, 'user_id') and action.act_mail_to_user:
if obj.user_id and obj.user_id.address_id:
emails.append(obj.user_id.address_id.email)
if action.act_mail_to_watchers:
emails += (action.act_email_cc or '').split(',')
if action.act_mail_to_email:
@ -158,11 +191,19 @@ class base_action_rule(osv.osv):
return True
def _action(self, cr, uid, ids, objects, scrit=None, context={}):
""" Do Action
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Basic Action Rules IDs,
@param objects: pass objects
@param context: A standard dictionary for contextual values """
if not scrit:
scrit = []
rule_line_obj = self.pool.get('base.action.rule.line')
for rule in self.browse(cr, uid, ids):
level = rule.max_level
for rule in self.browse(cr, uid, ids):
level = rule.max_level
if not level:
break
newactions = []
@ -184,7 +225,8 @@ class base_action_rule(osv.osv):
base = mx.DateTime.strptime(obj.date_action_last, '%Y-%m-%d %H:%M:%S')
else:
base = mx.DateTime.strptime(obj.create_date[:19], '%Y-%m-%d %H:%M:%S')
elif hasattr(obj, 'date_deadline') and action.trg_date_type=='deadline' and obj.date_deadline:
elif hasattr(obj, 'date_deadline') and action.trg_date_type=='deadline' \
and obj.date_deadline:
base = mx.DateTime.strptime(obj.date_deadline, '%Y-%m-%d %H:%M:%S')
elif hasattr(obj, 'date') and action.trg_date_type=='date' and obj.date:
base = mx.DateTime.strptime(obj.date, '%Y-%m-%d %H:%M:%S')
@ -212,7 +254,7 @@ class base_action_rule(osv.osv):
if ok:
self.do_action(cr, uid, action, model_obj, obj, context)
break
break
level -= 1
return True
base_action_rule()
@ -222,20 +264,46 @@ class base_action_rule_line(osv.osv):
_description = 'Action Rule Lines'
def _state_get(self, cr, uid, context={}):
""" Get State
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values """
return self.state_get(cr, uid, context=context)
def _priority_get(self, cr, uid, context={}):
""" Get Priority
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values """
return self.priority_get(cr, uid, context=context)
def state_get(self, cr, uid, context={}):
""" Get State
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values """
return [('','')]
def priority_get(self, cr, uid, context={}):
""" Get Priority
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values """
return [('','')]
_columns = {
'name': fields.char('Rule Name',size=64, required=True),
'rule_id': fields.many2one('base.action.rule','Rule'),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the rule without removing it."),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of rules."),
'active': fields.boolean('Active', help="If the active field is set to true,\
it will allow you to hide the rule without removing it."),
'sequence': fields.integer('Sequence', help="Gives the sequence order when\
displaying a list of rules."),
'trg_date_type': fields.selection([
('none','None'),
@ -243,11 +311,13 @@ class base_action_rule_line(osv.osv):
('action_last','Last Action Date'),
('date','Date'),
], 'Trigger Date', size=16),
'trg_date_range': fields.integer('Delay after trigger date',help="Delay After Trigger Date, specifies you can put a negative number " \
"if you need a delay before the trigger date, like sending a reminder 15 minutes before a meeting."),
'trg_date_range_type': fields.selection([('minutes', 'Minutes'),('hour','Hours'),('day','Days'),('month','Months')], 'Delay type'),
'trg_date_range': fields.integer('Delay after trigger date',help="Delay After Trigger Date,\
specifies you can put a negative number " \
"if you need a delay before the trigger date, like sending a reminder 15 minutes before a meeting."),
'trg_date_range_type': fields.selection([('minutes', 'Minutes'),('hour','Hours'),\
('day','Days'),('month','Months')], 'Delay type'),
'trg_user_id': fields.many2one('res.users', 'Responsible'),
'trg_partner_id': fields.many2one('res.partner', 'Partner'),
@ -255,42 +325,59 @@ class base_action_rule_line(osv.osv):
'trg_state_from': fields.selection(_state_get, 'State', size=16),
'trg_state_to': fields.selection(_state_get, 'Button Pressed', size=16),
'trg_priority_from': fields.selection(_priority_get, 'Minimum Priority'),
'trg_priority_to': fields.selection(_priority_get, 'Maximum Priority'),
'act_method': fields.char('Call Object Method', size=64),
'act_user_id': fields.many2one('res.users', 'Set responsible to'),
'trg_priority_to': fields.selection(_priority_get, 'Maximum Priority'),
'act_method': fields.char('Call Object Method', size=64),
'act_user_id': fields.many2one('res.users', 'Set responsible to'),
'act_state': fields.selection(_state_get, 'Set state to', size=16),
'act_priority': fields.selection(_priority_get, 'Set priority to'),
'act_email_cc': fields.char('Add watchers (Cc)', size=250, help="These people will receive a copy of the future communication between partner and users by email"),
'act_priority': fields.selection(_priority_get, 'Set priority to'),
'act_email_cc': fields.char('Add watchers (Cc)', size=250, help="These people\
will receive a copy of the future communication between partner and users by email"),
'act_remind_partner': fields.boolean('Remind Partner', help="Check this if you want the rule to send a reminder by email to the partner."),
'act_remind_user': fields.boolean('Remind responsible', help="Check this if you want the rule to send a reminder by email to the user."),
'act_remind_partner': fields.boolean('Remind Partner', help="Check this if\
you want the rule to send a reminder by email to the partner."),
'act_remind_user': fields.boolean('Remind responsible', help="Check this if \
you want the rule to send a reminder by email to the user."),
'act_reply_to': fields.char('Reply-To', size=64),
'act_remind_attach': fields.boolean('Remind with attachment', help="Check this if you want that all documents attached to the object be attached to the reminder email sent."),
'act_remind_attach': fields.boolean('Remind with attachment', help="Check this if\
you want that all documents attached to the object be attached \
to the reminder email sent."),
'act_mail_to_user': fields.boolean('Mail to responsible',help="Check this if you want the rule to send an email to the responsible person."),
'act_mail_to_watchers': fields.boolean('Mail to watchers (CC)',help="Check this if you want the rule to mark CC(mail to any other person defined in actions)."),
'act_mail_to_email': fields.char('Mail to these emails', size=128,help="Email-id of the persons whom mail is to be sent"),
'act_mail_to_user': fields.boolean('Mail to responsible',help="Check this if \
you want the rule to send an email to the responsible person."),
'act_mail_to_watchers': fields.boolean('Mail to watchers (CC)',help="Check this\
if you want the rule to mark CC(mail to any other person\
defined in actions)."),
'act_mail_to_email': fields.char('Mail to these emails', size=128,help="Email-id \
of the persons whom mail is to be sent"),
'act_mail_body': fields.text('Mail body',help="Content of mail"),
'regex_name': fields.char('Regular Expression on Model Name', size=128),
'server_action_id': fields.many2one('ir.actions.server','Server Action',help="Describes the action name." \
"eg:on which object which action to be taken on basis of which condition"),
'server_action_id': fields.many2one('ir.actions.server','Server Action',help="Describes the\
action name." \
"eg:on which object which action to be taken on basis of which condition"),
}
_defaults = {
'active': lambda *a: 1,
'trg_date_type': lambda *a: 'none',
'trg_date_range_type': lambda *a: 'day',
'act_mail_to_user': lambda *a: 0,
'act_remind_partner': lambda *a: 0,
'act_remind_user': lambda *a: 0,
'act_remind_user': lambda *a: 0,
'act_mail_to_watchers': lambda *a: 0,
}
_order = 'sequence'
_order = 'sequence'
def _check_mail(self, cr, uid, ids, context=None):
""" Check Mail
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Action Rules IDs
@param context: A standard dictionary for contextual values """
empty = orm.browse_null()
rule_obj = self.pool.get('base.action.rule')
for rule in self.browse(cr, uid, ids):
@ -300,10 +387,11 @@ class base_action_rule_line(osv.osv):
except (ValueError, KeyError, TypeError):
return False
return True
_constraints = [
(_check_mail, 'Error: The mail is not well formated', ['act_mail_body']),
]
base_action_rule_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<menuitem id="menu_base_action_rule" name="Action Rule" parent="base.menu_base_config" sequence="0"/>
<menuitem id="menu_base_action_rule" name="Action Rule"
parent="base.menu_base_config" sequence="0" />
<!--
Action Rule
<!--
Action Rule Form View
-->
<record id="view_base_action_rule_form" model="ir.ui.view">
<field name="name">base.action.rule.form</field>
@ -21,6 +22,8 @@
</field>
</record>
<!-- Action Rule Tree View -->
<record id="view_base_action_rule_tree" model="ir.ui.view">
<field name="name">base.action.rule.tree</field>
<field name="model">base.action.rule</field>
@ -34,6 +37,8 @@
</field>
</record>
<!-- Action Rule Action -->
<record id="base_action_rule_act" model="ir.actions.act_window">
<field name="name">Action Rules</field>
<field name="res_model">base.action.rule</field>
@ -42,10 +47,11 @@
<field name="view_id" ref="view_base_action_rule_tree"/>
</record>
<menuitem id="menu_base_action_rule_form" parent="menu_base_action_rule" action="base_action_rule_act"/>
<menuitem id="menu_base_action_rule_form"
parent="menu_base_action_rule" action="base_action_rule_act" />
<!--
Action Rule Lines
<!--
Action Rule Lines Form View
-->
<record id="view_base_action_rule_line_form" model="ir.ui.view">
<field name="name">base.action.rule.line.form</field>
@ -127,6 +133,9 @@
</form>
</field>
</record>
<!-- Action Rule Lines Tree View -->
<record id="view_base_action_rule_line_tree" model="ir.ui.view">
<field name="name">base.action.rule.line.tree</field>
<field name="model">base.action.rule.line</field>

0
addons/base_calendar/__init__.py Normal file → Executable file
View File

47
addons/base_calendar/__terp__.py Normal file → Executable file
View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@ -15,36 +15,33 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name" : "Basic Calendar Functionality",
"version" : "1.0",
"depends" : [
"base",
],
'description': """
Full featured calendar system that support:
- Alerts (create requests)
- Recurring events (*)
- Invitations to other people
""",
"author" : "Tiny",
'category': 'Generic Modules/Others',
'website': 'http://www.openerp.com',
"name" : "Basic Calendar Functionality",
"version" : "1.0",
"depends" : ["base"],
'description': """Full featured calendar system that support:
- Alerts (create requests)
- Recurring events (*)
- Invitations to others people""",
"author" : "Tiny",
'category': 'Generic Modules/Others',
'website': 'http://www.openerp.com',
"init_xml" : [
'base_calendar_data.xml'
],
"demo_xml" : [],
'base_calendar_data.xml'
],
"demo_xml" : [],
"update_xml" : [
'security/ir.model.access.csv',
'base_calendar_view.xml'
],
"installable" : True,
"active" : False,
'security/ir.model.access.csv',
'wizard/calendar_event_edit_all_view.xml',
'wizard/base_calendar_invite_attendee_view.xml',
'base_calendar_view.xml'
],
"installable" : True,
"active" : False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

File diff suppressed because it is too large Load Diff

489
addons/base_calendar/base_calendar_data.xml Normal file → Executable file
View File

@ -1,376 +1,133 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<!-- Event attributes-->
<record model="basic.calendar.attributes" id="field_event_comment">
<field name="name">comment</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_uid">
<field name="name">uid</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_seq">
<field name="name">seq</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_recurrence-id">
<field name="name">recurrence-id</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_transp">
<field name="name">transp</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_attendee">
<field name="name">attendee</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_related">
<field name="name">related</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_rrule">
<field name="name">rrule</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_dtend">
<field name="name">dtend</field>
<field name="type">vevent</field>
<record model="res.alarm" id="alarm1">
<field name="name">1 minute before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="1" />
<field name="trigger_interval">minutes</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="res.alarm" id="alarm2">
<field name="name">5 minutes before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="5" />
<field name="trigger_interval">minutes</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="basic.calendar.attributes" id="field_event_valarm">
<field name="name">valarm</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_vtimezone">
<field name="name">vtimezone</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_priority">
<field name="name">priority</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_location">
<field name="name">location</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_exrule">
<field name="name">exrule</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_resources">
<field name="name">resources</field>
<field name="type">vevent</field>
</record>
<record model="res.alarm" id="alarm3">
<field name="name">10 minutes before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="10" />
<field name="trigger_interval">minutes</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="res.alarm" id="alarm4">
<field name="name">15 minutes before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="15" />
<field name="trigger_interval">minutes</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="res.alarm" id="alarm5">
<field name="name">30 minutes before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="30" />
<field name="trigger_interval">minutes</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="res.alarm" id="alarm6">
<field name="name">45 minutes before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="45" />
<field name="trigger_interval">minutes</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="res.alarm" id="alarm7">
<field name="name">1 hour before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="1" />
<field name="trigger_interval">hours</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="res.alarm" id="alarm8">
<field name="name">2 hours before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="2" />
<field name="trigger_interval">hours</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="res.alarm" id="alarm9">
<field name="name">3 hours before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="3" />
<field name="trigger_interval">hours</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="res.alarm" id="alarm10">
<field name="name">4 hours before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="4" />
<field name="trigger_interval">hours</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="res.alarm" id="alarm11">
<field name="name">5 hours before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="5" />
<field name="trigger_interval">hours</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="res.alarm" id="alarm12">
<field name="name">18 hours before</field>
<field name="active" eval="1" />
<field name="trigger_duration" eval="18" />
<field name="trigger_interval">hours</field>
<field name="trigger_occurs">before</field>
<field name="trigger_related">start</field>
</record>
<record model="basic.calendar.attributes" id="field_event_rstatus">
<field name="name">rstatus</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_status">
<field name="name">status</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_exdate">
<field name="name">exdate</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_dtstamp">
<field name="name">dtstamp</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_description">
<field name="name">description</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_rdate">
<field name="name">rdate</field>
<field name="type">vevent</field>
<!-- Scheduler for Event Alarm-->
<record forcecreate="True" id="ir_cron_scheduler_alarm"
model="ir.cron">
<field name="name">Run Event Reminder</field>
<field eval="True" name="active" />
<field name="user_id" ref="base.user_root" />
<field name="interval_number">1</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
<field eval="'calendar.alarm'" name="model" />
<field eval="'do_run_scheduler'" name="function" />
<field eval="'(False,)'" name="args" />
</record>
<record model="basic.calendar.attributes" id="field_event_dtstart">
<field name="name">dtstart</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_class">
<field name="name">class</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_x-openobject-model">
<field name="name">x-openobject-model</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_created">
<field name="name">created</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_url">
<field name="name">url</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_summary">
<field name="name">summary</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_contact">
<field name="name">contact</field>
<field name="type">vevent</field>
</record>
<!-- Todo attributes-->
<record model="basic.calendar.attributes" id="field_todo_status">
<field name="name">status</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_comment">
<field name="name">comment</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_attendee">
<field name="name">attendee</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_valarm">
<field name="name">valarm</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_description">
<field name="name">description</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_seq">
<field name="name">seq</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_vtimezone">
<field name="name">vtimezone</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_url">
<field name="name">url</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_completed">
<field name="name">completed</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_percent">
<field name="name">percent</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_due">
<field name="name">due</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_summary">
<field name="name">summary</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_priority">
<field name="name">priority</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_exdate">
<field name="name">exdate</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_location">
<field name="name">location</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_exrule">
<field name="name">exrule</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_duration">
<field name="name">duration</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_organizer">
<field name="name">organizer</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_dtstart">
<field name="name">dtstart</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_rrule">
<field name="name">rrule</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_class">
<field name="name">class</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_uid">
<field name="name">uid</field>
<field name="type">vtodo</field>
</record>
<!-- Attendee's attributes-->
<record model="basic.calendar.attributes" id="field_attendee_cn">
<field name="name">cn</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_sent-by">
<field name="name">sent-by</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_language">
<field name="name">language</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_delegated-from">
<field name="name">delegated-from</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_member">
<field name="name">member</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_cutype">
<field name="name">cutype</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_role">
<field name="name">role</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_partstat">
<field name="name">partstat</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_delegated-to">
<field name="name">delegated-to</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_dir">
<field name="name">dir</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_rsvp">
<field name="name">rsvp</field>
<field name="type">attendee</field>
</record>
<!-- Alarm attributes-->
<record model="basic.calendar.attributes" id="field_alarm_attendee">
<field name="name">attendee</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_duration">
<field name="name">trigger_duration</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_description">
<field name="name">description</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_attach">
<field name="name">attach</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_occurs">
<field name="name">trigger_occurs</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_interval">
<field name="name">trigger_interval</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_summary">
<field name="name">summary</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_duration">
<field name="name">duration</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_repeat">
<field name="name">repeat</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_action">
<field name="name">action</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_related">
<field name="name">trigger_related</field>
<field name="type">alarm</field>
</record>
</data>
</openerp>

216
addons/base_calendar/base_calendar_view.xml Normal file → Executable file
View File

@ -1,141 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Attendee invite wizard-->
<record id="view_calendar_invite_attendee_wizard" model="ir.ui.view">
<field name="name">Invite Attendees</field>
<field name="model">base_calendar.invite.attendee</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Invite People">
<field name="type" />
<field name="send_mail" />
<newline/>
<group col="1" colspan="4"
attrs="{'invisible': [('type', '!=', 'external')]}">
<field name="email" colspan="4"
attrs="{'required': [('type', '=', 'external')]}" />
</group>
<group col="1" colspan="4"
attrs="{'invisible': [('type', '!=', 'internal')]}">
<separator string="Users" colspan="4" />
<field name="user_ids" select="1" colspan="4"
nolabel="1" />
<newline />
</group>
<group col="2" colspan="4"
attrs="{'invisible': [('type', '!=', 'partner')]}">
<field name="partner_id" colspan="2"
on_change="onchange_partner_id(partner_id)"
attrs="{'required': [('type', '=', 'partner')]}" />
<newline />
<separator string="Partner Contacts"
colspan="4" />
<field name="contact_ids" select="1" colspan="4"
nolabel="1" domain="[('partner_id', '=', partner_id)]"
attrs="{'readonly': [('type', '!=', 'partner')]}" />
</group>
<newline/>
<separator string="" colspan="6" />
<label string="" colspan="2" />
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="do_invite" string="Invite"
type="object" icon="gtk-ok" />
</form>
</field>
</record>
<record id="action_view_calendar_invite_attendee_wizard" model="ir.actions.act_window">
<field name="name">Invite Attendees</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">base_calendar.invite.attendee</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<record id="base_calendar_attendee_form_view" model="ir.ui.view">
<field name="name">calendar.attendee.form</field>
<field name="model">calendar.attendee</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Invitation details">
<field name="email" string="Invitation To"/>
<field name="sent_by_uid" string="Invitation From"/>
<notebook colspan="4">
<page string="Invitation">
<form string="Invitation details">
<field name="email" string="Invitation To"/>
<field name="sent_by_uid" string="Invitation From" />
<notebook colspan="4">
<page string="Invitation">
<separator string="Invitation Detail" colspan="4" />
<group colspan="4" col="4">
<field name="user_id" string="Invited User"/>
<newline/>
<field name="partner_address_id" string="Partner Contact"/>
<field name="partner_id" string="Partner" readonly="1"/>
<field name="partner_address_id"
string="Partner Contact" />
<field name="partner_id"
string="Partner" readonly="1" />
<field name="role" string="Role" />
<field name="cutype" string="Invitation type" />
<field name="rsvp" />
<field name="rsvp" />
</group>
<separator string="Event Detail" colspan="4" />
<group colspan="4" col="4">
<field name="event_date" />
<field name="event_end_date" />
<field name="language"/>
<field name="ref" colspan="4"/>
<field name="ref" colspan="4" readonly="1"/>
</group>
</page>
<page string="Delegation Info">
<separator string="Delegated From" colspan="4" />
<field name="parent_ids" nolabel="1"
colspan="4" readonly="1" />
<separator string="Delegated To" colspan="4" />
<field name="child_ids" nolabel="1"
colspan="4" readonly="1" />
</page>
</notebook>
<group col="6" colspan="4">
<field name="state" select="2" />
<button name="do_tentative" states="needs-action,declined,accepted"
string="Uncertain" type="object"
icon="terp-crm" />
<button name="do_accept" string="Accept" states="needs-action,tentative,declined"
type="object" icon="gtk-apply" />
<button name="do_decline" string="Decline" states="needs-action,tentative,accepted"
type="object" icon="gtk-cancel" />
<button
name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d"
string="Delegate" type="action"
icon="gtk-sort-descending" states="needs-action,tentative,declined,accepted"
context="{'model' : 'calendar.attendee', 'attendee_field' : 'child_ids'}" />
</group>
</form>
</page>
<page string="Delegation Info">
<separator string="Delegated From" colspan="4" />
<field name="parent_ids" nolabel="1"
colspan="4" readonly="1" />
<separator string="Delegated To" colspan="4" />
<field name="child_ids" nolabel="1"
colspan="4" readonly="1" />
</page>
</notebook>
<group col="6" colspan="4">
<field name="state" />
<button name="do_tentative"
states="needs-action,declined,accepted"
string="Uncertain" type="object"
icon="terp-crm" />
<button name="do_accept" string="Accept"
states="needs-action,tentative,declined"
type="object" icon="gtk-apply" />
<button name="do_decline" string="Decline"
states="needs-action,tentative,accepted"
type="object" icon="gtk-cancel" />
<button
name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d"
string="Delegate" type="action"
icon="gtk-sort-descending"
states="needs-action,tentative,declined,accepted"
context="{'model' : 'calendar.attendee', 'attendee_field' : 'child_ids'}" />
</group>
</form>
</field>
</record>
<record id="base_calendar_attendee_tree_view" model="ir.ui.view">
<record id="base_calendar_attendee_tree_view" model="ir.ui.view">
<field name="name">calendar.attendee.tree</field>
<field name="model">calendar.attendee</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Invitation details">
<field name="email" string="Invitation To"/>
<tree string="Invitation details">
<field name="email" string="Invitation To"/>
<field name="partner_id" string="Partner" />
<field name="partner_address_id" string="Contact" />
<field name="role" />
<field name="state" />
</tree>
<field name="role" />
<field name="state" />
</tree>
</field>
</record>
</record>
<record id="base_calendar_attendee_search_view" model="ir.ui.view">
<field name="name">calendar.attendee.search</field>
<field name="model">calendar.attendee</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Invitations">
<filter icon="gtk-apply" string="Accepted"
domain="[('state','=', 'accepted')]"
separator="1" help="Accepted Invitations" />
<filter icon="gtk-close" string="Declined"
domain="[('state','=', 'declined')]"
separator="1" help="Declined Invitations" />
<separator orientation="vertical"/>
<field name="email" select='1'/>
<field name="sent_by_uid" select="1" widget="selection"/>
<separator orientation="vertical"/>
<field name="cutype" string="Invitation type" select="1"/>
<field name="event_date" select="1"/>
</search>
</field>
</record>
<record id="res_alarm_form_view" model="ir.ui.view">
<field name="name">res.alarm.form</field>
<field name="model">res.alarm</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Reminder details">
<form string="Reminder details">
<field name="name" />
<field name="active" />
<separator string="Reminder Details" colspan="4" />
@ -146,7 +117,7 @@
<separator string="" colspan="4" />
<field name="duration" />
<field name="repeat" />
</form>
</form>
</field>
</record>
@ -154,34 +125,31 @@
<field name="name">res.alarm.tree</field>
<field name="model">res.alarm</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Reminder details">
<field name="name" select="1"/>
<field name="trigger_interval" select="1"/>
<field name="trigger_duration" select="1"/>
<field name="trigger_occurs" select="1"/>
<field name="trigger_related" select="1"/>
</tree>
<field name="arch" type="xml">
<tree string="Reminder details">
<field name="name" select="1"/>
<field name="trigger_interval" select="1"/>
<field name="trigger_duration" select="1"/>
<field name="trigger_occurs" select="1"/>
<field name="trigger_related" select="1"/>
</tree>
</field>
</record>
<record id="action_res_alarm_view" model="ir.actions.act_window">
<field name="name">Available Alarms</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.alarm</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="name">Available Alarms</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.alarm</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<!-- Available alarms-->
<menuitem id="base.menu_calendar_configuration" name="Calendar"
parent="base.menu_base_config" sequence="10" />
<!--Available alarms-->
<menuitem id="base.menu_calendar_configuration" name="Calendar"
parent="base.menu_base_config" sequence="10" />
<menuitem name="Available Alarms" id="menu_crm_meeting_avail_alarm"
action="base_calendar.action_res_alarm_view"
parent="base.menu_calendar_configuration" />
<menuitem name="Available Alarms" id="menu_crm_meeting_avail_alarm"
action="base_calendar.action_res_alarm_view"
parent="base.menu_calendar_configuration" />
</data>
</openerp>

1
addons/base_calendar/security/ir.model.access.csv Normal file → Executable file
View File

@ -5,3 +5,4 @@
"access_calendar_event_all","calendar.event","model_calendar_event",,1,1,1,1
"access_calendar_todo","calendar.todo","model_calendar_todo",,1,1,1,1
"access_base_calendar_invite_attendee","base_calendar.invite.attendee","model_base_calendar_invite_attendee",,1,1,1,1
"access_calendar_event_edit_all","calendar_event_edit_all","model_calendar_event_edit_all",,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
5 access_calendar_event_all calendar.event model_calendar_event 1 1 1 1
6 access_calendar_todo calendar.todo model_calendar_todo 1 1 1 1
7 access_base_calendar_invite_attendee base_calendar.invite.attendee model_base_calendar_invite_attendee 1 1 1 1
8 access_calendar_event_edit_all calendar_event_edit_all model_calendar_event_edit_all 1 1 1 1

4
addons/base_calendar/wizard/__init__.py Normal file → Executable file
View File

@ -18,7 +18,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard_cal_edit_event
import calendar_event_edit_all
import base_calendar_invite_attendee
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,170 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from base_calendar import base_calendar
from osv import fields, osv
from tools.translate import _
import tools
class base_calendar_invite_attendee(osv.osv_memory):
"""
Invite attendee.
"""
_name = "base_calendar.invite.attendee"
_description = "Invite Attendees"
_columns = {
'type': fields.selection([('internal', 'Internal User'), \
('external', 'External Email'), \
('partner', 'Partner Contacts')], 'Type', required=True),
'user_ids': fields.many2many('res.users', 'invite_user_rel',
'invite_id', 'user_id', 'Users'),
'partner_id': fields.many2one('res.partner', 'Partner'),
'email': fields.char('Email', size=124),
'contact_ids': fields.many2many('res.partner.address', 'invite_contact_rel',
'invite_id', 'contact_id', 'Contacts'),
'send_mail': fields.boolean('Send mail?', help='Check this if you want to \
send an Email to Invited Person')
}
_defaults = {
'type': lambda *x: 'internal'
}
def do_invite(self, cr, uid, ids, context=None):
"""
Invites attendee for meeting..
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of base calendar invite attendees IDs.
@param context: A standard dictionary for contextual values
@return: Dictionary of {}.
"""
if not context:
context = {}
model = False
model_field = False
context_id = context and context.get('active_id', False) or False
if not context or not context.get('model'):
return {}
else:
model = context.get('model')
model_field = context.get('attendee_field', False)
for datas in self.read(cr, uid, ids, context=context):
obj = self.pool.get(model)
res_obj = obj.browse(cr, uid, context_id)
type = datas.get('type')
att_obj = self.pool.get('calendar.attendee')
vals = []
mail_to = []
attendees = []
ref = {}
if not model == 'calendar.attendee':
if context_id:
ref = {'ref': '%s,%s' % (model, base_calendar.base_calendar_id2real_id(context_id))}
else:
return {}
if type == 'internal':
user_obj = self.pool.get('res.users')
if not datas.get('user_ids'):
raise osv.except_osv(_('Error!'), ("Please select any User"))
for user_id in datas.get('user_ids'):
user = user_obj.browse(cr, uid, user_id)
res = {
'user_id': user_id,
'email': user.address_id.email
}
res.update(ref)
vals.append(res)
if user.address_id.email:
mail_to.append(user.address_id.email)
elif type == 'external' and datas.get('email'):
res = {'email': datas['email']}
res.update(ref)
vals.append(res)
mail_to.append(datas['email'])
elif type == 'partner':
add_obj = self.pool.get('res.partner.address')
for contact in add_obj.browse(cr, uid, datas['contact_ids']):
res = {
'partner_address_id': contact.id,
'email': contact.email
}
res.update(ref)
vals.append(res)
if contact.email:
mail_to.append(contact.email)
att = att_obj.browse(cr, uid, context_id)
for att_val in vals:
if model == 'calendar.attendee':
if ref:
att_val.update({
'parent_ids': [(4, att.id)],
'ref': att.ref._name + ',' +str(att.ref.id)
})
attendees.append(att_obj.create(cr, uid, att_val))
if model_field:
for attendee in attendees:
obj.write(cr, uid, res_obj.id, {model_field: [(4, attendee)]})
if datas.get('send_mail'):
if not mail_to:
name = map(lambda x: x[1], filter(lambda x: type==x[0], \
self._columns['type'].selection))
raise osv.except_osv(_('Error!'), ("%s must have an email Address to send mail") %(name[0]))
att_obj._send_mail(cr, uid, attendees, mail_to, \
email_from= tools.config.get('email_from', False))
return {}
def onchange_partner_id(self, cr, uid, ids, partner_id, *args, **argv):
"""
Make entry on contact_ids on change of partner_id field.
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of base calendar invite attendees IDs.
@param partner_id: id of Partner
@return: dictionary of value.
"""
if not partner_id:
return {'value': {'contact_ids': []}}
cr.execute('select id from res_partner_address \
where partner_id=%s' % (partner_id))
contacts = map(lambda x: x[0], cr.fetchall())
return {'value': {'contact_ids': contacts}}
base_calendar_invite_attendee()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Attendee invite wizard-->
<record id="view_calendar_invite_attendee_wizard"
model="ir.ui.view">
<field name="name">Invite Attendees</field>
<field name="model">base_calendar.invite.attendee</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Invite People">
<field name="type" />
<field name="send_mail" />
<newline />
<group col="1" colspan="4"
attrs="{'invisible': [('type', '!=', 'external')]}">
<field name="email" colspan="4"
attrs="{'required': [('type', '=', 'external')]}" />
</group>
<group col="1" colspan="4"
attrs="{'invisible': [('type', '!=', 'internal')]}">
<separator string="Users" colspan="4" />
<field name="user_ids" select="1" colspan="4"
nolabel="1" />
<newline />
</group>
<group col="2" colspan="4"
attrs="{'invisible': [('type', '!=', 'partner')]}">
<field name="partner_id" colspan="2"
on_change="onchange_partner_id(partner_id)"
attrs="{'required': [('type', '=', 'partner')]}" />
<newline />
<separator string="Partner Contacts"
colspan="4" />
<field name="contact_ids" select="1" colspan="4"
nolabel="1" domain="[('partner_id', '=', partner_id)]"
attrs="{'readonly': [('type', '!=', 'partner')]}" />
</group>
<newline />
<separator string="" colspan="6" />
<label string="" colspan="2" />
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="do_invite" string="Invite"
type="object" icon="gtk-ok" />
</form>
</field>
</record>
<!-- Attendee invite action-->
<record id="action_view_calendar_invite_attendee_wizard" model="ir.actions.act_window">
<field name="name">Invite Attendees</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">base_calendar.invite.attendee</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv
from osv import fields
class calendar_event_edit_all(osv.osv_memory):
def _default_values(self, cr, uid, context={}):
""" Get Default value for Start Date
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values
@Return: Get Default value for Start Date
"""
context_id = context and context.get('active_id', False) or False
if context_id:
if context.get('date'):
return context.get('date')
else:
model = context.get('model', False)
model_obj = self.pool.get(model)
event = model_obj.read(cr, uid, context_id, ['name', 'location', 'alarm_id'])
return event['date']
def _default_deadline(self, cr, uid, context={}):
""" Get Default value for End Date
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values
@return: Get Default value for End Date
"""
context_id = context and context.get('active_id', False) or False
if context_id:
if context.get('date_deadline'):
return context.get('date_deadline')
else:
model = context.get('model', False)
model_obj = self.pool.get(model)
event = model_obj.read(cr, uid, context_id, ['name', 'location', 'alarm_id'])
return event['date_deadline']
def modify_this(self, cr, uid, ids, context=None):
"""
Modify All event for Crm Meeting.
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of calendar event edit alls IDs
@return: dictionary {}
"""
if not context:
context = {}
context_id = context and context.get('active_id', False) or False
if context_id:
for datas in self.read(cr, uid, ids):
model = context.get('model', False)
model_obj = self.pool.get(model)
model_obj.modify_all(cr, uid, [context_id], datas, context=context)
return {}
_name = "calendar.event.edit.all"
_description = "Calendar Edit all event"
_columns = {
'name': fields.char('Title', size=64, required=True),
'date': fields.datetime('Start Date', required=True),
'date_deadline': fields.datetime('End Date', required=True),
'location': fields.char('Location', size=124),
'alarm_id': fields.many2one('res.alarm', 'Reminder'),
}
_defaults = {
'date': _default_values,
'date_deadline': _default_deadline
}
calendar_event_edit_all()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_calendar_event_edit_all" model="ir.ui.view">
<field name="name">calendar.event.edit.all.form</field>
<field name="model">calendar.event.edit.all</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Edit all Occurrences">
<group colspan="4" >
<separator string="" colspan="4" />
<newline/>
<field name='name' colspan="4" />
<newline />
<field name='location' colspan="4" />
<newline />
<field name='date' />
<field name='date_deadline' />
<newline />
<field name='alarm_id'/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-save" string="_Save" name="modify_this" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_calendar_event_edit_all" model="ir.actions.act_window">
<field name="name">Edit all events</field>
<field name="res_model">calendar.event.edit.all</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_calendar_event_edit_all"/>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -1,78 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
import pooler
class event_edit_all(wizard.interface):
event_form = """<?xml version="1.0"?>
<form string="Edit all Occurrences">
<separator string="" colspan="4" />
<newline />
<field name='name' colspan="4" />
<newline />
<field name='location' colspan="4" />
<newline />
<field name='date' />
<field name='date_deadline' />
<newline />
<field name='alarm_id'/>
</form>"""
event_fields = {
'name': {'string': 'Title', 'type': 'char', 'size': 64, 'required': True},
'date': {'string': 'Start Date', 'type': 'datetime', 'required': True},
'date_deadline': {'string': 'End Date', 'type': 'datetime', 'required': True},
'location': {'string': 'Location', 'type': 'char', 'size': 124},
'alarm_id': {'string': 'Reminder', 'type': 'many2one', 'relation': 'res.alarm'},
}
def _default_values(self, cr, uid, data, context=None):
model = data.get('model')
model_obj = pooler.get_pool(cr.dbname).get(model)
event = model_obj.read(cr, uid, data['id'], ['name', 'location', 'alarm_id'])
event.update({
'date': context.get('date'),
'date_deadline': context.get('date_deadline')
})
return event
def _modify_all(self, cr, uid, datas, context=None):
model = datas.get('model')
model_obj = pooler.get_pool(cr.dbname).get(model)
model_obj.modify_all(cr, uid, datas['id'], datas['form'], context)
return {}
states = {
'init': {
'actions': [_default_values],
'result': {'type': 'form', 'arch': event_form, 'fields': event_fields,
'state': [('end', 'Cancel', 'gtk-cancel'), ('edit', '_Save', 'gtk-save')]}
},
'edit': {
'actions': [],
'result': {'type': 'action', 'action': _modify_all, 'state': 'end'}
}
}
event_edit_all('calendar.event.edit.all')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@ -23,16 +23,19 @@ import netsvc
from osv import fields, osv
class res_partner_contact(osv.osv):
""" Partner Contact """
_name = "res.partner.contact"
_description = "res.partner.contact"
# def init(self, cr):
# address_obj = self.pool.get('res.partner.address')
# job_obj = self.pool.get('res.partner.job')
# address_ids = address_obj.search(cr, 1, [])
# for address in address_obj.browse(cr, 1, address_ids):
# contact_id = self.create(cr, 1, {'name': address.name or 't'})
def _title_get(self,cr, user, context={}):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param user: the current user,
@param context: A standard dictionary for contextual values
"""
obj = self.pool.get('res.partner.title')
ids = obj.search(cr, user, [])
res = obj.read(cr, user, ids, ['shortcut', 'name','domain'], context)
@ -40,6 +43,16 @@ class res_partner_contact(osv.osv):
return res
def _main_job(self, cr, uid, ids, fields, arg, context=None):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of partner contacts IDs
@fields: Get Fields
@param context: A standard dictionary for contextual values
@param arg: list of tuples of form [(name_of_the_field, operator, value), ...]. """
res = dict.fromkeys(ids, False)
for contact in self.browse(cr, uid, ids, context):
if contact.job_ids:
@ -49,30 +62,43 @@ class res_partner_contact(osv.osv):
_columns = {
'name': fields.char('Last Name', size=30,required=True),
'first_name': fields.char('First Name', size=30),
'mobile':fields.char('Mobile',size=30),
'mobile': fields.char('Mobile',size=30),
'title': fields.selection(_title_get, 'Title'),
'website':fields.char('Website',size=120),
'lang_id':fields.many2one('res.lang','Language'),
'job_ids':fields.one2many('res.partner.job','contact_id','Functions and Addresses'),
'country_id':fields.many2one('res.country','Nationality'),
'birthdate':fields.date('Birth Date'),
'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the partner contact without removing it."),
'partner_id':fields.related('job_ids','address_id','partner_id',type='many2one', relation='res.partner', string='Main Employer'),
'function_id':fields.related('job_ids','function_id',type='many2one', relation='res.partner.function', string='Main Function'),
'job_id': fields.function(_main_job, method=True, type='many2one', relation='res.partner.job', string='Main Job'),
'website': fields.char('Website',size=120),
'lang_id': fields.many2one('res.lang','Language'),
'job_ids': fields.one2many('res.partner.job','contact_id','Functions and Addresses'),
'country_id': fields.many2one('res.country','Nationality'),
'birthdate': fields.date('Birth Date'),
'active': fields.boolean('Active', help="If the active field is set to true,\
it will allow you to hide the partner contact without removing it."),
'partner_id': fields.related('job_ids','address_id','partner_id',type='many2one',\
relation='res.partner', string='Main Employer'),
'function_id': fields.related('job_ids','function_id',type='many2one', \
relation='res.partner.function', string='Main Function'),
'job_id': fields.function(_main_job, method=True, type='many2one',\
relation='res.partner.job', string='Main Job'),
'email': fields.char('E-Mail', size=240),
'comment' : fields.text('Notes', translate=True),
'photo' : fields.binary('Image'),
'comment': fields.text('Notes', translate=True),
'photo': fields.binary('Image'),
}
_defaults = {
'active' : lambda *a: True,
}
_order = "name,first_name"
def name_get(self, cr, user, ids, context={}):
#will return name and first_name.......
""" will return name and first_name.......
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param user: the current users ID for security checks,
@param ids: List of create menus IDs
@return: name and first_name
@param context: A standard dictionary for contextual values
"""
if not len(ids):
return []
res = []
@ -84,60 +110,93 @@ class res_partner_contact(osv.osv):
addr += (r.get('first_name', '') or '')
res.append((r['id'], addr))
return res
res_partner_contact()
class res_partner_address(osv.osv):
def search(self, cr, user, args, offset=0, limit=None, order=None,
context=None, count=False):
""" search parnter address
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param user: the current user
@param args: list of tuples of form [(name_of_the_field, operator, value), ...].
@param offset: The Number of Results to Pass
@param limit: The Number of Results to Return
@param context: A standard dictionary for contextual values
"""
if context and context.has_key('address_partner_id' ) and context['address_partner_id']:
args.append(('partner_id', '=', context['address_partner_id']))
return super(res_partner_address, self).search(cr, user, args, offset, limit, order, context, count)
#overriding of the name_get defined in base in order to remove the old contact name
def name_get(self, cr, user, ids, context={}):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param user: the current user,
@param ids: List of partner addresss IDs
@param context: A standard dictionary for contextual values
"""
if not len(ids):
return []
res = []
for r in self.read(cr, user, ids, ['zip','city','partner_id', 'street']):
for r in self.read(cr, user, ids, ['zip', 'city', 'partner_id', 'street']):
if context.get('contact_display', 'contact')=='partner' and r['partner_id']:
res.append((r['id'], r['partner_id'][1]))
else:
addr = str('')
addr += "%s %s %s" % ( r.get('street', '') or '', r.get('zip', '') or '', r.get('city', '') or '' )
addr += "%s %s %s" % (r.get('street', '') or '', r.get('zip', '') \
or '', r.get('city', '') or '')
res.append((r['id'], addr.strip() or '/'))
return res
_name = 'res.partner.address'
_inherit='res.partner.address'
_inherit = 'res.partner.address'
_description ='Partner Address'
_columns = {
'job_id':fields.related('job_ids','contact_id','job_id',type='many2one', relation='res.partner.job', string='Main Job'),
'job_ids':fields.one2many('res.partner.job', 'address_id', 'Contacts'),
'job_id': fields.related('job_ids','contact_id','job_id',type='many2one',\
relation='res.partner.job', string='Main Job'),
'job_ids': fields.one2many('res.partner.job', 'address_id', 'Contacts'),
}
res_partner_address()
class res_partner_job(osv.osv):
# def init(self, cr):
# address_obj = self.pool.get('res.partner.address')
# contact_obj = self.pool.get('res.partner.contact')
# address_ids = address_obj.search(cr, 1, [])
# for address in address_obj.browse(cr, 1, address_ids):
# contact_id = contact_obj.search(cr, 1, [('name','=', address.name)])
# if contact_id:
# contact_id = contact_id[0]
# self.create(cr, 1, {'address_id': address.id, 'contact_id': contact_id})
def name_get(self, cr, uid, ids, context={}):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param user: the current user,
@param ids: List of partner addresss IDs
@param context: A standard dictionary for contextual values
"""
if not len(ids):
return []
res = []
for r in self.browse(cr, uid, ids):
funct = r.function_id and (", " + r.function_id.name) or ""
res.append((r.id, self.pool.get('res.partner.contact').name_get(cr, uid, [r.contact_id.id])[0][1] + funct))
res.append((r.id, self.pool.get('res.partner.contact').name_get(cr, uid, \
[r.contact_id.id])[0][1] + funct))
return res
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
""" search parnter job
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param user: the current user
@param args: list of tuples of form [(name_of_the_field, operator, value), ...].
@param offset: The Number of Results to Pass
@param limit: The Number of Results to Return
@param context: A standard dictionary for contextual values
"""
job_ids = []
for arg in args:
if arg[0] == 'address_id':
@ -147,12 +206,14 @@ class res_partner_job(osv.osv):
contact_obj = self.pool.get('res.partner.contact')
search_arg = ['|', ('first_name', 'ilike', arg[2]), ('name', 'ilike', arg[2])]
contact_ids = contact_obj.search(cr, user, search_arg, offset=offset, limit=limit, order=order, context=context, count=count)
contact_ids = contact_obj.search(cr, user, search_arg, offset=offset, \
limit=limit, order=order, context=context, count=count)
contacts = contact_obj.browse(cr, user, contact_ids, context=context)
for contact in contacts:
job_ids.extend([item.id for item in contact.job_ids])
res = super(res_partner_job,self).search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
res = super(res_partner_job,self).search(cr, user, args, offset=offset,\
limit=limit, order=order, context=context, count=count)
if job_ids:
res = list(set(res + job_ids))
@ -161,27 +222,36 @@ class res_partner_job(osv.osv):
_name = 'res.partner.job'
_description ='Contact Partner Function'
_order = 'sequence_contact'
_columns = {
'name': fields.related('address_id','partner_id', type='many2one', relation='res.partner', string='Partner', help="You may enter Address first,Partner will be linked automatically if any."),
'address_id':fields.many2one('res.partner.address','Address', help='Address which is linked to the Partner'),
'contact_id':fields.many2one('res.partner.contact','Contact', required=True, ondelete='cascade'),
'function_id': fields.many2one('res.partner.function','Partner Function', help="Function of this contact with this partner"),
'sequence_contact':fields.integer('Contact Seq.',help='Order of importance of this address in the list of addresses of the linked contact'),
'sequence_partner':fields.integer('Partner Seq.',help='Order of importance of this job title in the list of job title of the linked partner'),
'name': fields.related('address_id','partner_id', type='many2one',\
relation='res.partner', string='Partner', help="You may\
enter Address first,Partner will be linked automatically if any."),
'address_id': fields.many2one('res.partner.address','Address', \
help='Address which is linked to the Partner'),
'contact_id': fields.many2one('res.partner.contact','Contact', required=True, ondelete='cascade'),
'function_id': fields.many2one('res.partner.function','Partner Function', \
help="Function of this contact with this partner"),
'sequence_contact': fields.integer('Contact Seq.',help='Order of\
importance of this address in the list of addresses of the linked contact'),
'sequence_partner': fields.integer('Partner Seq.',help='Order of importance\
of this job title in the list of job title of the linked partner'),
'email': fields.char('E-Mail', size=240, help="Job E-Mail"),
'phone': fields.char('Phone', size=64, help="Job Phone no."),
'fax': fields.char('Fax', size=64, help="Job FAX no."),
'extension': fields.char('Extension', size=64, help='Internal/External extension phone number'),
'other': fields.char('Other', size=64, help='Additional phone field'),
'date_start' : fields.date('Date Start',help="Start date of job(Joining Date)"),
'date_stop' : fields.date('Date Stop', help="Last date of job"),
'state' : fields.selection([('past', 'Past'),('current', 'Current')], 'State', required=True, help="Status of Address"),
'date_start': fields.date('Date Start',help="Start date of job(Joining Date)"),
'date_stop': fields.date('Date Stop', help="Last date of job"),
'state': fields.selection([('past', 'Past'),('current', 'Current')], \
'State', required=True, help="Status of Address"),
}
_defaults = {
'sequence_contact' : lambda *a: 0,
'state' : lambda *a: 'current',
'state': lambda *a: 'current',
}
res_partner_job()

View File

@ -2,7 +2,8 @@
<openerp>
<data>
<!-- Views for Contacts -->
<!-- Views for Contacts Tree View -->
<record model="ir.ui.view" id="view_partner_contact_tree">
<field name="name">res.partner.contact.tree</field>
<field name="model">res.partner.contact</field>
@ -20,6 +21,8 @@
</field>
</record>
<!-- Views for Contacts Form View -->
<record model="ir.ui.view" id="view_partner_contact_form">
<field name="name">res.partner.contact.form</field>
<field name="model">res.partner.contact</field>
@ -93,6 +96,8 @@
</field>
</record>
<!-- Views for Contacts Search View -->
<record model="ir.ui.view" id="view_partner_contact_search">
<field name="name">res.partner.contact.search</field>
<field name="model">res.partner.contact</field>
@ -106,6 +111,8 @@
</field>
</record>
<!-- Views for Contacts Action -->
<record model="ir.actions.act_window" id="action_partner_contact_form">
<field name="name">Contacts</field>
<field name="res_model">res.partner.contact</field>
@ -116,7 +123,7 @@
</record>
<menuitem name="Contacts" id="menu_partner_contact_form" action="action_partner_contact_form" parent = "base.menu_address_book" sequence="2"/>
<!-- Views for Partners -->
<!-- Views for Partners Form View -->
<record model="ir.ui.view" id="view_partner_form_inherit">
<field name="name">Partner form inherited</field>
@ -186,6 +193,7 @@
<!-- don't display the categories, since it is displayed in an other tab-->
<record model="ir.ui.view" id="view_partner_form_inherit2">
<field name="name">res.partner.form</field>
<field name="type">form</field>
@ -198,6 +206,7 @@
</record>
<!-- don't display the categories label-->
<record model="ir.ui.view" id="view_partner_form_inherit2bis">
<field name="name">res.partner.form</field>
<field name="type">form</field>
@ -225,6 +234,7 @@
<!-- Views for Addresses -->
<record model="ir.ui.view" id="view_partner_address_tree_inherited1">
<field name="name">Partner addresses inherited</field>
<field name="model">res.partner.address</field>
@ -306,39 +316,6 @@
</field>
</record>
<!--
<record id='view_partner_address_form_inherited5' model='ir.ui.view'>
<field name='name'>res.partner.address.form.inherited5</field>
<field name='model'>res.partner.address</field>
<field name="inherit_id" ref="base.view_partner_address_form1"/>
<field name='type'>form</field>
<field name='arch' type='xml'>
<group string="Communication" colspan="2" col="2" position="after">
<newline/>
<field name="job_ids" mode="tree,form" colspan="4">
<tree string="Contacts" editable="top">
<field name="contact_id"/>
<field name="function_id"/>
<field name="phone"/>
<field name="fax"/>
<field name="extension"/>
<field name="email"/>
</tree>
<form string="Contacts">
<field name="contact_id"/>
<field name="function_id"/>
<field name="phone"/>
<field name="fax"/>
<field name="extension"/>
<field name="email" widget="email"/>
</form>
</field>
</group>
</field>
</record>
-->
<record id="view_res_partner_address_filter" model="ir.ui.view">
<field name="name">res.partner.address.select</field>
<field name="model">res.partner.address</field>
@ -351,8 +328,8 @@
</field>
</record>
<!-- Views for partner job Tree view -->
<!-- Views for res.partner.job -->
<record model="ir.ui.view" id="view_partner_job_tree">
<field name="name">res.partner.job.tree</field>
<field name="model">res.partner.job</field>
@ -372,6 +349,8 @@
</field>
</record>
<!-- Views for partner job Form view -->
<record model="ir.ui.view" id="view_partner_job_form">
<field name="name">res.partner.job.form</field>
<field name="model">res.partner.job</field>
@ -400,19 +379,14 @@
</record>
<!-- Menuitem for res.partner.job -->
<record model="ir.actions.act_window" id="action_res_partner_job">
<field name="name">Contact's Jobs</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner.job</field>
<field name="view_type">form</field>
</record>
<!-- <menuitem-->
<!-- name="Partners/Contact's Jobs"-->
<!-- action="action_res_partner_job"-->
<!-- id="menu_action_res_partner_job"-->
<!-- groups="base.group_extended"/>-->
<!-- Act window defining a shorcut on partners to open all his contacts -->
<act_window domain="[('name', '=', active_id)]"
id="act_res_partner_jobs" name="Partner Contacts"
res_model="res.partner.job"
@ -420,6 +394,7 @@
/>
<!-- Act window defining a shorcut on partner address to open all his jobs -->
<act_window
id="act_res_partner_jobs" name="Open Jobs"
domain="[('address_id', '=', active_id)]"
@ -427,9 +402,13 @@
src_model="res.partner.address"
/>
<menuitem icon="terp-purchase" id="base.menu_purchase_root" name="Procurement Management" sequence="7"/>
<menuitem id="base.menu_procurement_management_supplier" name="Suppliers"
parent="base.menu_purchase_root" sequence="3"/>
<menuitem name="Contacts" id="menu_partner_contact_supplier_form" action="action_partner_contact_form" parent = "base.menu_procurement_management_supplier" sequence="2"/>
<menuitem icon="terp-purchase" id="base.menu_purchase_root"
name="Procurement Management" sequence="7" />
<menuitem id="base.menu_procurement_management_supplier"
name="Suppliers" parent="base.menu_purchase_root" sequence="3" />
<menuitem name="Contacts" id="menu_partner_contact_supplier_form"
action="action_partner_contact_form"
parent="base.menu_procurement_management_supplier" sequence="2" />
</data>
</openerp>

View File

@ -37,6 +37,8 @@ the "Dashboard" menu.
'init_xml': [],
'update_xml': [
'security/ir.model.access.csv',
'wizard/report_menu_create_view.xml',
'wizard/report_open_view.xml',
'base_report_creator_wizard.xml',
'base_report_creator_view.xml'
],

View File

@ -19,35 +19,13 @@
#
##############################################################################
import string
import time
import tools
from osv import fields,osv,orm
from osv import fields, osv
from tools.translate import _
#class ir_model_fields(osv.osv):
# _inherit = 'ir.model.fields'
# def _get_models(self, cr, uid, model_name, level=1):
# if not level:
# return []
# result = [model_name]
# print model_name
# for field,data in self.pool.get(model_name).fields_get(cr, uid).items():
# if data.get('relation', False):
# result += self._get_models(cr, uid, data['relation'], level-1)
# return result
# def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None):
# if context and ('model_id' in context):
# model_name = self.pool.get("ir.model").browse(cr, uid, context['model_id'], context).model
# models = self._get_models(cr, uid, model_name, context.get('model_level',2))
# models = map(lambda x: self.pool.get('ir.model').search(cr, uid, [('model','=',x)])[0], models)
# args.append(('model_id','in',models))
# print args
# return super(ir_model_fields, self).search(cr, uid, args, offset, limit, order, context)
#ir_model_fields()
class report_creator(osv.osv):
"""
Report Creator
"""
_name = "base_report_creator.report"
_description = "Report"
model_set_id = False
@ -55,45 +33,74 @@ class report_creator(osv.osv):
# Should request only used fields
#
def export_data(self, cr, uid, ids, fields_to_export, context=None):
if not context:
context = {}
data_l = self.read(cr, uid, ids, ['sql_query'], context)
final_datas =[]
final_datas = []
#start Loop
for i in data_l:
datas = []
for key,value in i.items():
for key, value in i.items():
if key not in fields_to_export:
continue
if isinstance(value,tuple):
if isinstance(value, tuple):
datas.append(str(value[1]))
else:
datas.append(str(value))
final_datas += [datas]
return {'datas':final_datas}
#End Loop
return {'datas': final_datas}
def fields_get(self, cr, user, fields=None, context=None):
"""
Get Fields.
@param cr: the current row, from the database cursor,
@param user: the current users ID for security checks,
@param Fields: List of field of customer reports form.
@return: Dictionary of Fields
"""
if not context:
context = {}
data = context and context.get('report_id', False) or False
if (not context) or 'report_id' not in context:
return super(report_creator, self).fields_get(cr, user, fields, context)
report = self.browse(cr, user, context['report_id'])
models = {}
for model in report.model_ids:
models[model.model] = self.pool.get(model.model).fields_get(cr, user, context=context)
fields = {}
i = 0
for f in report.field_ids:
if f.field_id.model:
fields['field'+str(i)] = models[f.field_id.model][f.field_id.name]
i+=1
else:
fields['column_count'] = {'readonly': True, 'type': 'integer', 'string': 'Count', 'size': 64, 'name': 'column_count'}
return fields
if data:
report = self.browse(cr, user, data)
models = {}
#Start Loop
for model in report.model_ids:
models[model.model] = self.pool.get(model.model).fields_get(cr, user, context=context)
#End Loop
fields = {}
i = 0
for f in report.field_ids:
if f.field_id.model:
fields['field'+str(i)] = models[f.field_id.model][f.field_id.name]
i += 1
else:
fields['column_count'] = {'readonly': True, 'type': 'integer', 'string': 'Count', 'size': 64, 'name': 'column_count'}
return fields
#
# Should Call self.fields_get !
#
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
"""
Overrides orm field_view_get.
@param cr: the current row, from the database cursor,
@param user: the current users ID for security checks,
@return: Dictionary of Fields, arch and toolbar.
"""
if not context:
context = {}
data = context and context.get('report_id', False) or False
if (not context) or 'report_id' not in context:
return super(report_creator, self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
report = self.browse(cr, user, context['report_id'])
report = self.browse(cr, user, data)
models = {}
for model in report.model_ids:
models[model.model] = self.pool.get(model.model).fields_get(cr, user, context=context)
@ -102,33 +109,33 @@ class report_creator(osv.osv):
for f in report.field_ids:
if f.field_id.model:
fields['field'+str(i)] = models[f.field_id.model][f.field_id.name]
i+=1
i += 1
else:
fields['column_count'] = {'readonly': True, 'type': 'integer', 'string': 'Count', 'size': 64, 'name': 'column_count'}
arch = '<?xml version="1.0" encoding="utf-8"?>\n'
if view_type=='graph':
arch +='<graph string="%s" type="%s" orientation="%s">' % (report.name, report.view_graph_type,report.view_graph_orientation)
if view_type == 'graph':
arch += '<graph string="%s" type="%s" orientation="%s">' % (report.name, report.view_graph_type, report.view_graph_orientation)
for val in ('x','y'):
i = 0
for f in report.field_ids:
if f.graph_mode==val:
if f.graph_mode == val:
if f.field_id.model:
arch += '<field name="%s" select="1"/>' % ('field'+str(i),)
i+=1
i += 1
else:
arch += '<field name="%s" select="1"/>' % ('column_count',)
elif view_type=='calendar':
required_types = ['date_start','date_delay','color']
set_dict = {'view_type':view_type,'string':report.name}
elif view_type == 'calendar':
required_types = ['date_start', 'date_delay', 'color']
set_dict = {'view_type':view_type, 'string':report.name}
temp_list = []
i=0
i = 0
for f in report.field_ids:
if f.calendar_mode and f.calendar_mode in required_types:
if f.field_id.model:
field_cal = 'field'+str(i)
i+=1
i += 1
else:
field_cal = 'column_count'
set_dict[f.calendar_mode] = field_cal
@ -136,20 +143,20 @@ class report_creator(osv.osv):
else:
if f.field_id.model:
temp_list.append('''<field name="%(name)s" select="1"/>''' % {'name':'field'+str(i)})
i+=1
temp_list.append('''<field name = "%(name)s" select = "1"/>''' % {'name': 'field' + str(i)})
i += 1
else:
temp_list.append('''<field name="%(name)s" select="1"/>''' % {'name':'column_count'})
arch += '''<%(view_type)s string="%(string)s" date_start="%(date_start)s" ''' %set_dict
if set_dict.get('date_delay',False):
arch +=''' date_delay="%(date_delay)s" '''%set_dict
arch += '''<% (view_type)s string = "%(string)s" date_start = "%(date_start)s" ''' % set_dict
if set_dict.get('date_delay', False):
arch += ''' date_delay = "%(date_delay)s" ''' % set_dict
if set_dict.get('date_stop',False):
arch +=''' date_stop="%(date_stop)s" '''%set_dict
if set_dict.get('date_stop', False):
arch += ''' date_stop="%(date_stop)s" '''%set_dict
if set_dict.get('color',False):
arch +=''' color="%(color)s"'''%set_dict
if set_dict.get('color', False):
arch += ''' color="%(color)s"'''%set_dict
arch += '''>'''
arch += ''.join(temp_list)
else:
@ -157,8 +164,8 @@ class report_creator(osv.osv):
i = 0
for f in report.field_ids:
if f.field_id.model:
arch += '<field name="%s" select="1"/>' % ('field'+str(i),)
i+=1
arch += '<field name="%s" select="1"/>' % ('field' + str(i),)
i += 1
else:
arch += '<field name="%s" select="1"/>' % ('column_count',)
arch += '</%s>' % (view_type,)
@ -171,70 +178,90 @@ class report_creator(osv.osv):
'action': [],
'relate': []
}
return result
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
def read(self, cr, user, ids, fields = None, context = None, load = '_classic_read'):
"""
overrides orm Read method.Read List of fields for report creator.
@param cr: the current row, from the database cursor,
@param user: the current users ID for security checks,
@param ids: List of report creator's id.
@param fields: List of fields.
@return: List of Dictionary of form [{name_of_the_field: value, ...}, ...]
"""
data = context and context.get('report_id', False) or False
if (not context) or 'report_id' not in context:
return super(report_creator, self).read(cr, user, ids, fields, context, load)
ctx = context or {}
wp = ''
if self.model_set_id:
wp = [self._id_get(cr, user, context['report_id'], context)+(' in (%s)' % (','.join(map(lambda x: "'"+str(x)+"'",ids))))]
report = self._sql_query_get(cr, user, [context['report_id']], 'sql_query', None, ctx, where_plus = wp)
sql_query = report[context['report_id']]
cr.execute(sql_query)
res = cr.dictfetchall()
fields_get = self.fields_get(cr,user,None,context)
for r in res:
for k in r:
r[k] = r[k] or False
field_dict = fields_get.get(k)
field_type = field_dict and field_dict.get('type',False) or False
if field_type and field_type == 'many2one':
if r[k]==False:
continue
related_name = self.pool.get(field_dict.get('relation')).name_get(cr,user,[r[k]],context)[0]
r[k] = related_name
return res
if data:
if self.model_set_id:
wp = [self._id_get(cr, user, data, context) + (' in (%s)' % (','.join(map(lambda x: "'" + str(x) + "'", ids))))]
report = self._sql_query_get(cr, user, [data], 'sql_query', None, ctx, where_plus = wp)
sql_query = report[data]
cr.execute(sql_query)
res = cr.dictfetchall()
fields_get = self.fields_get(cr, user, None, context)
for r in res:
for k in r:
r[k] = r[k] or False
field_dict = fields_get.get(k)
field_type = field_dict and field_dict.get('type', False) or False
if field_type and field_type == 'many2one':
if r[k] == False:
continue
related_name = self.pool.get(field_dict.get('relation')).name_get(cr, user, [r[k]], context)[0]
r[k] = related_name
return res
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
"""
overrides orm search method.
@param cr: the current row, from the database cursor,
@param user: the current users ID for security checks,
@param args: list of tuples of form [(name_of_the_field, operator, value), ...].
@return: List of id
"""
context_id = context and context.get('report_id', False) or False
if (not context) or 'report_id' not in context:
return super(report_creator, self).search(cr, user, args, offset, limit, order, context, count)
report = self.browse(cr, user, context['report_id'])
i = 0
fields = {}
for f in report.field_ids:
if f.field_id.model:
fields['field'+str(i)] = (f.field_id.model, f.field_id.name)
i+=1
else:
fields['column_count'] = (False, 'Count')
newargs = []
newargs2 = []
for a in args:
if fields[a[0]][0]:
res = self.pool.get(fields[a[0]][0])._where_calc(cr, user, [[fields[a[0]][1],a[1],a[2]]], active_test=False, context=context)
newargs+=res[0]
newargs2+=res[1]
else:
newargs += [("count(*) " + a[1] +" " + str(a[2]))]
ctx = context or {}
ctx['getid'] = True
report = self._sql_query_get(cr, user, [context['report_id']], 'sql_query', None, ctx, where_plus=newargs, limit=limit, offset=offset)
query = report[context['report_id']]
cr.execute(query, newargs2)
result = cr.fetchall()
return map(lambda x: x[0], result)
if context_id:
report = self.browse(cr, user, context_id)
i = 0
fields = {}
for f in report.field_ids:
if f.field_id.model:
fields['field'+str(i)] = (f.field_id.model, f.field_id.name)
i += 1
else:
fields['column_count'] = (False, 'Count')
newargs = []
newargs2 = []
for a in args:
if fields[a[0]][0]:
res = self.pool.get(fields[a[0]][0])._where_calc(cr, user, [[fields[a[0]][1], a[1], a[2]]], active_test = False, context = context)
newargs += res[0]
newargs2 += res[1]
else:
newargs += [("count(*) " + a[1] +" " + str(a[2]))]
ctx = context or {}
ctx['getid'] = True
report = self._sql_query_get(cr, user, [context_id], 'sql_query', None, ctx, where_plus = newargs, limit=limit, offset=offset)
query = report[context_id]
cr.execute(query, newargs2)
result = cr.fetchall()
return map(lambda x: x[0], result)
def _path_get(self,cr, uid, models, filter_ids=[]):
# ret_str = """ sale_order_line
# left join sale_order on (sale_order_line.order_id=sale_order.id)
# left join res_partner on (res_partner.id=sale_order.partner_id)"""
# where_list = []
# for filter_id in filter_ids:
# where_list.append(filter_id.expression)
# if where_list:
# ret_str+="\nwhere\n\t"+" and\n\t".join(where_list)
def _path_get(self, cr, uid, models, filter_ids=[]):
"""
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param models: List of object.
"""
self.model_set_id = False
model_dict = {}
from_list = []
@ -242,7 +269,7 @@ class report_creator(osv.osv):
filter_list = []
for model in models:
model_dict[model.model] = self.pool.get(model.model)._table
model_list = model_dict.keys()
reference_model_dict = {}
for model in model_dict:
@ -250,7 +277,7 @@ class report_creator(osv.osv):
rest_list = model_dict.keys()
rest_list.remove(model)
model_pool = self.pool.get(model)
fields_get = model_pool.fields_get(cr,uid)
fields_get = model_pool.fields_get(cr, uid)
model_columns = {}
def _get_inherit_fields(obj):
@ -259,24 +286,24 @@ class report_creator(osv.osv):
model_columns.update(pool_model._columns)
#Adding the columns of its _inherits
for record in pool_model._inherits.keys():
_get_inherit_fields(record)
_get_inherit_fields(record)
_get_inherit_fields(model)
fields_filter = dict(filter(lambda x:x[1].get('relation',False)
fields_filter = dict(filter(lambda x:x[1].get('relation', False)
and x[1].get('relation') in rest_list
and x[1].get('type')=='many2one'
and not (isinstance(model_columns[x[0]],fields.function) or isinstance(model_columns[x[0]],fields.related)), fields_get.items()))
and x[1].get('type') == 'many2one'
and not (isinstance(model_columns[x[0]], fields.function) or isinstance(model_columns[x[0]], fields.related)), fields_get.items()))
if fields_filter:
model in model_list and model_list.remove(model)
model_count = reference_model_dict.get(model,False)
model_count = reference_model_dict.get(model, False)
if model_count:
reference_model_dict[model] = model_count +1
else:
reference_model_dict[model] = 1
for k,v in fields_filter.items():
for k, v in fields_filter.items():
v.get('relation') in model_list and model_list.remove(v.get('relation'))
relation_count = reference_model_dict.get(v.get('relation'),False)
relation_count = reference_model_dict.get(v.get('relation'), False)
if relation_count:
reference_model_dict[v.get('relation')] = relation_count+1
else:
@ -288,9 +315,9 @@ class report_creator(osv.osv):
if reference_model_dict:
self.model_set_id = model_dict.get(reference_model_dict.keys()[reference_model_dict.values().index(min(reference_model_dict.values()))])
if model_list and not len(model_dict.keys()) == 1:
raise osv.except_osv(_('No Related Models!!'),_('These is/are model(s) (%s) in selection which is/are not related to any other model') % ','.join(model_list))
raise osv.except_osv(_('No Related Models!!'), _('These is/are model(s) (%s) in selection which is/are not related to any other model') % ','.join(model_list))
if filter_ids and where_list<>[]:
if filter_ids and where_list <> []:
filter_list.append(' and ')
filter_list.append(' ')
@ -305,25 +332,32 @@ class report_creator(osv.osv):
else:
ret_str = ",\n".join(from_list)
if where_list:
where_list = list(set(where_list))
ret_str+="\n where \n"+" and\n".join(where_list)
ret_str += "\n where \n"+" and\n".join(where_list)
ret_str = ret_str.strip()
if filter_list:
ret_str +="\n".join(filter_list)
ret_str += "\n".join(filter_list)
if ret_str.endswith('and'):
ret_str = ret_str[0:len(ret_str)-3]
if ret_str.endswith('or'):
ret_str = ret_str[0:len(ret_str)-2]
ret_str = ret_str.strip()
return ret_str % {'uid' : uid}
return ret_str % {'uid': uid}
def _id_get(self, cr, uid, id, context):
"""
Get Model id
"""
# return 'min(sale_order_line.id)'
return self.model_set_id and 'min('+self.model_set_id+'.id)'
def _sql_query_get(self, cr, uid, ids, prop, unknow_none, context, where_plus=[], limit=None, offset=None):
"""
Get sql query which return on sql_query field.
@return: Dictionary of sql query.
"""
result = {}
for obj in self.browse(cr, uid, ids):
fields = []
@ -332,7 +366,7 @@ class report_creator(osv.osv):
for f in obj.field_ids:
# Allowing to use count(*)
if not f.field_id.model and f.group_method == 'count':
fields.insert(0,('count(*) as column_count'))
fields.insert(0, ('count(*) as column_count'))
continue
t = self.pool.get(f.field_id.model_id.model)._table
if f.group_method == 'group':
@ -340,11 +374,11 @@ class report_creator(osv.osv):
else:
fields.append('\t'+f.group_method+'('+t+'.'+f.field_id.name+')'+' as field'+str(i))
groupby.append(t+'.'+f.field_id.name)
i+=1
i += 1
models = self._path_get(cr, uid, obj.model_ids, obj.filter_ids)
check = self._id_get(cr, uid, ids[0], context)
if check<>False:
fields.insert(0,(check+' as id'))
fields.insert(0, (check + ' as id'))
if models:
result[obj.id] = """select
@ -365,36 +399,58 @@ class report_creator(osv.osv):
return result
_columns = {
'name': fields.char('Report Name',size=64, required=True),
'type': fields.selection([('list','Rows And Columns Report'),], 'Report Type',required=True),#('sum','Summation Report')
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the report without removing it."),
'view_type1': fields.selection([('form','Form'),('tree','Tree'),('graph','Graph'),('calendar','Calendar')], 'First View', required=True),
'view_type2': fields.selection([('','/'),('form','Form'),('tree','Tree'),('graph','Graph'),('calendar','Calendar')], 'Second View'),
'view_type3': fields.selection([('','/'),('form','Form'),('tree','Tree'),('graph','Graph'),('calendar','Calendar')], 'Third View'),
'view_graph_type': fields.selection([('pie','Pie Chart'),('bar','Bar Chart')], 'Graph Type', required=True),
'view_graph_orientation': fields.selection([('horz','Horizontal'),('vert','Vertical')], 'Graph Orientation', required=True),
'model_ids': fields.many2many('ir.model', 'base_report_creator_report_model_rel', 'report_id','model_id', 'Reported Objects'),
'field_ids': fields.one2many('base_report_creator.report.fields', 'report_id', 'Fields to Display'),
'filter_ids': fields.one2many('base_report_creator.report.filter', 'report_id', 'Filters'),
'name': fields.char('Report Name', size=64, required=True),
'type': fields.selection([('list', 'Rows And Columns Report'), ], 'Report Type', required=True), #('sum','Summation Report')
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the report without removing it."),
'view_type1': fields.selection([('form', 'Form'),
('tree', 'Tree'),
('graph', 'Graph'),
('calendar', 'Calendar')], 'First View', required=True),
'view_type2': fields.selection([('', '/'),
('form', 'Form'),
('tree', 'Tree'),
('graph', 'Graph'),
('calendar', 'Calendar')], 'Second View'),
'view_type3': fields.selection([('', '/'),
('form', 'Form'),
('tree', 'Tree'),
('graph', 'Graph'),
('calendar', 'Calendar')], 'Third View'),
'view_graph_type': fields.selection([('pie', 'Pie Chart'),
('bar', 'Bar Chart')], 'Graph Type', required=True),
'view_graph_orientation': fields.selection([('horz', 'Horizontal'),
('vert', 'Vertical')], 'Graph Orientation', required=True),
'model_ids': fields.many2many('ir.model', 'base_report_creator_report_model_rel', 'report_id', 'model_id', 'Reported Objects'),
'field_ids': fields.one2many('base_report_creator.report.fields', 'report_id', 'Fields to Display'),
'filter_ids': fields.one2many('base_report_creator.report.filter', 'report_id', 'Filters'),
'state': fields.selection([
('draft','Draft'),
('valid','Valid')],
'State', required=True,
('draft', 'Draft'),
('valid', 'Valid')],
'State', required=True,
help=' * The \'Draft\' state is used when a user is encoding a new and unconfirmed custom report. \
\n* The \'Valid\' state is used when user validates the custom report.'),
'sql_query': fields.function(_sql_query_get, method=True, type="text", string='SQL Query', store=True),
'group_ids': fields.many2many('res.groups', 'base_report_creator_group_rel','report_id','group_id','Authorized Groups'),
\n* The \'Valid\' state is used when user validates the custom report.'),
'sql_query': fields.function(_sql_query_get, method=True, type="text", string='SQL Query', store=True),
'group_ids': fields.many2many('res.groups', 'base_report_creator_group_rel', 'report_id', 'group_id', 'Authorized Groups'),
}
_defaults = {
'type': lambda *args: 'list',
'state': lambda *args: 'draft',
'active': lambda *args: True,
'view_type1': lambda *args: 'tree',
'view_type2': lambda *args: 'graph',
'view_graph_type': lambda *args: 'bar',
'view_graph_orientation': lambda *args: 'horz',
'type': lambda *args: 'list',
'state': lambda *args: 'draft',
'active': lambda *args: True,
'view_type1': lambda *args: 'tree',
'view_type2': lambda *args: 'graph',
'view_graph_type': lambda *args: 'bar',
'view_graph_orientation': lambda *args: 'horz',
}
def _function_field(self, cr, uid, ids):
"""
constraints function which specify that
not display field which are not stored in Database.
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Report creator's id.
@return: True if display field which are stored in database.
or false if display field which are not store in dtabase.
"""
this_objs = self.browse(cr, uid, ids)
for obj in this_objs:
for fld in obj.field_ids:
@ -402,13 +458,23 @@ class report_creator(osv.osv):
if not fld.field_id.model and fld.group_method == 'count':
continue
model_column = self.pool.get(fld.field_id.model)._columns[fld.field_id.name]
if (isinstance(model_column,fields.function) or isinstance(model_column,fields.related)) and not model_column.store:
if (isinstance(model_column, fields.function) or isinstance(model_column, fields.related)) and not model_column.store:
return False
return True
def _aggregation_error(self, cr, uid, ids):
aggregate_columns = ('integer','float')
apply_functions = ('sum','min','max','avg','count')
"""
constraints function which specify that
aggregate function to the non calculated field..
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Report creator's id.
@return: True if model colume type is in integer or float.
or false model colume type is not in integer or float.
"""
aggregate_columns = ('integer', 'float')
apply_functions = ('sum', 'min', 'max', 'avg', 'count')
this_objs = self.browse(cr, uid, ids)
for obj in this_objs:
for fld in obj.field_ids:
@ -425,7 +491,7 @@ class report_creator(osv.osv):
required_types = []
this_objs = self.browse(cr, uid, ids)
for obj in this_objs:
if obj.view_type1=='calendar' or obj.view_type2=='calendar' or obj.view_type3=='calendar':
if obj.view_type1 == 'calendar' or obj.view_type2 == 'calendar' or obj.view_type3 == 'calendar':
for fld in obj.field_ids:
# Allowing to use count(*)
if not fld.field_id.model and fld.group_method == 'count':
@ -442,43 +508,60 @@ class report_creator(osv.osv):
return True
_constraints = [
(_function_field, 'You can not display field which are not stored in Database.', ['field_ids']),
(_aggregation_error, 'You can apply aggregate function to the non calculated field.', ['field_ids']),
(_calander_view_error, "You must have to give calendar view's color,start date and delay.", ['field_ids']),
(_function_field, 'You can not display field which are not stored in Database.', ['field_ids']),
(_aggregation_error, 'You can apply aggregate function to the non calculated field.', ['field_ids']),
(_calander_view_error, "You must have to give calendar view's color,start date and delay.", ['field_ids']),
]
report_creator()
class report_creator_field(osv.osv):
"""
Report Creator Field
"""
_name = "base_report_creator.report.fields"
_description = "Display Fields"
_rec_name = 'field_id'
_order = "sequence,id"
_columns = {
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of fields."),
'field_id': fields.many2one('ir.model.fields', 'Field'),
'report_id': fields.many2one('base_report_creator.report','Report', on_delete='cascade'),
'group_method': fields.selection([('group','Grouped'),('sum','Sum'),('min','Minimum'),('count','Count'),('max','Maximum'),('avg','Average')], 'Grouping Method', required=True),
'graph_mode': fields.selection([('','/'),('x','X Axis'),('y','Y Axis')], 'Graph Mode'),
'calendar_mode': fields.selection([('','/'),('date_start','Starting Date'),('date_end','Ending Date'),('date_delay','Delay'),('date_stop','End Date'),('color','Unique Colors')], 'Calendar Mode'),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of fields."),
'field_id': fields.many2one('ir.model.fields', 'Field'),
'report_id': fields.many2one('base_report_creator.report', 'Report', on_delete='cascade'),
'group_method': fields.selection([('group', 'Grouped'),
('sum', 'Sum'),
('min', 'Minimum'),
('count', 'Count'),
('max', 'Maximum'),
('avg', 'Average')], 'Grouping Method', required=True),
'graph_mode': fields.selection([('', '/'),
('x', 'X Axis'),
('y', 'Y Axis')], 'Graph Mode'),
'calendar_mode': fields.selection([('', '/'),
('date_start', 'Starting Date'),
('date_end', 'Ending Date'), ('date_delay', 'Delay'), ('date_stop', 'End Date'), ('color', 'Unique Colors')], 'Calendar Mode'),
}
_defaults = {
'group_method': lambda *args: 'group',
'graph_mode': lambda *args: '',
'group_method': lambda *args: 'group',
'graph_mode': lambda *args: '',
}
report_creator_field()
class report_creator_filter(osv.osv):
"""
Report Creator Filter
"""
_name = "base_report_creator.report.filter"
_description = "Report Filters"
_columns = {
'name': fields.char('Filter Name',size=64, required=True),
'expression': fields.text('Value', required=True,help='Provide an expression for the field based on which you want to filter the records.\n e.g. res_partner.id=3'),
'report_id': fields.many2one('base_report_creator.report','Report', on_delete='cascade'),
'condition' : fields.selection([('and','AND'),('or','OR')], 'Condition')
'name': fields.char('Filter Name', size=64, required=True),
'expression': fields.text('Value', required=True, help='Provide an expression for the field based on which you want to filter the records.\n e.g. res_partner.id=3'),
'report_id': fields.many2one('base_report_creator.report', 'Report', on_delete='cascade'),
'condition': fields.selection([('and', 'AND'),
('or', 'OR')], 'Condition')
}
_defaults = {
'condition': lambda *args: 'and',
'condition': lambda *args: 'and',
}
report_creator_filter()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -27,6 +27,9 @@
</tree>
</field>
</record>
<!-- Report Creator form -->
<record model="ir.ui.view" id="base_report_creator_form">
<field name="name">base_report_creator.report.form</field>
<field name="model">base_report_creator.report</field>
@ -38,10 +41,13 @@
<field name="active" select="2"/>
<notebook colspan="4">
<page string="General Configuration">
<field name="model_ids" colspan="4" context="{'model_ids':model_ids}"/>
<field name="model_ids" colspan="4"
context="{'model_ids':model_ids}" />
<separator string="State" colspan="4"/>
<field name="state"/>
<button string="Create Menu" name="%(wizard_menu_create)d" type="action" colspan="2" icon="gtk-justify-fill"/>
<button string="Create Menu"
name="%(action_report_menu_create)d" type="action"
colspan="2" icon="gtk-justify-fill" />
</page><page string="View parameters">
<separator string="Used View" colspan="4"/>
<field name="view_type1"/>
@ -54,12 +60,13 @@
<field name="field_ids" nolabel="1" colspan="4">
<form string="Fields">
<field name="sequence"/>
<field name="field_id" domain="parent.model_ids and [('model_id','in',parent.model_ids[0][2]),('ttype','&lt;&gt;','many2many'),('ttype','&lt;&gt;','one2many')] or []">
<tree string="Field List">
<field name="model_id"/>
<field name="name"/>
<field name="field_description"/>
</tree>
<field name="field_id"
domain="parent.model_ids and [('model_id','in',parent.model_ids[0][2]),('ttype','&lt;&gt;','many2many'),('ttype','&lt;&gt;','one2many')] or []">
<tree string="Field List">
<field name="model_id" />
<field name="name" />
<field name="field_description" />
</tree>
</field>
<field name="group_method"/>
<field name="graph_mode"/>
@ -67,14 +74,18 @@
</form>
<tree editable="bottom" string="Fields to Display">
<field name="sequence"/>
<field name="field_id" domain="parent.model_ids and [('model_id','in',parent.model_ids[0][2]),('ttype','&lt;&gt;','many2many'),('ttype','&lt;&gt;','one2many')] or []" attrs="{'required':[('group_method','!=','count')]}"/>
<field name="field_id"
domain="parent.model_ids and [('model_id','in',parent.model_ids[0][2]),('ttype','&lt;&gt;','many2many'),('ttype','&lt;&gt;','one2many')] or []"
attrs="{'required':[('group_method','!=','count')]}" />
<field name="group_method"/>
<field name="graph_mode"/>
<field name="calendar_mode"/>
</tree>
</field>
</page><page string="Filters on Fields">
<button string="Add filter" name="%(wizard_set_filter_fields)d" type="action" icon="gtk-add"/>
<button string="Add filter"
name="%(wizard_set_filter_fields)d" type="action"
icon="gtk-add" />
<field name="filter_ids" nolabel="1" colspan="4">
<tree string="Filters">
<field name="name"/>
@ -87,8 +98,10 @@
</form>
</field>
<separator string="Legend" colspan="4"/>
<label string="Use %%(uid)s to filter by the connected user" align="0.0"/>
</page><page string="Security">
<label
string="Use %%(uid)s to filter by the connected user"
align="0.0" />
</page><page string="Security">
<separator string="Authorized Groups (empty for all)" colspan="4"/>
<field name="group_ids" colspan="4" nolabel="1"/>
</page><page string="SQL Query">
@ -98,15 +111,20 @@
</form>
</field>
</record>
<!-- Action for Report creator form -->
<record model="ir.actions.act_window" id="base_report_creator_action">
<field name="name">Custom Report</field>
<field name="res_model">base_report_creator.report</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem
name="Custom Reports" id="base.menu_custom_reports"
action="base_report_creator_action" parent="base.reporting_menu" sequence="1"/>
<menuitem
name="Custom Reports" parent="base.next_id_50"
id="menu_base_report_creator_action_config"
@ -122,36 +140,22 @@
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="base_report_creator_action_tree">
<field name="res_model">base_report_creator.report</field>
<field name="view_type">tree</field>
</record>
<menuitem
name="Custom Reports" parent="base.menu_custom_reports"
id="menu_base_report_creator_action"
action="base_report_creator_action_tree"/>
<wizard
id="wizard_report_open"
string="Open Report"
name="base_report_creator.report.open"/>
<record model="ir.values" id="ir_open_report">
<field name="key2" eval="'tree_but_open'"/>
<field name="model" eval="'base_report_creator.report'"/>
<field name="name">Browse Report</field>
<field name="value" eval="'ir.actions.wizard,%d'%wizard_report_open"/>
<field name="object" eval="True"/>
</record>
<record model="ir.values" id="ir_open_report_multi">
<field name="key2" eval="'client_action_multi'"/>
<field name="model" eval="'base_report_creator.report'"/>
<field name="name">Browse Report</field>
<field name="value" eval="'ir.actions.wizard,%d'%wizard_report_open"/>
<field name="object" eval="True"/>
</record>
<act_window id="action_report_open"
key2="client_action_multi" name="Open Report"
res_model="report.open" src_model="base_report_creator.report"
view_mode="form" target="new" view_type="form" />
</data>
</openerp>

View File

@ -1,13 +1,8 @@
<?xml version="1.0"?>
<openerp>
<data>
<wizard
id="wizard_set_filter_fields"
string="Set Filter Fields"
name="base_report_creator.report_filter.fields"/>
<wizard
id="wizard_menu_create"
string="Create Menu for Report"
name="base_report_creator.report.menu.create"/>
</data>
<data>
<wizard id="wizard_set_filter_fields" string="Set Filter Fields"
name="base_report_creator.report_filter.fields" />
</data>
</openerp>

View File

@ -1,4 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_base_report_creator_report,base_report_creator.report,model_base_report_creator_report,base.group_system,1,1,1,1
access_base_report_creator_report_fields,base_report_creator.report.fields,model_base_report_creator_report_fields,base.group_system,1,1,1,1
access_base_report_creator_report_filter,base_report_creator.report.filter,model_base_report_creator_report_filter,base.group_system,1,1,1,1
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_base_report_creator_report","base_report_creator.report","model_base_report_creator_report","base.group_system",1,1,1,1
"access_base_report_creator_report_fields","base_report_creator.report.fields","model_base_report_creator_report_fields","base.group_system",1,1,1,1
"access_base_report_creator_report_filter","base_report_creator.report.filter","model_base_report_creator_report_filter","base.group_system",1,1,1,1
"access_report_menu_create","report.menu.create","model_report_menu_create","base.group_system",1,1,1,1
"access_report_open","report.open","model_report_open","base.group_system",1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_base_report_creator_report base_report_creator.report model_base_report_creator_report base.group_system 1 1 1 1
3 access_base_report_creator_report_fields base_report_creator.report.fields model_base_report_creator_report_fields base.group_system 1 1 1 1
4 access_base_report_creator_report_filter base_report_creator.report.filter model_base_report_creator_report_filter base.group_system 1 1 1 1
5 access_report_menu_create report.menu.create model_report_menu_create base.group_system 1 1 1 1
6 access_report_open report.open model_report_open base.group_system 1 1 1 1

View File

@ -20,7 +20,7 @@
##############################################################################
import wiz_set_filter_fields
import base_report_creator_open
import report_menu_create
import report_open
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -19,63 +19,56 @@
#
##############################################################################
from osv import fields, osv
import time
import wizard
import osv
import pooler
section_form = '''<?xml version="1.0"?>
<form string="Create Menu For This Report">
<separator string="Menu Information" colspan="4"/>
<field name="menu_name"/>
<field name="menu_parent_id"/>
</form>'''
section_fields = {
'menu_name': {'string':'Menu Name', 'type':'char', 'required':True, 'size':64},
'menu_parent_id': {'string':'Parent Menu', 'type':'many2one', 'relation':'ir.ui.menu', 'required':True},
}
def report_menu_create(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
board = pool.get('base_report_creator.report').browse(cr, uid, data['id'])
view = board.view_type1
if board.view_type2:
view+=','+board.view_type2
if board.view_type3:
view+=','+board.view_type3
action_id = pool.get('ir.actions.act_window').create(cr, uid, {
'name': board.name,
'view_type':'form',
'view_mode':view,
'context': "{'report_id':%d}" % (board.id,),
'res_model': 'base_report_creator.report'
})
pool.get('ir.ui.menu').create(cr, uid, {
'name': data['form']['menu_name'],
'parent_id': data['form']['menu_parent_id'],
'icon': 'STOCK_SELECT_COLOR',
'action': 'ir.actions.act_window,'+str(action_id)
}, context)
return {}
class wizard_section_menu_create(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type':'form', 'arch':section_form, 'fields':section_fields, 'state':[('end','Cancel'),('create_menu','Create Menu')]}
},
'create_menu': {
'actions': [report_menu_create],
'result': {
'type':'state',
'state':'end'
}
}
}
wizard_section_menu_create('base_report_creator.report.menu.create')
class report_menu_create(osv.osv_memory):
"""
Create Menu
"""
_name = "report.menu.create"
_description = "Menu Create"
_columns = {
'menu_name':fields.char('Menu Name', size=64, required=True),
'menu_parent_id':fields.many2one('ir.ui.menu', 'Parent Menu', required=True),
}
def report_menu_create(self, cr, uid, ids, context=None):
"""
Create Menu.
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Report Menu Create's IDs
@return: Dictionary {}.
"""
if not context:
context = {}
context_id = context and context.get('active_id', False) or False
if context_id:
board = self.pool.get('base_report_creator.report').browse(cr, uid, context_id)
view = board.view_type1
if board.view_type2:
view += ',' + board.view_type2
if board.view_type3:
view += ',' + board.view_type3
action_id = self.pool.get('ir.actions.act_window').create(cr, uid, {
'name': board.name,
'view_type':'form',
'view_mode':view,
'context': "{'report_id':%d}" % (board.id,),
'res_model': 'base_report_creator.report'
})
obj_menu = self.pool.get('ir.ui.menu')
#start Loop
for data in self.read(cr, uid, ids):
obj_menu.create(cr, uid, {
'name': data.get('menu_name'),
'parent_id': data.get('menu_parent_id'),
'icon': 'STOCK_SELECT_COLOR',
'action': 'ir.actions.act_window, ' + str(action_id)
}, context=context)
return {}
#End Loop
report_menu_create()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Create Menu For report -->
<record id="view_report_menu_create" model="ir.ui.view">
<field name="name">report.menu.create.form</field>
<field name="model">report.menu.create</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Create Menu For This Report">
<group colspan="4" >
<separator string="Menu Information" colspan="4"/>
<field name="menu_name"/>
<field name="menu_parent_id"/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel"
string="Cancel" />
<button icon="gtk-save" string="Create Menu"
name="report_menu_create" type="object" />
</group>
</form>
</field>
</record>
<record id="action_report_menu_create" model="ir.actions.act_window">
<field name="name">Create Menu for Report</field>
<field name="res_model">report.menu.create</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_report_menu_create"/>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
class report_open(osv.osv_memory):
"""
Open report
"""
_name = "report.open"
_description = __doc__
def open_report(self, cr, uid, ids, context=None):
"""
This Function opens base creator report view
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of report open's IDs
@param context: A standard dictionary for contextual values
@return : Dictionary value for base creator report form
"""
if not context:
context = {}
context_id = context and context.get('active_id', False) or False
if context.get('report_id', False):
raise osv.except_osv(_('UserError'), _('No Wizards available for this object!'))
rep = self.pool.get('base_report_creator.report').browse(cr, uid, context_id, context)
view_mode = rep.view_type1
if rep.view_type2:
view_mode += ',' + rep.view_type2
if rep.view_type3:
view_mode += ',' + rep.view_type3
value = {
'name': rep.name,
'view_type': 'form',
'view_mode': view_mode,
'res_model': 'base_report_creator.report',
'context': {'report_id': context_id},
'view_id': False,
'type': 'ir.actions.act_window'
}
return value
report_open()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Report Open wizard -->
<record id="view_report_open" model="ir.ui.view">
<field name="name">report.open.form</field>
<field name="model">report.open</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Report open">
<separator string="" colspan="4" />
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel"
string="Cancel" />
<button icon="gtk-open" string="Open Report"
name="open_report" type="object" />
</group>
</form>
</field>
</record>
<record id="action_report_open" model="ir.actions.act_window">
<field name="name">Open Report</field>
<field name="res_model">report.open</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_report_open"/>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -23,4 +23,3 @@ import board
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -19,7 +19,6 @@
#
##############################################################################
{
'name': 'Dashboard main module',
'version': '1.0',
@ -27,7 +26,7 @@
'description': """Base module for all dashboards.""",
'author': 'Tiny',
'depends': ['base'],
'update_xml': ['security/ir.model.access.csv', 'board_view.xml'],
'update_xml': ['security/ir.model.access.csv', 'wizard/board_menu_create_view.xml', 'board_view.xml'],
'demo_xml': [],
'installable': True,
'active': False,

View File

@ -19,28 +19,42 @@
#
##############################################################################
from osv import fields, osv
import time
from osv import fields,osv
class board_board(osv.osv):
"""
Board
"""
_name = 'board.board'
_description = "Board"
def create_view(self, cr, uid, ids, context):
board = self.pool.get('board.board').browse(cr, uid, ids, context)
def create_view(self, cr, uid, ids, context=None):
"""
Create view
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Board's IDs
@return: arch of xml view.
"""
if not context:
context = {}
board = self.pool.get('board.board').browse(cr, uid, ids, context=context)
left = []
right = []
#start Loop
for line in board.line_ids:
linestr = '<action string="%s" name="%d" colspan="4"' % (line.name, line.action_id.id)
if line.height:
linestr+=(' height="%d"' % (line.height,))
linestr += (' height="%d"' % (line.height, ))
if line.width:
linestr+=(' width="%d"' % (line.width,))
linestr += (' width="%d"' % (line.width, ))
linestr += '/>'
if line.position=='left':
if line.position == 'left':
left.append(linestr)
else:
right.append(linestr)
#End Loop
arch = """<?xml version="1.0"?>
<form string="My Board">
<hpaned>
@ -55,24 +69,45 @@ class board_board(osv.osv):
return arch
def write(self, cr, uid, ids, vals, context={}):
def write(self, cr, uid, ids, vals, context = {}):
"""
Writes values in one or several fields.
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Board's IDs
@param vals: dictionary with values to update.
dictionary must be with the form: {name_of_the_field: value, ...}.
@return: True
"""
result = super(board_board, self).write(cr, uid, ids, vals, context)
board = self.pool.get('board.board').browse(cr, uid, ids[0])
view = self.create_view(cr, uid, ids[0], context)
id = board.view_id.id
cr.execute("update ir_ui_view set arch=%s where id=%s" , (view, id))
cr.execute("update ir_ui_view set arch=%s where id=%s", (view, id))
return result
def create(self, cr, user, vals, context=None):
"""
create new record.
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param vals: dictionary of values for every field.
dictionary must use this form: {name_of_the_field: value, ...}
@return: id of new created record of board.board.
"""
if not context:
context = {}
if not 'name' in vals:
return False
id = super(board_board, self).create(cr, user, vals, context)
view_id = self.pool.get('ir.ui.view').create(cr, user, {
'name': vals['name'],
'model':'board.board',
'priority':16,
'model': 'board.board',
'priority': 16,
'type': 'form',
'arch': self.create_view(cr, user, id, context),
})
@ -81,17 +116,28 @@ class board_board(osv.osv):
return id
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
res = {}
res = super(board_board, self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None,\
toolbar=False, submenu=False):
"""
Overrides orm field_view_get.
@return: Dictionary of Fields, arch and toolbar.
"""
vids = self.pool.get('ir.ui.view.custom').search(cr, user, [('user_id','=',user), ('ref_id','=',view_id)])
if not context:
context = {}
res = {}
res = super(board_board, self).fields_view_get(cr, user, view_id, view_type,\
context, toolbar=toolbar, submenu=submenu)
vids = self.pool.get('ir.ui.view.custom').search(cr, user,\
[('user_id', '=', user), ('ref_id' ,'=', view_id)])
if vids:
view_id = vids[0]
arch = self.pool.get('ir.ui.view.custom').browse(cr, user, view_id)
res['arch'] = arch.arch
res['toolbar'] = {'print':[],'action':[],'relate':[]}
res['toolbar'] = {'print': [], 'action': [], 'relate': []}
return res
_columns = {
@ -102,44 +148,67 @@ class board_board(osv.osv):
# the following lines added to let the button on dashboard work.
_defaults = {
'name': lambda *args: 'Dashboard'
'name':lambda *args: 'Dashboard'
}
board_board()
class board_line(osv.osv):
"""
Board Line
"""
_name = 'board.board.line'
_description = "Board Line"
_order = 'position,sequence'
_columns = {
'name': fields.char('Title', size=64, required=True),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of board lines."),
'sequence': fields.integer('Sequence', help="Gives the sequence order\
when displaying a list of board lines."),
'height': fields.integer('Height'),
'width': fields.integer('Width'),
'board_id': fields.many2one('board.board', 'Dashboard', required=True, ondelete='cascade'),
'action_id': fields.many2one('ir.actions.act_window', 'Action', required=True),
'position': fields.selection([('left','Left'),('right','Right')], 'Position', required=True)
'position': fields.selection([('left','Left'),
('right','Right')], 'Position', required=True)
}
_defaults = {
'position': lambda *args: 'left'
}
board_line()
class board_note_type(osv.osv):
"""
Board note Type
"""
_name = 'board.note.type'
_description = "NOte Type"
_columns = {
'name': fields.char('Note Type', size=64, required=True),
}
board_note_type()
def _type_get(self, cr, uid, context={}):
"""
Get by default Note type.
"""
obj = self.pool.get('board.note.type')
ids = obj.search(cr, uid, [])
res = obj.read(cr, uid, ids, ['name'], context)
res = [(r['name'], r['name']) for r in res]
return res
class board_note(osv.osv):
"""
Board Note
"""
_name = 'board.note'
_description = "Note"
_columns = {
'name': fields.char('Subject', size=128, required=True),
'note': fields.text('Note'),
@ -148,10 +217,10 @@ class board_note(osv.osv):
'type': fields.selection(_type_get, 'Note type', size=64),
}
_defaults = {
'user_id': lambda object,cr,uid,context: uid,
'date': lambda object,cr,uid,context: time.strftime('%Y-%m-%d'),
'user_id': lambda object, cr, uid, context: uid,
'date': lambda object, cr, uid, context: time.strftime('%Y-%m-%d'),
}
board_note()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<menuitem icon="terp-graph" id="base.reporting_menu" name="Reporting" sequence="8"/>
<!-- <menuitem icon="terp-graph" id="dashboard" name="Dashboards" sequence="2" parent="base.reporting_menu"/>-->
<menuitem icon="terp-graph" id="base.reporting_menu"
name="Reporting" sequence="8" />
<!--Board Note Tree View -->
<record id="view_board_note_tree" model="ir.ui.view">
<field name="name">board.note.tree</field>
<field name="model">board.note</field>
@ -13,6 +16,9 @@
</tree>
</field>
</record>
<!--Board Note Form View -->
<record id="view_board_note_form" model="ir.ui.view">
<field name="name">board.note.form</field>
<field name="model">board.note</field>
@ -27,6 +33,9 @@
</form>
</field>
</record>
<!-- Action for Publish note Form -->
<record id="action_view_board_note_form" model="ir.actions.act_window">
<field name="name">Publish a note</field>
<field name="res_model">board.note</field>
@ -34,7 +43,7 @@
<field name="view_mode">form,tree</field>
</record>
<wizard id="wizard_board_create_menu" model="board.board" multi="True" name="board.board.menu.create" string="Create Board Menu" />
<!-- Board Tree View -->
<record id="view_board_tree" model="ir.ui.view">
<field name="name">board.board.tree</field>
@ -46,6 +55,9 @@
</tree>
</field>
</record>
<!-- Dashboard Definition Form View -->
<record id="view_board_form" model="ir.ui.view">
<field name="name">board.board.form</field>
<field name="model">board.board</field>
@ -54,7 +66,10 @@
<field name="arch" type="xml">
<form string="Dashboard">
<field name="name" select="1"/>
<button colspan="2" name="%(wizard_board_create_menu)d" string="Create Menu" type="action" icon="gtk-justify-fill"/>
<button colspan="2"
name="%(action_board_menu_create)d"
string="Create Menu" type="action"
icon="gtk-justify-fill" />
<field colspan="4" name="line_ids">
<tree string="Dashboard View">
<field name="name"/>
@ -67,19 +82,24 @@
<field name="sequence"/>
<field name="width"/>
<field name="height"/>
<field name="action_id" domain="[('view_type','!=','tree')]"/>
<field name="action_id"
domain="[('view_type','!=','tree')]" />
<field name="position"/>
</form>
</field>
</form>
</field>
</record>
<!-- Action for DashBoard Definition form -->
<record id="action_view_board_list_form" model="ir.actions.act_window">
<field name="name">Dashboard Definition</field>
<field name="res_model">board.board</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem
id="base.next_id_50"
name="Configuration"
@ -90,10 +110,14 @@
action="action_view_board_list_form"
id="menu_view_board_form"
parent="base.next_id_50" sequence="1"/>
<menuitem action="action_view_board_note_form" id="menu_view_board_note_form" parent="base.next_id_50"
sequence="3"
groups="base.group_system" />
<act_window context="{'view': active_id}" id="dashboard_open" multi="True" name="Open Dashboard" res_model="board.board" src_model="board.board"/>
<menuitem action="action_view_board_note_form"
id="menu_view_board_note_form" parent="base.next_id_50"
sequence="3" groups="base.group_system" />
<act_window context="{'view': active_id}" id="dashboard_open"
multi="True" name="Open Dashboard" res_model="board.board"
src_model="board.board" />
</data>
</openerp>

View File

@ -1,5 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_board_board,board.board,model_board_board,base.group_user,1,1,1,1
access_board_board_line,board.board.line,model_board_board_line,base.group_user,1,1,1,1
access_board_note_type,board.note.type,model_board_note_type,base.group_user,1,1,1,1
access_board_note,board.note,model_board_note,base.group_user,1,1,1,1
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_board_board","board.board","model_board_board","base.group_user",1,1,1,1
"access_board_board_line","board.board.line","model_board_board_line","base.group_user",1,1,1,1
"access_board_note_type","board.note.type","model_board_note_type","base.group_user",1,1,1,1
"access_board_note","board.note","model_board_note","base.group_user",1,1,1,1
"access_board_menu_create","board.menu.create","model_board_menu_create","base.group_user",1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_board_board board.board model_board_board base.group_user 1 1 1 1
3 access_board_board_line board.board.line model_board_board_line base.group_user 1 1 1 1
4 access_board_note_type board.note.type model_board_note_type base.group_user 1 1 1 1
5 access_board_note board.note model_board_note base.group_user 1 1 1 1
6 access_board_menu_create board.menu.create model_board_menu_create base.group_user 1 1 1 1

View File

@ -19,7 +19,7 @@
#
##############################################################################
import board_wizard
import board_menu_create
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
class board_menu_create(osv.osv_memory):
"""
Create Menu
"""
def view_init(self, cr, uid, fields, context=None):
"""
This function checks for precondition before wizard executes
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param fields: List of fields for default value
@param context: A standard dictionary for contextual values
check dashboard view on menu name field.
@return: False
"""
data = context and context.get('active_id', False) or False
if data:
board = self.pool.get('board.board').browse(cr, uid, data)
if not board.line_ids:
raise osv.except_osv(_('User Error!'),
_('Please Insert Dashboard View(s) !'))
return False
def board_menu_create(self, cr, uid, ids, context=None):
"""
Create Menu.
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Board Menu Create's IDs
@return: Dictionary {}.
"""
if not context:
context = {}
context_id = context and context.get('active_id', False) or False
if context_id:
board = self.pool.get('board.board').browse(cr, uid, context_id)
action_id = self.pool.get('ir.actions.act_window').create(cr, uid, {
'name': board.name,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'board.board',
'view_id': board.view_id.id,
})
obj_menu = self.pool.get('ir.ui.menu')
#start Loop
for data in self.read(cr, uid, ids):
obj_menu.create(cr, uid, {
'name': data.get('menu_name'),
'parent_id': data.get('menu_parent_id'),
'icon': 'STOCK_SELECT_COLOR',
'action': 'ir.actions.act_window,' + str(action_id)
}, context=context)
#End Loop
return {}
_name = "board.menu.create"
_description = "Menu Create"
_columns = {
'menu_name': fields.char('Menu Name', size=64, required=True),
'menu_parent_id': fields.many2one('ir.ui.menu', 'Parent Menu', required=True),
}
board_menu_create()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--Board menu create wizard -->
<record id="view_board_menu_create" model="ir.ui.view">
<field name="name">board.menu.create.form</field>
<field name="model">board.menu.create</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Create Menu For Dashboard">
<group colspan="4" >
<separator string="Menu Information" colspan="4"/>
<field name="menu_name"/>
<field name="menu_parent_id"/>
</group>
<separator string="" colspan="4" />
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel"
string="Cancel" />
<button icon="gtk-save" string="Create Menu"
name="board_menu_create" type="object" />
</group>
</form>
</field>
</record>
<!-- Action for Board Menu create wizard. -->
<record id="action_board_menu_create" model="ir.actions.act_window">
<field name="name">Create Board Menu</field>
<field name="res_model">board.menu.create</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_board_menu_create"/>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -1,86 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import time
import wizard
import osv
import pooler
from tools.translate import _
section_form = '''<?xml version="1.0"?>
<form string="Create Menu For Dashboard">
<separator string="Menu Information" colspan="4"/>
<field name="menu_name"/>
<field name="menu_parent_id"/>
</form>'''
section_fields = {
'menu_name': {'string':'Menu Name', 'type':'char', 'required':True, 'size':64},
'menu_parent_id': {'string':'Parent Menu', 'type':'many2one', 'relation':'ir.ui.menu', 'required':True},
}
def check_views(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
board = pool.get('board.board').browse(cr, uid, data['id'])
if not board.line_ids:
raise wizard.except_wizard(_('User Error!'),_('Please Insert Dashboard View(s) !'))
return data['form']
def board_menu_create(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
board = pool.get('board.board').browse(cr, uid, data['id'])
action_id = pool.get('ir.actions.act_window').create(cr, uid, {
'name': board.name,
'view_type':'form',
'view_mode':'form',
'res_model': 'board.board',
'view_id': board.view_id.id,
})
pool.get('ir.ui.menu').create(cr, uid, {
'name': data['form']['menu_name'],
'parent_id': data['form']['menu_parent_id'],
'icon': 'STOCK_SELECT_COLOR',
'action': 'ir.actions.act_window,'+str(action_id)
}, context)
return {}
class wizard_section_menu_create(wizard.interface):
states = {
'init': {
'actions': [check_views],
'result': {'type':'form', 'arch':section_form, 'fields':section_fields, 'state':[('end','Cancel'),('create_menu','Create Menu')]}
},
'create_menu': {
'actions': [board_menu_create],
'result': {
'type':'state',
'state':'end'
}
}
}
wizard_section_menu_create('board.board.menu.create')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -27,6 +27,7 @@ __author__ = AUTHOR
from BaseHTTPServer import BaseHTTPRequestHandler
import os
class BufferedHTTPRequestHandler(BaseHTTPRequestHandler):
"""
Buffering HTTP Request Handler
@ -47,12 +48,12 @@ class BufferedHTTPRequestHandler(BaseHTTPRequestHandler):
If you override the handle() method remember to call
this (see below)
"""
self.__buffer=""
self.__outfp=os.tmpfile()
self.__buffer = ""
self.__outfp = os.tmpfile()
def _append(self,s):
""" append a string to the buffer """
self.__buffer=self.__buffer+s
self.__buffer = self.__buffer+s
def _flush(self):
""" flush the buffer to wfile """
@ -60,7 +61,7 @@ class BufferedHTTPRequestHandler(BaseHTTPRequestHandler):
self.__outfp.write(self.__buffer)
self.__outfp.flush()
self.wfile.flush()
self.__buffer=""
self.__buffer = ""
def handle(self):
""" Handle a HTTP request """
@ -97,3 +98,4 @@ class BufferedHTTPRequestHandler(BaseHTTPRequestHandler):
protocol_version="HTTP/1.1"
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

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