bzr revid: vir@tinyerp.com-20100710051043-bidtwbf0oj9a1ay9
This commit is contained in:
Vir (Open ERP)
2010-07-10 10:40:43 +05:30
93 changed files with 848 additions and 601 deletions
+1 -1
View File
@@ -159,7 +159,7 @@ class account_bank_statement(osv.osv):
'period_id': _get_period,
}
def button_confirm(self, cr, uid, ids, context={}):
def button_confirm_bank(self, cr, uid, ids, context={}):
done = []
res_currency_obj = self.pool.get('res.currency')
res_users_obj = self.pool.get('res.users')
+57 -22
View File
@@ -67,19 +67,25 @@ class account_cash_statement(osv.osv):
_inherit = 'account.bank.statement'
def _get_starting_balance(self, cr, uid, ids, name, arg, context=None):
def _get_starting_balance(self, cr, uid, ids, context=None):
""" Find starting balance "
""" 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
if statement.journal_id.type not in('cash'):
continue
for line in statement.starting_details_ids:
amount_total+= line.pieces * line.number
res[statement.id]=amount_total
res[statement.id] = {
'balance_start':amount_total
}
return res
def _balance_end_cash(self, cr, uid, ids, name, arg, context=None):
@@ -116,7 +122,7 @@ class account_cash_statement(osv.osv):
""" 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:
@@ -166,11 +172,10 @@ class account_cash_statement(osv.osv):
company_id = company_pool.search(cr, uid, [])[0]
return company_id
_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, store=True, 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'),
@@ -178,7 +183,7 @@ class account_cash_statement(osv.osv):
('open','Open')], 'State', required=True, states={'confirm': [('readonly', True)]}, readonly="1"),
'total_entry_encoding':fields.function(_get_sum_entry_encoding, method=True, store=True, string="Cash Transaction", help="Total cash transactions"),
'closing_date':fields.datetime("Closed On"),
'balance_end': fields.function(_end_balance, method=True, store=True, string='Balance', help="Closing balance based on transactions"),
'balance_end': fields.function(_end_balance, method=True, store=True, string='Balance', help="Closing balance based on Opening Balance and Transactions"),
'balance_end_cash': fields.function(_balance_end_cash, method=True, store=True, string='Balance', help="Closing balance based on cashBox"),
'starting_details_ids': fields.one2many('account.cashbox.line', 'starting_id', string='Opening Cashbox'),
'ending_details_ids': fields.one2many('account.cashbox.line', 'ending_id', string='Closing Cashbox'),
@@ -205,8 +210,31 @@ class account_cash_statement(osv.osv):
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
res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context)
res = self._get_starting_balance(cr, uid, [res_id])
for rs in res:
super(account_cash_statement, self).write(cr, uid, rs, res.get(rs))
return res_id
def write(self, cr, uid, ids, vals, context=None):
"""
Update redord(s) comes in {ids}, with new value comes as {vals}
return True on success, False otherwise
@param cr: cursor to database
@param user: id of current user
@param ids: list of record ids to be update
@param vals: dict of new values to be set
@param context: context arguments, like lang, time zone
@return: True on success, False otherwise
"""
super(account_cash_statement, self).write(cr, uid, ids, vals)
res = self._get_starting_balance(cr, uid, ids)
for rs in res:
super(account_cash_statement, self).write(cr, uid, rs, res.get(rs))
return True
def onchange_journal_id(self, cr, uid, statement_id, journal_id, context={}):
""" Changes balance start and starting details if journal_id changes"
@@ -285,7 +313,7 @@ class account_cash_statement(osv.osv):
self.write(cr, uid, ids, vals)
return True
def button_confirm(self, cr, uid, ids, context={}):
def button_confirm_cash(self, cr, uid, ids, context={}):
""" Check the starting and ending detail of statement
@return: True
@@ -296,20 +324,24 @@ class account_cash_statement(osv.osv):
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):
self.write(cr, uid, [st.id], {'balance_end_real':st.balance_end})
st.balance_end_real = st.balance_end
if not st.state == 'open':
continue
if not self._equal_balance(cr, uid, ids, st, context):
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))
raise osv.except_osv(_('Error !'), _('CashBox Balance is not matching with Calculated 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 !'),
@@ -435,7 +467,7 @@ class account_cash_statement(osv.osv):
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
@@ -447,13 +479,16 @@ class account_cash_statement(osv.osv):
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)
vals = {
'state':'confirm',
'closing_date':time.strftime("%Y-%m-%d %H:%M:%S")
}
self.write(cr, uid, done, vals, context=context)
return True
def button_cancel(self, cr, uid, ids, context={}):
+25 -10
View File
@@ -427,6 +427,9 @@
<field name="balance_end_real"/>
<field name="balance_end"/>
<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_bank" 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>
@@ -465,7 +468,7 @@
<field name="journal_id" on_change="onchange_journal_id(journal_id)" select="1"/>
<field name="period_id"/>
<field name="balance_start"/>
<field name="balance_end_real"/>
<field name="balance_end_real"/>
</group>
<notebook colspan="4">
<page string="Transaction">
@@ -505,7 +508,7 @@
<field name="state"/>
<field name="balance_end"/>
<button name="button_dummy" states="draft" string="Compute" icon="terp-stock_format-scientific"/>
<button name="button_confirm" states="draft" string="Confirm" type="object" icon="terp-camera_test"/>
<button name="button_confirm_bank" states="draft" string="Confirm" type="object" icon="terp-camera_test"/>
<button name="button_cancel" states="confirm" string="Cancel" type="object" icon="terp-gtk-stop"/>
</group>
</form>
@@ -518,6 +521,18 @@
<field name="view_mode">tree,form</field>
<field name="domain">[('journal_id.type', '=', 'bank')]</field>
</record>
<record model="ir.actions.act_window.view" id="action_bank_statement_tree_bank">
<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_bank_statement_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_bank_statement_form_bank">
<field name="sequence" eval="1"/>
<field name="view_mode">form</field>
<field name="view_id" ref="view_bank_statement_form"/>
<field name="act_window_id" ref="action_bank_statement_tree"/>
</record>
<menuitem string="Bank Statements" action="action_bank_statement_tree" id="menu_bank_statement_tree" parent="menu_finance_bank_and_cash" sequence="7"/>
<record id="action_bank_statement_draft_tree" model="ir.actions.act_window">
@@ -2267,7 +2282,7 @@
<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="Confirm" name="button_confirm_cash" states="open" icon="terp-gtk-go-back-rtl"/>
<button type="object" string="Cancel" name="button_cancel" states="confirm" icon="terp-gtk-stop"/>
</tree>
</field>
@@ -2285,7 +2300,7 @@
<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"/>
<!-- <field name="balance_end_real"/>-->
</group>
<notebook colspan="4">
@@ -2318,7 +2333,7 @@
</form>
</field>
</page>
<page string="Cash Box">
<page string="CashBox">
<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">
@@ -2349,7 +2364,7 @@
</group>
</page>
<page string="Accounting Entries" attrs="{'invisible': [('state','!=','confirm')]}">
<field colspan="4" name="move_line_ids" nolabel="1"/>
<field colspan="4" name="move_line_ids" nolabel="1" string="Accounting Entries"/>
</page>
</notebook>
<group col="6" colspan="4">
@@ -2360,18 +2375,18 @@
</group>
<group col="2" colspan="2">
<separator string="Opening Balance" colspan="4"/>
<field name="balance_start"/>
<field name="balance_start" readonly="1" string="Opening Balance"/>
<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"/>
<field name="balance_end" string="Calculated Balance"/>
<field name="balance_end_cash" string="CashBox 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_confirm_cash" 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>
+6 -6
View File
@@ -223,7 +223,7 @@ class account_invoice(osv.osv):
_log_create = True
_columns = {
'name': fields.char('Description', size=64, select=True, readonly=True, states={'draft':[('readonly',False)]}),
'origin': fields.char('Source Document', size=64, help="Reference of the document that produced this invoice."),
'origin': fields.char('Source Document', size=64, help="Reference of the document that produced this invoice.", readonly=True, states={'draft':[('readonly',False)]}),
'type': fields.selection([
('out_invoice','Customer Invoice'),
('in_invoice','Supplier Invoice'),
@@ -250,8 +250,8 @@ class account_invoice(osv.osv):
\n* The \'Open\' state is used when user create invoice,a invoice number is generated.Its in open state till user does not pay invoice. \
\n* The \'Done\' state is set automatically when invoice is paid.\
\n* The \'Cancelled\' state is used when user cancel invoice.'),
'date_invoice': fields.date('Date Invoiced', states={'open':[('readonly',True)], 'close':[('readonly',True)]}, help="Keep empty to use the current date"),
'date_due': fields.date('Due Date', states={'open':[('readonly',True)], 'close':[('readonly',True)]},
'date_invoice': fields.date('Date Invoiced', states={'paid':[('readonly',True)], 'open':[('readonly',True)], 'close':[('readonly',True)]}, help="Keep empty to use the current date"),
'date_due': fields.date('Due Date', states={'paid':[('readonly',True)], 'open':[('readonly',True)], 'close':[('readonly',True)]},
help="If you use payment terms, the due date will be computed automatically at the generation "\
"of accounting entries. If you keep the payment term and the due date empty, it means direct payment. The payment term may compute several due dates, for example 50% now, 50% in one month."),
'partner_id': fields.many2one('res.partner', 'Partner', change_default=True, readonly=True, required=True, states={'draft':[('readonly',False)]}),
@@ -291,7 +291,7 @@ class account_invoice(osv.osv):
multi='all'),
'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'journal_id': fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'company_id': fields.many2one('res.company', 'Company', required=True, change_default=True),
'company_id': fields.many2one('res.company', 'Company', required=True, change_default=True, readonly=True, states={'draft':[('readonly',False)]}),
'check_total': fields.float('Total', digits_compute=dp.get_precision('Account'), states={'open':[('readonly',True)],'close':[('readonly',True)]}),
'reconciled': fields.function(_reconciled, method=True, string='Paid/Reconciled', type='boolean',
store={
@@ -300,7 +300,7 @@ class account_invoice(osv.osv):
'account.move.reconcile': (_get_invoice_from_reconcile, None, 50),
}, help="The Ledger Postings of the invoice have been reconciled with Ledger Postings of the payment(s)."),
'partner_bank': fields.many2one('res.partner.bank', 'Bank Account',
help='The bank account to pay to or to be paid from'),
help='The bank account to pay to or to be paid from', readonly=True, states={'draft':[('readonly',False)]}),
'move_lines':fields.function(_get_lines , method=True, type='many2many', relation='account.move.line', string='Entry Lines'),
'residual': fields.function(_amount_residual, method=True, digits_compute=dp.get_precision('Account'), string='Residual',
store={
@@ -314,7 +314,7 @@ class account_invoice(osv.osv):
'payment_ids': fields.function(_compute_lines, method=True, relation='account.move.line', type="many2many", string='Payments'),
'move_name': fields.char('Ledger Posting', size=64, readonly=True, states={'draft':[('readonly',False)]}),
'user_id': fields.many2one('res.users', 'Salesman', readonly=True, states={'draft':[('readonly',False)]}),
'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position')
'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position', readonly=True, states={'draft':[('readonly',False)]})
}
_defaults = {
'type': _get_type,
@@ -28,12 +28,12 @@
<field name="partner_bank" invisible="1"/>
<field name="account_id" invisible="1"/>
<field name="nbr" sum="# of Lines"/>
<field name="product_qty"/>
<field name="product_qty" sum="Qty"/>
<field name="reconciled" sum="# Reconciled"/>
<field name="price_average" avg="Average Price"/>
<field name="price_average" sum="Average Price"/>
<field name="price_total" sum="Total Price"/>
<field name="residual" sum="Total Residual" invisible="not context.get('residual_visible',False)"/>
<field name="delay_to_pay" avg="Avg. Delay To Pay" invisible="not context.get('residual_visible',False)"/>
<field name="residual" sum="Total Residual" invisible="context.get('residual_invisible',False)"/>
<field name="delay_to_pay" sum="Avg. Delay To Pay" invisible="context.get('residual_invisible',False)"/>
</tree>
</field>
</record>
@@ -93,24 +93,24 @@
</group>
<newline/>
<group expand="1" string="Group By...">
<filter string="Salesman" name='user' icon="terp-personal" context="{'group_by':'user_id','residual_visible':True}"/>
<filter string="Salesman" name='user' icon="terp-personal" context="{'group_by':'user_id'}"/>
<filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id','residual_visible':True}"/>
<filter string="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id','set_visible':True}"/>
<filter string="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id','set_visible':True,'residual_invisible':True}"/>
<separator orientation="vertical"/>
<filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state','residual_visible':True}"/>
<filter string="Type" icon="terp-stock_symbol-selection" context="{'group_by':'type','residual_visible':True}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
<filter string="Type" icon="terp-stock_symbol-selection" context="{'group_by':'type'}"/>
<separator orientation="vertical"/>
<filter string="Journal" icon="terp-folder-orange" context="{'group_by':'journal_id','residual_visible':True}"/>
<filter string="Account" icon="terp-folder-orange" context="{'group_by':'account_id','residual_visible':True}"/>
<filter string="Journal" icon="terp-folder-orange" context="{'group_by':'journal_id'}"/>
<filter string="Account" icon="terp-folder-orange" context="{'group_by':'account_id'}"/>
<separator orientation="vertical"/>
<filter string="Category of Product" icon="terp-stock_symbol-selection" context="{'group_by':'categ_id'}"/>
<filter string="Force Period" icon="terp-go-month" context="{'group_by':'period_id','residual_visible':True}"/>
<filter string="Category of Product" icon="terp-stock_symbol-selection" context="{'group_by':'categ_id','residual_invisible':True}"/>
<filter string="Force Period" icon="terp-go-month" context="{'group_by':'period_id'}"/>
<separator orientation="vertical"/>
<filter string="Company" icon="terp-go-home" context="{'group_by':'company_id','residual_visible':True}" groups="base.group_multi_company"/>
<filter string="Company" icon="terp-go-home" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<separator orientation="vertical"/>
<filter string="Day" name="day" icon="terp-go-today" context="{'group_by':'day','residual_visible':True}"/>
<filter string="Month" name="month" icon="terp-go-month" context="{'group_by':'month','residual_visible':True}"/>
<filter string="Year" name="year" icon="terp-go-year" context="{'group_by':'year','residual_visible':True}"/>
<filter string="Day" name="day" icon="terp-go-today" context="{'group_by':'day'}"/>
<filter string="Month" name="month" icon="terp-go-month" context="{'group_by':'month'}"/>
<filter string="Year" name="year" icon="terp-go-year" context="{'group_by':'year'}"/>
</group>
<newline/>
<group expand="0" string="Extended options..." groups="base.group_extended">
@@ -35,7 +35,7 @@ class account_change_currency(osv.osv_memory):
context = {}
state = obj_inv.browse(cr, uid, context['active_id']).state
if obj_inv.browse(cr, uid, context['active_id']).state != 'draft':
raise osv.except_osv(_('Error'), _('You can not change currency for Open Invoice !'))
raise osv.except_osv(_('Error'), _('You can only change currency for Draft Invoice !'))
pass
def change_currency(self, cr, uid, ids, context=None):
@@ -61,7 +61,8 @@ class account_invoice_refund(osv.osv_memory):
date = False
period = False
description = False
for inv in inv_obj.browse(cr, uid, context['active_ids'], context=context):
company = self.pool.get('res.users').browse(cr, uid, uid).company_id
for inv in inv_obj.browse(cr, uid, context.get('active_ids'), context=context):
if inv.state in ['draft', 'proforma2', 'cancel']:
raise osv.except_osv(_('Error !'), _('Can not %s draft/proforma/cancel invoice.') % (mode))
if form['period'] :
@@ -77,11 +78,8 @@ class account_invoice_refund(osv.osv_memory):
and name = 'company_id'")
result_query = cr.fetchone()
if result_query:
cr.execute("""SELECT id
from account_period where date(%s)
between date_start AND date_stop \
and company_id = %s limit 1 """,
(date, self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id,))
cr.execute("""select p.id from account_fiscalyear y, account_period p where y.id=p.fiscalyear_id \
and date(%s) between p.date_start AND p.date_stop and y.company_id = %s limit 1""", (date, company.id,))
else:
cr.execute("""SELECT id
from account_period where date(%s)
@@ -154,7 +152,7 @@ class account_invoice_refund(osv.osv_memory):
'tax_line': tax_lines,
'period_id': period,
'name': description
})
})
for field in ('address_contact_id', 'address_invoice_id', 'partner_id',
'account_id', 'currency_id', 'payment_term', 'journal_id'):
@@ -192,4 +190,4 @@ class account_invoice_refund(osv.osv_memory):
account_invoice_refund()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -1,16 +1,17 @@
<?xml version="1.0"?>
<openerp>
<data>
<record id="view_account_journal_form_inherit" model="ir.ui.view">
<record id="view_account_journal_form_inherit" model="ir.ui.view">
<field name="name">account.journal.form</field>
<field name="model">account.journal</field>
<field name="type">form</field>
<field name="inherit_id" ref="account.view_account_journal_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page[@string='General Information']/group/group/field[@name='centralisation']" position="after">
<field name="entry_posted" position="after">
<!-- <xpath expr="/form/notebook/page[@string='General Information']/group/group/field[@name='centralisation']" position="after">-->
<field name="update_posted"/>
</xpath>
</field>
</field>
</record>
</data>
</openerp>
</record>
</data>
</openerp>
+9 -9
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
"PO-Revision-Date: 2010-07-07 09:59+0000\n"
"PO-Revision-Date: 2010-07-09 06:46+0000\n"
"Last-Translator: Bojan Markovic <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-07-08 03:50+0000\n"
"X-Launchpad-Export-Date: 2010-07-10 04:02+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_report
@@ -26,17 +26,17 @@ msgstr ""
#. module: account_report
#: wizard_field:print.indicators.pdf,init,file:0
msgid "Select a PDF File"
msgstr ""
msgstr "Odaberi PDF datoteku"
#. module: account_report
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
msgstr ""
msgstr "Neispravan naziv modela u definiciji zadatka."
#. module: account_report
#: view:account.report.report:0
msgid "Operators:"
msgstr ""
msgstr "Operatori:"
#. module: account_report
#: field:account.report.report,parent_id:0
@@ -46,12 +46,12 @@ msgstr "Sintetika"
#. module: account_report
#: field:account.report.report,disp_graph:0
msgid "Display As Graph"
msgstr ""
msgstr "Prikaži kao grafikon"
#. module: account_report
#: view:account.report.report:0
msgid "Account Debit:"
msgstr ""
msgstr "Dugovanje konta:"
#. module: account_report
#: selection:account.report.report,type:0
@@ -66,12 +66,12 @@ msgstr ""
#. module: account_report
#: rml:print.indicators:0
msgid "Tabular Summary"
msgstr ""
msgstr "Tablični sažetak"
#. module: account_report
#: view:account.report.report:0
msgid "Notes"
msgstr ""
msgstr "Bilješke"
#. module: account_report
#: view:account.report.report:0
@@ -49,7 +49,7 @@ class account_voucher_unreconcile(osv.osv_memory):
recs = [line.reconcile_id.id]
for rec in recs:
obj_reconcile.unlink(cr, uid, rec)
reconcile_pool.unlink(cr, uid, rec)
if res.remove:
wf_service = netsvc.LocalService("workflow")
+14 -11
View File
@@ -22,7 +22,8 @@
from datetime import datetime
from osv import fields, osv, orm
from tools.translate import _
import mx.DateTime
from datetime import datetime
from datetime import timedelta
import pooler
import re
import time
@@ -105,7 +106,9 @@ the rule to mark CC(mail to any other person defined in actions)."),
'act_mail_to_email': fields.char('Mail to these Emails', size=128, \
help="Email-id of the persons whom mail is to be sent"),
'act_mail_body': fields.text('Mail body', help="Content of mail"),
'regex_name': fields.char('Regular Expression on Model Name', size=128),
'regex_name': fields.char('Regex on Resource Name', size=128, help="Regular expression for mathching name of the resource\
\ne.g.: urgent.* will search for records having name starting with urgent\
\nNote: This is case sensitive search."),
'server_action_id': fields.many2one('ir.actions.server', 'Server Action', help="Describes the action name.\neg:on which object which action to be taken on basis of which condition"),
'filter_id':fields.many2one('ir.filters', 'Filter', required=False),
'domain':fields.char('Domain', size=124, required=False, readonly=False),
@@ -352,23 +355,23 @@ the rule to mark CC(mail to any other person defined in actions)."),
base = False
if hasattr(obj, 'create_date') and action.trg_date_type=='create':
base = mx.DateTime.strptime(obj.create_date[:19], '%Y-%m-%d %H:%M:%S')
base = datetime.strptime(obj.create_date[:19], '%Y-%m-%d %H:%M:%S')
elif hasattr(obj, 'create_date') and action.trg_date_type=='action_last':
if hasattr(obj, 'date_action_last') and obj.date_action_last:
base = mx.DateTime.strptime(obj.date_action_last, '%Y-%m-%d %H:%M:%S')
base = datetime.strptime(obj.date_action_last, '%Y-%m-%d %H:%M:%S')
else:
base = mx.DateTime.strptime(obj.create_date[:19], '%Y-%m-%d %H:%M:%S')
base = datetime.strptime(obj.create_date[:19], '%Y-%m-%d %H:%M:%S')
elif hasattr(obj, 'date_deadline') and action.trg_date_type=='deadline' \
and obj.date_deadline:
base = mx.DateTime.strptime(obj.date_deadline, '%Y-%m-%d %H:%M:%S')
base = datetime.strptime(obj.date_deadline, '%Y-%m-%d %H:%M:%S')
elif hasattr(obj, 'date') and action.trg_date_type=='date' and obj.date:
base = mx.DateTime.strptime(obj.date, '%Y-%m-%d %H:%M:%S')
base = datetime.strptime(obj.date, '%Y-%m-%d %H:%M:%S')
if base:
fnct = {
'minutes': lambda interval: mx.DateTime.RelativeDateTime(minutes=interval),
'day': lambda interval: mx.DateTime.RelativeDateTime(days=interval),
'hour': lambda interval: mx.DateTime.RelativeDateTime(hours=interval),
'month': lambda interval: mx.DateTime.RelativeDateTime(months=interval),
'minutes': lambda interval: timedelta(minutes=interval),
'day': lambda interval: timedelta(days=interval),
'hour': lambda interval: timedelta(hours=interval),
'month': lambda interval: timedelta(months=interval),
}
d = base + fnct[action.trg_date_range_type](action.trg_date_range)
dt = d.strftime('%Y-%m-%d %H:%M:%S')
@@ -24,7 +24,7 @@
<page string="Conditions">
<group col="2" colspan="2" name="model">
<separator colspan="4" string="Conditions on Model Fields"/>
<field name="regex_name" string="Regex on Model Name" colspan="2"/>
<field name="regex_name" colspan="2"/>
<field name="trg_user_id"/>
</group>
<group col="2" colspan="2" name="partner">
+14 -8
View File
@@ -317,7 +317,7 @@ class calendar_attendee(osv.osv):
obj = self.pool.get('res.lang')
ids = obj.search(cr, uid, [])
res = obj.read(cr, uid, ids, ['code', 'name'], context=context)
res = [((r['code']).replace('_', '-'), r['name']) for r in res]
res = [((r['code']).replace('_', '-').lower(), r['name']) for r in res]
return res
_columns = {
@@ -378,6 +378,10 @@ property or property parameter."),
}
_defaults = {
'state': 'needs-action',
'user_id': lambda self, cr, uid, ctx: uid,
'role': 'req-participant',
'rsvp': True,
'cutype': 'individual',
}
def copy(self, cr, uid, id, default=None, context=None):
@@ -542,13 +546,13 @@ property or property parameter."),
context = {}
for vals in self.browse(cr, uid, ids, context=context):
user = vals.user_id
if user:
mod_obj = self.pool.get(vals.ref._name)
if vals.ref:
if vals.ref.user_id.id != user.id:
defaults = {'user_id': user.id}
new_event = mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
#user = vals.user_id
#if user:
# mod_obj = self.pool.get(vals.ref._name)
# if vals.ref:
# if vals.ref.user_id.id != user.id:
# defaults = {'user_id': user.id}
# new_event = mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
self.write(cr, uid, vals.id, {'state': 'accepted'}, context)
return True
@@ -1416,6 +1420,8 @@ true, it will allow you to hide the event alarm information without removing it.
until_date = arg[2]
res = super(calendar_event, self).search(cr, uid, args_without_date, \
offset, limit, order, context, count)
#Search Event ID which are invitted
return self.get_recurrent_ids(cr, uid, res, start_date, until_date, limit)
+20 -7
View File
@@ -76,13 +76,26 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Invitation details">
<field name="email" string="Invitation To"/>
<field name="user_id" string="Internal User" />
<field name="partner_address_id" string="Contact" />
<field name="role" />
<field name="sent_by_uid" string="Invitation From" />
<field name="role" string="My Role"/>
<field name="cutype" string="Invitation type"/>
<field name="state" />
<field name="cutype" invisible="1"/>
<field name="rsvp" invisible="1"/>
<field name="rsvp" string="Required to Join"/>
<button name="do_tentative" states="needs-action,declined,accepted"
string="Uncertain" type="object"
icon="terp-crm" />
<button name="do_accept" string="Accept"
states="needs-action,tentative,declined"
type="object" icon="gtk-apply" />
<button name="do_decline" string="Decline"
states="needs-action,tentative,accepted"
type="object" icon="gtk-cancel" />
<button
name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d"
string="Delegate" type="action"
icon="gtk-sort-descending"
states="needs-action,tentative,declined,accepted"
context="{'model' : 'calendar.attendee', 'attendee_field' : 'child_ids'}" />
</tree>
</field>
</record>
@@ -103,7 +116,7 @@
separator="1" help="Declined Invitations" />
<separator orientation="vertical"/>
<field name="email" select='1'/>
<field name="sent_by_uid" select="1"/>
<field name="user_id" select="1"/>
<separator orientation="vertical"/>
<field name="cutype" string="Invitation type" select="1"/>
<field name="event_date" select="1"/>
@@ -75,7 +75,8 @@ send an Email to Invited Person')
obj = self.pool.get(model)
res_obj = obj.browse(cr, uid, context_id)
att_obj = self.pool.get('calendar.attendee')
user_obj = self.pool.get('res.users')
current_user = user_obj.browse(cr, uid, uid, context=context)
for datas in self.read(cr, uid, ids, context=context):
type = datas.get('type')
vals = []
@@ -89,7 +90,7 @@ send an Email to Invited Person')
else:
return {}
if type == 'internal':
user_obj = self.pool.get('res.users')
if not datas.get('user_ids'):
raise osv.except_osv(_('Error!'), ("Please select any User"))
for user_id in datas.get('user_ids'):
@@ -139,7 +140,7 @@ send an Email to Invited Person')
self._columns['type'].selection))
raise osv.except_osv(_('Error!'), ("%s must have an email Address to send mail") %(name[0]))
att_obj._send_mail(cr, uid, attendees, mail_to, \
email_from= tools.config.get('email_from', False))
email_from = current_user.user_email or tools.config.get('email_from', False))
return {}
+3 -1
View File
@@ -528,6 +528,7 @@ class Calendar(CalDAV, osv.osv):
})
self.__attribute__ = get_attribute_mapping(cr, uid, child.name.lower(), context=context)
val = self.parse_ics(cr, uid, child, cal_children=cal_children, context=context)
val.update({'user_id': uid})
vals.append(val)
obj = self.pool.get(cal_children[child.name.lower()])
if hasattr(obj, 'check_import'):
@@ -1052,7 +1053,8 @@ class Attendee(CalDAV, osv.osv_memory):
if cn_val:
attendee_add.params['CN'] = cn_val
if not attendee['email']:
raise osv.except_osv(_('Error !'), _('Attendee must have an Email Id'))
attendee_add.value = 'MAILTO:'
#raise osv.except_osv(_('Error !'), _('Attendee must have an Email Id'))
elif attendee['email']:
attendee_add.value = 'MAILTO:' + attendee['email']
return vevent
+1 -1
View File
@@ -121,7 +121,7 @@ Create dashboard for CRM that includes:
],
'test': [
'test/test_crm_lead.yml',
'test/test_crm_meeting.yml',
#'test/test_crm_meeting.yml',
'test/test_crm_opportunity.yml',
'test/test_crm_phonecall.yml',
],
+50 -34
View File
@@ -4,53 +4,69 @@
<!--
Board for statistical view of the sections
-->
<record model="ir.ui.view" id="view_crm_lead_stage_graph1">
<field name="name">Leads By Stage - Graph</field>
<field name="model">crm.lead.report</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Leads By Stage" type="pie">
<field name="stage_id"/>
<field name="nbr" operator="+"/>
</graph>
</field>
</record>
<record model="ir.ui.view" id="view_crm_opportunity_categ_graph">
<field name="name">report.crm.opportunity.categ.graph</field>
<record model="ir.ui.view" id="view_crm_opportunity_categ_graph">
<field name="name">Opportunities By Categories - Graph</field>
<field name="model">crm.lead.report</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Opportunity by Sales Team and Categories" type="bar" orientation="horizontal">
<graph string="Opportunity by Categories" type="bar" orientation="horizontal">
<field name="categ_id"/>
<field name="nbr" operator="+"/>
</graph>
</field>
</record>
<act_window name="Opportunities By Categories"
domain="[('state','!=','done'),('state','!=','cancel')]"
res_model="crm.lead.report"
view_type="form"
view_mode="graph,tree,form"
view_id="view_crm_opportunity_categ_graph"
id="act_oppor_categ"/>
<record model="ir.ui.view" id="view_crm_opportunity_stage_graph">
<field name="name">Opportunities By Stage - Graph</field>
<field name="model">crm.lead.report</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Opportunities By Stage" type="pie">
<field name="stage_id"/>
<field name="nbr" operator="+"/>
</graph>
</field>
</record>
<record model="ir.ui.view" id="view_crm_opportunity_user_stage_graph">
<field name="name">Opportunities By Stage Per User - Graph</field>
<field name="model">crm.lead.report</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Opportunities By Stage" type="bar">
<field name="stage_id"/>
<field name="nbr" operator="+"/>
<field name="user_id" group="True"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="act_leads_state">
<record model="ir.actions.act_window" id="act_oppor_categ">
<field name="res_model">Opportunities By Categories</field>
<field name="res_model">crm.lead.report</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_lead_stage_graph1"/>
<field name="view_id" ref="view_crm_opportunity_categ_graph"/>
<field name="domain">[('state','!=','done'),('state','!=','cancel')]</field>
</record>
<act_window name="Leads Of The Month By User"
domain="[('month','=',time.strftime('%%m')),('state','!=','cancel')]"
res_model="crm.lead.report"
view_type="form"
view_mode="graph,tree,form"
view_id="view_crm_lead_stage_graph1"
id="act_leads_month_user"/>
<record model="ir.actions.act_window" id="act_opportunity_stage">
<field name="res_model">crm.lead.report</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_stage_graph"/>
<field name="domain">[('state','!=','done'),('state','!=','cancel')]</field>
</record>
<record model="ir.actions.act_window" id="act_oppor_stage_user">
<field name="res_model">Number of Opportunities by stage</field>
<field name="res_model">crm.lead.report</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_user_stage_graph"/>
<field name="domain">[('state','!=','cancel')]</field>
</record>
<record model="ir.ui.view" id="board_crm_statistical_form">
<field name="name">CRM - Statistical Dashboard Form</field>
@@ -68,8 +84,8 @@
width="250"/>
<action
string="Leads By Stage"
name="%(act_leads_state)d"
string="Opportunities By Stage"
name="%(act_opportunity_stage)d"
height="200"
colspan="4"/>
@@ -77,8 +93,8 @@
<child2>
<action
string="Leads Of The Month By User"
name="%(act_leads_month_user)d"
string="Number of Opportunities by Stage and User"
name="%(act_oppor_stage_user)d"
colspan="4"/>
</child2>
+27 -12
View File
@@ -4,23 +4,38 @@
<record model="board.note.type" id="note_crm_type">
<field name="name">CRM Configuration</field>
</record>
<record model="ir.ui.view" id="view_crm_opportunity_user_graph1">
<field name="name">crm.opportunity.user.graph1</field>
<field name="model">crm.lead.report</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Opportunities by User and Section" type="pie">
<field name="state"/>
<graph string="Opportunities by User and Section" type="bar">
<field name="stage_id"/>
<field name="nbr" operator="+"/>
<field name="user_id" group="True"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="act_my_leads">
<record id="view_report_crm_oppor_graph" model="ir.ui.view">
<field name="name">crm.lead.report.graph</field>
<field name="model">crm.lead.report</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="vertical" string="Opportunity Analysis" type="bar">
<field name="stage_id"/>
<field name="planned_revenue" operator="+"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="act_my_oppor">
<field name="res_model">crm.lead</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="crm.crm_case_tree_view_oppor"/>
<field name="domain">[('user_id','=',uid),('state','!=','pending'),('state','!=','cancel')]</field>
<field name="domain">[('user_id','=',uid),('state','=','open'), ('type', '=', 'opportunity')]</field>
</record>
<record model="ir.actions.act_window" id="act_my_meetings">
@@ -31,12 +46,12 @@
<field name="domain">[('user_id','=',uid),('state','!=','cancel'),('date','ilike',time.strftime("%Y-%m"))]</field>
</record>
<record model="ir.actions.act_window" id="act_my_leads_stage">
<record model="ir.actions.act_window" id="act_my_oppor_stage">
<field name="res_model">crm.lead.report</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_report_crm_lead_graph"/>
<field name="domain">[('user_id','=',uid),('state','!=','pending'),('state','!=','cancel')]</field>
<field name="view_id" ref="view_report_crm_oppor_graph"/>
<field name="domain">['&amp;', ('user_id','=',uid), '!' , '&amp;', ('state', '=', 'done'), ('date_closed','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]</field>
</record>
<record model="ir.actions.act_window" id="act_sales_pipeline">
@@ -44,7 +59,7 @@
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_user_graph1"/>
<field name="domain">[('user_id','=',uid),('state','!=','pending'),('state','!=','cancel'),('type', '=', 'opportunity')]</field>
<field name="domain">['&amp;', ('state', '=', 'done') , '&amp;', ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%Y-%m-%d')), ('type', '=', 'opportunity')]</field>
</record>
<record model="ir.ui.view" id="board_crm_form">
@@ -56,8 +71,8 @@
<hpaned>
<child1>
<action
string="My Opportunities"
name="%(act_my_leads)d"
string="My Open Opportunities"
name="%(act_my_oppor)d"
colspan="4"
height="150"
width="510"/>
@@ -70,10 +85,10 @@
<child2>
<action
string="Revenues by stage"
name="%(act_my_leads_stage)d"
name="%(act_my_oppor_stage)d"
colspan="4"/>
<action
string="My Sales Pipeline"
string="Win/Lost Ratio for the last Year"
name="%(act_sales_pipeline)d"
colspan="4"/>
</child2>
+5 -3
View File
@@ -268,12 +268,13 @@ class crm_case(object):
"""
cases = self.browse(cr, uid, ids)
for case in cases:
data = {'active': True, 'user_id': False}
data = {'active': True}
if case.section_id.parent_id:
data['section_id'] = case.section_id.parent_id.id
if case.section_id.parent_id.user_id:
data['user_id'] = case.section_id.parent_id.user_id.id
if case.section_id.parent_id.change_responsible:
if case.section_id.parent_id.user_id:
data['user_id'] = case.section_id.parent_id.user_id.id
else:
raise osv.except_osv(_('Error !'), _('You can not escalate, You are already at the top level regarding your sales-team category.'))
self.write(cr, uid, [case.id], data)
@@ -439,6 +440,7 @@ class crm_case_section(osv.osv):
'active': fields.boolean('Active', help="If the active field is set to \
true, it will allow you to hide the sales team without removing it."),
'allow_unlink': fields.boolean('Allow Delete', help="Allows to delete non draft cases"),
'change_responsible': fields.boolean('Change Responsible', help="Set responsible of this Sales team on escalation to this team"),
'user_id': fields.many2one('res.users', 'Responsible User'),
'member_ids':fields.many2many('res.users', 'sale_member_rel', 'section_id', 'member_id', 'Team Members'),
'reply_to': fields.char('Reply-To', size=64, help="The email address put \
+20 -1
View File
@@ -24,7 +24,6 @@ import re
import os
import base64
import tools
import mx.DateTime
from tools.translate import _
from osv import fields
@@ -80,6 +79,26 @@ this if you want the rule to send an email to the partner."),
if hasattr(obj, 'categ_id'):
ok = ok and (not action.trg_categ_id or action.trg_categ_id.id==obj.categ_id.id)
#Cheking for history
regex = action.regex_history
result_history = True
if regex:
res = False
ptrn = re.compile(str(regex))
for history in obj.message_ids:
_result = ptrn.search(str(history.name))
if _result:
res = True
break
result_history = res
ok = ok and (not regex or result_history)
res_count = True
if action.trg_max_history:
res_count = False
if len(obj.message_ids) >= action.trg_max_history:
res_count = True
ok = ok and res_count
return ok
def do_action(self, cr, uid, action, model_obj, obj, context={}):
+98 -74
View File
@@ -1,81 +1,105 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<data>
<!-- CASE STATUS(stage_id) -->
<record model="crm.case.stage" id="stage_lead1">
<field name="name">New</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_lead2">
<field name="name">Assigned</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_lead3">
<field name="name">In Process</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_lead4">
<field name="name">Converted</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_lead5">
<field name="name">Recycled</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_lead6">
<field name="name">Dead</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<!-- CASE STATUS(stage_id) -->
<record model="crm.case.stage" id="stage_lead1">
<field name="name">New</field>
<field eval="'10'" name="probability"/>
<field eval="'1'" name="sequence"/>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<!-- CASE CATEGORY2(category2_id) -->
<record model="crm.case.resource.type" id="type_lead1">
<field name="name">Telesales</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead2">
<field name="name">Mail</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead3">
<field name="name">Email</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead4">
<field name="name">Print</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead5">
<field name="name">Web</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead6">
<field name="name">Radio</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead7">
<field name="name">Television</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead8">
<field name="name">Newsletter</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_lead2">
<field name="name">Qualification</field>
<field eval="'20'" name="probability"/>
<field eval="'2'" name="sequence"/>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
</data>
<record model="crm.case.stage" id="stage_lead3">
<field name="name">Proposition</field>
<field eval="'40'" name="probability"/>
<field eval="'3'" name="sequence"/>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_lead4">
<field name="name">Negotiation</field>
<field eval="'60'" name="probability"/>
<field eval="'4'" name="sequence"/>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_lead5">
<field name="name">Win</field>
<field eval="'100'" name="probability"/>
<field eval="'5'" name="sequence"/>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_lead6">
<field name="name">Lost</field>
<field eval="'0'" name="probability"/>
<field eval="'6'" name="sequence"/>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<!-- CASE CATEGORY2(category2_id) -->
<record model="crm.case.resource.type" id="type_lead1">
<field name="name">Telesales</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead2">
<field name="name">Mail</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead3">
<field name="name">Email</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead4">
<field name="name">Print</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead5">
<field name="name">Web</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead6">
<field name="name">Radio</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead7">
<field name="name">Television</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type_lead8">
<field name="name">Newsletter</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
</data>
</openerp>
+2 -1
View File
@@ -80,7 +80,8 @@ class crm_meeting(osv.osv, crm_case):
_defaults = {
'state': lambda *a: 'draft',
'active': lambda *a: 1,
'active': lambda *a: 1,
'user_id': lambda self, cr, uid, ctx: uid,
}
def open_meeting(self, cr, uid, ids, context=None):
+1 -1
View File
@@ -105,7 +105,7 @@
<field name="view_mode">tree,form</field>
<field name="view_id" ref="base_calendar.base_calendar_attendee_tree_view" />
<field name="domain">[('ref','like','crm.meeting,')]</field>
<field name="context">{'default_sent_by_uid': uid}</field>
<field name="context">{"search_default_user_id":uid}</field>
</record>
<menuitem id="menu_attendee_invitations"
+1 -14
View File
@@ -342,20 +342,7 @@
</field>
</field>
</record>
<!-- Calendar Attendee Tree View -->
<record id="attendee_tree_view_inherit" model="ir.ui.view">
<field name="name">calendar.attendee.tree.inherit</field>
<field name="model">calendar.attendee</field>
<field name="type">tree</field>
<field name="inherit_id" ref="base_calendar.base_calendar_attendee_tree_view"/>
<field name="arch" type="xml">
<field name="role" position="after">
<field name="categ_id" string="Event Type"/>
</field>
</field>
</record>
</data>
</openerp>
+1 -38
View File
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<data>
<record model="crm.case.categ" id="categ_oppor1">
<field name="name">Existing Customer</field>
<field name="section_id" ref="section_sales_department"/>
@@ -42,43 +42,6 @@
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<!-- CASE STATUS(stage_id) -->
<record model="crm.case.stage" id="stage_oppor1">
<field name="name">Prospecting</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_oppor2">
<field name="name">Needs Analysis</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_oppor3">
<field name="name">Value Proposition</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_oppor4">
<field name="name">Proposal/Price Quote</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_oppor5">
<field name="name">Negotiation/Review</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_oppor6">
<field name="name">Closed Won</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.stage" id="stage_oppor7">
<field name="name">Closed Lost</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<!-- Case Resource(type_id) -->
<record model="crm.case.resource.type" id="type_oppor1">
<field name="name">Existing Business</field>
+5 -5
View File
@@ -20,7 +20,7 @@
<field eval="85000.0" name="planned_revenue"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor1"/>
<field name="stage_id" ref="crm.stage_oppor3"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field eval="&quot;CONS TRUST (AZ) 529701 - 1000 units&quot;" name="name"/>
</record>
<record id="crm_case_rdroundfundingunits0" model="crm.lead">
@@ -36,7 +36,7 @@
<field eval="50" name="probability"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor5"/>
<field name="stage_id" ref="crm.stage_oppor1"/>
<field name="stage_id" ref="crm.stage_lead1"/>
<field eval="&quot;3rd Round Funding - 1000 units &quot;" name="name"/>
</record>
<record id="crm_case_mediapoleunits0" model="crm.lead">
@@ -53,7 +53,7 @@
<field eval="70" name="probability"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor7"/>
<field name="stage_id" ref="crm.stage_oppor5"/>
<field name="stage_id" ref="crm.stage_lead5"/>
<field eval="&quot;Mediapole - 5000 units&quot;" name="name"/>
<field eval="&quot;info@mycompany.net&quot;" name="email_from"/>
</record>
@@ -70,7 +70,7 @@
<field eval="45000.0" name="planned_revenue"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor5"/>
<field name="stage_id" ref="crm.stage_oppor4"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field eval="&quot;ABC FUEL CO 829264 - 1000 units &quot;" name="name"/>
<field eval="&quot;info@opensides.be&quot;" name="email_from"/>
</record>
@@ -86,7 +86,7 @@
<field eval="42000.0" name="planned_revenue"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor2"/>
<field name="stage_id" ref="crm.stage_oppor6"/>
<field name="stage_id" ref="crm.stage_lead6"/>
<field eval="&quot;Dirt Mining Ltd 271742 - 1000 units&quot;" name="name"/>
</record>
</data>
+12 -14
View File
@@ -69,17 +69,14 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Phone Call">
<group colspan="4" col="7">
<field name="name" string="Summary"/>
<field name="date" string="Planned Date"/>
<field name="user_id"/>
<button string="Schedule a Meeting"
name="action_make_meeting"
icon="gtk-redo"
type="object" />
<group colspan="6" col="7">
<field name="name" string="Summary" required="1"/>
<field name="partner_phone" required="1"/>
<field name="duration" widget="float_time" required="1"/>
<button string="Schedule a Meeting" name="action_make_meeting" icon="gtk-redo" type="object"/>
<field name="partner_phone"/>
<field name="duration"/>
<field name="date" string="Date" required="1"/>
<field name="user_id"/>
<field name="section_id" colspan="1" widget="selection" />
<button string="Convert to Opportunity"
name="%(phonecall2opportunity_act)d"
@@ -92,6 +89,7 @@
type="action" />
</group>
<group col="3" colspan="2">
<separator colspan="3" string="Contacts" />
<field name="partner_id"
@@ -146,15 +144,15 @@
<form string="Phone Call">
<group colspan="4" col="7">
<field name="name" string="Summary" required="1"/>
<field name="date" string="Planned Date" required="1"/>
<field name="user_id"/>
<field name="partner_phone"/>
<field name="duration" widget="float_time"/>
<button string="Schedule a Meeting"
name="action_make_meeting"
icon="gtk-redo"
type="object" />
<field name="partner_phone"/>
<field name="duration"/>
<field name="date" string="Date" required="1"/>
<field name="user_id"/>
<field name="section_id" colspan="1" widget="selection" />
<button string="Convert to Opportunity"
name="%(phonecall2opportunity_act)d"
+1
View File
@@ -43,6 +43,7 @@
<group col="2" colspan="1">
<separator string="Configuration" colspan="2"/>
<field name="allow_unlink" select="2"/>
<field name="change_responsible"/>
</group>
<separator string="Team Members" colspan="4"/>
<field name="member_ids" nolabel="1" colspan="4"/>
+1 -1
View File
@@ -8,7 +8,7 @@
partner_address_id: base.res_partner_address_1
partner_id: base.res_partner_9
probability: 1.0
stage_id: crm.stage_oppor1
stage_id: crm.stage_lead1
categ_id: crm.categ_oppor2
section_id: crm.section_sales_department
+4 -20
View File
@@ -1,25 +1,6 @@
<openerp>
<data>
<!-- Lead to partner confirmation form -->
<record id="view_crm_lead2partner_create" model="ir.ui.view">
<field name="name">crm.lead2partner.view.create</field>
<field name="model">crm.lead2partner</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Create a Partner?">
<label string="Are you sure you want to create a partner based on this lead ?" colspan="4"/>
<label string="You may have to verify that this partner does not exist already." colspan="4"/>
<separator string="" colspan="4" />
<group col="4" colspan="4">
<button special="cancel" string="_Cancel" icon="gtk-cancel"/>
<button name="open_create_partner" string="Create _Partner" type="object" icon="gtk-ok"/>
</group>
</form>
</field>
</record>
<!-- Lead to Partner form view -->
<record id="view_crm_lead2partner" model="ir.ui.view">
@@ -28,6 +9,9 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Create a Partner">
<separator string="Create a Partner" colspan="4" />
<label string="Are you sure you want to create a partner based on this lead ?" colspan="4"/>
<label string="You may have to verify that this partner does not exist already." colspan="4"/>
<field name="action"/>
<group attrs="{'invisible':[('action','!=','exist')]}">
<field name="partner_id" attrs="{'required': [('action', '=', 'exist')]}"/>
@@ -48,7 +32,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">crm.lead2partner</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_crm_lead2partner_create"/>
<field name="view_id" ref="view_crm_lead2partner"/>
<field name="target">new</field>
</record>
@@ -73,8 +73,8 @@ class crm_phonecall2phonecall(osv.osv_memory):
values = {
'name': this.name,
'user_id': this.user_id and this.user_id.id,
'categ_id': phonecall.categ_id and phonecall.categ_id.id or False,
'section_id': phonecall.section_id and phonecall.section_id.id,
'categ_id': this.categ_id.id,
'section_id': this.section_id.id or (phonecall.section_id and phonecall.section_id.id),
'description': phonecall.description or '',
'partner_id': phonecall.partner_id.id,
'partner_address_id': phonecall.partner_address_id.id,
@@ -94,7 +94,7 @@ class crm_phonecall2phonecall(osv.osv_memory):
'views': [(id2, 'form'), (id3, 'tree'), (False, 'calendar'), (False, 'graph')],
'type': 'ir.actions.act_window',
'res_id': phonecall_id,
'domain': [('id', 'in', [int(phonecall_id)])],
'domain': [('id', '=', phonecall_id)],
'search_view_id': res['res_id']
}
return res
@@ -102,7 +102,10 @@ class crm_phonecall2phonecall(osv.osv_memory):
_columns = {
'name' : fields.char('Call summary', size=64, required=True, select=1),
'user_id' : fields.many2one('res.users',"Assign To"),
'date': fields.datetime('Date'),
'categ_id': fields.many2one('crm.case.categ', 'Category', required=True, \
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.phonecall')]"),
'date': fields.datetime('Date', required=True),
'section_id':fields.many2one('crm.case.section','Sales Team'),
}
@@ -119,10 +122,16 @@ class crm_phonecall2phonecall(osv.osv_memory):
"""
res = super(crm_phonecall2phonecall, self).default_get(cr, uid, fields, context=context)
record_id = context and context.get('active_id', False) or False
if record_id:
phonecall = self.pool.get('crm.phonecall').browse(cr, uid, record_id, context=context)
categ_id = False
data_obj = self.pool.get('ir.model.data')
res_id = data_obj._get_id(cr, uid, 'crm', 'categ_phone2')
if res_id:
categ_id = data_obj.browse(cr, uid, res_id, context=context).res_id
if 'name' in fields:
res.update({'name': phonecall.name})
if 'user_id' in fields:
@@ -131,7 +140,8 @@ class crm_phonecall2phonecall(osv.osv_memory):
res.update({'date': phonecall.date})
if 'section_id' in fields:
res.update({'section_id': phonecall.section_id and phonecall.section_id.id or False})
if 'categ_id' in fields:
res.update({'categ_id': categ_id})
return res
crm_phonecall2phonecall()
@@ -10,16 +10,18 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Schedule Other Call">
<field name="name"/>
<field name="user_id" />
<field name="date" string="Planned Date"/>
<field name="section_id"/>
<separator string=" " colspan="4"/>
<group colspan="4" col="3" >
<label string=" " />
<button name="action_cancel" string="_Cancel" icon="gtk-cancel" special="cancel" />
<button name="action_apply" type="object" string="_Schedule" icon="gtk-go-forward" />
</group>
<separator string="Schedule Other Call" colspan="4"/>
<field name="name"/>
<field name="date" string="Planned Date"/>
<field name="user_id" />
<field name="section_id"/>
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'crm.phonecall')]"/>
<separator string=" " colspan="4"/>
<group colspan="4" col="3" >
<label string=" " />
<button name="action_cancel" string="_Cancel" icon="gtk-cancel" special="cancel" />
<button name="action_apply" type="object" string="_Schedule" icon="gtk-go-forward" />
</group>
</form>
</field>
</record>
@@ -36,4 +38,4 @@
</record>
</data>
</openerp>
</openerp>
@@ -9,6 +9,7 @@
"access_document_directory_content_type_group_system","document.directory.content.type group system","model_document_directory_content_type","base.group_user",1,0,0,0
"access_document_storage_group_document_manager","document.storage document manager","model_document_storage","group_document_manager",1,1,1,1
"access_document_storage_group_system","document.storage group system","model_document_storage","base.group_user",1,0,0,0
"access_document_directory_dctx_all","document.directory.dctx all","model_document_directory_dctx",,1,0,0,0
"access_document_directory_dctx_group_document_manager","document.directory.dctx document manager","model_document_directory_dctx","group_document_manager",1,1,1,1
"access_document_directory_dctx_group_system","document.directory.dctx group system","model_document_directory_dctx","base.group_system",1,1,1,1
"access_report_document_user_group_document_manager","report.document.user document manager","model_report_document_user","document.group_document_manager",1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
9 access_document_directory_content_type_group_system document.directory.content.type group system model_document_directory_content_type base.group_user 1 0 0 0
10 access_document_storage_group_document_manager document.storage document manager model_document_storage group_document_manager 1 1 1 1
11 access_document_storage_group_system document.storage group system model_document_storage base.group_user 1 0 0 0
12 access_document_directory_dctx_all document.directory.dctx all model_document_directory_dctx 1 0 0 0
13 access_document_directory_dctx_group_document_manager document.directory.dctx document manager model_document_directory_dctx group_document_manager 1 1 1 1
14 access_document_directory_dctx_group_system document.directory.dctx group system model_document_directory_dctx base.group_system 1 1 1 1
15 access_report_document_user_group_document_manager report.document.user document manager model_report_document_user document.group_document_manager 1 0 0 0
+3 -2
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@@ -15,12 +15,13 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import event
import wizard
import report
import res_partner
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1
View File
@@ -53,6 +53,7 @@
'wizard/event_make_invoice_view.xml',
'wizard/partner_event_registration_view.xml',
'board_association_view.xml',
'res_partner_view.xml',
],
'demo_xml': ['event_demo.xml', 'board_association_demo.xml'],
'test': ['test/test_event.yml'],
+4 -2
View File
@@ -176,11 +176,13 @@ class event_event(osv.osv):
'note': fields.text('Notes', help="Description or Summary of Event"),
'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}),
"unit_price": fields.float('Cost'),
'partner_id': fields.many2one('res.partner','Teacher'),
'main_speaker_id': fields.many2one('res.partner','Main Speaker'),
'speaker_ids':fields.many2many('res.partner', 'event_speaker_rel', 'speaker_id', 'partner_id', 'Other Speakers'),
'address_id': fields.many2one('res.partner.address','Location Room'),
'teacher_confirmed': fields.boolean('Teacher Confirmed'),
'speaker_confirmed': fields.boolean('Speaker Confirmed'),
'country_id': fields.related('address_id', 'country_id',
type='many2one', relation='res.country', string='Country'),
'language': fields.char('Language',size=64),
}
+9 -5
View File
@@ -57,18 +57,20 @@
<page string="General">
<field name="unit_price"/>
<field name="currency_id"/>
<separator string="Teacher Information" colspan="4"/>
<field name="partner_id"/>
<separator string="Speaker Information" colspan="4"/>
<field name="main_speaker_id" domain="[('speaker','=',True)]"/>
<field name="address_id"/>
<field name="teacher_confirmed"/>
<field name="speaker_ids" domain="[('speaker','=',True)]" colspan="4"/>
<field name="country_id" />
<field name="speaker_confirmed"/>
<field name="language"/>
<separator string="Event description" colspan="4"/>
<field name="parent_id" domain="[('parent_id','child_of','Event')]"/>
<field name="active"/>
<field name="register_min"/>
<field name="register_max"/>
<separator string="Notes" colspan="4"/>
<field name="note" colspan="4" nolabel="1"/>
<!--field name="note" colspan="4" nolabel="1"/-->
<field name="state" select="1"/>
<group col="4" colspan="2">
<button string="Confirm Event" name="button_confirm" states="draft" type="object" icon="gtk-apply"/>
@@ -120,9 +122,11 @@
<field name="arch" type="xml">
<tree string="Events" colors="red:register_min>register_current;black:register_min&lt;=register_current">
<field name="name" string="Name"/>
<field name="user_id"/>
<field name="main_speaker_id"/>
<field name="language"/>
<field name="type"/>
<field name="date_begin"/>
<field name="date_end"/>
<field name="register_min"/>
<field name="register_current"/>
<field name="state"/>
@@ -43,6 +43,7 @@ class report_event_registration(osv.osv):
'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),
'speaker_id':fields.many2one('res.partner', 'Speaker', readonly=True),
}
_order = 'date desc'
def init(self, cr):
@@ -57,6 +58,7 @@ class report_event_registration(osv.osv):
c.event_id as event_id,
e.date_begin as date,
e.user_id as user_id,
e.main_speaker_id as speaker_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,
@@ -75,7 +77,7 @@ class report_event_registration(osv.osv):
group by
to_char(e.date_begin, 'YYYY'),
to_char(e.date_begin, 'MM'),
t.id, e.id, e.date_begin,
t.id, e.id, e.date_begin,e.main_speaker_id,
e.register_max, e.type, e.state, c.event_id, e.user_id,
to_char(e.date_begin, 'YYYY-MM-DD')
)""")
@@ -10,6 +10,7 @@
<tree string="Event on Registration">
<field name="date" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="speaker_id" invisible="1"/>
<field name="year" invisible="1"/>
<field name="day" invisible="1"/>
<field name="month" invisible="1"/>
@@ -85,7 +86,8 @@
<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'}"/>
<filter string="Speaker" name="user" icon="terp-personal+" context="{'group_by': 'speaker_id'}"/>
<!--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'}"/>
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@@ -15,16 +15,22 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import xmlrpclib
from osv import fields,osv
sock = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/wizard')
wiz_id = sock.create('trunk', 1, 'admin', 'procurement.order.compute.all')
sock.execute('trunk', 1, 'admin', wiz_id, {'form': {'po_cycle': 1.0, 'po_lead': 1.0, 'user_id': 3, 'schedule_cycle': 1.0, 'picking_lead': 1.0, 'security_lead': 50.0, 'automatic': False}, 'ids': [], 'report_type': 'pdf', 'model': 'ir.ui.menu', 'id': False}, 'compute', {})
class res_partner(osv.osv):
_inherit = 'res.partner'
_columns = {
'speaker': fields.boolean('Speaker'),
'event_ids': fields.one2many('event.event','main_speaker_id',readonly=True),
'event_registration_ids': fields.one2many('event.registration','partner_id',readonly=True),
}
res_partner()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+44
View File
@@ -0,0 +1,44 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- Partners inherited form -->
<record id="view_speaker_partner_info_form" model="ir.ui.view">
<field name="name">res.partner.speaker.info.inherit</field>
<field name="model">res.partner</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<field name="supplier" position="after">
<field name="speaker"/>
</field>
</field>
</record>
<record id="view_event_partner_info_form" model="ir.ui.view">
<field name="name">res.partner.event.info.inherit</field>
<field name="model">res.partner</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<page string="History" position="inside">
<field name="event_ids" colspan="4" nolabel="1">
<tree string="Events">
<field name="name" string="Event"/>
<field name="main_speaker_id"/>
</tree>
</field>
<field name="event_registration_ids" colspan="4" nolabel="1">
<tree string="Events Registration">
<field name="event_id" />
<field name="partner_id"/>
<field name="unit_price"/>
</tree>
</field>
</page>
</field>
</record>
</data>
</openerp>
+3 -3
View File
@@ -158,9 +158,9 @@ class mailgate_message(osv.osv):
'user_id': fields.many2one('res.users', 'User Responsible', readonly=True),
'message': fields.text('Description'),
'email_from': fields.char('From', size=128, help="Email From"),
'email_to': fields.text('To', help="Email Recipients"),
'email_cc': fields.text('Cc', help="Carbon Copy Email Recipients"),
'email_bcc': fields.text('Bcc', help='Blind Carbon Copy Email Recipients'),
'email_to': fields.char('To', help="Email Recipients", size=256),
'email_cc': fields.char('Cc', help="Carbon Copy Email Recipients", size=256),
'email_bcc': fields.char('Bcc', help='Blind Carbon Copy Email Recipients', size=256),
'message_id': fields.char('Message Id', size=1024, readonly=True, help="Message Id on Email.", select=True),
'references': fields.text('References', readonly=True, help="References emails."),
'description': fields.text('Description'),
+1 -1
View File
@@ -372,7 +372,7 @@ class mrp_repair(osv.osv):
name = operation.name
if operation.product_id.property_account_income:
account_id = operation.product_id.property_account_income
account_id = operation.product_id.property_account_income.id
elif operation.product_id.categ_id.property_account_income_categ:
account_id = operation.product_id.categ_id.property_account_income_categ.id
else:
+27 -1
View File
@@ -31,7 +31,15 @@ class procurement_order(osv.osv):
def _procure_confirm(self, cr, uid, ids=None, use_new_cursor=False, context=None):
'''
use_new_cursor: False or the dbname
Call the scheduler to check the procurement order
@param self: The object pointer
@param cr: The current row, from the database cursor,
@param uid: The current user ID for security checks
@param ids: List of selected IDs
@param use_new_cursor: False or the dbname
@param context: A standard dictionary for contextual values
@return: Dictionary of values
'''
if not context:
context = {}
@@ -126,6 +134,15 @@ class procurement_order(osv.osv):
return {}
def create_automatic_op(self, cr, uid, context=None):
"""
Create procurement of virtual stock < 0
@param self: The object pointer
@param cr: The current row, from the database cursor,
@param uid: The current user ID for security checks
@param context: A standard dictionary for contextual values
@return: Dictionary of values
"""
if not context:
context = {}
product_obj = self.pool.get('product.product')
@@ -167,7 +184,16 @@ class procurement_order(osv.osv):
def _procure_orderpoint_confirm(self, cr, uid, automatic=False,\
use_new_cursor=False, context=None, user_id=False):
'''
Create procurement based on Orderpoint
use_new_cursor: False or the dbname
@param self: The object pointer
@param cr: The current row, from the database cursor,
@param user_id: The current user ID for security checks
@param context: A standard dictionary for contextual values
@param param: False or the dbname
@return: Dictionary of values
"""
'''
if not context:
context = {}
+2 -2
View File
@@ -39,13 +39,13 @@
<field name="uom_type">smaller</field>
</record>
<record id="uom_hour" model="product.uom">
<field name="name">hour</field>
<field name="name">Hour</field>
<field eval="uom_categ_wtime" name="category_id"/>
<field name="factor" eval="8.0"/>
<field name="uom_type">smaller</field>
</record>
<record id="uom_day" model="product.uom">
<field name="name">day</field>
<field name="name">Day</field>
<field eval="uom_categ_wtime" name="category_id"/>
<field name="factor" eval="1.0"/>
</record>
-1
View File
@@ -27,5 +27,4 @@ import report
import wizard
import res_partner
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+2 -3
View File
@@ -26,8 +26,8 @@
"author": "Tiny",
"website": "http://www.openerp.com",
"category": "Generic Modules/Projects & Services",
"depends": ["product", "analytic", "process", "mail_gateway","board"],
"description": """Project management module that track multi-level projects, tasks,
"depends": ["product", "analytic", "mail_gateway", "board"],
"description": """Project management module tracks multi-level projects, tasks,
work done on tasks, eso. It is able to render planning, order tasks, eso.
Dashboard for project members that includes:
* List of my open tasks
@@ -41,7 +41,6 @@ work done on tasks, eso. It is able to render planning, order tasks, eso.
"wizard/project_task_delegate_view.xml",
"security/ir.model.access.csv",
"project_data.xml",
"project_wizard.xml",
"project_view.xml",
"project_report.xml",
"process/task_process.xml",
+2 -2
View File
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<!--
Administrator shortcut
Demo user startup menu
@@ -14,6 +13,7 @@
<field name="sequence">3</field>
<field name="res_id" ref="menu_board_project"/>
</record-->
<record id="base.user_root" model="res.users">
<field name="action_id" ref="open_board_project"/>
</record>
+6 -16
View File
@@ -6,22 +6,6 @@
<field name="name">Project</field>
</record>
<record id="view_task_tree" model="ir.ui.view">
<field name="name">project.task.tree</field>
<field name="model">project.task</field>
<field name="type">tree</field>
<field eval="99" name="priority"/>
<field name="arch" type="xml">
<tree colors="red:date_deadline&lt;current_date;blue:date_deadline==current_date;black:date_deadline&gt;current_date" string="My Tasks">
<field name="name"/>
<field name="project_id"/>
<field name="date_deadline"/>
<field name="planned_hours"/>
<field name="effective_hours"/>
<field name="priority"/>
</tree>
</field>
</record>
<!-- Editable My task -->
<record id="view_task_tree" model="ir.ui.view">
<field name="name">project.task.tree</field>
@@ -39,6 +23,7 @@
</tree>
</field>
</record>
<record id="action_view_task_tree" model="ir.actions.act_window">
<field name="name">My Open Tasks</field>
<field name="res_model">project.task</field>
@@ -47,6 +32,7 @@
<field name="domain">[('user_id','=',uid),('state','=','open')]</field>
<field name="view_id" ref="view_task_tree"/>
</record>
<record id="action_view_pending_task_tree" model="ir.actions.act_window">
<field name="name">My Pending Tasks</field>
<field name="res_model">project.task</field>
@@ -55,6 +41,7 @@
<field name="domain">[('user_id','=',uid),('state','=','pending')]</field>
<field name="view_id" ref="view_task_tree"/>
</record>
<record id="action_view_task_tree_deadline" model="ir.actions.act_window">
<field name="name">My Task's Deadlines</field>
<field name="res_model">project.task</field>
@@ -125,17 +112,20 @@
<field name="usage">menu</field>
<field name="view_id" ref="board_project_form"/>
</record>
<menuitem
id="next_id_86"
name="Dashboard"
icon="terp-graph"
sequence="0"
parent="base.menu_project_report"/>
<menuitem
action="open_board_project"
icon="terp-graph"
id="menu_board_project"
parent="next_id_86"
sequence="1"/>
</data>
</openerp>
+8 -4
View File
@@ -18,6 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
class project_installer(osv.osv_memory):
@@ -26,7 +27,8 @@ class project_installer(osv.osv_memory):
_columns = {
# Project Management
'project_long_term': fields.boolean('Long Term Planning',
'project_long_term': fields.boolean(
'Long Term Planning',
help="Enables long-term projects tracking, including "
"multiple-phase projects and resource allocation handling."),
'project_wiki': fields.boolean('Specifications in a Wiki',
@@ -35,7 +37,7 @@ class project_installer(osv.osv_memory):
help="Tracks and helps employees encode and validate timesheets "
"and attendance."),
'hr_timesheet_invoice': fields.boolean('Invoice Based on Hours',
help="Helps generate invoice based on based on human resources "
help="Helps generate invoice based on human resources "
"costs and general expenses."),
'account_budget': fields.boolean('Budgets',
help="Helps accountants manage analytic and crossover budgets."),
@@ -49,12 +51,14 @@ class project_installer(osv.osv_memory):
help="Implements and tracks the concepts and task types defined "
"in the SCRUM methodology."),
'project_gtd': fields.boolean('Getting Things Done',
help="Embeds the Getting Things Done concepts into OpenERP's "
help="Embeds the 'Getting Things Done concepts' into OpenERP's "
"project management."),
}
_defaults={
'project_crm': True,
'project_crm': True,
}
project_installer()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+32 -34
View File
@@ -18,8 +18,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from lxml import etree
import datetime
import time
from tools.translate import _
@@ -38,6 +38,7 @@ class project_task_type(osv.osv):
_defaults = {
'sequence': 1
}
project_task_type()
class project(osv.osv):
@@ -46,10 +47,8 @@ class project(osv.osv):
_inherits = {'account.analytic.account':"category_id"}
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
if context is None:
context = {}
if user == 1:
return super(project, self).search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
return super(project, self).search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
if context and context.has_key('user_prefence') and context['user_prefence']:
cr.execute("""SELECT project.id FROM project_project project
LEFT JOIN account_analytic_account account ON account.id = project.category_id
@@ -61,8 +60,6 @@ class project(osv.osv):
context=context, count=count)
def _complete_name(self, cr, uid, ids, name, args, context=None):
if context is None:
context = {}
res = {}
for m in self.browse(cr, uid, ids, context=context):
res[m.id] = (m.parent_id and (m.parent_id.name + '/') or '') + m.name
@@ -73,8 +70,6 @@ class project(osv.osv):
parent=parent)
def onchange_partner_id(self, cr, uid, ids, part=False, context=None):
if context is None:
context = {}
partner_obj = self.pool.get('res.partner')
if not part:
return {'value':{'contact_id': False, 'pricelist_id': False}}
@@ -84,8 +79,6 @@ class project(osv.osv):
return {'value':{'contact_id': addr['contact'], 'pricelist_id': pricelist_id}}
def _progress_rate(self, cr, uid, ids, names, arg, context=None):
if context is None:
context = {}
res = {}.fromkeys(ids, 0.0)
progress = {}
if not ids:
@@ -143,13 +136,16 @@ class project(osv.osv):
'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages'),
'project_escalation_id': fields.many2one('project.project','Project Escalation', help='If any issue is escalated from the current Project, it will be listed under the project selected here.'),
}
_order = "sequence"
_defaults = {
'active': True,
'priority': 1,
'sequence': 10,
'warn_manager': True,
}
def _check_dates(self, cr, uid, ids):
leave = self.read(cr, uid, ids[0], ['date_start', 'date'])
if leave['date_start'] and leave['date']:
@@ -168,6 +164,7 @@ class project(osv.osv):
(_check_dates, 'Error! project start-date must be lower then project end-date.', ['date_start', 'date']),
(_check_escalation, 'Error! You cannot assign escalation to the same project!', ['project_escalation_id'])
]
def set_template(self, cr, uid, ids, context=None):
res = self.setActive(cr, uid, ids, value=False, context=context)
return res
@@ -255,16 +252,11 @@ class project(osv.osv):
'search_view_id': search_view['res_id'],
'nodestroy': True
}
# return result
# set active value for a project, its sub projects and its tasks
def setActive(self, cr, uid, ids, value=True, context=None):
if context is None:
context = {}
task_obj = self.pool.get('project.task')
for proj in self.browse(cr, uid, ids, context=None):
if context is None:
context = {}
self.write(cr, uid, [proj.id], {'state': value and 'open' or 'template'}, context)
cr.execute('select id from project_task where project_id=%s', (proj.id,))
tasks_id = [x[0] for x in cr.fetchall()]
@@ -273,9 +265,8 @@ class project(osv.osv):
child_ids = self.search(cr, uid, [('parent_id','=', proj.id)])
if child_ids:
self.setActive(cr, uid, child_ids, value, context=None)
if context is None:
context = {}
return True
project()
class task(osv.osv):
@@ -285,16 +276,12 @@ class task(osv.osv):
_date_name = "date_start"
def _str_get(self, task, level=0, border='***', context=None):
if context is None:
context = {}
return border+' '+(task.user_id and task.user_id.name.upper() or '')+(level and (': L'+str(level)) or '')+(' - %.1fh / %.1fh'%(task.effective_hours or 0.0,task.planned_hours))+' '+border+'\n'+ \
border[0]+' '+(task.name or '')+'\n'+ \
(task.description or '')+'\n\n'
# Compute: effective_hours, total_hours, progress
def _hours_get(self, cr, uid, ids, field_names, args, context=None):
if context is None:
context = {}
res = {}
cr.execute("SELECT task_id, COALESCE(SUM(hours),0) FROM project_task_work WHERE task_id IN %s GROUP BY task_id",(tuple(ids),))
hours = dict(cr.fetchall())
@@ -314,6 +301,8 @@ class task(osv.osv):
return {'value':{'remaining_hours': planned - effective}}
def _default_project(self, cr, uid, context=None):
if context is None:
context = {}
if 'project_id' in context and context['project_id']:
return int(context['project_id'])
return False
@@ -323,15 +312,11 @@ class task(osv.osv):
#]
def copy_data(self, cr, uid, id, default={}, context=None):
if context is None:
context = {}
default = default or {}
default['work_ids'] = []
return super(task, self).copy_data(cr, uid, id, default, context)
def _check_dates(self, cr, uid, ids, context=None):
if context is None:
context = {}
task = self.read(cr, uid, ids[0], ['date_start', 'date_end'])
if task['date_start'] and task['date_end']:
if task['date_start'] > task['date_end']:
@@ -346,7 +331,7 @@ class task(osv.osv):
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of tasks."),
'type': fields.many2one('project.task.type', 'Stage',),
'state': fields.selection([('draft', 'Draft'),('open', 'In Progress'),('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True,
help='If the task is created the state \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\
help='If the task is created the state is \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\
\n If the task is over, the states is set to \'Done\'.'),
'date_start': fields.datetime('Starting Date'),
'date_end': fields.datetime('Ending Date'),
@@ -370,6 +355,7 @@ class task(osv.osv):
'manager_id': fields.related('project_id', 'category_id', 'user_id', type='many2one', relation='res.users', string='Project Manager'),
'company_id': fields.many2one('res.company', 'Company'),
}
_defaults = {
'state': 'draft',
'priority': '2',
@@ -380,6 +366,7 @@ class task(osv.osv):
'project_id': _default_project,
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.task', context=c)
}
_order = "sequence, priority, date_start, id"
_constraints = [
@@ -388,10 +375,9 @@ class task(osv.osv):
#
# Override view according to the company definition
#
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
users_obj = self.pool.get('res.users')
if context is None:
context = {}
obj_tm = users_obj.browse(cr, uid, uid, context).company_id.project_time_mode_id
tm = obj_tm and obj_tm.name or 'Hours'
@@ -424,6 +410,10 @@ class task(osv.osv):
mod_obj = self.pool.get('ir.model.data')
request = self.pool.get('res.request')
tasks = self.browse(cr, uid, ids)
task_id = ids[0]
cntx = {}
if len(args):
cntx = args[0]
for task in tasks:
project = task.project_id
if project:
@@ -437,8 +427,7 @@ class task(osv.osv):
'ref_doc1': 'project.task,%d'% (task.id,),
'ref_doc2': 'project.project,%d'% (project.id,),
})
elif project.warn_manager:
task_id = ids[0]
elif project.warn_manager and cntx.get('mail_send',False):
mail_send = True
message = _('Task ') + " '" + task.name + "' "+ _("is Done.")
self.log(cr, uid, task.id, message)
@@ -454,11 +443,11 @@ class task(osv.osv):
if mail_send:
model_data_ids = mod_obj.search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_project_close_task')])
resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id']
args[0].update({'task_id': task_id})
cntx.update({'task_id': task_id})
return {
'name': _('Email Send to Customer'),
'view_type': 'form',
'context': args[0], # improve me
'context': cntx, # improve me
'view_mode': 'tree,form',
'res_model': 'close.task',
'views': [(resource_id,'form')],
@@ -466,7 +455,9 @@ class task(osv.osv):
'target': 'new',
'nodestroy': True
}
return True
else:
self.write(cr, uid, [task_id], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
return False
def do_reopen(self, cr, uid, ids, *args):
request = self.pool.get('res.request')
@@ -562,11 +553,14 @@ class project_work(osv.osv):
'user_id': fields.many2one('res.users', 'Done by', required=True),
'company_id': fields.related('task_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True)
}
_defaults = {
'user_id': lambda obj, cr, uid, context: uid,
'date': time.strftime('%Y-%m-%d %H:%M:%S')
}
_order = "date desc"
def create(self, cr, uid, vals, *args, **kwargs):
if 'hours' in vals and (not vals['hours']):
vals['hours'] = 0.00
@@ -588,10 +582,12 @@ class project_work(osv.osv):
for work in self.browse(cr, uid, ids):
cr.execute('update project_task set remaining_hours=remaining_hours + %s where id=%s', (work.hours, work.task_id.id))
return super(project_work,self).unlink(cr, uid, ids, *args, **kwargs)
project_work()
class config_compute_remaining(osv.osv_memory):
_name='config.compute.remaining'
def _get_remaining(self,cr, uid, ctx):
task_obj = self.pool.get('project.task')
if 'active_id' in ctx:
@@ -638,6 +634,7 @@ config_compute_remaining()
class message(osv.osv):
_name = "project.message"
_description = "Message"
_columns = {
'subject': fields.char('Subject', size=128, required="True"),
'project_id': fields.many2one('project.project', 'Project', ondelete='cascade'),
@@ -655,7 +652,7 @@ class message(osv.osv):
_defaults = {
'user_id': lambda self,cr,uid,ctx: uid,
'date': lambda self,cr,uid,ctx: time.strftime('%Y-%m-%d'),
'date': time.strftime('%Y-%m-%d'),
'project_id': _default_project
}
@@ -667,6 +664,7 @@ class users(osv.osv):
_columns = {
'context_project_id': fields.many2one('project.project', 'Project')
}
users()
class account_analytic_account(osv.osv):
+1
View File
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--
Requests Links
-->
+5 -4
View File
@@ -45,7 +45,7 @@
<record id="project_project_22" model="project.project">
<field name="priority">20</field>
<field name="parent_id" ref="project_project_9"/>
<field name="name">Specific Developements</field>
<field name="name">Specific Developments</field>
<field name="manager" ref="base.user_root"/>
<field eval="[(6, 0, [ref('project_tt_specification'), ref('project_tt_development')])]" name="type_ids"/>
</record>
@@ -64,7 +64,7 @@
<field name="type" ref="project_tt_development"/>
<field name="user_id" ref="base.user_root"/>
<field name="project_id" ref="project_project_22"/>
<field name="description">BoM, After sales returns, interventions. Tracability.</field>
<field name="description">BoM, After sales returns, interventions. Traceability.</field>
<field name="name">Specific adaptation to MRP</field>
</record>
<record id="project_task_130" model="project.task">
@@ -146,7 +146,7 @@
<field name="remaining_hours">24.0</field>
<field name="user_id" ref="base.user_root"/>
<field name="project_id" ref="project_project_21"/>
<field name="name">MRP; functionnal layer</field>
<field name="name">MRP; functional layer</field>
<field name="state">done</field>
<field eval="time.strftime('%Y-%m-%d 12:12')" name="date_close"/>
</record>
@@ -172,7 +172,7 @@
<field name="remaining_hours">32.0</field>
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
<field name="project_id" ref="project_project_22"/>
<field name="name">Customer docs</field>
<field name="name">Customer doc</field>
</record>
<record id="project_task_197" model="project.task">
<field name="sequence">30</field>
@@ -266,5 +266,6 @@
- Create Users</field>
<field name="subject">Configuration steps</field>
</record>
</data>
</openerp>
+6 -5
View File
@@ -1,12 +1,13 @@
<openerp>
<data>
<record id="view_project_installer" model="ir.ui.view">
<field name="name">project.installer.view</field>
<field name="model">project.installer</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.res_config_installer"/>
<field name="arch" type="xml">
<data>
<data>
<form position="attributes">
<attribute name="string">Project Modules Installation</attribute>
</form>
@@ -16,12 +17,11 @@
<xpath expr='//separator[@string="vsep"]' position='attributes'>
<attribute name='string'></attribute>
</xpath>
<xpath expr="//label[@string='description']"
position="attributes">
<attribute name="string">Various OpenERP applications are available to bring your project management to the next levels of control and flexibility.</attribute>
<xpath expr="//label[@string='description']" position="attributes">
<attribute name="string">Various OpenERP applications are available to bring your project management to the next levels of control and flexibility.</attribute>
</xpath>
<xpath expr="//button[@string='Install Modules']" position="attributes">
<attribute name="string">Configure</attribute>
<attribute name="string">Configure</attribute>
</xpath>
<group colspan="8">
<field name="project_crm"/>
@@ -65,5 +65,6 @@
</xpath>
</field>
</record>
</data>
</openerp>
+5 -17
View File
@@ -19,24 +19,13 @@
#
##############################################################################
import time
import re
import os
import mx.DateTime
import base64
from tools.translate import _
import tools
from osv import fields,osv,orm
from osv.orm import except_orm
from osv import fields,osv
class project_tasks(osv.osv):
_name = "project.task"
_inherit = "project.task"
def msg_new(self, cr, uid, msg):
def msg_new(self, cr, uid, msg):
mailgate_obj = self.pool.get('mail.gateway')
msg_body = mailgate_obj.msg_body_get(msg)
data = {
@@ -72,14 +61,11 @@ class project_tasks(osv.osv):
if msg_actions['priority'] in ('1','2','3','4','5'):
data['priority'] = msg_actions['priority']
self.write(cr, uid, [id], data)
getattr(self,act)(cr, uid, [id])
return True
def message_followers(self, cr, uid, ids, context=None):
if context is None:
context = {}
res = []
if isinstance(ids, (str, int, long)):
select = [ids]
@@ -93,6 +79,8 @@ class project_tasks(osv.osv):
return res
def msg_send(self, cr, uid, id, *args, **argv):
return True
return True
project_tasks()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+28 -7
View File
@@ -1,10 +1,29 @@
# -*- 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 pooler
import datetime
def timeformat_convert(cr, uid, time_string, context=None):
def timeformat_convert(cr, uid, time_string):
# Function to convert input time string:: 8.5 to output time string 8:30
if context is None:
context = {}
split_list = str(time_string).split('.')
hour_part = split_list[0]
mins_part = split_list[1]
@@ -12,7 +31,7 @@ def timeformat_convert(cr, uid, time_string, context=None):
converted_string = hour_part + ':' + str(round_mins)[0:2]
return converted_string
def leaves_resource(cr,uid,calendar_id,resource_id=False,resource_calendar=False):
def leaves_resource(cr, uid, calendar_id, resource_id=False, resource_calendar=False):
# To get the leaves for the resource_ids working on phase
pool = pooler.get_pool(cr.dbname)
@@ -31,20 +50,20 @@ def leaves_resource(cr,uid,calendar_id,resource_id=False,resource_calendar=False
leaves.sort()
return leaves
def compute_working_calendar(cr,uid,calendar_id):
def compute_working_calendar(cr, uid, calendar_id):
# To change the format of working calendar to bring it into 'faces' format
pool = pooler.get_pool(cr.dbname)
resource_week_pool = pool.get('resource.calendar.week')
time_range = "8:00-8:00"
non_working = ""
wk = {"0":"mon","1":"tue","2":"wed","3":"thu","4":"fri","5":"sat","6":"sun"}
wk = {"0":"mon", "1":"tue", "2":"wed", "3":"thu", "4":"fri", "5":"sat", "6":"sun"}
wk_days = {}
wk_time = {}
wktime_list = []
wktime_cal = []
week_ids = resource_week_pool.search(cr, uid, [('calendar_id','=',calendar_id)])
week_obj = resource_week_pool.read(cr, uid, week_ids, ['dayofweek','hour_from','hour_to'])
week_obj = resource_week_pool.read(cr, uid, week_ids, ['dayofweek', 'hour_from', 'hour_to'])
# Converting time formats into appropriate format required
# and creating a list like [('mon', '8:00-12:00'), ('mon', '13:00-18:00')]
@@ -80,3 +99,5 @@ def compute_working_calendar(cr,uid,calendar_id):
wktime_cal.append((non_working[:-1],time_range))
return wktime_cal
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+13 -9
View File
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<menuitem
icon="terp-project" id="base.menu_main_pm"
name="Project" sequence="10"
@@ -148,6 +149,7 @@
<field name="name" string="Project Name"/>
<field name="user_id" string="Project Manager"/>
<field name="partner_id" string="Partner"/>
<field name="parent_id" invisible="1"/>
<field name="planned_hours" widget="float_time"/>
<field name="total_hours" widget="float_time"/>
<field name="effective_hours" widget="float_time"/>
@@ -252,18 +254,19 @@
</group>
<notebook colspan="4">
<page string="Information">
<group col="2" colspan="2">
<field
name="planned_hours"
widget="float_time"
attrs="{'readonly':[('state','!=','draft')]}"
on_change="onchange_planned(planned_hours, effective_hours)"/>
<field name="effective_hours" widget="float_time"/>
</group>
<group col="3" colspan="2">
<field
name="planned_hours"
widget="float_time"
attrs="{'readonly':[('state','!=','draft')]}"
on_change="onchange_planned(planned_hours, effective_hours)"/>
<field name="remaining_hours" widget="float_time" attrs="{'readonly':[('state','!=','draft')]}" colspan="2"/>
<button name="%(action_config_compute_remaining)d" string="Reevaluate" type="action" colspan="1" target="new" states="open,pending" icon="gtk-edit"/>
</group>
<group col="2" colspan="2">
<field name="delay_hours" widget="float_time"/>
<field name="effective_hours" widget="float_time"/>
<field name="delay_hours" widget="float_time"/>
</group>
<field colspan="4" name="description" nolabel="1" attrs="{'readonly':[('state','=','done')]}" widget="text_wiki"/>
@@ -647,5 +650,6 @@
<act_window domain="[('user_id', '=', active_id),('date', '&gt;=', time.strftime('%Y-%m-01'))]" id="act_res_users_2_project_task_work_month" name="Month works" res_model="project.task.work" src_model="res.users" view_mode="tree,form" view_type="form"/>
<act_window domain="[('project_id', '=', active_id)]" id="act_project_messages" name="Messages" res_model="project.message" src_model="project.project"/>
</data>
</openerp>
-13
View File
@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--<wizard id="wizard_close_task" menu="False" model="project.task" name="project.task.close" string="Close Task"/>-->
<!--<wizard id="wizard_delegate_task" menu="False" model="project.task" name="project.task.delegate" string="Delegate Task"/>-->
<!--<wizard
id="wizard_duplicate_template"
menu="False"
model="project.project"
name="project.duplicate.template" string="Duplicate Template"/>
-->
</data>
</openerp>
+1
View File
@@ -18,6 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import project_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+3
View File
@@ -118,6 +118,7 @@ class report_project_task_user(osv.osv):
t.type
""")
report_project_task_user()
#This class is generated for project deshboard purpose
@@ -162,6 +163,7 @@ class project_vs_remaining_hours(osv.osv):
GROUP BY pur.uid,aaa.state,aaa.name
)
""")
project_vs_remaining_hours()
class task_by_days(osv.osv):
@@ -192,6 +194,7 @@ class task_by_days(osv.osv):
to_char(pt.create_date, 'YYYY-MM-DD'),pt.state,pt.project_id
)
""")
task_by_days()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+10 -9
View File
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<menuitem id="base.menu_project_report" name="Reporting" parent="base.menu_main_pm" sequence="50"/>
<record id="view_task_project_user_tree" model="ir.ui.view">
@@ -42,13 +43,13 @@
<field name="model">report.project.task.user</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Tasks Analysis" type="bar">
<field name="name"/>
<field name="state" group="True"/>
<field name="no_of_days" operator="+"/>
</graph>
</field>
</record>
<graph string="Tasks Analysis" type="bar">
<field name="name"/>
<field name="state" group="True"/>
<field name="no_of_days" operator="+"/>
</graph>
</field>
</record>
<record id="view_task_project_user_search" model="ir.ui.view">
<field name="name">report.project.task.user.search</field>
@@ -174,7 +175,7 @@
</field>
</record>
<record id="action_project_vs_remaining_hours_graph" model="ir.actions.act_window">
<record id="action_project_vs_remaining_hours_graph" model="ir.actions.act_window">
<field name="name">Project and remaining hours</field>
<field name="res_model">project.vs.remaining.hours</field>
<field name="view_type">form</field>
@@ -184,7 +185,7 @@
</record>
<!-- Views and action for project issue dashboard -->
<record id="view_task_by_days_tree" model="ir.ui.view">
<record id="view_task_by_days_tree" model="ir.ui.view">
<field name="name">task.by.days.tree</field>
<field name="model">task.by.days</field>
<field name="type">tree</field>
+1 -1
View File
@@ -23,7 +23,7 @@ from osv import fields,osv
class res_partner(osv.osv):
""" Inherits partner and adds CRM information in the partner form """
""" Inherits partner and adds Tasks information in the partner form """
_inherit = 'res.partner'
_columns = {
'task_ids': fields.one2many('project.task', 'partner_id', 'Tasks'),
+1
View File
@@ -20,6 +20,7 @@
</page>
</field>
</record>
</data>
</openerp>
+15 -5
View File
@@ -19,8 +19,9 @@
#
##############################################################################
from osv import fields, osv
import time
from osv import fields, osv
from tools.translate import _
from tools import email_send as email
@@ -42,7 +43,7 @@ class project_close_task(osv.osv_memory):
if 'task_id' in context:
task = self.pool.get('project.task').browse(cr, uid, context['task_id'])
partner_id = task.partner_id or task.project_id.partner_id
if partner_id and partner_id.address[0].email:
if partner_id and len(partner_id.address) and partner_id.address[0].email:
email = partner_id.address[0].email
return email
@@ -54,10 +55,15 @@ class project_close_task(osv.osv_memory):
return task.description or task.name
return ''
_defaults={
_defaults = {
'email': _get_email,
'description': _get_desc,
}
def close(self, cr, uid, ids, context=None):
if 'task_id' in context:
self.pool.get('project.task').write(cr, uid, [context['task_id']], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
return {}
def confirm(self, cr, uid, ids, context=None):
if context is None:
@@ -67,8 +73,10 @@ class project_close_task(osv.osv_memory):
close_task = self.read(cr, uid, ids[0], [])
to_adr = close_task['email']
description = close_task['description']
if 'task_id' in context:
for task in self.pool.get('project.task').browse(cr, uid, [context['task_id']], context=context):
task_obj = self.pool.get('project.task')
for task in task_obj.browse(cr, uid, [context['task_id']], context=context):
project = task.project_id
subject = "Task '%s' closed" % task.name
if task.user_id and task.user_id.address_id and task.user_id.address_id.email:
@@ -89,9 +97,11 @@ class project_close_task(osv.osv_memory):
footer = (project.warn_footer or '') % val
body = u'%s\n%s\n%s\n\n-- \n%s' % (header, description, footer, signature)
email(from_adr, [to_adr], subject, body.encode('utf-8'), email_bcc=[from_adr])
task_obj.write(cr, uid, [task.id], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
else:
raise osv.except_osv(_('Error'), _("Couldn't send mail because the contact for this task (%s) has no email address!") % contact.name)
raise osv.except_osv(_('Error'), _("Please specify the email address of partner."))
return {}
project_close_task()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -16,9 +16,11 @@
<newline/>
<field name="description" />
</group>
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="_Close"/>
<button icon="gtk-ok" name="confirm" string="Send Mail" type="object"/>
<separator string="" colspan="6"/>
<group colspan="6" col="6">
<button icon="gtk-ok" name="confirm" string="Send and Close" type="object"/>
<button icon="gtk-ok" string="Close" name="close" type="object"/>
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
</group>
</form>
</field>
@@ -102,19 +102,20 @@ class project_task_delegate(osv.osv_memory):
'description': delegate_data['new_task_description'] or '',
'child_ids': [],
'work_ids': []
})
}, context)
task_obj.write(cr, uid, [task.id], {
'remaining_hours': delegate_data['planned_hours_me'],
'planned_hours': delegate_data['planned_hours_me'] + (task.effective_hours or 0.0),
'name': newname,
})
}, context)
if delegate_data['state'] == 'pending':
task_obj.do_pending(cr, uid, [task.id])
task_obj.do_pending(cr, uid, [task.id], context)
else:
task_obj.do_close(cr, uid, [task.id])
delegrate_user = user_obj.browse(cr, uid, delegate_data['user_id'], context=context)
message = _('Task ') + " '" + delegate_data['name'] + "' "+ _("is Delegated to User:") +" '"+ delegrate_user.name +"' "
self.log(cr, uid, task.id, message)
context.update({'mail_send': False} )
task_obj.do_close(cr, uid, [task.id], context)
delegrate_user = user_obj.browse(cr, uid, delegate_data['user_id'], context=context)
message = _('Task ') + " '" + delegate_data['name'] + "' "+ _("is Delegated to User:") +" '"+ delegrate_user.name +"' "
self.log(cr, uid, task.id, message)
return {}
project_task_delegate()
-1
View File
@@ -34,7 +34,6 @@
'crm',
'project',
'hr_timesheet_sheet',
'resource'
],
'init_xml': [
'project_issue_data.xml'
+1 -3
View File
@@ -144,7 +144,6 @@ class project_issue(osv.osv, crm.crm_case):
'create_date': fields.datetime('Creation Date', readonly=True),
'write_date': fields.datetime('Update Date', readonly=True),
'date_deadline': fields.date('Deadline'),
'date_closed': fields.datetime('Closed', readonly=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team', \
select=True, help='Sales team to which Case belongs to.\
Define Responsible user and Email account for mail gateway.'),
@@ -160,7 +159,7 @@ class project_issue(osv.osv, crm.crm_case):
\nWhen the case is over, the state is set to \'Done\'.\
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
'email_from': fields.char('Email', size=128, help="These people will receive email."),
'email_cc': fields.text('Watchers Emails', size=252, help="These people\
'email_cc': fields.char('Watchers Emails', size=256, help="These people\
will receive a copy of the future" \
" communication between partner and users by email"),
'date_open': fields.datetime('Opened', readonly=True),
@@ -391,7 +390,6 @@ class project_issue(osv.osv, crm.crm_case):
res = self.write(cr, uid, ids, vals)
return res
def msg_send(self, cr, uid, id, *args, **argv):
""" Send The Message
+1 -1
View File
@@ -154,9 +154,9 @@
<tree string="Issue Tracker Tree" colors="red:state=='open';blue:state=='pending';grey:state in ('cancel', 'done')">
<field name="id"/>
<field name="create_date"/>
<field name="project_id" invisible="1"/>
<field name="name"/>
<field name="partner_id"/>
<field name="project_id" />
<field name="priority" string="Severity"/>
<field name="stage_id" string="Resolution"/>
<button icon="gtk-go-back" string="" name="stage_previous" type="object"
@@ -52,7 +52,7 @@ class project_issue_report(osv.osv):
_columns = {
'name': fields.char('Year', size=64, required=False, readonly=True),
'user_id':fields.many2one('res.users', 'Responsible', readonly=True),
'user_id2':fields.many2one('res.users', 'Assigned To', readonly=True),
'user_id2':fields.many2one('res.users', 'Assignee', readonly=True),
'section_id':fields.many2one('crm.case.section', 'Section', readonly=True),
'state': fields.selection(AVAILABLE_STATES, 'State', size=16, readonly=True),
'avg_answers': fields.function(_get_data, string='Avg. Answers', method=True, type="integer"),
@@ -66,17 +66,17 @@ class project_issue_report(osv.osv):
('11', 'November'), ('12', 'December')], 'Month', readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'day': fields.char('Day', size=128, readonly=True),
'opening_date': fields.date('Opening Date', readonly=True),
'opening_date': fields.date('Date of Opening', readonly=True),
'creation_date': fields.date('Creation Date', readonly=True),
'date_closed': fields.date('Closed Date', readonly=True),
'date_closed': fields.date('Date of Closing', readonly=True),
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'project.issue')]"),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('object_id.model', '=', 'project.issue')]"),
'nbr': fields.integer('# of Issues', readonly=True),
'working_hours_open': fields.float('# Working Open Hours', readonly=True),
'working_hours_close': fields.float('# Working Closing Hours', readonly=True),
'delay_open': fields.float('Avg opening Delay', digits=(16,2), readonly=True, group_operator="avg",
'working_hours_open': fields.float('Avg. Working Hours to Open', readonly=True),
'working_hours_close': fields.float('Avg. Working Hours to Close', readonly=True),
'delay_open': fields.float('Avg. Delay to Open', digits=(16,2), readonly=True, group_operator="avg",
help="Number of Days to close the project issue"),
'delay_close': fields.float('Avg Closing Delay', digits=(16,2), readonly=True, group_operator="avg",
'delay_close': fields.float('Avg. Delay to Close', digits=(16,2), readonly=True, group_operator="avg",
help="Number of Days to close the project issue"),
'company_id' : fields.many2one('res.company', 'Company'),
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
@@ -29,6 +29,7 @@ class project_issue(osv.osv):
'timesheet_ids': fields.one2many('hr.analytic.timesheet', 'issue_id', 'Timesheets'),
'analytic_account_id': fields.related('project_id', 'category_id', string='Analytic Account')
}
project_issue()
class account_analytic_line(osv.osv):
@@ -29,4 +29,4 @@
</field>
</record>
</data>
</openerp>
</openerp>
+1 -1
View File
@@ -25,7 +25,7 @@
"author": "Tiny",
"website": "http://www.openerp.com",
"category": "Generic Modules/Projects & Services",
"depends": ["project", "resource"],
"depends": ["resource", "project"],
"description": """
Long Term Project management module that tracks planning, scheduling, resources allocation.
@@ -114,7 +114,7 @@ class project_phase(osv.osv):
'responsible_id': lambda obj,cr,uid,context: uid,
'state': 'draft',
'sequence': 10,
'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', 'Day')], context=c)[0]
'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', 'day')], context=c)[0]
}
_order = "name"
_constraints = [
@@ -61,7 +61,6 @@ class project_compute_phases(osv.osv_memory):
resource_obj = self.pool.get('resource.resource')
uom_obj = self.pool.get('product.uom')
phase_resource_obj = False
if context is None:
context = {}
if phase:
@@ -134,14 +133,13 @@ class project_compute_phases(osv.osv_memory):
if context is None:
context = {}
project_obj = self.pool.get('project.project')
phase_obj = self.pool.get('project.phase')
data = self.read(cr, uid, ids, [], context=context)[0]
if not data['project_id'] and data['target_project'] == 'one':
raise osv.except_osv(_('Error!'), _('Please Specify Project to be schedule'))
if data['project_id']: # If project mentioned find its phases
project_id = project_obj.browse(cr, uid, data['project_id'], context=context)
phase_ids = phase_obj.search(cr, uid, [('project_id', '=', project_id.id),
project_id = data['project_id']
phase_ids = phase_obj.search(cr, uid, [('project_id', '=', project_id),
('state', 'in', ['draft', 'open', 'pending']),
('previous_phase_ids', '=', False)
])
@@ -160,4 +160,5 @@ class project_schedule_task(osv.osv_memory):
return {}
project_schedule_task()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+2 -2
View File
@@ -26,8 +26,8 @@
"depends": ["project"],
"author": "Tiny",
"description": """
This module provides the functionality to send messages within a project.'
A user can send messages individually to other user also he can broadcast
This module provides the functionality to send messages within a project.
A user can send messages individually to other user. He can even broadcast
it to all the users.
""",
'website': 'http://www.openerp.com',
+9 -4
View File
@@ -498,7 +498,10 @@ class report_account_analytic_planning_stat(osv.osv):
WHERE user_id=%s and account_id=%s and date>=%s and date<=%s''', (line.user_id.id, line.account_id.id, line.planning_id.date_from, line.planning_id.date_to))
else:
cr.execute('SELECT sum(unit_amount) FROM account_analytic_line WHERE account_id=%s AND date>=%s AND date<=%s', (line.account_id.id, line.planning_id.date_from, line.planning_id.date_to))
result[line.id] = cr.fetchone()[0] * div2
sum = cr.fetchone()
if sum and sum[0]:
result[line.id] = sum[0] * div2
return result
def _sum_amount_tasks(self, cr, uid, ids, name, args, context=None):
@@ -527,13 +530,15 @@ WHERE user_id=%s and account_id=%s and date>=%s and date<=%s''', (line.user_id.i
WHERE
''' + where + '''
project_id IN (select id from project_project where category_id=%s) AND
date_close>=%s AND
date_close<=%s''', (
date_end>=%s AND
date_end<=%s''', (
line.account_id.id,
line.planning_id.date_from,
line.planning_id.date_to)
)
result[line.id] = cr.fetchone()[0] /div * div2
sum = cr.fetchone()
if sum and sum[0]:
result[line.id] = sum[0] /div * div2
return result
_columns = {
@@ -37,11 +37,12 @@ class project_project(osv.osv):
for task in prj.tasks:
start_dt = (datetime(*time.strptime(task.date_start,'%Y-%m-%d %H:%M:%S')[:6])+(new_end_date-old_end_date)).strftime('%Y-%m-%d %H:%M:%S')
if task.date_deadline:
deadline_dt = (datetime(*time.strptime(task.date_deadline,'%Y-%m-%d %H:%M:%S')[:6])+(c-d)).strftime('%Y-%m-%d %H:%M:%S')
deadline_dt = (datetime(*time.strptime(task.date_deadline,'%Y-%m-%d')[:6])+(new_end_date-old_end_date)).strftime('%Y-%m-%d %H:%M:%S')
self.pool.get('project.task').write(cr, uid, task.id, {'date_start':start_dt, 'date_deadline':deadline_dt})
else:
self.pool.get('project.task').write(cr, uid, task.id, {'date_start':start_dt})
return super(project_project,self).write(cr, uid, ids, vals, *args, **kwargs)
project_project()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -3,7 +3,7 @@
-
!record {model: project.project, id: project_project_retroplanning0}:
company_id: base.main_company
date: '2010-06-11'
date: '2010-06-10'
name: Retro Planning
@@ -84,10 +84,10 @@ class project_work(osv.osv):
timeline_id = obj_timesheet.create(cr, uid, vals=vals_line, context=kwargs['context'])
# Compute based on pricetype
amount_unit=obj_timesheet.on_change_unit_amount(cr, uid, timeline_id,
amount_unit = obj_timesheet.on_change_unit_amount(cr, uid, timeline_id,
prod_id, amount, unit, context=kwargs['context'])
vals_line['amount'] = (-1) * vals['hours']* (amount_unit['value']['amount'] or 0.0)
if amount_unit:
vals_line['amount'] = (-1) * vals['hours']* (amount_unit.get('value',{}).get('amount',0.0) or 0.0)
obj_timesheet.write(cr, uid, [timeline_id], vals_line, {})
vals['hr_analytic_timesheet_id'] = timeline_id
return super(project_work,self).create(cr, uid, vals, *args, **kwargs)
@@ -120,8 +120,10 @@ class project_work(osv.osv):
unit = False
amount_unit=obj.on_change_unit_amount(cr, uid, line_id,
vals_line['product_id'], vals_line['unit_amount'], unit, context=context)
vals_line['amount'] = (-1) * vals['hours'] * (amount_unit['value']['amount'] or 0.0)
if amount_unit:
vals_line['amount'] = (-1) * vals['hours'] * (amount_unit.get('value',{}).get('amount',0.0) or 0.0)
obj.write(cr, uid, [line_id], vals_line, context=context)
return super(project_work,self).write(cr, uid, ids, vals, context)
+3 -4
View File
@@ -36,9 +36,7 @@
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['base', 'account', 'stock', 'process', 'procurement'],
'init_xml': [],
'update_xml': [
'data': [
'security/purchase_security.xml',
'security/ir.model.access.csv',
'purchase_workflow.xml',
@@ -60,8 +58,9 @@
'test/purchase_from_order.yml',
'test/purchase_from_manual.yml',
# 'test/purchase_from_picking.yml',
'purchase_unit_test.xml'
],
'demo_xml': ['purchase_demo.xml','purchase_unit_test.xml'],
'demo': ['purchase_demo.xml'],
'installable': True,
'active': False,
'certificate': '0057234283549',
+3 -2
View File
@@ -425,6 +425,7 @@ class purchase_order(osv.osv):
'invoice_state': istate,
'purchase_id': order.id,
'company_id': order.company_id.id,
'move_lines' : [],
})
todo_moves = []
for order_line in order.order_line:
@@ -720,7 +721,7 @@ purchase_order_line()
class procurement_order(osv.osv):
_inherit = 'procurement.order'
_columns = {
'purchase_id': fields.many2one('purchase.order', 'Latest Requisition'),
'purchase_id': fields.many2one('purchase.order', 'Purchase Order'),
}
def action_po_assign(self, cr, uid, ids, context={}):
@@ -800,4 +801,4 @@ class procurement_order(osv.osv):
procurement_order()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+4 -4
View File
@@ -54,14 +54,14 @@ class purchase_report(osv.osv):
'validator' : fields.many2one('res.users', 'Validated By', readonly=True),
'company_id':fields.many2one('res.company', 'Company', readonly=True),
'user_id':fields.many2one('res.users', 'Responsible', readonly=True),
'delay':fields.float('Days to Validate', digits=(16,2), readonly=True, group_operator="avg"),
'delay_pass':fields.float('Days to Deliver', digits=(16,2), readonly=True, group_operator="avg"),
'delay':fields.float('Days to Validate', digits=(16,2), readonly=True),
'delay_pass':fields.float('Days to Deliver', digits=(16,2), readonly=True),
'quantity': fields.float('# of Products', readonly=True),
'price_total': fields.float('Total Price', readonly=True),
'price_average': fields.float('Unit Price', readonly=True, group_operator="avg"),
'price_average': fields.float('Average Price', readonly=True, group_operator="avg"),
'negociation': fields.float('Purchase-Standard Price', readonly=True, group_operator="avg"),
'price_standard': fields.float('Products Value', readonly=True, group_operator="sum"),
'nbr': fields.integer('# of PO Lines', readonly=True),
'nbr': fields.integer('# of Lines', 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),
@@ -33,14 +33,14 @@
<field name="company_id" invisible="1"/>
<field name="state" invisible="1"/>
<field name="location_id" invisible="1"/>
<field name="nbr"/>
<field name="nbr" sum="# of Lines"/>
<field name="quantity" sum="# of Products"/>
<field name="price_average" avg="Average Price"/>
<field name="price_average" sum="Average Price"/>
<field name="price_total" sum="Total Price"/>
<field name="price_standard" sum="Products Costs"/>
<field name="price_standard" sum="Products Value"/>
<field name="negociation" widget="progressbar"/>
<field name="delay"/>
<field name="delay_pass"/>
<field name="delay" sum="Days to Validate"/>
<field name="delay_pass" sum="Days to Deliver"/>
</tree>
</field>
</record>
@@ -142,10 +142,11 @@
<record id="action_purchase_order_report_all" model="ir.actions.act_window">
<field name="name">Purchase Orders</field>
<field name="name">Purchase Analysis</field>
<field name="res_model">purchase.report</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="view_id" ref="view_purchase_order_tree"></field>
<field name="context">{'search_default_month':1,'search_default_group_partner_id':1,'search_default_group_product_id': 1, 'search_default_orders': 1, 'group_by_no_leaf':1,'group_by':[]}</field>
</record>
@@ -129,10 +129,14 @@ class purchase_order(osv.osv):
}
def wkf_confirm_order(self, cr, uid, ids, context={}):
res = super(purchase_order, self).wkf_confirm_order(cr, uid, ids, context)
proc_obj=self.pool.get('procurement.order')
for po in self.browse(cr, uid, ids, context):
if po.requisition_id and (po.requisition_id.exclusive=='exclusive'):
for order in po.requisition_id.purchase_ids:
if order.id<>po.id:
proc_ids = proc_obj.search(cr, uid, [('purchase_id', '=', order.id)])
if proc_ids and po.state=='confirmed':
proc_obj.wirte(cr,uid,proc_ids,{'purchase_id':po.id})
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'purchase.order', order.id, 'purchase_cancel', cr)
self.pool.get('purchase.requisition').write(cr, uid, [po.requisition_id.id], {'state':'done','date_end':time.strftime('%Y-%m-%d %H:%M:%S')})
@@ -155,14 +159,17 @@ product_product()
class procurement_order(osv.osv):
_inherit = 'procurement.order'
_columns = {
'requisition_id' : fields.many2one('purchase.requisition','Latest Requisition')
}
def make_po(self, cr, uid, ids, context=None):
sequence_obj = self.pool.get('ir.sequence')
res = super(procurement_order, self).make_po(cr, uid, ids, context=context)
for proc_id, po_id in res.items():
procurement = self.browse(cr, uid, proc_id)
requisition_id=False
if procurement.product_id.purchase_requisition:
self.pool.get('purchase.requisition').create(cr, uid, {
requisition_id=self.pool.get('purchase.requisition').create(cr, uid, {
'name': sequence_obj.get(cr, uid, 'purchase.order.requisition'),
'origin': procurement.name,
'date_end': procurement.date_planned,
@@ -174,6 +181,7 @@ class procurement_order(osv.osv):
})],
'purchase_ids': [(6,0,[po_id])]
})
self.write(cr,uid,proc_id,{'requisition_id':requisition_id})
return res
procurement_order()
@@ -168,6 +168,17 @@
</field>
</field>
</record>
<record model="ir.ui.view" id="procurement_normal_form_view_inherit">
<field name="name">procurement.form.inherit</field>
<field name="type">form</field>
<field name="model">procurement.order</field>
<field name="inherit_id" ref="procurement.procurement_form_view"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='close_move']" position="after">
<field name="requisition_id"/>
</xpath>
</field>
</record>
</data>
</openerp>
@@ -63,7 +63,7 @@
proc_obj = self.pool.get('procurement.order')
proc_obj._procure_confirm(cr,uid)
-
On the purchase tender, I create a new purchase order for the supplier 'DistriPC' by clicking on
On the purchase requisition, I create a new purchase order for the supplier 'DistriPC' by clicking on
the button 'New RfQ'. This opens a window to ask me the supplier and I set DistriPC .
-
!record {model: purchase.requisition.partner, id: purchase_requisition_partner_0}:
@@ -74,23 +74,25 @@
-
!python {model: purchase.requisition.partner}: |
req_obj = self.pool.get('purchase.requisition')
ids =req_obj.search(cr, uid, [('origin','=','TEST/TENDER/0001')])
ids =req_obj.search(cr, uid, [('origin','=','Laptop ACER')])
self.create_order(cr, uid, [ref("purchase_requisition_partner_0")], {"lang":
'en_US', "active_model": "purchase.requisition", "tz": False, "record_id":
1, "active_ids": ids, "active_id": ids[0], })
-
I check that I have two purchase orders on the purchase tender.
I check that I have two purchase orders on the purchase requisition.
-
!python {model: purchase.order}: |
from tools.translate import _
order_ids =self.search(cr, uid, [('origin','=','TEST/TENDER/0001')])
ids=len(order_ids)
assert (ids==2), "Purchase order hasn't Created"
assert(ids == 2), _('Purchase Order not Created')
-
I set the purchase requisition as 'Not Exclusive'.
-
!python {model: purchase.requisition}: |
ids =self.search(cr, uid, [('origin','=','TEST/TENDER/0001')])
ids =self.search(cr, uid, [('origin','=','Laptop ACER')])
self.write(cr,uid,ids[0],{'exclusive': 'multiple' })
-
I change the quantities so that the purchase order for DistriPC includes 3 pieces and the
@@ -100,7 +102,7 @@
line_obj=self.pool.get('purchase.order.line')
partner_obj=self.pool.get('res.partner')
requistion_obj=self.pool.get('purchase.requisition')
requistion_ids =requistion_obj.search(cr, uid, [('origin','=','TEST/TENDER/0001')])
requistion_ids =requistion_obj.search(cr, uid, [('origin','=','Laptop ACER')])
partner_id1=partner_obj.search(cr,uid,[('name','=','ASUStek')])[0]
partner_id2=partner_obj.search(cr,uid,[('name','=','Distrib PC')])[0]
purchase_id1= self.search(cr, uid, [('partner_id','=',partner_id1),('requisition_id','in',requistion_ids)])
@@ -123,11 +125,13 @@
I check that the delivery order of the customer is in state 'Waiting Goods'.
-
!python {model: stock.picking }: |
from tools.translate import _
picking_id = self.search(cr, uid, [('origin','=','TEST/TENDER/0001'),('type','=','delivery')])
if picking_id:
pick=self.browse(cr,uid,picking_id[0])
assert (pick.state) =='confirmed'," Order is not confirm"
assert(pick.move_lines[0].state=='wating'),'Order is not wating"'
assert (pick.state =='confirmed'),_('Picking is not in confirm state.')
assert (pick.move_lines[0].state == 'waiting'), _('Stock Move is not Waiting state.')
-
I receive the order of the supplier Asustek from the Incoming Products menu.
-
@@ -176,8 +180,10 @@
I check that the delivery order of the customer is in the state Available.
-
!python {model: stock.picking }: |
from tools.translate import _
picking_id = self.search(cr, uid, [('origin','=','TEST/TENDER/0001'),('type','=','out')])
if picking_id:
pick=self.browse(cr,uid,picking_id[0])
assert (pick.state) =='available'," Order is not available"
print pick.state
assert(pick.state == 'assigned'), _('Picking is not in available state')
@@ -60,11 +60,11 @@
5 Laptop ACER, and a purchase order on the default supplier for this product.
-
!python {model: purchase.requisition}: |
requisition_ids =self.search(cr, uid, [('origin','=','TEST/TENDER/0002')])
requisition_ids =self.search(cr, uid, [('origin','=','Laptop ACER1')])
ids=len(requisition_ids)
assert len(requisition_ids), "Purchase requisition hasn't Created"
-
On the purchase tender, I create a new purchase order for the supplier 'DistriPC' by clicking on
On the purchase requisition, I create a new purchase order for the supplier 'DistriPC' by clicking on
the button 'New Request for Quotation'. This opens a window to ask me the supplier and I set DistriPC .
-
I Create purchase.requisition.partner .
@@ -77,15 +77,15 @@
-
!python {model: purchase.requisition.partner}: |
req_obj = self.pool.get('purchase.requisition')
ids =req_obj.search(cr, uid, [('origin','=','TEST/TENDER/0002')])
ids =req_obj.search(cr, uid, [('origin','=','Laptop ACER1')])
self.create_order(cr, uid, [ref("purchase_requisition_partner_0")], {"lang":
'en_US', "active_model": "purchase.requisition", "tz": False, "record_id":
1, "active_ids": ids, "active_id": ids[0], })
-
I set the purchase tender as 'Exclusive'
I set the purchase requisition as 'Exclusive'
-
!python {model: purchase.requisition}: |
ids =self.search(cr, uid, [('origin','=','TEST/TENDER/0002')])
ids =self.search(cr, uid, [('origin','=','Laptop ACER1')])
self.write(cr,uid,ids[0],{'exclusive': 'exclusive' })
-
I confirm and validate the Request for Quotation of ASUStek.
@@ -93,7 +93,7 @@
!python {model: purchase.order}: |
partner_id=self.pool.get('res.partner').search(cr,uid,[('name','=','ASUStek')])[0]
req_obj = self.pool.get('purchase.requisition')
ids =req_obj.search(cr, uid, [('origin','=','TEST/TENDER/0002')])
ids =req_obj.search(cr, uid, [('origin','=','Laptop ACER1')])
purchase_id= self.search(cr, uid, [('partner_id','=',partner_id),('requisition_id','in',ids)])[0]
import netsvc
wf_service = netsvc.LocalService("workflow")
@@ -106,7 +106,7 @@
!python {model: purchase.order}: |
partner_id=self.pool.get('res.partner').search(cr,uid,[('name','=','Distrib PC')])[0]
req_obj = self.pool.get('purchase.requisition')
ids =req_obj.search(cr, uid, [('origin','=','TEST/TENDER/0002')])
ids =req_obj.search(cr, uid, [('origin','=','Laptop ACER1')])
purchase_id= self.search(cr, uid, [('partner_id','=',partner_id),('requisition_id','in',ids)])[0]
state=self.browse(cr,uid,purchase_id).state
assert (state=='cancel')
+36 -18
View File
@@ -74,7 +74,7 @@ class sale_report(osv.osv):
tools.drop_view_if_exists(cr, 'sale_report')
cr.execute("""
create or replace view sale_report as (
select el.*,
select el.*,
-- (select count(1) from sale_order_line where order_id = s.id) as nbr,
(select 1) as nbr,
s.date_order as date,
@@ -86,28 +86,46 @@ class sale_report(osv.osv):
s.user_id as user_id,
s.shop_id as shop_id,
s.company_id as company_id,
extract(epoch from (s.date_confirm-s.create_date))/(24*60*60)::decimal(16,2) as delay,
extract(epoch from avg(date_trunc('day',s.date_confirm)-date_trunc('day',s.create_date)))/(24*60*60)::decimal(16,2) as delay,
s.state,
s.shipped,
s.shipped::integer as shipped_qty_1,
s.pricelist_id as pricelist_id,
s.project_id as analytic_account_id
from
sale_order s,
(
select l.id as id,
l.product_id as product_id,
u.name as uom_name,
sum(l.product_uom_qty * u.factor) as product_uom_qty,
sum(l.product_uom_qty*l.price_unit) as price_total,
(sum(l.product_uom_qty*l.price_unit)/sum(l.product_uom_qty * u.factor)*count(l.product_id))::decimal(16,2) as price_average,
pt.categ_id, l.order_id
from
sale_order_line l
left join product_uom u on (u.id=l.product_uom)
left join product_template pt on (pt.id=l.product_id)
group by l.id, l.order_id, l.product_id, u.name, pt.categ_id) el
where s.id = el.order_id
from
sale_order s,
(
select l.id as id,
l.product_id as product_id,
u.name as uom_name,
sum(l.product_uom_qty * u.factor) as product_uom_qty,
sum(l.product_uom_qty*l.price_unit) as price_total,
(sum(l.product_uom_qty*l.price_unit)/sum(l.product_uom_qty * u.factor)*count(l.product_id))::decimal(16,2) as price_average,
pt.categ_id, l.order_id
from
sale_order_line l
left join product_uom u on (u.id=l.product_uom)
left join product_template pt on (pt.id=l.product_id)
group by l.id, l.order_id, l.product_id, u.name, pt.categ_id) el
where s.id = el.order_id
group by el.id,
el.product_id,
el.uom_name,
el.product_uom_qty,
el.price_total,
el.price_average,
el.categ_id,
el.order_id,
s.date_order,
s.date_confirm,
s.partner_id,
s.user_id,
s.shop_id,
s.company_id,
s.state,
s.shipped,
s.pricelist_id,
s.project_id
)
""")
sale_report()
+5 -4
View File
@@ -20,11 +20,11 @@
<field name="categ_id" invisible="1"/>
<field name="nbr" sum="# of Lines"/>
<field name="product_uom_qty" sum="# of Qty"/>
<field name="shipped_qty_1"/>
<field name="uom_name" invisible="context.get('set_visible',False)"/>
<field name="price_average" avg="Average Price"/>
<field name="shipped_qty_1" sum="Shipped Qty"/>
<field name="uom_name" invisible="not context.get('set_visible',False)"/>
<field name="price_average" sum="Average Price"/>
<field name="price_total" sum="Total Price"/>
<field name="delay" avg="Commitment Delay"/>
<field name="delay" sum="Commitment Delay"/>
<field name="state" invisible="1"/>
<field name="analytic_account_id" invisible="1"/>
</tree>
@@ -122,6 +122,7 @@
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="search_view_id" ref="view_order_product_search"/>
<field name="view_id" ref="view_order_product_tree"/>
<field name="context">{'search_default_month':1,'search_default_User':1,'group_by_no_leaf':1,'group_by':[]}</field>
</record>
+1 -1
View File
@@ -254,7 +254,7 @@ class scrum_product_backlog(osv.osv):
'tasks_id': fields.one2many('project.task', 'product_backlog_id', 'Tasks Details'),
'state': fields.selection([('draft','Draft'),('open','Open'),('pending','Pending'),('done','Done'),('cancel','Cancelled')], 'State', required=True),
'progress': fields.function(_calc_progress, method=True, string='Progress', help="Computed as: Time Spent / Total Time."),
'effective_hours': fields.function(_calc_effective, method=True, string='Effective hours', help="Computed using the sum of the task work done (Time spent on tasks)"),
'effective_hours': fields.function(_calc_effective, method=True, string='Spent Hours', help="Computed using the sum of the time spent on every related tasks"),
'expected_hours': fields.float('Planned Hours', help='Estimated total time to do the Backlog'),
'create_date': fields.datetime("Creation Date", readonly=True),
'task_hours': fields.function(_calc_task, method=True, string='Task Hours', help='Estimated time of the total hours of the tasks')