[MERGE]: Merged with lp:openobject-addons
bzr revid: atp@tinyerp.com-20121004050405-de1o2nl772ow12yf bzr revid: atp@tinyerp.com-20121008051226-6fz3lau22ylb02oc bzr revid: atp@tinyerp.com-20121008113735-ubbudyuqotrsg5fo
This commit is contained in:
commit
8944588931
|
@ -461,10 +461,9 @@ class account_bank_statement(osv.osv):
|
||||||
return {}
|
return {}
|
||||||
balance_start = self._compute_balance_end_real(cr, uid, journal_id, context=context)
|
balance_start = self._compute_balance_end_real(cr, uid, journal_id, context=context)
|
||||||
|
|
||||||
journal_data = self.pool.get('account.journal').read(cr, uid, journal_id, ['default_debit_account_id', 'company_id'], context=context)
|
journal_data = self.pool.get('account.journal').read(cr, uid, journal_id, ['company_id'], context=context)
|
||||||
account_id = journal_data['default_debit_account_id']
|
|
||||||
company_id = journal_data['company_id']
|
company_id = journal_data['company_id']
|
||||||
return {'value': {'balance_start': balance_start, 'account_id': account_id, 'company_id': company_id}}
|
return {'value': {'balance_start': balance_start, 'company_id': company_id}}
|
||||||
|
|
||||||
def unlink(self, cr, uid, ids, context=None):
|
def unlink(self, cr, uid, ids, context=None):
|
||||||
stat = self.read(cr, uid, ids, ['state'], context=context)
|
stat = self.read(cr, uid, ids, ['state'], context=context)
|
||||||
|
|
|
@ -189,7 +189,7 @@
|
||||||
</group>
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="Invoice">
|
<page string="Invoice">
|
||||||
<field context="{'partner_id': partner_id, 'price_type': 'price_type' in dir() and price_type or False, 'type': type}" name="invoice_line">
|
<field context="{'partner_id': partner_id, 'price_type': context.get('price_type') or False, 'type': type}" name="invoice_line">
|
||||||
<tree string="Invoice lines" editable="bottom">
|
<tree string="Invoice lines" editable="bottom">
|
||||||
<field name="product_id"
|
<field name="product_id"
|
||||||
on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/>
|
on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/>
|
||||||
|
|
|
@ -1549,10 +1549,7 @@
|
||||||
<field name="view_mode">account_reconciliation_list</field>
|
<field name="view_mode">account_reconciliation_list</field>
|
||||||
<field name="help" type="html">
|
<field name="help" type="html">
|
||||||
<p>
|
<p>
|
||||||
Good job!
|
No journal items found.
|
||||||
</p><p>
|
|
||||||
There is nothing to reconcile. All invoices and payments
|
|
||||||
have been reconciled, your partner balance is clean.
|
|
||||||
</p>
|
</p>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
|
@ -3,10 +3,17 @@
|
||||||
<templates id="template" xml:space="preserve">
|
<templates id="template" xml:space="preserve">
|
||||||
|
|
||||||
<t t-name="AccountReconciliation">
|
<t t-name="AccountReconciliation">
|
||||||
|
<t t-if="widget.current_partner === null">
|
||||||
|
<div class="oe_view_nocontent">
|
||||||
|
<p>
|
||||||
|
Good job!
|
||||||
|
</p><p>
|
||||||
|
There is nothing to reconcile. All invoices and payments
|
||||||
|
have been reconciled, your partner balance is clean.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
<div class="oe_account_reconciliation">
|
<div class="oe_account_reconciliation">
|
||||||
<t t-if="widget.current_partner === null">
|
|
||||||
There is no pending reconciliation.
|
|
||||||
</t>
|
|
||||||
<t t-if="widget.current_partner !== null">
|
<t t-if="widget.current_partner !== null">
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
-
|
-
|
||||||
I create a supplier invoice
|
I create a supplier invoice
|
||||||
-
|
-
|
||||||
!record {model: account.invoice, id: account_invoice_supplier0}:
|
!record {model: account.invoice, id: account_invoice_supplier0, view: invoice_supplier_form}:
|
||||||
account_id: account.a_pay
|
account_id: account.a_pay
|
||||||
check_total: 3000.0
|
check_total: 3000.0
|
||||||
company_id: base.main_company
|
company_id: base.main_company
|
||||||
|
|
|
@ -6,7 +6,12 @@
|
||||||
<field name="model">account.invoice.confirm</field>
|
<field name="model">account.invoice.confirm</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Confirm Draft Invoices" version="7.0">
|
<form string="Confirm Draft Invoices" version="7.0">
|
||||||
<separator string="Confirm Draft Invoices"/>
|
<p class="oe_grey">
|
||||||
|
Once draft invoices are confirmed, you will not be able
|
||||||
|
to modify them. The invoices will receive a unique
|
||||||
|
number and journal items will be created in your chart
|
||||||
|
of accounts.
|
||||||
|
</p>
|
||||||
<footer>
|
<footer>
|
||||||
<button string="Confirm Invoices" name="invoice_confirm" type="object" default_focus="1" class="oe_highlight"/>
|
<button string="Confirm Invoices" name="invoice_confirm" type="object" default_focus="1" class="oe_highlight"/>
|
||||||
or
|
or
|
||||||
|
@ -27,7 +32,6 @@
|
||||||
<field name="model">account.invoice.cancel</field>
|
<field name="model">account.invoice.cancel</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Cancel Selected Invoices" version="7.0">
|
<form string="Cancel Selected Invoices" version="7.0">
|
||||||
<separator string="Cancel Selected Invoices"/>
|
|
||||||
<footer>
|
<footer>
|
||||||
<button string="Cancel Invoices" name="invoice_cancel" type="object" default_focus="1" class="oe_highlight"/>
|
<button string="Cancel Invoices" name="invoice_cancel" type="object" default_focus="1" class="oe_highlight"/>
|
||||||
or
|
or
|
||||||
|
|
|
@ -86,24 +86,24 @@ class account_payment_populate_statement(osv.osv_memory):
|
||||||
'name': line.name,
|
'name': line.name,
|
||||||
'partner_id': line.partner_id.id,
|
'partner_id': line.partner_id.id,
|
||||||
'journal_id': statement.journal_id.id,
|
'journal_id': statement.journal_id.id,
|
||||||
'account_id': result.get('account_id', statement.journal_id.default_credit_account_id.id),
|
'account_id': result['value'].get('account_id', statement.journal_id.default_credit_account_id.id),
|
||||||
'company_id': statement.company_id.id,
|
'company_id': statement.company_id.id,
|
||||||
'currency_id': statement.currency.id,
|
'currency_id': statement.currency.id,
|
||||||
'date': line.date or time.strftime('%Y-%m-%d'),
|
'date': line.date or time.strftime('%Y-%m-%d'),
|
||||||
'amount': abs(amount),
|
'amount': abs(amount),
|
||||||
'period_id': statement.period_id.id
|
'period_id': statement.period_id.id,
|
||||||
}
|
}
|
||||||
voucher_id = voucher_obj.create(cr, uid, voucher_res, context=context)
|
voucher_id = voucher_obj.create(cr, uid, voucher_res, context=context)
|
||||||
voucher_line_dict = False
|
|
||||||
if result['value']['line_ids']:
|
voucher_line_dict = {}
|
||||||
for line_dict in result['value']['line_ids']:
|
for line_dict in result['value']['line_cr_ids'] + result['value']['line_dr_ids']:
|
||||||
move_line = move_line_obj.browse(cr, uid, line_dict['move_line_id'], context)
|
move_line = move_line_obj.browse(cr, uid, line_dict['move_line_id'], context)
|
||||||
if line.move_line_id.move_id.id == move_line.move_id.id:
|
if line.move_line_id.move_id.id == move_line.move_id.id:
|
||||||
voucher_line_dict = line_dict
|
voucher_line_dict = line_dict
|
||||||
|
|
||||||
if voucher_line_dict:
|
if voucher_line_dict:
|
||||||
voucher_line_dict.update({'voucher_id': voucher_id})
|
voucher_line_dict.update({'voucher_id': voucher_id})
|
||||||
voucher_line_obj.create(cr, uid, voucher_line_dict, context=context)
|
voucher_line_obj.create(cr, uid, voucher_line_dict, context=context)
|
||||||
|
|
||||||
st_line_id = statement_line_obj.create(cr, uid, {
|
st_line_id = statement_line_obj.create(cr, uid, {
|
||||||
'name': line.order_id.reference or '?',
|
'name': line.order_id.reference or '?',
|
||||||
'amount': - amount,
|
'amount': - amount,
|
||||||
|
|
|
@ -547,6 +547,19 @@ class account_voucher(osv.osv):
|
||||||
vals = self.recompute_payment_rate(cr, uid, ids, res, currency_id, date, ttype, journal_id, amount, context=context)
|
vals = self.recompute_payment_rate(cr, uid, ids, res, currency_id, date, ttype, journal_id, amount, context=context)
|
||||||
for key in vals.keys():
|
for key in vals.keys():
|
||||||
res[key].update(vals[key])
|
res[key].update(vals[key])
|
||||||
|
#TODO: onchange_partner_id() should not returns [pre_line, line_dr_ids, payment_rate...] for type sale, and not
|
||||||
|
# [pre_line, line_cr_ids, payment_rate...] for type purchase.
|
||||||
|
# We should definitively split account.voucher object in two and make distinct on_change functions. In the
|
||||||
|
# meanwhile, bellow lines must be there because the fields aren't present in the view, what crashes if the
|
||||||
|
# onchange returns a value for them
|
||||||
|
if ttype == 'sale':
|
||||||
|
del(res['value']['line_dr_ids'])
|
||||||
|
del(res['value']['pre_line'])
|
||||||
|
del(res['value']['payment_rate'])
|
||||||
|
elif ttype == 'purchase':
|
||||||
|
del(res['value']['line_cr_ids'])
|
||||||
|
del(res['value']['pre_line'])
|
||||||
|
del(res['value']['payment_rate'])
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def recompute_voucher_lines(self, cr, uid, ids, partner_id, journal_id, price, currency_id, ttype, date, context=None):
|
def recompute_voucher_lines(self, cr, uid, ids, partner_id, journal_id, price, currency_id, ttype, date, context=None):
|
||||||
|
@ -588,7 +601,7 @@ class account_voucher(osv.osv):
|
||||||
|
|
||||||
#set default values
|
#set default values
|
||||||
default = {
|
default = {
|
||||||
'value': {'line_ids': [] ,'line_dr_ids': [] ,'line_cr_ids': [] ,'pre_line': False,},
|
'value': {'line_dr_ids': [] ,'line_cr_ids': [] ,'pre_line': False,},
|
||||||
}
|
}
|
||||||
|
|
||||||
#drop existing lines
|
#drop existing lines
|
||||||
|
@ -667,6 +680,7 @@ class account_voucher(osv.osv):
|
||||||
|
|
||||||
#voucher line creation
|
#voucher line creation
|
||||||
for line in account_move_lines:
|
for line in account_move_lines:
|
||||||
|
|
||||||
if _remove_noise_in_o2m():
|
if _remove_noise_in_o2m():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -771,8 +785,10 @@ class account_voucher(osv.osv):
|
||||||
if account_id and account_id.tax_ids:
|
if account_id and account_id.tax_ids:
|
||||||
tax_id = account_id.tax_ids[0].id
|
tax_id = account_id.tax_ids[0].id
|
||||||
|
|
||||||
vals = self.onchange_price(cr, uid, ids, line_ids, tax_id, partner_id, context)
|
vals = {'value':{} }
|
||||||
vals['value'].update({'tax_id':tax_id,'amount': amount})
|
if ttype in ('sale', 'purchase'):
|
||||||
|
vals = self.onchange_price(cr, uid, ids, line_ids, tax_id, partner_id, context)
|
||||||
|
vals['value'].update({'tax_id':tax_id,'amount': amount})
|
||||||
currency_id = False
|
currency_id = False
|
||||||
if journal.currency:
|
if journal.currency:
|
||||||
currency_id = journal.currency.id
|
currency_id = journal.currency.id
|
||||||
|
@ -1183,6 +1199,7 @@ class account_voucher(osv.osv):
|
||||||
account_id = voucher_brw.partner_id.property_account_receivable.id
|
account_id = voucher_brw.partner_id.property_account_receivable.id
|
||||||
else:
|
else:
|
||||||
account_id = voucher_brw.partner_id.property_account_payable.id
|
account_id = voucher_brw.partner_id.property_account_payable.id
|
||||||
|
sign = voucher_brw.type == 'payment' and -1 or 1
|
||||||
move_line = {
|
move_line = {
|
||||||
'name': write_off_name or name,
|
'name': write_off_name or name,
|
||||||
'account_id': account_id,
|
'account_id': account_id,
|
||||||
|
@ -1191,7 +1208,7 @@ class account_voucher(osv.osv):
|
||||||
'date': voucher_brw.date,
|
'date': voucher_brw.date,
|
||||||
'credit': diff > 0 and diff or 0.0,
|
'credit': diff > 0 and diff or 0.0,
|
||||||
'debit': diff < 0 and -diff or 0.0,
|
'debit': diff < 0 and -diff or 0.0,
|
||||||
'amount_currency': company_currency <> current_currency and voucher_brw.writeoff_amount or False,
|
'amount_currency': company_currency <> current_currency and (sign * -1 * voucher_brw.writeoff_amount) or False,
|
||||||
'currency_id': company_currency <> current_currency and current_currency or False,
|
'currency_id': company_currency <> current_currency and current_currency or False,
|
||||||
'analytic_account_id': voucher_brw.analytic_id and voucher_brw.analytic_id.id or False,
|
'analytic_account_id': voucher_brw.analytic_id and voucher_brw.analytic_id.id or False,
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<!-- where and when is this view used?? -->
|
||||||
<record model="ir.ui.view" id="view_voucher_form">
|
<record model="ir.ui.view" id="view_voucher_form">
|
||||||
<field name="name">account.voucher.form</field>
|
<field name="name">account.voucher.form</field>
|
||||||
<field name="model">account.voucher</field>
|
<field name="model">account.voucher</field>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
-
|
-
|
||||||
In order to check account voucher module in OpenERP I create a customer voucher
|
In order to check account voucher module in OpenERP I create a customer voucher
|
||||||
-
|
-
|
||||||
!record {model: account.voucher, id: account_voucher_voucherforaxelor0}:
|
!record {model: account.voucher, id: account_voucher_voucherforaxelor0, view: view_sale_receipt_form}:
|
||||||
|
type: sale
|
||||||
account_id: account.cash
|
account_id: account.cash
|
||||||
amount: 1000.0
|
amount: 1000.0
|
||||||
company_id: base.main_company
|
company_id: base.main_company
|
||||||
|
@ -47,7 +48,8 @@
|
||||||
-
|
-
|
||||||
Now I create a Vendor Voucher
|
Now I create a Vendor Voucher
|
||||||
-
|
-
|
||||||
!record {model: account.voucher, id: account_voucher_voucheraxelor0, view: False}:
|
!record {model: account.voucher, id: account_voucher_voucheraxelor0, view: view_voucher_filter_vendor}:
|
||||||
|
type: purchase
|
||||||
account_id: account.cash
|
account_id: account.cash
|
||||||
amount: 1000.0
|
amount: 1000.0
|
||||||
company_id: base.main_company
|
company_id: base.main_company
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
-
|
-
|
||||||
Demo for Account Voucher
|
Demo for Account Voucher
|
||||||
-
|
-
|
||||||
!record {model: account.voucher, id: account_voucher_voucheraxelor0again}:
|
!record {model: account.voucher, id: account_voucher_voucheraxelor0again, view: view_sale_receipt_form}:
|
||||||
|
type: sale
|
||||||
account_id: account.cash
|
account_id: account.cash
|
||||||
company_id: base.main_company
|
company_id: base.main_company
|
||||||
journal_id: account.bank_journal
|
journal_id: account.bank_journal
|
||||||
|
|
|
@ -216,6 +216,10 @@
|
||||||
assert move_line.credit == 63.00, "Debtor account has wrong entry."
|
assert move_line.credit == 63.00, "Debtor account has wrong entry."
|
||||||
elif move_line.amount_currency == 10.00:
|
elif move_line.amount_currency == 10.00:
|
||||||
assert move_line.debit == 9.00, "Writeoff amount is wrong."
|
assert move_line.debit == 9.00, "Writeoff amount is wrong."
|
||||||
|
elif move_line.amount_currency == 240.00:
|
||||||
|
assert move_line.debit == 216.00, "Bank entry is wrong."
|
||||||
|
else:
|
||||||
|
assert False, "Unrecognized journal entry"
|
||||||
-
|
-
|
||||||
I check the residual amount of Invoice1, should be 20 in amount_currency
|
I check the residual amount of Invoice1, should be 20 in amount_currency
|
||||||
-
|
-
|
||||||
|
@ -237,7 +241,7 @@
|
||||||
-
|
-
|
||||||
On the first April, I create the second voucher of payment with values 45 USD, journal USD,
|
On the first April, I create the second voucher of payment with values 45 USD, journal USD,
|
||||||
-
|
-
|
||||||
!record {model: account.voucher, id: account_voucher_2_case1}:
|
!record {model: account.voucher, id: account_voucher_2_case1, view: view_vendor_receipt_form}:
|
||||||
account_id: account.cash
|
account_id: account.cash
|
||||||
amount: 45.0
|
amount: 45.0
|
||||||
company_id: base.main_company
|
company_id: base.main_company
|
||||||
|
@ -323,8 +327,16 @@
|
||||||
assert move_line.debit == 4.75, "Writeoff amount is wrong."
|
assert move_line.debit == 4.75, "Writeoff amount is wrong."
|
||||||
elif move_line.debit == 11.5 and move_line.account_id.reconcile:
|
elif move_line.debit == 11.5 and move_line.account_id.reconcile:
|
||||||
assert move_line.amount_currency == 0.0 and move_line.reconcile_id.id == reconcile_a, "Exchange difference entry for the invoice of 100$ is wrong"
|
assert move_line.amount_currency == 0.0 and move_line.reconcile_id.id == reconcile_a, "Exchange difference entry for the invoice of 100$ is wrong"
|
||||||
|
elif move_line.credit == 11.5:
|
||||||
|
assert move_line.amount_currency == 0.0
|
||||||
elif move_line.debit == 31.0 and move_line.account_id.reconcile:
|
elif move_line.debit == 31.0 and move_line.account_id.reconcile:
|
||||||
assert move_line.amount_currency == 0.0 and move_line.reconcile_id.id == reconcile_b, "Exchange difference entry for the invoice of 200$ is wrong"
|
assert move_line.amount_currency == 0.0 and move_line.reconcile_id.id == reconcile_b, "Exchange difference entry for the invoice of 200$ is wrong"
|
||||||
|
elif move_line.credit == 31.0:
|
||||||
|
assert move_line.amount_currency == 0.0
|
||||||
|
elif move_line.amount_currency == 45.00:
|
||||||
|
assert move_line.debit == 42.75, "Bank entry is wrong."
|
||||||
|
else:
|
||||||
|
assert False, "Unrecognized journal entry"
|
||||||
-
|
-
|
||||||
I check the residual amount of Invoice1, should be 0 in residual currency and 0 in amount_residual and paid
|
I check the residual amount of Invoice1, should be 0 in residual currency and 0 in amount_residual and paid
|
||||||
-
|
-
|
||||||
|
|
|
@ -164,7 +164,7 @@
|
||||||
-
|
-
|
||||||
I check that my currency rate difference is correct. 0 in debit with no amount_currency
|
I check that my currency rate difference is correct. 0 in debit with no amount_currency
|
||||||
-
|
-
|
||||||
I check that my writeoff is correct. 11.05 credit and 13.26 amount_currency
|
I check that my writeoff is correct. 11.05 credit and -13.26 amount_currency
|
||||||
-
|
-
|
||||||
!python {model: account.voucher}: |
|
!python {model: account.voucher}: |
|
||||||
voucher = self.search(cr, uid, [('name', '=', 'First payment: Case 4'), ('partner_id', '=', ref('base.res_partner_19'))])
|
voucher = self.search(cr, uid, [('name', '=', 'First payment: Case 4'), ('partner_id', '=', ref('base.res_partner_19'))])
|
||||||
|
@ -179,7 +179,7 @@
|
||||||
elif move_line.debit == 0.00 and move_line.credit == 0.00:
|
elif move_line.debit == 0.00 and move_line.credit == 0.00:
|
||||||
assert move_line.amount_currency == 0.00, "Incorrect Currency Difference."
|
assert move_line.amount_currency == 0.00, "Incorrect Currency Difference."
|
||||||
elif move_line.credit == 10.61:
|
elif move_line.credit == 10.61:
|
||||||
assert move_line.amount_currency == 13.26, "Writeoff amount is wrong."
|
assert move_line.amount_currency == -13.26, "Writeoff amount is wrong."
|
||||||
else:
|
else:
|
||||||
assert False, "Wrong entry"
|
assert False, "Wrong entry"
|
||||||
-
|
-
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
-
|
-
|
||||||
Creating a Voucher Receipt for partner Seagate with amount 30000.0
|
Creating a Voucher Receipt for partner Seagate with amount 30000.0
|
||||||
-
|
-
|
||||||
!record {model: account.voucher, id: account_voucher_seagate_0}:
|
!record {model: account.voucher, id: account_voucher_seagate_0, view: view_sale_receipt_form}:
|
||||||
account_id: account.a_recv
|
account_id: account.a_recv
|
||||||
amount: 30000.0
|
amount: 30000.0
|
||||||
company_id: base.main_company
|
company_id: base.main_company
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
<h1><label for="number" string="Sale Receipt"/> <field name="number" class="oe_inline" readonly="1"/></h1>
|
<h1><label for="number" string="Sale Receipt"/> <field name="number" class="oe_inline" readonly="1"/></h1>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
|
<field name="type" invisible="True"/>
|
||||||
<field name="partner_id" domain="[('customer','=',True)]" on_change="onchange_partner_id(partner_id, journal_id, amount, currency_id, type, date, context)" string="Customer" context="{'search_default_customer':1, 'show_address': 1}" options='{"always_reload": true}'/>
|
<field name="partner_id" domain="[('customer','=',True)]" on_change="onchange_partner_id(partner_id, journal_id, amount, currency_id, type, date, context)" string="Customer" context="{'search_default_customer':1, 'show_address': 1}" options='{"always_reload": true}'/>
|
||||||
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
|
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
|
||||||
</group>
|
</group>
|
||||||
|
@ -80,9 +81,9 @@
|
||||||
<field name="date" on_change="onchange_date(date, currency_id, currency_id, amount, company_id, context)"/>
|
<field name="date" on_change="onchange_date(date, currency_id, currency_id, amount, company_id, context)"/>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="paid" invisible="1"/>
|
<field name="paid" invisible="1"/>
|
||||||
|
<field name="paid_amount_in_company_currency" invisible="1"/>
|
||||||
<field name="currency_id" invisible="1"/>
|
<field name="currency_id" invisible="1"/>
|
||||||
</group>
|
</group>
|
||||||
<field name="type" invisible="True"/>
|
|
||||||
</group>
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="Sales Information">
|
<page string="Sales Information">
|
||||||
|
@ -235,6 +236,7 @@
|
||||||
widget="selection"
|
widget="selection"
|
||||||
on_change="onchange_journal(journal_id, line_dr_ids, tax_id, partner_id, date, amount, type, company_id, context)"
|
on_change="onchange_journal(journal_id, line_dr_ids, tax_id, partner_id, date, amount, type, company_id, context)"
|
||||||
groups="account.group_account_user"/>
|
groups="account.group_account_user"/>
|
||||||
|
<field name="paid_amount_in_company_currency" invisible="1"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
|
|
|
@ -125,7 +125,8 @@ class account_analytic_account(osv.osv):
|
||||||
if account.company_id:
|
if account.company_id:
|
||||||
if account.company_id.currency_id.id != value:
|
if account.company_id.currency_id.id != value:
|
||||||
raise osv.except_osv(_('Error!'), _("If you set a company, the currency selected has to be the same as it's currency. \nYou can remove the company belonging, and thus change the currency, only on analytic account of type 'view'. This can be really usefull for consolidation purposes of several companies charts with different currencies, for example."))
|
raise osv.except_osv(_('Error!'), _("If you set a company, the currency selected has to be the same as it's currency. \nYou can remove the company belonging, and thus change the currency, only on analytic account of type 'view'. This can be really usefull for consolidation purposes of several companies charts with different currencies, for example."))
|
||||||
return cr.execute("""update account_analytic_account set currency_id=%s where id=%s""", (value, account.id, ))
|
if value:
|
||||||
|
return cr.execute("""update account_analytic_account set currency_id=%s where id=%s""", (value, account.id, ))
|
||||||
|
|
||||||
def _currency(self, cr, uid, ids, field_name, arg, context=None):
|
def _currency(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
result = {}
|
result = {}
|
||||||
|
@ -163,7 +164,7 @@ class account_analytic_account(osv.osv):
|
||||||
'date': fields.date('Date End', select=True),
|
'date': fields.date('Date End', select=True),
|
||||||
'company_id': fields.many2one('res.company', 'Company', required=False), #not required because we want to allow different companies to use the same chart of account, except for leaf accounts.
|
'company_id': fields.many2one('res.company', 'Company', required=False), #not required because we want to allow different companies to use the same chart of account, except for leaf accounts.
|
||||||
'state': fields.selection([('template', 'Template'),('draft','New'),('open','In Progress'), ('cancelled', 'Cancelled'),('pending','To Renew'),('close','Closed')], 'Status', required=True,),
|
'state': fields.selection([('template', 'Template'),('draft','New'),('open','In Progress'), ('cancelled', 'Cancelled'),('pending','To Renew'),('close','Closed')], 'Status', required=True,),
|
||||||
'currency_id': fields.function(_currency, fnct_inv=_set_company_currency,
|
'currency_id': fields.function(_currency, fnct_inv=_set_company_currency, #the currency_id field is readonly except if it's a view account and if there is no company
|
||||||
store = {
|
store = {
|
||||||
'res.company': (_get_analytic_account, ['currency_id'], 10),
|
'res.company': (_get_analytic_account, ['currency_id'], 10),
|
||||||
}, string='Currency', type='many2one', relation='res.currency'),
|
}, string='Currency', type='many2one', relation='res.currency'),
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
<field name="partner_id" on_change="on_change_partner_id(partner_id, name)" attrs="{'required':[('type','=','contract')]}"/>
|
<field name="partner_id" on_change="on_change_partner_id(partner_id, name)" attrs="{'required':[('type','=','contract')]}"/>
|
||||||
<field name="manager_id"/>
|
<field name="manager_id"/>
|
||||||
<field name="code"/>
|
<field name="code"/>
|
||||||
|
<field name="currency_id" attrs="{'invisible': ['|',('type', '<>', 'view'), ('company_id', '<>', False)]}"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="type"/>
|
<field name="type"/>
|
||||||
|
|
|
@ -34,6 +34,7 @@ Allow users to login through Google OAuth2.
|
||||||
'depends': ['base', 'web', 'base_setup'],
|
'depends': ['base', 'web', 'base_setup'],
|
||||||
'data': [
|
'data': [
|
||||||
'auth_oauth_data.xml',
|
'auth_oauth_data.xml',
|
||||||
|
'auth_oauth_data.yml',
|
||||||
'auth_oauth_view.xml',
|
'auth_oauth_view.xml',
|
||||||
'security/ir.model.access.csv'
|
'security/ir.model.access.csv'
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
-
|
||||||
|
Use database uuid as client_id for OpenERP oauth provider
|
||||||
|
-
|
||||||
|
!python {model: ir.config_parameter}: |
|
||||||
|
oauth = self.pool.get('auth.oauth.provider')
|
||||||
|
oauth.write(cr, uid, [ref('provider_openerp')], {'client_id': self.get_param(cr, uid, 'database.uuid')})
|
|
@ -39,11 +39,11 @@ months = {
|
||||||
|
|
||||||
def get_recurrent_dates(rrulestring, exdate, startdate=None, exrule=None):
|
def get_recurrent_dates(rrulestring, exdate, startdate=None, exrule=None):
|
||||||
"""
|
"""
|
||||||
Get recurrent dates based on Rule string considering exdate and start date
|
Get recurrent dates based on Rule string considering exdate and start date.
|
||||||
@param rrulestring: Rulestring
|
@param rrulestring: rulestring
|
||||||
@param exdate: List of exception dates for rrule
|
@param exdate: list of exception dates for rrule
|
||||||
@param startdate: Startdate for computing recurrent dates
|
@param startdate: startdate for computing recurrent dates
|
||||||
@return: List of Recurrent dates
|
@return: list of Recurrent dates
|
||||||
"""
|
"""
|
||||||
def todate(date):
|
def todate(date):
|
||||||
val = parser.parse(''.join((re.compile('\d')).findall(date)))
|
val = parser.parse(''.join((re.compile('\d')).findall(date)))
|
||||||
|
@ -67,11 +67,12 @@ def get_recurrent_dates(rrulestring, exdate, startdate=None, exrule=None):
|
||||||
|
|
||||||
def base_calendar_id2real_id(base_calendar_id=None, with_date=False):
|
def base_calendar_id2real_id(base_calendar_id=None, with_date=False):
|
||||||
"""
|
"""
|
||||||
This function converts virtual event id into real id of actual event
|
Convert a "virtual/recurring event id" (type string) into a real event id (type int).
|
||||||
@param base_calendar_id: Id of calendar
|
E.g. virtual/recurring event id is 4-20091201100000, so it will return 4.
|
||||||
@param with_date: If value passed to this param it will return dates based on value of withdate + base_calendar_id
|
@param base_calendar_id: id of calendar
|
||||||
|
@param with_date: if a value is passed to this param it will return dates based on value of withdate + base_calendar_id
|
||||||
|
@return: real event id
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if base_calendar_id and isinstance(base_calendar_id, (str, unicode)):
|
if base_calendar_id and isinstance(base_calendar_id, (str, unicode)):
|
||||||
res = base_calendar_id.split('-')
|
res = base_calendar_id.split('-')
|
||||||
|
|
||||||
|
@ -89,12 +90,13 @@ def base_calendar_id2real_id(base_calendar_id=None, with_date=False):
|
||||||
|
|
||||||
def real_id2base_calendar_id(real_id, recurrent_date):
|
def real_id2base_calendar_id(real_id, recurrent_date):
|
||||||
"""
|
"""
|
||||||
Convert real id of record into virtual id using recurrent_date
|
Convert a real event id (type int) into a "virtual/recurring event id" (type string).
|
||||||
e.g. real id is 1 and recurrent_date is 01-12-2009 10:00:00 then it will return
|
E.g. real event id is 1 and recurrent_date is set to 01-12-2009 10:00:00, so
|
||||||
1-20091201100000
|
it will return 1-20091201100000.
|
||||||
@return: real id with recurrent date.
|
@param real_id: real event id
|
||||||
|
@param recurrent_date: real event recurrent date
|
||||||
|
@return: string containing the real id and the recurrent date
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if real_id and recurrent_date:
|
if real_id and recurrent_date:
|
||||||
recurrent_date = time.strftime("%Y%m%d%H%M%S", \
|
recurrent_date = time.strftime("%Y%m%d%H%M%S", \
|
||||||
time.strptime(recurrent_date, "%Y-%m-%d %H:%M:%S"))
|
time.strptime(recurrent_date, "%Y-%m-%d %H:%M:%S"))
|
||||||
|
@ -104,10 +106,10 @@ def real_id2base_calendar_id(real_id, recurrent_date):
|
||||||
def _links_get(self, cr, uid, context=None):
|
def _links_get(self, cr, uid, context=None):
|
||||||
"""
|
"""
|
||||||
Get request link.
|
Get request link.
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: a standard dictionary for contextual values
|
||||||
@return: list of dictionary which contain object and name and id.
|
@return: list of dictionary which contain object and name and id
|
||||||
"""
|
"""
|
||||||
obj = self.pool.get('res.request.link')
|
obj = self.pool.get('res.request.link')
|
||||||
ids = obj.search(cr, uid, [])
|
ids = obj.search(cr, uid, [])
|
||||||
|
@ -216,9 +218,9 @@ class calendar_attendee(osv.osv):
|
||||||
|
|
||||||
def _get_address(self, name=None, email=None):
|
def _get_address(self, name=None, email=None):
|
||||||
"""
|
"""
|
||||||
Gives email information in ical CAL-ADDRESS type format
|
Gives email information in ical CAL-ADDRESS type format.
|
||||||
@param name: Name for CAL-ADDRESS value
|
@param name: name for CAL-ADDRESS value
|
||||||
@param email: Email address for CAL-ADDRESS value
|
@param email: email address for CAL-ADDRESS value
|
||||||
"""
|
"""
|
||||||
if name and email:
|
if name and email:
|
||||||
name += ':'
|
name += ':'
|
||||||
|
@ -226,13 +228,13 @@ class calendar_attendee(osv.osv):
|
||||||
|
|
||||||
def _compute_data(self, cr, uid, ids, name, arg, context=None):
|
def _compute_data(self, cr, uid, ids, name, arg, context=None):
|
||||||
"""
|
"""
|
||||||
Compute data on function fields for attendee values .
|
Compute data on function fields for attendee values.
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks
|
||||||
@param ids: List of calendar attendee’s IDs.
|
@param ids: list of calendar attendee's IDs
|
||||||
@param name: name of field.
|
@param name: name of field
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: a standard dictionary for contextual values
|
||||||
@return: Dictionary of form {id: {'field Name': value'}}.
|
@return: dictionary of form {id: {'field Name': value'}}
|
||||||
"""
|
"""
|
||||||
name = name[0]
|
name = name[0]
|
||||||
result = {}
|
result = {}
|
||||||
|
@ -297,10 +299,10 @@ class calendar_attendee(osv.osv):
|
||||||
def _links_get(self, cr, uid, context=None):
|
def _links_get(self, cr, uid, context=None):
|
||||||
"""
|
"""
|
||||||
Get request link for ref field in calendar attendee.
|
Get request link for ref field in calendar attendee.
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's id for security checks
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: list of dictionary which contain object and name and id.
|
@return: list of dictionary which contain object and name and id
|
||||||
"""
|
"""
|
||||||
obj = self.pool.get('res.request.link')
|
obj = self.pool.get('res.request.link')
|
||||||
ids = obj.search(cr, uid, [])
|
ids = obj.search(cr, uid, [])
|
||||||
|
@ -310,10 +312,10 @@ class calendar_attendee(osv.osv):
|
||||||
def _lang_get(self, cr, uid, context=None):
|
def _lang_get(self, cr, uid, context=None):
|
||||||
"""
|
"""
|
||||||
Get language for language selection field.
|
Get language for language selection field.
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's id for security checks
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: a standard dictionary for contextual values
|
||||||
@return: list of dictionary which contain code and name and id.
|
@return: list of dictionary which contain code and name and id
|
||||||
"""
|
"""
|
||||||
obj = self.pool.get('res.lang')
|
obj = self.pool.get('res.lang')
|
||||||
ids = obj.search(cr, uid, [])
|
ids = obj.search(cr, uid, [])
|
||||||
|
@ -375,7 +377,6 @@ property or property parameter."),
|
||||||
'ref': fields.reference('Event Ref', selection=_links_get, size=128),
|
'ref': fields.reference('Event Ref', selection=_links_get, size=128),
|
||||||
'availability': fields.selection([('free', 'Free'), ('busy', 'Busy')], 'Free/Busy', readonly="True"),
|
'availability': fields.selection([('free', 'Free'), ('busy', 'Busy')], 'Free/Busy', readonly="True"),
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'state': 'needs-action',
|
'state': 'needs-action',
|
||||||
'role': 'req-participant',
|
'role': 'req-participant',
|
||||||
|
@ -388,12 +389,12 @@ property or property parameter."),
|
||||||
|
|
||||||
def get_ics_file(self, cr, uid, event_obj, context=None):
|
def get_ics_file(self, cr, uid, event_obj, context=None):
|
||||||
"""
|
"""
|
||||||
Returns iCalendar file for the event invitation
|
Returns iCalendar file for the event invitation.
|
||||||
@param self: The object pointer
|
@param self: the object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's id for security checks
|
||||||
@param event_obj: Event object (browse record)
|
@param event_obj: event object (browse record)
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: a standard dictionary for contextual values
|
||||||
@return: .ics file content
|
@return: .ics file content
|
||||||
"""
|
"""
|
||||||
res = None
|
res = None
|
||||||
|
@ -471,7 +472,7 @@ property or property parameter."),
|
||||||
def _send_mail(self, cr, uid, ids, mail_to, email_from=tools.config.get('email_from', False), context=None):
|
def _send_mail(self, cr, uid, ids, mail_to, email_from=tools.config.get('email_from', False), context=None):
|
||||||
"""
|
"""
|
||||||
Send mail for event invitation to event attendees.
|
Send mail for event invitation to event attendees.
|
||||||
@param email_from: Email address for user sending the mail
|
@param email_from: email address for user sending the mail
|
||||||
@return: True
|
@return: True
|
||||||
"""
|
"""
|
||||||
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name
|
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name
|
||||||
|
@ -517,11 +518,11 @@ property or property parameter."),
|
||||||
def onchange_user_id(self, cr, uid, ids, user_id, *args, **argv):
|
def onchange_user_id(self, cr, uid, ids, user_id, *args, **argv):
|
||||||
"""
|
"""
|
||||||
Make entry on email and availbility on change of user_id field.
|
Make entry on email and availbility on change of user_id field.
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks
|
||||||
@param ids: List of calendar attendee’s IDs.
|
@param ids: list of calendar attendee's IDs
|
||||||
@param user_id: Changed value of User id
|
@param user_id: changed value of User id
|
||||||
@return: dictionary of value. which put value in email and availability fields.
|
@return: dictionary of values which put value in email and availability fields
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not user_id:
|
if not user_id:
|
||||||
|
@ -531,24 +532,25 @@ property or property parameter."),
|
||||||
return {'value': {'email': user.email, 'availability':user.availability}}
|
return {'value': {'email': user.email, 'availability':user.availability}}
|
||||||
|
|
||||||
def do_tentative(self, cr, uid, ids, context=None, *args):
|
def do_tentative(self, cr, uid, ids, context=None, *args):
|
||||||
""" Makes event invitation as Tentative
|
"""
|
||||||
@param self: The object pointer
|
Makes event invitation as Tentative.
|
||||||
@param cr: the current row, from the database cursor,
|
@param self: the object pointer
|
||||||
@param uid: the current user’s ID for security checks,
|
@param cr: the current row, from the database cursor
|
||||||
@param ids: List of calendar attendee’s IDs
|
@param uid: the current user's ID for security checks
|
||||||
@param *args: Get Tupple value
|
@param ids: list of calendar attendee's IDs
|
||||||
@param context: A standard dictionary for contextual values
|
@param *args: get Tupple value
|
||||||
|
@param context: a standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
return self.write(cr, uid, ids, {'state': 'tentative'}, context)
|
return self.write(cr, uid, ids, {'state': 'tentative'}, context)
|
||||||
|
|
||||||
def do_accept(self, cr, uid, ids, context=None, *args):
|
def do_accept(self, cr, uid, ids, context=None, *args):
|
||||||
"""
|
"""
|
||||||
Update state of invitation as Accepted and
|
Update state of invitation as Accepted and if the invited user is other
|
||||||
if the invited user is other then event user it will make a copy of this event for invited user
|
then event user it will make a copy of this event for invited user.
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks
|
||||||
@param ids: List of calendar attendee’s IDs.
|
@param ids: list of calendar attendee's IDs
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: a standard dictionary for contextual values
|
||||||
@return: True
|
@return: True
|
||||||
"""
|
"""
|
||||||
if context is None:
|
if context is None:
|
||||||
|
@ -564,25 +566,28 @@ property or property parameter."),
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def do_decline(self, cr, uid, ids, context=None, *args):
|
def do_decline(self, cr, uid, ids, context=None, *args):
|
||||||
""" Marks event invitation as Declined
|
"""
|
||||||
@param self: The object pointer
|
Marks event invitation as Declined.
|
||||||
@param cr: the current row, from the database cursor,
|
@param self: the object pointer
|
||||||
@param uid: the current user’s ID for security checks,
|
@param cr: the current row, from the database cursor
|
||||||
@param ids: List of calendar attendee’s IDs
|
@param uid: the current user's ID for security checks
|
||||||
@param *args: Get Tupple value
|
@param ids: list of calendar attendee's IDs
|
||||||
@param context: A standard dictionary for contextual values """
|
@param *args: get Tupple value
|
||||||
|
@param context: a standard dictionary for contextual values
|
||||||
|
"""
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
return self.write(cr, uid, ids, {'state': 'declined'}, context)
|
return self.write(cr, uid, ids, {'state': 'declined'}, context)
|
||||||
|
|
||||||
def create(self, cr, uid, vals, context=None):
|
def create(self, cr, uid, vals, context=None):
|
||||||
""" Overrides orm create method.
|
"""
|
||||||
|
Overrides orm create method.
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks
|
||||||
@param vals: Get Values
|
@param vals: get Values
|
||||||
@param context: A standard dictionary for contextual values """
|
@param context: a standard dictionary for contextual values
|
||||||
|
"""
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
if not vals.get("email") and vals.get("cn"):
|
if not vals.get("email") and vals.get("cn"):
|
||||||
|
@ -592,6 +597,7 @@ property or property parameter."),
|
||||||
vals['cn'] = vals.get("cn")
|
vals['cn'] = vals.get("cn")
|
||||||
res = super(calendar_attendee, self).create(cr, uid, vals, context)
|
res = super(calendar_attendee, self).create(cr, uid, vals, context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
calendar_attendee()
|
calendar_attendee()
|
||||||
|
|
||||||
class res_alarm(osv.osv):
|
class res_alarm(osv.osv):
|
||||||
|
@ -630,8 +636,8 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
"""
|
"""
|
||||||
Create Alarm for event.
|
Create Alarm for event.
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of res alarm’s IDs.
|
@param ids: List of res alarm's IDs.
|
||||||
@param model: Model name.
|
@param model: Model name.
|
||||||
@param date: Event date
|
@param date: Event date
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
|
@ -704,8 +710,8 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
"""
|
"""
|
||||||
Delete alarm specified in ids
|
Delete alarm specified in ids
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of res alarm’s IDs.
|
@param ids: List of res alarm's IDs.
|
||||||
@param model: Model name for which alarm is to be cleared.
|
@param model: Model name for which alarm is to be cleared.
|
||||||
@return: True
|
@return: True
|
||||||
"""
|
"""
|
||||||
|
@ -715,12 +721,12 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
ir_obj = self.pool.get('ir.model')
|
ir_obj = self.pool.get('ir.model')
|
||||||
model_id = ir_obj.search(cr, uid, [('model', '=', model)])[0]
|
model_id = ir_obj.search(cr, uid, [('model', '=', model)])[0]
|
||||||
model_obj = self.pool.get(model)
|
model_obj = self.pool.get(model)
|
||||||
for datas in model_obj.browse(cr, uid, ids, context=context):
|
for data in model_obj.browse(cr, uid, ids, context=context):
|
||||||
alarm_ids = alarm_obj.search(cr, uid, [('model_id', '=', model_id), ('res_id', '=', datas.id)])
|
alarm_ids = alarm_obj.search(cr, uid, [('model_id', '=', model_id), ('res_id', '=', data.id)])
|
||||||
if alarm_ids:
|
if alarm_ids:
|
||||||
alarm_obj.unlink(cr, uid, alarm_ids)
|
alarm_obj.unlink(cr, uid, alarm_ids)
|
||||||
cr.execute('Update %s set base_calendar_alarm_id=NULL, alarm_id=NULL\
|
cr.execute('Update %s set base_calendar_alarm_id=NULL, alarm_id=NULL\
|
||||||
where id=%%s' % model_obj._table,(datas.id,))
|
where id=%%s' % model_obj._table,(data.id,))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
res_alarm()
|
res_alarm()
|
||||||
|
@ -773,7 +779,7 @@ class calendar_alarm(osv.osv):
|
||||||
Overrides orm create method.
|
Overrides orm create method.
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param vals: dictionary of fields value.{‘name_of_the_field’: value, ...}
|
@param vals: dictionary of fields value.{'name_of_the_field': value, ...}
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: new record id for calendar_alarm.
|
@return: new record id for calendar_alarm.
|
||||||
"""
|
"""
|
||||||
|
@ -798,8 +804,8 @@ class calendar_alarm(osv.osv):
|
||||||
"""Scheduler for event reminder
|
"""Scheduler for event reminder
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of calendar alarm’s IDs.
|
@param ids: List of calendar alarm's IDs.
|
||||||
@param use_new_cursor: False or the dbname
|
@param use_new_cursor: False or the dbname
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
|
@ -891,8 +897,8 @@ class calendar_event(osv.osv):
|
||||||
"""Returns duration and/or end date based on values passed
|
"""Returns duration and/or end date based on values passed
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of calendar event’s IDs.
|
@param ids: List of calendar event's IDs.
|
||||||
@param start_date: Starting date
|
@param start_date: Starting date
|
||||||
@param duration: Duration between start date and end date
|
@param duration: Duration between start date and end date
|
||||||
@param end_date: Ending Datee
|
@param end_date: Ending Datee
|
||||||
|
@ -967,14 +973,14 @@ class calendar_event(osv.osv):
|
||||||
if not isinstance(ids, list):
|
if not isinstance(ids, list):
|
||||||
ids = [ids]
|
ids = [ids]
|
||||||
|
|
||||||
for datas in self.read(cr, uid, ids, ['id','byday','recurrency', 'month_list','end_date', 'rrule_type', 'select1', 'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'exrule', 'day', 'week_list' ], context=context):
|
for data in self.read(cr, uid, ids, ['id','byday','recurrency', 'month_list','end_date', 'rrule_type', 'select1', 'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'exrule', 'day', 'week_list' ], context=context):
|
||||||
event = datas['id']
|
event = data['id']
|
||||||
if datas.get('interval', 0) < 0:
|
if data.get('interval', 0) < 0:
|
||||||
raise osv.except_osv(_('Warning!'), _('Interval cannot be negative.'))
|
raise osv.except_osv(_('Warning!'), _('Interval cannot be negative.'))
|
||||||
if datas.get('count', 0) <= 0:
|
if data.get('count', 0) <= 0:
|
||||||
raise osv.except_osv(_('Warning!'), _('Count cannot be negative or 0.'))
|
raise osv.except_osv(_('Warning!'), _('Count cannot be negative or 0.'))
|
||||||
if datas['recurrency']:
|
if data['recurrency']:
|
||||||
result[event] = self.compute_rule_string(datas)
|
result[event] = self.compute_rule_string(data)
|
||||||
else:
|
else:
|
||||||
result[event] = ""
|
result[event] = ""
|
||||||
return result
|
return result
|
||||||
|
@ -990,7 +996,6 @@ class calendar_event(osv.osv):
|
||||||
super(calendar_event, obj).write(cr, uid, ids, data, context=context)
|
super(calendar_event, obj).write(cr, uid, ids, data, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'id': fields.integer('ID', readonly=True),
|
'id': fields.integer('ID', readonly=True),
|
||||||
'sequence': fields.integer('Sequence'),
|
'sequence': fields.integer('Sequence'),
|
||||||
|
@ -1006,21 +1011,24 @@ class calendar_event(osv.osv):
|
||||||
'show_as': fields.selection([('free', 'Free'), ('busy', 'Busy')], \
|
'show_as': fields.selection([('free', 'Free'), ('busy', 'Busy')], \
|
||||||
'Show Time as', states={'done': [('readonly', True)]}),
|
'Show Time as', states={'done': [('readonly', True)]}),
|
||||||
'base_calendar_url': fields.char('Caldav URL', size=264),
|
'base_calendar_url': fields.char('Caldav URL', size=264),
|
||||||
'state': fields.selection([('tentative', 'Tentative'),
|
'state': fields.selection([
|
||||||
('cancelled', 'Cancelled'),
|
('tentative', 'Tentative'),
|
||||||
('confirmed', 'Confirmed'),
|
('cancelled', 'Cancelled'),
|
||||||
], 'Status', readonly=True),
|
('confirmed', 'Confirmed'),
|
||||||
|
], 'Status', readonly=True),
|
||||||
'exdate': fields.text('Exception Date/Times', help="This property \
|
'exdate': fields.text('Exception Date/Times', help="This property \
|
||||||
defines the list of date/time exceptions for a recurring calendar component."),
|
defines the list of date/time exceptions for a recurring calendar component."),
|
||||||
'exrule': fields.char('Exception Rule', size=352, help="Defines a \
|
'exrule': fields.char('Exception Rule', size=352, help="Defines a \
|
||||||
rule or repeating pattern of time to exclude from the recurring rule."),
|
rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
'rrule': fields.function(_get_rulestring, type='char', size=124, \
|
'rrule': fields.function(_get_rulestring, type='char', size=124, \
|
||||||
fnct_inv=_rrule_write, store=True, string='Recurrent Rule'),
|
fnct_inv=_rrule_write, store=True, string='Recurrent Rule'),
|
||||||
'rrule_type': fields.selection([('none', ''), ('daily', 'Daily'), \
|
'rrule_type': fields.selection([
|
||||||
('weekly', 'Weekly'), ('monthly', 'Monthly'), \
|
('daily', 'Daily'),
|
||||||
('yearly', 'Yearly'),],
|
('weekly', 'Weekly'),
|
||||||
'Recurrency', states={'done': [('readonly', True)]},
|
('monthly', 'Monthly'),
|
||||||
help="Let the event automatically repeat at that interval"),
|
('yearly', 'Yearly')
|
||||||
|
], 'Recurrency', states={'done': [('readonly', True)]},
|
||||||
|
help="Let the event automatically repeat at that interval"),
|
||||||
'alarm_id': fields.many2one('res.alarm', 'Reminder', states={'done': [('readonly', True)]},
|
'alarm_id': fields.many2one('res.alarm', 'Reminder', states={'done': [('readonly', True)]},
|
||||||
help="Set an alarm at this time, before the event occurs" ),
|
help="Set an alarm at this time, before the event occurs" ),
|
||||||
'base_calendar_alarm_id': fields.many2one('calendar.alarm', 'Alarm'),
|
'base_calendar_alarm_id': fields.many2one('calendar.alarm', 'Alarm'),
|
||||||
|
@ -1028,7 +1036,7 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
'recurrent_id': fields.datetime('Recurrent ID date'),
|
'recurrent_id': fields.datetime('Recurrent ID date'),
|
||||||
'vtimezone': fields.selection(_tz_get, size=64, string='Timezone'),
|
'vtimezone': fields.selection(_tz_get, size=64, string='Timezone'),
|
||||||
'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
|
'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
|
||||||
'organizer': fields.char("Organizer", size=256, states={'done': [('readonly', True)]}), # Map with Organizer Attribure of VEvent.
|
'organizer': fields.char("Organizer", size=256, states={'done': [('readonly', True)]}), # Map with organizer attribute of VEvent.
|
||||||
'organizer_id': fields.many2one('res.users', 'Organizer', states={'done': [('readonly', True)]}),
|
'organizer_id': fields.many2one('res.users', 'Organizer', states={'done': [('readonly', True)]}),
|
||||||
'end_type' : fields.selection([('count', 'Number of repetitions'), ('end_date','End date')], 'Recurrence Termination'),
|
'end_type' : fields.selection([('count', 'Number of repetitions'), ('end_date','End date')], 'Recurrence Termination'),
|
||||||
'interval': fields.integer('Repeat Every', help="Repeat every (Days/Week/Month/Year)"),
|
'interval': fields.integer('Repeat Every', help="Repeat every (Days/Week/Month/Year)"),
|
||||||
|
@ -1043,13 +1051,21 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
'select1': fields.selection([('date', 'Date of month'),
|
'select1': fields.selection([('date', 'Date of month'),
|
||||||
('day', 'Day of month')], 'Option'),
|
('day', 'Day of month')], 'Option'),
|
||||||
'day': fields.integer('Date of month'),
|
'day': fields.integer('Date of month'),
|
||||||
'week_list': fields.selection([('MO', 'Monday'), ('TU', 'Tuesday'), \
|
'week_list': fields.selection([
|
||||||
('WE', 'Wednesday'), ('TH', 'Thursday'), \
|
('MO', 'Monday'),
|
||||||
('FR', 'Friday'), ('SA', 'Saturday'), \
|
('TU', 'Tuesday'),
|
||||||
('SU', 'Sunday')], 'Weekday'),
|
('WE', 'Wednesday'),
|
||||||
'byday': fields.selection([('1', 'First'), ('2', 'Second'), \
|
('TH', 'Thursday'),
|
||||||
('3', 'Third'), ('4', 'Fourth'), \
|
('FR', 'Friday'),
|
||||||
('5', 'Fifth'), ('-1', 'Last')], 'By day'),
|
('SA', 'Saturday'),
|
||||||
|
('SU', 'Sunday')], 'Weekday'),
|
||||||
|
'byday': fields.selection([
|
||||||
|
('1', 'First'),
|
||||||
|
('2', 'Second'),
|
||||||
|
('3', 'Third'),
|
||||||
|
('4', 'Fourth'),
|
||||||
|
('5', 'Fifth'),
|
||||||
|
('-1', 'Last')], 'By day'),
|
||||||
'month_list': fields.selection(months.items(), 'Month'),
|
'month_list': fields.selection(months.items(), 'Month'),
|
||||||
'end_date': fields.date('Repeat Until'),
|
'end_date': fields.date('Repeat Until'),
|
||||||
'attendee_ids': fields.many2many('calendar.attendee', 'event_attendee_rel', \
|
'attendee_ids': fields.many2many('calendar.attendee', 'event_attendee_rel', \
|
||||||
|
@ -1101,9 +1117,9 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'end_type' : 'count',
|
'end_type': 'count',
|
||||||
'count' : 1,
|
'count': 1,
|
||||||
'rrule_type' : 'none',
|
'rrule_type': False,
|
||||||
'state': 'tentative',
|
'state': 'tentative',
|
||||||
'class': 'public',
|
'class': 'public',
|
||||||
'show_as': 'busy',
|
'show_as': 'busy',
|
||||||
|
@ -1113,7 +1129,7 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
'user_id': lambda self, cr, uid, ctx: uid,
|
'user_id': lambda self, cr, uid, ctx: uid,
|
||||||
'organizer': default_organizer,
|
'organizer': default_organizer,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _check_closing_date(self, cr, uid, ids, context=None):
|
def _check_closing_date(self, cr, uid, ids, context=None):
|
||||||
for event in self.browse(cr, uid, ids, context=context):
|
for event in self.browse(cr, uid, ids, context=context):
|
||||||
if event.date_deadline < event.date:
|
if event.date_deadline < event.date:
|
||||||
|
@ -1129,7 +1145,7 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
This method gives ids of dates that comes between start date and end date of calendar views
|
This method gives ids of dates that comes between start date and end date of calendar views
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param limit: The Number of Results to Return """
|
@param limit: The Number of Results to Return """
|
||||||
if not context:
|
if not context:
|
||||||
context = {}
|
context = {}
|
||||||
|
@ -1140,7 +1156,8 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
result.append(data['id'])
|
result.append(data['id'])
|
||||||
continue
|
continue
|
||||||
event_date = datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
|
event_date = datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
|
||||||
# To check: If the start date is replace by event date .. the event date will be changed by that of calendar code
|
|
||||||
|
# TOCHECK: the start date should be replaced by event date; the event date will be changed by that of calendar code
|
||||||
|
|
||||||
if not data['rrule']:
|
if not data['rrule']:
|
||||||
continue
|
continue
|
||||||
|
@ -1186,45 +1203,46 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
ids = list(set(result))
|
ids = list(set(result))
|
||||||
return ids
|
return ids
|
||||||
|
|
||||||
def compute_rule_string(self, datas):
|
def compute_rule_string(self, data):
|
||||||
"""
|
"""
|
||||||
Compute rule string according to value type RECUR of iCalendar from the values given.
|
Compute rule string according to value type RECUR of iCalendar from the values given.
|
||||||
@param self: the object pointer
|
@param self: the object pointer
|
||||||
@param datas: dictionary of freq and interval value.
|
@param data: dictionary of freq and interval value
|
||||||
|
@return: string containing recurring rule (empty if no rule)
|
||||||
"""
|
"""
|
||||||
def get_week_string(freq, datas):
|
def get_week_string(freq, data):
|
||||||
weekdays = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
|
weekdays = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
|
||||||
if freq == 'weekly':
|
if freq == 'weekly':
|
||||||
byday = map(lambda x: x.upper(), filter(lambda x: datas.get(x) and x in weekdays, datas))
|
byday = map(lambda x: x.upper(), filter(lambda x: data.get(x) and x in weekdays, data))
|
||||||
if byday:
|
if byday:
|
||||||
return ';BYDAY=' + ','.join(byday)
|
return ';BYDAY=' + ','.join(byday)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_month_string(freq, datas):
|
def get_month_string(freq, data):
|
||||||
if freq == 'monthly':
|
if freq == 'monthly':
|
||||||
if datas.get('select1')=='date' and (datas.get('day') < 1 or datas.get('day') > 31):
|
if data.get('select1')=='date' and (data.get('day') < 1 or data.get('day') > 31):
|
||||||
raise osv.except_osv(_('Error!'), ("Please select a proper day of the month."))
|
raise osv.except_osv(_('Error!'), ("Please select a proper day of the month."))
|
||||||
|
|
||||||
if datas.get('select1')=='day':
|
if data.get('select1')=='day':
|
||||||
return ';BYDAY=' + datas.get('byday') + datas.get('week_list')
|
return ';BYDAY=' + data.get('byday') + data.get('week_list')
|
||||||
elif datas.get('select1')=='date':
|
elif data.get('select1')=='date':
|
||||||
return ';BYMONTHDAY=' + str(datas.get('day'))
|
return ';BYMONTHDAY=' + str(data.get('day'))
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_end_date(datas):
|
def get_end_date(data):
|
||||||
if datas.get('end_date'):
|
if data.get('end_date'):
|
||||||
datas['end_date_new'] = ''.join((re.compile('\d')).findall(datas.get('end_date'))) + 'T235959Z'
|
data['end_date_new'] = ''.join((re.compile('\d')).findall(data.get('end_date'))) + 'T235959Z'
|
||||||
|
|
||||||
return (datas.get('end_type') == 'count' and (';COUNT=' + str(datas.get('count'))) or '') +\
|
return (data.get('end_type') == 'count' and (';COUNT=' + str(data.get('count'))) or '') +\
|
||||||
((datas.get('end_date_new') and datas.get('end_type') == 'end_date' and (';UNTIL=' + datas.get('end_date_new'))) or '')
|
((data.get('end_date_new') and data.get('end_type') == 'end_date' and (';UNTIL=' + data.get('end_date_new'))) or '')
|
||||||
|
|
||||||
freq=datas.get('rrule_type')
|
freq = data.get('rrule_type', False)
|
||||||
if freq == 'none':
|
res = ''
|
||||||
return ''
|
if freq:
|
||||||
|
interval_srting = data.get('interval') and (';INTERVAL=' + str(data.get('interval'))) or ''
|
||||||
|
res = 'FREQ=' + freq.upper() + get_week_string(freq, data) + interval_srting + get_end_date(data) + get_month_string(freq, data)
|
||||||
|
|
||||||
interval_srting = datas.get('interval') and (';INTERVAL=' + str(datas.get('interval'))) or ''
|
return res
|
||||||
|
|
||||||
return 'FREQ=' + freq.upper() + get_week_string(freq, datas) + interval_srting + get_end_date(datas) + get_month_string(freq, datas)
|
|
||||||
|
|
||||||
def _get_empty_rrule_data(self):
|
def _get_empty_rrule_data(self):
|
||||||
return {
|
return {
|
||||||
|
@ -1248,19 +1266,6 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
'week_list' : False
|
'week_list' : False
|
||||||
}
|
}
|
||||||
|
|
||||||
#def _write_rrule(self, cr, uid, ids, field_value, rule_date=False, context=None):
|
|
||||||
# data = self._get_empty_rrule_data()
|
|
||||||
#
|
|
||||||
# if field_value:
|
|
||||||
# data['recurrency'] = True
|
|
||||||
# for event in self.browse(cr, uid, ids, context=context):
|
|
||||||
# rdate = rule_date or event.date
|
|
||||||
# update_data = self._parse_rrule(field_value, dict(data), rdate)
|
|
||||||
# data.update(update_data)
|
|
||||||
# #parse_rrule
|
|
||||||
# self.write(cr, uid, event.id, data, context=context)
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_rrule(self, rule, data, date_start):
|
def _parse_rrule(self, rule, data, date_start):
|
||||||
day_list = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
|
day_list = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
|
||||||
rrule_type = ['yearly', 'monthly', 'weekly', 'daily']
|
rrule_type = ['yearly', 'monthly', 'weekly', 'daily']
|
||||||
|
@ -1278,7 +1283,7 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
if i in r._byweekday:
|
if i in r._byweekday:
|
||||||
data[day_list[i]] = True
|
data[day_list[i]] = True
|
||||||
data['rrule_type'] = 'weekly'
|
data['rrule_type'] = 'weekly'
|
||||||
#repeat monthly bynweekday ((weekday, weeknumber), )
|
#repeat monthly by nweekday ((weekday, weeknumber), )
|
||||||
if r._bynweekday:
|
if r._bynweekday:
|
||||||
data['week_list'] = day_list[r._bynweekday[0][0]].upper()
|
data['week_list'] = day_list[r._bynweekday[0][0]].upper()
|
||||||
data['byday'] = r._bynweekday[0][1]
|
data['byday'] = r._bynweekday[0][1]
|
||||||
|
@ -1290,7 +1295,7 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
data['select1'] = 'date'
|
data['select1'] = 'date'
|
||||||
data['rrule_type'] = 'monthly'
|
data['rrule_type'] = 'monthly'
|
||||||
|
|
||||||
#yearly but for openerp it's monthly, take same information as monthly but interval is 12 times
|
#repeat yearly but for openerp it's monthly, take same information as monthly but interval is 12 times
|
||||||
if r._bymonth:
|
if r._bymonth:
|
||||||
data['interval'] = data['interval'] * 12
|
data['interval'] = data['interval'] * 12
|
||||||
|
|
||||||
|
@ -1363,7 +1368,6 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
except Exception:
|
except Exception:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
|
def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
|
||||||
context = context or {}
|
context = context or {}
|
||||||
if isinstance(ids, (str, int, long)):
|
if isinstance(ids, (str, int, long)):
|
||||||
|
@ -1384,14 +1388,14 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
data = self.read(cr, uid, event_id, ['date', 'date_deadline', \
|
data = self.read(cr, uid, event_id, ['date', 'date_deadline', \
|
||||||
'rrule', 'duration', 'exdate'])
|
'rrule', 'duration', 'exdate'])
|
||||||
if data.get('rrule'):
|
if data.get('rrule'):
|
||||||
data.update(vals)
|
data.update(
|
||||||
data.update({
|
vals,
|
||||||
'recurrent_uid': real_event_id,
|
recurrent_uid=real_event_id,
|
||||||
'recurrent_id': data.get('date'),
|
recurrent_id=data.get('date'),
|
||||||
'rrule_type': 'none',
|
rrule_type=False,
|
||||||
'rrule': '',
|
rrule='',
|
||||||
'recurrency' : False,
|
recurrency=False,
|
||||||
})
|
)
|
||||||
|
|
||||||
new_id = self.copy(cr, uid, real_event_id, default=data, context=context)
|
new_id = self.copy(cr, uid, real_event_id, default=data, context=context)
|
||||||
|
|
||||||
|
@ -1435,7 +1439,6 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
||||||
# FIXME This whole id mangling has to go!
|
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
fields2 = fields and fields[:] or None
|
fields2 = fields and fields[:] or None
|
||||||
|
@ -1445,10 +1448,12 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
if fields and (f not in fields):
|
if fields and (f not in fields):
|
||||||
fields2.append(f)
|
fields2.append(f)
|
||||||
|
|
||||||
|
# FIXME This whole id mangling has to go!
|
||||||
if isinstance(ids, (str, int, long)):
|
if isinstance(ids, (str, int, long)):
|
||||||
select = [ids]
|
select = [ids]
|
||||||
else:
|
else:
|
||||||
select = ids
|
select = ids
|
||||||
|
|
||||||
select = map(lambda x: (x, base_calendar_id2real_id(x)), select)
|
select = map(lambda x: (x, base_calendar_id2real_id(x)), select)
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
|
@ -1477,7 +1482,7 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
if f not in ('id','date','date_deadline','duration','user_id','state'):
|
if f not in ('id','date','date_deadline','duration','user_id','state'):
|
||||||
if isinstance(r[f], list):
|
if isinstance(r[f], list):
|
||||||
r[f] = []
|
r[f] = []
|
||||||
else:
|
else:
|
||||||
r[f] = False
|
r[f] = False
|
||||||
if f=='name':
|
if f=='name':
|
||||||
r[f] = _('Busy')
|
r[f] = _('Busy')
|
||||||
|
@ -1525,7 +1530,6 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
self.unlink_events(cr, uid, ids, context=context)
|
self.unlink_events(cr, uid, ids, context=context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def create(self, cr, uid, vals, context=None):
|
def create(self, cr, uid, vals, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
@ -1543,7 +1547,7 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
""" Makes event invitation as Tentative
|
""" Makes event invitation as Tentative
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of Event IDs
|
@param ids: List of Event IDs
|
||||||
@param *args: Get Tupple value
|
@param *args: Get Tupple value
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
|
@ -1554,7 +1558,7 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
""" Makes event invitation as Tentative
|
""" Makes event invitation as Tentative
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of Event IDs
|
@param ids: List of Event IDs
|
||||||
@param *args: Get Tupple value
|
@param *args: Get Tupple value
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
|
@ -1565,7 +1569,7 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
||||||
""" Makes event invitation as Tentative
|
""" Makes event invitation as Tentative
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of Event IDs
|
@param ids: List of Event IDs
|
||||||
@param *args: Get Tupple value
|
@param *args: Get Tupple value
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
|
@ -1586,9 +1590,9 @@ class calendar_todo(osv.osv):
|
||||||
Get Date
|
Get Date
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of calendar todo's IDs.
|
@param ids: List of calendar todo's IDs.
|
||||||
@param args: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...].
|
@param args: list of tuples of form [(‘name_of_the_field', ‘operator', value), ...].
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -1602,10 +1606,10 @@ class calendar_todo(osv.osv):
|
||||||
Set Date
|
Set Date
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param id: calendar's ID.
|
@param id: calendar's ID.
|
||||||
@param value: Get Value
|
@param value: Get Value
|
||||||
@param args: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...].
|
@param args: list of tuples of form [('name_of_the_field', 'operator', value), ...].
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -1633,7 +1637,7 @@ class ir_values(osv.osv):
|
||||||
Set IR Values
|
Set IR Values
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param model: Get The Model
|
@param model: Get The Model
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -1652,7 +1656,7 @@ class ir_values(osv.osv):
|
||||||
Get IR Values
|
Get IR Values
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param model: Get The Model
|
@param model: Get The Model
|
||||||
"""
|
"""
|
||||||
if context is None:
|
if context is None:
|
||||||
|
@ -1678,8 +1682,8 @@ class ir_model(osv.osv):
|
||||||
Overrides orm read method.
|
Overrides orm read method.
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of IR Model’s IDs.
|
@param ids: List of IR Model's IDs.
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
new_ids = isinstance(ids, (str, int, long)) and [ids] or ids
|
new_ids = isinstance(ids, (str, int, long)) and [ids] or ids
|
||||||
|
@ -1696,24 +1700,24 @@ ir_model()
|
||||||
|
|
||||||
class virtual_report_spool(web_services.report_spool):
|
class virtual_report_spool(web_services.report_spool):
|
||||||
|
|
||||||
def exp_report(self, db, uid, object, ids, datas=None, context=None):
|
def exp_report(self, db, uid, object, ids, data=None, context=None):
|
||||||
"""
|
"""
|
||||||
Export Report
|
Export Report
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param db: get the current database,
|
@param db: get the current database,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if object == 'printscreen.list':
|
if object == 'printscreen.list':
|
||||||
return super(virtual_report_spool, self).exp_report(db, uid, \
|
return super(virtual_report_spool, self).exp_report(db, uid, \
|
||||||
object, ids, datas, context)
|
object, ids, data, context)
|
||||||
new_ids = []
|
new_ids = []
|
||||||
for id in ids:
|
for id in ids:
|
||||||
new_ids.append(base_calendar_id2real_id(id))
|
new_ids.append(base_calendar_id2real_id(id))
|
||||||
if datas.get('id', False):
|
if data.get('id', False):
|
||||||
datas['id'] = base_calendar_id2real_id(datas['id'])
|
data['id'] = base_calendar_id2real_id(data['id'])
|
||||||
return super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, datas, context)
|
return super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, data, context)
|
||||||
|
|
||||||
virtual_report_spool()
|
virtual_report_spool()
|
||||||
|
|
||||||
|
@ -1725,8 +1729,8 @@ class res_users(osv.osv):
|
||||||
Get User Availability
|
Get User Availability
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of res user’s IDs.
|
@param ids: List of res user's IDs.
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -1755,8 +1759,8 @@ class res_users(osv.osv):
|
||||||
Get User Availability Function
|
Get User Availability Function
|
||||||
@param self: The object pointer
|
@param self: The object pointer
|
||||||
@param cr: the current row, from the database cursor,
|
@param cr: the current row, from the database cursor,
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user's ID for security checks,
|
||||||
@param ids: List of res user’s IDs.
|
@param ids: List of res user's IDs.
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -1770,5 +1774,4 @@ class res_users(osv.osv):
|
||||||
|
|
||||||
res_users()
|
res_users()
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data>
|
||||||
<!-- Attendee form view-->
|
<!-- Attendee form view -->
|
||||||
|
|
||||||
<record id="base_calendar_attendee_form_view" model="ir.ui.view">
|
<record id="base_calendar_attendee_form_view" model="ir.ui.view">
|
||||||
<field name="name">calendar.attendee.form</field>
|
<field name="name">calendar.attendee.form</field>
|
||||||
<field name="model">calendar.attendee</field>
|
<field name="model">calendar.attendee</field>
|
||||||
|
@ -55,8 +54,7 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Attendee tree view-->
|
<!-- Attendee tree view -->
|
||||||
|
|
||||||
<record id="base_calendar_attendee_tree_view" model="ir.ui.view">
|
<record id="base_calendar_attendee_tree_view" model="ir.ui.view">
|
||||||
<field name="name">calendar.attendee.tree</field>
|
<field name="name">calendar.attendee.tree</field>
|
||||||
<field name="model">calendar.attendee</field>
|
<field name="model">calendar.attendee</field>
|
||||||
|
@ -73,8 +71,7 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Attendee search view-->
|
<!-- Attendee search view -->
|
||||||
|
|
||||||
<record id="base_calendar_attendee_search_view" model="ir.ui.view">
|
<record id="base_calendar_attendee_search_view" model="ir.ui.view">
|
||||||
<field name="name">calendar.attendee.search</field>
|
<field name="name">calendar.attendee.search</field>
|
||||||
<field name="model">calendar.attendee</field>
|
<field name="model">calendar.attendee</field>
|
||||||
|
@ -110,18 +107,16 @@
|
||||||
<field name="context">{'default_sent_by_uid': uid}</field>
|
<field name="context">{'default_sent_by_uid': uid}</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Calenadar's menu -->
|
<!-- Calendar's menu -->
|
||||||
<menuitem id="base.menu_calendar_configuration" name="Calendar"
|
<menuitem id="base.menu_calendar_configuration" name="Calendar"
|
||||||
parent="base.menu_base_config" sequence="50" groups="base.group_no_one"/>
|
parent="base.menu_base_config" sequence="50" groups="base.group_no_one"/>
|
||||||
|
|
||||||
<!-- Invitation menu -->
|
<!-- Invitation menu -->
|
||||||
|
|
||||||
<menuitem id="menu_attendee_invitations"
|
<menuitem id="menu_attendee_invitations"
|
||||||
parent="base.menu_calendar_configuration"
|
parent="base.menu_calendar_configuration"
|
||||||
sequence="10" action="action_view_attendee_form"/>
|
sequence="10" action="action_view_attendee_form"/>
|
||||||
|
|
||||||
<!-- ALARM FORM VIEW-->
|
<!-- Alarm form view -->
|
||||||
|
|
||||||
<record id="res_alarm_form_view" model="ir.ui.view">
|
<record id="res_alarm_form_view" model="ir.ui.view">
|
||||||
<field name="name">res.alarm.form</field>
|
<field name="name">res.alarm.form</field>
|
||||||
<field name="model">res.alarm</field>
|
<field name="model">res.alarm</field>
|
||||||
|
@ -140,8 +135,7 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- ALARM TREE VIEW-->
|
<!-- Alarm list view -->
|
||||||
|
|
||||||
<record id="res_alarm_tree_view" model="ir.ui.view">
|
<record id="res_alarm_tree_view" model="ir.ui.view">
|
||||||
<field name="name">res.alarm.tree</field>
|
<field name="name">res.alarm.tree</field>
|
||||||
<field name="model">res.alarm</field>
|
<field name="model">res.alarm</field>
|
||||||
|
@ -171,15 +165,13 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Menu for Alarms-->
|
<!-- Alarms menu -->
|
||||||
|
|
||||||
<menuitem id="menu_crm_meeting_avail_alarm"
|
<menuitem id="menu_crm_meeting_avail_alarm"
|
||||||
groups="base.group_no_one"
|
groups="base.group_no_one"
|
||||||
action="base_calendar.action_res_alarm_view"
|
action="base_calendar.action_res_alarm_view"
|
||||||
parent="base.menu_calendar_configuration" sequence="5"/>
|
parent="base.menu_calendar_configuration" sequence="5"/>
|
||||||
|
|
||||||
<!-- Event Form View-->
|
<!-- Event form view -->
|
||||||
|
|
||||||
<record model="ir.ui.view" id="event_form_view">
|
<record model="ir.ui.view" id="event_form_view">
|
||||||
<field name="name">Event Form</field>
|
<field name="name">Event Form</field>
|
||||||
<field name="model">calendar.event</field>
|
<field name="model">calendar.event</field>
|
||||||
|
@ -334,8 +326,7 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Event Tree View -->
|
<!-- Event list view -->
|
||||||
|
|
||||||
<record model="ir.ui.view" id="event_tree_view">
|
<record model="ir.ui.view" id="event_tree_view">
|
||||||
<field name="name">Event Tree</field>
|
<field name="name">Event Tree</field>
|
||||||
<field name="model">calendar.event</field>
|
<field name="model">calendar.event</field>
|
||||||
|
@ -352,8 +343,7 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Event Calendar View -->
|
<!-- Event calendar view -->
|
||||||
|
|
||||||
<record model="ir.ui.view" id="event_calendar_view">
|
<record model="ir.ui.view" id="event_calendar_view">
|
||||||
<field name="name">Events Calendar</field>
|
<field name="name">Events Calendar</field>
|
||||||
<field name="model">calendar.event</field>
|
<field name="model">calendar.event</field>
|
||||||
|
@ -367,8 +357,7 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Event Search View-->
|
<!-- Event search view -->
|
||||||
|
|
||||||
<record id="view_calendar_event_filter" model="ir.ui.view">
|
<record id="view_calendar_event_filter" model="ir.ui.view">
|
||||||
<field name="name">Calendar Events Search</field>
|
<field name="name">Calendar Events Search</field>
|
||||||
<field name="model">calendar.event</field>
|
<field name="model">calendar.event</field>
|
||||||
|
@ -393,8 +382,7 @@
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
||||||
<!-- Event action -->
|
<!-- Event action -->
|
||||||
|
|
||||||
<record id="action_view_event" model="ir.actions.act_window">
|
<record id="action_view_event" model="ir.actions.act_window">
|
||||||
<field name="name">Events</field>
|
<field name="name">Events</field>
|
||||||
<field name="type">ir.actions.act_window</field>
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
@ -404,8 +392,7 @@
|
||||||
<field name="search_view_id" ref="view_calendar_event_filter"/>
|
<field name="search_view_id" ref="view_calendar_event_filter"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Event menu -->
|
<!-- Event menu -->
|
||||||
|
|
||||||
<menuitem id="menu_events"
|
<menuitem id="menu_events"
|
||||||
name="Events" parent="base.menu_calendar_configuration"
|
name="Events" parent="base.menu_calendar_configuration"
|
||||||
sequence="15" action="action_view_event"/>
|
sequence="15" action="action_view_event"/>
|
||||||
|
|
|
@ -43,14 +43,14 @@ class crm_meeting(base_state, osv.Model):
|
||||||
_name = 'crm.meeting'
|
_name = 'crm.meeting'
|
||||||
_description = "Meeting"
|
_description = "Meeting"
|
||||||
_order = "id desc"
|
_order = "id desc"
|
||||||
_inherit = ["calendar.event", "mail.thread", 'ir.needaction_mixin']
|
_inherit = ["calendar.event", "mail.thread", "ir.needaction_mixin"]
|
||||||
_columns = {
|
_columns = {
|
||||||
# base_state required fields
|
# base_state required fields
|
||||||
'create_date': fields.datetime('Creation Date', readonly=True),
|
'create_date': fields.datetime('Creation Date', readonly=True),
|
||||||
'write_date': fields.datetime('Write Date', readonly=True),
|
'write_date': fields.datetime('Write Date', readonly=True),
|
||||||
'date_open': fields.datetime('Confirmed', readonly=True),
|
'date_open': fields.datetime('Confirmed', readonly=True),
|
||||||
'date_closed': fields.datetime('Closed', readonly=True),
|
'date_closed': fields.datetime('Closed', readonly=True),
|
||||||
'partner_ids': fields.many2many('res.partner', 'crm_meeting_partner_rel', 'meeting_id','partner_id',
|
'partner_ids': fields.many2many('res.partner', 'crm_meeting_partner_rel', 'meeting_id', 'partner_id',
|
||||||
string='Attendees', states={'done': [('readonly', True)]}),
|
string='Attendees', states={'done': [('readonly', True)]}),
|
||||||
'state': fields.selection(
|
'state': fields.selection(
|
||||||
[('draft', 'Unconfirmed'), ('open', 'Confirmed')],
|
[('draft', 'Unconfirmed'), ('open', 'Confirmed')],
|
||||||
|
@ -115,5 +115,3 @@ class crm_meeting(base_state, osv.Model):
|
||||||
|
|
||||||
def case_close_send_note(self, cr, uid, ids, context=None):
|
def case_close_send_note(self, cr, uid, ids, context=None):
|
||||||
return self.message_post(cr, uid, ids, body=_("Meeting <b>completed</b>."), context=context)
|
return self.message_post(cr, uid, ids, body=_("Meeting <b>completed</b>."), context=context)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
<record id="action_crm_meeting_read" model="ir.values">
|
<record id="action_crm_meeting_read" model="ir.values">
|
||||||
<field name="name">action_crm_meeting_read</field>
|
<field name="name">action_crm_meeting_read</field>
|
||||||
<field name="action_id" ref="actions_server_crm_meeting_read"/>
|
<field name="action_id" ref="actions_server_crm_meeting_read"/>
|
||||||
<field name="value" eval="'ir.actions.server,' + str(ref('actions_server_crm_meeting_read'))" />
|
<field name="value" eval="'ir.actions.server,' + str(ref('actions_server_crm_meeting_read'))"/>
|
||||||
<field name="key">action</field>
|
<field name="key">action</field>
|
||||||
<field name="model_id" ref="model_crm_meeting" />
|
<field name="model_id" ref="model_crm_meeting"/>
|
||||||
<field name="model">crm.meeting</field>
|
<field name="model">crm.meeting</field>
|
||||||
<field name="key2">client_action_multi</field>
|
<field name="key2">client_action_multi</field>
|
||||||
</record>
|
</record>
|
||||||
|
@ -33,9 +33,9 @@
|
||||||
<record id="action_crm_meeting_unread" model="ir.values">
|
<record id="action_crm_meeting_unread" model="ir.values">
|
||||||
<field name="name">action_crm_meeting_unread</field>
|
<field name="name">action_crm_meeting_unread</field>
|
||||||
<field name="action_id" ref="actions_server_crm_meeting_unread"/>
|
<field name="action_id" ref="actions_server_crm_meeting_unread"/>
|
||||||
<field name="value" eval="'ir.actions.server,' + str(ref('actions_server_crm_meeting_unread'))" />
|
<field name="value" eval="'ir.actions.server,' + str(ref('actions_server_crm_meeting_unread'))"/>
|
||||||
<field name="key">action</field>
|
<field name="key">action</field>
|
||||||
<field name="model_id" ref="model_crm_meeting" />
|
<field name="model_id" ref="model_crm_meeting"/>
|
||||||
<field name="model">crm.meeting</field>
|
<field name="model">crm.meeting</field>
|
||||||
<field name="key2">client_action_multi</field>
|
<field name="key2">client_action_multi</field>
|
||||||
</record>
|
</record>
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
<sheet>
|
<sheet>
|
||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
<div class="oe_edit_only">
|
<div class="oe_edit_only">
|
||||||
<label for="name"/>
|
<label for="name"/>
|
||||||
</div>
|
</div>
|
||||||
<h1>
|
<h1>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
|
@ -116,9 +116,49 @@
|
||||||
</page>
|
</page>
|
||||||
<page string="Options">
|
<page string="Options">
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group col="1">
|
||||||
<field name="recurrency"
|
<group>
|
||||||
attrs="{'readonly': [('recurrent_uid','!=',False)]}"/>
|
<field name="recurrency"
|
||||||
|
attrs="{'readonly': [('recurrent_uid','!=',False)]}"/>
|
||||||
|
</group>
|
||||||
|
<group attrs="{'invisible': [('recurrency','=',False)]}">
|
||||||
|
<label for="interval"/>
|
||||||
|
<div>
|
||||||
|
<field name="interval" attrs="{'required': [('recurrency','==',True)]}" class="oe_inline"/>
|
||||||
|
<field name="rrule_type" attrs="{'required': [('recurrency','==',True)]}" class="oe_inline"/>
|
||||||
|
</div>
|
||||||
|
<label string="Until" for="end_type"/>
|
||||||
|
<div>
|
||||||
|
<field name="end_type" attrs="{'required': [('recurrency','==',True)]}" class="oe_inline"/>
|
||||||
|
<field name="count" attrs="{'invisible': [('end_type', '!=', 'count')], 'required': [('recurrency','==',True)]}" class="oe_inline"/>
|
||||||
|
<field name="end_date" attrs="{'invisible': [('end_type', '!=', 'end_date')], 'required': [('end_type', '=', 'end_date')]}" class="oe_inline"/>
|
||||||
|
</div>
|
||||||
|
<label string="Select Weekdays" attrs="{'invisible' :[('rrule_type','not in', ['weekly'])]}"/>
|
||||||
|
<group col="2" colspan="1" name="weekdays" attrs="{'invisible' :[('rrule_type','not in', ['weekly'])]}">
|
||||||
|
<field name="mo"/>
|
||||||
|
<field name="tu"/>
|
||||||
|
<field name="we"/>
|
||||||
|
<field name="th"/>
|
||||||
|
<field name="fr"/>
|
||||||
|
<field name="sa"/>
|
||||||
|
<field name="su"/>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<label string="Day of Month"
|
||||||
|
attrs="{'invisible': [('rrule_type','!=','monthly')]}"/>
|
||||||
|
|
||||||
|
<div attrs="{'invisible': [('rrule_type','!=','monthly')]}">
|
||||||
|
<field name="select1"/>
|
||||||
|
<field name="day"
|
||||||
|
attrs="{'required': [('select1','=','date'), ('rrule_type','=','monthly')],
|
||||||
|
'invisible': [('select1','=','day')]}"/>
|
||||||
|
<field name="byday" string="The"
|
||||||
|
attrs="{'required': [('select1','=','day'), ('rrule_type','=','monthly')], 'invisible': [('select1','=','date')]}"/>
|
||||||
|
<field name="week_list" nolabel="1"
|
||||||
|
attrs="{'required': [('select1','=','day'), ('rrule_type','=','monthly')], 'invisible': [('select1','=','date')]}"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="alarm_id" widget="selection" groups="base.group_no_one"/>
|
<field name="alarm_id" widget="selection" groups="base.group_no_one"/>
|
||||||
|
@ -128,44 +168,6 @@
|
||||||
<field name="recurrent_id" invisible="1"/>
|
<field name="recurrent_id" invisible="1"/>
|
||||||
<field name="recurrent_uid" invisible="1"/>
|
<field name="recurrent_uid" invisible="1"/>
|
||||||
</group>
|
</group>
|
||||||
<group attrs="{'invisible': [('recurrency','=',False)]}">
|
|
||||||
<label for="interval"/>
|
|
||||||
<div>
|
|
||||||
<field name="interval" class="oe_inline"/>
|
|
||||||
<field name="rrule_type" class="oe_inline"/>
|
|
||||||
</div>
|
|
||||||
<label string="Until" for="end_type"/>
|
|
||||||
<div>
|
|
||||||
<field name="end_type" class="oe_inline"/>
|
|
||||||
<field name="count" attrs="{'invisible' : [('end_type', '!=', 'count')] }" class="oe_inline"/>
|
|
||||||
<field name="end_date" attrs="{'invisible' : [('end_type', '!=', 'end_date')], 'required': [('end_type', '=', 'end_date')]}" class="oe_inline"/>
|
|
||||||
</div>
|
|
||||||
<label string="Select Weekdays" attrs="{'invisible' :[('rrule_type','not in', ['weekly'])]}"/>
|
|
||||||
<group col="2" colspan="1" name="weekdays" attrs="{'invisible' :[('rrule_type','not in', ['weekly'])]}">
|
|
||||||
<field name="mo" />
|
|
||||||
<field name="tu" />
|
|
||||||
<field name="we" />
|
|
||||||
<field name="th" />
|
|
||||||
<field name="fr" />
|
|
||||||
<field name="sa" />
|
|
||||||
<field name="su" />
|
|
||||||
</group>
|
|
||||||
|
|
||||||
<label string="Day of Month"
|
|
||||||
attrs="{'invisible' : [('rrule_type','!=','monthly')]}"/>
|
|
||||||
|
|
||||||
<div attrs="{'invisible' : [('rrule_type','!=','monthly')]}">
|
|
||||||
<field name="select1" />
|
|
||||||
<field name="day"
|
|
||||||
attrs="{'required' : [('select1','=','date'), ('rrule_type','=','monthly')],
|
|
||||||
'invisible' : [('select1','=','day')]}" />
|
|
||||||
<field name="byday" string="The"
|
|
||||||
attrs="{'required' : [('select1','=','day'), ('rrule_type','=','monthly')], 'invisible' : [('select1','=','date')]}" />
|
|
||||||
<field name="week_list" nolabel="1"
|
|
||||||
attrs="{'required' : [('select1','=','day'), ('rrule_type','=','monthly')], 'invisible' : [('select1','=','date')]}" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</group>
|
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
<!--
|
<!--
|
||||||
|
@ -178,12 +180,11 @@
|
||||||
<tree string="Invitation details" editable="top">
|
<tree string="Invitation details" editable="top">
|
||||||
<field name="partner_id"/>
|
<field name="partner_id"/>
|
||||||
<field name="email" string="Mail To"/>
|
<field name="email" string="Mail To"/>
|
||||||
<field name="state" />
|
<field name="state"/>
|
||||||
<button name="do_tentative"
|
<button name="do_tentative"
|
||||||
states="needs-action,declined,accepted"
|
states="needs-action,declined,accepted"
|
||||||
string="Uncertain" type="object"
|
string="Uncertain" type="object"
|
||||||
icon="terp-crm"
|
icon="terp-crm"/>
|
||||||
/>
|
|
||||||
<button name="do_accept" string="Accept"
|
<button name="do_accept" string="Accept"
|
||||||
states="needs-action,tentative,declined"
|
states="needs-action,tentative,declined"
|
||||||
type="object" icon="gtk-apply"/>
|
type="object" icon="gtk-apply"/>
|
||||||
|
@ -195,21 +196,21 @@
|
||||||
<header>
|
<header>
|
||||||
<button name="do_tentative" type="object"
|
<button name="do_tentative" type="object"
|
||||||
states="needs-action,declined,accepted"
|
states="needs-action,declined,accepted"
|
||||||
string="Uncertain" />
|
string="Uncertain"/>
|
||||||
<button name="do_accept" type="object"
|
<button name="do_accept" type="object"
|
||||||
states="needs-action,tentative,declined"
|
states="needs-action,tentative,declined"
|
||||||
string="Accept" />
|
string="Accept"/>
|
||||||
<button name="do_decline" type="object"
|
<button name="do_decline" type="object"
|
||||||
states="needs-action,tentative,accepted"
|
states="needs-action,tentative,accepted"
|
||||||
string="Decline" />
|
string="Decline"/>
|
||||||
<field name="state" widget="statusbar" statusbar_visible="draft,open,done"/>
|
<field name="state" widget="statusbar" statusbar_visible="draft,open,done"/>
|
||||||
</header>
|
</header>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="email" />
|
<field name="email"/>
|
||||||
<field name="rsvp" />
|
<field name="rsvp"/>
|
||||||
<field name="cutype" />
|
<field name="cutype"/>
|
||||||
<field name="role" />
|
<field name="role"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="partner_id"/>
|
<field name="partner_id"/>
|
||||||
|
@ -237,11 +238,11 @@
|
||||||
<field name="model">crm.meeting</field>
|
<field name="model">crm.meeting</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree string="Meetings" fonts="bold:message_unread==True">
|
<tree string="Meetings" fonts="bold:message_unread==True">
|
||||||
<field name="name" string="Subject" />
|
<field name="name" string="Subject"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<field name="date"/>
|
<field name="date"/>
|
||||||
<field name="state" invisible="True"/>
|
<field name="state" invisible="True"/>
|
||||||
<field name="duration" />
|
<field name="duration"/>
|
||||||
<field name="message_unread" invisible="1"/>
|
<field name="message_unread" invisible="1"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
|
@ -299,7 +300,7 @@
|
||||||
<field name="context">{"calendar_default_user_id": uid}</field>
|
<field name="context">{"calendar_default_user_id": uid}</field>
|
||||||
<field name="help" type="html">
|
<field name="help" type="html">
|
||||||
<p class="oe_view_nocontent_create">
|
<p class="oe_view_nocontent_create">
|
||||||
Click to schedule a new meeting.
|
Click to schedule a new meeting.
|
||||||
</p><p>
|
</p><p>
|
||||||
The calendar is shared between employees and fully integrated with
|
The calendar is shared between employees and fully integrated with
|
||||||
other applications such as the employee holidays or the business
|
other applications such as the employee holidays or the business
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
duration: 2.5
|
duration: 2.5
|
||||||
location: OpenERP S.A.
|
location: OpenERP S.A.
|
||||||
name: Technical Presentation
|
name: Technical Presentation
|
||||||
rrule_type: none
|
-
|
||||||
-
|
|
||||||
Now I will set recurrence for this event to occur monday and friday of week
|
Now I will set recurrence for this event to occur monday and friday of week
|
||||||
-
|
-
|
||||||
!python {model: calendar.event}: |
|
!python {model: calendar.event}: |
|
||||||
|
@ -39,10 +38,9 @@
|
||||||
description: 'All day technical test '
|
description: 'All day technical test '
|
||||||
location: School
|
location: School
|
||||||
name: All day test event
|
name: All day test event
|
||||||
rrule_type: none
|
|
||||||
-
|
-
|
||||||
In order to check reminder I will first create reminder
|
In order to check reminder I will first create reminder
|
||||||
-
|
-
|
||||||
!record {model: res.alarm, id: res_alarm_daybeforeeventstarts0}:
|
!record {model: res.alarm, id: res_alarm_daybeforeeventstarts0}:
|
||||||
name: 1 Day before event starts
|
name: 1 Day before event starts
|
||||||
trigger_duration: 1
|
trigger_duration: 1
|
||||||
|
|
|
@ -140,6 +140,7 @@
|
||||||
<field name="duration" widget="float_time"/>
|
<field name="duration" widget="float_time"/>
|
||||||
<field name="section_id" colspan="1" widget="selection"/>
|
<field name="section_id" colspan="1" widget="selection"/>
|
||||||
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
|
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
|
||||||
|
<field name="email_from" invisible="1"/> <!--not needed because of the chatter, thus invisible, but must be in the view as it's returned by onchange_partner_id()-->
|
||||||
<field name="categ_id" widget="selection"
|
<field name="categ_id" widget="selection"
|
||||||
domain="[('object_id.model', '=', 'crm.phonecall')]"/>
|
domain="[('object_id.model', '=', 'crm.phonecall')]"/>
|
||||||
<field name="partner_mobile"/>
|
<field name="partner_mobile"/>
|
||||||
|
|
|
@ -435,22 +435,6 @@ class event_registration(osv.osv):
|
||||||
'phone':contact_id.phone,
|
'phone':contact_id.phone,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
def onchange_event(self, cr, uid, ids, event_id, context=None):
|
|
||||||
"""This function returns value of Product Name, Unit Price based on Event.
|
|
||||||
"""
|
|
||||||
if context is None:
|
|
||||||
context = {}
|
|
||||||
if not event_id:
|
|
||||||
return {}
|
|
||||||
event_obj = self.pool.get('event.event')
|
|
||||||
data_event = event_obj.browse(cr, uid, event_id, context=context)
|
|
||||||
return {'value':
|
|
||||||
{'event_begin_date': data_event.date_begin,
|
|
||||||
'event_end_date': data_event.date_end,
|
|
||||||
'company_id': data_event.company_id and data_event.company_id.id or False,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def onchange_partner_id(self, cr, uid, ids, part, context=None):
|
def onchange_partner_id(self, cr, uid, ids, part, context=None):
|
||||||
res_obj = self.pool.get('res.partner')
|
res_obj = self.pool.get('res.partner')
|
||||||
data = {}
|
data = {}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
<record id="act_event_list_register_event" model="ir.actions.act_window">
|
<record id="act_event_list_register_event" model="ir.actions.act_window">
|
||||||
<field name="res_model">event.registration</field>
|
<field name="res_model">event.registration</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
|
@ -136,10 +136,22 @@
|
||||||
<field name="type" on_change="onchange_event_type(type,context)"/>
|
<field name="type" on_change="onchange_event_type(type,context)"/>
|
||||||
<field name="date_begin"/>
|
<field name="date_begin"/>
|
||||||
<field name="date_end"/>
|
<field name="date_end"/>
|
||||||
|
<field name="company_id" groups="base.group_multi_company"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</div>
|
</div>
|
||||||
<notebook>
|
<notebook>
|
||||||
|
<page string="Email Configuration" groups="base.group_no_one">
|
||||||
|
<group>
|
||||||
|
<field name="reply_to"/>
|
||||||
|
<group>
|
||||||
|
<field name="email_registration_id"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="email_confirmation_id"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
<page string="Event Description">
|
<page string="Event Description">
|
||||||
<field name="note" colspan="4" nolabel="1"/>
|
<field name="note" colspan="4" nolabel="1"/>
|
||||||
</page>
|
</page>
|
||||||
|
@ -217,7 +229,7 @@
|
||||||
<field name="register_current"/>
|
<field name="register_current"/>
|
||||||
<field name="register_min"/>
|
<field name="register_min"/>
|
||||||
<field name="register_max" invisible="1"/>
|
<field name="register_max" invisible="1"/>
|
||||||
<field name="main_speaker_id" groups="base.extended"/>
|
<field name="main_speaker_id" groups="base.group_no_one"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<field name="state"/>
|
<field name="state"/>
|
||||||
<field name="message_unread" invisible="1"/>
|
<field name="message_unread" invisible="1"/>
|
||||||
|
@ -452,7 +464,7 @@
|
||||||
<sheet string="Registration">
|
<sheet string="Registration">
|
||||||
<label for="event_id" class="oe_edit_only"/>
|
<label for="event_id" class="oe_edit_only"/>
|
||||||
<h1>
|
<h1>
|
||||||
<field name="event_id" on_change="onchange_event(event_id, context)" domain="[('state','in',('draft','confirm'))]"/>
|
<field name="event_id" domain="[('state','in',('draft','confirm'))]"/>
|
||||||
</h1>
|
</h1>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
|
|
|
@ -62,8 +62,8 @@
|
||||||
<newline/>
|
<newline/>
|
||||||
<group expand="1" string="Group By...">
|
<group expand="1" string="Group By...">
|
||||||
<filter string="Participant / Contact" icon="terp-personal" context="{'group_by':'name_registration'}" help="Registration contact"/>
|
<filter string="Participant / Contact" icon="terp-personal" context="{'group_by':'name_registration'}" help="Registration contact"/>
|
||||||
<filter string="Register" icon="terp-personal" context="{'group_by':'user_id_registration'}" help="Registration contact" groups="base.extended"/>
|
<filter string="Register" icon="terp-personal" context="{'group_by':'user_id_registration'}" help="Registration contact" groups="base.group_no_one"/>
|
||||||
<filter string="Speaker" name="speaker" icon="terp-personal+" context="{'group_by': 'speaker_id'}" groups="base.extended"/>
|
<filter string="Speaker" name="speaker" icon="terp-personal+" context="{'group_by': 'speaker_id'}" groups="base.group_no_one"/>
|
||||||
<filter string="Event Responsible" name="user_id" icon="terp-personal" context="{'group_by': 'user_id'}"/>
|
<filter string="Event Responsible" name="user_id" icon="terp-personal" context="{'group_by': 'user_id'}"/>
|
||||||
<filter string="Event" name="event" icon="terp-crm" context="{'group_by':'event_id', 'max_reg_event_visible':0}"/>
|
<filter string="Event" name="event" icon="terp-crm" context="{'group_by':'event_id', 'max_reg_event_visible':0}"/>
|
||||||
<filter string="Event Type" icon="terp-crm" context="{'group_by':'event_type'}"/>
|
<filter string="Event Type" icon="terp-crm" context="{'group_by':'event_type'}"/>
|
||||||
|
|
|
@ -212,13 +212,6 @@ class hr_holidays(osv.osv):
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def onchange_status_id(self, cr, uid, ids, status_id, context=None):
|
|
||||||
double_validation = False
|
|
||||||
if status_id:
|
|
||||||
holiday_status = self.pool.get('hr.holidays.status').browse(cr, uid, status_id, context=context)
|
|
||||||
double_validation = holiday_status.double_validation
|
|
||||||
return {'value': {'double_validation': double_validation}}
|
|
||||||
|
|
||||||
def set_to_draft(self, cr, uid, ids, context=None):
|
def set_to_draft(self, cr, uid, ids, context=None):
|
||||||
self.write(cr, uid, ids, {
|
self.write(cr, uid, ids, {
|
||||||
'state': 'draft',
|
'state': 'draft',
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="name" attrs="{'readonly':[('state','!=','draft'),('state','!=','confirm')]}"/>
|
<field name="name" attrs="{'readonly':[('state','!=','draft'),('state','!=','confirm')]}"/>
|
||||||
<field name="holiday_status_id" on_change="onchange_status_id(holiday_status_id)" context="{'employee_id':employee_id}"/>
|
<field name="holiday_status_id" context="{'employee_id':employee_id}"/>
|
||||||
<label for="number_of_days_temp" string="Duration"/>
|
<label for="number_of_days_temp" string="Duration"/>
|
||||||
<div>
|
<div>
|
||||||
<group col="3">
|
<group col="3">
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="name" required="1" attrs="{'readonly':[('state','!=','draft'),('state','!=','confirm')]}"/>
|
<field name="name" required="1" attrs="{'readonly':[('state','!=','draft'),('state','!=','confirm')]}"/>
|
||||||
<field name="holiday_status_id" on_change="onchange_status_id(holiday_status_id)" context="{'employee_id':employee_id}"/>
|
<field name="holiday_status_id" context="{'employee_id':employee_id}"/>
|
||||||
<field name="number_of_days_temp"/>
|
<field name="number_of_days_temp"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
|
|
|
@ -33,6 +33,7 @@ import report
|
||||||
import wizard
|
import wizard
|
||||||
import res_config
|
import res_config
|
||||||
import mail_group_menu
|
import mail_group_menu
|
||||||
|
import update
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,20 @@
|
||||||
<field eval="'()'" name="args"/>
|
<field eval="'()'" name="args"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record id="ir_cron_module_update_notification" model="ir.cron">
|
||||||
|
<field name="name">Update Notification</field>
|
||||||
|
<field eval="True" name="active" />
|
||||||
|
<field name="user_id" ref="base.user_root" />
|
||||||
|
<field name="interval_number">1</field>
|
||||||
|
<field name="interval_type">weeks</field>
|
||||||
|
<field name="numbercall">-1</field>
|
||||||
|
<field eval="False" name="doall" />
|
||||||
|
<field eval="'ir.module.module'" name="model" />
|
||||||
|
<field eval="'update_notification'" name="function" />
|
||||||
|
<field eval="'(None,)'" name="args" />
|
||||||
|
<field name="priority">1000</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
<record id="mt_comment" model="mail.message.subtype">
|
<record id="mt_comment" model="mail.message.subtype">
|
||||||
<field name="name">comment</field>
|
<field name="name">comment</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
|
@ -504,7 +504,7 @@ class mail_message(osv.Model):
|
||||||
if not values.get('message_id') and values.get('res_id') and values.get('model'):
|
if not values.get('message_id') and values.get('res_id') and values.get('model'):
|
||||||
values['message_id'] = tools.generate_tracking_message_id('%(model)s-%(res_id)s' % values)
|
values['message_id'] = tools.generate_tracking_message_id('%(model)s-%(res_id)s' % values)
|
||||||
newid = super(mail_message, self).create(cr, uid, values, context)
|
newid = super(mail_message, self).create(cr, uid, values, context)
|
||||||
self._notify(cr, 1, newid, context=context)
|
self._notify(cr, SUPERUSER_ID, newid, context=context)
|
||||||
return newid
|
return newid
|
||||||
|
|
||||||
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
import urllib
|
||||||
|
import urllib2
|
||||||
|
|
||||||
|
import pooler
|
||||||
|
import release
|
||||||
|
from osv import osv, fields
|
||||||
|
from tools.translate import _
|
||||||
|
from tools.safe_eval import safe_eval
|
||||||
|
from tools.config import config
|
||||||
|
from tools import misc
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
"""
|
||||||
|
Time interval that will be used to determine up to which date we will
|
||||||
|
check the logs to see if a message we just received was already logged.
|
||||||
|
@type: datetime.timedelta
|
||||||
|
"""
|
||||||
|
_PREVIOUS_LOG_CHECK = datetime.timedelta(days=365)
|
||||||
|
|
||||||
|
def get_sys_logs(cr, uid):
|
||||||
|
"""
|
||||||
|
Utility method to send a publisher warranty get logs messages.
|
||||||
|
"""
|
||||||
|
pool = pooler.get_pool(cr.dbname)
|
||||||
|
|
||||||
|
dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
|
||||||
|
db_create_date = pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
|
||||||
|
limit_date = datetime.datetime.now()
|
||||||
|
limit_date = limit_date - datetime.timedelta(15)
|
||||||
|
limit_date_str = limit_date.strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
|
nbr_users = pool.get("res.users").search(cr, uid, [], count=True)
|
||||||
|
nbr_active_users = pool.get("res.users").search(cr, uid, [("date", ">=", limit_date_str)], count=True)
|
||||||
|
nbr_share_users = False
|
||||||
|
nbr_active_share_users = False
|
||||||
|
if "share" in pool.get("res.users")._all_columns:
|
||||||
|
nbr_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True)], count=True)
|
||||||
|
nbr_active_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True), ("date", ">=", limit_date_str)], count=True)
|
||||||
|
user = pool.get("res.users").browse(cr, uid, uid)
|
||||||
|
msg = {
|
||||||
|
"dbuuid": dbuuid,
|
||||||
|
"nbr_users": nbr_users,
|
||||||
|
"nbr_active_users": nbr_active_users,
|
||||||
|
"nbr_share_users": nbr_share_users,
|
||||||
|
"nbr_active_share_users": nbr_active_share_users,
|
||||||
|
"dbname": cr.dbname,
|
||||||
|
"db_create_date": db_create_date,
|
||||||
|
"version": release.version,
|
||||||
|
"language": user.lang,
|
||||||
|
}
|
||||||
|
msg.update(pool.get("res.company").read(cr,uid,[1],["name","email","phone"])[0])
|
||||||
|
|
||||||
|
add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
|
||||||
|
arguments = {'arg0': msg, "action": "update",}
|
||||||
|
arguments_raw = urllib.urlencode(arguments)
|
||||||
|
|
||||||
|
url = config.get("publisher_warranty_url")
|
||||||
|
uo = urllib2.urlopen(url, arguments_raw, **add_arg)
|
||||||
|
result = {}
|
||||||
|
try:
|
||||||
|
submit_result = uo.read()
|
||||||
|
result = safe_eval(submit_result)
|
||||||
|
finally:
|
||||||
|
uo.close()
|
||||||
|
return result
|
||||||
|
|
||||||
|
class publisher_warranty_contract(osv.osv):
|
||||||
|
_name = "publisher_warranty.contract"
|
||||||
|
|
||||||
|
def update_notification(self, cr, uid, ids, cron_mode=True, context=None):
|
||||||
|
"""
|
||||||
|
Send a message to OpenERP's publisher warranty server to check the
|
||||||
|
validity of the contracts, get notifications, etc...
|
||||||
|
|
||||||
|
@param cron_mode: If true, catch all exceptions (appropriate for usage in a cron).
|
||||||
|
@type cron_mode: boolean
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
result = get_sys_logs(cr, uid)
|
||||||
|
except Exception:
|
||||||
|
if cron_mode: # we don't want to see any stack trace in cron
|
||||||
|
return False
|
||||||
|
_logger.debug("Exception while sending a get logs messages", exc_info=1)
|
||||||
|
raise osv.except_osv(_("Error"), _("Error during communication with the publisher warranty server."))
|
||||||
|
limit_date = (datetime.datetime.now() - _PREVIOUS_LOG_CHECK).strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
|
# old behavior based on res.log; now on mail.message, that is not necessarily installed
|
||||||
|
proxy = self.pool.get('mail.message')
|
||||||
|
|
||||||
|
model, res_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'group_all_employees')
|
||||||
|
|
||||||
|
for message in result["messages"]:
|
||||||
|
values = {
|
||||||
|
'body' : message,
|
||||||
|
'model' : 'mail.group',
|
||||||
|
'res_id' : res_id,
|
||||||
|
'user_id' : False,
|
||||||
|
}
|
||||||
|
proxy.create(cr, uid, values, context=context)
|
||||||
|
except Exception:
|
||||||
|
if cron_mode:
|
||||||
|
return False # we don't want to see any stack trace in cron
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
return True
|
||||||
|
|
||||||
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -121,7 +121,7 @@ class mail_compose_message(osv.TransientModel):
|
||||||
'partner_ids': lambda self, cr, uid, ctx={}: [],
|
'partner_ids': lambda self, cr, uid, ctx={}: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
def notify(self, cr, uid, newid, context=None):
|
def _notify(self, cr, uid, newid, context=None):
|
||||||
""" Override specific notify method of mail.message, because we do
|
""" Override specific notify method of mail.message, because we do
|
||||||
not want that feature in the wizard. """
|
not want that feature in the wizard. """
|
||||||
return
|
return
|
||||||
|
|
|
@ -910,12 +910,11 @@ class mrp_production(osv.osv):
|
||||||
# Internal shipment is created for Stockable and Consumer Products
|
# Internal shipment is created for Stockable and Consumer Products
|
||||||
if production_line.product_id.type not in ('product', 'consu'):
|
if production_line.product_id.type not in ('product', 'consu'):
|
||||||
return False
|
return False
|
||||||
move_name = _('PROD: %s') % production.name
|
|
||||||
source_location_id = production.location_src_id.id
|
source_location_id = production.location_src_id.id
|
||||||
if not destination_location_id:
|
if not destination_location_id:
|
||||||
destination_location_id = source_location_id
|
destination_location_id = source_location_id
|
||||||
return stock_move.create(cr, uid, {
|
return stock_move.create(cr, uid, {
|
||||||
'name': move_name,
|
'name': production.name,
|
||||||
'picking_id': shipment_id,
|
'picking_id': shipment_id,
|
||||||
'product_id': production_line.product_id.id,
|
'product_id': production_line.product_id.id,
|
||||||
'product_qty': production_line.product_qty,
|
'product_qty': production_line.product_qty,
|
||||||
|
@ -965,9 +964,8 @@ class mrp_production(osv.osv):
|
||||||
stock_move = self.pool.get('stock.move')
|
stock_move = self.pool.get('stock.move')
|
||||||
source_location_id = production.product_id.product_tmpl_id.property_stock_production.id
|
source_location_id = production.product_id.product_tmpl_id.property_stock_production.id
|
||||||
destination_location_id = production.location_dest_id.id
|
destination_location_id = production.location_dest_id.id
|
||||||
move_name = _('PROD: %s') + production.name
|
|
||||||
data = {
|
data = {
|
||||||
'name': move_name,
|
'name': production.name,
|
||||||
'date': production.date_planned,
|
'date': production.date_planned,
|
||||||
'product_id': production.product_id.id,
|
'product_id': production.product_id.id,
|
||||||
'product_qty': production.product_qty,
|
'product_qty': production.product_qty,
|
||||||
|
@ -990,12 +988,11 @@ class mrp_production(osv.osv):
|
||||||
# Internal shipment is created for Stockable and Consumer Products
|
# Internal shipment is created for Stockable and Consumer Products
|
||||||
if production_line.product_id.type not in ('product', 'consu'):
|
if production_line.product_id.type not in ('product', 'consu'):
|
||||||
return False
|
return False
|
||||||
move_name = _('PROD: %s') % production.name
|
|
||||||
destination_location_id = production.product_id.product_tmpl_id.property_stock_production.id
|
destination_location_id = production.product_id.product_tmpl_id.property_stock_production.id
|
||||||
if not source_location_id:
|
if not source_location_id:
|
||||||
source_location_id = production.location_src_id.id
|
source_location_id = production.location_src_id.id
|
||||||
move_id = stock_move.create(cr, uid, {
|
move_id = stock_move.create(cr, uid, {
|
||||||
'name': move_name,
|
'name': production.name,
|
||||||
'date': production.date_planned,
|
'date': production.date_planned,
|
||||||
'product_id': production_line.product_id.id,
|
'product_id': production_line.product_id.id,
|
||||||
'product_qty': production_line.product_qty,
|
'product_qty': production_line.product_qty,
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
<!-- title -->
|
<!-- title -->
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="oe_clear"></div>
|
||||||
<field name="tag_ids"/>
|
<field name="tag_ids"/>
|
||||||
<div class="oe_right">
|
<div class="oe_right">
|
||||||
<t t-foreach="record.message_follower_ids.raw_value" t-as="follower">
|
<t t-foreach="record.message_follower_ids.raw_value" t-as="follower">
|
||||||
|
|
|
@ -348,6 +348,29 @@ class pos_session(osv.osv):
|
||||||
statement.unlink(context=context)
|
statement.unlink(context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def open_cb(self, cr, uid, ids, context=None):
|
||||||
|
"""
|
||||||
|
call the Point Of Sale interface and set the pos.session to 'opened' (in progress)
|
||||||
|
"""
|
||||||
|
if context is None:
|
||||||
|
context = dict()
|
||||||
|
|
||||||
|
if isinstance(ids, (int, long)):
|
||||||
|
ids = [ids]
|
||||||
|
|
||||||
|
this_record = self.browse(cr, uid, ids[0], context=context)
|
||||||
|
this_record._workflow_signal('open')
|
||||||
|
|
||||||
|
context.update(active_id=this_record.id)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'type' : 'ir.actions.client',
|
||||||
|
'name' : _('Start Point Of Sale'),
|
||||||
|
'tag' : 'pos.ui',
|
||||||
|
'context' : context,
|
||||||
|
}
|
||||||
|
|
||||||
def wkf_action_open(self, cr, uid, ids, context=None):
|
def wkf_action_open(self, cr, uid, ids, context=None):
|
||||||
# second browse because we need to refetch the data from the DB for cash_register_id
|
# second browse because we need to refetch the data from the DB for cash_register_id
|
||||||
for record in self.browse(cr, uid, ids, context=context):
|
for record in self.browse(cr, uid, ids, context=context):
|
||||||
|
@ -439,10 +462,10 @@ class pos_session(osv.osv):
|
||||||
context = {}
|
context = {}
|
||||||
if not ids:
|
if not ids:
|
||||||
return {}
|
return {}
|
||||||
context.update({'session_id' : ids[0]})
|
context.update({'active_id': ids[0]})
|
||||||
return {
|
return {
|
||||||
'type' : 'ir.actions.client',
|
'type' : 'ir.actions.client',
|
||||||
'name' : 'Start Point Of Sale',
|
'name' : _('Start Point Of Sale'),
|
||||||
'tag' : 'pos.ui',
|
'tag' : 'pos.ui',
|
||||||
'context' : context,
|
'context' : context,
|
||||||
}
|
}
|
||||||
|
|
|
@ -862,7 +862,7 @@
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Point of Sale Session" version="7.0">
|
<form string="Point of Sale Session" version="7.0">
|
||||||
<header>
|
<header>
|
||||||
<button name="open" type="workflow" string="Validate & Open Session" states="opening_control" class="oe_highlight"/>
|
<button name="open_cb" type="object" string="Validate & Open Session" states="opening_control" class="oe_highlight"/>
|
||||||
<button name="open_frontend_cb" type="object" string="Continue Selling" states="opened"
|
<button name="open_frontend_cb" type="object" string="Continue Selling" states="opened"
|
||||||
class="oe_highlight"/>
|
class="oe_highlight"/>
|
||||||
<button name="cashbox_control" type="workflow" string="End of Session"
|
<button name="cashbox_control" type="workflow" string="End of Session"
|
||||||
|
@ -890,15 +890,14 @@
|
||||||
<field name="cash_control" invisible="1" />
|
<field name="cash_control" invisible="1" />
|
||||||
<group>
|
<group>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<field name="config_id" attrs="{'invisible' : [('config_id', '<>', False)]}"/>
|
<field name="config_id" attrs="{'invisible' : [('config_id', '!=', False)]}"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="start_at" attrs="{'invisible' : [('state', '=', 'opening_control')]}"/>
|
<field name="start_at" attrs="{'invisible' : [('state', '=', 'opening_control')]}"/>
|
||||||
<field name="stop_at" attrs="{'invisible' : [('state', '!=', 'closed')]}"/>
|
<field name="stop_at" attrs="{'invisible' : [('state', '!=', 'closed')]}"/>
|
||||||
</group>
|
</group>
|
||||||
<newline/>
|
<newline/>
|
||||||
<group string="Opening Cash Control" attrs="{'invisible' : [ '&' ,'!', '&', ('state', '=', 'opening_control'), ('cash_control', '=', True), ('state', '!=',
|
<group string="Opening Cash Control" attrs="{'invisible' : [('cash_control', '=', False)]}">
|
||||||
'closed')] }" >
|
|
||||||
<field name="opening_details_ids" nolabel="1" colspan="2" attrs="{'readonly' : [('state', 'not in', ('opening_control',))]}">
|
<field name="opening_details_ids" nolabel="1" colspan="2" attrs="{'readonly' : [('state', 'not in', ('opening_control',))]}">
|
||||||
<tree string="Opening Cashbox Lines" editable="bottom">
|
<tree string="Opening Cashbox Lines" editable="bottom">
|
||||||
<field name="pieces" readonly="1" />
|
<field name="pieces" readonly="1" />
|
||||||
|
@ -907,8 +906,7 @@
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</group>
|
</group>
|
||||||
<group string="Closing Cash Control" attrs="{'invisible' : [ '&' ,'!', '&', ('state', '=', 'closing_control'), ('cash_control', '=', True), ('state', '!=',
|
<group string="Closing Cash Control" attrs="{'invisible': ['|', ('cash_control', '=', False), ('state', '=', 'opening_control')]}">
|
||||||
'closed')] }" >
|
|
||||||
<field name="details_ids" nolabel="1" colspan="2">
|
<field name="details_ids" nolabel="1" colspan="2">
|
||||||
<tree string="Cashbox Lines" editable="bottom">
|
<tree string="Cashbox Lines" editable="bottom">
|
||||||
<field name="pieces" readonly="1" />
|
<field name="pieces" readonly="1" />
|
||||||
|
@ -918,7 +916,7 @@
|
||||||
</field>
|
</field>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<div attrs="{'invisible' : [('state', '!=', 'closed')]}">
|
<div attrs="{'invisible' : [('cash_control', '=', False)]}">
|
||||||
<group class="oe_subtotal_footer oe_right">
|
<group class="oe_subtotal_footer oe_right">
|
||||||
<field name="cash_register_balance_start" readonly="1" string="Opening Balance" class="oe_subtotal_footer_separator"/>
|
<field name="cash_register_balance_start" readonly="1" string="Opening Balance" class="oe_subtotal_footer_separator"/>
|
||||||
<field name="cash_register_total_entry_encoding" attrs="{'invisible' : [('state', '=', 'opening_control')]}" string="+ Transactions"/>
|
<field name="cash_register_total_entry_encoding" attrs="{'invisible' : [('state', '=', 'opening_control')]}" string="+ Transactions"/>
|
||||||
|
@ -935,7 +933,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<group class="oe_subtotal_footer oe_right" attrs="{'invisible': [('state', '!=', 'closed')]}">
|
<group class="oe_subtotal_footer oe_right" attrs="{'invisible': ['|', ('cash_control', '=', False), ('state', '=', 'opening_control')]}">
|
||||||
<field name="cash_register_balance_end_real" class="oe_subtotal_footer_separator"/>
|
<field name="cash_register_balance_end_real" class="oe_subtotal_footer_separator"/>
|
||||||
<field name="cash_register_difference" class="oe_subtotal_footer_separator"/>
|
<field name="cash_register_difference" class="oe_subtotal_footer_separator"/>
|
||||||
</group>
|
</group>
|
||||||
|
|
|
@ -6,7 +6,6 @@ instance.web.ViewManager.include({
|
||||||
var self = this;
|
var self = this;
|
||||||
var _super = this._super();
|
var _super = this._super();
|
||||||
this.process_help = this.action ? this.action.help : '';
|
this.process_help = this.action ? this.action.help : '';
|
||||||
self.process_help = $(this.process_help).text();
|
|
||||||
if(this.action) {
|
if(this.action) {
|
||||||
this.process_model = this.action.res_model;
|
this.process_model = this.action.res_model;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<record id="product_uom_dozen" model="product.uom">
|
<record id="product_uom_dozen" model="product.uom">
|
||||||
<field name="category_id" ref="product.product_uom_categ_unit"/>
|
<field name="category_id" ref="product.product_uom_categ_unit"/>
|
||||||
<field name="name">Dozen</field>
|
<field name="name">Dozen</field>
|
||||||
<field name="factor" eval="0.083"/>
|
<field name="factor_inv" eval="12"/>
|
||||||
<field name="uom_type">bigger</field>
|
<field name="uom_type">bigger</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="product_uom_kgm" model="product.uom">
|
<record id="product_uom_kgm" model="product.uom">
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
<!-- 'tonne' is the most common spelling in english-speaking countries,
|
<!-- 'tonne' is the most common spelling in english-speaking countries,
|
||||||
the alternative is 'metric ton' in the US, abbreviated as 'mt' -->
|
the alternative is 'metric ton' in the US, abbreviated as 'mt' -->
|
||||||
<field name="name">t</field>
|
<field name="name">t</field>
|
||||||
<field name="factor" eval="0.001"/>
|
<field name="factor_inv" eval="1000"/>
|
||||||
<field name="uom_type">bigger</field>
|
<field name="uom_type">bigger</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="product_uom_meter" model="product.uom">
|
<record id="product_uom_meter" model="product.uom">
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
<record id="product_uom_km" model="product.uom">
|
<record id="product_uom_km" model="product.uom">
|
||||||
<field name="category_id" ref="uom_categ_length"/>
|
<field name="category_id" ref="uom_categ_length"/>
|
||||||
<field name="name">km</field>
|
<field name="name">km</field>
|
||||||
<field name="factor" eval="0.001"/>
|
<field name="factor_inv" eval="1000"/>
|
||||||
<field name="uom_type">bigger</field>
|
<field name="uom_type">bigger</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="product_uom_cm" model="product.uom">
|
<record id="product_uom_cm" model="product.uom">
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
</record>
|
</record>
|
||||||
<record id="project_tt_deployment" model="project.task.type">
|
<record id="project_tt_deployment" model="project.task.type">
|
||||||
<field name="sequence">7</field>
|
<field name="sequence">7</field>
|
||||||
<field name="name">Deployment</field>
|
<field name="name">Done</field>
|
||||||
<field name="state">done</field>
|
<field name="state">done</field>
|
||||||
<field name="case_default" eval="True"/>
|
<field name="case_default" eval="True"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
|
@ -279,7 +279,7 @@ class project_issue(base_stage, osv.osv):
|
||||||
'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c),
|
'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c),
|
||||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
|
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
|
||||||
'priority': crm.AVAILABLE_PRIORITIES[2][0],
|
'priority': crm.AVAILABLE_PRIORITIES[2][0],
|
||||||
}
|
}
|
||||||
|
|
||||||
_group_by_full = {
|
_group_by_full = {
|
||||||
'stage_id': _read_group_stage_ids
|
'stage_id': _read_group_stage_ids
|
||||||
|
|
|
@ -28,6 +28,7 @@ from tools.translate import _
|
||||||
|
|
||||||
class project_project(osv.osv):
|
class project_project(osv.osv):
|
||||||
_inherit = 'project.project'
|
_inherit = 'project.project'
|
||||||
|
|
||||||
def onchange_partner_id(self, cr, uid, ids, part=False, context=None):
|
def onchange_partner_id(self, cr, uid, ids, part=False, context=None):
|
||||||
res = super(project_project, self).onchange_partner_id(cr, uid, ids, part, context)
|
res = super(project_project, self).onchange_partner_id(cr, uid, ids, part, context)
|
||||||
if part and res and ('value' in res):
|
if part and res and ('value' in res):
|
||||||
|
@ -68,6 +69,7 @@ class project_project(osv.osv):
|
||||||
'nodestroy': True,
|
'nodestroy': True,
|
||||||
'help': help
|
'help': help
|
||||||
}
|
}
|
||||||
|
|
||||||
project_project()
|
project_project()
|
||||||
|
|
||||||
class project_work(osv.osv):
|
class project_work(osv.osv):
|
||||||
|
@ -81,7 +83,7 @@ class project_work(osv.osv):
|
||||||
user_name = self.pool.get('res.users').read(cr, uid, [user_id], ['name'])[0]['name']
|
user_name = self.pool.get('res.users').read(cr, uid, [user_id], ['name'])[0]['name']
|
||||||
raise osv.except_osv(_('Bad Configuration !'),
|
raise osv.except_osv(_('Bad Configuration !'),
|
||||||
_('Please define employee for user "%s". You must create one.')% (user_name,))
|
_('Please define employee for user "%s". You must create one.')% (user_name,))
|
||||||
emp = self.pool.get('hr.employee').browse(cr, uid, emp_id[0])
|
emp = emp_obj.browse(cr, uid, emp_id[0])
|
||||||
if not emp.product_id:
|
if not emp.product_id:
|
||||||
raise osv.except_osv(_('Bad Configuration !'),
|
raise osv.except_osv(_('Bad Configuration !'),
|
||||||
_('Please define product on the related employee.\nFill in the timesheet tab of the employee form.'))
|
_('Please define product on the related employee.\nFill in the timesheet tab of the employee form.'))
|
||||||
|
@ -90,44 +92,44 @@ class project_work(osv.osv):
|
||||||
raise osv.except_osv(_('Bad Configuration !'),
|
raise osv.except_osv(_('Bad Configuration !'),
|
||||||
_('Please define journal on the related employee.\nFill in the timesheet tab of the employee form.'))
|
_('Please define journal on the related employee.\nFill in the timesheet tab of the employee form.'))
|
||||||
|
|
||||||
a = emp.product_id.product_tmpl_id.property_account_expense.id
|
acc_id = emp.product_id.product_tmpl_id.property_account_expense.id
|
||||||
if not a:
|
if not acc_id:
|
||||||
a = emp.product_id.categ_id.property_account_expense_categ.id
|
acc_id = emp.product_id.categ_id.property_account_expense_categ.id
|
||||||
if not a:
|
if not acc_id:
|
||||||
raise osv.except_osv(_('Bad Configuration !'),
|
raise osv.except_osv(_('Bad Configuration !'),
|
||||||
_('Please define product and product category property account on the related employee.\nFill in the timesheet tab of the employee form.'))
|
_('Please define product and product category property account on the related employee.\nFill in the timesheet tab of the employee form.'))
|
||||||
|
|
||||||
res['product_id'] = emp.product_id.id
|
res['product_id'] = emp.product_id.id
|
||||||
res['journal_id'] = emp.journal_id.id
|
res['journal_id'] = emp.journal_id.id
|
||||||
res['general_account_id'] = a
|
res['general_account_id'] = acc_id
|
||||||
res['product_uom_id'] = emp.product_id.uom_id.id
|
res['product_uom_id'] = emp.product_id.uom_id.id
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def create(self, cr, uid, vals, *args, **kwargs):
|
def create(self, cr, uid, vals, *args, **kwargs):
|
||||||
obj_timesheet = self.pool.get('hr.analytic.timesheet')
|
timesheet_obj = self.pool.get('hr.analytic.timesheet')
|
||||||
project_obj = self.pool.get('project.project')
|
|
||||||
task_obj = self.pool.get('project.task')
|
task_obj = self.pool.get('project.task')
|
||||||
uom_obj = self.pool.get('product.uom')
|
uom_obj = self.pool.get('product.uom')
|
||||||
|
|
||||||
vals_line = {}
|
vals_line = {}
|
||||||
context = kwargs.get('context', {})
|
context = kwargs.get('context', {})
|
||||||
if not context.get('no_analytic_entry',False):
|
if not context.get('no_analytic_entry',False):
|
||||||
obj_task = task_obj.browse(cr, uid, vals['task_id'])
|
task_obj = task_obj.browse(cr, uid, vals['task_id'])
|
||||||
result = self.get_user_related_details(cr, uid, vals.get('user_id', uid))
|
result = self.get_user_related_details(cr, uid, vals.get('user_id', uid))
|
||||||
vals_line['name'] = '%s: %s' % (tools.ustr(obj_task.name), tools.ustr(vals['name']) or '/')
|
vals_line['name'] = '%s: %s' % (tools.ustr(task_obj.name), tools.ustr(vals['name']) or '/')
|
||||||
vals_line['user_id'] = vals['user_id']
|
vals_line['user_id'] = vals['user_id']
|
||||||
vals_line['product_id'] = result['product_id']
|
vals_line['product_id'] = result['product_id']
|
||||||
vals_line['date'] = vals['date'][:10]
|
vals_line['date'] = vals['date'][:10]
|
||||||
|
|
||||||
#calculate quantity based on employee's product's uom
|
# Calculate quantity based on employee's product's uom
|
||||||
vals_line['unit_amount'] = vals['hours']
|
vals_line['unit_amount'] = vals['hours']
|
||||||
|
|
||||||
default_uom = self.pool.get('res.users').browse(cr, uid, uid).company_id.project_time_mode_id.id
|
default_uom = self.pool.get('res.users').browse(cr, uid, uid).company_id.project_time_mode_id.id
|
||||||
if result['product_uom_id'] != default_uom:
|
if result['product_uom_id'] != default_uom:
|
||||||
vals_line['unit_amount'] = uom_obj._compute_qty(cr, uid, default_uom, vals['hours'], result['product_uom_id'])
|
vals_line['unit_amount'] = uom_obj._compute_qty(cr, uid, default_uom, vals['hours'], result['product_uom_id'])
|
||||||
acc_id = obj_task.project_id and obj_task.project_id.analytic_account_id.id or False
|
acc_id = task_obj.project_id and task_obj.project_id.analytic_account_id.id or False
|
||||||
if acc_id:
|
if acc_id:
|
||||||
vals_line['account_id'] = acc_id
|
vals_line['account_id'] = acc_id
|
||||||
res = obj_timesheet.on_change_account_id(cr, uid, False, acc_id)
|
res = timesheet_obj.on_change_account_id(cr, uid, False, acc_id)
|
||||||
if res.get('value'):
|
if res.get('value'):
|
||||||
vals_line.update(res['value'])
|
vals_line.update(res['value'])
|
||||||
vals_line['general_account_id'] = result['general_account_id']
|
vals_line['general_account_id'] = result['general_account_id']
|
||||||
|
@ -137,27 +139,29 @@ class project_work(osv.osv):
|
||||||
amount = vals_line['unit_amount']
|
amount = vals_line['unit_amount']
|
||||||
prod_id = vals_line['product_id']
|
prod_id = vals_line['product_id']
|
||||||
unit = False
|
unit = False
|
||||||
timeline_id = obj_timesheet.create(cr, uid, vals=vals_line, context=context)
|
timeline_id = timesheet_obj.create(cr, uid, vals=vals_line, context=context)
|
||||||
|
|
||||||
# Compute based on pricetype
|
# Compute based on pricetype
|
||||||
amount_unit = obj_timesheet.on_change_unit_amount(cr, uid, timeline_id,
|
amount_unit = timesheet_obj.on_change_unit_amount(cr, uid, timeline_id,
|
||||||
prod_id, amount, False, unit, vals_line['journal_id'], context=context)
|
prod_id, amount, False, unit, vals_line['journal_id'], context=context)
|
||||||
if amount_unit and 'amount' in amount_unit.get('value',{}):
|
if amount_unit and 'amount' in amount_unit.get('value',{}):
|
||||||
updv = { 'amount': amount_unit['value']['amount'] }
|
updv = { 'amount': amount_unit['value']['amount'] }
|
||||||
obj_timesheet.write(cr, uid, [timeline_id], updv, context=context)
|
timesheet_obj.write(cr, uid, [timeline_id], updv, context=context)
|
||||||
vals['hr_analytic_timesheet_id'] = timeline_id
|
vals['hr_analytic_timesheet_id'] = timeline_id
|
||||||
return super(project_work,self).create(cr, uid, vals, *args, **kwargs)
|
return super(project_work,self).create(cr, uid, vals, *args, **kwargs)
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, context=None):
|
def write(self, cr, uid, ids, vals, context=None):
|
||||||
|
"""
|
||||||
|
When a project task work gets updated, handle its hr analytic timesheet.
|
||||||
|
"""
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
timesheet_obj = self.pool.get('hr.analytic.timesheet')
|
timesheet_obj = self.pool.get('hr.analytic.timesheet')
|
||||||
project_obj = self.pool.get('project.project')
|
|
||||||
uom_obj = self.pool.get('product.uom')
|
uom_obj = self.pool.get('product.uom')
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
if isinstance(ids, (long, int)):
|
if isinstance(ids, (long, int)):
|
||||||
ids = [ids,]
|
ids = [ids]
|
||||||
|
|
||||||
for task in self.browse(cr, uid, ids, context=context):
|
for task in self.browse(cr, uid, ids, context=context):
|
||||||
line_id = task.hr_analytic_timesheet_id
|
line_id = task.hr_analytic_timesheet_id
|
||||||
|
@ -165,25 +169,28 @@ class project_work(osv.osv):
|
||||||
# if a record is deleted from timesheet, the line_id will become
|
# if a record is deleted from timesheet, the line_id will become
|
||||||
# null because of the foreign key on-delete=set null
|
# null because of the foreign key on-delete=set null
|
||||||
continue
|
continue
|
||||||
|
|
||||||
vals_line = {}
|
vals_line = {}
|
||||||
if 'name' in vals:
|
if 'name' in vals:
|
||||||
vals_line['name'] = '%s: %s' % (tools.ustr(task.task_id.name), tools.ustr(vals['name']) or '/')
|
vals_line['name'] = '%s: %s' % (tools.ustr(task.task_id.name), tools.ustr(vals['name']) or '/')
|
||||||
if 'user_id' in vals:
|
if 'user_id' in vals:
|
||||||
vals_line['user_id'] = vals['user_id']
|
vals_line['user_id'] = vals['user_id']
|
||||||
result = self.get_user_related_details(cr, uid, vals.get('user_id', task.user_id.id))
|
|
||||||
for fld in ('product_id', 'general_account_id', 'journal_id', 'product_uom_id'):
|
|
||||||
if result.get(fld, False):
|
|
||||||
vals_line[fld] = result[fld]
|
|
||||||
|
|
||||||
if 'date' in vals:
|
if 'date' in vals:
|
||||||
vals_line['date'] = vals['date'][:10]
|
vals_line['date'] = vals['date'][:10]
|
||||||
if 'hours' in vals:
|
if 'hours' in vals:
|
||||||
default_uom = self.pool.get('res.users').browse(cr, uid, uid).company_id.project_time_mode_id.id
|
|
||||||
vals_line['unit_amount'] = vals['hours']
|
vals_line['unit_amount'] = vals['hours']
|
||||||
prod_id = vals_line.get('product_id', line_id.product_id.id) # False may be set
|
prod_id = vals_line.get('product_id', line_id.product_id.id) # False may be set
|
||||||
|
|
||||||
if result.get('product_uom_id',False) and (not result['product_uom_id'] == default_uom):
|
# Put user related details in analytic timesheet values
|
||||||
vals_line['unit_amount'] = uom_obj._compute_qty(cr, uid, default_uom, vals['hours'], result['product_uom_id'])
|
details = self.get_user_related_details(cr, uid, vals.get('user_id', task.user_id.id))
|
||||||
|
for field in ('product_id', 'general_account_id', 'journal_id', 'product_uom_id'):
|
||||||
|
if details.get(field, False):
|
||||||
|
vals_line[field] = details[field]
|
||||||
|
|
||||||
|
# Check if user's default UOM differs from product's UOM
|
||||||
|
user_default_uom_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.project_time_mode_id.id
|
||||||
|
if details.get('product_uom_id', False) and details['product_uom_id'] != user_default_uom_id:
|
||||||
|
vals_line['unit_amount'] = uom_obj._compute_qty(cr, uid, user_default_uom_id, vals['hours'], details['product_uom_id'])
|
||||||
|
|
||||||
# Compute based on pricetype
|
# Compute based on pricetype
|
||||||
amount_unit = timesheet_obj.on_change_unit_amount(cr, uid, line_id.id,
|
amount_unit = timesheet_obj.on_change_unit_amount(cr, uid, line_id.id,
|
||||||
|
@ -203,7 +210,7 @@ class project_work(osv.osv):
|
||||||
for task in self.browse(cr, uid, ids):
|
for task in self.browse(cr, uid, ids):
|
||||||
if task.hr_analytic_timesheet_id:
|
if task.hr_analytic_timesheet_id:
|
||||||
hat_ids.append(task.hr_analytic_timesheet_id.id)
|
hat_ids.append(task.hr_analytic_timesheet_id.id)
|
||||||
# delete entry from timesheet too while deleting entry to task.
|
# Delete entry from timesheet too while deleting entry to task.
|
||||||
if hat_ids:
|
if hat_ids:
|
||||||
hat_obj.unlink(cr, uid, hat_ids, *args, **kwargs)
|
hat_obj.unlink(cr, uid, hat_ids, *args, **kwargs)
|
||||||
return super(project_work,self).unlink(cr, uid, ids, *args, **kwargs)
|
return super(project_work,self).unlink(cr, uid, ids, *args, **kwargs)
|
||||||
|
@ -231,12 +238,11 @@ class task(osv.osv):
|
||||||
if vals.get('project_id',False) or vals.get('name',False):
|
if vals.get('project_id',False) or vals.get('name',False):
|
||||||
vals_line = {}
|
vals_line = {}
|
||||||
hr_anlytic_timesheet = self.pool.get('hr.analytic.timesheet')
|
hr_anlytic_timesheet = self.pool.get('hr.analytic.timesheet')
|
||||||
task_obj_l = self.browse(cr, uid, ids, context=context)
|
|
||||||
if vals.get('project_id',False):
|
if vals.get('project_id',False):
|
||||||
project_obj = self.pool.get('project.project').browse(cr, uid, vals['project_id'], context=context)
|
project_obj = self.pool.get('project.project').browse(cr, uid, vals['project_id'], context=context)
|
||||||
acc_id = project_obj.analytic_account_id.id
|
acc_id = project_obj.analytic_account_id.id
|
||||||
|
|
||||||
for task_obj in task_obj_l:
|
for task_obj in self.browse(cr, uid, ids, context=context):
|
||||||
if len(task_obj.work_ids):
|
if len(task_obj.work_ids):
|
||||||
for task_work in task_obj.work_ids:
|
for task_work in task_obj.work_ids:
|
||||||
if not task_work.hr_analytic_timesheet_id:
|
if not task_work.hr_analytic_timesheet_id:
|
||||||
|
@ -253,16 +259,19 @@ task()
|
||||||
|
|
||||||
class res_partner(osv.osv):
|
class res_partner(osv.osv):
|
||||||
_inherit = 'res.partner'
|
_inherit = 'res.partner'
|
||||||
|
|
||||||
def unlink(self, cursor, user, ids, context=None):
|
def unlink(self, cursor, user, ids, context=None):
|
||||||
parnter_id=self.pool.get('project.project').search(cursor, user, [('partner_id', 'in', ids)])
|
parnter_id=self.pool.get('project.project').search(cursor, user, [('partner_id', 'in', ids)])
|
||||||
if parnter_id:
|
if parnter_id:
|
||||||
raise osv.except_osv(_('Invalid Action!'), _('You cannot delete a partner which is assigned to project, but you can uncheck the active box.'))
|
raise osv.except_osv(_('Invalid Action!'), _('You cannot delete a partner which is assigned to project, but you can uncheck the active box.'))
|
||||||
return super(res_partner,self).unlink(cursor, user, ids,
|
return super(res_partner,self).unlink(cursor, user, ids,
|
||||||
context=context)
|
context=context)
|
||||||
|
|
||||||
res_partner()
|
res_partner()
|
||||||
|
|
||||||
class account_analytic_line(osv.osv):
|
class account_analytic_line(osv.osv):
|
||||||
_inherit = "account.analytic.line"
|
_inherit = "account.analytic.line"
|
||||||
|
|
||||||
def on_change_account_id(self, cr, uid, ids, account_id):
|
def on_change_account_id(self, cr, uid, ids, account_id):
|
||||||
res = {}
|
res = {}
|
||||||
if not account_id:
|
if not account_id:
|
||||||
|
@ -274,5 +283,7 @@ class account_analytic_line(osv.osv):
|
||||||
if acc.state == 'close' or acc.state == 'cancelled':
|
if acc.state == 'close' or acc.state == 'cancelled':
|
||||||
raise osv.except_osv(_('Invalid Analytic Account !'), _('You cannot select a Analytic Account which is in Close or Cancelled state.'))
|
raise osv.except_osv(_('Invalid Analytic Account !'), _('You cannot select a Analytic Account which is in Close or Cancelled state.'))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
account_analytic_line()
|
account_analytic_line()
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -50,6 +50,16 @@ class sale_order(osv.osv):
|
||||||
_inherit = ['mail.thread', 'ir.needaction_mixin']
|
_inherit = ['mail.thread', 'ir.needaction_mixin']
|
||||||
_description = "Sales Order"
|
_description = "Sales Order"
|
||||||
|
|
||||||
|
def onchange_shop_id(self, cr, uid, ids, shop_id, context=None):
|
||||||
|
v = {}
|
||||||
|
if shop_id:
|
||||||
|
shop = self.pool.get('sale.shop').browse(cr, uid, shop_id, context=context)
|
||||||
|
if shop.project_id.id:
|
||||||
|
v['project_id'] = shop.project_id.id
|
||||||
|
if shop.pricelist_id.id:
|
||||||
|
v['pricelist_id'] = shop.pricelist_id.id
|
||||||
|
return {'value': v}
|
||||||
|
|
||||||
def copy(self, cr, uid, id, default=None, context=None):
|
def copy(self, cr, uid, id, default=None, context=None):
|
||||||
if not default:
|
if not default:
|
||||||
default = {}
|
default = {}
|
||||||
|
@ -900,7 +910,6 @@ class sale_order_line(osv.osv):
|
||||||
fpos = fiscal_position and self.pool.get('account.fiscal.position').browse(cr, uid, fiscal_position) or False
|
fpos = fiscal_position and self.pool.get('account.fiscal.position').browse(cr, uid, fiscal_position) or False
|
||||||
if update_tax: #The quantity only have changed
|
if update_tax: #The quantity only have changed
|
||||||
result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, product_obj.taxes_id)
|
result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, product_obj.taxes_id)
|
||||||
result.update({'type': product_obj.procure_method})
|
|
||||||
|
|
||||||
if not flag:
|
if not flag:
|
||||||
result['name'] = self.pool.get('product.product').name_get(cr, uid, [product_obj.id], context=context_partner)[0][1]
|
result['name'] = self.pool.get('product.product').name_get(cr, uid, [product_obj.id], context=context_partner)[0][1]
|
||||||
|
|
|
@ -181,7 +181,7 @@
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="date_order"/>
|
<field name="date_order"/>
|
||||||
<field name="shop_id" invisible="1"/>
|
<field name="shop_id" groups="base.group_no_one" on_change="onchange_shop_id(shop_id, context)" widget="selection"/>
|
||||||
<field name="client_order_ref"/>
|
<field name="client_order_ref"/>
|
||||||
<field domain="[('type','=','sale')]" name="pricelist_id" groups="product.group_sale_pricelist" on_change="onchange_pricelist_id(pricelist_id,order_line)"/>
|
<field domain="[('type','=','sale')]" name="pricelist_id" groups="product.group_sale_pricelist" on_change="onchange_pricelist_id(pricelist_id,order_line)"/>
|
||||||
</group>
|
</group>
|
||||||
|
@ -200,7 +200,7 @@
|
||||||
<field name="product_id"
|
<field name="product_id"
|
||||||
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'shop':parent.shop_id, 'uom':product_uom}"
|
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'shop':parent.shop_id, 'uom':product_uom}"
|
||||||
groups="base.group_user"
|
groups="base.group_user"
|
||||||
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, True, parent.date_order, False, parent.fiscal_position, False, context)"/>
|
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, product_uos_qty, product_uos, name, parent.partner_id, False, True, parent.date_order, False, parent.fiscal_position, False, context)"/>
|
||||||
<label for="product_uom_qty"/>
|
<label for="product_uom_qty"/>
|
||||||
<div>
|
<div>
|
||||||
<field
|
<field
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
partner_id: base.res_partner_2
|
partner_id: base.res_partner_2
|
||||||
note: Invoice after delivery
|
note: Invoice after delivery
|
||||||
payment_term: account.account_payment_term
|
payment_term: account.account_payment_term
|
||||||
|
order_line:
|
||||||
|
- product_id: product.product_product_7
|
||||||
|
product_uom_qty: 8
|
||||||
-
|
-
|
||||||
!record {model: sale.order.line, id: line}:
|
I verify that the onchange was correctly triggered
|
||||||
name : 'LCD Monitor'
|
-
|
||||||
order_id: sale_order_test1
|
!assert {model: sale.order, id: sale.sale_order_test1, string: The onchange function of product was not correctly triggered}:
|
||||||
product_id: product.product_product_7
|
- order_line[0].name == u'[LCD17] 17\u201d LCD Monitor'
|
||||||
price_unit: 190.50
|
- order_line[0].price_unit == 1350.0
|
||||||
product_uom_qty: 8
|
|
||||||
|
|
|
@ -39,4 +39,14 @@ class sale_order_line(osv.osv):
|
||||||
|
|
||||||
sale_order_line()
|
sale_order_line()
|
||||||
|
|
||||||
|
class sale_order(osv.osv):
|
||||||
|
_inherit = "sale.order"
|
||||||
|
|
||||||
|
def onchange_shop_id(self, cr, uid, ids, shop_id, context=None):
|
||||||
|
# Remove the project_id from the result of super() call, if any, as this field is not in the view anymore
|
||||||
|
res = super(sale_order, self).onchange_shop_id(cr, uid, ids, shop_id, context=context)
|
||||||
|
if res.get('value',{}).get('project_id'):
|
||||||
|
del(res['value']['project_id'])
|
||||||
|
return res
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -117,26 +117,13 @@
|
||||||
proc_ids = self.search(cr, uid, [('origin','=',so.name) and ('state','=','running')])
|
proc_ids = self.search(cr, uid, [('origin','=',so.name) and ('state','=','running')])
|
||||||
assert proc_ids, _('Procurement is not in the running state!')
|
assert proc_ids, _('Procurement is not in the running state!')
|
||||||
-
|
-
|
||||||
I verify that a manufacturing order has been generated
|
I verify that a manufacturing order has been generated, and that its name and reference are correct
|
||||||
-
|
-
|
||||||
!python {model: sale.order}: |
|
!python {model: sale.order}: |
|
||||||
|
mnf_obj = self.pool.get('mrp.production')
|
||||||
so = self.browse(cr, uid, ref("sale_order_so0"))
|
so = self.browse(cr, uid, ref("sale_order_so0"))
|
||||||
mnf_obj=self.pool.get('mrp.production')
|
mnf_id = mnf_obj.search(cr, uid, [('origin','=',so.name)])
|
||||||
mnf_id=mnf_obj.search(cr, uid, [('origin','=',so.name)])
|
|
||||||
assert mnf_id, _('Manufacturing order has not been generated')
|
assert mnf_id, _('Manufacturing order has not been generated')
|
||||||
-
|
mo = mnf_obj.browse(cr, uid, mnf_id)[0]
|
||||||
I verify that a 'Sale Name' field of Manufacturing order gets bind with the value
|
assert mo.sale_name == so.name, 'Wrong Name for the Manufacturing Order. Expected %s, Got %s' % (so.name, mo.name)
|
||||||
-
|
assert mo.sale_ref == so.client_order_ref, 'Wrong Sale Reference for the Manufacturing Order'
|
||||||
!python {model: sale.order}: |
|
|
||||||
so = self.browse(cr, uid, ref("sale_order_so0"))
|
|
||||||
mnf_obj=self.pool.get('mrp.production')
|
|
||||||
mnf_id=mnf_obj.search(cr, uid, [('sale_name','=',so.name)])
|
|
||||||
assert mnf_id, _('Sale Name is not bind with the value')
|
|
||||||
-
|
|
||||||
I verify that a 'Sale Reference' field of Manufacturing order gets bind with the value
|
|
||||||
-
|
|
||||||
!python {model: sale.order}: |
|
|
||||||
so = self.browse(cr, uid, ref("sale_order_so0"))
|
|
||||||
mnf_obj=self.pool.get('mrp.production')
|
|
||||||
mnf_id=mnf_obj.search(cr, uid, [('sale_ref','=',so.client_order_ref)])
|
|
||||||
assert mnf_id, _('Sale Reference is not bind with the value')
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ You can choose flexible invoicing methods:
|
||||||
'test': ['test/cancel_order_sale_stock.yml',
|
'test': ['test/cancel_order_sale_stock.yml',
|
||||||
'test/picking_order_policy.yml',
|
'test/picking_order_policy.yml',
|
||||||
'test/prepaid_order_policy.yml',
|
'test/prepaid_order_policy.yml',
|
||||||
|
'test/sale_order_onchange.yml',
|
||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'auto_install': True,
|
'auto_install': True,
|
||||||
|
|
|
@ -165,16 +165,6 @@ class sale_order(osv.osv):
|
||||||
|
|
||||||
return osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
|
return osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
|
||||||
|
|
||||||
def onchange_shop_id(self, cr, uid, ids, shop_id):
|
|
||||||
v = {}
|
|
||||||
if shop_id:
|
|
||||||
shop = self.pool.get('sale.shop').browse(cr, uid, shop_id)
|
|
||||||
v['project_id'] = shop.project_id.id
|
|
||||||
# Que faire si le client a une pricelist a lui ?
|
|
||||||
if shop.pricelist_id.id:
|
|
||||||
v['pricelist_id'] = shop.pricelist_id.id
|
|
||||||
return {'value': v}
|
|
||||||
|
|
||||||
def action_view_delivery(self, cr, uid, ids, context=None):
|
def action_view_delivery(self, cr, uid, ids, context=None):
|
||||||
'''
|
'''
|
||||||
This function returns an action that display existing delivery orders of given sale order ids. It can either be a in a list or in a form view, if there is only one delivery order to show.
|
This function returns an action that display existing delivery orders of given sale order ids. It can either be a in a list or in a form view, if there is only one delivery order to show.
|
||||||
|
@ -604,14 +594,18 @@ class sale_order_line(osv.osv):
|
||||||
lang=lang, update_tax=update_tax, date_order=date_order, packaging=packaging, fiscal_position=fiscal_position, flag=flag, context=context)
|
lang=lang, update_tax=update_tax, date_order=date_order, packaging=packaging, fiscal_position=fiscal_position, flag=flag, context=context)
|
||||||
|
|
||||||
if not product:
|
if not product:
|
||||||
return {'value': {'th_weight': 0, 'product_packaging': False,
|
res['value'].update({'product_packaging': False})
|
||||||
'product_uos_qty': qty}, 'domain': {'product_uom': [],
|
return res
|
||||||
'product_uos': []}}
|
|
||||||
|
#update of result obtained in super function
|
||||||
res_packing = self.product_packaging_change(cr, uid, ids, pricelist, product, qty, uom, partner_id, packaging, context=context)
|
res_packing = self.product_packaging_change(cr, uid, ids, pricelist, product, qty, uom, partner_id, packaging, context=context)
|
||||||
res['value'].update(res_packing.get('value', {}))
|
res['value'].update(res_packing.get('value', {}))
|
||||||
warning_msgs = res_packing.get('warning') and res_packing['warning']['message'] or ''
|
warning_msgs = res_packing.get('warning') and res_packing['warning']['message'] or ''
|
||||||
product_obj = product_obj.browse(cr, uid, product, context=context)
|
product_obj = product_obj.browse(cr, uid, product, context=context)
|
||||||
res['value']['delay'] = (product_obj.sale_delay or 0.0)
|
res['value']['delay'] = (product_obj.sale_delay or 0.0)
|
||||||
|
res['value']['type'] = product_obj.procure_method
|
||||||
|
|
||||||
|
#check if product is available, and if not: raise an error
|
||||||
uom2 = False
|
uom2 = False
|
||||||
if uom:
|
if uom:
|
||||||
uom2 = product_uom_obj.browse(cr, uid, uom)
|
uom2 = product_uom_obj.browse(cr, uid, uom)
|
||||||
|
@ -619,7 +613,6 @@ class sale_order_line(osv.osv):
|
||||||
uom = False
|
uom = False
|
||||||
if not uom2:
|
if not uom2:
|
||||||
uom2 = product_obj.uom_id
|
uom2 = product_obj.uom_id
|
||||||
|
|
||||||
compare_qty = float_compare(product_obj.virtual_available * uom2.factor, qty * product_obj.uom_id.factor, precision_rounding=product_obj.uom_id.rounding)
|
compare_qty = float_compare(product_obj.virtual_available * uom2.factor, qty * product_obj.uom_id.factor, precision_rounding=product_obj.uom_id.rounding)
|
||||||
if (product_obj.type=='product') and int(compare_qty) == -1 \
|
if (product_obj.type=='product') and int(compare_qty) == -1 \
|
||||||
and (product_obj.procure_method=='make_to_stock'):
|
and (product_obj.procure_method=='make_to_stock'):
|
||||||
|
@ -628,7 +621,8 @@ class sale_order_line(osv.osv):
|
||||||
max(0,product_obj.virtual_available), product_obj.uom_id.name,
|
max(0,product_obj.virtual_available), product_obj.uom_id.name,
|
||||||
max(0,product_obj.qty_available), product_obj.uom_id.name)
|
max(0,product_obj.qty_available), product_obj.uom_id.name)
|
||||||
warning_msgs += _("Not enough stock ! : ") + warn_msg + "\n\n"
|
warning_msgs += _("Not enough stock ! : ") + warn_msg + "\n\n"
|
||||||
# get unit price
|
|
||||||
|
#update of warning messages
|
||||||
if warning_msgs:
|
if warning_msgs:
|
||||||
warning = {
|
warning = {
|
||||||
'title': _('Configuration Error!'),
|
'title': _('Configuration Error!'),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
<record id="view_sale_shop_form_inherit" model="ir.ui.view">
|
<record id="view_sale_shop_form_inherit" model="ir.ui.view">
|
||||||
<field name="name">sale.shop.inherit.form</field>
|
<field name="name">sale.shop.inherit.form</field>
|
||||||
<field name="model">sale.shop</field>
|
<field name="model">sale.shop</field>
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="view_shop_tree_inherit" model="ir.ui.view">
|
<record id="view_shop_tree_inherit" model="ir.ui.view">
|
||||||
<field name="name">sale.shop.sale.stock</field>
|
<field name="name">sale.shop.sale.stock</field>
|
||||||
<field name="model">sale.shop</field>
|
<field name="model">sale.shop</field>
|
||||||
|
@ -41,7 +41,8 @@
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//button[@name='action_view_invoice']" position="after">
|
<xpath expr="//button[@name='action_view_invoice']" position="after">
|
||||||
<button name="action_view_delivery" string="View Delivery Order" type="object" class="oe_highlight"
|
<button name="action_view_delivery" string="View Delivery Order" type="object" class="oe_highlight"
|
||||||
attrs="{'invisible': ['|','|','|',('picking_ids','=',False),('picking_ids','=',[]), ('state', 'not in', ('progress','manual')),('shipped','=',True)]}"/> </xpath>
|
attrs="{'invisible': ['|','|','|',('picking_ids','=',False),('picking_ids','=',[]), ('state', 'not in', ('progress','manual')),('shipped','=',True)]}"/>
|
||||||
|
</xpath>
|
||||||
<xpath expr="//button[@name='action_cancel']" position="after">
|
<xpath expr="//button[@name='action_cancel']" position="after">
|
||||||
<button name="ship_cancel" states="shipping_except" string="Cancel"/>
|
<button name="ship_cancel" states="shipping_except" string="Cancel"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
-
|
||||||
|
In order to test the onchange of the Sale Order, I create a product
|
||||||
|
-
|
||||||
|
!record {model: product.product, id: product_onchange1}:
|
||||||
|
name: 'Devil Worship Book'
|
||||||
|
list_price: 66.6
|
||||||
|
procure_method: 'make_to_order'
|
||||||
|
-
|
||||||
|
Now i create a sale order that uses my new product
|
||||||
|
-
|
||||||
|
!record {model: sale.order, id: sale_order_onchange1}:
|
||||||
|
partner_id: base.res_partner_2
|
||||||
|
order_line:
|
||||||
|
- product_id: sale_stock.product_onchange1
|
||||||
|
product_uom_qty: 10
|
||||||
|
-
|
||||||
|
I verify that the onchange of product on sale order line was correctly triggered
|
||||||
|
-
|
||||||
|
!assert {model: sale.order, id: sale_order_onchange1, string: The onchange function of product was not correctly triggered}:
|
||||||
|
- order_line[0].name == u'Devil Worship Book'
|
||||||
|
- order_line[0].price_unit == 66.6
|
||||||
|
- order_line[0].type == 'make_to_order'
|
|
@ -1125,7 +1125,8 @@
|
||||||
<field name="date_deadline"/>
|
<field name="date_deadline"/>
|
||||||
<field name="survey_id"/>
|
<field name="survey_id"/>
|
||||||
<field name="user_id" on_change="on_change_user(user_id)"/>
|
<field name="user_id" on_change="on_change_user(user_id)"/>
|
||||||
<field name="response" readonly="1"/>
|
<field name="email"/>
|
||||||
|
<field name="response" readonly="1"/>
|
||||||
</group>
|
</group>
|
||||||
</sheet>
|
</sheet>
|
||||||
</form>
|
</form>
|
||||||
|
@ -1139,6 +1140,7 @@
|
||||||
<tree string="Evaluation Plan Phase" colors="red:date_deadline<current_date">
|
<tree string="Evaluation Plan Phase" colors="red:date_deadline<current_date">
|
||||||
<field name="date_deadline"/>
|
<field name="date_deadline"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
|
<field name="email"/>
|
||||||
<field name="survey_id"/>
|
<field name="survey_id"/>
|
||||||
<field name="response" />
|
<field name="response" />
|
||||||
<field name="state" />
|
<field name="state" />
|
||||||
|
|
Loading…
Reference in New Issue