[MERGE] merge with trunk addons

bzr revid: mra@mra-laptop-20100628044353-c4zv8ebcryeyz4o7
This commit is contained in:
Mustufa Rangwala 2010-06-28 10:13:53 +05:30
commit b7da8b9a6b
77 changed files with 3018 additions and 1853 deletions

View File

@ -25,6 +25,7 @@ import project
import partner import partner
import invoice import invoice
import account_bank_statement import account_bank_statement
import account_cash_statement
import account_move_line import account_move_line
import account_analytic_line import account_analytic_line
import wizard import wizard
@ -33,4 +34,4 @@ import product
import sequence import sequence
import company import company
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,448 @@
# encoding: utf-8
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 PC Solutions (<http://pcsol.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv, fields
import time
from mx import DateTime
from decimal import Decimal
from tools.translate import _
class singer_statement(osv.osv):
""" Singer Statements """
_name = 'singer.statement'
_description = 'Statement'
def _sub_total(self, cr, uid, ids, name, arg, context=None):
""" Calculates Sub total"
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
res = {}
for obj in self.browse(cr, uid, ids):
res[obj.id] = obj.pieces * obj.number
return res
def on_change_sub(self, cr, uid, ids, pieces, number,*a):
""" Calculates Sub total on change of number
@param pieces: Names of fields.
@param number:
"""
sub=pieces*number
return {'value':{'subtotal': sub or 0.0}}
_columns = {
'pieces': fields.float('Values', digits=(16,2)),
'number': fields.integer('Number'),
'subtotal': fields.function(_sub_total, method=True, string='Sub Total', type='float',digits=(16,2)),
'starting_id': fields.many2one('account.bank.statement',ondelete='cascade'),
'ending_id': fields.many2one('account.bank.statement',ondelete='cascade'),
}
singer_statement()
class account_cash_statement(osv.osv):
_inherit = 'account.bank.statement'
def _get_starting_balance(self, cr, uid, ids, name, arg, context=None):
""" Find starting balance "
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
res ={}
for statement in self.browse(cr, uid, ids):
amount_total=0.0
for line in statement.starting_details_ids:
amount_total+= line.pieces * line.number
res[statement.id]=amount_total
return res
def _balance_end_cash(self, cr, uid, ids, name, arg, context=None):
""" Find ending balance "
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
res ={}
for statement in self.browse(cr, uid, ids):
amount_total=0.0
for line in statement.ending_details_ids:
amount_total+= line.pieces * line.number
res[statement.id]=amount_total
return res
def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None):
""" Find encoding total of statements "
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
res2={}
for statement in self.browse(cr, uid, ids):
encoding_total=0.0
for line in statement.line_ids:
encoding_total+= line.amount
res2[statement.id]=encoding_total
return res2
def _default_journal_id(self, cr, uid, context={}):
""" To get default journal for the object"
@param name: Names of fields.
@return: journal
"""
company_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.id
journal = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash'), ('company_id', '=', company_id)])
if journal:
return journal[0]
else:
return False
def _end_balance(self, cursor, user, ids, name, attr, context=None):
res_currency_obj = self.pool.get('res.currency')
res_users_obj = self.pool.get('res.users')
res = {}
company_currency_id = res_users_obj.browse(cursor, user, user,
context=context).company_id.currency_id.id
statements = self.browse(cursor, user, ids, context=context)
for statement in statements:
res[statement.id] = statement.balance_start
currency_id = statement.currency.id
for line in statement.move_line_ids:
if line.debit > 0:
if line.account_id.id == \
statement.journal_id.default_debit_account_id.id:
res[statement.id] += res_currency_obj.compute(cursor,
user, company_currency_id, currency_id,
line.debit, context=context)
else:
if line.account_id.id == \
statement.journal_id.default_credit_account_id.id:
res[statement.id] -= res_currency_obj.compute(cursor,
user, company_currency_id, currency_id,
line.credit, context=context)
if statement.state in ('draft', 'open'):
for line in statement.line_ids:
res[statement.id] += line.amount
for r in res:
res[r] = round(res[r], 2)
return res
_columns = {
'company_id':fields.many2one('res.company', 'Company', required=False),
'journal_id': fields.many2one('account.journal', 'Journal', required=True),
'balance_start': fields.function(_get_starting_balance, method=True, string='Opening Balance', type='float',digits=(16,2), help="Opening balance based on cashBox"),
'balance_end_real': fields.float('Closing Balance', digits=(16,2), states={'confirm':[('readonly', True)]}, help="closing balance entered by the cashbox verifier"),
'state': fields.selection(
[('draft', 'Draft'),
('confirm', 'Confirm'),
('open','Open')], 'State', required=True, states={'confirm': [('readonly', True)]}, readonly="1"),
'total_entry_encoding':fields.function(_get_sum_entry_encoding, method=True, string="Cash Transaction", help="Total cash transactions"),
'date':fields.datetime("Open On"),
'closing_date':fields.datetime("Closed On"),
'balance_end': fields.function(_end_balance, method=True, string='Balance', help="Closing balance based on transactions"),
'balance_end_cash': fields.function(_balance_end_cash, method=True, string='Balance', help="Closing balance based on cashBox"),
'starting_details_ids': fields.one2many('singer.statement', 'starting_id', string='Opening Cashbox'),
'ending_details_ids': fields.one2many('singer.statement', 'ending_id', string='Closing Cashbox'),
'name': fields.char('Name', size=64, required=True, readonly=True),
'user_id':fields.many2one('res.users', 'Responsible', required=False),
}
_defaults = {
'state': lambda *a: 'draft',
'name': lambda *a: '/',
'date': lambda *a:time.strftime("%Y-%m-%d %H:%M:%S"),
'journal_id': _default_journal_id,
'user_id': lambda self, cr, uid, context=None: uid
}
def create(self, cr, uid, vals, context=None):
company_id = vals and vals.get('company_id',False)
if company_id:
open_jrnl = self.search(cr, uid, [('company_id', '=', vals['company_id']), ('journal_id', '=', vals['journal_id']), ('state', '=', 'open')])
if open_jrnl:
raise osv.except_osv('Error', u'Une caisse de type espèce est déjà ouverte')
if 'starting_details_ids' in vals:
vals['starting_details_ids'] = starting_details_ids = map(list, vals['starting_details_ids'])
for i in starting_details_ids:
if i and i[0] and i[1]:
i[0], i[1] = 0, 0
res = super(account_cash_statement, self).create(cr, uid, vals, context=context)
return res
def onchange_journal_id(self, cr, uid, statement_id, journal_id, context={}):
""" Changes balance start and starting details if journal_id changes"
@param statement_id: Changed statement_id
@param journal_id: Changed journal_id
@return: Dictionary of changed values
"""
cash_pool = self.pool.get('singer.statement')
statement_pool = self.pool.get('account.bank.statement')
res = {}
balance_start = 0.0
if not journal_id:
res.update({
'balance_start': balance_start
})
return res
res = super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context)
return res
def button_open(self, cr, uid, ids, context=None):
""" Changes statement state to Running.
@return: True
"""
cash_pool = self.pool.get('singer.statement')
statement_pool = self.pool.get('account.bank.statement')
statement = statement_pool.browse(cr, uid, ids[0])
number = self.pool.get('ir.sequence').get(cr, uid, 'account.bank.statement')
if len(statement.starting_details_ids) > 0:
sid = []
for line in statement.starting_details_ids:
sid.append(line.id)
cash_pool.unlink(cr, uid, sid)
cr.execute("select id from account_bank_statement where journal_id=%s and user_id=%s and state=%s order by id desc limit 1", (statement.journal_id.id, uid, 'confirm'))
rs = cr.fetchone()
rs = rs and rs[0] or None
if rs:
statement = statement_pool.browse(cr, uid, rs)
balance_start = statement.balance_end_real or 0.0
open_ids = cash_pool.search(cr, uid, [('ending_id','=',statement.id)])
for sid in open_ids:
default = {
'ending_id': False,
'starting_id':ids[0]
}
cash_pool.copy(cr, uid, sid, default)
vals = {
'date':time.strftime("%Y-%m-%d %H:%M:%S"),
'state':'open',
'name':number
}
self.write(cr, uid, ids, vals)
return True
def button_confirm(self, cr, uid, ids, context={}):
""" Check the starting and ending detail of statement
@return: True
"""
done = []
res_currency_obj = self.pool.get('res.currency')
res_users_obj = self.pool.get('res.users')
account_move_obj = self.pool.get('account.move')
account_move_line_obj = self.pool.get('account.move.line')
account_bank_statement_line_obj = self.pool.get('account.bank.statement.line')
company_currency_id = res_users_obj.browse(cr, uid, uid, context=context).company_id.currency_id.id
for st in self.browse(cr, uid, ids, context):
if not st.state == 'open':
continue
if st.balance_end != st.balance_end_cash:
raise osv.except_osv(_('Error !'), _('Cash balance is not matching with closing balance !'))
if not (abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001):
raise osv.except_osv(_('Error !'),
_('The statement balance is incorrect !\n') +
_('The expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end))
if (not st.journal_id.default_credit_account_id) \
or (not st.journal_id.default_debit_account_id):
raise osv.except_osv(_('Configuration Error !'),
_('Please verify that an account is defined in the journal.'))
for line in st.move_line_ids:
if line.state <> 'valid':
raise osv.except_osv(_('Error !'),
_('The account entries lines are not in valid state.'))
# for bank.statement.lines
# In line we get reconcile_id on bank.ste.rec.
# in bank stat.rec we get line_new_ids on bank.stat.rec.line
for move in st.line_ids:
context.update({'date':move.date})
move_id = account_move_obj.create(cr, uid, {
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
'date': move.date,
}, context=context)
account_bank_statement_line_obj.write(cr, uid, [move.id], {
'move_ids': [(4,move_id, False)]
})
if not move.amount:
continue
torec = []
if move.amount >= 0:
account_id = st.journal_id.default_credit_account_id.id
else:
account_id = st.journal_id.default_debit_account_id.id
acc_cur = ((move.amount<=0) and st.journal_id.default_debit_account_id) or move.account_id
amount = res_currency_obj.compute(cr, uid, st.currency.id,
company_currency_id, move.amount, context=context,
account=acc_cur)
if move.reconcile_id and move.reconcile_id.line_new_ids:
for newline in move.reconcile_id.line_new_ids:
amount += newline.amount
val = {
'name': move.name,
'date': move.date,
'ref': move.ref,
'move_id': move_id,
'partner_id': ((move.partner_id) and move.partner_id.id) or False,
'account_id': (move.account_id) and move.account_id.id,
'credit': ((amount>0) and amount) or 0.0,
'debit': ((amount<0) and -amount) or 0.0,
'statement_id': st.id,
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
'currency_id': st.currency.id,
}
amount = res_currency_obj.compute(cr, uid, st.currency.id,
company_currency_id, move.amount, context=context,
account=acc_cur)
if st.currency.id <> company_currency_id:
amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
st.currency.id, amount, context=context,
account=acc_cur)
val['amount_currency'] = -amount_cur
if move.account_id and move.account_id.currency_id and move.account_id.currency_id.id <> company_currency_id:
val['currency_id'] = move.account_id.currency_id.id
if company_currency_id==move.account_id.currency_id.id:
amount_cur = move.amount
else:
amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
move.account_id.currency_id.id, amount, context=context,
account=acc_cur)
val['amount_currency'] = amount_cur
torec.append(account_move_line_obj.create(cr, uid, val , context=context))
if move.reconcile_id and move.reconcile_id.line_new_ids:
for newline in move.reconcile_id.line_new_ids:
account_move_line_obj.create(cr, uid, {
'name': newline.name or move.name,
'date': move.date,
'ref': move.ref,
'move_id': move_id,
'partner_id': ((move.partner_id) and move.partner_id.id) or False,
'account_id': (newline.account_id) and newline.account_id.id,
'debit': newline.amount>0 and newline.amount or 0.0,
'credit': newline.amount<0 and -newline.amount or 0.0,
'statement_id': st.id,
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
'analytic_account_id':newline.analytic_id and newline.analytic_id.id or False,
}, context=context)
# Fill the secondary amount/currency
# if currency is not the same than the company
amount_currency = False
currency_id = False
if st.currency.id <> company_currency_id:
amount_currency = move.amount
currency_id = st.currency.id
account_move_line_obj.create(cr, uid, {
'name': move.name,
'date': move.date,
'ref': move.ref,
'move_id': move_id,
'partner_id': ((move.partner_id) and move.partner_id.id) or False,
'account_id': account_id,
'credit': ((amount < 0) and -amount) or 0.0,
'debit': ((amount > 0) and amount) or 0.0,
'statement_id': st.id,
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
'amount_currency': amount_currency,
'currency_id': currency_id,
}, context=context)
for line in account_move_line_obj.browse(cr, uid, [x.id for x in
account_move_obj.browse(cr, uid, move_id,
context=context).line_id],
context=context):
if line.state <> 'valid':
raise osv.except_osv(_('Error !'),
_('Ledger Posting line "%s" is not valid') % line.name)
if move.reconcile_id and move.reconcile_id.line_ids:
torec += map(lambda x: x.id, move.reconcile_id.line_ids)
#try:
if abs(move.reconcile_amount-move.amount)<0.0001:
writeoff_acc_id = False
#There should only be one write-off account!
for entry in move.reconcile_id.line_new_ids:
writeoff_acc_id = entry.account_id.id
break
account_move_line_obj.reconcile(cr, uid, torec, 'statement', writeoff_acc_id=writeoff_acc_id, writeoff_period_id=st.period_id.id, writeoff_journal_id=st.journal_id.id, context=context)
else:
account_move_line_obj.reconcile_partial(cr, uid, torec, 'statement', context)
#except:
# raise osv.except_osv(_('Error !'), _('Unable to reconcile entry "%s": %.2f') % (move.name, move.amount))
if st.journal_id.entry_posted:
account_move_obj.write(cr, uid, [move_id], {'state':'posted'})
done.append(st.id)
self.write(cr, uid, done, {'state':'confirm'}, context=context)
return True
def button_cancel(self, cr, uid, ids, context={}):
done = []
for st in self.browse(cr, uid, ids, context):
ids = []
for line in st.line_ids:
ids += [x.id for x in line.move_ids]
self.pool.get('account.move').unlink(cr, uid, ids, context)
done.append(st.id)
self.write(cr, uid, done, {'state':'draft'}, context=context)
return True
account_cash_statement()

View File

@ -460,22 +460,22 @@
<field name="model">account.bank.statement</field> <field name="model">account.bank.statement</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Statement"> <form string="Bank Statement">
<field name="name"/> <group col="6" colspan="4">
<field name="date"/> <field name="name" select="1"/>
<field name="journal_id" on_change="onchange_journal_id(journal_id)"/> <field name="date" select="1"/>
<field name="currency"/> <field name="journal_id" on_change="onchange_journal_id(journal_id)" select="1"/>
<field name="period_id"/> <!-- <field name="currency"/>-->
<group colspan="2" col="3"> <field name="period_id"/>
<!-- <button name="%(action_view_account_statement_from_invoice)d" <!-- <group colspan="2" col="3">-->
string="Import Invoice" type="action" attrs="{'invisible':[('state','=','confirm')]}" icon="gtk-open"/>--> <!-- <button name="%(action_view_account_statement_from_invoice)d"-->
<button name="button_import_invoice" string="Import Invoice" attrs="{'invisible':[('state','=','confirm')]}" type="object" icon="gtk-apply"/> <!-- string="Import Invoice" type="action" attrs="{'invisible':[('state','=','confirm')]}" icon="gtk-open"/>-->
</group> <!-- <button name="button_import_invoice" string="Import Invoice" attrs="{'invisible':[('state','=','confirm')]}" type="object" icon="gtk-apply"/>-->
<newline/> <!-- </group>-->
<field name="balance_start"/> <field name="balance_start"/>
<field name="balance_end_real"/> <field name="balance_end_real"/>
<notebook colspan="4"> <notebook colspan="4">
<page string="Entry encoding"> <page string="Transaction">
<field colspan="4" name="line_ids" nolabel="1"> <field colspan="4" name="line_ids" nolabel="1">
<tree editable="bottom" string="Statement lines"> <tree editable="bottom" string="Statement lines">
<field name="sequence" invisible="1"/> <field name="sequence" invisible="1"/>
@ -504,7 +504,7 @@
</form> </form>
</field> </field>
</page> </page>
<page string="Real Entries"> <page string="Accounting Entries">
<field colspan="4" name="move_line_ids" nolabel="1"/> <field colspan="4" name="move_line_ids" nolabel="1"/>
</page> </page>
</notebook> </notebook>
@ -523,6 +523,7 @@
<field name="res_model">account.bank.statement</field> <field name="res_model">account.bank.statement</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="domain">[('journal_id.type', '=', 'bank')]</field>
</record> </record>
<menuitem string="Bank Statements" action="action_bank_statement_tree" id="menu_bank_statement_tree" parent="menu_finance_bank_and_cash" sequence="7"/> <menuitem string="Bank Statements" action="action_bank_statement_tree" id="menu_bank_statement_tree" parent="menu_finance_bank_and_cash" sequence="7"/>
@ -1173,7 +1174,7 @@
<field name="view_id" ref="view_move_tree"/> <field name="view_id" ref="view_move_tree"/>
<field name="search_view_id" ref="view_account_move_filter"/> <field name="search_view_id" ref="view_account_move_filter"/>
</record> </record>
<act_window <act_window
domain="[('move_id','=',active_id)]" domain="[('move_id','=',active_id)]"
id="act_account_move_to_account_move_line_open" id="act_account_move_to_account_move_line_open"
@ -1181,7 +1182,7 @@
context="{'move_id':active_id}" context="{'move_id':active_id}"
res_model="account.move.line" res_model="account.move.line"
src_model="account.move"/> src_model="account.move"/>
<record id="action_move_to_review" model="ir.actions.act_window"> <record id="action_move_to_review" model="ir.actions.act_window">
<field name="name">Journal Entries to Review</field> <field name="name">Journal Entries to Review</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
@ -1251,16 +1252,6 @@
<field name="view_mode">form</field> <field name="view_mode">form</field>
<field name="act_window_id" ref="action_move_line_search"/> <field name="act_window_id" ref="action_move_line_search"/>
</record> </record>
<record id="action_move_line_search_view3" model="ir.actions.act_window">
<field name="name">Cash Registers</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.move.line</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_move_line_tree"/>
<field name="search_view_id" ref="view_account_move_line_filter"/>
<field name="domain">[('journal_id.type', '=', 'cash')]</field>
</record>
<record id="action_move_line_search_view4" model="ir.actions.act_window"> <record id="action_move_line_search_view4" model="ir.actions.act_window">
<field name="name">Check Registers</field> <field name="name">Check Registers</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
@ -1271,7 +1262,7 @@
<field name="search_view_id" ref="view_account_move_line_filter"/> <field name="search_view_id" ref="view_account_move_line_filter"/>
<field name="domain">[('journal_id.type', '=', 'bank')]</field> <field name="domain">[('journal_id.type', '=', 'bank')]</field>
</record> </record>
<menuitem action="action_move_line_search_view3" id="journal_cash_move_lines" parent="menu_finance_bank_and_cash"/>
<menuitem action="action_move_line_search_view4" id="journal_bank_move_lines" parent="menu_finance_bank_and_cash"/> <menuitem action="action_move_line_search_view4" id="journal_bank_move_lines" parent="menu_finance_bank_and_cash"/>
<!-- <menuitem action="action_move_line_search" id="menu_action_move_line_search" parent="account.next_id_29"/>--> <!-- <menuitem action="action_move_line_search" id="menu_action_move_line_search" parent="account.next_id_29"/>-->
@ -2281,6 +2272,144 @@
sequence="4" sequence="4"
/> />
<!-- Cash Statement -->
<record id="view_bank_statement_tree" model="ir.ui.view">
<field name="name">account.bank.statement.tree</field>
<field name="model">account.bank.statement</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="red:balance_end_real!=balance_end;blue:state=='draft' and (balance_end_real==balance_end);black:state in ('open');blue:state in ('draft')" string="Statement">
<field name="date"/>
<field name="name"/>
<field name="journal_id"/>
<field name="period_id"/>
<field name="balance_start"/>
<field name="balance_end_real"/>
<field name="balance_end"/>
<field name="user_id" select="1"/>
<field name="state"/>
<button type="object" string="Open" name="button_open" states="draft" icon="terp-camera_test"/>
<button type="object" string="Confirm" name="button_confirm" states="open" icon="terp-gtk-go-back-rtl"/>
<button type="object" string="Cancel" name="button_cancel" states="confirm" icon="terp-gtk-stop"/>
</tree>
</field>
</record>
<record id="view_bank_statement_form2" model="ir.ui.view">
<field name="name">account.bank.statement.form</field>
<field name="model">account.bank.statement</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Statement">
<group col="6" colspan="4">
<field name="name" select="1"/>
<field name="company_id" select="1" groups="base.group_multi_company"/>
<field name="journal_id" on_change="onchange_journal_id(journal_id)" domain="[('type','=','cash')]" select="1" />
<field name="user_id" select="1" readonly="1"/>
<field name="period_id" select="1"/>
<field name="balance_end_real"/>
</group>
<notebook colspan="4">
<page string="Cash Transactions" attrs="{'invisible': [('state','=','draft')]}">
<field colspan="4" name="line_ids" nolabel="1">
<tree editable="bottom" string="Statement lines">
<field name="sequence" invisible="1"/>
<field name="date"/>
<field name="ref"/>
<field name="name"/>
<field name="type"/>
<field name="partner_id" on_change="onchange_partner_id(partner_id, type, parent.currency, {'amount': amount})"/>
<field domain="[('journal_id','=',parent.journal_id)]" name="account_id"/>
<field name="amount"/>
<field context="{'partner_id': partner_id, 'amount': amount, 'account_id': account_id, 'currency_id': parent.currency, 'journal_id': parent.journal_id, 'date':date}" name="reconcile_id"/>
<field invisible="1" name="reconcile_amount"/>
</tree>
</field>
</page>
<page string="Cash Box">
<group col="2" colspan="2" expand="1">
<field name="starting_details_ids" nolabel="1" colspan="2" attrs="{'readonly':[('state','=','draft')]}">
<tree string = "Opening Balance" editable="bottom">
<field name="pieces"/>
<field name="number" on_change="on_change_sub(pieces,number, parent.balance_end)"/>
<field name="subtotal" sum="Total"/>
</tree>
<form string = "Opening Balance">
<field name="pieces"/>
<field name="number" on_change="on_change_sub(pieces,number, parent.balance_end)"/>
<field name="subtotal"/>
</form>
</field>
</group>
<group col="2" colspan="2" expand="1">
<field name="ending_details_ids" nolabel="1" colspan="2" attrs="{'readonly':[('state','=','draft')]}">
<tree string = "Closing Balance" editable="bottom">
<field name="pieces"/>
<field name="number" on_change="on_change_sub(pieces,number, parent.balance_end)"/>
<field name="subtotal" sum="Total"/>
</tree>
<form string = "Closing Balance">
<field name="pieces"/>
<field name="number" on_change="on_change_sub(pieces,number, parent.balance_end)"/>
<field name="subtotal"/>
</form>
</field>
</group>
</page>
<page string="Accounting Entries" attrs="{'invisible': [('state','!=','confirm')]}">
<field colspan="4" name="move_line_ids" nolabel="1"/>
</page>
</notebook>
<group col="6" colspan="4">
<group col="2" colspan="2">
<separator string="Dates" colspan="4"/>
<field name="date" select="1" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="closing_date" select="1" attrs="{'readonly':[('state','=','confirm')]}"/>
</group>
<group col="2" colspan="2">
<separator string="Opening Balance" colspan="4"/>
<field name="balance_start"/>
<field name="total_entry_encoding"/>
</group>
<group col="2" colspan="2">
<separator string="Closing Balance" colspan="4"/>
<field name="balance_end" string="Approx"/>
<field name="balance_end_cash" string="Cash Balance"/>
</group>
</group>
<group col="8" colspan="4">
<field name="state" colspan="4"/>
<button name="button_confirm" states="open" string="Close CashBox" icon="terp-check" type="object"/>
<button name="button_open" states="draft" string="Open CashBox" icon="terp-document-new" type="object"/>
<button name="button_cancel" states="confirm,open" string="Cancel" icon="terp-gtk-stop" type="object" groups="base.group_extended"/>
</group>
</form>
</field>
</record>
<record id="action_view_bank_statement_tree" model="ir.actions.act_window">
<field name="name">Cash Register</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.bank.statement</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_bank_statement_tree"/>
<field name="search_view_id" ref="view_account_bank_statement_filter"/>
<field name="domain">[('journal_id.type', '=', 'cash')]</field>
</record>
<record model="ir.actions.act_window.view" id="act_cash_statement1_all">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_bank_statement_tree"/>
<field name="act_window_id" ref="action_view_bank_statement_tree"/>
</record>
<record model="ir.actions.act_window.view" id="act_cash_statement2_all">
<field name="sequence" eval="1"/>
<field name="view_mode">form</field>
<field name="view_id" ref="view_bank_statement_form2"/>
<field name="act_window_id" ref="action_view_bank_statement_tree"/>
</record>
<menuitem action="action_view_bank_statement_tree" id="journal_cash_move_lines" parent="menu_finance_bank_and_cash"/>
</data> </data>
</openerp> </openerp>

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n" "Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2009-11-17 09:23+0000\n" "PO-Revision-Date: 2010-06-27 21:01+0000\n"
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n" "Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-22 04:17+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: account_voucher #. module: account_voucher
@ -215,7 +215,7 @@ msgstr "Estado"
#: selection:account.voucher.line,type:0 #: selection:account.voucher.line,type:0
#: rml:voucher.cash_receipt.drcr:0 #: rml:voucher.cash_receipt.drcr:0
msgid "Debit" msgid "Debit"
msgstr "Débito" msgstr "Debe"
#. module: account_voucher #. module: account_voucher
#: field:account.voucher,type:0 #: field:account.voucher,type:0

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-26 03:58+0000\n" "X-Launchpad-Export-Date: 2010-06-27 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: auction #. module: auction

View File

@ -7,14 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n" "Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2009-11-17 08:59+0000\n" "PO-Revision-Date: 2010-06-27 21:04+0000\n"
"Last-Translator: Jordi Esteve (www.zikzakmedia.com) " "Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\n"
"<jesteve@zikzakmedia.com>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-22 04:16+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: audittrail #. module: audittrail
@ -83,7 +82,7 @@ msgstr "Ver registro"
#. module: audittrail #. module: audittrail
#: model:ir.model,name:audittrail.model_audittrail_log_line #: model:ir.model,name:audittrail.model_audittrail_log_line
msgid "audittrail.log.line" msgid "audittrail.log.line"
msgstr "audittrail.registro.linea" msgstr "auditoria.registro.linea"
#. module: audittrail #. module: audittrail
#: field:audittrail.log,method:0 #: field:audittrail.log,method:0
@ -212,7 +211,7 @@ msgstr "Reglas de auditoría"
#. module: audittrail #. module: audittrail
#: model:ir.model,name:audittrail.model_audittrail_rule #: model:ir.model,name:audittrail.model_audittrail_rule
msgid "audittrail.rule" msgid "audittrail.rule"
msgstr "audittrail.regla" msgstr "auditoria.regla"
#. module: audittrail #. module: audittrail
#: view:audittrail.rule:0 #: view:audittrail.rule:0
@ -227,7 +226,7 @@ msgstr "Registrar escrituras"
#. module: audittrail #. module: audittrail
#: model:ir.model,name:audittrail.model_audittrail_log #: model:ir.model,name:audittrail.model_audittrail_log
msgid "audittrail.log" msgid "audittrail.log"
msgstr "audittrail.registro" msgstr "auditoria.registro"
#. module: audittrail #. module: audittrail
#: field:audittrail.log.line,field_description:0 #: field:audittrail.log.line,field_description:0

View File

@ -52,7 +52,7 @@ class crm_phonecall(osv.osv, crm_case):
('draft', 'Draft'), ('draft', 'Draft'),
('open', 'Todo'), ('open', 'Todo'),
('cancel', 'Cancelled'), ('cancel', 'Cancelled'),
('done', 'Closed'), ('done', 'Done'),
('pending', 'Pending'), ('pending', 'Pending'),
], 'State', size=16, readonly=True, ], 'State', size=16, readonly=True,
help='The state is set to \'Draft\', when a case is created.\ help='The state is set to \'Draft\', when a case is created.\
@ -89,7 +89,7 @@ class crm_phonecall(osv.osv, crm_case):
_defaults = { _defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), 'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0], 'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
'state': lambda *a: 'draft', 'state': lambda *a: 'open',
'user_id': lambda self,cr,uid,ctx: uid, 'user_id': lambda self,cr,uid,ctx: uid,
'active': lambda *a: 1, 'active': lambda *a: 1,
} }

View File

@ -67,7 +67,7 @@
<field name="view_mode">tree,calendar</field> <field name="view_mode">tree,calendar</field>
<field name="view_id" ref="crm_case_phone_tree_view"/> <field name="view_id" ref="crm_case_phone_tree_view"/>
<field name="domain" eval="'[(\'categ_id\',\'=\','+str(ref('categ_phone1'))+')]'"/> <field name="domain" eval="'[(\'categ_id\',\'=\','+str(ref('categ_phone1'))+')]'"/>
<field name="context">{'set_editable':True,'default_state':'open'}</field> <field name="context">{'set_editable':True,'default_state':'open','search_default_current':1,'search_default_today':1}</field>
<field name="search_view_id" ref="crm.view_crm_case_phonecalls_filter"/> <field name="search_view_id" ref="crm.view_crm_case_phonecalls_filter"/>
</record> </record>
@ -103,7 +103,7 @@
<field name="view_mode">tree,calendar</field> <field name="view_mode">tree,calendar</field>
<field name="view_id" ref="crm_case_phone_tree_view"/> <field name="view_id" ref="crm_case_phone_tree_view"/>
<field name="domain" eval="'[(\'categ_id\',\'=\','+str(ref('categ_phone2'))+')]'"/> <field name="domain" eval="'[(\'categ_id\',\'=\','+str(ref('categ_phone2'))+')]'"/>
<field name="context">{'default_state':'open'}</field> <field name="context">{'default_state':'open','search_default_current':1}</field>
<field name="search_view_id" ref="crm.view_crm_case_phonecalls_filter"/> <field name="search_view_id" ref="crm.view_crm_case_phonecalls_filter"/>
</record> </record>

View File

@ -245,17 +245,22 @@
<field name="type">search</field> <field name="type">search</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Search Phonecalls"> <search string="Search Phonecalls">
<filter icon="terp-go-today" string="Current"
name="current"
domain="[('state','in', ('draft','open','pending'))]"/>
<separator orientation="vertical"/>
<filter icon="terp-go-today" string="Today" <filter icon="terp-go-today" string="Today"
domain="[('date','&lt;', time.strftime('%%Y-%%m-%%d 23:59:59')),\ domain="[('date','&lt;', time.strftime('%%Y-%%m-%%d 23:59:59')),\
('date','&gt;=',datetime.strftime('%%Y-%%m-%%d 00:00:00'))]" ('date','&gt;=',datetime.strftime('%%Y-%%m-%%d 00:00:00'))]"
name="today"
help="Todays's Phonecalls" help="Todays's Phonecalls"
/> />
<filter icon="terp-go-week" <filter icon="terp-go-week"
string="7 Days" string="7 Days"
help="Phonecalls during last 7 days" help="Phonecalls during last 7 days"
domain="[('date','&lt;', time.strftime('%%Y-%%m-%%d')),\ domain="[('date','&gt;=',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
('date','&gt;=',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
/> />
<separator orientation="vertical"/> <separator orientation="vertical"/>
<field name="name" string="Call Summary"/> <field name="name" string="Call Summary"/>
<field name="partner_id"/> <field name="partner_id"/>

View File

@ -7,14 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n" "Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2010-01-05 05:59+0000\n" "POT-Creation-Date: 2010-01-05 05:59+0000\n"
"PO-Revision-Date: 2010-06-23 17:20+0000\n" "PO-Revision-Date: 2010-06-27 22:27+0000\n"
"Last-Translator: Jordi Esteve (www.zikzakmedia.com) " "Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\n"
"<jesteve@zikzakmedia.com>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-26 03:57+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: crm #. module: crm
@ -2302,7 +2301,7 @@ msgstr "Email empleado"
#. module: crm #. module: crm
#: model:ir.model,name:crm.model_crm_meeting #: model:ir.model,name:crm.model_crm_meeting
msgid "Meeting Cases" msgid "Meeting Cases"
msgstr "" msgstr "Casos reuniones"
#. module: crm #. module: crm
#: view:crm.job:0 #: view:crm.job:0
@ -2322,7 +2321,7 @@ msgstr "Trabajos"
#. module: crm #. module: crm
#: view:crm.case.rule:0 #: view:crm.case.rule:0
msgid "%(case_date)s = Creation date" msgid "%(case_date)s = Creation date"
msgstr "" msgstr "%(case_date)s = Fecha de creación"
#. module: crm #. module: crm
#: model:crm.case.stage,name:crm.stage_phone3 #: model:crm.case.stage,name:crm.stage_phone3
@ -2348,12 +2347,12 @@ msgstr "Correctivo"
#. module: crm #. module: crm
#: model:ir.model,name:crm.model_crm_opportunity #: model:ir.model,name:crm.model_crm_opportunity
msgid "Opportunity Cases" msgid "Opportunity Cases"
msgstr "" msgstr "Casos oportunidades"
#. module: crm #. module: crm
#: view:crm.case:0 #: view:crm.case:0
msgid "Support Query" msgid "Support Query"
msgstr "" msgstr "Petición de soporte"
#. module: crm #. module: crm
#: view:crm.case.rule:0 #: view:crm.case.rule:0
@ -2387,7 +2386,7 @@ msgstr "Enviar correo"
#. module: crm #. module: crm
#: wizard_view:crm.new.send.mail,init:0 #: wizard_view:crm.new.send.mail,init:0
msgid "Set case state to" msgid "Set case state to"
msgstr "" msgstr "Establecer estado del caso a"
#. module: crm #. module: crm
#: model:crm.case.category2,name:crm.categ2_fund3 #: model:crm.case.category2,name:crm.categ2_fund3
@ -2474,7 +2473,7 @@ msgstr "Cerrado"
#. module: crm #. module: crm
#: view:crm.job:0 #: view:crm.job:0
msgid "Candidate Name2" msgid "Candidate Name2"
msgstr "" msgstr "Nombre 2 candidato"
#. module: crm #. module: crm
#: code:addons/crm/crm.py:0 #: code:addons/crm/crm.py:0
@ -2516,32 +2515,32 @@ msgstr ""
#. module: crm #. module: crm
#: field:crm.meeting,freebusy:0 #: field:crm.meeting,freebusy:0
msgid "FreeBusy" msgid "FreeBusy"
msgstr "" msgstr "LibreOcupado"
#. module: crm #. module: crm
#: model:crm.case.categ,name:crm.categ_meet1 #: model:crm.case.categ,name:crm.categ_meet1
msgid "Customer Meeting" msgid "Customer Meeting"
msgstr "" msgstr "Reunión de cliente"
#. module: crm #. module: crm
#: wizard_field:crm.new.send.mail,init,doc2:0 #: wizard_field:crm.new.send.mail,init,doc2:0
msgid "Attachment2" msgid "Attachment2"
msgstr "" msgstr "Adjunto 2"
#. module: crm #. module: crm
#: wizard_field:crm.new.send.mail,init,doc3:0 #: wizard_field:crm.new.send.mail,init,doc3:0
msgid "Attachment3" msgid "Attachment3"
msgstr "" msgstr "Adjunto 3"
#. module: crm #. module: crm
#: view:crm.job:0 #: view:crm.job:0
msgid "Degree" msgid "Degree"
msgstr "" msgstr "Grado"
#. module: crm #. module: crm
#: wizard_field:crm.new.send.mail,init,doc1:0 #: wizard_field:crm.new.send.mail,init,doc1:0
msgid "Attachment1" msgid "Attachment1"
msgstr "" msgstr "Adjunto 1"
#. module: crm #. module: crm
#: code:addons/crm/crm_phonecall.py:0 #: code:addons/crm/crm_phonecall.py:0
@ -2610,7 +2609,7 @@ msgstr ">"
#. module: crm #. module: crm
#: view:crm.job:0 #: view:crm.job:0
msgid "Candidate Phone" msgid "Candidate Phone"
msgstr "" msgstr "Teléfono candidato"
#. module: crm #. module: crm
#: model:ir.actions.wizard,name:crm.wizard_crm_send_mail #: model:ir.actions.wizard,name:crm.wizard_crm_send_mail
@ -2632,7 +2631,7 @@ msgstr "Meses"
#: model:ir.actions.act_window,name:crm.action_crm_opportunity_assign_wizard #: model:ir.actions.act_window,name:crm.action_crm_opportunity_assign_wizard
#: model:ir.actions.act_window,name:crm.action_crm_phonecall_assign_wizard #: model:ir.actions.act_window,name:crm.action_crm_phonecall_assign_wizard
msgid "To Assign" msgid "To Assign"
msgstr "" msgstr "Para asignar"
#. module: crm #. module: crm
#: code:addons/crm/wizard/wizard_cal_subscribe.py:0 #: code:addons/crm/wizard/wizard_cal_subscribe.py:0
@ -2649,6 +2648,7 @@ msgstr "Cuando un proyecto/oportunidad real es detectado"
#: wizard_view:crm.job.partner_create,init:0 #: wizard_view:crm.job.partner_create,init:0
msgid "Are you sure you want to create a partner based on this job request ?" msgid "Are you sure you want to create a partner based on this job request ?"
msgstr "" msgstr ""
"Está seguro de que desea crear una empresa basada en esta solicitud laboral ?"
#. module: crm #. module: crm
#: wizard_field:crm.lead.opportunity_set,create_partner,action:0 #: wizard_field:crm.lead.opportunity_set,create_partner,action:0
@ -2675,12 +2675,12 @@ msgstr "Disminuir (0>1)"
#. module: crm #. module: crm
#: model:ir.actions.wizard,name:crm.wizard_case_history_event #: model:ir.actions.wizard,name:crm.wizard_case_history_event
msgid "History of Events" msgid "History of Events"
msgstr "" msgstr "Histórico de eventos"
#. module: crm #. module: crm
#: model:ir.model,name:crm.model_crm_case_category2 #: model:ir.model,name:crm.model_crm_case_category2
msgid "Category2 of case" msgid "Category2 of case"
msgstr "" msgstr "Categoría 2 del caso"
#. module: crm #. module: crm
#: wizard_field:crm.new.send.mail,init,to:0 #: wizard_field:crm.new.send.mail,init,to:0
@ -2718,7 +2718,7 @@ msgstr "Reciclado"
#: model:crm.case.categ,name:crm.categ_lead8 #: model:crm.case.categ,name:crm.categ_lead8
#: model:crm.case.categ,name:crm.categ_oppor8 #: model:crm.case.categ,name:crm.categ_oppor8
msgid "Other" msgid "Other"
msgstr "" msgstr "Otro"
#. module: crm #. module: crm
#: view:crm.case:0 #: view:crm.case:0
@ -2728,7 +2728,7 @@ msgstr ""
#: selection:crm.new.send.mail,init,state:0 #: selection:crm.new.send.mail,init,state:0
#: view:crm.opportunity:0 #: view:crm.opportunity:0
msgid "Done" msgid "Done"
msgstr "" msgstr "Hecho"
#. module: crm #. module: crm
#: field:crm.segmentation,som_interval_max:0 #: field:crm.segmentation,som_interval_max:0
@ -2777,7 +2777,7 @@ msgstr "Ya existe una empresa con el mismo nombre."
#. module: crm #. module: crm
#: model:ir.model,name:crm.model_crm_phonecall #: model:ir.model,name:crm.model_crm_phonecall
msgid "Phonecall Cases" msgid "Phonecall Cases"
msgstr "" msgstr "Casos llamadas"
#. module: crm #. module: crm
#: help:crm.case.rule,sequence:0 #: help:crm.case.rule,sequence:0
@ -2787,7 +2787,7 @@ msgstr ""
#. module: crm #. module: crm
#: field:crm.menu.config_wizard,helpdesk:0 #: field:crm.menu.config_wizard,helpdesk:0
msgid "Helpdesk" msgid "Helpdesk"
msgstr "" msgstr "Asistencia/Ayuda"
#. module: crm #. module: crm
#: field:crm.case,user_id:0 #: field:crm.case,user_id:0
@ -2809,18 +2809,18 @@ msgstr "Responsable"
#: model:crm.case.stage,name:crm.stage_claim4 #: model:crm.case.stage,name:crm.stage_claim4
#: model:crm.case.stage,name:crm.stage_meet3 #: model:crm.case.stage,name:crm.stage_meet3
msgid "Invalid" msgid "Invalid"
msgstr "" msgstr "Inválido"
#. module: crm #. module: crm
#: wizard_button:crm.job.meeting_set,init,order:0 #: wizard_button:crm.job.meeting_set,init,order:0
#: wizard_button:crm.phonecall.meeting_set,init,order:0 #: wizard_button:crm.phonecall.meeting_set,init,order:0
msgid "Set Meeting" msgid "Set Meeting"
msgstr "" msgstr "Fijar reunión"
#. module: crm #. module: crm
#: field:crm.menu.config_wizard,meeting:0 #: field:crm.menu.config_wizard,meeting:0
msgid "Calendar of Meetings" msgid "Calendar of Meetings"
msgstr "" msgstr "Calendario de reuniones"
#. module: crm #. module: crm
#: view:crm.case:0 #: view:crm.case:0
@ -2840,7 +2840,7 @@ msgstr ""
#. module: crm #. module: crm
#: view:crm.lead:0 #: view:crm.lead:0
msgid "Lead Name" msgid "Lead Name"
msgstr "" msgstr "Nombre iniciativa"
#. module: crm #. module: crm
#: view:crm.claim:0 #: view:crm.claim:0
@ -2861,22 +2861,22 @@ msgstr ""
#: wizard_view:crm.lead.opportunity_set,create_partner:0 #: wizard_view:crm.lead.opportunity_set,create_partner:0
#: wizard_view:crm.lead.partner_create,init:0 #: wizard_view:crm.lead.partner_create,init:0
msgid "Are you sure you want to create a partner based on this lead ?" msgid "Are you sure you want to create a partner based on this lead ?"
msgstr "" msgstr "¿Está seguro que quiere crear una empresa basada en esta iniciativa?"
#. module: crm #. module: crm
#: model:crm.case.stage,name:crm.stage_job6 #: model:crm.case.stage,name:crm.stage_job6
msgid "Refused by Employee" msgid "Refused by Employee"
msgstr "" msgstr "Rechazado por el empleado"
#. module: crm #. module: crm
#: field:crm.case,partner_name:0 #: field:crm.case,partner_name:0
msgid "Employee's Name" msgid "Employee's Name"
msgstr "" msgstr "Nombre del empleado"
#. module: crm #. module: crm
#: model:crm.case.stage,name:crm.stage_job2 #: model:crm.case.stage,name:crm.stage_job2
msgid "First Interview" msgid "First Interview"
msgstr "" msgstr "Primera entrevista"
#. module: crm #. module: crm
#: view:report.crm.case.section.categ.categ2:0 #: view:report.crm.case.section.categ.categ2:0
@ -2884,17 +2884,17 @@ msgstr ""
#: view:report.crm.case.section.categ2:0 #: view:report.crm.case.section.categ2:0
#: view:report.crm.case.section.stage:0 #: view:report.crm.case.section.stage:0
msgid "This Month" msgid "This Month"
msgstr "" msgstr "Este mes"
#. module: crm #. module: crm
#: view:crm.job:0 #: view:crm.job:0
msgid "Availability (weeks)" msgid "Availability (weeks)"
msgstr "" msgstr "Disponibilidad (semanas)"
#. module: crm #. module: crm
#: view:crm.opportunity:0 #: view:crm.opportunity:0
msgid "Opportunities Tree" msgid "Opportunities Tree"
msgstr "" msgstr "Árbol de oportunidades"
#. module: crm #. module: crm
#: help:crm.case,state:0 #: help:crm.case,state:0
@ -2911,12 +2911,12 @@ msgstr ""
#. module: crm #. module: crm
#: view:crm.job:0 #: view:crm.job:0
msgid "Open Jobs" msgid "Open Jobs"
msgstr "" msgstr "Trabajos abiertos"
#. module: crm #. module: crm
#: selection:crm.email.add.cc,name:0 #: selection:crm.email.add.cc,name:0
msgid "Email Address" msgid "Email Address"
msgstr "" msgstr "Correo electrónico"
#. module: crm #. module: crm
#: help:crm.segmentation,som_interval_max:0 #: help:crm.segmentation,som_interval_max:0
@ -2930,17 +2930,17 @@ msgstr ""
#. module: crm #. module: crm
#: field:crm.case,case_id:0 #: field:crm.case,case_id:0
msgid "Related Case" msgid "Related Case"
msgstr "" msgstr "Caso relacionado"
#. module: crm #. module: crm
#: field:crm.case.rule,server_action_id:0 #: field:crm.case.rule,server_action_id:0
msgid "Server Action" msgid "Server Action"
msgstr "" msgstr "Acción servidor"
#. module: crm #. module: crm
#: model:ir.actions.act_window,name:crm.crm_case_categ_claim0 #: model:ir.actions.act_window,name:crm.crm_case_categ_claim0
msgid "All Claims" msgid "All Claims"
msgstr "" msgstr "Todas las reclamaciones"
#. module: crm #. module: crm
#: field:crm.case.log,user_id:0 #: field:crm.case.log,user_id:0

View File

@ -98,6 +98,7 @@ class document_file(osv.osv):
('binary','Binary'), ('binary','Binary'),
],'Type', help="Type is used to separate URL and binary File"), ],'Type', help="Type is used to separate URL and binary File"),
'company_id': fields.many2one('res.company', 'Company'),
} }
def __get_def_directory(self, cr, uid, context=None): def __get_def_directory(self, cr, uid, context=None):
@ -105,6 +106,7 @@ class document_file(osv.osv):
return dirobj._get_root_directory(cr, uid, context) return dirobj._get_root_directory(cr, uid, context)
_defaults = { _defaults = {
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'ir.attachment', context=c),
'user_id': lambda self, cr, uid, ctx:uid, 'user_id': lambda self, cr, uid, ctx:uid,
'file_size': lambda self, cr, uid, ctx:0, 'file_size': lambda self, cr, uid, ctx:0,
'store_method': lambda *args: 'db', 'store_method': lambda *args: 'db',

View File

@ -9,15 +9,9 @@
</record> </record>
<record model="document.storage" id="storage_default"> <record model="document.storage" id="storage_default">
<field name="name">Default File storage</field> <field name="name">Default DB storage</field>
<field name="user_id" ref="base.user_admin"/> <field name="type">db</field>
</record> <field name="user_id" ref="base.user_admin"/>
<record model="document.storage" id="storage_db">
<field name="name">DB storage</field>
<field name="user_id" ref="base.user_admin"/>
<field name="type" eval="'db'" />
<field name="path"></field>
</record> </record>
<record model="document.directory" id="dir_root"> <record model="document.directory" id="dir_root">
@ -60,7 +54,7 @@
</record> </record>
<record model="document.directory" id="dir_personnal_folder"> <record model="document.directory" id="dir_personnal_folder">
<field name="name">Personnal Folders</field> <field name="name">Personal Folders</field>
<field name="parent_id" ref="dir_root"/> <field name="parent_id" ref="dir_root"/>
<field name="type">ressource</field> <field name="type">ressource</field>
<field name="storage_id" ref="storage_default"/> <field name="storage_id" ref="storage_default"/>

View File

@ -60,6 +60,7 @@ class document_directory(osv.osv):
'ressource_tree': fields.boolean('Tree Structure', 'ressource_tree': fields.boolean('Tree Structure',
help="Check this if you want to use the same tree structure as the object selected in the system."), help="Check this if you want to use the same tree structure as the object selected in the system."),
'dctx_ids': fields.one2many('document.directory.dctx', 'dir_id', 'Context fields'), 'dctx_ids': fields.one2many('document.directory.dctx', 'dir_id', 'Context fields'),
'company_id': fields.many2one('res.company', 'Company'),
} }
@ -92,6 +93,7 @@ class document_directory(osv.osv):
return None return None
_defaults = { _defaults = {
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'document.directory', context=c),
'user_id': lambda self,cr,uid,ctx: uid, 'user_id': lambda self,cr,uid,ctx: uid,
'domain': lambda self,cr,uid,ctx: '[]', 'domain': lambda self,cr,uid,ctx: '[]',
'type': lambda *args: 'directory', 'type': lambda *args: 'directory',

View File

@ -24,6 +24,8 @@ from osv import osv, fields
import os import os
import tools import tools
import base64 import base64
import logging
from tools.misc import ustr from tools.misc import ustr
from tools.translate import _ from tools.translate import _
@ -96,6 +98,8 @@ class document_storage(osv.osv):
""" """
_name = 'document.storage' _name = 'document.storage'
_description = 'Storage Media' _description = 'Storage Media'
_doclog = logging.getLogger('document')
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True, select=1), 'name': fields.char('Name', size=64, required=True, select=1),
'write_date': fields.datetime('Date Modified', readonly=True), 'write_date': fields.datetime('Date Modified', readonly=True),
@ -151,7 +155,7 @@ class document_storage(osv.osv):
# On a migrated db, some files may have the wrong storage type # On a migrated db, some files may have the wrong storage type
# try to fix their directory. # try to fix their directory.
if ira.file_size: if ira.file_size:
netsvc.Logger().notifyChannel('document', netsvc.LOG_WARNING, "ir.attachment #%d does not have a filename, but is at filestore, fix it!" % ira.id) self._doclog.warning( "ir.attachment #%d does not have a filename, but is at filestore, fix it!" % ira.id)
return None return None
fpath = os.path.join(boo.path, ira.store_fname) fpath = os.path.join(boo.path, ira.store_fname)
return file(fpath, 'rb').read() return file(fpath, 'rb').read()
@ -167,7 +171,7 @@ class document_storage(osv.osv):
# On a migrated db, some files may have the wrong storage type # On a migrated db, some files may have the wrong storage type
# try to fix their directory. # try to fix their directory.
if ira.file_size: if ira.file_size:
netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"ir.attachment #%d does not have a filename, trying the name." %ira.id) self._doclog.warning("ir.attachment #%d does not have a filename, trying the name." %ira.id)
sfname = ira.name sfname = ira.name
fpath = os.path.join(boo.path,ira.store_fname or ira.name) fpath = os.path.join(boo.path,ira.store_fname or ira.name)
if os.path.exists(fpath): if os.path.exists(fpath):
@ -187,7 +191,6 @@ class document_storage(osv.osv):
if not context: if not context:
context = {} context = {}
boo = self.browse(cr, uid, id, context) boo = self.browse(cr, uid, id, context)
logger = netsvc.Logger()
if fil_obj: if fil_obj:
ira = fil_obj ira = fil_obj
else: else:
@ -195,7 +198,7 @@ class document_storage(osv.osv):
if not boo.online: if not boo.online:
raise RuntimeError('media offline') raise RuntimeError('media offline')
logger.notifyChannel('document', netsvc.LOG_DEBUG, "Store data for ir.attachment #%d" % ira.id) self._doclog.debug( "Store data for ir.attachment #%d" % ira.id)
store_fname = None store_fname = None
fname = None fname = None
if boo.type == 'filestore': if boo.type == 'filestore':
@ -214,14 +217,14 @@ class document_storage(osv.osv):
fp = file(fname, 'wb') fp = file(fname, 'wb')
fp.write(data) fp.write(data)
fp.close() fp.close()
logger.notifyChannel('document', netsvc.LOG_DEBUG, "Saved data to %s" % fname) self._doclog.debug( "Saved data to %s" % fname)
filesize = len(data) # os.stat(fname).st_size filesize = len(data) # os.stat(fname).st_size
store_fname = os.path.join(flag, filename) store_fname = os.path.join(flag, filename)
# TODO Here, an old file would be left hanging. # TODO Here, an old file would be left hanging.
except Exception, e : except Exception, e:
netsvc.Logger().notifyChannel('document', netsvc.LOG_WARNING, "Couldn't save data: %s" % str(e)) self._doclog.warning( "Couldn't save data to %s", path, exc_info=True)
raise except_orm(_('Error!'), str(e)) raise except_orm(_('Error!'), str(e))
elif boo.type == 'db': elif boo.type == 'db':
filesize = len(data) filesize = len(data)
@ -250,14 +253,12 @@ class document_storage(osv.osv):
fp = file(fname,'wb') fp = file(fname,'wb')
fp.write(data) fp.write(data)
fp.close() fp.close()
logger.notifyChannel('document',netsvc.LOG_DEBUG,"Saved data to %s" % fname) self._doclog.debug("Saved data to %s", fname)
filesize = len(data) # os.stat(fname).st_size filesize = len(data) # os.stat(fname).st_size
store_fname = os.path.join(*npath) store_fname = os.path.join(*npath)
# TODO Here, an old file would be left hanging. # TODO Here, an old file would be left hanging.
except Exception,e : except Exception,e :
import traceback self._doclog.warning("Couldn't save data:", exc_info=True)
traceback.print_exc()
netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Couldn't save data: %s" % e)
raise except_orm(_('Error!'), str(e)) raise except_orm(_('Error!'), str(e))
else: else:
raise TypeError("No %s storage" % boo.type) raise TypeError("No %s storage" % boo.type)
@ -271,8 +272,8 @@ class document_storage(osv.osv):
try: try:
mime, icont = cntIndex.doIndex(data, ira.datas_fname, mime, icont = cntIndex.doIndex(data, ira.datas_fname,
ira.file_type or None, fname) ira.file_type or None, fname)
except Exception, e: except Exception:
logger.notifyChannel('document', netsvc.LOG_DEBUG, 'Cannot index file: %s' % str(e)) self._doclog.debug('Cannot index file:', exc_info=True)
pass pass
# a hack: /assume/ that the calling write operation will not try # a hack: /assume/ that the calling write operation will not try
@ -284,7 +285,7 @@ class document_storage(osv.osv):
file_node.content_type = mime file_node.content_type = mime
return True return True
except Exception, e : except Exception, e :
netsvc.Logger().notifyChannel('document', netsvc.LOG_WARNING, "Couldn't save data: %s" % str(e)) self._doclog.warning( "Couldn't save data:", exc_info=True)
# should we really rollback once we have written the actual data? # should we really rollback once we have written the actual data?
# at the db case (only), that rollback would be safe # at the db case (only), that rollback would be safe
raise except_orm(_('Error at doc write!'), str(e)) raise except_orm(_('Error at doc write!'), str(e))
@ -319,9 +320,9 @@ class document_storage(osv.osv):
try: try:
os.unlink(fname) os.unlink(fname)
except Exception, e: except Exception, e:
netsvc.Logger().notifyChannel('document', netsvc.LOG_WARNING, "Could not remove file %s, please remove manually." % fname) self._doclog.warning("Could not remove file %s, please remove manually.", fname, exc_info=True)
else: else:
netsvc.Logger().notifyChannel('document', netsvc.LOG_WARNING, "Unknown unlink key %s" % ktype) self._doclog.warning("Unknown unlink key %s" % ktype)
return True return True

View File

@ -13,14 +13,15 @@
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Storage Media"> <form string="Storage Media">
<group colspan="4" col="4"> <group colspan="4" col="6">
<field name="name" select="1" colspan="4"/> <field name="name" select="1" colspan="4"/>
<field name="user_id"/>
<field name="type"/> <field name="type"/>
<newline/>
<field name="user_id"/>
<field name="online"/> <field name="online"/>
<field name="readonly"/> <field name="readonly"/>
</group> </group>
<group colspan="2" attrs="{'invisible':[('type','!=','realstore')]}"> <group colspan="2" attrs="{'invisible':[('type','=','db')]}">
<field name="path"/> <field name="path"/>
</group> </group>
</form> </form>
@ -35,17 +36,31 @@
<tree string="Storage Media" toolbar="1"> <tree string="Storage Media" toolbar="1">
<field name="name"/> <field name="name"/>
<field name="type"/> <field name="type"/>
<field name="online"/>
<field name="readonly"/>
</tree> </tree>
</field> </field>
</record> </record>
<record id="view_document_storage_filter" model="ir.ui.view">
<field name="name">Search View: Document Storage</field>
<field name="model">document.storage</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Document storage">
<field name="name" />
<newline/>
<group expand="0" string="Group By..." groups="base.group_extended">
<filter string="Type" domain="[]" context="{'group_by':'type'}"/>
</group>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_document_storage_form"> <record model="ir.actions.act_window" id="action_document_storage_form">
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">document.storage</field> <field name="res_model">document.storage</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_document_storage_filter"/>
</record> </record>
<menuitem <menuitem
name="Storage Media" name="Storage Media"
@ -63,6 +78,7 @@
<field name="user_id"/> <field name="user_id"/>
<field name="parent_id"/> <field name="parent_id"/>
<field name="storage_id" /> <field name="storage_id" />
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
<notebook colspan="4"> <notebook colspan="4">
<page string="Definition"> <page string="Definition">
<separator string="Directory Type" colspan="4"/> <separator string="Directory Type" colspan="4"/>
@ -96,7 +112,7 @@
</tree> </tree>
</field> </field>
</page> </page>
<page string="Dynamic context"> <page string="Dynamic context" groups="base.group_extended">
<field name="dctx_ids" nolabel="1" colspan="4"> <field name="dctx_ids" nolabel="1" colspan="4">
<tree string="Fields" editable="bottom"> <tree string="Fields" editable="bottom">
<field name="field"/> <field name="field"/>
@ -119,6 +135,7 @@
<field name="name">document.directory</field> <field name="name">document.directory</field>
<field name="model">document.directory</field> <field name="model">document.directory</field>
<field name="type">tree</field> <field name="type">tree</field>
<field name="field_parent">child_ids</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Directories" toolbar="1"> <tree string="Directories" toolbar="1">
<field name="name"/> <field name="name"/>
@ -130,12 +147,35 @@
</field> </field>
</record> </record>
<record id="view_document_directory_filter" model="ir.ui.view">
<field name="name">Search View: Document Directory</field>
<field name="model">document.directory</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Document Directory">
<filter string="Static" domain="[('type','=','directory')]"/>
<filter string="Resources" domain="[('type','=','ressource')]"/>
<separator orientation="vertical"/>
<field name="name" />
<field name="user_id" />
<field name="storage_id" />
<newline/>
<group expand="0" string="Group By..." groups="base.group_extended">
<filter string="Type" domain="[]" context="{'group_by':'type'}"/>
<filter string="Owner" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Storage" domain="[]" context="{'group_by':'storage_id'}"/>
</group>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_document_directory_form"> <record model="ir.actions.act_window" id="action_document_directory_form">
<field name="name">Directories</field> <field name="name">Directories</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">document.directory</field> <field name="res_model">document.directory</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_document_directory_filter"/>
</record> </record>
<record id="action_dir_view1" model="ir.actions.act_window.view"> <record id="action_dir_view1" model="ir.actions.act_window.view">
@ -159,7 +199,7 @@
<record model="ir.actions.act_window" id="action_document_directory_tree"> <record model="ir.actions.act_window" id="action_document_directory_tree">
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="name">Directorie's Structure</field> <field name="name">Directories' Structure</field>
<field name="res_model">document.directory</field> <field name="res_model">document.directory</field>
<field name="view_type">tree</field> <field name="view_type">tree</field>
<field name="view_id" ref="document.view_document_directory_tree"/> <field name="view_id" ref="document.view_document_directory_tree"/>
@ -180,7 +220,8 @@
<group colspan="4" col="6"> <group colspan="4" col="6">
<field name="name" select="1" /> <field name="name" select="1" />
<field name="type"/> <field name="type"/>
<field name="parent_id"/> <field name="parent_id"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
</group> </group>
<notebook colspan="4"> <notebook colspan="4">
<page string="Attachment"> <page string="Attachment">
@ -244,11 +285,15 @@
help="Filter on my Attachment" /> help="Filter on my Attachment" />
</field> </field>
<field name="partner_id"/> <field name="partner_id"/>
<field name="company_id" groups="base.group_multi_company"/>
<newline/> <newline/>
<group expand="0" string="Group By..."> <group expand="0" string="Group By...">
<filter string="Partner" icon="terp-personal" domain="[]" <filter string="Partner" icon="terp-personal" domain="[]"
context="{'group_by':'partner_id'}" /> context="{'group_by':'partner_id'}" />
<filter string="Directory" icon="terp-folder-green" domain="[]" context="{'group_by':'parent_id'}"/> <filter string="Directory" icon="terp-folder-green" domain="[]" context="{'group_by':'parent_id'}"/>
<filter string="Type" domain="[]" context="{'group_by':'type'}"/>
<filter string="Owner" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Company" icon="terp-personal" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
</group> </group>
</search> </search>
</field> </field>
@ -259,7 +304,7 @@
<field name="type">tree</field> <field name="type">tree</field>
<field name="priority" eval="1"/> <field name="priority" eval="1"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree colors="blue:type in ('url')" string="Documents"> <tree colors="blue:type in ('url',)">
<field name="name"/> <field name="name"/>
<field name="type"/> <field name="type"/>
<field name="datas_fname"/> <field name="datas_fname"/>
@ -272,8 +317,10 @@
</record> </record>
<record model="ir.actions.act_window" id="action_document_file_form"> <record model="ir.actions.act_window" id="action_document_file_form">
<field name="name">Documents</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">ir.attachment</field> <field name="res_model">ir.attachment</field>
<field name="name">Document</field>
<field name="view_type">form</field> <field name="view_type">form</field>
</record> </record>
<menuitem name="Documents" id="menu_document_doc" parent="base.menu_document" sequence="5"/> <menuitem name="Documents" id="menu_document_doc" parent="base.menu_document" sequence="5"/>
@ -286,6 +333,7 @@
<record model="ir.actions.act_window" id="action_document_file_directory_form"> <record model="ir.actions.act_window" id="action_document_file_directory_form">
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">ir.attachment</field> <field name="res_model">ir.attachment</field>
<field name="name">Directory</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="domain">[('parent_id','child_of',active_id)]</field> <field name="domain">[('parent_id','child_of',active_id)]</field>
<field name="context">{'parent_id':active_id}</field> <field name="context">{'parent_id':active_id}</field>
@ -348,6 +396,9 @@
res_model="ir.attachment" res_model="ir.attachment"
src_model="document.directory"/> src_model="document.directory"/>
</data> </data>
</openerp> </openerp>

View File

@ -339,7 +339,8 @@ class node_dir(node_database):
fil_id = fil_obj.create(cr, uid, val, context=ctx) fil_id = fil_obj.create(cr, uid, val, context=ctx)
fil = fil_obj.browse(cr, uid, fil_id, context=ctx) fil = fil_obj.browse(cr, uid, fil_id, context=ctx)
fnode = node_file(path, self, self.context, fil) fnode = node_file(path, self, self.context, fil)
fnode.set_data(cr, data, fil) if data is not None:
fnode.set_data(cr, data, fil)
return fnode return fnode
def get_etag(self, cr): def get_etag(self, cr):
@ -667,7 +668,7 @@ class node_file(node_class):
self.file_id = fil.id self.file_id = fil.id
#todo: more info from ir_attachment #todo: more info from ir_attachment
if fil.file_type and '/' in fil.file_type: if fil.file_type and '/' in fil.file_type:
self.mimetype = fil.file_type self.mimetype = str(fil.file_type)
self.create_date = fil.create_date self.create_date = fil.create_date
self.write_date = fil.write_date or fil.create_date self.write_date = fil.write_date or fil.create_date
self.content_length = fil.file_size self.content_length = fil.file_size
@ -809,7 +810,7 @@ class node_content(node_class):
(self.extension,)) (self.extension,))
res = cr.fetchall() res = cr.fetchall()
if res and res[0][0]: if res and res[0][0]:
self.mimetype = res[0][0] self.mimetype = str(res[0][0])
def get_data(self, cr, fil_obj = None): def get_data(self, cr, fil_obj = None):

View File

@ -19,16 +19,6 @@
# #
############################################################################## ##############################################################################
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from osv import fields,osv from osv import fields,osv
import time import time
@ -55,8 +45,8 @@ class report_document_user(osv.osv):
def init(self, cr): def init(self, cr):
tools.drop_view_if_exists(cr, 'report_document_user') tools.drop_view_if_exists(cr, 'report_document_user')
cr.execute(""" cr.execute("""
create or replace view report_document_user as ( CREATE OR REPLACE VIEW report_document_user as (
select SELECT
min(f.id) as id, min(f.id) as id,
to_char(f.create_date, 'YYYY') as name, to_char(f.create_date, 'YYYY') as name,
to_char(f.create_date, 'MM') as month, to_char(f.create_date, 'MM') as month,
@ -68,7 +58,7 @@ class report_document_user(osv.osv):
f.file_size as file_size, f.file_size as file_size,
min(d.type) as type, min(d.type) as type,
f.write_date as change_date f.write_date as change_date
from ir_attachment f FROM ir_attachment f
left join document_directory d on (f.parent_id=d.id and d.name<>'') left join document_directory d on (f.parent_id=d.id and d.name<>'')
inner join res_users u on (f.user_id=u.id) inner join res_users u on (f.user_id=u.id)
group by to_char(f.create_date, 'YYYY'), to_char(f.create_date, 'MM'),d.name,f.parent_id,d.type,f.create_date,f.user_id,f.file_size,u.name,d.type,f.write_date group by to_char(f.create_date, 'YYYY'), to_char(f.create_date, 'MM'),d.name,f.parent_id,d.type,f.create_date,f.user_id,f.file_size,u.name,d.type,f.write_date
@ -95,7 +85,7 @@ class report_files_partner(osv.osv):
def init(self, cr): def init(self, cr):
tools.drop_view_if_exists(cr, 'report_files_partner') tools.drop_view_if_exists(cr, 'report_files_partner')
cr.execute(""" cr.execute("""
create or replace view report_files_partner as ( CREATE VIEW report_files_partner as (
select min(f.id) as id,count(*) as nbr, select min(f.id) as id,count(*) as nbr,
to_char(f.create_date,'YYYY') as name, to_char(f.create_date,'YYYY') as name,
min(to_char(f.create_date,'MM')) as month, min(to_char(f.create_date,'MM')) as month,

View File

@ -49,14 +49,14 @@ def textToString(element) :
class TxtIndex(indexer): class TxtIndex(indexer):
def _getMimeTypes(self): def _getMimeTypes(self):
return ['text/plain','text/html','text/diff','text/xml', 'text/*', return ['text/plain','text/html','text/diff','text/xml', 'text/*',
'application/xml'] 'application/xml']
def _getExtensions(self): def _getExtensions(self):
return ['.txt', '.py'] return ['.txt', '.py']
def _doIndexContent(self,content): def _doIndexContent(self,content):
return content return content
cntIndex.register(TxtIndex()) cntIndex.register(TxtIndex())
class PptxIndex(indexer): class PptxIndex(indexer):
@ -95,8 +95,8 @@ class DocIndex(indexer):
return ['.doc'] return ['.doc']
def _doIndexFile(self,fname): def _doIndexFile(self,fname):
#fp = Popen(['antiword', fname], shell=False, stdout=PIPE).stdout fp = Popen(['antiword', fname], shell=False, stdout=PIPE).stdout
return _to_unicode( 'None') return _to_unicode(fp.read())
cntIndex.register(DocIndex()) cntIndex.register(DocIndex())
@ -177,21 +177,33 @@ class ImageNoIndex(indexer):
cntIndex.register(ImageNoIndex()) cntIndex.register(ImageNoIndex())
#class Doc(indexer): # other opendocument formats:
#def _getDefMime(self,ext): # chart-template chart database
# formula-template formula graphics-template graphics
# image
# presentation-template presentation spreadsheet-template spreadsheet
class OpenDoc(indexer):
""" Index OpenDocument files.
Q: is it really worth it to index spreadsheets, or do we only get a
meaningless list of numbers (cell contents) ?
"""
def _getMimeTypes(self):
otypes = [ 'text', 'text-web', 'text-template', 'text-master' ]
return map(lambda a: 'application/vnd.oasis.opendocument.'+a, otypes)
def _getExtensions(self):
return ['.odt', '.ott', ] # '.ods'
def _doIndexContent(self, content):
s = StringIO.StringIO(content)
o = odt2txt.OpenDocumentTextFile(s)
result = _to_unicode(o.toString())
s.close()
return result
cntIndex.register(OpenDoc())
#def content_index(content, filename=None, content_type=None):
#fname,ext = os.path.splitext(filename)
#result = ''
#elif ext in ('.xls','.ods','.odt','.odp'):
#s = StringIO.StringIO(content)
#o = odt2txt.OpenDocumentTextFile(s)
#result = _to_unicode(o.toString())
#s.close()
#elif ext in ('.txt','.py','.patch','.html','.csv','.xml'):
#result = content
#else:
#result = content
#return result
#eof #eof

View File

@ -31,6 +31,9 @@ for fname in args:
else: else:
res = cntIndex.doIndex(None, fname, None, fname,True) res = cntIndex.doIndex(None, fname, None, fname,True)
if options.verbose:
for line in res[:5]:
print line
except Exception,e: except Exception,e:
import traceback,sys import traceback,sys
tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback)) tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback))

View File

@ -55,8 +55,6 @@ class openerp_dav_handler(dav_interface):
M_NS={ "DAV:" : dav_interface.M_NS['DAV:'],} M_NS={ "DAV:" : dav_interface.M_NS['DAV:'],}
def __init__(self, parent, verbose=False): def __init__(self, parent, verbose=False):
self.db_name = False
self.directory_id=False
self.db_name_list=[] self.db_name_list=[]
self.parent = parent self.parent = parent
self.baseuri = parent.baseuri self.baseuri = parent.baseuri
@ -65,10 +63,10 @@ class openerp_dav_handler(dav_interface):
def get_propnames(self, uri): def get_propnames(self, uri):
props = self.PROPS props = self.PROPS
self.parent.log_message('get propnames: %s' % uri) self.parent.log_message('get propnames: %s' % uri)
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
if cr: cr.close() if cr: cr.close()
# TODO: maybe limit props for databases..?
return props return props
node = self.uri2object(cr, uid, pool, uri2) node = self.uri2object(cr, uid, pool, uri2)
if node: if node:
@ -83,7 +81,6 @@ class openerp_dav_handler(dav_interface):
raise DAV_NotFound raise DAV_NotFound
def match_prop(self, uri, match, ns, propname): def match_prop(self, uri, match, ns, propname):
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
if cr: cr.close() if cr: cr.close()
@ -104,8 +101,7 @@ class openerp_dav_handler(dav_interface):
pname -- name of the property pname -- name of the property
""" """
if self.M_NS.has_key(ns): if self.M_NS.has_key(ns):
return dav_interface.get_prop(self, uri, ns, propname) return dav_interface.get_prop(self, uri, ns, propname)
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
if cr: cr.close() if cr: cr.close()
@ -114,19 +110,46 @@ class openerp_dav_handler(dav_interface):
if not node: if not node:
cr.close() cr.close()
raise DAV_NotFound raise DAV_NotFound
res = node.get_dav_eprop(cr, ns, propname) res = node.get_dav_eprop(cr, ns, propname)
cr.close() cr.close()
return res return res
def get_db(self,uri): def get_db(self, uri, rest_ret=False, allow_last=False):
names=self.uri2local(uri).split('/') """Parse the uri and get the dbname and the rest.
self.db_name=False Db name should be the first component in the unix-like
if len(names) > 1: path supplied in uri.
self.db_name=self.uri2local(uri).split('/')[1]
if self.db_name=='': @param rest_ret Instead of the db_name, return (db_name, rest),
raise Exception,'Plese specify Database name in folder' where rest is the remaining path
return self.db_name @param allow_last If the dbname is the last component in the
path, allow it to be resolved. The default False value means
we will not attempt to use the db, unless there is more
path.
@return db_name or (dbname, rest) depending on rest_ret,
will return dbname=False when component is not found.
"""
uri2 = self.uri2local(uri)
if uri2.startswith('/'):
uri2 = uri2[1:]
names=uri2.split('/',1)
db_name=False
rest = None
if allow_last:
ll = 0
else:
ll = 1
if len(names) > ll and names[0]:
db_name = names[0]
names = names[1:]
if rest_ret:
if len(names):
rest = names[0]
return db_name, rest
return db_name
def urijoin(self,*ajoin): def urijoin(self,*ajoin):
""" Return the base URI of this request, or even join it with the """ Return the base URI of this request, or even join it with the
@ -140,20 +163,25 @@ class openerp_dav_handler(dav_interface):
result = s.exp_list() result = s.exp_list()
self.db_name_list=[] self.db_name_list=[]
for db_name in result: for db_name in result:
db = pooler.get_db_only(db_name) cr = None
cr = db.cursor() try:
cr.execute("select id from ir_module_module where name = 'document' and state='installed' ") db = pooler.get_db_only(db_name)
res=cr.fetchone() cr = db.cursor()
if res and len(res): cr.execute("SELECT id FROM ir_module_module WHERE name = 'document' AND state='installed' ")
self.db_name_list.append(db_name) res=cr.fetchone()
cr.close() if res and len(res):
self.db_name_list.append(db_name)
except Exception, e:
self.parent.log_error("Exception in db list: %s" % e)
finally:
if cr:
cr.close()
return self.db_name_list return self.db_name_list
def get_childs(self, uri, filters=None): def get_childs(self, uri, filters=None):
""" return the child objects as self.baseuris for the given URI """ """ return the child objects as self.baseuris for the given URI """
self.parent.log_message('get childs: %s' % uri) self.parent.log_message('get childs: %s' % uri)
if uri[-1]=='/':uri=uri[:-1] cr, uid, pool, dbname, uri2 = self.get_cr(uri, allow_last=True)
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
if cr: cr.close() if cr: cr.close()
@ -194,38 +222,33 @@ class openerp_dav_handler(dav_interface):
# #
# pos: -1 to get the parent of the uri # pos: -1 to get the parent of the uri
# #
def get_cr(self, uri): def get_cr(self, uri, allow_last=False):
""" Split the uri, grab a cursor for that db
"""
pdb = self.parent.auth_proxy.last_auth pdb = self.parent.auth_proxy.last_auth
reluri = self.uri2local(uri) dbname, uri2 = self.get_db(uri, rest_ret=True, allow_last=allow_last)
try: uri2 = (uri2 and uri2.split('/')) or []
dbname = reluri.split('/')[1]
except:
dbname = False
if not dbname: if not dbname:
return None, None, None, False, None return None, None, None, False, uri2
if not pdb and dbname: # if dbname was in our uri, we should have authenticated
# if dbname was in our uri, we should have authenticated # against that.
# against that. assert pdb == dbname, " %s != %s" %(pdb, dbname)
raise Exception("Programming error")
#assert pdb == dbname, " %s != %s" %(pdb, dbname)
res = self.parent.auth_proxy.auth_creds.get(dbname, False) res = self.parent.auth_proxy.auth_creds.get(dbname, False)
if not res: if not res:
self.parent.auth_proxy.checkRequest(self.parent, uri, dbname) self.parent.auth_proxy.checkRequest(self.parent, uri, dbname)
res = self.parent.auth_proxy.auth_creds[dbname] res = self.parent.auth_proxy.auth_creds[dbname]
user, passwd, dbn2, uid = res user, passwd, dbn2, uid = res
db,pool = pooler.get_db_and_pool(dbname) db,pool = pooler.get_db_and_pool(dbname)
cr = db.cursor() cr = db.cursor()
uri2 = reluri.split('/')[2:]
return cr, uid, pool, dbname, uri2 return cr, uid, pool, dbname, uri2
def uri2object(self, cr, uid, pool,uri): def uri2object(self, cr, uid, pool, uri):
if not uid: if not uid:
return None return None
return pool.get('document.directory').get_object(cr, uid, uri) return pool.get('document.directory').get_object(cr, uid, uri)
def get_data(self,uri): def get_data(self,uri, rrange=None):
self.parent.log_message('GET: %s' % uri) self.parent.log_message('GET: %s' % uri)
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
try: try:
if not dbname: if not dbname:
@ -234,6 +257,9 @@ class openerp_dav_handler(dav_interface):
if not node: if not node:
raise DAV_NotFound(uri2) raise DAV_NotFound(uri2)
try: try:
if rrange:
self.parent.log_error("Doc get_data cannot use range")
raise DAV_Error(409)
datas = node.get_data(cr) datas = node.get_data(cr)
except TypeError,e: except TypeError,e:
import traceback import traceback
@ -256,7 +282,6 @@ class openerp_dav_handler(dav_interface):
def _get_dav_resourcetype(self,uri): def _get_dav_resourcetype(self,uri):
""" return type of object """ """ return type of object """
self.parent.log_message('get RT: %s' % uri) self.parent.log_message('get RT: %s' % uri)
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
try: try:
if not dbname: if not dbname:
@ -272,7 +297,6 @@ class openerp_dav_handler(dav_interface):
def _get_dav_displayname(self,uri): def _get_dav_displayname(self,uri):
self.parent.log_message('get DN: %s' % uri) self.parent.log_message('get DN: %s' % uri)
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
cr.close() cr.close()
@ -288,7 +312,6 @@ class openerp_dav_handler(dav_interface):
def _get_dav_getcontentlength(self, uri): def _get_dav_getcontentlength(self, uri):
""" return the content length of an object """ """ return the content length of an object """
self.parent.log_message('get length: %s' % uri) self.parent.log_message('get length: %s' % uri)
if uri[-1]=='/':uri=uri[:-1]
result = 0 result = 0
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
@ -306,7 +329,6 @@ class openerp_dav_handler(dav_interface):
def _get_dav_getetag(self,uri): def _get_dav_getetag(self,uri):
""" return the ETag of an object """ """ return the ETag of an object """
self.parent.log_message('get etag: %s' % uri) self.parent.log_message('get etag: %s' % uri)
if uri[-1]=='/':uri=uri[:-1]
result = 0 result = 0
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
@ -323,7 +345,6 @@ class openerp_dav_handler(dav_interface):
@memoize(CACHE_SIZE) @memoize(CACHE_SIZE)
def get_lastmodified(self, uri): def get_lastmodified(self, uri):
""" return the last modified date of the object """ """ return the last modified date of the object """
if uri[-1]=='/':uri=uri[:-1]
today = time.time() today = time.time()
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
@ -342,7 +363,6 @@ class openerp_dav_handler(dav_interface):
@memoize(CACHE_SIZE) @memoize(CACHE_SIZE)
def get_creationdate(self, uri): def get_creationdate(self, uri):
""" return the last modified date of the object """ """ return the last modified date of the object """
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
raise DAV_Error, 409 raise DAV_Error, 409
@ -361,7 +381,6 @@ class openerp_dav_handler(dav_interface):
@memoize(CACHE_SIZE) @memoize(CACHE_SIZE)
def _get_dav_getcontenttype(self,uri): def _get_dav_getcontenttype(self,uri):
self.parent.log_message('get contenttype: %s' % uri) self.parent.log_message('get contenttype: %s' % uri)
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
return 'httpd/unix-directory' return 'httpd/unix-directory'
@ -369,7 +388,7 @@ class openerp_dav_handler(dav_interface):
node = self.uri2object(cr, uid, pool, uri2) node = self.uri2object(cr, uid, pool, uri2)
if not node: if not node:
raise DAV_NotFound(uri2) raise DAV_NotFound(uri2)
result = node.mimetype result = str(node.mimetype)
return result return result
#raise DAV_NotFound, 'Could not find %s' % path #raise DAV_NotFound, 'Could not find %s' % path
finally: finally:
@ -434,10 +453,8 @@ class openerp_dav_handler(dav_interface):
def rmcol(self,uri): def rmcol(self,uri):
""" delete a collection """ """ delete a collection """
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool, dbname, uri2 = self.get_cr(uri) cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname: # *-* if not dbname:
raise DAV_Error, 409 raise DAV_Error, 409
node = self.uri2object(cr, uid, pool, uri2) node = self.uri2object(cr, uid, pool, uri2)
node.rmcol(cr) node.rmcol(cr)
@ -447,7 +464,6 @@ class openerp_dav_handler(dav_interface):
return 204 return 204
def rm(self,uri): def rm(self,uri):
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool,dbname, uri2 = self.get_cr(uri) cr, uid, pool,dbname, uri2 = self.get_cr(uri)
if not dbname: if not dbname:
cr.close() cr.close()
@ -626,3 +642,5 @@ class openerp_dav_handler(dav_interface):
def is_collection(self, uri): def is_collection(self, uri):
""" test if the given uri is a collection """ """ test if the given uri is a collection """
return self._get_dav_resourcetype(uri)==COLLECTION return self._get_dav_resourcetype(uri)==COLLECTION
#eof

View File

@ -3,6 +3,7 @@
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
# Copyright (c) 1999 Christian Scholz (ruebe@aachen.heimat.de)
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -48,7 +49,9 @@ def mk_prop_response(self, uri, good_props, bad_props, doc):
uparts=urlparse.urlparse(uri) uparts=urlparse.urlparse(uri)
fileloc=uparts[2] fileloc=uparts[2]
href=doc.createElement("D:href") href=doc.createElement("D:href")
huri=doc.createTextNode(uparts[0]+'://'+'/'.join(uparts[1:2]) + urllib.quote(fileloc)) davpath = self._dataclass.parent.get_davpath()
hurl = '%s://%s%s%s' % (uparts[0], uparts[1], davpath, urllib.quote(fileloc))
huri=doc.createTextNode(hurl)
href.appendChild(huri) href.appendChild(huri)
re.appendChild(href) re.appendChild(href)
@ -111,5 +114,45 @@ def mk_prop_response(self, uri, good_props, bad_props, doc):
return re return re
PROPFIND.mk_prop_response = mk_prop_response def mk_propname_response(self,uri,propnames,doc):
""" make a new <prop> result element for a PROPNAME request
This will simply format the propnames list.
propnames should have the format {NS1 : [prop1, prop2, ...], NS2: ...}
"""
re=doc.createElement("D:response")
# write href information
uparts=urlparse.urlparse(uri)
fileloc=uparts[2]
href=doc.createElement("D:href")
davpath = self._dataclass.parent.get_davpath()
hurl = '%s://%s%s%s' % (uparts[0], uparts[1], davpath, urllib.quote(fileloc))
huri=doc.createTextNode(hurl)
href.appendChild(huri)
re.appendChild(href)
ps=doc.createElement("D:propstat")
nsnum=0
for ns,plist in propnames.items():
# write prop element
pr=doc.createElement("D:prop")
nsp="ns"+str(nsnum)
pr.setAttribute("xmlns:"+nsp,ns)
nsnum=nsnum+1
# write propertynames
for p in plist:
pe=doc.createElement(nsp+":"+p)
pr.appendChild(pe)
ps.appendChild(pr)
re.appendChild(ps)
return re
PROPFIND.mk_prop_response = mk_prop_response
PROPFIND.mk_propname_response = mk_propname_response

View File

@ -33,6 +33,7 @@ from dav_fs import openerp_dav_handler
from tools.config import config from tools.config import config
from DAV.WebDAVServer import DAVRequestHandler from DAV.WebDAVServer import DAVRequestHandler
from service.websrv_lib import HTTPDir,FixSendError from service.websrv_lib import HTTPDir,FixSendError
from BaseHTTPServer import BaseHTTPRequestHandler
import urlparse import urlparse
import urllib import urllib
from string import atoi,split from string import atoi,split
@ -42,6 +43,9 @@ def OpenDAVConfig(**kw):
class OpenDAV: class OpenDAV:
def __init__(self, **kw): def __init__(self, **kw):
self.__dict__.update(**kw) self.__dict__.update(**kw)
def getboolean(self, word):
return self.__dict__.get(word, False)
class Config: class Config:
DAV = OpenDAV(**kw) DAV = OpenDAV(**kw)
@ -51,6 +55,7 @@ def OpenDAVConfig(**kw):
class DAVHandler(FixSendError,DAVRequestHandler): class DAVHandler(FixSendError,DAVRequestHandler):
verbose = False verbose = False
protocol_version = 'HTTP/1.1'
def get_userinfo(self,user,pw): def get_userinfo(self,user,pw):
return False return False
@ -64,18 +69,17 @@ class DAVHandler(FixSendError,DAVRequestHandler):
pass pass
def get_db_from_path(self, uri): def get_db_from_path(self, uri):
if uri or uri == '/': # interface class will handle all cases.
dbs = self.IFACE_CLASS.db_list() res = self.IFACE_CLASS.get_db(uri, allow_last=True)
res = len(dbs) and dbs[0] or False
else:
res = self.IFACE_CLASS.get_db(uri)
return res return res
def setup(self): def setup(self):
davpath = '/'+config.get_misc('webdav','vdir','webdav') self.davpath = '/'+config.get_misc('webdav','vdir','webdav')
self.baseuri = "http://%s:%d/"% (self.server.server_name, self.server.server_port) self.baseuri = "http://%s:%d/"% (self.server.server_name, self.server.server_port)
self.IFACE_CLASS = openerp_dav_handler(self, self.verbose) self.IFACE_CLASS = openerp_dav_handler(self, self.verbose)
def get_davpath(self):
return self.davpath
def log_message(self, format, *args): def log_message(self, format, *args):
netsvc.Logger().notifyChannel('webdav', netsvc.LOG_DEBUG_RPC, format % args) netsvc.Logger().notifyChannel('webdav', netsvc.LOG_DEBUG_RPC, format % args)
@ -83,6 +87,17 @@ class DAVHandler(FixSendError,DAVRequestHandler):
def log_error(self, format, *args): def log_error(self, format, *args):
netsvc.Logger().notifyChannel('xmlrpc', netsvc.LOG_WARNING, format % args) netsvc.Logger().notifyChannel('xmlrpc', netsvc.LOG_WARNING, format % args)
def send_response(self, code, message=None):
# the BufferingHttpServer will send Connection: close , while
# the BaseHTTPRequestHandler will only accept int code.
# workaround both of them.
BaseHTTPRequestHandler.send_response(self, int(code), message)
def send_header(self, key, value):
if key == 'Connection' and value == 'close':
self.close_connection = 1
DAVRequestHandler.send_header(self, key, value)
def do_PUT(self): def do_PUT(self):
dc=self.IFACE_CLASS dc=self.IFACE_CLASS
uri=urlparse.urljoin(self.get_baseuri(dc), self.path) uri=urlparse.urljoin(self.get_baseuri(dc), self.path)
@ -161,8 +176,18 @@ class DAVHandler(FixSendError,DAVRequestHandler):
self.send_body(None, '201', 'Created', '', headers=headers) self.send_body(None, '201', 'Created', '', headers=headers)
from service.http_server import reg_http_service,OpenERPAuthProvider
class DAVAuthProvider(OpenERPAuthProvider):
def authenticate(self, db, user, passwd, client_address):
""" authenticate, but also allow the False db, meaning to skip
authentication when no db is specified.
"""
if db is False:
return True
return OpenERPAuthProvider.authenticate(self, db, user, passwd, client_address)
try: try:
from service.http_server import reg_http_service,OpenERPAuthProvider
if (config.get_misc('webdav','enable',True)): if (config.get_misc('webdav','enable',True)):
directory = '/'+config.get_misc('webdav','vdir','webdav') directory = '/'+config.get_misc('webdav','vdir','webdav')
@ -177,7 +202,7 @@ try:
conf = OpenDAVConfig(**_dc) conf = OpenDAVConfig(**_dc)
handler._config = conf handler._config = conf
reg_http_service(HTTPDir(directory,DAVHandler,OpenERPAuthProvider())) reg_http_service(HTTPDir(directory,DAVHandler,DAVAuthProvider()))
netsvc.Logger().notifyChannel('webdav', netsvc.LOG_INFO, "WebDAV service registered at path: %s/ "% directory) netsvc.Logger().notifyChannel('webdav', netsvc.LOG_INFO, "WebDAV service registered at path: %s/ "% directory)
except Exception, e: except Exception, e:
logger = netsvc.Logger() logger = netsvc.Logger()

View File

@ -21,5 +21,6 @@
import event import event
import wizard import wizard
import report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -37,7 +37,7 @@
Note that: Note that:
- You can define new types of events in - You can define new types of events in
Events / Configuration / Types of Events Events / Configuration / Types of Events
- You can access predefined reports about number of registration per event or per event category in : - You can access predefined reports about number of registration per event or per event category in:
Events / Reporting Events / Reporting
""", """,
'author': 'Tiny', 'author': 'Tiny',
@ -46,15 +46,15 @@
'update_xml': [ 'update_xml': [
'wizard/event_confirm_registration_view.xml', 'wizard/event_confirm_registration_view.xml',
'event_view.xml', 'event_view.xml',
'report/report_event_registration_view.xml',
'event_sequence.xml', 'event_sequence.xml',
'security/event_security.xml', 'security/event_security.xml',
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'wizard/event_registration_view.xml',
'wizard/event_registrations_partner.xml',
'wizard/event_make_invoice_view.xml', 'wizard/event_make_invoice_view.xml',
'board_association_view.xml', 'board_association_view.xml',
], ],
'demo_xml': ['event_demo.xml','board_association_demo.xml'], 'demo_xml': ['event_demo.xml', 'board_association_demo.xml'],
'test': ['test/test_event.yml'],
'installable': True, 'installable': True,
'active': False, 'active': False,
'certificate': '0083059161581', 'certificate': '0083059161581',

View File

@ -12,8 +12,38 @@
<action <action
string="New members" string="New members"
name="%(membership.action_report_partner_member_year_tree)d" name="%(membership.action_report_partner_member_year_tree)d"
view_mode="graph,tree" colspan="4"/>--> view_mode="graph,tree" colspan="4"/>-->
<record model ="ir.ui.view" id="view_report_event_reg_graph">
<field name="name">Registration Event report</field>
<field name="model">report.event.registration</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Event on Registration" type="bar" >
<field name="event_id"/>
<field name="draft_state" operator="+"/>
<field name="confirm_state" operator="+"/>
<field name="register_max" operator="+"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="act_event_reg">
<field name="name">Events On Registrations</field>
<field name="res_model">report.event.registration</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="view_id" ref="view_report_event_reg_graph"/>
</record>
<record model="ir.actions.act_window" id="act_event_view">
<field name="name">Next Events</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">event.event</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<record model="board.note.type" id="note_association_type"> <record model="board.note.type" id="note_association_type">
<field name="name">associations</field> <field name="name">associations</field>
</record> </record>
@ -27,7 +57,7 @@
<hpaned position="100"> <hpaned position="100">
<child1> <child1>
<action string="Next Events" <action string="Next Events"
name="%(event.action_event_registration_report)d" name="%(act_event_view)d"
colspan="4"/> colspan="4"/>
<action <action
string="Unpaid Invoices" string="Unpaid Invoices"
@ -35,14 +65,13 @@
colspan="4" colspan="4"
domain="[('state','not in',['draft','cancel']),('reconciled','=',False),('type','=','out_invoice')]"/> domain="[('state','not in',['draft','cancel']),('reconciled','=',False),('type','=','out_invoice')]"/>
</child1> </child1>
<child2> <child2>
<action <action string="Register Events"
string="Registrations by Events" name="%(act_event_reg)d"
name="%(event.action_event_type_registration)d" colspan="4"/>
view_mode="graph,tree"
colspan="4"/>
</child2> </child2>
</hpaned> </hpaned>
</form> </form>
</field> </field>

View File

@ -19,231 +19,166 @@
# #
############################################################################## ##############################################################################
from crm import crm
from osv import fields, osv from osv import fields, osv
import time from tools.translate import _
import netsvc import netsvc
import pooler import pooler
import time
import tools import tools
from tools.translate import _
from crm import crm
class event_type(osv.osv): class event_type(osv.osv):
""" Event Type """
_name = 'event.type' _name = 'event.type'
_description= 'Event type' _description = __doc__
_columns = { _columns = {
'name': fields.char('Event type', size=64, required=True), 'name': fields.char('Event type', size=64, required=True),
} }
event_type() event_type()
class event(osv.osv): class event_event(osv.osv):
"""Event"""
_name = 'event.event' _name = 'event.event'
_description = 'Event' _description = __doc__
_inherits = {'crm.case.section': 'section_id'} _inherit = 'crm.case.section'
_order = 'date_begin' _order = 'date_begin'
def copy(self, cr, uid, id, default=None, context=None): def copy(self, cr, uid, id, default=None, context=None):
return super(event, self).copy(cr, uid, id, default={'code': self.pool.get('ir.sequence').get(cr, uid, 'event.event'), 'state': 'draft'}) """ Copy record of Given id
@param id: Id of Event Registration type record.
@param context: A standard dictionary for contextual values
"""
if not default:
default = {}
default.update({
'code': self.pool.get('ir.sequence').get(cr, uid, 'event.event'),
'state': 'draft'
})
return super(event_event, self).copy(cr, uid, id, default=default, context=context)
def button_draft(self, cr, uid, ids, context={}): def button_draft(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state': 'draft'}) return self.write(cr, uid, ids, {'state': 'draft'}, context=context)
def button_cancel(self, cr, uid, ids, context={}): def button_cancel(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state': 'cancel'}) return self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
def button_done(self, cr, uid, ids, context={}): def button_done(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state': 'done'}) return self.write(cr, uid, ids, {'state': 'done'}, context=context)
def button_confirm(self, cr, uid, ids, context={}): def button_confirm(self, cr, uid, ids, context=None):
for eve in self.browse(cr, uid, ids): register_pool = self.pool.get('event.registration')
if eve.mail_auto_confirm: for event in self.browse(cr, uid, ids, context=context):
if event.mail_auto_confirm:
#send reminder that will confirm the event for all the people that were already confirmed #send reminder that will confirm the event for all the people that were already confirmed
reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id', '=', eve.id), ('state', 'not in', ['draft', 'cancel'])]) reg_ids = register_pool.search(cr, uid, [
if reg_ids: ('event_id', '=', event.id),
self.pool.get('event.registration').mail_user_confirm(cr, uid, reg_ids) ('state', 'not in', ['draft', 'cancel'])])
register_pool.mail_user_confirm(cr, uid, reg_ids)
return self.write(cr, uid, ids, {'state': 'confirm'}) return self.write(cr, uid, ids, {'state': 'confirm'})
def _get_register(self, cr, uid, ids, name, args, context=None):
res={} def _get_register(self, cr, uid, ids, fields, args, context=None):
"""
Get Confirm or uncofirm register value.
@param ids: List of Event registration type's id
@param fields: List of function fields(register_current and register_prospect).
@param context: A standard dictionary for contextual values
@return: Dictionary of function fields value.
"""
register_pool = self.pool.get('event.registration')
res = {}
for event in self.browse(cr, uid, ids, context): for event in self.browse(cr, uid, ids, context):
res[event.id] = {} res[event.id] = {}
state = 'draft' for field in fields:
if name[0] == 'register_current': res[event.id][field] = False
state = 'open' state = []
query = """SELECT sum(r.nb_register) if 'register_current' in fields:
from event_registration r state.append('open')
where state=%s and event_id=%s""" if 'register_prospect' in fields:
state.append('draft')
cr.execute(query, (state, event.id, ))
res2 = cr.fetchone() reg_ids = register_pool.search(cr, uid, [
if res2 and res2[0]: ('event_id', '=', event.id),
res[event.id][name[0]] = res2[0] ('state', 'in', state)])
else: if 'register_current' in fields:
res[event.id][name[0]] = 0 res[event.id]['register_current'] = len(reg_ids)
if 'register_prospect' in fields:
res[event.id]['register_prospect'] = len(reg_ids)
return res return res
def write(self, cr, uid, ids, vals, *args, **kwargs): def write(self, cr, uid, ids, vals, context=None):
res = super(event, self).write(cr, uid, ids, vals, *args, **kwargs) """
if 'date_begin' in vals and vals['date_begin']: Writes values in one or several fields.
for eve in self.browse(cr, uid, ids): @param ids: List of Event registration type's IDs
@param vals: dictionary with values to update.
@return: True
"""
register_pool = self.pool.get('event.registration')
res = super(event_event, self).write(cr, uid, ids, vals, context=context)
if vals.get('date_begin', False) or vals.get('mail_auto_confirm', False) or vals.get('mail_confirm', False):
for event in self.browse(cr, uid, ids, context=context):
#change the deadlines of the registration linked to this event #change the deadlines of the registration linked to this event
reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id', '=', eve.id)]) register_values = {}
if reg_ids: if vals.get('date_begin', False):
self.pool.get('event.registration').write(cr, uid, reg_ids, {'date_deadline': vals['date_begin']}) register_values['date_deadline'] = vals['date_begin']
#change the description of the registration linked to this event #change the description of the registration linked to this event
if 'mail_auto_confirm' in vals: if vals.get('mail_auto_confirm', False):
if vals['mail_auto_confirm']: if vals['mail_auto_confirm']:
if 'mail_confirm' not in vals: if 'mail_confirm' not in vals:
for eve in self.browse(cr, uid, ids): vals['mail_confirm'] = event.mail_confirm
vals['mail_confirm'] = eve.mail_confirm else:
else: vals['mail_confirm'] = False
vals['mail_confirm']=False if 'mail_confirm' in vals:
if 'mail_confirm' in vals: register_values['description'] = vals['mail_confirm']
for eve in self.browse(cr, uid, ids):
reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id', '=', eve.id)]) if register_values:
if reg_ids: reg_ids = register_pool.search(cr, uid, [('event_id', '=', event.id)])
self.pool.get('event.registration').write(cr, uid, reg_ids, {'description': vals['mail_confirm']}) register_pool.write(cr, uid, reg_ids, register_values)
return res return res
_columns = { _columns = {
'type': fields.many2one('event.type', 'Type'), 'type': fields.many2one('event.type', 'Type', help="Type of Event like Seminar, Exhibition, Conference, Training."),
'section_id': fields.many2one('crm.case.section', 'Case section', required=True), 'register_max': fields.integer('Maximum Registrations', help="Provide Maximun Number of Registrations"),
'register_max': fields.integer('Maximum Registrations'), 'register_min': fields.integer('Minimum Registrations', help="Providee Minimum Number of Registrations"),
'register_min': fields.integer('Minimum Registrations'), 'register_current': fields.function(_get_register, method=True, string='Confirmed Registrations', multi='register_current', help="Total of Open Registrations"),
'register_current': fields.function(_get_register, method=True, string='Confirmed Registrations', multi='register_current'), 'register_prospect': fields.function(_get_register, method=True, string='Unconfirmed Registrations', multi='register_prospect', help="Total of Prospect Registrations"),
'register_prospect': fields.function(_get_register, method=True, string='Unconfirmed Registrations', multi='register_prospect'), 'date_begin': fields.datetime('Beginning date', required=True, help="Beginning Date of Event"),
'date_begin': fields.datetime('Beginning date', required=True), 'date_end': fields.datetime('Closing date', required=True, help="Closing Date of Event"),
'date_end': fields.datetime('Ending date', required=True), 'state': fields.selection([('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, required=True, help='If event is created, the state is \'Draft\'.\n If event is confirmed for the particular dates the state is set to \'Confirmed\'.\
'state': fields.selection([('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, required=True,
help='If event is created, the state is \'Draft\'.\n If event is confirmed for the particular dates the state is set to \'Confirmed\'.\
\nIf the event is over, the state is set to \'Done\'.\n If event is cancelled the state is set to \'Cancelled\'.'), \nIf the event is over, the state is set to \'Done\'.\n If event is cancelled the state is set to \'Cancelled\'.'),
'mail_auto_registr': fields.boolean('Mail Auto Register', help='Check this box if you want to use the automatic mailing for new registration'), 'mail_auto_registr': fields.boolean('Mail Auto Register', help='Check this box if you want to use the automatic mailing for new registration'),
'mail_auto_confirm': fields.boolean('Mail Auto Confirm', help='Check this box if you want ot use the automatic confirmation emailing or the reminder'), 'mail_auto_confirm': fields.boolean('Mail Auto Confirm', help='Check this box if you want ot use the automatic confirmation emailing or the reminder'),
'mail_registr': fields.text('Registration Email', help='This email will be sent when someone subscribes to the event.'), 'mail_registr': fields.text('Registration Email', help='This email will be sent when someone subscribes to the event.'),
'mail_confirm': fields.text('Confirmation Email', help="This email will be sent when the event gets confimed or when someone subscribes to a confirmed event. This is also the email sent to remind someone about the event."), 'mail_confirm': fields.text('Confirmation Email', help="This email will be sent when the event gets confimed or when someone subscribes to a confirmed event. This is also the email sent to remind someone about the event."),
'product_id': fields.many2one('product.product', 'Product', required=True), 'product_id': fields.many2one('product.product', 'Product', required=True, help="Product which is provided cost of event. Invoice of event will be created with this Product."),
'note': fields.text('Notes', help="Description or Summary of Event")
} }
_defaults = { _defaults = {
'state': lambda *args: 'draft', 'state': 'draft',
'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'event.event'), 'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'event.event'),
'user_id': lambda self, cr, uid, ctx: uid, 'user_id': lambda obj, cr, uid, context: uid,
} }
event() event_event()
class event_registration(osv.osv): class event_registration(osv.osv):
"""Event Registration"""
def check_confirm(self, cr, uid, ids, context):
mod_obj = self.pool.get('ir.model.data')
current_registration = self.browse(cr, uid, [ids[0]])[0]
total_confirmed = current_registration.event_id.register_current + current_registration.nb_register
if total_confirmed <= current_registration.event_id.register_max or current_registration.event_id.register_max == 0:
self.write(cr, uid, [ids[0]], {'state': 'open'}, context=context)
self._history(cr, uid, [ids[0]], 'Open', history=True)
self.mail_user(cr, uid, [ids[0]])
return True
else:
model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'view_event_confirm_registration')], context=context)
resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
context.update({'reg_id': ids[0]})
return {
'name': _('Confirm Registration'),
'context': context,
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'event.confirm.registration',
'views': [(resource_id, 'form')],
'type': 'ir.actions.act_window',
'target': 'new',
'nodestroy': True
}
def _history(self, cr, uid, ids, keyword, history=False, email=False, context={}):
for case in self.browse(cr, uid, ids):
data = {
'name': keyword,
'som': case.som.id,
'canal_id': case.canal_id.id,
'user_id': uid,
}
obj = self.pool.get('mailgate.message')
obj.create(cr, uid, data, context=context)
return True
def button_reg_close(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state': 'done', })
self._history(cr, uid, ids, 'Done', history=True)
return True
def button_reg_cancel(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state': 'cancel', })
self._history(cr, uid, ids, 'Cancel', history=True)
return True
def create(self, cr, uid, *args, **argv):
event = self.pool.get('event.event').browse(cr, uid, args[0]['event_id'], None)
args[0]['section_id']= event.section_id.id
args[0]['date_deadline']= event.date_begin
args[0]['description']= event.mail_confirm
res = super(event_registration, self).create(cr, uid, *args, **argv)
self._history(cr, uid, [res], 'Created', history=True)
return res
def write(self, cr, uid, *args, **argv):
if 'event_id' in args[1]:
event = self.pool.get('event.event').browse(cr, uid, args[1]['event_id'], None)
args[1]['section_id']= event.section_id.id
args[1]['date_deadline']= event.date_begin
args[1]['description']= event.mail_confirm
return super(event_registration, self).write(cr, uid, *args, **argv)
def mail_user_confirm(self, cr, uid, ids):
reg_ids = self.browse(cr, uid, ids)
for reg_id in reg_ids:
src = reg_id.event_id.reply_to or False
dest = []
if reg_id.email_from:
dest += [reg_id.email_from]
if reg_id.email_cc:
dest += [reg_id.email_cc]
if dest and src:
tools.email_send(src, dest, 'Auto Confirmation: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_confirm, openobject_id = str(reg_id.id))
if not src:
raise osv.except_osv(_('Error!'), _('You must define a reply-to address in order to mail the participant. You can do this in the Mailing tab of your event. Note that this is also the place where you can configure your event to not send emails automaticly while registering'))
return False
def mail_user(self, cr, uid, ids):
reg_ids = self.browse(cr, uid, ids)
for reg_id in reg_ids:
src = reg_id.event_id.reply_to or False
dest = []
if reg_id.email_from:
dest += [reg_id.email_from]
if reg_id.email_cc:
dest += [reg_id.email_cc]
if reg_id.event_id.mail_auto_confirm or reg_id.event_id.mail_auto_registr:
if dest and src:
if reg_id.event_id.state in ['draft', 'fixed', 'open', 'confirm', 'running'] and reg_id.event_id.mail_auto_registr:
tools.email_send(src, dest, 'Auto Registration: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_registr, openobject_id = str(reg_id.id))
if (reg_id.event_id.state in ['confirm', 'running']) and reg_id.event_id.mail_auto_confirm:
tools.email_send(src, dest, 'Auto Confirmation: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_confirm, openobject_id = str(reg_id.id))
if not src:
raise osv.except_osv(_('Error!'), _('You must define a reply-to address in order to mail the participant. You can do this in the Mailing tab of your event. Note that this is also the place where you can configure your event to not send emails automaticly while registering'))
return False
def _create_invoice_lines(self, cr, uid, ids, vals):
return self.pool.get('account.invoice.line').create(cr, uid, vals)
_name= 'event.registration' _name= 'event.registration'
_description = 'Event Registration' _description = __doc__
_inherit = 'crm.meeting' _inherit = 'crm.meeting'
_columns = { _columns = {
'email_cc': fields.text('Watchers Emails', size=252 , help="These \ 'email_cc': fields.text('CC', size=252 , help="These \
people will receive a copy of the future communication between partner \ people will receive a copy of the future communication between partner \
and users by email"), and users by email"),
'nb_register': fields.integer('Number of Registration', readonly=True, states={'draft': [('readonly', False)]}), 'nb_register': fields.integer('Number of Registration', readonly=True, states={'draft': [('readonly', False)]}),
'event_id': fields.many2one('event.event', 'Event Related', required=True), 'event_id': fields.many2one('event.event', 'Event Related', required=True),
"partner_invoice_id": fields.many2one('res.partner', 'Partner Invoiced'), "partner_invoice_id": fields.many2one('res.partner', 'Partner Invoiced'),
@ -252,26 +187,223 @@ and users by email"),
"badge_title": fields.char('Badge Title', size=128), "badge_title": fields.char('Badge Title', size=128),
"badge_name": fields.char('Badge Name', size=128), "badge_name": fields.char('Badge Name', size=128),
"badge_partner": fields.char('Badge Partner', size=128), "badge_partner": fields.char('Badge Partner', size=128),
"invoice_label": fields.char("Label Invoice", size=128, required=True), "event_product": fields.char("Product Name", size=128, required=True),
"tobe_invoiced": fields.boolean("To be Invoiced"), "tobe_invoiced": fields.boolean("To be Invoiced"),
"invoice_id": fields.many2one("account.invoice", "Invoice"), "invoice_id": fields.many2one("account.invoice", "Invoice"),
'date_closed': fields.datetime('Closed', readonly=True), 'date_closed': fields.datetime('Closed', readonly=True),
'ref': fields.reference('Reference', selection=crm._links_get, size=128), 'ref': fields.reference('Reference', selection=crm._links_get, size=128),
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128), 'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
'canal_id': fields.many2one('res.partner.canal', 'Channel', help="The channels represent the different communication modes available with the customer." \
" With each commercial opportunity, you can indicate the canall which is this opportunity source."),
'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
"the partner mentality in relation to our services.The scale has" \
"to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
} }
_defaults = { _defaults = {
'nb_register': lambda *a: 1, 'nb_register': 1,
'tobe_invoiced': lambda *a: True, 'tobe_invoiced': True,
'name': lambda *a: 'Registration', 'name': 'Registration',
} }
def _make_invoice(self, cr, uid, reg, lines, context=None):
""" Create Invoice from Invoice lines
@param reg : Object of event.registration
@param lines: ids of Invoice lines
"""
if context is None:
context = {}
inv_pool = self.pool.get('account.invoice')
inv_lines_pool = self.pool.get('account.invoice.line')
val_invoice = inv_pool.onchange_partner_id(cr, uid, [], 'out_invoice', reg.partner_invoice_id.id, False, False)
val_invoice['value'].update({'partner_id': reg.partner_invoice_id.id})
partner_address_id = val_invoice['value']['address_invoice_id']
value = inv_lines_pool.product_id_change(cr, uid, [], reg.event_id.product_id.id, uom =False, partner_id=reg.partner_invoice_id.id, fposition_id=reg.partner_invoice_id.property_account_position.id)
l = inv_lines_pool.read(cr, uid, lines)
val_invoice['value'].update({
'origin': reg.event_product,
'reference': False,
'invoice_line': [(6, 0, lines)],
'comment': "",
})
inv_id = inv_pool.create(cr, uid, val_invoice['value'])
inv_pool.button_compute(cr, uid, [inv_id])
self._history(cr, uid, [reg], _('Invoiced'))
return inv_id
def action_invoice_create(self, cr, uid, ids, grouped=False, date_inv = False, context=None):
""" Action of Create Invoice """
res = False
invoices = {}
tax_ids=[]
inv_lines_pool = self.pool.get('account.invoice.line')
inv_pool = self.pool.get('account.invoice')
product_pool = self.pool.get('product.product')
contact_pool = self.pool.get('res.partner.contact')
if not context:
context = {}
# If date was specified, use it as date invoiced, usefull when invoices are generated this month and put the
# last day of the last month as invoice date
if date_inv:
context['date_inv'] = date_inv
for reg in self.browse(cr, uid, ids, context=context):
val_invoice = inv_pool.onchange_partner_id(cr, uid, [], 'out_invoice', reg.partner_invoice_id.id, False, False)
val_invoice['value'].update({'partner_id': reg.partner_invoice_id.id})
partner_address_id = val_invoice['value']['address_invoice_id']
if not partner_address_id:
raise osv.except_osv(_('Error !'),
_("Registered partner doesn't have an address to make the invoice."))
value = inv_lines_pool.product_id_change(cr, uid, [], reg.event_id.product_id.id, uom =False, partner_id=reg.partner_invoice_id.id, fposition_id=reg.partner_invoice_id.property_account_position.id)
product = product_pool.browse(cr, uid, reg.event_id.product_id.id, context=context)
for tax in product.taxes_id:
tax_ids.append(tax.id)
vals = value['value']
c_name = reg.contact_id and ('-' + contact_pool.name_get(cr, uid, [reg.contact_id.id])[0][1]) or ''
vals.update({
'name': reg.event_product + '-' + c_name,
'price_unit': reg.unit_price,
'quantity': reg.nb_register,
'product_id':reg.event_id.product_id.id,
'invoice_line_tax_id': [(6, 0, tax_ids)],
})
inv_line_ids = self._create_invoice_lines(cr, uid, [reg.id], vals)
invoices.setdefault(reg.partner_id.id, []).append((reg, inv_line_ids))
for val in invoices.values():
if grouped:
res = self._make_invoice(cr, uid, val[0][0], [v for k , v in val], context=context)
for k , v in val:
self.write(cr, uid, [k.id], {'state': 'done', 'invoice_id': res}, context=context)
else:
for k , v in val:
res = self._make_invoice(cr, uid, k, [v], context=context)
self.write(cr, uid, [k.id], {'state': 'done', 'invoice_id': res}, context=context)
return res
def check_confirm(self, cr, uid, ids, context=None):
"""
Check confirm event register on given id.
@param ids: List of Event registration's IDs
@param context: A standard dictionary for contextual values
@return: Dictionary value which open Confirm registration form.
"""
data_pool = self.pool.get('ir.model.data')
unconfirmed_ids = []
for registration in self.browse(cr, uid, ids, context=context):
total_confirmed = registration.event_id.register_current + registration.nb_register
if total_confirmed <= registration.event_id.register_max or registration.event_id.register_max == 0:
self.write(cr, uid, [registration.id], {'state': 'open'}, context=context)
self.mail_user(cr, uid, [registration.id])
self._history(cr, uid, [registration.id], _('Open'))
else:
unconfirmed_ids.append(registration.id)
if unconfirmed_ids:
view_id = data_pool._get_id(cr, uid, 'event', 'view_event_confirm_registration')
view_data = data_pool.browse(cr, uid, view_id)
view_id = view_data.res_id
context['registration_ids'] = unconfirmed_ids
return {
'name': _('Confirm Registration'),
'context': context,
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'event.confirm.registration',
'views': [(view_id, 'form')],
'type': 'ir.actions.act_window',
'target': 'new',
'context': context,
'nodestroy': True
}
return True
def button_reg_close(self, cr, uid, ids, *args):
registrations = self.browse(cr, uid, ids)
self._history(cr, uid, registrations, _('Done'))
self.write(cr, uid, ids, {'state': 'done', 'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')})
return True
def button_reg_cancel(self, cr, uid, ids, *args):
registrations = self.browse(cr, uid, ids)
self._history(cr, uid, registrations, _('Cancel'))
self.write(cr, uid, ids, {'state': 'cancel'})
return True
def create(self, cr, uid, values, context=None):
""" Overrides orm create method.
"""
event = self.pool.get('event.event').browse(cr, uid, values['event_id'], context=context)
values['date_deadline']= event.date_begin
values['description']= event.mail_confirm
res = super(event_registration, self).create(cr, uid, values, context=context)
registrations = self.browse(cr, uid, [res], context=context)
self._history(cr, uid, registrations, _('Created'))
return res
def write(self, cr, uid, ids, values, context=None):
if 'event_id' in values:
event = self.pool.get('event.event').browse(cr, uid, values['event_id'], context=context)
values['date_deadline']= event.date_begin
values['description']= event.mail_confirm
return super(event_registration, self).write(cr, uid, ids, values, context=context)
def mail_user(self, cr, uid, ids, confirm=False, context=None):
"""
Send email to user
"""
if not context:
context = {}
for reg_id in self.browse(cr, uid, ids):
src = reg_id.event_id.reply_to or False
dest = []
if reg_id.email_from:
dest += [reg_id.email_from]
if reg_id.email_cc:
dest += [reg_id.email_cc]
if dest and src:
if confirm:
tools.email_send(src, dest,
_('Auto Confirmation: [%s] %s') %(reg_id.id, reg_id.name),
reg_id.event_id.mail_confirm,
openobject_id = reg_id.id)
elif reg_id.event_id.mail_auto_confirm or reg_id.event_id.mail_auto_registr:
if reg_id.event_id.state in ['draft', 'fixed', 'open', 'confirm', 'running'] and reg_id.event_id.mail_auto_registr:
tools.email_send(src, dest,
_('Auto Registration: [%s] %s') %(reg_id.id, reg_id.name),
reg_id.event_id.mail_registr, openobject_id = reg_id.id)
if (reg_id.event_id.state in ['confirm', 'running']) and reg_id.event_id.mail_auto_confirm:
tools.email_send(src, dest,
_('Auto Confirmation: [%s] %s') %(reg_id.id, reg_id.name),
reg_id.event_id.mail_confirm, openobject_id = reg_id.id)
if not src:
raise osv.except_osv(_('Error!'), _('You must define a reply-to address in order to mail the participant. You can do this in the Mailing tab of your event. Note that this is also the place where you can configure your event to not send emails automaticly while registering'))
return True
def mail_user_confirm(self, cr, uid, ids, context=None):
"""
Send email to user
"""
return self.mail_user(cr, uid, ids, confirm=True, context=context)
def _create_invoice_lines(self, cr, uid, ids, vals):
""" Create account Invoice line for Registration Id.
"""
return self.pool.get('account.invoice.line').create(cr, uid, vals)
def onchange_badge_name(self, cr, uid, ids, badge_name): def onchange_badge_name(self, cr, uid, ids, badge_name):
data ={} data ={}
if not badge_name: if not badge_name:
return data return data
@ -279,9 +411,11 @@ and users by email"),
return {'value': data} return {'value': data}
def onchange_contact_id(self, cr, uid, ids, contact, partner): def onchange_contact_id(self, cr, uid, ids, contact, partner):
data ={} data ={}
if not contact: if not contact:
return data return data
contact_id = self.pool.get('res.partner.contact').browse(cr, uid, contact) contact_id = self.pool.get('res.partner.contact').browse(cr, uid, contact)
data['badge_name'] = contact_id.name data['badge_name'] = contact_id.name
data['badge_title'] = contact_id.title data['badge_title'] = contact_id.title
@ -292,26 +426,27 @@ and users by email"),
data['email_from'] = self.pool.get('res.partner.job').browse(cr, uid, job_ids[0]).email data['email_from'] = self.pool.get('res.partner.job').browse(cr, uid, job_ids[0]).email
d = self.onchange_badge_name(cr, uid, ids, data['badge_name']) d = self.onchange_badge_name(cr, uid, ids, data['badge_name'])
data.update(d['value']) data.update(d['value'])
return {'value': data} return {'value': data}
def onchange_event(self, cr, uid, ids, event_id, partner_invoice_id): def onchange_event(self, cr, uid, ids, event_id, partner_invoice_id):
context={} context={}
if not event_id: if not event_id:
return {'value': {'unit_price': False , 'invoice_label': False }} return {'value': {'unit_price': False, 'event_product': False}}
data_event = self.pool.get('event.event').browse(cr, uid, event_id) data_event = self.pool.get('event.event').browse(cr, uid, event_id)
if data_event.product_id: if data_event.product_id:
if not partner_invoice_id: if not partner_invoice_id:
unit_price=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id] unit_price=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id]
return {'value': {'unit_price': unit_price , 'invoice_label': data_event.product_id.name}} return {'value': {'unit_price': unit_price, 'event_product': data_event.product_id.name}}
data_partner = self.pool.get('res.partner').browse(cr, uid, partner_invoice_id) data_partner = self.pool.get('res.partner').browse(cr, uid, partner_invoice_id)
context.update({'partner_id': data_partner}) context.update({'partner_id': data_partner})
unit_price = self.pool.get('product.product')._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist': data_partner.property_product_pricelist.id})[data_event.product_id.id] unit_price = self.pool.get('product.product')._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist': data_partner.property_product_pricelist.id})[data_event.product_id.id]
return {'value': {'unit_price': unit_price , 'invoice_label': data_event.product_id.name}} return {'value': {'unit_price': unit_price, 'event_product': data_event.product_id.name}}
return {'value': {'unit_price': False, 'invoice_label': False}}
return {'value': {'unit_price': False, 'event_product': False}}
def onchange_partner_id(self, cr, uid, ids, part, event_id, email=False): def onchange_partner_id(self, cr, uid, ids, part, event_id, email=False):
data={} data={}
data['badge_partner'] = data['contact_id'] = data['partner_invoice_id'] = data['email_from'] = data['badge_title'] = data['badge_name'] = False data['badge_partner'] = data['contact_id'] = data['partner_invoice_id'] = data['email_from'] = data['badge_title'] = data['badge_name'] = False
if not part: if not part:
@ -334,6 +469,7 @@ and users by email"),
return {'value': data} return {'value': data}
def onchange_partner_invoice_id(self, cr, uid, ids, event_id, partner_invoice_id): def onchange_partner_invoice_id(self, cr, uid, ids, event_id, partner_invoice_id):
data={} data={}
context={} context={}
data['unit_price']=False data['unit_price']=False
@ -351,80 +487,8 @@ and users by email"),
return {'value': data} return {'value': data}
return {'value': data} return {'value': data}
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
if not categ:
return {'value': {}}
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
return {'value': {'probability': cat}}
event_registration() event_registration()
class report_event_registration(osv.osv):
_name = "report.event.registration"
_description = "Events on registrations"
_auto = False
_columns = {
'name': fields.char('Event', size=20),
'date_begin': fields.datetime('Beginning date', required=True),
'date_end': fields.datetime('Ending date', required=True),
'draft_state': fields.integer('Draft Registration', size=20),
'confirm_state': fields.integer('Confirm Registration', size=20),
'register_max': fields.integer('Maximum Registrations'),
}
def init(self, cr):
cr.execute("""
create or replace view report_event_registration as (
select
e.id as id,
c.name as name,
e.date_begin as date_begin,
e.date_end as date_end,
(SELECT sum(c.nb_register) FROM event_registration c WHERE c.section_id=e.section_id and state in ('draft')) as draft_state,
(SELECT sum(c.nb_register) FROM event_registration c WHERE c.section_id=e.section_id and state in ('open')) as confirm_state,
e.register_max as register_max
from
event_event e,crm_case_section c
where
e.section_id=c.id
)""")
report_event_registration()
class report_event_type_registration(osv.osv):
_name = "report.event.type.registration"
_description = "Event type on registration"
_auto = False
_columns = {
'name': fields.char('Event Type', size=20),
'nbevent': fields.integer('Number Of Events'),
'draft_state': fields.integer('Draft Registrations', size=20),
'confirm_state': fields.integer('Confirm Registrations', size=20),
}
def init(self, cr):
cr.execute("""
create or replace view report_event_type_registration as (
select
count(t.id) as id,
t.name as name,
(select sum(c.nb_register) from event_registration c, event_event e where c.section_id=e.section_id and c.state='draft' and e.type=t.id ) as draft_state ,
(select sum(c.nb_register) from event_registration c, event_event e where c.section_id=e.section_id and c.state='open' and e.type=t.id ) as confirm_state,
count(t.id) as nbevent
from
event_event e
inner join
crm_case_section c1 on (e.section_id=c1.id)
inner join
event_type t on (e.type=t.id)
group by
t.name,t.id
)""")
report_event_type_registration()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -2,12 +2,5 @@
<openerp> <openerp>
<data> <data>
<!-- The base section for all events -->
<record model="crm.case.section" id="case_section_event">
<field name="name">Events</field>
</record>
</data> </data>
</openerp> </openerp>

View File

@ -58,7 +58,6 @@
<field name="date_begin">2008-01-01 19:00:00</field> <field name="date_begin">2008-01-01 19:00:00</field>
<field name="date_end">2008-01-01 23:00:00</field> <field name="date_end">2008-01-01 23:00:00</field>
<field name="product_id" ref="event_product_0"/> <field name="product_id" ref="event_product_0"/>
<field name="parent_id" ref="case_section_event"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="register_max">500</field> <field name="register_max">500</field>
<field name="type" ref="event_type_1"/> <field name="type" ref="event_type_1"/>
@ -94,7 +93,6 @@
<field name="product_id" ref="event_product_1"/> <field name="product_id" ref="event_product_1"/>
<field name="type" ref="event_type_1"/> <field name="type" ref="event_type_1"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="parent_id" ref="case_section_event"/>
<field name="register_max">350</field> <field name="register_max">350</field>
<field name="state">confirm</field> <field name="state">confirm</field>
</record> </record>
@ -107,7 +105,6 @@
<field name="type" ref="event_type_2"/> <field name="type" ref="event_type_2"/>
<field name="register_max">200</field> <field name="register_max">200</field>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="parent_id" ref="case_section_event"/>
<field name="mail_auto_registr">True</field> <field name="mail_auto_registr">True</field>
<field name="mail_auto_confirm">True</field> <field name="mail_auto_confirm">True</field>
<field name="state">done</field> <field name="state">done</field>

View File

@ -36,19 +36,8 @@
<menuitem name="Configuration" id="menu_event_config" parent="menu_marketing_event_main" sequence="30" groups="base.group_extended"/> <menuitem name="Configuration" id="menu_event_config" parent="menu_marketing_event_main" sequence="30" groups="base.group_extended"/>
<menuitem name="Types of Events" id="menu_event_type" action="action_event_type" parent="menu_event_config" groups="base.group_extended,crm.group_crm_manager"/> <menuitem name="Types of Events" id="menu_event_type" action="action_event_type" parent="menu_event_config" groups="base.group_extended,crm.group_crm_manager"/>
<!-- The base section for all events -->
<record model="ir.actions.act_window" id="action_event_categories"> <!-- Events Organisation/CONFIGURATION/EVENTS -->
<field name="name">Events by section</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">crm.case.section</field>
<field name="domain" eval="[('parent_id','=',False)]" />
<field name="view_type">tree</field>
</record>
<menuitem name="Events by Categories" id="menu_action_event_categories" action="action_event_categories" parent="menu_event_main"/>
<!-- Events Organisation/CONFIGURATION/EVENTS -->
<record model="ir.ui.view" id="view_event_form"> <record model="ir.ui.view" id="view_event_form">
<field name="name">Events</field> <field name="name">Events</field>
@ -58,7 +47,7 @@
<form string="Events"> <form string="Events">
<group col="6" colspan="4"> <group col="6" colspan="4">
<field name="name" string="Event" select="1"/> <field name="name" string="Event" select="1"/>
<field name="type"/> <field name="type" widget="selection"/>
<field name="user_id" select="1"/> <field name="user_id" select="1"/>
<field name="date_begin" select="1"/> <field name="date_begin" select="1"/>
<field name="date_end"/> <field name="date_end"/>
@ -67,11 +56,12 @@
<notebook colspan="4"> <notebook colspan="4">
<page string="General"> <page string="General">
<separator string="Event description" colspan="4"/> <separator string="Event description" colspan="4"/>
<field name="parent_id" domain="[('parent_id','child_of','Event')]" string="Parent Category"/> <field name="parent_id" domain="[('parent_id','child_of','Event')]"/>
<field name="active"/> <field name="active"/>
<field name="register_min"/> <field name="register_min"/>
<field name="register_max"/> <field name="register_max"/>
<separator string="Status" colspan="4"/> <separator string="Notes" colspan="4"/>
<field name="note" colspan="4" nolabel="1"/>
<field name="state" select="1"/> <field name="state" select="1"/>
<group col="4" colspan="2"> <group col="4" colspan="2">
<button string="Confirm Event" name="button_confirm" states="draft" type="object" icon="gtk-apply"/> <button string="Confirm Event" name="button_confirm" states="draft" type="object" icon="gtk-apply"/>
@ -80,17 +70,25 @@
<button string="Set To Draft" name="button_draft" states="confirm,cancel,done" type="object" icon="gtk-convert"/> <button string="Set To Draft" name="button_draft" states="confirm,cancel,done" type="object" icon="gtk-convert"/>
</group> </group>
</page> </page>
<page string="Mailing"> <page string="Mailing">
<field name="reply_to"/> <field name="reply_to" />
<separator string="Auto Registration Email" colspan="4"/>
<field name="mail_auto_registr"/>
<newline/>
<field name="mail_registr" colspan="4"/>
<separator string="Auto Confirmation Email" colspan="4"/>
<field name="mail_auto_confirm"/>
<newline/>
<field name="mail_confirm" colspan="4"/>
<newline/> <newline/>
<group col="3" colspan="2" expand="1">
<separator string="Auto Registration Email" colspan="2"/>
<newline/>
<field name="mail_auto_registr"/>
<separator string="Registration Email" colspan="2"/>
<newline/>
<field name="mail_registr" colspan="2" nolabel="1"/>
</group>
<group col="2" colspan="2" >
<separator string="Auto Confirmation Email" colspan="2"/>
<field name="mail_auto_confirm"/>
<newline/>
<separator string="Confirmation Email" colspan="2"/>
<field name="mail_confirm" colspan="2" nolabel="1"/>
</group>
</page> </page>
<page string="Statistics"> <page string="Statistics">
<separator string="Registrations" colspan="4"/> <separator string="Registrations" colspan="4"/>
@ -103,6 +101,7 @@
</record> </record>
<!-- event.event tree view --> <!-- event.event tree view -->
<record model="ir.ui.view" id="view_event_tree"> <record model="ir.ui.view" id="view_event_tree">
<field name="name">event.event.tree</field> <field name="name">event.event.tree</field>
<field name="model">event.event</field> <field name="model">event.event</field>
@ -111,6 +110,7 @@
<tree string="Events" colors="red:register_min>register_current;black:register_min&lt;=register_current"> <tree string="Events" colors="red:register_min>register_current;black:register_min&lt;=register_current">
<field name="name" string="Name"/> <field name="name" string="Name"/>
<field name="user_id"/> <field name="user_id"/>
<field name="type"/>
<field name="date_begin"/> <field name="date_begin"/>
<field name="register_min"/> <field name="register_min"/>
<field name="register_current"/> <field name="register_current"/>
@ -126,36 +126,61 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Events"> <search string="Events">
<group col="10" colspan="4"> <group col="10" colspan="4">
<separator orientation="vertical"/> <filter icon="terp-document-new" string="Draft" name="draft" domain="[('state','=','draft')]" help="Draft Events"/>
<filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Events"/>
<filter icon="terp-camera_test" string="Confirmed" domain="[('state','=','confirm')]" help="Confirmed Events"/> <filter icon="terp-camera_test" string="Confirmed" domain="[('state','=','confirm')]" help="Confirmed Events"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>
<field name="name" string="Event" select="1"/> <field name="name" string="Event" select="1"/>
<field name="user_id" select="1"/>
<field name="date_begin" select="1"/>
<field name="state" select="1"/> <field name="state" select="1"/>
<field name="user_id" widget="selection">
<filter icon="terp-personal"
string="My Events"
help="My Events"
domain="[('user_id','=',uid)]"/>
</field>
<field name="date_begin" select="1"/>
</group>
<newline/>
<group expand="0" string="Group By..." colspan="4" col="12">
<filter string="Event Type" icon="terp-crm" context="{'group_by':'type'}"/>
<filter string="state" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Responsible" icon="terp-personal" context="{'group_by': 'user_id'}"/>
<separator orientation="vertical"/>
<filter string="Creation" icon="terp-go-month"
domain="[]" context="{'group_by':'date_begin'}"/>
</group> </group>
</search> </search>
</field> </field>
</record> </record>
<!-- Events Organisation/CONFIGURATION/EVENTS --> <!-- Events Organisation/CONFIGURATION/EVENTS -->
<record model="ir.actions.act_window" id="action_event_view"> <record model="ir.actions.act_window" id="action_event_view">
<field name="name">Events</field> <field name="name">Events</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">event.event</field> <field name="res_model">event.event</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="context">{"search_default_user_id":uid}</field> <field name="context">{"search_default_draft": "1"}</field>
<field name="search_view_id" ref="view_event_search"/> <field name="search_view_id" ref="view_event_search"/>
</record> </record>
<act_window
id="act_event_list_register_event"
name="Registration"
res_model="event.registration"
src_model="event.event"
view_mode="tree,form"
domain="[('event_id', '=', active_id)]"
view_type="form"/>
<menuitem name="Events" id="menu_event_event" action="action_event_view" parent="menu_event_main" /> <menuitem name="Events" id="menu_event_event" action="action_event_view" parent="menu_event_main" />
<!-- EVENTS/REGISTRATIONS/EVENTS --> <!-- EVENTS/REGISTRATIONS/EVENTS -->
<!-- Registration view (form) by _inherits .................. --> <!-- Registration view (form) by _inherits .................. -->
<record model="ir.ui.view" id="event_registration_tree">
<record model="ir.ui.view" id="view_event_registration_tree">
<field name="name">event.registration.tree</field> <field name="name">event.registration.tree</field>
<field name="model">event.registration</field> <field name="model">event.registration</field>
<field name="type">tree</field> <field name="type">tree</field>
@ -171,7 +196,7 @@
</field> </field>
</record> </record>
<record model="ir.ui.view" id="event_registration_form"> <record model="ir.ui.view" id="view_event_registration_form">
<field name="name">event.registration.form</field> <field name="name">event.registration.form</field>
<field name="model">event.registration</field> <field name="model">event.registration</field>
<field name="type">form</field> <field name="type">form</field>
@ -189,91 +214,107 @@
<field name="unit_price"/> <field name="unit_price"/>
</group> </group>
<notebook colspan="4"> <notebook colspan="4">
<page string="General"> <page string="General">
<field name="contact_id" on_change="onchange_contact_id(contact_id, partner_id)" /><newline/> <field name="contact_id" on_change="onchange_contact_id(contact_id, partner_id)" /><newline/>
<field name="email_from"/> <field name="email_from"/>
<button name="remind_partner" string="Send Reminder" states="open,pending" type="object" colspan="2" icon="gtk-go-forward"/> <button name="remind_partner" string="Send Reminder" states="open,pending" type="object" colspan="2" icon="gtk-go-forward"/>
<newline/> <newline/>
<separator string="Badge" colspan="4"/> <separator string="Badge" colspan="4"/>
<field name="badge_title"/> <field name="badge_title"/>
<field name="badge_name" on_change="onchange_badge_name(badge_name)"/> <field name="badge_name" on_change="onchange_badge_name(badge_name)"/>
<field name="badge_partner"/> <field name="badge_partner"/>
<newline/> <newline/>
<separator string="Status" colspan="4"/> <separator string="Status" colspan="4"/>
<group col="8" colspan="4"> <group col="8" colspan="4">
<field name="state" select="1" colspan="2"/> <field name="state" select="1" colspan="2"/>
<button name="button_reg_close" string="Registration Invoiced" states="open" type="object" icon="gtk-print"/> <button name="button_reg_close" string="Close Registration" states="open" type="object" icon="gtk-close"/>
<button name="check_confirm" string="Confirm Registration" states="draft" type="object" icon="gtk-apply"/> <button name="check_confirm" string="Confirm Registration" states="draft" type="object" icon="gtk-apply"/>
<button name="button_reg_cancel" string="Cancel Registration" states="draft,open" type="object" icon="gtk-cancel"/> <button name="button_reg_cancel" string="Cancel Registration" states="draft,open" type="object" icon="gtk-cancel"/>
</group> </group>
</page> </page>
<page string="Extra Info"> <page string="Payments">
<field name="name" select="1" colspan="4"/> <field name="event_product" select="1"/>
<field name="id" select="1"/> <field name="tobe_invoiced" select="1"/>
<field name="active"/> <field name="invoice_id"/>
<field name="email_cc" colspan="4"/> </page>
<field name="categ_id" on_change="onchange_categ_id(categ_id)"/> <page string="Emails" groups="base.group_extended">
<separator colspan="4" string="Dates"/> <group colspan="4">
<field name="create_date"/> <field colspan="4" name="email_cc" string="CC"/>
<field name="date_closed"/> </group>
<separator colspan="4" string="References"/> <field name="message_ids" colspan="4" nolabel="1" mode="form,tree">
<field name="ref" colspan="4"/> <form string="Communication history">
<field name="ref2" colspan="4"/> <group col="6" colspan="4">
</page> <field name="date"/>
<page string="History"> <field name="email_to"/>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form"> <field name="email_from"/>
<form string="Communication history"> </group>
<group col="6" colspan="4"> <notebook colspan="4">
<field name="date"/> <page string="Details">
<field name="email_to"/> <field name="description" colspan="4" nolabel="1"/>
<field name="email_from"/> </page>
</group> <page string="Attachments">
<notebook colspan="4"> <field name="attachment_ids" colspan="4" readonly="1" nolabel="1"/>
<page string="Details"> </page>
<field name="description" colspan="4" nolabel="1"/> </notebook>
</page> <button colspan="4"
<page string="Attachments"> string="Reply to Last Email"
<field name="attachment_ids" colspan="4" readonly="1" nolabel="1"/> name="%(crm.action_crm_send_mail)d"
</page> context="{'mail':'reply', 'model': 'crm.lead', 'include_original' : True}"
</notebook> icon="gtk-undo" type="action" />
<button colspan="4" </form>
string="Reply to Last Email" <tree string="Communication history">
name="%(crm.action_crm_send_mail)d" <field name="date"/>
context="{'mail':'reply', 'model': 'event.registration'}" <field name="email_from" />
icon="gtk-undo" type="action" /> <field name="email_to"/>
</form> <field name="description"/>
<tree string="Communication history"> </tree>
<field name="date"/> </field>
<field name="email_from" /> <button colspan="4" string="Send New Email"
<field name="email_to"/> name="%(crm.action_crm_send_mail)d"
<field name="description"/> context="{'mail':'new', 'model': 'event.registration'}"
</tree> icon="gtk-go-forward" type="action" />
</field> </page>
<field name="log_ids" nolabel="1" colspan="4" mode="tree,form" readonly="1"> <page string="History">
<tree string="Actions"> <group colspan="4">
<separator string="Action Information" colspan="4"/> <field name="name" select="1" colspan="4"/>
<field name="name"/> </group>
<field name="date"/> <group col="2" colspan="2">
<field name="user_id"/> <separator string="Dates" colspan="2"/>
</tree> <field name="create_date"/>
<form string="Actions"> <field name="date_closed"/>
<separator string="Action Information" colspan="4"/> </group>
<field name="name" colspan="4"/> <group col="2" colspan="2">
<field name="date"/> <separator string="Misc" colspan="2"/>
<field name="user_id"/> <field name="id"/>
</form> <field name="active"/>
</field> </group>
</page> <group col="3" colspan="4">
<page string="Payments"> <separator colspan="4" string="References"/>
<field name="invoice_label" select="1"/> <field name="ref" />
<field name="tobe_invoiced" select="1"/> <field name="ref2" />
<field name="invoice_id"/> </group>
</page> <!-- TODO-->
<field name="log_ids" nolabel="1" colspan="4">
<tree string="Logs">
<field name="name" colspan="4"/>
<field name="date"/>
<field name="user_id"/>
</tree>
<form string="Logs">
<separator string="Action Information" colspan="4"/>
<field name="name" colspan="4"/>
<field name="date"/>
<field name="user_id"/>
</form>
</field>
</page>
</notebook> </notebook>
</form> </form>
</field> </field>
</record> </record>
<!-- Search view of event registration form-->
<record model="ir.ui.view" id="view_registration_search"> <record model="ir.ui.view" id="view_registration_search">
<field name="name">Registrations</field> <field name="name">Registrations</field>
<field name="model">event.registration</field> <field name="model">event.registration</field>
@ -281,16 +322,28 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Event Registration"> <search string="Event Registration">
<group col="12" colspan="4"> <group col="12" colspan="4">
<separator orientation="vertical"/> <filter icon="terp-document-new" string="Draft" name="draft" domain="[('state','=','draft')]" help="Draft Registrations"/>
<filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Registrations"/>
<filter icon="terp-camera_test" string="Confirmed" domain="[('state','in',('open','done'))]" help="Confirmed Registrations"/> <filter icon="terp-camera_test" string="Confirmed" domain="[('state','in',('open','done'))]" help="Confirmed Registrations"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>
<field name="event_id" select="1"/> <field name="partner_id" />
<field name="user_id" select="1"/> <field name="event_id" widget="selection"/>
<field name="partner_id" select="1"/>
<field name="state" select="1"/> <field name="state" select="1"/>
<field name="invoice_label" select="1"/>
<field name="user_id" widget="selection">
<filter icon="terp-personal"
string="My Registration"
help="My Registration"
domain="[('user_id','=',uid)]"/>
</field>
</group> </group>
<newline/>
<group expand="0" string="Group By...">
<filter string="Event" icon="terp-crm" domain="[]" context="{'group_by':'event_id'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
</group>
</search> </search>
</field> </field>
</record> </record>
@ -301,93 +354,14 @@
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="domain"></field> <field name="domain"></field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="context">{"search_default_user_id":uid}</field> <field name="context">{"search_default_draft": "1"}</field>
<field name="search_view_id" ref="view_registration_search"/> <field name="search_view_id" ref="view_registration_search"/>
</record> </record>
<menuitem <menuitem
name="Registrations" name="Registrations"
id="menu_action_registration" parent="menu_event_main" id="menu_action_registration" parent="menu_event_main"
action="action_registration"/> action="action_registration"/>
<!-- report , event on registration... start -->
<record model="ir.ui.view" id="report_event_registration_tree">
<field name="name">report.event.registration.tree</field>
<field name="model">report.event.registration</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Event on Registration">
<field name="name" select="1"/>
<field name="date_begin" select="1"/>
<field name="date_end"/>
<field name="draft_state"/>
<field name="confirm_state"/>
<field name="register_max"/>
</tree>
</field>
</record>
<record model ="ir.ui.view" id="report_event_registration_graph">
<field name="name">report.event.registration.graph</field>
<field name="model">report.event.registration</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Event on Registration" type="bar">
<field name="name"/>
<field name="draft_state" operator="+"/>
<field name="confirm_state" operator="+"/>
<field name="register_max" operator="+"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="action_event_registration_report">
<field name="name">Events On Registrations</field>
<field name="res_model">report.event.registration</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
</record>
<menuitem name="Reporting" id="menu_report_event" parent="menu_marketing_event_main" sequence="20"/> <menuitem name="Reporting" id="menu_report_event" parent="menu_marketing_event_main" sequence="20"/>
<!--<menuitem parent="menu_report_event" action="action_event_registration" id="menu_report_event_registration"/>-->
<menuitem parent="menu_report_event" action="action_event_registration_report" id="menu_report_event_registration" />
<!-- end... -->
<!-- report , event type on registration... start -->
<record model="ir.ui.view" id="report_event_type_registration_tree">
<field name="name">report.event.type.registration.tree</field>
<field name="model">report.event.type.registration</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Registration By Event Types">
<field name="name" select="1"/>
<field name="nbevent"/>
<field name="draft_state"/>
<field name="confirm_state"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="report_event_type_registration_graph">
<field name="name">report.event.type.registration.graph</field>
<field name="model">report.event.type.registration</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Registration By Event Types" type="bar">
<field name="name"/>
<field name="draft_state" operator="+"/>
<field name="confirm_state" operator="+"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="action_event_type_registration">
<field name="name">Registration By Event Types</field>
<field name="res_model">report.event.type.registration</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
</record>
<menuitem parent="menu_report_event" action="action_event_type_registration" id="menu_report_event_type_registration"/>
<!-- end... -->
</data> </data>
</openerp> </openerp>

View File

@ -7,111 +7,110 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n" "Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2009-01-26 17:13+0000\n" "PO-Revision-Date: 2010-06-27 22:00+0000\n"
"Last-Translator: Jordi Esteve (www.zikzakmedia.com) " "Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\n"
"<jesteve@zikzakmedia.com>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-22 03:58+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: event #. module: event
#: field:event.event,date_end:0 #: field:event.event,date_end:0
#: field:report.event.registration,date_end:0 #: field:report.event.registration,date_end:0
msgid "Ending date" msgid "Ending date"
msgstr "" msgstr "Fecha de finalización"
#. module: event #. module: event
#: field:event.event,register_min:0 #: field:event.event,register_min:0
msgid "Minimum Registrations" msgid "Minimum Registrations"
msgstr "" msgstr "Registros mínimos"
#. module: event #. module: event
#: constraint:ir.actions.act_window:0 #: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition." msgid "Invalid model name in the action definition."
msgstr "" msgstr "Nombre de modelo inválido en la definición de acción."
#. module: event #. module: event
#: field:event.event,mail_registr:0 #: field:event.event,mail_registr:0
msgid "Registration Email" msgid "Registration Email"
msgstr "" msgstr "Email de registro"
#. module: event #. module: event
#: model:crm.case.section,name:event.event_0_crm_case_section #: model:crm.case.section,name:event.event_0_crm_case_section
msgid "Concert of Bon Jovi" msgid "Concert of Bon Jovi"
msgstr "" msgstr "Concierto de Bon Jovi"
#. module: event #. module: event
#: field:event.event,mail_confirm:0 #: field:event.event,mail_confirm:0
msgid "Confirmation Email" msgid "Confirmation Email"
msgstr "" msgstr "Email de confirmación"
#. module: event #. module: event
#: constraint:crm.case.section:0 #: constraint:crm.case.section:0
msgid "Error ! You cannot create recursive sections." msgid "Error ! You cannot create recursive sections."
msgstr "" msgstr "¡Error! No puede crear secciones recursivas."
#. module: event #. module: event
#: model:ir.model,name:event.model_event_registration #: model:ir.model,name:event.model_event_registration
msgid "Event Registration" msgid "Event Registration"
msgstr "" msgstr "Registro evento"
#. module: event #. module: event
#: model:ir.actions.wizard,name:event.event_reg_invoice #: model:ir.actions.wizard,name:event.event_reg_invoice
msgid "Make Invoice" msgid "Make Invoice"
msgstr "" msgstr "Crear factura"
#. module: event #. module: event
#: field:report.event.type.registration,draft_state:0 #: field:report.event.type.registration,draft_state:0
msgid "Draft Registrations" msgid "Draft Registrations"
msgstr "" msgstr "Registros borrador"
#. module: event #. module: event
#: view:report.event.registration:0 #: view:report.event.registration:0
msgid "Event on Registration" msgid "Event on Registration"
msgstr "" msgstr "Evento en el registro"
#. module: event #. module: event
#: wizard_button:event.reg_make_invoice,init,end:0 #: wizard_button:event.reg_make_invoice,init,end:0
msgid "Ok" msgid "Ok"
msgstr "" msgstr "Aceptar"
#. module: event #. module: event
#: field:event.event,mail_auto_confirm:0 #: field:event.event,mail_auto_confirm:0
msgid "Mail Auto Confirm" msgid "Mail Auto Confirm"
msgstr "" msgstr "Enviar correo auto confirmación"
#. module: event #. module: event
#: model:product.template,name:event.event_product_1_product_template #: model:product.template,name:event.event_product_1_product_template
msgid "Ticket for Opera" msgid "Ticket for Opera"
msgstr "" msgstr "Entrada para la ópera"
#. module: event #. module: event
#: wizard_field:event.reg_make_invoice,init,inv_rejected:0 #: wizard_field:event.reg_make_invoice,init,inv_rejected:0
msgid "Invoice Rejected" msgid "Invoice Rejected"
msgstr "" msgstr "Factura rechazada"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Confirm Event" msgid "Confirm Event"
msgstr "" msgstr "Confirmar evento"
#. module: event #. module: event
#: model:crm.case.section,name:event.event_1_crm_case_section #: model:crm.case.section,name:event.event_1_crm_case_section
msgid "Opera of Verdi" msgid "Opera of Verdi"
msgstr "" msgstr "Ópera de Verdi"
#. module: event #. module: event
#: field:report.event.registration,draft_state:0 #: field:report.event.registration,draft_state:0
msgid "Draft Registration" msgid "Draft Registration"
msgstr "" msgstr "Registro borrador"
#. module: event #. module: event
#: wizard_view:event.reg_make_invoice,init:0 #: wizard_view:event.reg_make_invoice,init:0
msgid "Create Invoices" msgid "Create Invoices"
msgstr "" msgstr "Crear facturas"
#. module: event #. module: event
#: model:ir.module.module,description:event.module_meta_information #: model:ir.module.module,description:event.module_meta_information
@ -131,22 +130,36 @@ msgid ""
"event or per event category in :\n" "event or per event category in :\n"
" Events / Reporting\n" " Events / Reporting\n"
msgstr "" msgstr ""
"Organización y planificación de eventos.\n"
"\n"
" Este módulo le permite\n"
" * gestionar sus eventos y sus registros\n"
" * usar emails para confirmar automáticamente y enviar confirmaciones "
"para cualquier registro a un evento\n"
" * ...\n"
"\n"
" Note that:\n"
" - You can define new types of events in\n"
" Events / Configuration / Types of Events\n"
" - You can access predefined reports about number of registration per "
"event or per event category in :\n"
" Events / Reporting\n"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "Extra Info" msgid "Extra Info"
msgstr "" msgstr "Información extra"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "Registration" msgid "Registration"
msgstr "" msgstr "Registro"
#. module: event #. module: event
#: field:event.type,name:0 #: field:event.type,name:0
#: model:ir.model,name:event.model_event_type #: model:ir.model,name:event.model_event_type
msgid "Event type" msgid "Event type"
msgstr "" msgstr "Tipo de evento"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
@ -154,54 +167,54 @@ msgstr ""
#: model:ir.module.module,shortdesc:event.module_meta_information #: model:ir.module.module,shortdesc:event.module_meta_information
#: field:report.event.registration,name:0 #: field:report.event.registration,name:0
msgid "Event" msgid "Event"
msgstr "" msgstr "Evento"
#. module: event #. module: event
#: selection:event.event,state:0 #: selection:event.event,state:0
msgid "Confirmed" msgid "Confirmed"
msgstr "" msgstr "Confirmado"
#. module: event #. module: event
#: wizard_view:event.confirm_registration,split:0 #: wizard_view:event.confirm_registration,split:0
msgid "Registration Confirmation" msgid "Registration Confirmation"
msgstr "" msgstr "Confirmación del registro"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "Dates" msgid "Dates"
msgstr "" msgstr "Fechas"
#. module: event #. module: event
#: field:event.event,register_current:0 #: field:event.event,register_current:0
#: model:ir.actions.act_window,name:event.action_registration_confirm #: model:ir.actions.act_window,name:event.action_registration_confirm
#: model:ir.ui.menu,name:event.menu_action_registration_confirm #: model:ir.ui.menu,name:event.menu_action_registration_confirm
msgid "Confirmed Registrations" msgid "Confirmed Registrations"
msgstr "" msgstr "Registros confirmados"
#. module: event #. module: event
#: field:event.event,mail_auto_registr:0 #: field:event.event,mail_auto_registr:0
msgid "Mail Auto Register" msgid "Mail Auto Register"
msgstr "" msgstr "Enviar correo auto registro"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "Badge" msgid "Badge"
msgstr "" msgstr "Distintivo"
#. module: event #. module: event
#: field:event.event,section_id:0 #: field:event.event,section_id:0
msgid "Case section" msgid "Case section"
msgstr "" msgstr "Sección del caso"
#. module: event #. module: event
#: field:event.registration,tobe_invoiced:0 #: field:event.registration,tobe_invoiced:0
msgid "To be Invoiced" msgid "To be Invoiced"
msgstr "" msgstr "Para ser facturado"
#. module: event #. module: event
#: model:ir.ui.menu,name:event.menu_event_event #: model:ir.ui.menu,name:event.menu_event_event
msgid "All Events" msgid "All Events"
msgstr "" msgstr "Todos los eventos"
#. module: event #. module: event
#: model:ir.ui.menu,name:event.menu_report_event #: model:ir.ui.menu,name:event.menu_report_event
@ -211,34 +224,34 @@ msgstr "Informe"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "Cancel Registration" msgid "Cancel Registration"
msgstr "" msgstr "Cancelar registro"
#. module: event #. module: event
#: model:ir.ui.menu,name:event.menu_action_event_categories #: model:ir.ui.menu,name:event.menu_action_event_categories
msgid "Events by Categories" msgid "Events by Categories"
msgstr "" msgstr "Eventos por categorías"
#. module: event #. module: event
#: wizard_view:event.confirm_registration,split:0 #: wizard_view:event.confirm_registration,split:0
msgid "The event limit is reached. What do you want to do?" msgid "The event limit is reached. What do you want to do?"
msgstr "" msgstr "Se ha alcanzado el límite del evento. ¿Qué desea hacer?"
#. module: event #. module: event
#: field:report.event.type.registration,confirm_state:0 #: field:report.event.type.registration,confirm_state:0
msgid "Confirm Registrations" msgid "Confirm Registrations"
msgstr "" msgstr "Confirmar registros"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "References" msgid "References"
msgstr "" msgstr "Referencias"
#. module: event #. module: event
#: model:ir.actions.act_window,name:event.action_event_type_registration #: model:ir.actions.act_window,name:event.action_event_type_registration
#: model:ir.ui.menu,name:event.menu_report_event_type_registration #: model:ir.ui.menu,name:event.menu_report_event_type_registration
#: view:report.event.type.registration:0 #: view:report.event.type.registration:0
msgid "Registration By Event Types" msgid "Registration By Event Types"
msgstr "" msgstr "Registro por tipos de evento"
#. module: event #. module: event
#: model:ir.ui.menu,name:event.menu_event_config #: model:ir.ui.menu,name:event.menu_event_config
@ -253,7 +266,7 @@ msgstr "¡XML inválido para la definición de la vista!"
#. module: event #. module: event
#: wizard_button:event.confirm_registration,split,confirm:0 #: wizard_button:event.confirm_registration,split,confirm:0
msgid "Confirm Anyway" msgid "Confirm Anyway"
msgstr "" msgstr "Confirmar de todos modos"
#. module: event #. module: event
#: constraint:product.template:0 #: constraint:product.template:0
@ -263,75 +276,75 @@ msgstr "Error: La UdV debe estar en una categoría diferente que la UdM"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Parent Category" msgid "Parent Category"
msgstr "" msgstr "Categoría padre"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "Registration Invoiced" msgid "Registration Invoiced"
msgstr "" msgstr "Registro facturado"
#. module: event #. module: event
#: field:report.event.type.registration,nbevent:0 #: field:report.event.type.registration,nbevent:0
msgid "Number Of Events" msgid "Number Of Events"
msgstr "" msgstr "Número de eventos"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Cancel Event" msgid "Cancel Event"
msgstr "" msgstr "Cancelar evento"
#. module: event #. module: event
#: wizard_field:event.reg_make_invoice,init,inv_rej_reason:0 #: wizard_field:event.reg_make_invoice,init,inv_rej_reason:0
msgid "Error Messages" msgid "Error Messages"
msgstr "" msgstr "Mensajes de error"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Mailing" msgid "Mailing"
msgstr "" msgstr "Envío correo"
#. module: event #. module: event
#: model:product.template,name:event.event_product_0_product_template #: model:product.template,name:event.event_product_0_product_template
msgid "Ticket for Concert" msgid "Ticket for Concert"
msgstr "" msgstr "Entrada para concierto"
#. module: event #. module: event
#: field:event.event,register_prospect:0 #: field:event.event,register_prospect:0
#: model:ir.actions.act_window,name:event.action_registration_draft #: model:ir.actions.act_window,name:event.action_registration_draft
#: model:ir.ui.menu,name:event.menu_action_registration_draft #: model:ir.ui.menu,name:event.menu_action_registration_draft
msgid "Unconfirmed Registrations" msgid "Unconfirmed Registrations"
msgstr "" msgstr "Registros sin confirmar"
#. module: event #. module: event
#: field:event.registration,partner_invoice_id:0 #: field:event.registration,partner_invoice_id:0
msgid "Partner Invoiced" msgid "Partner Invoiced"
msgstr "" msgstr "Empresa facturada"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "Communication history" msgid "Communication history"
msgstr "" msgstr "Histórico comunicación"
#. module: event #. module: event
#: selection:event.event,state:0 #: selection:event.event,state:0
msgid "Canceled" msgid "Canceled"
msgstr "" msgstr "Cancelado"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Event Done" msgid "Event Done"
msgstr "" msgstr "Evento realizado"
#. module: event #. module: event
#: field:event.registration,badge_name:0 #: field:event.registration,badge_name:0
msgid "Badge Name" msgid "Badge Name"
msgstr "" msgstr "Nombre de distintivo"
#. module: event #. module: event
#: model:ir.actions.act_window,name:event.action_event_registration #: model:ir.actions.act_window,name:event.action_event_registration
#: model:ir.ui.menu,name:event.menu_report_event_registration #: model:ir.ui.menu,name:event.menu_report_event_registration
msgid "Events On Registrations" msgid "Events On Registrations"
msgstr "" msgstr "Eventos en los registros"
#. module: event #. module: event
#: constraint:product.template:0 #: constraint:product.template:0
@ -344,27 +357,27 @@ msgstr ""
#. module: event #. module: event
#: wizard_field:event.reg_make_invoice,init,inv_created:0 #: wizard_field:event.reg_make_invoice,init,inv_created:0
msgid "Invoice Created" msgid "Invoice Created"
msgstr "" msgstr "Factura creada"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Statistics" msgid "Statistics"
msgstr "" msgstr "Estadísticas"
#. module: event #. module: event
#: selection:event.event,state:0 #: selection:event.event,state:0
msgid "Draft" msgid "Draft"
msgstr "" msgstr "Borrador"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Event description" msgid "Event description"
msgstr "" msgstr "Descripción del evento"
#. module: event #. module: event
#: model:ir.model,name:event.model_report_event_type_registration #: model:ir.model,name:event.model_report_event_type_registration
msgid "Event type on registration" msgid "Event type on registration"
msgstr "" msgstr "Tipo de evento en el registro"
#. module: event #. module: event
#: constraint:ir.model:0 #: constraint:ir.model:0
@ -377,7 +390,7 @@ msgstr ""
#. module: event #. module: event
#: field:event.registration,event_id:0 #: field:event.registration,event_id:0
msgid "Event Related" msgid "Event Related"
msgstr "" msgstr "Evento relacionado"
#. module: event #. module: event
#: model:crm.case.section,name:event.case_section_event #: model:crm.case.section,name:event.case_section_event
@ -389,167 +402,170 @@ msgstr "Eventos"
#. module: event #. module: event
#: field:event.registration,nb_register:0 #: field:event.registration,nb_register:0
msgid "Number of Registration" msgid "Number of Registration"
msgstr "" msgstr "Número de registro"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
#: field:event.event,state:0 #: field:event.event,state:0
#: view:event.registration:0 #: view:event.registration:0
msgid "Status" msgid "Status"
msgstr "" msgstr "Estado"
#. module: event #. module: event
#: model:ir.actions.act_window,name:event.action_event_categories #: model:ir.actions.act_window,name:event.action_event_categories
msgid "Events by section" msgid "Events by section"
msgstr "" msgstr "Eventos por sección"
#. module: event #. module: event
#: model:ir.ui.menu,name:event.menu_action_registration #: model:ir.ui.menu,name:event.menu_action_registration
msgid "All Registrations" msgid "All Registrations"
msgstr "" msgstr "Todos los registros"
#. module: event #. module: event
#: help:event.event,mail_auto_registr:0 #: help:event.event,mail_auto_registr:0
msgid "" msgid ""
"Check this box if you want to use the automatic mailing for new registration" "Check this box if you want to use the automatic mailing for new registration"
msgstr "" msgstr ""
"Marque esta opción si desea utilizar el correo automático para nuevos "
"registros"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Set To Draft" msgid "Set To Draft"
msgstr "" msgstr "Establecer en borrador"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
#: model:ir.actions.wizard,name:event.event_confirm_registration #: model:ir.actions.wizard,name:event.event_confirm_registration
#: field:report.event.registration,confirm_state:0 #: field:report.event.registration,confirm_state:0
msgid "Confirm Registration" msgid "Confirm Registration"
msgstr "" msgstr "Confirmación registro"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "History" msgid "History"
msgstr "" msgstr "Histórico"
#. module: event #. module: event
#: model:ir.ui.menu,name:event.menu_event_type #: model:ir.ui.menu,name:event.menu_event_type
msgid "Types of Events" msgid "Types of Events"
msgstr "" msgstr "Tipos de eventos"
#. module: event #. module: event
#: field:event.registration,contact_id:0 #: field:event.registration,contact_id:0
msgid "Partner Contact" msgid "Partner Contact"
msgstr "" msgstr "Contacto empresa"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Auto Confirmation Email" msgid "Auto Confirmation Email"
msgstr "" msgstr "Correo de confirmación automático"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
#: view:event.registration:0 #: view:event.registration:0
msgid "General" msgid "General"
msgstr "" msgstr "General"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "Send Reminder" msgid "Send Reminder"
msgstr "" msgstr "Enviar recordatorio"
#. module: event #. module: event
#: selection:event.event,state:0 #: selection:event.event,state:0
msgid "Done" msgid "Done"
msgstr "" msgstr "Realizado"
#. module: event #. module: event
#: field:event.event,date_begin:0 #: field:event.event,date_begin:0
#: field:report.event.registration,date_begin:0 #: field:report.event.registration,date_begin:0
msgid "Beginning date" msgid "Beginning date"
msgstr "" msgstr "Fecha inicio"
#. module: event #. module: event
#: field:event.registration,invoice_id:0 #: field:event.registration,invoice_id:0
msgid "Invoice" msgid "Invoice"
msgstr "" msgstr "Factura"
#. module: event #. module: event
#: model:ir.model,name:event.model_report_event_registration #: model:ir.model,name:event.model_report_event_registration
msgid "Events on registrations" msgid "Events on registrations"
msgstr "" msgstr "Eventos en los registros"
#. module: event #. module: event
#: wizard_button:event.confirm_registration,split,end:0 #: wizard_button:event.confirm_registration,split,end:0
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr "Cancelar"
#. module: event #. module: event
#: wizard_button:event.reg_make_invoice,init,open:0 #: wizard_button:event.reg_make_invoice,init,open:0
msgid "Open" msgid "Open"
msgstr "" msgstr "Abierto"
#. module: event #. module: event
#: field:event.registration,badge_title:0 #: field:event.registration,badge_title:0
msgid "Badge Title" msgid "Badge Title"
msgstr "" msgstr "Título del distintivo"
#. module: event #. module: event
#: model:ir.actions.act_window,name:event.action_new_event_form #: model:ir.actions.act_window,name:event.action_new_event_form
#: model:ir.ui.menu,name:event.menu_event_new_event #: model:ir.ui.menu,name:event.menu_event_new_event
msgid "New event" msgid "New event"
msgstr "" msgstr "Nuevo evento"
#. module: event #. module: event
#: field:event.registration,unit_price:0 #: field:event.registration,unit_price:0
msgid "Unit Price" msgid "Unit Price"
msgstr "" msgstr "Precio unitario"
#. module: event #. module: event
#: model:crm.case.section,name:event.event_2_crm_case_section #: model:crm.case.section,name:event.event_2_crm_case_section
msgid "Conference on ERP Buisness" msgid "Conference on ERP Buisness"
msgstr "" msgstr "Conferencia en negocios ERP"
#. module: event #. module: event
#: field:event.registration,badge_partner:0 #: field:event.registration,badge_partner:0
msgid "Badge Partner" msgid "Badge Partner"
msgstr "" msgstr "Empresa distinguida"
#. module: event #. module: event
#: model:ir.actions.act_window,name:event.action_event_view_confirm #: model:ir.actions.act_window,name:event.action_event_view_confirm
#: model:ir.ui.menu,name:event.menu_event_event_confirm #: model:ir.ui.menu,name:event.menu_event_event_confirm
msgid "Confirmed Events" msgid "Confirmed Events"
msgstr "" msgstr "Eventos confirmados"
#. module: event #. module: event
#: field:event.event,register_max:0 #: field:event.event,register_max:0
#: field:report.event.registration,register_max:0 #: field:report.event.registration,register_max:0
msgid "Maximum Registrations" msgid "Maximum Registrations"
msgstr "" msgstr "Registros máximos"
#. module: event #. module: event
#: field:event.event,type:0 #: field:event.event,type:0
msgid "Type" msgid "Type"
msgstr "" msgstr "Tipo"
#. module: event #. module: event
#: help:event.event,mail_registr:0 #: help:event.event,mail_registr:0
msgid "This email will be sent when someone subscribes to the event." msgid "This email will be sent when someone subscribes to the event."
msgstr "" msgstr ""
"Este correo electrónico será enviado cuando alguien se suscriba al evento."
#. module: event #. module: event
#: model:product.template,name:event.event_product_2_product_template #: model:product.template,name:event.event_product_2_product_template
msgid "Ticket for Conference" msgid "Ticket for Conference"
msgstr "" msgstr "Entrada para conferencia"
#. module: event #. module: event
#: field:event.registration,case_id:0 #: field:event.registration,case_id:0
msgid "Case" msgid "Case"
msgstr "" msgstr "Caso"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Name" msgid "Name"
msgstr "" msgstr "Nombre"
#. module: event #. module: event
#: help:event.event,mail_auto_confirm:0 #: help:event.event,mail_auto_confirm:0
@ -557,6 +573,8 @@ msgid ""
"Check this box if you want ot use the automatic confirmation emailing or the " "Check this box if you want ot use the automatic confirmation emailing or the "
"reminder" "reminder"
msgstr "" msgstr ""
"Marque esta opción si desea utilizar el correo de confirmación automático o "
"el recordatorio"
#. module: event #. module: event
#: help:event.event,mail_confirm:0 #: help:event.event,mail_confirm:0
@ -565,55 +583,58 @@ msgid ""
"subscribes to a confirmed event. This is also the email sent to remind " "subscribes to a confirmed event. This is also the email sent to remind "
"someone about the event." "someone about the event."
msgstr "" msgstr ""
"Este correo electrónico será enviado cuando el evento sea confirmado o "
"cuando alguien se suscriba a un evento confirmado. Éste es también el correo "
"que será enviado para recordar a alguien sobre el evento."
#. module: event #. module: event
#: field:event.event,product_id:0 #: field:event.event,product_id:0
msgid "Product" msgid "Product"
msgstr "" msgstr "Producto"
#. module: event #. module: event
#: field:event.registration,invoice_label:0 #: field:event.registration,invoice_label:0
msgid "Label Invoice" msgid "Label Invoice"
msgstr "" msgstr "Etiquetar factura"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "Payments" msgid "Payments"
msgstr "" msgstr "Pagos"
#. module: event #. module: event
#: view:event.type:0 #: view:event.type:0
#: field:report.event.type.registration,name:0 #: field:report.event.type.registration,name:0
msgid "Event Type" msgid "Event Type"
msgstr "" msgstr "Tipo de evento"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
#: model:ir.actions.act_window,name:event.action_registration #: model:ir.actions.act_window,name:event.action_registration
#: model:ir.actions.wizard,name:event.wizard_event_registration #: model:ir.actions.wizard,name:event.wizard_event_registration
msgid "Registrations" msgid "Registrations"
msgstr "" msgstr "Registros"
#. module: event #. module: event
#: model:ir.actions.act_window,name:event.action_event_view_draft #: model:ir.actions.act_window,name:event.action_event_view_draft
#: model:ir.ui.menu,name:event.menu_event_event_draft #: model:ir.ui.menu,name:event.menu_event_event_draft
msgid "Draft Events" msgid "Draft Events"
msgstr "" msgstr "Eventos en borrador"
#. module: event #. module: event
#: model:ir.ui.menu,name:event.menu_event_main #: model:ir.ui.menu,name:event.menu_event_main
msgid "Events Organisation" msgid "Events Organisation"
msgstr "" msgstr "Organización de eventos"
#. module: event #. module: event
#: view:event.registration:0 #: view:event.registration:0
msgid "Actions" msgid "Actions"
msgstr "" msgstr "Acciones"
#. module: event #. module: event
#: model:ir.actions.wizard,name:event.wizard_event_reg_partners #: model:ir.actions.wizard,name:event.wizard_event_reg_partners
msgid "List Register Partners" msgid "List Register Partners"
msgstr "" msgstr "Listar empresas registradas"
#. module: event #. module: event
#: constraint:product.product:0 #: constraint:product.product:0
@ -623,4 +644,4 @@ msgstr "Error: Código EAN erróneo"
#. module: event #. module: event
#: view:event.event:0 #: view:event.event:0
msgid "Auto Registration Email" msgid "Auto Registration Email"
msgstr "" msgstr "Correo de registro automático"

View File

@ -19,32 +19,6 @@
# #
############################################################################## ##############################################################################
from osv import fields, osv import report_event_registration
class event_registration_list(osv.osv_memory): # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
""" List Event Registration """
_name = "event.registration.list"
_description = "List Event Registrations"
def open_registration(self, cr, uid, ids, context={}):
if not context.get('active_id', None):
return {
'name': 'Event Registrations',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'event.registration',
'type': 'ir.actions.act_window'
}
return {
'domain': [('section_id', '=', context['active_id'])],
'name': 'Event Registrations',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'event.registration',
'type': 'ir.actions.act_window'
}
event_registration_list()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,83 @@
# -*- 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 tools
class report_event_registration(osv.osv):
_name = "report.event.registration"
_description = "Events on registrations and Events on type"
_auto = False
_rec_name = 'date'
_columns = {
'date': fields.date('Date', readonly=True),
'year': fields.char('Year', size=4, readonly=True),
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
'day': fields.char('Day', size=128, readonly=True),
'event_id': fields.many2one('event.event', 'Event Related', required=True),
'draft_state': fields.integer(' # No of draft Registration.', size=20),
'confirm_state': fields.integer(' # No of Confirm Registration', size=20),
'register_max': fields.integer('Maximum Registrations'),
'nbevent': fields.integer('Number Of Events'),
'type': fields.many2one('event.type', 'Event Type'),
'state': fields.selection([('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, required=True),
'user_id':fields.many2one('res.users', 'Responsible', readonly=True),
}
_order = 'date desc'
def init(self, cr):
"""
initialize the sql view for the event registration
cr -- the cursor
"""
cr.execute("""
create or replace view report_event_registration as (
select
e.id as id,
c.event_id as event_id,
e.date_begin as date,
e.user_id as user_id,
to_char(e.date_begin, 'YYYY') as year,
to_char(e.date_begin, 'MM') as month,
to_char(e.date_begin, 'YYYY-MM-DD') as day,
count(t.id) as nbevent,
t.id as type,
(SELECT sum(c.nb_register) FROM event_registration c WHERE c.event_id=e.id and t.id=e.type and state in ('draft')) as draft_state,
(SELECT sum(c.nb_register) FROM event_registration c WHERE c.event_id=e.id and t.id=e.type and state in ('open')) as confirm_state,
e.register_max as register_max,
e.state as state
from
event_event e
inner join
event_registration c on (e.id=c.event_id)
inner join
event_type t on (e.type=t.id)
group by
to_char(e.date_begin, 'YYYY'),
to_char(e.date_begin, 'MM'),
t.id, e.id, e.date_begin,
e.register_max, e.type, e.state, c.event_id, e.user_id,
to_char(e.date_begin, 'YYYY-MM-DD')
)""")
report_event_registration()

View File

@ -0,0 +1,129 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- report , event on registration... start -->
<record model="ir.ui.view" id="report_event_registration_tree">
<field name="name">report.event.registration.tree</field>
<field name="model">report.event.registration</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Event on Registration">
<field name="date" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="year" invisible="1"/>
<field name="day" invisible="1"/>
<field name="month" invisible="1"/>
<field name="event_id" invisible="1"/>
<field name="state" invisible="1"/>
<field name="type" invisible="1"/>
<field name="nbevent"/>
<field name="draft_state"/>
<field name="confirm_state"/>
<field name="register_max"/>
</tree>
</field>
</record>
<record model ="ir.ui.view" id="report_event_registration_graph">
<field name="name">report.event.registration.graph</field>
<field name="model">report.event.registration</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Event on Registration" type="bar" >
<field name="event_id"/>
<field name="draft_state" operator="+"/>
<field name="confirm_state" operator="+"/>
<field name="register_max" operator="+"/>
</graph>
</field>
</record>
<!-- Event on Registration search view -->
<record model="ir.ui.view" id="view_report_event_registration_search">
<field name="name">.search</field>
<field name="model">report.event.registration</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Event on Registration">
<group col="8" colspan="4">
<filter icon="terp-go-year" string="Last 365 Days"
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')),('date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"
help="Tasks performed in last 365 days"/>
<filter icon="terp-go-month" string="Last 30 Days"
name="month"
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
help="Tasks performed in last 30 days"/>
<filter icon="terp-go-week"
string="Last 7 Days"
separator="1"
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
help="Tasks during last 7 days"/>
<separator orientation="vertical"/>
<filter icon="terp-document-new"
string="Draft"
domain="[('state','=','draft')]"/>
<filter icon="terp-camera_test"
string="Confirm"
domain="[('state', '=', 'confirm')]"/>
<separator orientation="vertical"/>
<field name="event_id" widget="selection"/>
<field name="type" widget="selection"/>
<field name="user_id" widget="selection">
<filter icon="terp-personal"
string="My Events"
help="My Events"
domain="[('user_id','=',uid)]"/>
</field>
<field name="date"/>
</group>
<newline/>
<group expand="0" string="Group By..." colspan="4" col="12">
<filter string="Event" name="event" icon="terp-crm" context="{'group_by':'event_id'}"/>
<filter string="Event Type" icon="terp-crm" context="{'group_by':'type'}"/>
<separator orientation="vertical"/>
<filter string="state" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Responsible" name="user" icon="terp-personal" context="{'group_by': 'user_id'}"/>
<separator orientation="vertical" />
<filter string="Day" icon="terp-go-month"
domain="[]" context="{'group_by':'day'}"/>
<filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'month'}"/>
<filter string="Year" icon="terp-go-year"
domain="[]" context="{'group_by':'year'}"/>
</group>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_event_registration">
<field name="name">Events On Registrations</field>
<field name="res_model">report.event.registration</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="search_view_id" ref="view_report_event_registration_search"/>
<field name="context">{"search_default_user":1,"search_default_month":1,'group_by_no_leaf':1,'group_by':[]}</field>
</record>
<record model="ir.actions.act_window.view" id="action_report_event_registration_tree">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="report_event_registration_tree"/>
<field name="act_window_id" ref="action_report_event_registration"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_event_registration_graph">
<field name="sequence" eval="2"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="report_event_registration_graph"/>
<field name="act_window_id" ref="action_report_event_registration"/>
</record>
<!--<menuitem parent="menu_report_event" action="action_event_registration" id="menu_report_event_registration"/>-->
<menuitem parent="menu_report_event" action="action_report_event_registration" id="menu_report_event_registration" />
<!-- end... -->
</data>
</openerp>

View File

@ -1,13 +1,24 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<openerp> <openerp>
<data> <data noupdate="0">
<record id="menu_event_config" model="ir.ui.menu">
<field name="groups_id" eval="[(6,0,[ref('crm.group_crm_manager'), ref('base.group_extended')])]"/>
</record> <record id="group_event_manager" model="res.groups">
<field name="name">EVENT / Manager</field>
</record>
<record id="group_event_subscriber" model="res.groups">
<field name="name">EVENT / Subscriber</field>
</record>
<!-- <record id="menu_event_config" model="ir.ui.menu">-->
<!-- <field name="groups_id" eval="[(6,0,[ref('crm.group_crm_manager'), ref('base.group_extended')])]"/>-->
<!-- </record>-->
<!---->
<!-- <record id="menu_report_event" model="ir.ui.menu">-->
<!-- <field name="groups_id" eval="[(6,0,[ref('crm.group_crm_manager'), ref('base.group_extended')])]"/>-->
<!-- </record>-->
<record id="menu_report_event" model="ir.ui.menu">
<field name="groups_id" eval="[(6,0,[ref('crm.group_crm_manager'), ref('base.group_extended')])]"/>
</record>
</data> </data>
</openerp> </openerp>

View File

@ -1,12 +1,6 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_event_type","event.type","model_event_type","crm.group_crm_user",1,0,0,0 "access_event_type","event.type","model_event_type","event.group_event_subscriber",1,0,0,0
"access_event_type_manager","event.type manager","model_event_type","crm.group_crm_manager",1,1,1,1 "access_event_type_manager","event.type manager","model_event_type","event.group_event_manager",1,1,1,1
"access_event_event","event.event","model_event_event","crm.group_crm_user",1,1,1,1 "access_event_event","event.event","model_event_event","event.group_event_subscriber",1,1,1,1
"access_event_registration","event.registration","model_event_registration","crm.group_crm_user",1,1,1,1 "access_event_registration","event.registration","model_event_registration","event.group_event_subscriber",1,1,1,1
"access_report_event_registration","report.event.registration","model_report_event_registration","crm.group_crm_user",1,0,0,0 "access_report_event_registration","report.event.registration","model_report_event_registration","event.group_event_subscriber",1,0,0,0
"access_report_event_type_registration","report.event.type.registration","model_report_event_type_registration","crm.group_crm_user",1,0,0,0
"access_event_confirm_registration","event.confirm.registration","model_event_confirm_registration","crm.group_crm_user",1,0,0,0
"access_event_confirm_registration_manager","event.confirm.registration manager","model_event_confirm_registration","crm.group_crm_manager",1,1,1,1
"access_event_make_invoice","event.make.invoice","model_event_make_invoice","crm.group_crm_user",1,1,1,1
"access_event_partners_list","event.partners.list","model_event_partners_list","crm.group_crm_user",1,0,0,0
"access_event_registration_list","event.registration.list","model_event_registration_list","crm.group_crm_user",1,0,0,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_event_type event.type model_event_type crm.group_crm_user event.group_event_subscriber 1 0 0 0
3 access_event_type_manager event.type manager model_event_type crm.group_crm_manager event.group_event_manager 1 1 1 1
4 access_event_event event.event model_event_event crm.group_crm_user event.group_event_subscriber 1 1 1 1
5 access_event_registration event.registration model_event_registration crm.group_crm_user event.group_event_subscriber 1 1 1 1
6 access_report_event_registration report.event.registration model_report_event_registration crm.group_crm_user event.group_event_subscriber 1 0 0 0
access_report_event_type_registration report.event.type.registration model_report_event_type_registration crm.group_crm_user 1 0 0 0
access_event_confirm_registration event.confirm.registration model_event_confirm_registration crm.group_crm_user 1 0 0 0
access_event_confirm_registration_manager event.confirm.registration manager model_event_confirm_registration crm.group_crm_manager 1 1 1 1
access_event_make_invoice event.make.invoice model_event_make_invoice crm.group_crm_user 1 1 1 1
access_event_partners_list event.partners.list model_event_partners_list crm.group_crm_user 1 0 0 0
access_event_registration_list event.registration.list model_event_registration_list crm.group_crm_user 1 0 0 0

View File

@ -0,0 +1,227 @@
- |
In order to test the 'event' module in OpenERP, we create a new event.
- |
Given that I have product "Ticket for Concert".
-
!record {model: product.product, id: product_product_ticketforconcert0}:
categ_id: product.cat1
cost_method: standard
list_price: 68.0
mes_type: fixed
name: Ticket for Concert
procure_method: make_to_stock
standard_price: 15.0
supply_method: buy
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
volume: 0.0
warranty: 0.0
weight: 0.0
weight_net: 0.0
- |
Given that I have also Event type "Conference".
-
!record {model: event.type, id: event_type_conference0}:
name: Conference
- |
I create partner "Mark Johnson" and and I provide an address to this
new customer, as well as an email "info@mycustomer.com".
-
!record {model: res.partner, id: res_partner_markjohnson0}:
address:
- city: Bruxelles
country_id: base.be
job_ids:
- contact_id: base_contact.res_partner_contact_jacot0
function: CTO
name: base.res_partner_maxtor
sequence_partner: 0.0
state: current
street: Rue des Palais 51, bte 33
type: default
zip: '1000'
email: 'info@mycustomer.com'
credit_limit: 0.0
lang: en_US
name: Mark Johnson
property_account_payable: account.a_pay
property_account_receivable: account.a_recv
- |
we create it with a "Conference on OpenERP Offshore Business" event and provide "Beginning date", "Ending Date", "Product" as Concert Ticket.
-
!record {model: event.event, id: event_event_conference0}:
code: C/004
date_begin: '2010-06-07 13:39:00'
date_end: '2010-06-10 13:39:00'
name: Conference on OpenERP Offshore Business.
product_id: 'product_product_ticketforconcert0'
register_max: 0.0
register_min: 0.0
state: draft
type: 'event_type_conference0'
- |
we set the limit of registrations to this event using "Minimum Registrations" 2 and "Maximum Registrations" 10
-
!python {model: event.event}: |
self.write(cr, uid, [ref('event_event_conference0')], {'register_max': 10, 'register_min': 2})
- |
We Check that the event is in "Draft" state.
-
!assert {model: event.event, id: event_event_conference0}:
- state == 'draft'
- |
Then we confirm it press on "Confirm Event" button.
-
!python {model: event.event}: |
self.button_confirm(cr, uid, [ref("event_event_conference0")], {"active_ids": [ref("event.menu_event_event")]})
- |
Check that Event is "confirmed" or not.
-
!assert {model: event.event, id: event_event_conference0}:
- state == 'confirm'
- |
person "Mark Johnson" want to confirm their registrations. for that
I create New Registration for "Conference on OpenERP Offshore Business.
-
!record {model: event.registration, id: event_registration_registrationjacot0}:
badge_name: Jacot
badge_partner: Mark Johnson
badge_title: M.
contact_id: base_contact.res_partner_contact_jacot0
date_deadline: '2010-06-07 13:39:00'
event_id: event.event_event_conference0
event_product: Ticket for Concert
name: 'Registration: Jacot'
partner_id: 'res_partner_markjohnson0'
partner_invoice_id: 'res_partner_markjohnson0'
unit_price: 68.0
- |
I check that "Number of registration" is less than "Maximum registration" defined in "Conference on OpenERP Offshore Business" event.
if not then confirmation will fail because its greater then the Maximum registration.
-
!python {model: event.event}: |
obj_register = self.pool.get('event.registration')
event_id1 = self.browse(cr, uid, [ref('event_event_conference0')])[0]
register_ids = obj_register.search(cr, uid, [('event_id', '=', event_id1.id)])
register_id = obj_register.browse(cr, uid, register_ids)[0]
assert register_id.nb_register <= event_id1.register_max
- |
And Confirm that Registration by click on "Confirm Registration" button of Registraion form.
-
!python {model: event.registration}: |
self.check_confirm(cr, uid, [ref("event_registration_registrationjacot0")], {"active_ids": [ref("event.menu_action_registration")]})
- |
one other Person "Zen" also want to confirm their Registraions. so
They create New registraion for This event.
-
!record {model: event.registration, id: event_registration_registrationzen0}:
badge_name: Zen
badge_partner: China Export
contact_id: base_contact.res_partner_contact_zen0
date_deadline: '2010-06-07 13:39:00'
event_id: event.event_event_conference0
event_product: Ticket for Concert
name: 'Registration: Zen'
partner_id: base.res_partner_3
partner_invoice_id: base.res_partner_3
unit_price: 68.0
- |
And Confirm that Registration by click on "Confirm Registration" button of Registraion form.
-
!python {model: event.registration}: |
self.check_confirm(cr, uid, [ref("event_registration_registrationzen0")], {"active_ids": [ref("event.menu_action_registration")]})
- |
Third person create New Registration for "Conference on OpenERP Offshore Business" event.
-
!record {model: event.registration, id: event_registration_registrationpassot0}:
badge_name: Passot
badge_partner: Mediapole SPRL
badge_title: M.
contact_id: base_contact.res_partner_contact_passot0
date_deadline: '2010-06-07 13:39:00'
email_from: info@mediapole.net
event_id: 'event_event_conference0'
event_product: Ticket for Concert
name: 'Registration: Passot'
partner_id: base.res_partner_8
partner_invoice_id: base.res_partner_8
unit_price: 68.0
- |
This person cannot Confirm their registration.so I check that state is "Unconfirmed".
-
!assert {model: event.registration, id: event_registration_registrationpassot0}:
- state == 'draft'
- |
I Check that the total number of confirmed is 2 and unconfirmed registrations 1.
-
!python {model: event.event}: |
obj_event = self.browse(cr, uid, [ref('event_event_conference0')])[0]
assert obj_event.register_current == '2'
assert obj_event.register_prospect == '1'
- |
We check all registered partners to this event using the wizard "List Register Partners".
-
!record {model: event.partners.list, id: event_partners_list_0}:
{}
-
I click on "Open Partners" button of "List Register Partners" wizard.
-
!python {model: event.partners.list}: |
self.list_partners(cr, uid, [ref("event_partners_list_0")], {"active_ids":
[ref("event.event_event_conference0")]})
- |
This event is finished by click on "Event Done" button of this event form.
-
!python {model: event.event}: |
self.button_done(cr, uid, [ref("event.event_event_conference0")], {"active_ids": [ref("event.menu_event_event")] })
- |
We can create invoice if the registration is in "Open" state otherwise it gives the warning to the user.
so I check that Registration is in "Open" state before click on "Make Invoices."
-
!assert {model: event.registration, id: event_registration_registrationjacot0}:
- state == 'open'
- |
Now, I will invoice the participant who have address using "Make Invoices". This wizard will also give the number of invoices are created and rejected.
Create invoice will be linked to Invoice Field available on Payments tab of registrations
-
!record {model: event.make.invoice, id: event_make_invoice_0}:
{}
- |
I click on "Done" button of this "Make Invoices" wizard.
-
!python {model: event.make.invoice}: |
self.make_invoice(cr, uid, [ref("event_make_invoice_0")], {"active_ids": [ref("event_registration_registrationzen0")]})
- |
I check that Invoice for this partner is create or not.
-
!python {model: event.registration}: |
obj_event_reg = self.pool.get('event.registration')
obj_lines = self.pool.get('account.invoice.line')
inv_obj = self.pool.get('account.invoice')
data_event_reg = obj_event_reg.browse(cr, uid, [ref('event_registration_registrationzen0')], context=context)[0]
invoice_ids = inv_obj.search(cr, uid, [('partner_id', '=', data_event_reg.partner_invoice_id.id)])
if invoice_ids:
invoice_id = inv_obj.browse(cr, uid, invoice_ids)[0]
line_ids = obj_lines.search(cr, uid, [('product_id', '=', data_event_reg.event_id.product_id.id), ('invoice_id', '=', invoice_id.id), ('price_unit', '=', data_event_reg.unit_price)])
line_id = obj_lines.browse(cr, uid, line_ids)[0]
assert line_id.product_id == data_event_reg.event_id.product_id
assert data_event_reg.partner_id == invoice_id.partner_id
assert invoice_id.address_invoice_id == data_event_reg.partner_address_id

View File

@ -19,8 +19,6 @@
# #
############################################################################## ##############################################################################
import event_registration
import event_make_invoice import event_make_invoice
import event_registrations_partner
import event_confirm_registration import event_confirm_registration
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -20,7 +20,8 @@
############################################################################## ##############################################################################
from osv import fields, osv from osv import fields, osv
from tools.translate import _
class event_confirm_registration(osv.osv_memory): class event_confirm_registration(osv.osv_memory):
""" """
Confirm Event Registration Confirm Event Registration
@ -29,19 +30,40 @@ class event_confirm_registration(osv.osv_memory):
_description = "Event Registraion" _description = "Event Registraion"
_columns = { _columns = {
'msg': fields.text('Message', readonly=True), 'msg': fields.text('Message', readonly=True),
} }
_defaults={ _defaults = {
'msg':lambda *a:'The event limit is reached. What do you want to do?' 'msg': 'The event limit is reached. What do you want to do?'
} }
def default_get(self, cr, uid, fields, context=None):
"""
This function gets default values
"""
registration_pool = self.pool.get('event.registration')
registration_ids = context.get('registration_ids', [])
res = super(event_confirm_registration, self).default_get(cr, uid, fields, context=context)
msg = ""
overlimit_event_ids = []
for registration in registration_pool.browse(cr, uid, registration_ids, context=context):
total_confirmed = registration.event_id.register_current
register_max = registration.event_id.register_max
if registration.event_id.id not in overlimit_event_ids:
overlimit_event_ids.append(registration.event_id.id)
msg += _("The Event '%s' is reached Maximum Limit(%s). It has %s Confirmed registration\n") \
%(registration.event_id.name, register_max, total_confirmed)
if 'msg' in fields:
res.update({'msg': msg})
return res
def confirm(self, cr, uid, ids, context): def confirm(self, cr, uid, ids, context):
registration_obj = self.pool.get('event.registration') registration_pool = self.pool.get('event.registration')
reg_id = context.get('reg_id', False) or context.get('active_id', False) registration_ids = context.get('registration_ids', [])
if reg_id: for reg_id in registration_ids:
registration_obj.write(cr, uid, [reg_id], {'state':'open', }) registration_pool.write(cr, uid, [reg_id], {'state':'open', })
registration_obj._history(cr, uid, [reg_id], 'Open', history=True) registration_pool._history(cr, uid, [reg_id], _('Open'))
registration_obj.mail_user(cr, uid, [reg_id]) registration_pool.mail_user(cr, uid, [reg_id])
return {} return {}
event_confirm_registration() event_confirm_registration()

View File

@ -2,32 +2,32 @@
<openerp> <openerp>
<data> <data>
<record id="view_event_confirm_registration" model="ir.ui.view"> <record id="view_event_confirm_registration" model="ir.ui.view">
<field name="name">Registration Confirmation</field> <field name="name">Registration Confirmation</field>
<field name="model">event.confirm.registration</field> <field name="model">event.confirm.registration</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Registration Confirmation"> <form string="Registration Confirmation">
<field name="msg"/> <field name="msg" nolabel="1" colspan="4"/>
<separator string="" colspan="4"/> <separator string="" colspan="4"/>
<group colspan="4" col="6"> <group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="_Cancel"/> <button icon="gtk-close" special="cancel" string="Close"/>
<button icon="gtk-ok" name="confirm" string="Confirm Anyway" type="object"/> <button icon="gtk-ok" name="confirm" string="Confirm Anyway" type="object"/>
</group> </group>
</form> </form>
</field> </field>
</record> </record>
<record id="action_event_confirm_registration" model="ir.actions.act_window"> <record id="action_event_confirm_registration" model="ir.actions.act_window">
<field name="name">Registrations</field> <field name="name">Registrations</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">event.confirm.registration</field> <field name="res_model">event.confirm.registration</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">form</field> <field name="view_mode">form</field>
<field name="view_id" ref="view_event_confirm_registration"/> <field name="view_id" ref="view_event_confirm_registration"/>
<field name="context">{'record_id' : active_id}</field> <field name="context">{'record_id' : active_id}</field>
<field name="target">new</field> <field name="target">new</field>
</record> </record>
</data> </data>
</openerp> </openerp>

View File

@ -19,6 +19,7 @@
# #
############################################################################## ##############################################################################
from osv import fields, osv from osv import fields, osv
from tools.translate import _
class event_make_invoice(osv.osv_memory): class event_make_invoice(osv.osv_memory):
""" """
@ -27,109 +28,71 @@ class event_make_invoice(osv.osv_memory):
_name = "event.make.invoice" _name = "event.make.invoice"
_description = "Event Make Invoice" _description = "Event Make Invoice"
_columns = { _columns = {
'inv_created': fields.char('Invoice Created', size=32, readonly=True),
'inv_rejected': fields.char('Invoice Rejected', size=32, readonly=True),
'inv_rej_reason': fields.text('Error Messages', readonly=True),
# 'invoice_ids': fields.char('Invoice Ids', size=128), # Improve me
}
def _makeInvoices(self, cr, uid, context={}):
invoices = {}
invoice_ids = []
create_ids=[]
tax_ids=[]
inv_create = 0
inv_reject = 0
inv_rej_reason = ""
list_inv = []
obj_event_reg = self.pool.get('event.registration')
obj_lines = self.pool.get('account.invoice.line')
inv_obj = self.pool.get('account.invoice')
data_event_reg = obj_event_reg.browse(cr,uid, context['active_ids'], context=context)
for reg in data_event_reg:
if reg.state=='draft':
inv_reject = inv_reject + 1
inv_rej_reason += "ID "+str(reg.id)+": Invoice cannot be created if the registration is in draft state. \n"
continue
if (not reg.tobe_invoiced):
inv_reject = inv_reject + 1
inv_rej_reason += "ID "+str(reg.id)+": Registration is set as 'Cannot be invoiced'. \n"
continue
if reg.invoice_id:
inv_reject = inv_reject + 1
inv_rej_reason += "ID "+str(reg.id)+": Registration already has an invoice linked. \n"
continue
if not reg.event_id.product_id:
inv_reject = inv_reject + 1
inv_rej_reason += "ID "+str(reg.id)+": Event related doesn't have any product defined. \n"
continue
if not reg.partner_invoice_id:
inv_reject = inv_reject + 1
inv_rej_reason += "ID "+str(reg.id)+": Registration doesn't have any partner to invoice. \n"
continue
else:
val_invoice = inv_obj.onchange_partner_id(cr, uid, [], 'out_invoice', reg.partner_invoice_id.id, False, False)
val_invoice['value'].update({'partner_id': reg.partner_invoice_id.id})
partner_address_id = val_invoice['value']['address_invoice_id']
if not partner_address_id: 'grouped': fields.boolean('Group the invoices'),
inv_reject = inv_reject + 1 'invoice_date':fields.date('Invoice Date'),
inv_rej_reason += "ID "+str(reg.id)+": Registered partner doesn't have an address to make the invoice. \n" # 'invoice_ids': fields.char('Invoice Ids', size=128), # Improve me
continue }
inv_create = inv_create + 1 def view_init(self, cr, uid, fields, context=None):
value = obj_lines.product_id_change(cr, uid, [], reg.event_id.product_id.id,uom =False, partner_id=reg.partner_invoice_id.id, fposition_id=reg.partner_invoice_id.property_account_position.id) """
data_product = self.pool.get('product.product').browse(cr,uid,[reg.event_id.product_id.id]) This function checks for precondition before wizard executes
for tax in data_product[0].taxes_id: @param self: The object pointer
tax_ids.append(tax.id) @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
"""
obj_event_reg = self.pool.get('event.registration')
data = context and context.get('active_ids', [])
for event_reg in obj_event_reg.browse(cr, uid, data, context=context):
if event_reg.state == 'draft':
raise osv.except_osv(_('Warning !'),
_("Invoice cannot be created if the registration is in draft state."))
if event_reg.state == 'done':
raise osv.except_osv(_('Warning !'),
_("Invoice cannot be created if the registration is in done state."))
if (not event_reg.tobe_invoiced):
raise osv.except_osv(_('Warning !'),
_("Registration is set as Cannot be invoiced"))
vals = value['value'] if not event_reg.event_id.product_id:
c_name = reg.contact_id and ('-' + self.pool.get('res.partner.contact').name_get(cr, uid, [reg.contact_id.id])[0][1]) or '' raise osv.except_osv(_('Warning !'),
vals.update({ _("Event related doesn't have any product defined"))
'name': reg.invoice_label + '-' + c_name, if not event_reg.partner_invoice_id:
'price_unit': reg.unit_price, raise osv.except_osv(_('Warning !'),
'quantity': reg.nb_register, _("Registration doesn't have any partner to invoice."))
'product_id':reg.event_id.product_id.id,
'invoice_line_tax_id': [(6, 0, tax_ids)],
})
inv_line_ids = obj_event_reg._create_invoice_lines(cr, uid, [reg.id], vals)
val_invoice['value'].update({
'origin': reg.invoice_label,
'reference': False,
'invoice_line': [(6,0,[inv_line_ids])],
'comment': "",
})
inv_id = inv_obj.create(cr, uid, val_invoice['value'])
list_inv.append(inv_id)
obj_event_reg.write(cr, uid, reg.id, {'invoice_id': inv_id, 'state': 'done'})
obj_event_reg._history(cr, uid, [reg.id], 'Invoiced', history=True)
# {'inv_created' : str(inv_create) , 'inv_rejected' : str(inv_reject), 'invoice_ids': str(list_inv), 'inv_rej_reason': inv_rej_reason}
return {'inv_created' : str(inv_create) , 'inv_rejected' : str(inv_reject), 'inv_rej_reason': inv_rej_reason}
def default_get(self, cr, uid, fields_list, context=None): def default_get(self, cr, uid, fields_list, context=None):
res = super(event_make_invoice, self).default_get(cr, uid, fields_list, context) res = super(event_make_invoice, self).default_get(cr, uid, fields_list, context)
res.update(self._makeInvoices(cr, uid, context=context))
return res return res
def confirm(self, cr, uid, ids, context={}): def make_invoice(self, cr, uid, ids, context={}):
obj_model = self.pool.get('ir.model.data')
data_inv = self.read(cr, uid, ids, [], context)[0] reg_obj = self.pool.get('event.registration')
model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','invoice_form')]) newinv = []
resource_id = obj_model.read(cr,uid,model_data_ids,fields=['res_id'])[0]['res_id']
for data in self.browse(cr, uid, ids):
res = reg_obj.action_invoice_create(cr, uid, context.get(('active_ids'),[]), data.grouped, date_inv = data.invoice_date)
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'])
return { return {
# 'domain': "[('id','in', ["+','.join(map(str,data_inv['invoice_ids']))+"])]", 'domain': "[('id','=',%s)]" % res,
'name': 'Invoices', 'name': 'Invoices',
'view_type': 'form', 'view_type': 'form',
'view_mode': 'tree,form', 'view_mode': 'tree,form',
'res_model': 'account.invoice', 'res_model': 'account.invoice',
'views': [(False,'tree'),(resource_id,'form')], 'view_id': False,
'context': "{'type':'out_invoice'}", 'context': "{'type':'out_refund'}",
'type': 'ir.actions.act_window' 'type': 'ir.actions.act_window',
'search_view_id': id['id']
} }
event_make_invoice() event_make_invoice()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -7,15 +7,17 @@
<field name="model">event.make.invoice</field> <field name="model">event.make.invoice</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Make Invoices"> <form string="Create invoices">
<field name="inv_created" /> <separator colspan="4" string="Do you really want to create the invoices ?" />
<field name="inv_rejected" /> <field name="grouped" />
<field name="inv_rej_reason" colspan="4"/> <field name="invoice_date"/>
<group colspan="4" col="6"> <group colspan="4">
<button icon="gtk-cancel" special="cancel" string="_Ok"/> <separator string="" colspan="4" />
<button icon="gtk-ok" name="confirm" string="Open" type="object"/> <label string="" colspan="2"/>
</group> <button special="cancel" string="Close" icon="gtk-close"/>
</form> <button name="make_invoice" string="Done" type="object" icon="gtk-ok"/>
</group>
</form>
</field> </field>
</record> </record>

View File

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_event_registration" model="ir.ui.view">
<field name="name">List Event Registrations</field>
<field name="model">event.registration.list</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="">
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="open_registration" string="Open Registrations" type="object" icon="gtk-open"/>
</form>
</field>
</record>
<record id="action_event_registration" model="ir.actions.act_window">
<field name="name">Registrations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">event.registration.list</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_event_registration"/>
<field name="context">{'record_id' : active_id}</field>
<field name="target">new</field>
</record>
<record model="ir.values" id="event_registration_values">
<field name="model_id" ref="event.model_event_event" />
<field name="object" eval="1" />
<field name="name">Event Registrations</field>
<field name="key2">client_action_multi</field>
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_event_registration'))" />
<field name="key">action</field>
<field name="model">event.event</field>
</record>
</data>
</openerp>

View File

@ -1,55 +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/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
class event_partners_list(osv.osv_memory):
""" Event Partners """
_name = "event.partners.list"
_description = "List Event Partners"
def list_partners(self, cr, uid, ids, context={}):
obj_reg = self.pool.get('event.registration')
mod_obj = self.pool.get('ir.model.data')
list_partner = []
reg_ids = obj_reg.search(cr, uid, [('event_id','in',context['active_ids'])], context=context)
data_reg = obj_reg.browse(cr, uid, reg_ids, context=context)
for reg in data_reg:
if not reg.partner_id.id in list_partner:
list_partner.append(reg.partner_id.id)
result = mod_obj._get_id(cr, uid, 'base', 'view_res_partner_filter')
id = mod_obj.read(cr, uid, result, ['res_id'], context=context)
model_data_ids = mod_obj.search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_partner_form')], context=context)
resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
return {
'domain': "[('id','in', ["+','.join(map(str, list_partner))+"])]",
'name': _('Event Partners'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'res.partner',
'views': [(False,'tree'),(resource_id,'form')],
'type': 'ir.actions.act_window',
'search_view_id': id['res_id']
}
event_partners_list()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_event_partners" model="ir.ui.view">
<field name="name">Event Partners</field>
<field name="model">event.partners.list</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Event Partners">
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="list_partners" string="Open Partners" type="object" icon="gtk-open"/>
</form>
</field>
</record>
<record id="action_event_partners" model="ir.actions.act_window">
<field name="name">List Register Partners</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">event.partners.list</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_event_partners"/>
<field name="context">{'record_id' : active_id}</field>
<field name="target">new</field>
</record>
<record model="ir.values" id="event_partner_values">
<field name="model_id" ref="event.model_event_event" />
<field name="object" eval="1" />
<field name="name">Event Partners</field>
<field name="key2">client_action_multi</field>
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_event_partners'))"/>
<field name="key">action</field>
<field name="model">event.event</field>
</record>
</data>
</openerp>

View File

@ -21,5 +21,6 @@
import membership import membership
import wizard import wizard
import report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -43,10 +43,12 @@ invoice and send propositions for membership renewal.
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'wizard/membership_invoice_view.xml', 'wizard/membership_invoice_view.xml',
'membership_view.xml', 'membership_view.xml',
'report/report_membership_view.xml',
'wizard/membership_unpaid_invoice_view.xml', 'wizard/membership_unpaid_invoice_view.xml',
'process/membership_process.xml' 'process/membership_process.xml'
], ],
'demo_xml': ['membership_demo.xml'], 'demo_xml': ['membership_demo.xml'],
'test': ['test/test_membership.yml'],
'installable': True, 'installable': True,
'active': False, 'active': False,
'certificate': '0042907796381', 'certificate': '0042907796381',

View File

@ -201,10 +201,10 @@ class membership_line(osv.osv):
_name = 'membership.membership_line' _name = 'membership.membership_line'
_columns = { _columns = {
'partner': fields.many2one('res.partner', 'Partner', ondelete='cascade', select=1), 'partner': fields.many2one('res.partner', 'Partner', ondelete='cascade', select=1),
'date_from': fields.date('From'), 'date_from': fields.date('From', readonly=True),
'date_to': fields.date('To'), 'date_to': fields.date('To', readonly=True),
'date_cancel' : fields.date('Cancel date'), 'date_cancel' : fields.date('Cancel date'),
'account_invoice_line': fields.many2one('account.invoice.line', 'Account Invoice line'), 'account_invoice_line': fields.many2one('account.invoice.line', 'Account Invoice line', readonly=True),
'state': fields.function(_state, method=True, string='State', type='selection', selection=STATE), 'state': fields.function(_state, method=True, string='State', type='selection', selection=STATE),
} }
_rec_name = 'partner' _rec_name = 'partner'
@ -221,6 +221,7 @@ class Partner(osv.osv):
_inherit = 'res.partner' _inherit = 'res.partner'
def _get_partner_id(self, cr, uid, ids, context=None): def _get_partner_id(self, cr, uid, ids, context=None):
data_inv = self.pool.get('membership.membership_line').browse(cr, uid, ids, context) data_inv = self.pool.get('membership.membership_line').browse(cr, uid, ids, context)
list_partner = [] list_partner = []
for data in data_inv: for data in data_inv:
@ -298,55 +299,47 @@ class Partner(osv.osv):
res_state = self._membership_state(cr, uid, [partner_data.associate_member.id], name, args, context) res_state = self._membership_state(cr, uid, [partner_data.associate_member.id], name, args, context)
res[id] = res_state[partner_data.associate_member.id] res[id] = res_state[partner_data.associate_member.id]
return res return res
def _membership_start(self, cr, uid, ids, name, args, context=None): def _membership_date(self, cr, uid, ids, name, args, context=None):
'''Return the start date of membership'''
'''Return date of membership'''
name = name[0]
res = {} res = {}
member_line_obj = self.pool.get('membership.membership_line') member_line_obj = self.pool.get('membership.membership_line')
for partner in self.browse(cr, uid, ids): for partner in self.browse(cr, uid, ids):
if partner.associate_member: if partner.associate_member:
partner_id = partner.associate_member.id partner_id = partner.associate_member.id
else: else:
partner_id = partner.id partner_id = partner.id
line_id = member_line_obj.search(cr, uid, [('partner', '=', partner_id)],
limit=1, order='date_from') res[partner.id]={
if line_id: 'membership_start': False,
res[partner.id] = member_line_obj.read(cr, uid, line_id[0], 'membership_stop': False,
['date_from'])['date_from'] 'membership_cancel': False
else: }
res[partner.id] = False
return res if name == 'membership_start':
line_id = member_line_obj.search(cr, uid, [('partner', '=', partner_id)],
def _membership_stop(self, cr, uid, ids, name, args, context=None): limit=1, order='date_from')
'''Return the stop date of membership'''
res = {}
member_line_obj = self.pool.get('membership.membership_line')
for partner in self.browse(cr, uid, ids):
cr.execute('select membership_state from res_partner where id=%s', (partner.id,))
data_state = cr.fetchall()
if partner.associate_member:
partner_id = partner.associate_member.id
else:
partner_id = partner.id
line_id = member_line_obj.search(cr, uid, [('partner', '=', partner_id)],
limit=1, order='date_to desc')
if line_id:
res[partner.id] = member_line_obj.read(cr, uid, line_id[0],
['date_to'])['date_to']
else:
res[partner.id] = False
return res
def _membership_cancel(self, cr, uid, ids, name, args, context=None):
'''Return the cancel date of membership'''
res = {}
member_line_obj = self.pool.get('membership.membership_line')
for partner in self.browse(cr, uid, ids, context=context):
res[partner.id] = False
if partner.membership_state == 'canceled':
line_id = member_line_obj.search(cr, uid, [('partner', '=', partner.id)],limit=1, order='date_cancel')
if line_id: if line_id:
res[partner.id] = member_line_obj.read(cr, uid, line_id[0],['date_cancel'])['date_cancel'] res[partner.id]['membership_start'] = member_line_obj.read(cr, uid, line_id[0],
['date_from'])['date_from']
if name == 'membership_stop':
line_id1 = member_line_obj.search(cr, uid, [('partner', '=', partner_id)],
limit=1, order='date_to desc')
if line_id1:
res[partner.id]['membership_stop'] = member_line_obj.read(cr, uid, line_id1[0],
['date_to'])['date_to']
if name == 'membership_cancel':
if partner.membership_state == 'canceled':
line_id2 = member_line_obj.search(cr, uid, [('partner', '=', partner.id)],limit=1, order='date_cancel')
if line_id2:
res[partner.id]['membership_cancel'] = member_line_obj.read(cr, uid, line_id2[0],['date_cancel'])['date_cancel']
return res return res
def _get_partners(self, cr, uid, ids, context={}): def _get_partners(self, cr, uid, ids, context={}):
@ -377,17 +370,17 @@ class Partner(osv.osv):
} }
), ),
'membership_start': fields.function( 'membership_start': fields.function(
_membership_start, method=True, _membership_date, method=True, multi='membeship_start',
string = 'Start membership date', type = 'date', string = 'Start membership date', type = 'date',
store = { store = {
'account.invoice':(_get_invoice_partner,['state'], 10), 'account.invoice':(_get_invoice_partner,['state'], 10),
'membership.membership_line':(_get_partner_id,['state'], 10), 'membership.membership_line':(_get_partner_id,['state'], 10, ),
'res.partner':(lambda self,cr,uid,ids,c={}:ids, ['free_member'], 10) 'res.partner':(lambda self,cr,uid,ids,c={}:ids, ['free_member'], 10)
} }
), ),
'membership_stop': fields.function( 'membership_stop': fields.function(
_membership_stop, method = True, _membership_date, method = True,
string = 'Stop membership date', type = 'date', string = 'Stop membership date', type = 'date', multi='membership_stop',
store = { store = {
'account.invoice':(_get_invoice_partner,['state'], 10), 'account.invoice':(_get_invoice_partner,['state'], 10),
'membership.membership_line':(_get_partner_id,['state'], 10), 'membership.membership_line':(_get_partner_id,['state'], 10),
@ -396,8 +389,8 @@ class Partner(osv.osv):
), ),
'membership_cancel': fields.function( 'membership_cancel': fields.function(
_membership_cancel, method = True, _membership_date, method = True,
string = 'Cancel membership date', type='date', string = 'Cancel membership date', type='date', multi='membership_cancel',
store = { store = {
'account.invoice':(_get_invoice_partner,['state'], 11), 'account.invoice':(_get_invoice_partner,['state'], 11),
'membership.membership_line':(_get_partner_id,['state'], 10), 'membership.membership_line':(_get_partner_id,['state'], 10),
@ -491,160 +484,6 @@ class Invoice(osv.osv):
return super(Invoice, self).action_cancel(cr, uid, ids, context) return super(Invoice, self).action_cancel(cr, uid, ids, context)
Invoice() Invoice()
class ReportPartnerMemberYear(osv.osv):
'''Membership by Years'''
_name = 'report.partner_member.year'
_description = __doc__
_auto = False
_rec_name = 'year'
_columns = {
'year': fields.char('Year', size='4', readonly=True, select=1),
'canceled_number': fields.integer('Canceled', readonly=True),
'waiting_number': fields.integer('Waiting', readonly=True),
'invoiced_number': fields.integer('Invoiced', readonly=True),
'paid_number': fields.integer('Paid', readonly=True),
'canceled_amount': fields.float('Canceled', digits=(16, 2), readonly=True),
'waiting_amount': fields.float('Waiting', digits=(16, 2), readonly=True),
'invoiced_amount': fields.float('Invoiced', digits=(16, 2), readonly=True),
'paid_amount': fields.float('Paid', digits=(16, 2), readonly=True),
'currency': fields.many2one('res.currency', 'Currency', readonly=True,
select=2),
}
def init(self, cr):
'''Create the view'''
cr.execute("""
CREATE OR REPLACE VIEW report_partner_member_year AS (
SELECT
MIN(id) AS id,
COUNT(ncanceled) as canceled_number,
COUNT(npaid) as paid_number,
COUNT(ninvoiced) as invoiced_number,
COUNT(nwaiting) as waiting_number,
SUM(acanceled) as canceled_amount,
SUM(apaid) as paid_amount,
SUM(ainvoiced) as invoiced_amount,
SUM(awaiting) as waiting_amount,
year,
currency
FROM (SELECT
CASE WHEN ai.state = 'cancel' THEN ml.id END AS ncanceled,
CASE WHEN ai.state = 'paid' THEN ml.id END AS npaid,
CASE WHEN ai.state = 'open' THEN ml.id END AS ninvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN ml.id END AS nwaiting,
CASE WHEN ai.state = 'cancel'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS acanceled,
CASE WHEN ai.state = 'paid'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS apaid,
CASE WHEN ai.state = 'open'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS ainvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS awaiting,
TO_CHAR(ml.date_from, 'YYYY') AS year,
ai.currency_id AS currency,
MIN(ml.id) AS id
FROM membership_membership_line ml
JOIN (account_invoice_line ail
LEFT JOIN account_invoice ai
ON (ail.invoice_id = ai.id))
ON (ml.account_invoice_line = ail.id)
JOIN res_partner p
ON (ml.partner = p.id)
GROUP BY TO_CHAR(ml.date_from, 'YYYY'), ai.state,
ai.currency_id, ml.id) AS foo
GROUP BY year, currency)
""")
ReportPartnerMemberYear()
class ReportPartnerMemberYearNew(osv.osv):
'''New Membership by Years'''
_name = 'report.partner_member.year_new'
_description = __doc__
_auto = False
_rec_name = 'year'
_columns = {
'year': fields.char('Year', size='4', readonly=True, select=1),
'canceled_number': fields.integer('Canceled', readonly=True),
'waiting_number': fields.integer('Waiting', readonly=True),
'invoiced_number': fields.integer('Invoiced', readonly=True),
'paid_number': fields.integer('Paid', readonly=True),
'canceled_amount': fields.float('Canceled', digits=(16, 2), readonly=True),
'waiting_amount': fields.float('Waiting', digits=(16, 2), readonly=True),
'invoiced_amount': fields.float('Invoiced', digits=(16, 2), readonly=True),
'paid_amount': fields.float('Paid', digits=(16, 2), readonly=True),
'currency': fields.many2one('res.currency', 'Currency', readonly=True,
select=2),
}
def init(self, cursor):
'''Create the view'''
cursor.execute("""
CREATE OR REPLACE VIEW report_partner_member_year_new AS (
SELECT
MIN(id) AS id,
COUNT(ncanceled) AS canceled_number,
COUNT(npaid) AS paid_number,
COUNT(ninvoiced) AS invoiced_number,
COUNT(nwaiting) AS waiting_number,
SUM(acanceled) AS canceled_amount,
SUM(apaid) AS paid_amount,
SUM(ainvoiced) AS invoiced_amount,
SUM(awaiting) AS waiting_amount,
year,
currency
FROM (SELECT
CASE WHEN ai.state = 'cancel' THEN ml2.id END AS ncanceled,
CASE WHEN ai.state = 'paid' THEN ml2.id END AS npaid,
CASE WHEN ai.state = 'open' THEN ml2.id END AS ninvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN ml2.id END AS nwaiting,
CASE WHEN ai.state = 'cancel'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS acanceled,
CASE WHEN ai.state = 'paid'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS apaid,
CASE WHEN ai.state = 'open'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS ainvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS awaiting,
TO_CHAR(ml2.date_from, 'YYYY') AS year,
ai.currency_id AS currency,
MIN(ml2.id) AS id
FROM (SELECT
partner AS id,
MIN(date_from) AS date_from
FROM membership_membership_line
GROUP BY partner
) AS ml1
JOIN membership_membership_line ml2
JOIN (account_invoice_line ail
LEFT JOIN account_invoice ai
ON (ail.invoice_id = ai.id))
ON (ml2.account_invoice_line = ail.id)
ON (ml1.id = ml2.partner AND ml1.date_from = ml2.date_from)
JOIN res_partner p
ON (ml2.partner = p.id)
GROUP BY TO_CHAR(ml2.date_from, 'YYYY'), ai.state,
ai.currency_id, ml2.id) AS foo
GROUP BY year, currency
)
""")
ReportPartnerMemberYearNew()
class account_invoice_line(osv.osv): class account_invoice_line(osv.osv):
_inherit='account.invoice.line' _inherit='account.invoice.line'
@ -703,4 +542,4 @@ class account_invoice_line(osv.osv):
return result return result
account_invoice_line() account_invoice_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -39,7 +39,8 @@
<field name="membership" colspan="1"/> <field name="membership" colspan="1"/>
<field name="active" colspan="1"/> <field name="active" colspan="1"/>
<newline/> <newline/>
<field name="taxes_id" colspan="4"/> <separator colspan="4" string="Customer Taxes:"/>
<field name="taxes_id" colspan="4" nolabel="1"/>
</form> </form>
</field> </field>
</record> </record>
@ -117,28 +118,32 @@
<field name="type">search</field> <field name="type">search</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="category_id" position="after"> <field name="category_id" position="after">
<group col="4" colspan="6"> <filter icon="terp-personal" name="old" domain="[('membership_state', '=', 'old')]" string="Old Members" />
<filter string="Members" icon="terp-personal" domain="[]" context="{'group_by':'membership_state'}"/> <filter icon="terp-personal" name = "invoiced" domain="[('membership_state', '=', 'invoiced')]" string="Invoiced Members"/>
<separator orientation="vertical"/> <filter icon="terp-personal" domain="[('membership_state', '=', 'paid')]" string="Paid Members" />
<field name="membership_state"/> <filter icon="terp-personal" domain="[('membership_state', '=', 'waiting')]" string="Future Members" />
</group> <separator orientation="vertical"/>
<field name="membership_state"/>
<field name="membership_start"/>
<newline/>
</field> </field>
</field> </field>
</record> </record>
<record id="view_res_partner_member_filter2" model="ir.ui.view"> <record id="view_res_partner_member_filter2" model="ir.ui.view">
<field name="name">res.partner.select2</field> <field name="name">res.partner.select2</field>
<field name="model">res.partner</field> <field name="model">res.partner</field>
<field name="inherit_id" ref="view_res_partner_member_filter"/> <field name="inherit_id" ref="view_res_partner_member_filter"/>
<field name="type">search</field> <field name="type">search</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="membership_state" position="after"> <field name="membership_start" position="after">
<newline/>
<group expand="1" string="Group By" colspan="10" col="8"> <group expand="1" string="Group By" colspan="10" col="8">
<separator orientation="vertical"/> <filter string="Associate Member" name = "associate" icon="terp-personal" domain="[]" context="{'group_by':'associate_member'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'membership_state'}"/>
<separator orientation="vertical"/>
<filter string="Start Date" icon="terp-go-month" domain="[]" context="{'group_by':'membership_start'}"/> <filter string="Start Date" icon="terp-go-month" domain="[]" context="{'group_by':'membership_start'}"/>
<filter string="End Date" icon="terp-go-month" domain="[]" context="{'group_by':'membership_stop'}"/> <filter string="End Date" icon="terp-go-month" domain="[]" context="{'group_by':'membership_stop'}"/>
<filter string="Associate Member" icon="terp-personal" domain="[]" context="{'group_by':'associate_member'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'membership_state'}"/>
</group> </group>
</field> </field>
</field> </field>
@ -149,6 +154,7 @@
<field name="res_model">res.partner</field> <field name="res_model">res.partner</field>
<field name="domain">[('membership_state','&lt;&gt;','none'),('membership_state','&lt;&gt;','canceled'),('membership_state','&lt;&gt;','old'),('membership_state','&lt;&gt;','waiting')]</field> <field name="domain">[('membership_state','&lt;&gt;','none'),('membership_state','&lt;&gt;','canceled'),('membership_state','&lt;&gt;','old'),('membership_state','&lt;&gt;','waiting')]</field>
<field name="search_view_id" ref="view_res_partner_member_filter"/> <field name="search_view_id" ref="view_res_partner_member_filter"/>
<field name="context">{"search_default_old": 1}</field>
</record> </record>
<record model="ir.actions.act_window.view" id="action_membership_members_view_tree"> <record model="ir.actions.act_window.view" id="action_membership_members_view_tree">
@ -229,7 +235,6 @@
</field> </field>
</page> </page>
</notebook> </notebook>
</field> </field>
</record> </record>
@ -238,211 +243,6 @@
sequence="2" sequence="2"
id="menu_reporting"/> id="menu_reporting"/>
<!-- REPORTING/MEMBERSHIP BY YEAR -->
<record model="ir.ui.view" id="view_report_partner_member_year_tree1">
<field name="name">report.partner_member.year.tree</field>
<field name="model">report.partner_member.year</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Membership by Years">
<field name="canceled_number"/>
<field name="waiting_number"/>
<field name="invoiced_number"/>
<field name="paid_number"/>
<field name="year"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_tree2">
<field name="name">report.partner_member.year.tree</field>
<field name="model">report.partner_member.year</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Membership by Years">
<field name="canceled_amount"/>
<field name="waiting_amount"/>
<field name="invoiced_amount"/>
<field name="paid_amount"/>
<field name="currency"/>
<field name="year"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_graph1">
<field name="name">report.partner_member.year.graph1</field>
<field name="model">report.partner_member.year</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Membership by Years" type="bar">
<field name="year"/>
<field name="canceled_number"/>
<field name="waiting_number"/>
<field name="invoiced_number"/>
<field name="paid_number"/>
</graph>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_graph2">
<field name="name">report.partner_member.year.graph2</field>
<field name="model">report.partner_member.year</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Membership by Years" type="bar">
<field name="year"/>
<field name="canceled_amount"/>
<field name="waiting_amount"/>
<field name="invoiced_amount"/>
<field name="paid_amount"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_partner_member_year_tree">
<field name="res_model">report.partner_member.year</field>
<field name="view_type">form</field>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_tree_view1">
<field name="sequence" eval="3"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_partner_member_year_tree1"/>
<field name="act_window_id" ref="action_report_partner_member_year_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_tree_view4">
<field name="sequence" eval="4"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_partner_member_year_tree2"/>
<field name="act_window_id" ref="action_report_partner_member_year_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_tree_view2">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_partner_member_year_graph1"/>
<field name="act_window_id" ref="action_report_partner_member_year_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_tree_view3">
<field name="sequence" eval="2"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_partner_member_year_graph2"/>
<field name="act_window_id" ref="action_report_partner_member_year_tree"/>
</record>
<menuitem name="Membership by Years" parent="menu_reporting"
action="action_report_partner_member_year_tree"
id="menu_report_partner_member_year"/>
<!-- REPORTING/NEW MEMBERSHIP BY YEAR -->
<record model="ir.ui.view" id="view_report_partner_member_year_new_tree1">
<field name="name">report.partner_member.year_new.tree</field>
<field name="model">report.partner_member.year_new</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="New Membership by Years">
<field name="canceled_number"/>
<field name="waiting_number"/>
<field name="invoiced_number"/>
<field name="paid_number"/>
<field name="year"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_new_tree2">
<field name="name">report.partner_member.year_new.tree</field>
<field name="model">report.partner_member.year_new</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="New Membership by Years">
<field name="canceled_amount"/>
<field name="waiting_amount"/>
<field name="invoiced_amount"/>
<field name="paid_amount"/>
<field name="currency"/>
<field name="year"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_new_graph1">
<field name="name">report.partner_member.year_new.graph1</field>
<field name="model">report.partner_member.year_new</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="New Membership by Years" type="bar">
<field name="year"/>
<field name="canceled_number"/>
<field name="waiting_number"/>
<field name="invoiced_number"/>
<field name="paid_number"/>
</graph>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_new_graph2">
<field name="name">report.partner_member.year_new.graph2</field>
<field name="model">report.partner_member.year_new</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="New Membership by Years" type="bar">
<field name="year"/>
<field name="canceled_amount"/>
<field name="waiting_amount"/>
<field name="invoiced_amount"/>
<field name="paid_amount"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_partner_member_year_new_tree">
<field name="res_model">report.partner_member.year_new</field>
<field name="view_type">form</field>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_new_tree_view4">
<field name="sequence" eval="4"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_partner_member_year_new_tree2"/>
<field name="act_window_id" ref="action_report_partner_member_year_new_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_new_tree_view1">
<field name="sequence" eval="3"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_partner_member_year_new_tree1"/>
<field name="act_window_id" ref="action_report_partner_member_year_new_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_new_tree_view2">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_partner_member_year_new_graph1"/>
<field name="act_window_id" ref="action_report_partner_member_year_new_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_new_tree_view3">
<field name="sequence" eval="2"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_partner_member_year_new_graph2"/>
<field name="act_window_id" ref="action_report_partner_member_year_new_tree"/>
</record>
<menuitem name="New Membership by Years" parent="menu_reporting"
action="action_report_partner_member_year_new_tree"
id="menu_report_partner_member_year_new"/>
<!-- View for product.product object inherited from product module................ --> <!-- View for product.product object inherited from product module................ -->
<record model="ir.ui.view" id="view_product_form_inherit1"> <record model="ir.ui.view" id="view_product_form_inherit1">

View File

@ -0,0 +1,22 @@
# -*- 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 report_membership

View File

@ -0,0 +1,123 @@
# -*- 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 tools
class report_membership(osv.osv):
'''Membership by Years'''
_name = 'report.membership'
_description = __doc__
_auto = False
_rec_name = 'year'
_columns = {
'year': fields.char('Year', size=4, readonly=True, select=1),
'month':fields.selection([('01', 'January'), ('02', 'February'), \
('03', 'March'), ('04', 'April'),\
('05', 'May'), ('06', 'June'), \
('07', 'July'), ('08', 'August'),\
('09', 'September'), ('10', 'October'),\
('11', 'November'), ('12', 'December')], 'Month', readonly=True),
'create_date': fields.datetime('Create Date', readonly=True),
'canceled_number': fields.integer('Canceled', readonly=True),
'waiting_number': fields.integer('Waiting', readonly=True),
'invoiced_number': fields.integer('Invoiced', readonly=True),
'paid_number': fields.integer('Paid', readonly=True),
'canceled_amount': fields.float('Canceled', digits=(16, 2), readonly=True),
'waiting_amount': fields.float('Waiting', digits=(16, 2), readonly=True),
'invoiced_amount': fields.float('Invoiced', digits=(16, 2), readonly=True),
'paid_amount': fields.float('Paid', digits=(16, 2), readonly=True),
'currency': fields.many2one('res.currency', 'Currency', readonly=True,
select=2),
'state':fields.selection([('draft', 'Non Member'),
('cancel', 'Cancelled Member'),
('done', 'Old Member'),
('open', 'Invoiced Member'),
('free', 'Free Member'), ('paid', 'Paid Member')], 'State'),
'partner_id': fields.many2one('res.partner', 'Members', readonly=True, select=3)
}
def init(self, cr):
'''Create the view'''
cr.execute("""
CREATE OR REPLACE VIEW report_membership AS (
SELECT
MIN(id) as id,
COUNT(ncanceled) as canceled_number,
COUNT(npaid) as paid_number,
COUNT(ninvoiced) as invoiced_number,
COUNT(nwaiting) as waiting_number,
SUM(acanceled) as canceled_amount,
SUM(apaid) as paid_amount,
SUM(ainvoiced) as invoiced_amount,
SUM(awaiting) as waiting_amount,
year,
month,
create_date,
partner_id,
state,
currency
FROM (SELECT
CASE WHEN ai.state = 'cancel' THEN ml.id END AS ncanceled,
CASE WHEN ai.state = 'paid' THEN ml.id END AS npaid,
CASE WHEN ai.state = 'open' THEN ml.id END AS ninvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN ml.id END AS nwaiting,
CASE WHEN ai.state = 'cancel'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS acanceled,
CASE WHEN ai.state = 'paid'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS apaid,
CASE WHEN ai.state = 'open'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS ainvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS awaiting,
TO_CHAR(ml.date_from, 'YYYY') AS year,
TO_CHAR(ml.date_from, 'MM')as month,
TO_CHAR(ml.date_from, 'YYYY-MM-DD') as create_date,
ai.partner_id AS partner_id,
ai.currency_id AS currency,
ai.state as state,
MIN(ml.id) AS id
FROM membership_membership_line ml
JOIN (account_invoice_line ail
LEFT JOIN account_invoice ai
ON (ail.invoice_id = ai.id))
ON (ml.account_invoice_line = ail.id)
JOIN res_partner p
ON (ml.partner = p.id)
GROUP BY TO_CHAR(ml.date_from, 'YYYY'), TO_CHAR(ml.date_from, 'MM'), TO_CHAR(ml.date_from, 'YYYY-MM-DD'), ai.state, ai.partner_id,
ai.currency_id, ml.id) AS foo
GROUP BY year, month, create_date, currency, partner_id, state)
""")
report_membership()
#

View File

@ -0,0 +1,112 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- REPORTING/MEMBERSHIP BY YEAR -->
<record model="ir.ui.view" id="view_report_membership_tree1">
<field name="name">report.membership.tree</field>
<field name="model">report.membership</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Membership">
<field name="state"/>
<field name="partner_id"/>
<field name="canceled_number"/>
<field name="waiting_number"/>
<field name="invoiced_number"/>
<field name="paid_number"/>
<field name="year"/>
<field name="month"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_report_membership_search">
<field name="name">report.membership.search</field>
<field name="model">report.membership</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Membership">
<group col="8" colspan="4">
<filter string="Last 365 Days" icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"/>
<filter string="Last 30 Days" icon="terp-go-month" name="month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"/>
<separator orientation="vertical"/>
<filter icon="terp-camera_test"
string="Invoiced"
domain="[('state','=','open')]"/>
<filter icon="terp-check"
string="Paid"
domain="[('state','=','paid')]"/>
<filter icon="terp-gtk-media-pause"
string="Waiting"
default="1" name="none"
domain="[('state','=', 'draft')]"/>
<separator orientation="vertical"/>
<field name="partner_id"/>
</group>
<newline/>
<group expand="0" string="Group By..." colspan="4" col="12">
<filter string="Members" icon="terp-personal" name="member"
domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="state" icon="terp-stock_effects-object-colorize"
domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Year" name="year" icon="terp-go-year"
domain="[]" context="{'group_by':'year'}"/>
<filter string="Month" name="month" icon="terp-go-month"
domain="[]" context="{'group_by':'month'}"/>
</group>
</search>
</field>
</record>
<record model="ir.ui.view" id="view_report_membership_graph1">
<field name="name">report.membership.graph1</field>
<field name="model">report.membership</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Membership" type="bar">
<field name="year"/>
<field name="canceled_number"/>
<field name="waiting_number"/>
<field name="invoiced_number"/>
<field name="paid_number"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_membership_tree">
<field name="res_model">report.membership</field>
<field name="view_type">form</field>
<field name="search_view_id" ref="view_report_membership_search"/>
<field name="context">{"search_default_member":1}</field>
</record>
<record model="ir.actions.act_window.view" id="action_report_membership_tree_view1">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_membership_tree1"/>
<field name="act_window_id" ref="action_report_membership_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_membership_tree_view2">
<field name="sequence" eval="3"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_membership_graph1"/>
<field name="act_window_id" ref="action_report_membership_tree"/>
</record>
<menuitem name="Membership" parent="menu_reporting"
action="action_report_membership_tree"
id="menu_report_membership"/>
</data>
</openerp>

View File

@ -1,7 +1,6 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_membership_membership_line_partner_manager","membership.membership_line partner_manager","model_membership_membership_line","base.group_partner_manager",1,1,1,1 "access_membership_membership_line_partner_manager","membership.membership_line partner_manager","model_membership_membership_line","base.group_partner_manager",1,1,1,1
"access_membership_membership_line","membership.membership_line","model_membership_membership_line",,1,0,0,0 "access_membership_membership_line","membership.membership_line","model_membership_membership_line",,1,0,0,0
"access_report_partner_member_year","report.partner_member.year","model_report_partner_member_year","base.group_partner_manager",1,0,0,0 "access_report_membership","report.membership","model_report_membership","base.group_partner_manager",1,0,0,0
"access_report_partner_member_year_new","report.partner_member.year_new","model_report_partner_member_year_new","base.group_partner_manager",1,0,0,0
"access_membership_invoice","membership.invoice","model_membership_invoice",,1,1,1,1 "access_membership_invoice","membership.invoice","model_membership_invoice",,1,1,1,1
"access_membership_unpaid_invoice","membership.unpaid.invoice","model_membership_unpaid_invoice",,1,0,0,0 "access_membership_unpaid_invoice","membership.unpaid.invoice","model_membership_unpaid_invoice",,1,0,0,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_membership_membership_line_partner_manager membership.membership_line partner_manager model_membership_membership_line base.group_partner_manager 1 1 1 1
3 access_membership_membership_line membership.membership_line model_membership_membership_line 1 0 0 0
4 access_report_partner_member_year access_report_membership report.partner_member.year report.membership model_report_partner_member_year model_report_membership base.group_partner_manager 1 0 0 0
access_report_partner_member_year_new report.partner_member.year_new model_report_partner_member_year_new base.group_partner_manager 1 0 0 0
5 access_membership_invoice membership.invoice model_membership_invoice 1 1 1 1
6 access_membership_unpaid_invoice membership.unpaid.invoice model_membership_unpaid_invoice 1 0 0 0

View File

@ -0,0 +1,115 @@
- |
In Order to test the Membership in OpenERP, which allows us to manage all operations for managing memberships.
- |
We have to create "Membership Products" to make it available for partner or customer to make membership with it.
select product type to "service" type and membership field is ticked to visible this product while creating membership for the partner.
-
!record {model: product.product, id: product_product_membershipproduct0}:
categ_id: product.cat1
membership: 1
membership_date_from: '2009-06-01'
membership_date_to: '2010-06-01'
name: Membership Products
type: service
list_price: 80.00
- |
I create new member "Mark Johnson" and I provide an address to this
new customer, as well as an email "info@mycustomer.com".
-
!record {model: res.partner, id: res_partner_markjohnson0}:
address:
- city: paris
country_id: base.fr
name: Arthur Grosbonnet
street: 1 rue Rockfeller
title: M.
type: default
zip: '75016'
credit_limit: 0.0
membership_amount: 0.0
name: Mark Johnson
property_account_payable: account.a_pay
property_account_receivable: account.a_recv
- |
I check that "Current membership state" is set to "Non Member".
-
!assert {model: res.partner, id: res_partner_markjohnson0}:
- membership_state == 'none'
- |
I can make it a Free member by selecting the "Free member" check box.
-
!record {model: res.partner, id: membership.res_partner_markjohnson0}:
free_member: 1
- |
Now, I create Membership Invoices using wizard available on partner and Select Membership Product.
-
!record {model: membership.invoice, id: membership_invoice_0}:
product_id: membership.product_product_membershipproduct0
- |
I check that address is defined or not for this Member.
-
!python {model: membership.invoice}: |
partner_ids = [ref('res_partner_markjohnson0')]
addre_obj = self.pool.get('res.partner.address')
ids = addre_obj.search(cr, uid, [('partner_id', '=', partner_ids)])
addre_id = addre_obj.browse(cr, uid, ids)[0]
assert addre_id.partner_id
assert addre_id.id
assert addre_id.type
- |
I click on "Confirm" button of this wizard.
-
!python {model: membership.invoice}: |
self.membership_invoice(cr, uid, [ref("membership_invoice_0")], {"active_ids": [ref("membership.res_partner_markjohnson0")]})
- |
I check that Invoice is created for this members.
-
!python {model: res.partner}: |
invoice_obj = self.pool.get('account.invoice')
partner_obj = self.pool.get('res.partner')
product_obj = self.pool.get('product.product')
invoice_line_obj = self.pool.get(('account.invoice.line'))
partner_id = self.browse(cr, uid, [ref('res_partner_markjohnson0')])[0]
ids = invoice_obj.search(cr, uid, [('partner_id', '=', partner_id.id), ('account_id', '=', partner_id.property_account_receivable.id)])
invoice_id = invoice_obj.browse(cr, uid, ids)[0]
product = product_obj.browse(cr, uid, [ref('product_product_membershipproduct0')], context=context)[0]
line_ids = invoice_line_obj.search(cr, uid, [('product_id', '=', product.id), ('invoice_id', '=', invoice_id.id)])
line_id = invoice_line_obj.browse(cr, uid, line_ids)[0]
assert line_id.product_id.id == product.id
assert invoice_id.partner_id.id == partner_id.id
- |
I check that the "Current membership state" will remain same untill opening the invoice.
-
!assert {model: res.partner, id: res_partner_markjohnson0}:
- membership_state == 'free'
- |
"Current membership state" of any member depends on the state of invoice.
So, I check that invoice is in draft state then the "membership state" of a member is "Waiting member".
-
!python {model: membership.membership_line}: |
partner_id = self.pool.get('res.partner').browse(cr, uid, [ref('res_partner_markjohnson0')])[0]
ids = self.search(cr, uid, [('partner', '=', partner_id.id)])
current_id = self.browse(cr, uid, ids)[0]
partner_obj = self.pool.get('res.partner')
inv_obj = self.pool.get('account.invoice')
ids = inv_obj.search(cr, uid, [('partner_id', '=', partner_id.id), ('account_id', '=', partner_id.property_account_receivable.id)])
inv_id = inv_obj.browse(cr, uid, ids)[0]
if inv_id.state == 'draft':
assert current_id == 'waiting'
- |
When the invoice is in open state it become Invoiced Member, When the invoice is in paid state the same "Current membership state" changed to Paid Member.
Now, If we cancel the invoice "Current membership state" changed to Cancel Member.

View File

@ -12,7 +12,7 @@
<field name="product_id" context="{'product':membership_product}" domain="[('membership','=',True)]"/> <field name="product_id" context="{'product':membership_product}" domain="[('membership','=',True)]"/>
</group> </group>
<group colspan="4" col="6"> <group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="Cancel"/> <button icon="gtk-close" special="cancel" string="Close"/>
<button icon="gtk-ok" string="Confirm" name="membership_invoice" type="object"/> <button icon="gtk-ok" string="Confirm" name="membership_invoice" type="object"/>
</group> </group>
</form> </form>

View File

@ -29,7 +29,7 @@ class member_unpaid_invoice(osv.osv_memory):
'product': fields.many2one('product.product','Membership product', size=64,required=True, help='Select Membership product'), 'product': fields.many2one('product.product','Membership product', size=64,required=True, help='Select Membership product'),
} }
def _invoice_membership(self, cr, uid, ids, context): def invoice_membership(self, cr, uid, ids, context):
model_obj = self.pool.get('ir.model.data') model_obj = self.pool.get('ir.model.data')
partners = [] partners = []
result = model_obj._get_id(cr, uid, 'base', 'view_res_partner_filter') result = model_obj._get_id(cr, uid, 'base', 'view_res_partner_filter')
@ -56,4 +56,4 @@ class member_unpaid_invoice(osv.osv_memory):
member_unpaid_invoice() member_unpaid_invoice()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -12,8 +12,8 @@
<field name="product" context="{'product':membership_product}" domain="[('membership','=',True)]"/> <field name="product" context="{'product':membership_product}" domain="[('membership','=',True)]"/>
</group> </group>
<group colspan="4" col="6"> <group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="Cancel"/> <button icon="gtk-close" special="cancel" string="Close"/>
<button icon="gtk-ok" string="Unpaid Partners" name="_invoice_membership" type="object"/> <button icon="gtk-ok" string="Unpaid Partners" name="invoice_membership" type="object"/>
</group> </group>
</form> </form>
</field> </field>

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0_rc3\n" "Project-Id-Version: OpenERP Server 5.0.0_rc3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2010-03-21 19:25+0000\n" "PO-Revision-Date: 2010-06-27 21:00+0000\n"
"Last-Translator: Jonay <jonay.santana@gmail.com>\n" "Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-22 04:09+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: product #. module: product
@ -192,7 +192,7 @@ msgstr "Tipos de precios"
#. module: product #. module: product
#: selection:product.template,type:0 #: selection:product.template,type:0
msgid "Stockable Product" msgid "Stockable Product"
msgstr "Producto almacenable" msgstr "Almacenable"
#. module: product #. module: product
#: model:product.category,name:product.product_category_services #: model:product.category,name:product.product_category_services
@ -226,7 +226,7 @@ msgstr "Nombre de este tipo de precio."
#. module: product #. module: product
#: help:product.pricelist.version,date_start:0 #: help:product.pricelist.version,date_start:0
msgid "Starting date for this pricelist version to be valid." msgid "Starting date for this pricelist version to be valid."
msgstr "Fecha inicial de esta versión de tarifa para ser válida." msgstr "Fecha inicial de validez para esta versión de tarifa."
#. module: product #. module: product
#: field:product.product,incoming_qty:0 #: field:product.product,incoming_qty:0
@ -256,7 +256,7 @@ msgid ""
"type. Purchase will trigger purchase orders when requested." "type. Purchase will trigger purchase orders when requested."
msgstr "" msgstr ""
"Producir generará órdenes de producción o tareas, de acuerdo al tipo de " "Producir generará órdenes de producción o tareas, de acuerdo al tipo de "
"producto. Comprar disparará pedidos de compras cuando sea necesario." "producto. Comprar generará pedidos de compras cuando sea necesario."
#. module: product #. module: product
#: model:process.transition,note:product.process_transition_supplierofproduct0 #: model:process.transition,note:product.process_transition_supplierofproduct0
@ -1534,7 +1534,7 @@ msgstr "Obtener bajo pedido"
#. module: product #. module: product
#: field:product.pricelist.item,price_surcharge:0 #: field:product.pricelist.item,price_surcharge:0
msgid "Price Surcharge" msgid "Price Surcharge"
msgstr "Sobrecarga precio" msgstr "Recargo precio"
#. module: product #. module: product
#: constraint:product.pricelist.version:0 #: constraint:product.pricelist.version:0

View File

@ -48,35 +48,25 @@ class product_uom(osv.osv):
_name = 'product.uom' _name = 'product.uom'
_description = 'Product Unit of Measure' _description = 'Product Unit of Measure'
def _factor(self, cursor, user, ids, name, arg, context): def _factor_inv(self, cursor, user, ids, name, arg, context):
res = {} res = {}
for uom in self.browse(cursor, user, ids, context=context): for uom in self.browse(cursor, user, ids, context=context):
if uom.factor: if uom.factor:
if uom.factor_inv_data: res[uom.id] = round(1 / uom.factor, 6)
res[uom.id] = uom.factor_inv_data
else:
res[uom.id] = round(1 / uom.factor, 6)
else: else:
res[uom.id] = 0.0 res[uom.id] = 0.0
return res return res
def _factor_inv(self, cursor, user, id, name, value, arg, context): def _factor_inv_write(self, cursor, user, id, name, value, arg, context):
ctx = context.copy()
if 'read_delta' in ctx:
del ctx['read_delta']
if value: if value:
data = 0.0
if round(1 / round(1/value, 6), 6) != value:
data = value
self.write(cursor, user, id, { self.write(cursor, user, id, {
'factor': round(1/value, 6), 'factor': round(1/value, 6),
'factor_inv_data': data, }, context=context)
}, context=ctx)
else: else:
self.write(cursor, user, id, { self.write(cursor, user, id, {
'factor': 0.0, 'factor': 0.0,
'factor_inv_data': 0.0, }, context=context)
}, context=ctx) return True
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True, translate=True), 'name': fields.char('Name', size=64, required=True, translate=True),
@ -85,17 +75,17 @@ class product_uom(osv.osv):
'factor': fields.float('Ratio', digits=(12, 6), required=True, 'factor': fields.float('Ratio', digits=(12, 6), required=True,
help='The coefficient for the formula:\n' \ help='The coefficient for the formula:\n' \
'1 (base unit) = coeff (this unit). Ratio = 1 / Factor.'), '1 (base unit) = coeff (this unit). Ratio = 1 / Factor.'),
'factor_inv': fields.function(_factor, digits=(12, 6), 'factor_inv': fields.function(_factor_inv, digits=(12, 6),
method=True, string='Factor', fnct_inv=_factor_inv_write,
method=True, string='Ratio',
help='The coefficient for the formula:\n' \ help='The coefficient for the formula:\n' \
'coeff (base unit) = 1 (this unit). Factor = 1 / Rate.'), 'coeff (base unit) = 1 (this unit). Factor = 1 / Rate.'),
'factor_inv_data': fields.float('Factor', digits=(12, 6)),
'rounding': fields.float('Rounding Precision', digits=(16, 3), required=True, 'rounding': fields.float('Rounding Precision', digits=(16, 3), required=True,
help="The computed quantity will be a multiple of this value. Use 1.0 for products that can not be split."), help="The computed quantity will be a multiple of this value. Use 1.0 for products that can not be split."),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the unit of measure without removing it."), 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the unit of measure without removing it."),
'uom_factor': fields.selection([('bigger','Bigger than the Default'), 'uom_factor': fields.selection([('bigger','Bigger than the default'),
('smaller','Smaller than the Default'), ('smaller','Smaller than the default'),
('','')],'UoM Factor'), ('default','Default UoM for the category')],'Type of Unit', required=1),
} }
_defaults = { _defaults = {
@ -103,12 +93,11 @@ class product_uom(osv.osv):
'factor_inv': lambda *a: 1.0, 'factor_inv': lambda *a: 1.0,
'active': lambda *a: 1, 'active': lambda *a: 1,
'rounding': lambda *a: 0.01, 'rounding': lambda *a: 0.01,
'uom_factor': lambda *a: 'smaller', 'uom_factor': lambda *a: 'default',
} }
_sql_constraints = [ _sql_constraints = [
('factor_gt_zero', 'CHECK (factor!=0)', 'Value of the factor can never be 0 !'), ('factor_gt_zero', 'CHECK (factor!=0)', 'Value of the factor can never be 0 !'),
('factor_inv_data_gt_zero', 'CHECK (factor_inv_data!=0)', 'Value of the factor_inv_data can never be 0 !'),
] ]
def _compute_qty(self, cr, uid, from_uom_id, qty, to_uom_id=False): def _compute_qty(self, cr, uid, from_uom_id, qty, to_uom_id=False):
@ -124,15 +113,9 @@ class product_uom(osv.osv):
def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, context={}): def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, context={}):
if from_unit.category_id.id <> to_unit.category_id.id: if from_unit.category_id.id <> to_unit.category_id.id:
return qty return qty
if from_unit.factor_inv_data: amount = qty / from_unit.factor
amount = qty * from_unit.factor_inv_data
else:
amount = qty / from_unit.factor
if to_unit: if to_unit:
if to_unit.factor_inv_data: amount = rounding(amount * to_unit.factor, to_unit.rounding)
amount = rounding(amount / to_unit.factor_inv_data, to_unit.rounding)
else:
amount = rounding(amount * to_unit.factor, to_unit.rounding)
return amount return amount
def _compute_price(self, cr, uid, from_uom_id, price, to_uom_id=False): def _compute_price(self, cr, uid, from_uom_id, price, to_uom_id=False):
@ -145,26 +128,15 @@ class product_uom(osv.osv):
from_unit, to_unit = uoms[-1], uoms[0] from_unit, to_unit = uoms[-1], uoms[0]
if from_unit.category_id.id <> to_unit.category_id.id: if from_unit.category_id.id <> to_unit.category_id.id:
return price return price
if from_unit.factor_inv_data: amount = price * from_unit.factor
amount = price / from_unit.factor_inv_data
else:
amount = price * from_unit.factor
if to_uom_id: if to_uom_id:
if to_unit.factor_inv_data: amount = amount / to_unit.factor
amount = amount * to_unit.factor_inv_data
else:
amount = amount / to_unit.factor
return amount return amount
def onchange_factor_inv(self, cursor, user, ids, value):
if value == 0.0:
return {'value': {'factor': 0}}
return {'value': {'factor': round(1/value, 6)}}
def onchange_factor(self, cursor, user, ids, value): def onchange_factor(self, cursor, user, ids, value):
if value == 0.0: if value == 'default':
return {'value': {'factor_inv': 0}} return {'value': {'factor': 1, 'factor_inv': 1}}
return {'value': {'factor_inv': round(1/value, 6)}} return {}
product_uom() product_uom()

View File

@ -30,7 +30,7 @@
<record id="product_uom_kgm" model="product.uom"> <record id="product_uom_kgm" model="product.uom">
<field name="category_id" ref="product_uom_categ_kgm"/> <field name="category_id" ref="product_uom_categ_kgm"/>
<field name="name">KGM</field> <field name="name">KGM</field>
<field name="factor">1000.0</field> <field name="factor">1</field>
</record> </record>
<record id="uom_hour" model="product.uom"> <record id="uom_hour" model="product.uom">
<field name="name">Hour</field> <field name="name">Hour</field>
@ -45,7 +45,7 @@
<record id="product_uom_ton" model="product.uom"> <record id="product_uom_ton" model="product.uom">
<field name="category_id" ref="product_uom_categ_kgm"/> <field name="category_id" ref="product_uom_categ_kgm"/>
<field name="name">TON</field> <field name="name">TON</field>
<field name="factor">1.0</field> <field name="factor">0.001</field>
</record> </record>
<record id="product_uom_meter" model="product.uom"> <record id="product_uom_meter" model="product.uom">
<field name="category_id" ref="uom_categ_length"/> <field name="category_id" ref="uom_categ_length"/>

View File

@ -298,7 +298,6 @@
<field name="name"/> <field name="name"/>
<field name="category_id"/> <field name="category_id"/>
<field name="factor"/> <field name="factor"/>
<field name="factor_inv"/>
<field name="rounding"/> <field name="rounding"/>
</tree> </tree>
</field> </field>
@ -310,14 +309,18 @@
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Units of Measure"> <form string="Units of Measure">
<field name="name" select="1"/> <group col="6" colspan="4">
<field name="category_id" select="1"/> <field name="name" select="1"/>
<field name="factor" select="1" attrs="{'readonly':[('uom_factor','=','bigger')]}"/> <field name="category_id" select="1" widget="selection"/>
<field name="factor_inv_data" select="1" string="Factor Data" attrs="{'readonly':[('uom_factor','=','smaller')]}"/> <field name="active"/>
<field name="factor_inv" invisible="1"/> <field name="uom_factor" on_change="onchange_factor(uom_factor)"/>
<field name="rounding"/> <group colspan="2" col="2">
<field name="uom_factor"/> <field name="factor" attrs="{'invisible':[('uom_factor','&lt;&gt;','smaller')]}"/>
<field name="active"/> <field name="factor_inv" string="Factor Data" attrs="{'invisible':[('uom_factor','&lt;&gt;','bigger')]}"/>
</group>
<newline/>
<field name="rounding"/>
</group>
</form> </form>
</field> </field>
</record> </record>

View File

@ -8,19 +8,19 @@ msgstr ""
"Project-Id-Version: openobject-addons\n" "Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-06-30 15:09+0000\n" "POT-Creation-Date: 2009-06-30 15:09+0000\n"
"PO-Revision-Date: 2010-04-29 04:43+0000\n" "PO-Revision-Date: 2010-06-27 22:08+0000\n"
"Last-Translator: Rhubeni Lopes de Andrade <rhube.itsasecret@gmail.com>\n" "Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\n"
"Language-Team: Spanish <es@li.org>\n" "Language-Team: Spanish <es@li.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-04-30 03:57+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: product_expiry #. module: product_expiry
#: field:product.product,life_time:0 #: field:product.product,life_time:0
msgid "Product lifetime" msgid "Product lifetime"
msgstr "Ciclo de vida producto" msgstr "Ciclo de vida del producto"
#. module: product_expiry #. module: product_expiry
#: model:product.template,name:product_expiry.product_product_from_product_template #: model:product.template,name:product_expiry.product_product_from_product_template
@ -54,11 +54,13 @@ msgstr "¡XML no válido para la definición de la vista!"
#: help:stock.production.lot,life_date:0 #: help:stock.production.lot,life_date:0
msgid "The date the lot may become dangerous and should not be consumed." msgid "The date the lot may become dangerous and should not be consumed."
msgstr "" msgstr ""
"Fecha en la que el producto puede llegar a ser peligroso y no debería ser "
"consumido."
#. module: product_expiry #. module: product_expiry
#: field:stock.production.lot,removal_date:0 #: field:stock.production.lot,removal_date:0
msgid "Removal Date" msgid "Removal Date"
msgstr "" msgstr "Fecha de eliminación"
#. module: product_expiry #. module: product_expiry
#: model:ir.module.module,description:product_expiry.module_meta_information #: model:ir.module.module,description:product_expiry.module_meta_information
@ -70,6 +72,12 @@ msgid ""
" - alert date\n" " - alert date\n"
"Used, for example, in food industries." "Used, for example, in food industries."
msgstr "" msgstr ""
"Gestionar diferentes fechas en productos y lotes de producción:\n"
" - fin de vida\n"
" - fecha de caducidad\n"
" - fecha de retirada\n"
" - fecha de alerta\n"
"Usados, por ejemplo, en la industria alimentaria."
#. module: product_expiry #. module: product_expiry
#: model:product.template,name:product_expiry.product_product_pain_product_template #: model:product.template,name:product_expiry.product_product_pain_product_template
@ -96,17 +104,19 @@ msgstr "Error: La UdV debe estar en una categoría diferente que la UdM."
#. module: product_expiry #. module: product_expiry
#: field:stock.production.lot,life_date:0 #: field:stock.production.lot,life_date:0
msgid "End of Life Date" msgid "End of Life Date"
msgstr "" msgstr "Fecha de fin de vida"
#. module: product_expiry #. module: product_expiry
#: field:stock.production.lot,use_date:0 #: field:stock.production.lot,use_date:0
msgid "Best before Date" msgid "Best before Date"
msgstr "" msgstr "Fecha caducidad"
#. module: product_expiry #. module: product_expiry
#: help:stock.production.lot,use_date:0 #: help:stock.production.lot,use_date:0
msgid "The date the lot starts deteriorating without becoming dangerous." msgid "The date the lot starts deteriorating without becoming dangerous."
msgstr "" msgstr ""
"Fecha en la que el producto empieza a deteriorarse sin llegar a ser "
"peligroso."
#. module: product_expiry #. module: product_expiry
#: model:product.template,name:product_expiry.product_product_jambon_product_template #: model:product.template,name:product_expiry.product_product_jambon_product_template
@ -116,7 +126,7 @@ msgstr "Queso Camembert francés"
#. module: product_expiry #. module: product_expiry
#: help:product.product,removal_time:0 #: help:product.product,removal_time:0
msgid "The number of days before a production lot should be removed." msgid "The number of days before a production lot should be removed."
msgstr "" msgstr "Número de días antes de que un lote de producción deba ser retirado."
#. module: product_expiry #. module: product_expiry
#: field:product.product,use_time:0 #: field:product.product,use_time:0
@ -126,7 +136,7 @@ msgstr "Tiempo de uso producto"
#. module: product_expiry #. module: product_expiry
#: field:stock.production.lot,alert_date:0 #: field:stock.production.lot,alert_date:0
msgid "Alert Date" msgid "Alert Date"
msgstr "" msgstr "Fecha de alerta"
#. module: product_expiry #. module: product_expiry
#: field:product.product,removal_time:0 #: field:product.product,removal_time:0
@ -139,6 +149,8 @@ msgid ""
"The number of days before a production lot starts deteriorating without " "The number of days before a production lot starts deteriorating without "
"becoming dangerous." "becoming dangerous."
msgstr "" msgstr ""
"Número de días antes de que un producto empieza a deteriorarse sin llegar a "
"ser peligroso."
#. module: product_expiry #. module: product_expiry
#: constraint:product.product:0 #: constraint:product.product:0
@ -151,30 +163,15 @@ msgid ""
"The number of days before a production lot may become dangerous and should " "The number of days before a production lot may become dangerous and should "
"not be consumed." "not be consumed."
msgstr "" msgstr ""
"Número de días antes de que un producto pueda llegar a ser peligroso y no "
"debe ser consumido."
#. module: product_expiry #. module: product_expiry
#: help:stock.production.lot,removal_date:0 #: help:stock.production.lot,removal_date:0
msgid "The date the lot should be removed." msgid "The date the lot should be removed."
msgstr "" msgstr "Fecha en la que el producto debería ser eliminado."
#. module: product_expiry #. module: product_expiry
#: field:product.product,alert_time:0 #: field:product.product,alert_time:0
msgid "Product alert time" msgid "Product alert time"
msgstr "Fecha alerta producto" msgstr "Fecha alerta producto"
#~ msgid "Alert date"
#~ msgstr "Fecha alarma"
#~ msgid ""
#~ "Track different dates on products and lots. Used, for exampel, in food "
#~ "industries: expiry date, alert date, date of removal, eso."
#~ msgstr ""
#~ "Gestiona distintas fechas para productos y lotes. Utilizado, por ejemplo, en "
#~ "industria alimentaria: Fecha de caducidad, fecha de alarma, fecha de "
#~ "eliminación, ..."
#~ msgid "DLUO"
#~ msgstr "Fecha caducidad"
#~ msgid "Removal date"
#~ msgstr "Fecha eliminación"

View File

@ -0,0 +1,108 @@
# Spanish translation for openobject-addons
# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-11-25 13:27+0000\n"
"PO-Revision-Date: 2010-06-27 21:56+0000\n"
"Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\n"
"Language-Team: Spanish <es@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: product_electronic
#: model:ir.module.module,description:product_electronic.module_meta_information
msgid "A module that add manufacturers and attributes on the product form"
msgstr ""
"Un módulo que añade fabricantes y atributos en el formulario de producto"
#. module: product_electronic
#: field:product.product,manufacturer_pref:0
msgid "Manufacturer product code"
msgstr "Código de producto del fabricante"
#. module: product_electronic
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
msgstr "¡XML inválido para la estructura de la vista!"
#. module: product_electronic
#: view:product.electronic.attribute:0
msgid "Product Template Name"
msgstr "Nombre de plantilla de producto"
#. module: product_electronic
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
msgstr ""
"¡El nombre del objeto debe empezar con x_ y no puede contener ningún "
"carácter especial!"
#. module: product_electronic
#: model:ir.model,name:product_electronic.model_product_electronic_attribute
msgid "Product attributes"
msgstr "Atributos de producto"
#. module: product_electronic
#: view:product.product:0
msgid "Manufacturing data"
msgstr "Datos de fabricación"
#. module: product_electronic
#: view:product.product:0
msgid "Product reference"
msgstr "Referencia del producto"
#. module: product_electronic
#: field:product.electronic.attribute,name:0
msgid "Attribute"
msgstr "Atributo"
#. module: product_electronic
#: field:product.electronic.attribute,product_id:0
msgid "Product"
msgstr "Producto"
#. module: product_electronic
#: field:product.electronic.attribute,value:0
msgid "Value"
msgstr "Valor"
#. module: product_electronic
#: view:product.product:0
msgid "Manufacturing Data"
msgstr "Datos de fabricación"
#. module: product_electronic
#: view:product.product:0
msgid "Product name"
msgstr "Nombre del producto"
#. module: product_electronic
#: view:product.product:0
#: field:product.product,attribute_ids:0
msgid "Attributes"
msgstr "Atributos"
#. module: product_electronic
#: model:ir.module.module,shortdesc:product_electronic.module_meta_information
msgid "Products Attributes & Manufacturers"
msgstr "Fabricantes y atributos de los productos"
#. module: product_electronic
#: field:product.product,manufacturer_pname:0
msgid "Manufacturer product name"
msgstr "Nombre del fabricante del producto"
#. module: product_electronic
#: field:product.product,manufacturer:0
msgid "Manufacturer"
msgstr "Fabricante"

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n" "Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2010-03-20 09:47+0000\n" "PO-Revision-Date: 2010-06-27 22:23+0000\n"
"Last-Translator: Black Jack <onetimespeed@hotmail.com>\n" "Last-Translator: Fan.Khiyon <Unknown>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-22 04:13+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: project_gtd #. module: project_gtd
@ -30,7 +30,7 @@ msgstr "对象名必须以x_开头并且不能包含特殊字符"
#. module: project_gtd #. module: project_gtd
#: model:ir.model,name:project_gtd.model_project_gtd_timebox #: model:ir.model,name:project_gtd.model_project_gtd_timebox
msgid "project.gtd.timebox" msgid "project.gtd.timebox"
msgstr "" msgstr "project.gtd.timebox"
#. module: project_gtd #. module: project_gtd
#: model:ir.actions.act_window,name:project_gtd.act_timebox_tasks_my_deadline_open #: model:ir.actions.act_window,name:project_gtd.act_timebox_tasks_my_deadline_open

View File

@ -7,16 +7,16 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n" "Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2009-01-30 12:44+0000\n" "PO-Revision-Date: 2010-06-27 14:09+0000\n"
"Last-Translator: <>\n" "Last-Translator: Rossi Liu <Unknown>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-22 04:19+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: project_retro_planning #. module: project_retro_planning
#: model:ir.module.module,shortdesc:project_retro_planning.module_meta_information #: model:ir.module.module,shortdesc:project_retro_planning.module_meta_information
msgid "Project Retro planning" msgid "Project Retro planning"
msgstr "" msgstr "舊有的規劃項目"

View File

@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-26 03:57+0000\n" "X-Launchpad-Export-Date: 2010-06-27 03:47+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n" "X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n" "X-Poedit-Language: Greek\n"

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n" "Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2010-03-20 19:39+0000\n" "PO-Revision-Date: 2010-06-27 20:58+0000\n"
"Last-Translator: Jonay <jonay.santana@gmail.com>\n" "Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-22 03:57+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: purchase #. module: purchase
@ -681,7 +681,7 @@ msgstr "Posición fiscal"
#. module: purchase #. module: purchase
#: rml:purchase.order:0 #: rml:purchase.order:0
msgid "Request for Quotation N°" msgid "Request for Quotation N°"
msgstr "" msgstr "Petición de presupuesto Nº"
#. module: purchase #. module: purchase
#: field:purchase.order,invoice_id:0 #: field:purchase.order,invoice_id:0

View File

@ -98,6 +98,7 @@ class sale_order(osv.osv):
res[order.id]['amount_total'] = res[order.id]['amount_untaxed'] + res[order.id]['amount_tax'] res[order.id]['amount_total'] = res[order.id]['amount_untaxed'] + res[order.id]['amount_tax']
return res return res
# This is False
def _picked_rate(self, cr, uid, ids, name, arg, context=None): def _picked_rate(self, cr, uid, ids, name, arg, context=None):
if context is None: if context is None:
context = {} context = {}
@ -1026,6 +1027,7 @@ class sale_order_line(osv.osv):
} }
result['product_uom_qty'] = qty result['product_uom_qty'] = qty
uom2 = False
if uom: if uom:
uom2 = product_uom_obj.browse(cr, uid, uom) uom2 = product_uom_obj.browse(cr, uid, uom)
if product_obj.uom_id.category_id.id != uom2.category_id.id: if product_obj.uom_id.category_id.id != uom2.category_id.id:
@ -1081,6 +1083,19 @@ class sale_order_line(osv.osv):
result['product_uos_qty'] = qty result['product_uos_qty'] = qty
result['th_weight'] = q * product_obj.weight # Round the quantity up result['th_weight'] = q * product_obj.weight # Round the quantity up
if not uom2:
uom2 = product_obj.uom_id
if (product_obj.type=='product') and (product_obj.virtual_available * uom2.factor < qty * product_obj.uom_id.factor) \
and (product_obj.procure_method=='make_to_stock'):
warning = {
'title': _('Not enough stock !'),
'message': _('You plan to sell %.2f %s but you only have %.2f %s available !\nThe real stock is %.2f %s. (without reservations)') %
(qty, uom2 and uom2.name or product_obj.uom_id.name,
max(0,product_obj.virtual_available), product_obj.uom_id.name,
max(0,product_obj.qty_available), product_obj.uom_id.name)
}
# get unit price # get unit price
if not pricelist: if not pricelist:

View File

@ -134,7 +134,7 @@
<field colspan="4" <field colspan="4"
context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom" context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom"
name="product_id" name="product_id"
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], True, parent.date_order, product_packaging, parent.fiscal_position)" on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], True, parent.date_order, product_packaging, parent.fiscal_position, False)"
/> />
<field <field
context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom" context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom"
@ -147,7 +147,7 @@
<field <field
name="product_packaging" name="product_packaging"
context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom" context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom"
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], False, parent.date_order, product_packaging, parent.fiscal_position)" on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], False, parent.date_order, product_packaging, parent.fiscal_position, False)"
domain="[('product_id','=',product_id)]" domain="[('product_id','=',product_id)]"
groups="base.group_extended"/> groups="base.group_extended"/>

View File

@ -7,26 +7,26 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n" "Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2009-01-30 13:19+0000\n" "PO-Revision-Date: 2010-06-27 14:29+0000\n"
"Last-Translator: <>\n" "Last-Translator: Rossi Liu <Unknown>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-22 04:16+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: sale_analytic_plans #. module: sale_analytic_plans
#: field:sale.order.line,analytics_id:0 #: field:sale.order.line,analytics_id:0
msgid "Analytic Distribution" msgid "Analytic Distribution"
msgstr "" msgstr "分佈分析"
#. module: sale_analytic_plans #. module: sale_analytic_plans
#: constraint:ir.ui.view:0 #: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!" msgid "Invalid XML for View Architecture!"
msgstr "" msgstr "無效的XML視圖結構!"
#. module: sale_analytic_plans #. module: sale_analytic_plans
#: model:ir.module.module,shortdesc:sale_analytic_plans.module_meta_information #: model:ir.module.module,shortdesc:sale_analytic_plans.module_meta_information
msgid "Sales Analytic Distribution Management" msgid "Sales Analytic Distribution Management"
msgstr "" msgstr "銷售分佈分析管理"

View File

@ -7,14 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n" "Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2009-11-17 10:39+0000\n" "PO-Revision-Date: 2010-06-27 22:12+0000\n"
"Last-Translator: Jordi Esteve (www.zikzakmedia.com) " "Last-Translator: Borja López Soilán (Pexego) <borjals@pexego.es>\n"
"<jesteve@zikzakmedia.com>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-22 04:10+0000\n" "X-Launchpad-Export-Date: 2010-06-28 03:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#. module: sale_journal #. module: sale_journal
@ -315,7 +314,7 @@ msgstr "Activo"
#. module: sale_journal #. module: sale_journal
#: model:ir.actions.act_window,name:sale_journal.act_sale_journal_sale_journal_2_sale_order_draft #: model:ir.actions.act_window,name:sale_journal.act_sale_journal_sale_journal_2_sale_order_draft
msgid "Draft sales" msgid "Draft sales"
msgstr "Borrador de ventas" msgstr "Ventas borrador"
#. module: sale_journal #. module: sale_journal
#: selection:sale_journal.sale.stats,state:0 #: selection:sale_journal.sale.stats,state:0
@ -335,7 +334,7 @@ msgstr "diario_venta.factura.tipo.árbol"
#. module: sale_journal #. module: sale_journal
#: view:sale_journal.sale.journal:0 #: view:sale_journal.sale.journal:0
msgid "Confirm Sales" msgid "Confirm Sales"
msgstr "Confirmar las ventas" msgstr "Confirmar ventas"
#. module: sale_journal #. module: sale_journal
#: field:sale_journal.picking.journal,date_created:0 #: field:sale_journal.picking.journal,date_created:0
@ -383,7 +382,7 @@ msgstr "Realizado"
#. module: sale_journal #. module: sale_journal
#: selection:sale_journal.sale.stats,state:0 #: selection:sale_journal.sale.stats,state:0
msgid "Cancel" msgid "Cancel"
msgstr "Cancelar" msgstr "Cancelado"
#. module: sale_journal #. module: sale_journal
#: field:sale_journal.picking.journal,picking_stats_ids:0 #: field:sale_journal.picking.journal,picking_stats_ids:0

View File

@ -408,7 +408,7 @@ stock_location()
class stock_tracking(osv.osv): class stock_tracking(osv.osv):
_name = "stock.tracking" _name = "stock.tracking"
_description = "Stock Tracking Lots" _description = "Packs"
def checksum(sscc): def checksum(sscc):
salt = '31' * 8 + '3' salt = '31' * 8 + '3'
@ -424,7 +424,7 @@ class stock_tracking(osv.osv):
_columns = { _columns = {
'name': fields.char('Tracking ID', size=64, required=True), 'name': fields.char('Tracking ID', size=64, required=True),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the tracking lots without removing it."), 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the pack without removing it."),
'serial': fields.char('Reference', size=64), 'serial': fields.char('Reference', size=64),
'move_ids': fields.one2many('stock.move', 'tracking_id', 'Moves Tracked'), 'move_ids': fields.one2many('stock.move', 'tracking_id', 'Moves Tracked'),
'date': fields.datetime('Created Date', required=True), 'date': fields.datetime('Created Date', required=True),
@ -1310,7 +1310,7 @@ class stock_move(osv.osv):
return (res and res[0]) or False return (res and res[0]) or False
_name = "stock.move" _name = "stock.move"
_description = "Stock Move" _description = "Stock Move"
_order = 'date_planned desc' _order = 'date_expected desc, id'
_log_create = False _log_create = False
def name_get(self, cr, uid, ids, context={}): def name_get(self, cr, uid, ids, context={}):
@ -1364,7 +1364,7 @@ class stock_move(osv.osv):
'address_id': fields.many2one('res.partner.address', 'Dest. Address', help="Address where goods are to be delivered"), 'address_id': fields.many2one('res.partner.address', 'Dest. Address', help="Address where goods are to be delivered"),
'prodlot_id': fields.many2one('stock.production.lot', 'Production Lot', help="Production lot is used to put a serial number on the production"), 'prodlot_id': fields.many2one('stock.production.lot', 'Production Lot', help="Production lot is used to put a serial number on the production"),
'tracking_id': fields.many2one('stock.tracking', 'Tracking Lot', select=True, help="Tracking lot is the code that will be put on the logistical unit/pallet"), 'tracking_id': fields.many2one('stock.tracking', 'Pack', select=True, help="This is the code that will be put on the logistical unit: pallet, box, pack."),
# 'lot_id': fields.many2one('stock.lot', 'Consumer lot', select=True, readonly=True), # 'lot_id': fields.many2one('stock.lot', 'Consumer lot', select=True, readonly=True),
'auto_validate': fields.boolean('Auto Validate'), 'auto_validate': fields.boolean('Auto Validate'),

View File

@ -61,11 +61,11 @@
Sequences from tracking numbers Sequences from tracking numbers
--> -->
<record id="sequence_type_serial" model="ir.sequence.type"> <record id="sequence_type_serial" model="ir.sequence.type">
<field name="name">Stock Production Lots</field> <field name="name">Production Lots</field>
<field name="code">stock.lot.serial</field> <field name="code">stock.lot.serial</field>
</record> </record>
<record id="sequence_production_lots" model="ir.sequence"> <record id="sequence_production_lots" model="ir.sequence">
<field name="name">Stock Production Lots</field> <field name="name">Production Lots</field>
<field name="code">stock.lot.serial</field> <field name="code">stock.lot.serial</field>
<field name="prefix"></field> <field name="prefix"></field>
<field name="padding">7</field> <field name="padding">7</field>
@ -74,12 +74,12 @@
</record> </record>
<record id="sequence_type_tracking" model="ir.sequence.type"> <record id="sequence_type_tracking" model="ir.sequence.type">
<field name="name">Stock Tracking Lots</field> <field name="name">Packs</field>
<field name="code">stock.lot.tracking</field> <field name="code">stock.lot.tracking</field>
</record> </record>
<record id="sequence_tracking" model="ir.sequence"> <record id="sequence_tracking" model="ir.sequence">
<field name="name">Stock Tracking Lots</field> <field name="name">Packs</field>
<field name="code">stock.lot.tracking</field> <field name="code">stock.lot.tracking</field>
<field name="prefix"></field> <field name="prefix"></field>
<field name="padding">7</field> <field name="padding">7</field>

View File

@ -154,7 +154,7 @@
<field name="model">stock.tracking</field> <field name="model">stock.tracking</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Tracking/Serial"> <form string="Packs">
<field name="name" select="1"/> <field name="name" select="1"/>
<field name="serial" select="1"/> <field name="serial" select="1"/>
<field name="date" select="1"/> <field name="date" select="1"/>
@ -167,7 +167,7 @@
<field name="model">stock.tracking</field> <field name="model">stock.tracking</field>
<field name="type">tree</field> <field name="type">tree</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Tracking/Serial"> <tree string="Packs">
<field name="name"/> <field name="name"/>
<field name="serial"/> <field name="serial"/>
<field name="date"/> <field name="date"/>
@ -176,7 +176,7 @@
</field> </field>
</record> </record>
<record id="action_tracking_form" model="ir.actions.act_window"> <record id="action_tracking_form" model="ir.actions.act_window">
<field name="name">Tracking Lots</field> <field name="name">Packs</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">stock.tracking</field> <field name="res_model">stock.tracking</field>
<field name="view_type">form</field> <field name="view_type">form</field>
@ -193,7 +193,7 @@
<field name="type">tree</field> <field name="type">tree</field>
<field name="field_parent">child_ids</field> <field name="field_parent">child_ids</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree colors="grey:not active" string="Tracking Number"> <tree colors="grey:not active" string="Packs">
<field name="name" /> <field name="name" />
<field name="serial" /> <field name="serial" />
<field name="date" /> <field name="date" />
@ -640,15 +640,14 @@
type="action" icon="terp-stock_effects-object-colorize" type="action" icon="terp-stock_effects-object-colorize"
states="draft,waiting,confirmed,assigned" /> states="draft,waiting,confirmed,assigned" />
<field groups="base.group_extended" name="tracking_id"/> <field groups="base.group_extended" name="tracking_id"/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="setlast_tracking" string="Put in current pack" type="object"
attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
groups="base.group_extended"
icon="terp-stock_effects-object-colorize" icon="terp-stock_effects-object-colorize"
groups="base.group_extended"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<button name="setlast_tracking" string="Set Last Tracking" type="object" <button name="%(split_into)d" string="Put in a new pack" type="action"
attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
icon="terp-stock_effects-object-colorize"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<field name="location_id"/> <field name="location_id"/>
<field name="location_dest_id"/> <field name="location_dest_id"/>
@ -691,9 +690,8 @@
states="draft,waiting,confirmed,assigned" states="draft,waiting,confirmed,assigned"
type="action" icon="terp-stock_effects-object-colorize" type="action" icon="terp-stock_effects-object-colorize"
groups="base.group_extended" /> groups="base.group_extended" />
<button name="%(move_scrap)d" string="Scrap Move Line" type="action" icon="gtk-justify-fill"/> <button name="%(move_scrap)d" string="Scrap" type="action" icon="gtk-justify-fill"/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="%(split_into)d" string="Put in a new pack" type="action"
attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
states="draft,assigned,confirmed,done" states="draft,assigned,confirmed,done"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize" /> icon="terp-stock_effects-object-colorize" />
@ -807,15 +805,15 @@
<field name="picking_id" /> <field name="picking_id" />
<field name="prodlot_id" groups="base.group_extended"/> <field name="prodlot_id" groups="base.group_extended"/>
<field groups="base.group_extended" name="tracking_id"/> <field groups="base.group_extended" name="tracking_id"/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="setlast_tracking" string="Put in current pack" type="object"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
states="draft,assigned,confirmed,done"
groups="base.group_extended"/>
<button name="setlast_tracking" string="Set Last Tracking" type="object"
attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize" icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<button name="%(split_into)d" string="Put in a new pack" type="action"
icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"
groups="base.group_extended"/>
<field name="location_id"/> <field name="location_id"/>
<field name="location_dest_id"/> <field name="location_dest_id"/>
<field name="date_planned"/> <field name="date_planned"/>
@ -862,9 +860,8 @@
states="draft,waiting,confirmed,assigned" states="draft,waiting,confirmed,assigned"
type="action" icon="terp-stock_effects-object-colorize"/> type="action" icon="terp-stock_effects-object-colorize"/>
<label/> <label/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="%(split_into)d" string="Put in a new pack" type="action"
attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" groups="base.group_extended"
groups="base.group_extended"
icon="terp-stock_effects-object-colorize" icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<separator colspan="4" string="Move State"/> <separator colspan="4" string="Move State"/>
@ -1017,16 +1014,15 @@
states="draft,assigned,confirmed,done" states="draft,assigned,confirmed,done"
groups="base.group_extended"/> groups="base.group_extended"/>
<field name="tracking_id" groups="base.group_extended"/> <field name="tracking_id" groups="base.group_extended"/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="setlast_tracking" string="Put in current pack" type="object"
attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
groups="base.group_extended"
icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/>
<button name="%(split_into)d" string="Put in a new pack" type="action"
icon="terp-stock_effects-object-colorize" icon="terp-stock_effects-object-colorize"
groups="base.group_extended" groups="base.group_extended"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<button name="setlast_tracking" string="Set Last Tracking" type="object"
attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
groups="base.group_extended"
icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/>
<field name="location_id"/> <field name="location_id"/>
<field name="date_planned"/> <field name="date_planned"/>
<field name="state"/> <field name="state"/>
@ -1062,8 +1058,7 @@
groups="base.group_extended" groups="base.group_extended"
/> />
<label/> <label/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="%(split_into)d" string="Put in a new pack" type="action"
attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize" icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
@ -1085,7 +1080,7 @@
<button name="draft_validate" states="draft" string="Process Now" type="object" icon="gtk-yes"/> <button name="draft_validate" states="draft" string="Process Now" type="object" icon="gtk-yes"/>
<button name="action_assign" states="confirmed" string="Check Availability" type="object" groups="base.group_extended" icon="gtk-apply"/> <button name="action_assign" states="confirmed" string="Check Availability" type="object" groups="base.group_extended" icon="gtk-apply"/>
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/> <button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
<button name="%(action_partial_picking)d" states="assigned" string="Picking Done" type="action" icon="gtk-execute"/> <button name="%(action_partial_picking)d" states="assigned" string="Done" type="action" icon="gtk-execute"/>
<button name="button_cancel" states="assigned,confirmed,draft" string="Cancel" icon="gtk-cancel"/> <button name="button_cancel" states="assigned,confirmed,draft" string="Cancel" icon="gtk-cancel"/>
</group> </group>
</page> </page>
@ -1218,16 +1213,16 @@
type="action" icon="terp-stock_effects-object-colorize" type="action" icon="terp-stock_effects-object-colorize"
states="draft,waiting,confirmed,assigned" /> states="draft,waiting,confirmed,assigned" />
<field name="tracking_id" groups="base.group_extended"/> <field name="tracking_id" groups="base.group_extended"/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="setlast_tracking" string="Put in current pack" type="object"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<button name="setlast_tracking" string="Set Last Tracking" type="object" <button name="%(split_into)d" string="Put in a new pack" type="action"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<field name="state"/> <field name="state"/>
<button name="%(stock.move_scrap)d" <button name="%(stock.move_scrap)d"
string="Scrap Products" type="action" string="Scrap Products" type="action"
icon="gtk-convert" context="{'scrap': True}" icon="gtk-convert" context="{'scrap': True}"
states="draft,waiting,confirmed,assigned" /> states="draft,waiting,confirmed,assigned" />
@ -1408,13 +1403,13 @@
states="draft,waiting,confirmed,assigned" states="draft,waiting,confirmed,assigned"
groups="base.group_extended"/> groups="base.group_extended"/>
<field groups="base.group_extended" name="tracking_id"/> <field groups="base.group_extended" name="tracking_id"/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="setlast_tracking" string="Put in current pack" type="object"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<button name="setlast_tracking" string="Set Last Tracking" type="object" <button name="%(split_into)d" string="Put in a new pack" type="action"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<field name="location_id"/> <field name="location_id"/>
<field name="location_dest_id"/> <field name="location_dest_id"/>
@ -1479,9 +1474,9 @@
states="draft,waiting,confirmed,assigned" states="draft,waiting,confirmed,assigned"
string="Split in production lots" type="action" icon="terp-stock_effects-object-colorize" colspan="2" /> string="Split in production lots" type="action" icon="terp-stock_effects-object-colorize" colspan="2" />
<label/> <label/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="%(split_into)d" string="Put in a new pack" type="action"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
</group> </group>
</group> </group>
@ -1572,15 +1567,15 @@
context="{'default_use_exist': picking_id.type=='in'}" context="{'default_use_exist': picking_id.type=='in'}"
groups="base.group_extended"/> groups="base.group_extended"/>
<field name="tracking_id" groups="base.group_extended"/> <field name="tracking_id" groups="base.group_extended"/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="setlast_tracking" string="Put in current pack" type="object"
groups="base.group_extended"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
states="draft,assigned,confirmed,done"/>
<button name="setlast_tracking" string="Set Last Tracking" type="object"
attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize" icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<button name="%(split_into)d" string="Put in a new pack" type="action"
groups="base.group_extended"
icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/>
<field name="date_planned"/> <field name="date_planned"/>
<field name="backorder_id" groups="base.group_extended"/> <field name="backorder_id" groups="base.group_extended"/>
<field name="state"/> <field name="state"/>
@ -1628,9 +1623,9 @@
groups="base.group_extended" groups="base.group_extended"
type="action" icon="terp-stock_effects-object-colorize"/> type="action" icon="terp-stock_effects-object-colorize"/>
<label/> <label/>
<button name="%(split_into)d" string="Split Stock Moves" type="action" <button name="%(split_into)d" string="Put in a new pack" type="action"
groups="base.group_extended" groups="base.group_extended"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}" icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed,done"/> states="draft,assigned,confirmed,done"/>
<label/> <label/>
<button name="%(track_line)d" string="Split in production lots" <button name="%(track_line)d" string="Split in production lots"

View File

@ -194,7 +194,7 @@ class split_in_production_lot(osv.osv_memory):
'product_uom': fields.many2one('product.uom', 'Product UOM'), 'product_uom': fields.many2one('product.uom', 'Product UOM'),
'line_ids': fields.one2many('stock.move.split.lines', 'lot_id', 'Lots Number'), 'line_ids': fields.one2many('stock.move.split.lines', 'lot_id', 'Lots Number'),
'line_exist_ids': fields.one2many('stock.move.split.lines.exist', 'lot_id', 'Lots Existing Numbers'), 'line_exist_ids': fields.one2many('stock.move.split.lines.exist', 'lot_id', 'Lots Existing Numbers'),
'use_exist' : fields.boolean('Use Exist'), 'use_exist' : fields.boolean('Existing Lot'),
} }
def split_lot(self, cr, uid, ids, context=None): def split_lot(self, cr, uid, ids, context=None):
@ -294,7 +294,7 @@ class stock_move_split_lines(osv.osv_memory):
_columns = { _columns = {
'name': fields.char('Tracking serial', size=64), 'name': fields.char('Tracking serial', size=64),
'quantity': fields.integer('Quantity'), 'quantity': fields.integer('Quantity'),
'use_exist' : fields.boolean('Use Exist'), 'use_exist' : fields.boolean('Existing Lot'),
'lot_id': fields.many2one('stock.move.split', 'Lot'), 'lot_id': fields.many2one('stock.move.split', 'Lot'),
'action': fields.selection([('split','Split'),('keepinone','Keep in one lot')],'Action'), 'action': fields.selection([('split','Split'),('keepinone','Keep in one lot')],'Action'),
} }

View File

@ -40,32 +40,25 @@ class stock_split_into(osv.osv_memory):
quantity = self.browse(cr, uid, data[0], context).quantity or 0.0 quantity = self.browse(cr, uid, data[0], context).quantity or 0.0
for move in move_obj.browse(cr, uid, rec_id): for move in move_obj.browse(cr, uid, rec_id):
move_qty = move.product_qty
uos_qty_rest = move.product_uos_qty
quantity_rest = move_qty - quantity
if (quantity_rest == 0) or (quantity <= 0) :
continue
move_obj.setlast_tracking(cr, uid, [move.id], context=context)
move_obj.write(cr, uid, [move.id], {
'product_qty': quantity,
'product_uos_qty': quantity,
'product_uos': move.product_uom.id,
})
quantity_rest = move.product_qty - quantity quantity_rest = move.product_qty - quantity
tracking_id = track_obj.create(cr, uid, {}) if quantity > 0:
default_val = { move_obj.setlast_tracking(cr, uid, [move.id], context=context)
'product_qty': quantity_rest, move_obj.write(cr, uid, [move.id], {
'product_uos_qty': quantity_rest, 'product_qty': quantity,
'tracking_id': tracking_id, 'product_uos_qty': quantity,
'state': move.state, 'product_uos': move.product_uom.id,
'product_uos': move.product_uom.id })
} if quantity_rest>0:
current_move = move_obj.copy(cr, uid, move.id, default_val) quantity_rest = move.product_qty - quantity
new_move.append(current_move) tracking_id = track_obj.create(cr, uid, {})
update_val['product_qty'] = quantity default_val = {
update_val['tracking_id'] = tracking_id 'product_qty': quantity_rest,
update_val['product_uos_qty'] = uos_qty_rest 'product_uos_qty': quantity_rest,
move_obj.write(cr, uid, [move.id], update_val) 'tracking_id': tracking_id,
'state': move.state,
'product_uos': move.product_uom.id
}
current_move = move_obj.copy(cr, uid, move.id, default_val)
return {} return {}
stock_split_into() stock_split_into()

View File

@ -1,31 +1,28 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<openerp> <openerp>
<data> <data>
<record id="view_stock_move_split_wizard" model="ir.ui.view">
<record id="view_stock_move_split_wizard" model="ir.ui.view"> <field name="name">Split move</field>
<field name="name">Split move</field> <field name="model">stock.split.into</field>
<field name="model">stock.split.into</field> <field name="type">form</field>
<field name="type">form</field> <field name="arch" type="xml">
<field name="arch" type="xml"> <form string="Split Move">
<form string="Split Move"> <separator string="Quantity for current pack" colspan="4"/>
<separator string="Set quantity to split your palets" colspan="4"/> <field name="quantity"/>
<field name="quantity"/> <button icon='gtk-cancel' special="cancel"
<button icon='gtk-cancel' special="cancel" string="Cancel" />
string="Cancel" /> <button name="split" string="Ok"
<button name="split" string="Ok" type="object" icon="gtk-ok" />
type="object" icon="gtk-ok" /> </form>
</form> </field>
</field> </record>
</record> <record id="split_into" model="ir.actions.act_window">
<field name="name">Split into</field>
<record id="split_into" model="ir.actions.act_window"> <field name="type">ir.actions.act_window</field>
<field name="name">Split into</field> <field name="res_model">stock.split.into</field>
<field name="type">ir.actions.act_window</field> <field name="view_type">form</field>
<field name="res_model">stock.split.into</field> <field name="view_mode">form</field>
<field name="view_type">form</field> <field name="target">new</field>
<field name="view_mode">form</field> </record>
<field name="target">new</field> </data>
</record> </openerp>
</data>
</openerp>

View File

@ -8,25 +8,25 @@
<field name="model">stock.traceability.downstream</field> <field name="model">stock.traceability.downstream</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Downstream traceability"> <form string="Downstream traceability">
<label string="It will give information about the stock of a product as per the Tracking Lot" colspan="2" /> <label string="It will give information about the stock of a product as per the pack" colspan="2" />
<separator string="" colspan="4" /> <separator string="" colspan="4" />
<button icon='gtk-cancel' special="cancel" <button icon='gtk-cancel' special="cancel"
string="Cancel" /> string="Cancel" />
<button name="action_traceability" string="Downstream traceability" type="object" context="{'type': 'move_history_ids2','field': ''}"/> <button name="action_traceability" string="Downstream traceability" type="object" context="{'type': 'move_history_ids2','field': ''}"/>
</form> </form>
</field> </field>
</record> </record>
<act_window name="Downstream traceability" <act_window name="Downstream traceability"
res_model="stock.traceability.downstream" res_model="stock.traceability.downstream"
src_model="stock.tracking" src_model="stock.tracking"
view_mode="form" view_mode="form"
target="new" target="new"
key2="client_action_multi" key2="client_action_multi"
id="action_view_stock_traceability_downstream"/> id="action_view_stock_traceability_downstream"/>
<!-- =========stock.traceability.upstream================= --> <!-- =========stock.traceability.upstream================= -->
@ -35,25 +35,25 @@
<field name="model">stock.traceability.upstream</field> <field name="model">stock.traceability.upstream</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Upstream traceability"> <form string="Upstream traceability">
<label string="It will give information about the stock of a product as per the Tracking Lot" colspan="2" /> <label string="It will give information about the stock of a product as per the pack" colspan="2" />
<separator string="" colspan="4" /> <separator string="" colspan="4" />
<button icon='gtk-cancel' special="cancel" <button icon='gtk-cancel' special="cancel"
string="Cancel" /> string="Cancel" />
<button name="action_traceability" string="Upstream traceability" type="object" context="{'type': '','field': ''}"/> <button name="action_traceability" string="Upstream traceability" type="object" context="{'type': '','field': ''}"/>
</form> </form>
</field> </field>
</record> </record>
<act_window name="Upstream traceability" <act_window name="Upstream traceability"
res_model="stock.traceability.upstream" res_model="stock.traceability.upstream"
src_model="stock.tracking" src_model="stock.tracking"
view_mode="form" view_mode="form"
target="new" target="new"
key2="client_action_multi" key2="client_action_multi"
id="action_view_stock_traceability_upstream"/> id="action_view_stock_traceability_upstream"/>
<!-- =========stock.traceability.lot.upstream================= --> <!-- =========stock.traceability.lot.upstream================= -->
@ -62,25 +62,25 @@
<field name="model">stock.traceability.lot.upstream</field> <field name="model">stock.traceability.lot.upstream</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Stock traceability lot upstream"> <form string="Stock traceability lot upstream">
<label string="It will give information about the stock of a product as per the Production Lot" colspan="2" /> <label string="It will give information about the stock of a product as per the Production Lot" colspan="2" />
<separator string="" colspan="4" /> <separator string="" colspan="4" />
<button icon='gtk-cancel' special="cancel" <button icon='gtk-cancel' special="cancel"
string="Cancel" /> string="Cancel" />
<button name="action_traceability" string="Upstream traceability" type="object" context="{'type': '', 'field': 'prodlot_id'}"/> <button name="action_traceability" string="Upstream traceability" type="object" context="{'type': '', 'field': 'prodlot_id'}"/>
</form> </form>
</field> </field>
</record> </record>
<act_window name="Upstream traceability" <act_window name="Upstream traceability"
res_model="stock.traceability.lot.upstream" res_model="stock.traceability.lot.upstream"
src_model="stock.production.lot" src_model="stock.production.lot"
view_mode="form" view_mode="form"
target="new" target="new"
key2="client_action_multi" key2="client_action_multi"
id="action_view_stock_traceability_lot_upstream"/> id="action_view_stock_traceability_lot_upstream"/>
<!-- =========stock.traceability.lot.downstream================= --> <!-- =========stock.traceability.lot.downstream================= -->
@ -89,26 +89,26 @@
<field name="model">stock.traceability.lot.downstream</field> <field name="model">stock.traceability.lot.downstream</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Stock traceability lot downstream"> <form string="Stock traceability lot downstream">
<label string="It will give information about the stock of a product as per the Production Lot" colspan="2" />
<separator string="" colspan="4" />
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="action_traceability" string="Downstream traceability" type="object" context="{'type': 'move_history_ids2', 'field': 'prodlot_id'}"/>
</form>
</field>
</record>
<act_window name="Downstream traceability"
res_model="stock.traceability.lot.downstream"
src_model="stock.production.lot"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_view_stock_traceability_lot_downstream"/>
</data> <label string="It will give information about the stock of a product as per the Production Lot" colspan="2" />
<separator string="" colspan="4" />
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="action_traceability" string="Downstream traceability" type="object" context="{'type': 'move_history_ids2', 'field': 'prodlot_id'}"/>
</form>
</field>
</record>
<act_window name="Downstream traceability"
res_model="stock.traceability.lot.downstream"
src_model="stock.production.lot"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_view_stock_traceability_lot_downstream"/>
</data>
</openerp> </openerp>