@@ -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')
|
||||
|
||||
@@ -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={}):
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
],
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">['&', ('user_id','=',uid), '!' , '&', ('state', '=', 'done'), ('date_closed','>',(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">['&', ('state', '=', 'done') , '&', ('create_date','>',(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
@@ -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 \
|
||||
|
||||
@@ -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={}):
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,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>
|
||||
|
||||
@@ -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=""CONS TRUST (AZ) 529701 - 1000 units"" 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=""3rd Round Funding - 1000 units "" 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=""Mediapole - 5000 units"" name="name"/>
|
||||
<field eval=""info@mycompany.net"" 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=""ABC FUEL CO 829264 - 1000 units "" name="name"/>
|
||||
<field eval=""info@opensides.be"" 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=""Dirt Mining Ltd 271742 - 1000 units"" name="name"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,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:
|
||||
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -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),
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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<=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:
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -27,5 +27,4 @@ import report
|
||||
import wizard
|
||||
import res_partner
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,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<current_date;blue:date_deadline==current_date;black:date_deadline>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>
|
||||
|
||||
@@ -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
@@ -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,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!--
|
||||
Requests Links
|
||||
-->
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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', '>=', 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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
</page>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
'crm',
|
||||
'project',
|
||||
'hr_timesheet_sheet',
|
||||
'resource'
|
||||
],
|
||||
'init_xml': [
|
||||
'project_issue_data.xml'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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:
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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')
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user