[MERGE] from trunk
bzr revid: fva@openerp.com-20121017140509-67yq1gjzrs871hb6
This commit is contained in:
commit
cbdb0ccf9c
|
@ -155,6 +155,7 @@ class account_account_type(osv.osv):
|
|||
return res
|
||||
|
||||
def _save_report_type(self, cr, uid, account_type_id, field_name, field_value, arg, context=None):
|
||||
field_value = field_value or 'none'
|
||||
obj_data = self.pool.get('ir.model.data')
|
||||
obj_financial_report = self.pool.get('account.financial.report')
|
||||
#unlink if it exists somewhere in the financial reports related to BS or PL
|
||||
|
@ -299,7 +300,6 @@ class account_account(osv.osv):
|
|||
if aml_query.strip():
|
||||
wheres.append(aml_query.strip())
|
||||
filters = " AND ".join(wheres)
|
||||
_logger.debug('Filters: %s',(filters))
|
||||
# IN might not work ideally in case there are too many
|
||||
# children_and_consolidated, in that case join on a
|
||||
# values() e.g.:
|
||||
|
@ -315,7 +315,6 @@ class account_account(osv.osv):
|
|||
" GROUP BY l.account_id")
|
||||
params = (tuple(children_and_consolidated),) + query_params
|
||||
cr.execute(request, params)
|
||||
_logger.debug('Status: %s',(cr.statusmessage))
|
||||
|
||||
for row in cr.dictfetchall():
|
||||
accounts[row['id']] = row
|
||||
|
@ -596,10 +595,7 @@ class account_account(osv.osv):
|
|||
return res
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None, done_list=None, local=False):
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
default = {} if default is None else default.copy()
|
||||
if done_list is None:
|
||||
done_list = []
|
||||
account = self.browse(cr, uid, id, context=context)
|
||||
|
@ -781,10 +777,7 @@ class account_journal(osv.osv):
|
|||
]
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None, done_list=None, local=False):
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
default = {} if default is None else default.copy()
|
||||
if done_list is None:
|
||||
done_list = []
|
||||
journal = self.browse(cr, uid, id, context=context)
|
||||
|
@ -1185,6 +1178,7 @@ class account_fiscalyear(osv.osv):
|
|||
}
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
default = {} if default is None else default.copy()
|
||||
default.update({
|
||||
'period_ids': [],
|
||||
'end_journal_period_id': False
|
||||
|
@ -1444,14 +1438,8 @@ class account_move(osv.osv):
|
|||
return result
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
if context is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
if context is None:
|
||||
context = {}
|
||||
else:
|
||||
context = context.copy()
|
||||
default = {} if default is None else default.copy()
|
||||
context = {} if context is None else context.copy()
|
||||
default.update({
|
||||
'state':'draft',
|
||||
'name':'/',
|
||||
|
@ -2780,7 +2768,6 @@ class account_chart_template(osv.osv):
|
|||
'property_account_income_categ': fields.many2one('account.account.template', 'Income Category Account'),
|
||||
'property_account_expense': fields.many2one('account.account.template', 'Expense Account on Product Template'),
|
||||
'property_account_income': fields.many2one('account.account.template', 'Income Account on Product Template'),
|
||||
'property_reserve_and_surplus_account': fields.many2one('account.account.template', 'Reserve and Profit/Loss Account', domain=[('type', '=', 'payable')], help='This Account is used for transferring Profit/Loss(If It is Profit: Amount will be added, Loss: Amount will be deducted.), Which is calculated from Profilt & Loss Report'),
|
||||
'property_account_income_opening': fields.many2one('account.account.template', 'Opening Entries Income Account'),
|
||||
'property_account_expense_opening': fields.many2one('account.account.template', 'Opening Entries Expense Account'),
|
||||
}
|
||||
|
@ -3228,7 +3215,6 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
|||
('property_account_income_categ','product.category','account.account'),
|
||||
('property_account_expense','product.template','account.account'),
|
||||
('property_account_income','product.template','account.account'),
|
||||
('property_reserve_and_surplus_account','res.company','account.account')
|
||||
]
|
||||
template = self.pool.get('account.chart.template').browse(cr, uid, chart_template_id, context=context)
|
||||
for record in todo_list:
|
||||
|
|
|
@ -461,9 +461,10 @@ class account_bank_statement(osv.osv):
|
|||
return {}
|
||||
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, ['company_id'], context=context)
|
||||
journal_data = self.pool.get('account.journal').read(cr, uid, journal_id, ['company_id', 'currency'], context=context)
|
||||
company_id = journal_data['company_id']
|
||||
return {'value': {'balance_start': balance_start, 'company_id': company_id}}
|
||||
currency_id = journal_data['currency'] or self.pool.get('res.company').browse(cr, uid, company_id[0], context=context).currency_id.id
|
||||
return {'value': {'balance_start': balance_start, 'company_id': company_id, 'currency': currency_id}}
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
stat = self.read(cr, uid, ids, ['state'], context=context)
|
||||
|
|
|
@ -211,17 +211,17 @@
|
|||
</tree>
|
||||
</field>
|
||||
<group class="oe_subtotal_footer oe_right">
|
||||
<field name="amount_untaxed"/>
|
||||
<field name="amount_untaxed" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<div>
|
||||
<label for="amount_tax"/>
|
||||
<button name="button_reset_taxes" states="draft,proforma2"
|
||||
string="(update)" class="oe_link oe_edit_only"
|
||||
type="object" help="Recompute taxes and total"/>
|
||||
</div>
|
||||
<field name="amount_tax" nolabel="1"/>
|
||||
<field name="amount_total" class="oe_subtotal_footer_separator"/>
|
||||
<field name="amount_tax" nolabel="1" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="amount_total" class="oe_subtotal_footer_separator" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
|
||||
<field name="residual"/>
|
||||
<field name="residual" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="reconciled" invisible="1"/>
|
||||
</group>
|
||||
<div style="width: 50%%">
|
||||
|
@ -322,7 +322,7 @@
|
|||
<field string="Customer" name="partner_id"
|
||||
on_change="onchange_partner_id(type,partner_id,date_invoice,payment_term, partner_bank_id,company_id)"
|
||||
groups="base.group_user" context="{'search_default_customer':1, 'show_address': 1}"
|
||||
options='{"always_reload": true}'/>
|
||||
options='{"always_reload": True}'/>
|
||||
<field name="fiscal_position" widget="selection" />
|
||||
</group>
|
||||
<group>
|
||||
|
@ -368,16 +368,16 @@
|
|||
</tree>
|
||||
</field>
|
||||
<group class="oe_subtotal_footer oe_right">
|
||||
<field name="amount_untaxed"/>
|
||||
<field name="amount_untaxed" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<div>
|
||||
<label for="amount_tax"/>
|
||||
<button name="button_reset_taxes" states="draft,proforma2"
|
||||
string="(update)" class="oe_link oe_edit_only"
|
||||
type="object" help="Recompute taxes and total"/>
|
||||
</div>
|
||||
<field name="amount_tax" nolabel="1"/>
|
||||
<field name="amount_total" class="oe_subtotal_footer_separator"/>
|
||||
<field name="residual" groups="account.group_account_user"/>
|
||||
<field name="amount_tax" nolabel="1" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="amount_total" class="oe_subtotal_footer_separator" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="residual" groups="account.group_account_user" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="reconciled" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
|
|
|
@ -514,8 +514,7 @@ class account_move_line(osv.osv):
|
|||
'analytic_lines': fields.one2many('account.analytic.line', 'move_id', 'Analytic lines'),
|
||||
'centralisation': fields.selection([('normal','Normal'),('credit','Credit Centralisation'),('debit','Debit Centralisation'),('currency','Currency Adjustment')], 'Centralisation', size=8),
|
||||
'balance': fields.function(_balance, fnct_search=_balance_search, string='Balance'),
|
||||
'state': fields.selection([('draft','Unbalanced'), ('valid','Valid')], 'Status', readonly=True,
|
||||
help='When new move line is created the state will be \'Draft\'.\n* When all the payments are done it will be in \'Valid\' state.'),
|
||||
'state': fields.selection([('draft','Unbalanced'), ('valid','Balanced')], 'Status', readonly=True),
|
||||
'tax_code_id': fields.many2one('account.tax.code', 'Tax Account', help="The Account can either be a base tax code or a tax code account."),
|
||||
'tax_amount': fields.float('Tax/Base Amount', digits_compute=dp.get_precision('Account'), select=True, help="If the Tax account is a tax code account, this field will contain the taxed amount.If the tax account is base tax code, "\
|
||||
"this field will contain the basic amount(without tax)."),
|
||||
|
|
|
@ -633,13 +633,10 @@
|
|||
<field name="period_id" class="oe_inline"/>
|
||||
</div>
|
||||
<field name='company_id' widget="selection" groups="base.group_multi_company" />
|
||||
<field name="currency" invisible="1"/>
|
||||
</group><group>
|
||||
<label for="balance_start"/>
|
||||
<div>
|
||||
<field name="balance_start" class="oe_inline"/>
|
||||
<field name="currency" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="balance_end_real"/>
|
||||
<field name="balance_start" widget="monetary" options='{"currency_field" : "currency"}'/>
|
||||
<field name="balance_end_real" widget="monetary" options='{"currency_field" : "currency"}'/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
|
@ -1040,11 +1037,10 @@
|
|||
-->
|
||||
|
||||
<record id="view_move_line_tree_reconcile" model="ir.ui.view">
|
||||
<field name="name">account.move.line.reconcile.tree</field>
|
||||
<field name="model">account.move.line</field>
|
||||
<field eval="24" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="red:state == 'draft';black:state == 'valid'" string="Journal Items to Reconcile" create="false">
|
||||
<tree_account_reconciliation colors="red:state == 'draft';black:state == 'valid'" string="Journal Items to Reconcile" create="false" version="7.0">
|
||||
<field name="date"/>
|
||||
<field name="move_id"/>
|
||||
<field name="ref"/>
|
||||
|
@ -1052,9 +1048,10 @@
|
|||
<field name="partner_id"/>
|
||||
<field name="account_id"/>
|
||||
<field name="reconcile_partial_id"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="debit" sum="Total debit"/>
|
||||
<field name="credit" sum="Total credit"/>
|
||||
</tree>
|
||||
</tree_account_reconciliation>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
@ -1081,7 +1078,7 @@
|
|||
<field name="currency_id" attrs="{'readonly':[('state','=','valid')]}" groups="base.group_multi_currency"/>
|
||||
<field name="reconcile_partial_id"/>
|
||||
<field name="reconcile_id"/>
|
||||
<field name="state"/>
|
||||
<field name="state" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -1130,8 +1127,8 @@
|
|||
<field name="account_tax_id" domain="[('parent_id','=',False)]"/>
|
||||
</group>
|
||||
<group attrs="{'readonly':[('state','=','valid')]}" string="Currency" groups="base.group_multi_currency">
|
||||
<field name="currency_id"/>
|
||||
<field name="amount_currency"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="amount_currency" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
</group>
|
||||
<group string="Reconciliation">
|
||||
<field name="reconcile_id"/>
|
||||
|
@ -1177,8 +1174,8 @@
|
|||
<field name="credit"/>
|
||||
|
||||
<separator colspan="4" string="Optional Information"/>
|
||||
<field name="currency_id" groups="base.group_multi_currency"/>
|
||||
<field name="amount_currency" groups="base.group_multi_currency"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="amount_currency" groups="base.group_multi_currency" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="quantity"/>
|
||||
<field name="move_id" required="False"/>
|
||||
<newline/>
|
||||
|
@ -1545,8 +1542,7 @@
|
|||
<field name="name">Journal Items to Reconcile</field>
|
||||
<field name="res_model">account.move.line</field>
|
||||
<field name="view_id" ref="view_move_line_tree_reconcile"/>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">account_reconciliation_list</field>
|
||||
<field name="view_mode">tree_account_reconciliation</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
No journal items found.
|
||||
|
@ -1984,7 +1980,7 @@
|
|||
<field name="credit" sum="Total credit"/>
|
||||
<field name="account_tax_id"/>
|
||||
<field name="analytic_account_id" domain="[('parent_id','!=',False)]" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="state"/>
|
||||
<field name="state" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -2174,7 +2170,6 @@
|
|||
<field name="property_account_income" domain="[('id', 'child_of', [account_root_id])]"/>
|
||||
<field name="property_account_income_opening" domain="[('id', 'child_of', [account_root_id])]"/>
|
||||
<field name="property_account_expense_opening" domain="[('id', 'child_of', [account_root_id])]"/>
|
||||
<field name="property_reserve_and_surplus_account" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -2567,7 +2562,7 @@ action = pool.get('res.config').next(cr, uid, [], context)
|
|||
<field name="date" attrs="{'readonly':[('state','!=','draft')]}" on_change="onchange_date(date, company_id)"/>
|
||||
<field name="closing_date" readonly="1"/>
|
||||
<field name="period_id" class="oe_inline"/>
|
||||
<field name="currency" invisible="1" groups="base.group_multi_currency"/>
|
||||
<field name="currency" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
|
@ -2629,12 +2624,12 @@ action = pool.get('res.config').next(cr, uid, [], context)
|
|||
<group col="6" colspan="4">
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Opening Balance" colspan="4"/>
|
||||
<field name="balance_start" readonly="1" string="Opening Cash Control"/>
|
||||
<field name="last_closing_balance" readonly="1" string="Last Closing Balance" />
|
||||
<field name="total_entry_encoding" />
|
||||
<field name="balance_start" readonly="1" string="Opening Cash Control" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="last_closing_balance" readonly="1" string="Last Closing Balance" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="total_entry_encoding" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
</group>
|
||||
<group string="Closing Balance">
|
||||
<field name="balance_end"/>
|
||||
<field name="balance_end" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
|
|
|
@ -32,14 +32,6 @@ class res_company(osv.osv):
|
|||
help="If you select 'Round per Line' : for each tax, the tax amount will first be computed and rounded for each PO/SO/invoice line and then these rounded amounts will be summed, leading to the total amount for that tax. If you select 'Round Globally': for each tax, the tax amount will be computed for each PO/SO/invoice line, then these amounts will be summed and eventually this total tax amount will be rounded. If you sell with tax included, you should choose 'Round per line' because you certainly want the sum of your tax-included line subtotals to be equal to the total amount with taxes."),
|
||||
'paypal_account': fields.char("Paypal Account", size=128, help="Paypal username (usually email) for receiving online payments."),
|
||||
'overdue_msg': fields.text('Overdue Payments Message', translate=True),
|
||||
'property_reserve_and_surplus_account': fields.property(
|
||||
'account.account',
|
||||
type='many2one',
|
||||
relation='account.account',
|
||||
string="Reserve and Profit/Loss Account",
|
||||
view_load=True,
|
||||
domain="[('type', '=', 'other')]",
|
||||
help="This account is used for transferring Profit/Loss (If It is Profit: Amount will be added, Loss : Amount will be deducted.), as calculated in Profit & Loss Report"),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
|
|
@ -15,18 +15,5 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_company_inherit_1_form">
|
||||
<field name="name">res.company.form.inherit</field>
|
||||
<field name="inherit_id" ref="base.view_company_form"/>
|
||||
<field name="model">res.company</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='account_grp']" position="inside">
|
||||
<field name="property_reserve_and_surplus_account"/>
|
||||
<field name="tax_calculation_rounding_method"/>
|
||||
<field name="paypal_account" placeholder="e.g. sales@openerp.com"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -127,6 +127,7 @@
|
|||
<field name="view_id" ref="account_journal_bank_view"/>
|
||||
<field name="name">Status</field>
|
||||
<field name="field">state</field>
|
||||
<field eval="True" name="invisible"/>
|
||||
<field eval="19" name="sequence"/>
|
||||
</record>
|
||||
<record id="bank_col20" model="account.journal.column">
|
||||
|
@ -214,6 +215,7 @@
|
|||
<field name="view_id" ref="account_journal_bank_view_multi"/>
|
||||
<field name="name">Status</field>
|
||||
<field name="field">state</field>
|
||||
<field eval="True" name="invisible"/>
|
||||
<field eval="19" name="sequence"/>
|
||||
</record>
|
||||
<record id="bank_col20_multi" model="account.journal.column">
|
||||
|
@ -289,6 +291,7 @@
|
|||
<field name="view_id" ref="account_journal_view"/>
|
||||
<field name="name">Status</field>
|
||||
<field name="field">state</field>
|
||||
<field eval="True" name="invisible"/>
|
||||
<field eval="19" name="sequence"/>
|
||||
</record>
|
||||
|
||||
|
@ -370,6 +373,7 @@
|
|||
<field name="view_id" ref="account_sp_journal_view"/>
|
||||
<field name="name">Status</field>
|
||||
<field name="field">state</field>
|
||||
<field eval="True" name="invisible"/>
|
||||
<field eval="19" name="sequence"/>
|
||||
</record>
|
||||
<record id="sp_journal_col20" model="account.journal.column">
|
||||
|
@ -456,6 +460,7 @@
|
|||
<field name="view_id" ref="account_sp_refund_journal_view"/>
|
||||
<field name="name">Status</field>
|
||||
<field name="field">state</field>
|
||||
<field eval="True" name="invisible"/>
|
||||
<field eval="19" name="sequence"/>
|
||||
</record>
|
||||
<record id="sp_refund_journal_col20" model="account.journal.column">
|
||||
|
|
|
@ -381,7 +381,6 @@
|
|||
<field name="property_account_income_categ" ref="conf_a_sale"/>
|
||||
<field name="property_account_income_opening" ref="conf_o_income"/>
|
||||
<field name="property_account_expense_opening" ref="conf_o_expense"/>
|
||||
<field name="property_reserve_and_surplus_account" ref="conf_a_reserve_and_surplus"/>
|
||||
<field name="complete_tax_set" eval="False"/>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -304,14 +304,6 @@
|
|||
<field name="company_id" ref="base.main_company"/>
|
||||
</record>
|
||||
|
||||
<record forcecreate="True" id="property_reserve_and_surplus_account" model="ir.property">
|
||||
<field name="name">property_account_receivable</field>
|
||||
<field name="fields_id" search="[('model','=','res.company'),('name','=','property_reserve_and_surplus_account')]"/>
|
||||
<field eval="'account.account,'+str(rsa)" name="value"/>
|
||||
<field name="company_id" ref="base.main_company"/>
|
||||
</record>
|
||||
|
||||
|
||||
<!--
|
||||
Account Journal
|
||||
-->
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -14,8 +14,8 @@
|
|||
<field name="taxes_id" colspan="2" attrs="{'readonly':[('sale_ok','=',0)]}" widget="many2many_tags"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="property_account_expense" domain="[('type','<>','view'),('type','<>','consolidation')]" attrs="{'readonly':[('purchase_ok','=',0)]}"/>
|
||||
<field name="supplier_taxes_id" colspan="2" attrs="{'readonly':[('purchase_ok','=',0)]}" widget="many2many_tags"/>
|
||||
<field name="property_account_expense" domain="[('type','<>','view'),('type','<>','consolidation')]" />
|
||||
<field name="supplier_taxes_id" colspan="2" widget="many2many_tags"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
|
|
|
@ -163,7 +163,7 @@
|
|||
<para style="terp_tblheader_Details_Right">[[ formatLang(sum_all(get_objects(data['form']['empty_acc']),data['form']['date1'],data['form']['date2'],'credit')) ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Right">[[ formatLang(sum_balance(get_objects(data['form']['empty_acc']),data['form']['date1'],data['form']['date2'])) ]] [[ company.currency_id.symbol]]</para>
|
||||
<para style="terp_tblheader_Details_Right">[[ formatLang(sum_balance(get_objects(data['form']['empty_acc']),data['form']['date1'],data['form']['date2']), currency_obj = company.currency_id)]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Right">[[ formatLang(sum_all(get_objects(data['form']['empty_acc']),data['form']['date1'],data['form']['date2'],'quantity')) ]]</para>
|
||||
|
@ -187,7 +187,7 @@
|
|||
<para style="terp_default_Right_9_Bold">[[ formatLang(move_sum(o['id'],data['form']['date1'],data['form']['date2'],'credit')) ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9_Bold">[[ formatLang(move_sum_balance(o['id'],data['form']['date1'],data['form']['date2'])) ]] [[ company.currency_id.symbol]]</para>
|
||||
<para style="terp_default_Right_9_Bold">[[ formatLang(move_sum_balance(o['id'],data['form']['date1'],data['form']['date2']), currency_obj = company.currency_id)]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9_Bold">[[ formatLang(move_sum(o['id'],data['form']['date1'],data['form']['date2'],'quantity')) ]]</para>
|
||||
|
@ -211,7 +211,7 @@
|
|||
<para style="terp_default_Right_9">[[ formatLang(move_g['credit']) ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(move_g['balance'])]] [[ company.currency_id.symbol ]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(move_g['balance'], currency_obj = company.currency_id) ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(move_g['quantity']) ]]</para>
|
||||
|
|
|
@ -224,7 +224,7 @@
|
|||
<para style="terp_Default_Bold_Right_9_U">[[ formatLang (sum_credit(objects,data['form']['date1'],data['form']['date2'])) ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_Default_Bold_Right_9_U">[[ formatLang (sum_balance(objects,data['form']['date1'],data['form']['date2'])) ]] [[ company.currency_id.symbol ]]</para>
|
||||
<para style="terp_Default_Bold_Right_9_U">[[ formatLang (sum_balance(objects,data['form']['date1'],data['form']['date2']), currency_obj = company.currency_id) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
@ -245,7 +245,7 @@
|
|||
<para style="terp_Default_Bold_Right_9_U">[[ formatLang (account_sum_credit(account,data['form']['date1'],data['form']['date2'])) ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_Default_Bold_Right_9_U">[[ formatLang (account_sum_balance(account,data['form']['date1'],data['form']['date2']))]] [[ company.currency_id.symbol ]]</para>
|
||||
<para style="terp_Default_Bold_Right_9_U">[[ formatLang (account_sum_balance(account,data['form']['date1'],data['form']['date2']), currency_obj = company.currency_id) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
@ -266,7 +266,7 @@
|
|||
<para style="terp_Default_Bold_Right_9_U">[[ formatLang( move_g['credit']) ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_Default_Bold_Right_9_U">[[ formatLang( move_g['balance']) ]] [[ company.currency_id.symbol ]]</para>
|
||||
<para style="terp_Default_Bold_Right_9_U">[[ formatLang( move_g['balance'], currency_obj = company.currency_id) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
@ -290,7 +290,7 @@
|
|||
<para style="terp_default_9_italic_Rignt">[[ formatLang( move_a['credit']) ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_9_italic_Rignt">[[ formatLang( move_a['balance']) ]] [[ company.currency_id.symbol]]</para>
|
||||
<para style="terp_default_9_italic_Rignt">[[ formatLang( move_a['balance'], currency_obj = company.currency_id)]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
|
|
@ -164,7 +164,7 @@
|
|||
<para style="terp_tblheader_Details_Right">[[ formatLang(sum_credit(objects,data['form']['date1'],data['form']['date2']))]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Right">[[ formatLang(sum_balance(objects,data['form']['date1'],data['form']['date2']))]] [[ company.currency_id.symbol]]</para>
|
||||
<para style="terp_tblheader_Details_Right">[[ formatLang(sum_balance(objects,data['form']['date1'],data['form']['date2']), currency_obj = company.currency_id)]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Right">[[ formatLang(sum_quantity(objects,data['form']['date1'],data['form']['date2'])) ]]</para>
|
||||
|
@ -188,7 +188,7 @@
|
|||
<para style="terp_tblheader_Details_Right">[[formatLang(move_g['credit'])]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Right">[[ formatLang(move_g['balance'])]] [[ company.currency_id.symbol]]</para>
|
||||
<para style="terp_tblheader_Details_Right">[[ formatLang(move_g['balance'], currency_obj = company.currency_id)]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Right">[[formatLang(move_g['quantity']) ]]</para>
|
||||
|
@ -212,7 +212,7 @@
|
|||
<para style="terp_default_Right_9">[[ formatLang(move_a['credit']) ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(move_a['balance']) ]] [[ company.currency_id.symbol]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(move_a['balance'], currency_obj = company.currency_id)]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(move_a['quantity']) ]]</para>
|
||||
|
|
|
@ -63,8 +63,12 @@ class account_analytic_journal_report(osv.osv_memory):
|
|||
if context is None:
|
||||
context = {}
|
||||
res = super(account_analytic_journal_report, self).default_get(cr, uid, fields, context=context)
|
||||
if not context.has_key('active_ids'):
|
||||
journal_ids = self.pool.get('account.analytic.journal').search(cr, uid, [], context=context)
|
||||
else:
|
||||
journal_ids = context.get('active_ids')
|
||||
if 'analytic_account_journal_id' in fields:
|
||||
res.update({'analytic_account_journal_id': context.get('active_ids',[])})
|
||||
res.update({'analytic_account_journal_id': journal_ids})
|
||||
return res
|
||||
|
||||
account_analytic_journal_report()
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<field name="name">analytic.entries.report.tree</field>
|
||||
<field name="model">analytic.entries.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Analytic Entries Analysis">
|
||||
<tree string="Analytic Entries Analysis" create="false">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="year" invisible="1"/>
|
||||
<field name="day" invisible="1"/>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<field name="name">account.entries.report.tree</field>
|
||||
<field name="model">account.entries.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:move_state == 'draft';black:move_state == 'posted'" string="Entries Analysis">
|
||||
<tree colors="blue:move_state == 'draft';black:move_state == 'posted'" create="false" string="Entries Analysis">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="date_created" invisible="1"/>
|
||||
<field name="date_maturity" invisible="1"/>
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
##############################################################################
|
||||
|
||||
import tools
|
||||
import decimal_precision as dp
|
||||
from osv import fields,osv
|
||||
|
||||
class account_invoice_report(osv.osv):
|
||||
|
@ -27,6 +28,31 @@ class account_invoice_report(osv.osv):
|
|||
_description = "Invoices Statistics"
|
||||
_auto = False
|
||||
_rec_name = 'date'
|
||||
|
||||
def _compute_amounts_in_user_currency(self, cr, uid, ids, field_names, args, context=None):
|
||||
"""Compute the amounts in the currency of the user
|
||||
"""
|
||||
if context is None:
|
||||
context={}
|
||||
currency_obj = self.pool.get('res.currency')
|
||||
currency_rate_obj = self.pool.get('res.currency.rate')
|
||||
user_currency_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
|
||||
currency_rate_id = currency_rate_obj.search(cr, uid, [('rate', '=', 1)], limit=1, context=context)[0]
|
||||
base_currency_id = currency_rate_obj.browse(cr, uid, currency_rate_id, context=context).currency_id.id
|
||||
res = {}
|
||||
ctx = context.copy()
|
||||
for item in self.browse(cr, uid, ids, context=context):
|
||||
ctx['date'] = item.date
|
||||
price_total = currency_obj.compute(cr, uid, base_currency_id, user_currency_id, item.price_total, context=ctx)
|
||||
price_average = currency_obj.compute(cr, uid, base_currency_id, user_currency_id, item.price_average, context=ctx)
|
||||
residual = currency_obj.compute(cr, uid, base_currency_id, user_currency_id, item.residual, context=ctx)
|
||||
res[item.id] = {
|
||||
'user_currency_price_total': price_total,
|
||||
'user_currency_price_average': price_average,
|
||||
'user_currency_residual': residual,
|
||||
}
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'date': fields.date('Date', readonly=True),
|
||||
'year': fields.char('Year', size=4, readonly=True),
|
||||
|
@ -47,7 +73,9 @@ class account_invoice_report(osv.osv):
|
|||
'company_id': fields.many2one('res.company', 'Company', readonly=True),
|
||||
'user_id': fields.many2one('res.users', 'Salesperson', readonly=True),
|
||||
'price_total': fields.float('Total Without Tax', readonly=True),
|
||||
'user_currency_price_total': fields.function(_compute_amounts_in_user_currency, string="Total Without Tax", type='float', digits_compute=dp.get_precision('Account'), multi="_compute_amounts"),
|
||||
'price_average': fields.float('Average Price', readonly=True, group_operator="avg"),
|
||||
'user_currency_price_average': fields.function(_compute_amounts_in_user_currency, string="Average Price", type='float', digits_compute=dp.get_precision('Account'), multi="_compute_amounts"),
|
||||
'currency_rate': fields.float('Currency Rate', readonly=True),
|
||||
'nbr':fields.integer('# of Lines', readonly=True),
|
||||
'type': fields.selection([
|
||||
|
@ -69,6 +97,7 @@ class account_invoice_report(osv.osv):
|
|||
'account_line_id': fields.many2one('account.account', 'Account Line',readonly=True),
|
||||
'partner_bank_id': fields.many2one('res.partner.bank', 'Bank Account',readonly=True),
|
||||
'residual': fields.float('Total Residual', readonly=True),
|
||||
'user_currency_residual': fields.function(_compute_amounts_in_user_currency, string="Total Residual", type='float', digits_compute=dp.get_precision('Account'), multi="_compute_amounts"),
|
||||
'delay_to_pay': fields.float('Avg. Delay To Pay', readonly=True, group_operator="avg"),
|
||||
'due_delay': fields.float('Avg. Due Delay', readonly=True, group_operator="avg"),
|
||||
}
|
||||
|
@ -161,7 +190,7 @@ class account_invoice_report(osv.osv):
|
|||
left join product_uom u on (u.id=ail.uos_id),
|
||||
res_currency_rate cr
|
||||
where cr.id in (select id from res_currency_rate cr2 where (cr2.currency_id = ai.currency_id)
|
||||
and ((ai.date_invoice is not null and cr.name <= ai.date_invoice) or (ai.date_invoice is null and cr.name <= NOW())) limit 1)
|
||||
and ((ai.date_invoice is not null and cr.name <= ai.date_invoice) or (ai.date_invoice is null and cr.name <= NOW())) order by name desc limit 1)
|
||||
group by ail.product_id,
|
||||
ai.date_invoice,
|
||||
ai.id,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<field name="name">account.invoice.report.tree</field>
|
||||
<field name="model">account.invoice.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state == 'draft';gray:state in ('cancel','paid');black:state in ('proforma','proforma2')" string="Invoices Analysis">
|
||||
<tree colors="blue:state == 'draft';gray:state in ('cancel','paid');black:state in ('proforma','proforma2')" create="false" string="Invoices Analysis">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="year" invisible="1"/>
|
||||
|
@ -28,8 +28,8 @@
|
|||
<field name="nbr" sum="# of Lines"/>
|
||||
<field name="product_qty" sum="Qty"/>
|
||||
<!-- <field name="reconciled" sum="# Reconciled"/> -->
|
||||
<field name="price_total" sum="Total Without Tax"/>
|
||||
<field name="residual" sum="Total Residual" invisible="context.get('residual_invisible',False)"/>
|
||||
<field name="user_currency_price_total" sum="Total Without Tax"/>
|
||||
<field name="user_currency_residual" sum="Total Residual" invisible="context.get('residual_invisible',False)"/>
|
||||
<field name="due_delay" sum="Avg. Due Delay" invisible="context.get('residual_invisible',False)"/>
|
||||
<field name="delay_to_pay" sum="Avg. Delay To Pay" invisible="context.get('residual_invisible',False)"/>
|
||||
</tree>
|
||||
|
@ -42,7 +42,7 @@
|
|||
<field name="arch" type="xml">
|
||||
<graph string="Invoices Analysis" type="bar">
|
||||
<field name="product_id"/>
|
||||
<field name="price_total"/>
|
||||
<field name="user_currency_price_total"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -29,34 +29,11 @@ class Overdue(report_sxw.rml_parse):
|
|||
super(Overdue, self).__init__(cr, uid, name, context=context)
|
||||
self.localcontext.update( {
|
||||
'time': time,
|
||||
'adr_get': self._adr_get,
|
||||
'getLines': self._lines_get,
|
||||
'tel_get': self._tel_get,
|
||||
'message': self._message,
|
||||
})
|
||||
self.context = context
|
||||
def _adr_get(self, partner, type):
|
||||
res = []
|
||||
res_partner = pooler.get_pool(self.cr.dbname).get('res.partner')
|
||||
addresses = res_partner.address_get(self.cr, self.uid, [partner.id], [type])
|
||||
adr_id = addresses and addresses[type] or False
|
||||
result = {
|
||||
'name': False,
|
||||
'street': False,
|
||||
'street2': False,
|
||||
'city': False,
|
||||
'zip': False,
|
||||
'state_id':False,
|
||||
'country_id': False,
|
||||
}
|
||||
if adr_id:
|
||||
result = res_partner.read(self.cr, self.uid, [adr_id], context=self.context.copy())
|
||||
result[0]['country_id'] = result[0]['country_id'] and result[0]['country_id'][1] or False
|
||||
result[0]['state_id'] = result[0]['state_id'] and result[0]['state_id'][1] or False
|
||||
return result
|
||||
|
||||
res.append(result)
|
||||
return res
|
||||
|
||||
def _tel_get(self,partner):
|
||||
if not partner:
|
||||
|
|
|
@ -126,15 +126,10 @@
|
|||
<blockTable colWidths="286.0,224.0" style="Tableau2">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_default_9">[[ repeatIn(adr_get(o, 'invoice'),'addr') ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_9">[[ o.title.name or '' ]] [[ o.name ]]</para>
|
||||
<para style="terp_default_9">[[ addr['street'] ]]</para>
|
||||
<para style="terp_default_9">[[ addr['street2'] or removeParentNode('para') ]]</para>
|
||||
<para style="terp_default_9">[[ addr['zip'] ]] [[ addr['city'] ]]</para>
|
||||
<para style="terp_default_9">[[ addr['state_id'] or removeParentNode('para')]]</para>
|
||||
<para style="terp_default_9">[[ addr['country_id'] ]]</para>
|
||||
<para style="terp_default_9">[[ display_address(o.partner_id) ]]</para>
|
||||
<para style="terp_default_9">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
|
@ -216,7 +211,7 @@
|
|||
<para style="terp_default_Right_9">[[ (line['account_id']['type'] == 'receivable' and formatLang(line['credit']) or 0) or (line['account_id']['type'] == 'payable' and formatLang(line['debit'] * -1) or 0) ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ time.strftime('%Y-%m-%d') > formatLang((line['date_maturity'])) and formatLang(line['debit'] - line['credit']) ]] [[ company.currency_id.symbol ]]</para>
|
||||
<para style="terp_default_Right_9">[[ time.strftime('%Y-%m-%d') > formatLang((line['date_maturity'])) and formatLang(line['debit'] - line['credit'], currency_obj = company.currency_id) ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Centre_9">[[ line['blocked'] and 'X' or '' ]]</para>
|
||||
|
@ -241,7 +236,7 @@
|
|||
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x, y: x + ((y['account_id']['type'] == 'receivable' and y['credit'] or 0) or (y['account_id']['type'] == 'payable' and y['debit'] * -1 or 0)), getLines(o), 0))) ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x, y: x + (y['debit'] - y['credit']), filter(lambda x: x['date_maturity'] < time.strftime('%Y-%m-%d'), getLines(o)), 0))) ]] [[ company.currency_id.symbol ]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x, y: x + (y['debit'] - y['credit']), filter(lambda x: x['date_maturity'] < time.strftime('%Y-%m-%d'), getLines(o)), 0)), currency_obj=company.currency_id) ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_9">
|
||||
|
@ -261,7 +256,7 @@
|
|||
<para style="terp_default_Bold_9">Balance :</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Right">[[ formatLang((reduce(lambda x, y: x +(y['debit'] - y['credit']), getLines(o), 0))) ]] [[ company.currency_id.symbol ]]</para>
|
||||
<para style="terp_tblheader_Details_Right">[[ formatLang((reduce(lambda x, y: x +(y['debit'] - y['credit']), getLines(o), 0)), currency_obj = company.currency_id) ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_8">
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<field name="name">account.treasury.report.tree</field>
|
||||
<field name="model">account.treasury.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Treasury Analysis">
|
||||
<tree string="Treasury Analysis" create="false">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="fiscalyear_id"/>
|
||||
<field name="period_id"/>
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
</div>
|
||||
<label for="id" string="Features"/>
|
||||
<div>
|
||||
<div>
|
||||
<div name="group_multi_currency">
|
||||
<field name="group_multi_currency" class="oe_inline"/>
|
||||
<label for="group_multi_currency"/>
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,7 @@ openerp.account = function (instance) {
|
|||
|
||||
instance.web.account = {};
|
||||
|
||||
instance.web.views.add('account_reconciliation_list', 'instance.web.account.ReconciliationListView');
|
||||
instance.web.views.add('tree_account_reconciliation', 'instance.web.account.ReconciliationListView');
|
||||
instance.web.account.ReconciliationListView = instance.web.ListView.extend({
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
|
@ -101,7 +101,7 @@ openerp.account = function (instance) {
|
|||
return self.rpc("/web/action/load", {
|
||||
action_id: result[1],
|
||||
context: additional_context
|
||||
}, function (result) {
|
||||
}).then(function (result) {
|
||||
result = result.result;
|
||||
result.context = _.extend(result.context || {}, additional_context);
|
||||
result.flags = result.flags || {};
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
|
||||
"PO-Revision-Date: 2012-02-08 08:45+0000\n"
|
||||
"PO-Revision-Date: 2012-10-12 23:19+0000\n"
|
||||
"Last-Translator: Ferdinand @ Camptocamp <Unknown>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 06:19+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-14 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16137)\n"
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: view:analytic.plan.create.model:0
|
||||
|
@ -471,7 +471,7 @@ msgstr "Analyt. Verrechnungsvorlage"
|
|||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,code:0
|
||||
msgid "Distribution Code"
|
||||
msgstr "Kurzbezeichnung"
|
||||
msgstr "Verteilungs-Schlüssel"
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: report:account.analytic.account.crossovered.analytic:0
|
||||
|
@ -526,6 +526,8 @@ msgid ""
|
|||
"analytic accounts for each plan set. Then, you must attach a plan set to "
|
||||
"your account journals."
|
||||
msgstr ""
|
||||
"Für jede Kostenrechnung muss ein Stammkonto definiert werden. Dann muss ein "
|
||||
"Plan definiert werden"
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: constraint:account.move.line:0
|
||||
|
|
|
@ -106,27 +106,27 @@
|
|||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="General">
|
||||
<group>
|
||||
<group>
|
||||
<field name="purchase_value"/>
|
||||
<field name="salvage_value"/>
|
||||
<field name="value_residual"/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="purchase_value" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="salvage_value" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="value_residual" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="partner_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="method"/>
|
||||
<field name="method_progress_factor" attrs="{'invisible':[('method','=','linear')], 'required':[('method','=','degressive')]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="method"/>
|
||||
<field name="method_progress_factor" attrs="{'invisible':[('method','=','linear')], 'required':[('method','=','degressive')]}"/>
|
||||
<label for="method_time"/>
|
||||
<div>
|
||||
<field name="method_time" on_change="onchange_method_time(method_time)" class="oe_inline"/>
|
||||
<button name="%(action_asset_modify)d" states="open" string="Change Duration" type="action" icon="terp-stock_effects-object-colorize" class="oe_inline" colspan="1"/>
|
||||
<field name="method_time" on_change="onchange_method_time(method_time)" class="oe_inline"/>
|
||||
<button name="%(action_asset_modify)d" states="open" string="Change Duration" type="action" icon="terp-stock_effects-object-colorize" class="oe_inline" colspan="1"/>
|
||||
</div>
|
||||
<field name="prorata" attrs="{'invisible': [('method_time','=','end')]}"/>
|
||||
<field name="method_number" attrs="{'invisible':[('method_time','=','end')], 'required':[('method_time','=','number')]}"/>
|
||||
<field name="method_period"/>
|
||||
<field name="method_end" attrs="{'required': [('method_time','=','end')], 'invisible':[('method_time','=','number')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="prorata" attrs="{'invisible': [('method_time','=','end')]}"/>
|
||||
<field name="method_number" attrs="{'invisible':[('method_time','=','end')], 'required':[('method_time','=','number')]}"/>
|
||||
<field name="method_period"/>
|
||||
<field name="method_end" attrs="{'required': [('method_time','=','end')], 'invisible':[('method_time','=','number')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Depreciation Board">
|
||||
<field name="depreciation_line_ids" mode="tree">
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<field name="name">asset.asset.report.tree</field>
|
||||
<field name="model">asset.asset.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Assets">
|
||||
<tree string="Assets" create="false">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="asset_id" invisible="1"/>
|
||||
<field name="asset_category_id" invisible="1"/>
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
<field name="view_id" ref="view_bank_statement_line_list"/>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_bank_statement_line" id="bank_statement_line" parent="account.menu_finance_bank_and_cash" sequence="20"/>
|
||||
<menuitem action="action_bank_statement_line" id="bank_statement_line" parent="account.menu_finance_bank_and_cash" sequence="20" groups="base.group_no_one"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
<?xml version="1.0" ?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- budget form and tree view from account module *********************************** -->
|
||||
<record id="action_account_budget_post_tree" model="ir.actions.act_window">
|
||||
<field name="name">Budgets</field>
|
||||
<field name="res_model">account.budget.post</field>
|
||||
<field name="view_type">tree</field>
|
||||
</record>
|
||||
<menuitem action="action_account_budget_post_tree" id="menu_action_account_budget_post_tree" parent="account.menu_finance_generic_reporting" sequence="6"/>
|
||||
|
||||
<menuitem name="Budgets" id="menu_action_account_budget_post_tree" parent="account.menu_finance_generic_reporting" sequence="6"/>
|
||||
|
||||
<!--
|
||||
Budgets
|
||||
|
|
|
@ -32,7 +32,6 @@ class report_print_check(report_sxw.rml_parse):
|
|||
'time': time,
|
||||
'get_lines': self.get_lines,
|
||||
'fill_stars' : self.fill_stars,
|
||||
'get_zip_line': self.get_zip_line,
|
||||
})
|
||||
def fill_stars(self, amount):
|
||||
amount = amount.replace('Dollars','')
|
||||
|
@ -41,25 +40,6 @@ class report_print_check(report_sxw.rml_parse):
|
|||
return ' '.join([amount,'*'*stars])
|
||||
|
||||
else: return amount
|
||||
|
||||
def get_zip_line(self, address):
|
||||
'''
|
||||
Get the address line
|
||||
'''
|
||||
ret = ''
|
||||
if address:
|
||||
if address.city:
|
||||
ret += address.city
|
||||
if address.state_id:
|
||||
if address.state_id.name:
|
||||
if ret:
|
||||
ret += ', '
|
||||
ret += address.state_id.name
|
||||
if address.zip:
|
||||
if ret:
|
||||
ret += ' '
|
||||
ret += address.zip
|
||||
return ret
|
||||
|
||||
def get_lines(self, voucher_lines):
|
||||
result = []
|
||||
|
|
|
@ -281,10 +281,7 @@
|
|||
</td>
|
||||
<td>
|
||||
<para style="P15">[[ voucher.partner_id.name ]]</para>
|
||||
<para style="P15">[[ voucher.partner_id.street or removeParentNode('para') ]]</para>
|
||||
<para style="P15">[[ voucher.partner_id.street2 or removeParentNode('para') ]]</para>
|
||||
<para style="P15">[[ get_zip_line(voucher.partner_id) ]] </para>
|
||||
<para style="P15">[[ voucher.partner_id.country_id.name]]</para>
|
||||
<para style="P15">[[ display_address(voucher.partner_id) or removeParentNode('para') ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
|
|
@ -237,10 +237,7 @@
|
|||
</td>
|
||||
<td>
|
||||
<para style="P15">[[ voucher.partner_id.name ]]</para>
|
||||
<para style="P15">[[ voucher.partner_id.street or removeParentNode('para') ]]</para>
|
||||
<para style="P15">[[ voucher.partner_id.street2 or removeParentNode('para') ]]</para>
|
||||
<para style="P15">[[ get_zip_line(voucher.partner_id) ]] </para>
|
||||
<para style="P15">[[ voucher.partner_id.country_id.name]]</para>
|
||||
<para style="P15">[[ display_address(voucher.partner_id) or removeParentNode('para') ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
|
|
@ -153,9 +153,7 @@
|
|||
</td>
|
||||
<td>
|
||||
<para style="P9">[[ voucher.partner_id.name ]] </para>
|
||||
<para style="P15">[[ voucher.partner_id.street2 or removeParentNode('para') ]]</para>
|
||||
<para style="P15">[[ get_zip_line(voucher.partner_id) ]] </para>
|
||||
<para style="P15">[[ voucher.partner_id.country_id.name]]</para>
|
||||
<para style="P15">[[ display_address(voucher.partner_id) or removeParentNode('para') ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para/>
|
||||
|
|
|
@ -30,7 +30,6 @@ class report_rappel(report_sxw.rml_parse):
|
|||
self.localcontext.update({
|
||||
'time': time,
|
||||
'ids_to_objects': self._ids_to_objects,
|
||||
'adr_get': self._adr_get,
|
||||
'getLines': self._lines_get,
|
||||
'get_text': self._get_text
|
||||
})
|
||||
|
@ -43,11 +42,6 @@ class report_rappel(report_sxw.rml_parse):
|
|||
all_lines.append(line)
|
||||
return all_lines
|
||||
|
||||
def _adr_get(self, stat_line, type):
|
||||
res_partner = pooler.get_pool(self.cr.dbname).get('res.partner')
|
||||
adr = res_partner.address_get(self.cr, self.uid, [stat_line.partner_id.id], [type])[type]
|
||||
return adr and res_partner.read(self.cr, self.uid, [adr]) or [{}]
|
||||
|
||||
def _lines_get(self, stat_by_partner_line):
|
||||
pool = pooler.get_pool(self.cr.dbname)
|
||||
moveline_obj = pool.get('account.move.line')
|
||||
|
|
|
@ -129,15 +129,10 @@
|
|||
<blockTable colWidths="298.0,234.0" style="Tableau2">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_default_9">[[ repeatIn(adr_get(o,'invoice'),'a' )]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_9">[[ o.partner_id.name or '' ]]</para>
|
||||
<para style="terp_default_9">[[ a['street'] or '']]</para>
|
||||
<para style="terp_default_9">[[ a['street2'] or removeParentNode('para') ]]</para>
|
||||
<para style="terp_default_9">[[ a['zip'] or '' ]] [[ a['city'] or '' ]]</para>
|
||||
<para style="terp_default_9">[[( a['state_id'] and a['state_id'][1]) or removeParentNode('para') ]]</para>
|
||||
<para style="terp_default_9">[[( a['country_id'] and a['country_id'][1]) or '']]</para>
|
||||
<para style="terp_default_9">[[ display_address(o.partner_id) or '']]</para>
|
||||
<para style="terp_default_9">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
|
|
|
@ -256,10 +256,10 @@
|
|||
<para style="terp_default_Centre_9">[[line.date=='False' and '-' or formatLang(line.date,date=True) ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[formatLang(line.amount) or '-' ]] [[get_company_currency_symbol()]] </para>
|
||||
<para style="terp_default_Right_9">[[formatLang(line.amount, currency_obj= user.company_id.currency_id) or '-' ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(line.amount_currency) ]] [[ line.currency.symbol]] </para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(line.amount_currency, currency_obj= line.currency)]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
@ -275,10 +275,10 @@
|
|||
<para style="terp_default_Bold_9">Total:</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(get_amount_total(o)) or '' ]] [[get_company_currency_symbol()]] </para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(get_amount_total(o), currency_obj= user.company_id.currency_id) or '' ]] </para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(get_amount_total_in_currency(o)) or '' ]] [[get_company_currency_symbol()]] </para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(get_amount_total_in_currency(o), currency_obj= user.company_id.currency_id) or '' ]] </para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
|
|
@ -32,7 +32,6 @@ class payment_order(report_sxw.rml_parse):
|
|||
'time': time,
|
||||
'get_invoice_name': self._get_invoice_name,
|
||||
'get_company_currency': self._get_company_currency,
|
||||
'get_company_currency_symbol': self._get_company_currency_symbol,
|
||||
'get_amount_total_in_currency': self._get_amount_total_in_currency,
|
||||
'get_amount_total': self._get_amount_total,
|
||||
'get_account_name': self._get_account_name,
|
||||
|
@ -72,12 +71,8 @@ class payment_order(report_sxw.rml_parse):
|
|||
user = pool.get('res.users').browse(self.cr, self.uid, self.uid)
|
||||
return user.company_id and user.company_id.currency_id and user.company_id.currency_id.symbol or False
|
||||
|
||||
def _get_company_currency_symbol(self):
|
||||
pool = pooler.get_pool(self.cr.dbname)
|
||||
user = pool.get('res.users').browse(self.cr, self.uid, self.uid)
|
||||
return user.company_id and user.company_id.currency_id and user.company_id.currency_id.symbol or False
|
||||
|
||||
def _get_account_name(self, bank_id):
|
||||
def _get_account_name(self,bank_id):
|
||||
if bank_id:
|
||||
pool = pooler.get_pool(self.cr.dbname)
|
||||
value_name = pool.get('res.partner.bank').name_get(self.cr, self.uid, [bank_id])
|
||||
|
|
|
@ -42,6 +42,21 @@ class res_company(osv.osv):
|
|||
|
||||
res_company()
|
||||
|
||||
class account_config_settings(osv.osv_memory):
|
||||
_inherit = 'account.config.settings'
|
||||
_columns = {
|
||||
'income_currency_exchange_account_id': fields.related(
|
||||
'company_id', 'income_currency_exchange_account_id',
|
||||
type='many2one',
|
||||
relation='account.account',
|
||||
string="Gain Exchange Rate Account"),
|
||||
'expense_currency_exchange_account_id': fields.related(
|
||||
'company_id', 'expense_currency_exchange_account_id',
|
||||
type="many2one",
|
||||
relation='account.account',
|
||||
string="Loss Exchange Rate Account"),
|
||||
}
|
||||
|
||||
class account_voucher(osv.osv):
|
||||
def _check_paid(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
|
@ -1070,7 +1085,8 @@ class account_voucher(osv.osv):
|
|||
if line.amount == line.amount_unreconciled:
|
||||
if not line.move_line_id.amount_residual:
|
||||
raise osv.except_osv(_('Wrong bank statement line'),_("You have to delete the bank statement line which the payment was reconciled to manually. Please check the payment of the partner %s by the amount of %s.")%(line.voucher_id.partner_id.name, line.voucher_id.amount))
|
||||
currency_rate_difference = line.move_line_id.amount_residual - amount
|
||||
sign = voucher_brw.type in ('payment', 'purchase') and -1 or 1
|
||||
currency_rate_difference = sign * (line.move_line_id.amount_residual - amount)
|
||||
else:
|
||||
currency_rate_difference = 0.0
|
||||
move_line = {
|
||||
|
|
|
@ -249,16 +249,23 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<!-- res.company form view -->
|
||||
<record model="ir.ui.view" id="view_company_inherit_currency_xchange_form">
|
||||
<field name="name">res.company.form.inherit</field>
|
||||
<field name="inherit_id" ref="base.view_company_form"/>
|
||||
<field name="model">res.company</field>
|
||||
<!-- res.config form view -->
|
||||
<record model="ir.ui.view" id="view_account_settings_currency_xchange_form">
|
||||
<field name="name">account.config.settings.inherit</field>
|
||||
<field name="inherit_id" ref="account.view_account_config_settings"/>
|
||||
<field name="model">account.config.settings</field>
|
||||
<field name="priority">20</field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="currency_id" position="after">
|
||||
<field name="income_currency_exchange_account_id"/>
|
||||
<field name="expense_currency_exchange_account_id"/>
|
||||
</field>
|
||||
<xpath expr="//div[@name='group_multi_currency']" position="after">
|
||||
<group attrs="{'invisible': [('group_multi_currency', '<>', True)]}" col="2">
|
||||
<group>
|
||||
<field name="income_currency_exchange_account_id"/>
|
||||
<field name="expense_currency_exchange_account_id"/>
|
||||
</group>
|
||||
<group>
|
||||
</group>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@
|
|||
<para style="terp_default_9_30cm">[[ p['pname'] ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ p['amount'] ]] [[ voucher.currency_id.symbol ]]</para>
|
||||
<para style="terp_default_Right_9">[[ formatLang(p['amount'], currency_obj=voucher.currency_id) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -323,7 +323,7 @@
|
|||
</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9_Bold">[[ voucher.amount ]] [[ voucher.currency_id.symbol ]]</para>
|
||||
<para style="terp_default_Right_9_Bold">[[ formatLang(voucher.amount, currency_obj=voucher.currency_id) ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<field name="name">sale.receipt.report.tree</field>
|
||||
<field name="model">sale.receipt.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state == 'draft';gray:state in ('cancel','paid');black:state in ('proforma','proforma2')" string="Sales Receipt Analysis">
|
||||
<tree colors="blue:state == 'draft';gray:state in ('cancel','paid');black:state in ('proforma','proforma2')" create="false" string="Sales Receipt Analysis">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="year" invisible="1"/>
|
||||
|
|
|
@ -136,11 +136,8 @@
|
|||
<group>
|
||||
<group>
|
||||
<field name="partner_id" required="1" invisible="context.get('line_type', False)" on_change="onchange_partner_id(partner_id, journal_id, amount, currency_id, type, date, context)" context="{'invoice_currency':currency_id, 'default_customer': 0, 'search_default_supplier': 1, 'default_supplier': 1}" string="Supplier"/>
|
||||
<label for="amount" string="Amount"/>
|
||||
<div>
|
||||
<field name="amount" invisible="context.get('line_type', False)" on_change="onchange_amount(amount, payment_rate, partner_id, journal_id, currency_id, type, date, payment_rate_currency_id, company_id, context)" class="oe_inline"/>
|
||||
<field name="currency_id" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="amount" invisible="context.get('line_type', False)" on_change="onchange_amount(amount, payment_rate, partner_id, journal_id, currency_id, type, date, payment_rate_currency_id, company_id, context)" class="oe_inline" widget='monetary' options='{"currency_field": "currency_id"}'/>
|
||||
<field name="journal_id"
|
||||
domain="[('type','in',['bank', 'cash'])]"
|
||||
invisible="context.get('line_type', False)"
|
||||
|
@ -203,7 +200,7 @@
|
|||
</group>
|
||||
<group col="2">
|
||||
<separator string="Payment Options" colspan="2"/>
|
||||
<field name="writeoff_amount"/>
|
||||
<field name="writeoff_amount" widget='monetary' options='{"currency_field": "currency_id"}'/>
|
||||
<field name="payment_option" required="1"/>
|
||||
<field name="writeoff_acc_id"
|
||||
attrs="{'invisible':[('payment_option','!=','with_writeoff')], 'required':[('payment_option','=','with_writeoff')]}"
|
||||
|
@ -294,13 +291,12 @@
|
|||
<group>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="partner_id" required="1" on_change="onchange_partner_id(partner_id, journal_id, amount, currency_id, type, date, context)" string="Customer" context="{'search_default_customer': 1}"/>
|
||||
<label for="amount" string="Paid Amount"/>
|
||||
<div>
|
||||
<field name="amount" class="oe_inline"
|
||||
invisible="context.get('line_type', False)"
|
||||
on_change="onchange_amount(amount, payment_rate, partner_id, journal_id, currency_id, type, date, payment_rate_currency_id, company_id, context)"/>
|
||||
<field name="currency_id" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="amount" class="oe_inline"
|
||||
string="Paid Amount"
|
||||
widget='monetary' options='{"currency_field": "currency_id"}'
|
||||
invisible="context.get('line_type', False)"
|
||||
on_change="onchange_amount(amount, payment_rate, partner_id, journal_id, currency_id, type, date, payment_rate_currency_id, company_id, context)"/>
|
||||
<field name="journal_id"
|
||||
domain="[('type','in',['bank', 'cash'])]"
|
||||
invisible="context.get('line_type', False)"
|
||||
|
@ -323,7 +319,7 @@
|
|||
</group>
|
||||
<notebook invisible="1">
|
||||
<page string="Payment Information" groups="base.group_user">
|
||||
<label for="line_cr_ids"/>
|
||||
<label for="line_cr_ids"/>
|
||||
<field name="line_cr_ids" context="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, type, context)">
|
||||
<tree string="Invoices and outstanding transactions" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
|
@ -367,7 +363,7 @@
|
|||
<field name="paid_amount_in_company_currency" colspan="4" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="writeoff_amount"/>
|
||||
<field name="writeoff_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="payment_option" required="1"/>
|
||||
<field name="writeoff_acc_id"
|
||||
attrs="{'invisible':[('payment_option','!=','with_writeoff')], 'required':[('payment_option','=','with_writeoff')]}"
|
||||
|
@ -406,14 +402,12 @@
|
|||
<group>
|
||||
<group>
|
||||
<field name="partner_id" domain="[('customer','=',True)]" required="1" invisible="context.get('line_type', False)" on_change="onchange_partner_id(partner_id, journal_id, amount, currency_id, type, date, context)" string="Customer" context="{'search_default_customer': 1}"/>
|
||||
<label for="amount" string="Paid Amount"/>
|
||||
<div>
|
||||
<field name="amount" class="oe_inline"
|
||||
invisible="context.get('line_type', False)"
|
||||
on_change="onchange_amount(amount, payment_rate, partner_id, journal_id, currency_id, type, date, payment_rate_currency_id, company_id, context)"/>
|
||||
<field name="currency_id" class="oe_inline"/>
|
||||
</div>
|
||||
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="amount" class="oe_inline"
|
||||
string="Paid Amount"
|
||||
widget="monetary" options="{'currency_field': 'currency_id'}"
|
||||
invisible="context.get('line_type', False)"
|
||||
on_change="onchange_amount(amount, payment_rate, partner_id, journal_id, currency_id, type, date, payment_rate_currency_id, company_id, context)"/>
|
||||
<field name="journal_id"
|
||||
domain="[('type','in',['bank', 'cash'])]"
|
||||
invisible="context.get('line_type', False)"
|
||||
|
@ -436,7 +430,7 @@
|
|||
</group>
|
||||
<notebook>
|
||||
<page string="Payment Information" groups="base.group_user">
|
||||
<label for="line_cr_ids"/>
|
||||
<label for="line_cr_ids"/>
|
||||
<field name="line_cr_ids" context="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, type, context)">
|
||||
<tree string="Invoices and outstanding transactions" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
|
@ -480,7 +474,7 @@
|
|||
<field name="paid_amount_in_company_currency" colspan="4" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="writeoff_amount"/>
|
||||
<field name="writeoff_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="payment_option" required="1"/>
|
||||
<field name="writeoff_acc_id"
|
||||
attrs="{'invisible':[('payment_option','!=','with_writeoff')], 'required':[('payment_option','=','with_writeoff')]}"
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<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"/>
|
||||
</group>
|
||||
<group>
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
# Latvian translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
|
||||
"PO-Revision-Date: 2012-10-16 20:21+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Latvian <lv@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-17 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16152)\n"
|
||||
|
||||
#. module: anonymization
|
||||
#: model:ir.model,name:anonymization.model_ir_model_fields_anonymize_wizard
|
||||
msgid "ir.model.fields.anonymize.wizard"
|
||||
msgstr "ir.model.fields.anonymize.wizard"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymization,field_name:0
|
||||
msgid "Field Name"
|
||||
msgstr "Lauka Nosaukums"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymization,field_id:0
|
||||
msgid "Field"
|
||||
msgstr "Lauks"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymization.history,state:0
|
||||
#: field:ir.model.fields.anonymize.wizard,state:0
|
||||
msgid "State"
|
||||
msgstr "Stāvoklis"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymize.wizard,file_import:0
|
||||
msgid "Import"
|
||||
msgstr "Importēt"
|
||||
|
||||
#. module: anonymization
|
||||
#: model:ir.model,name:anonymization.model_ir_model_fields_anonymization
|
||||
msgid "ir.model.fields.anonymization"
|
||||
msgstr "ir.model.fields.anonymization"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymization.history,direction:0
|
||||
msgid "Direction"
|
||||
msgstr "Virziens"
|
||||
|
||||
#. module: anonymization
|
||||
#: model:ir.actions.act_window,name:anonymization.action_ir_model_fields_anonymization_tree
|
||||
#: view:ir.model.fields.anonymization:0
|
||||
#: model:ir.ui.menu,name:anonymization.menu_administration_anonymization_fields
|
||||
msgid "Anonymized Fields"
|
||||
msgstr "Anonimizēti Lauki"
|
||||
|
||||
#. module: anonymization
|
||||
#: model:ir.ui.menu,name:anonymization.menu_administration_anonymization
|
||||
msgid "Database anonymization"
|
||||
msgstr "Datubāzes anonimizācija"
|
||||
|
||||
#. module: anonymization
|
||||
#: selection:ir.model.fields.anonymization.history,direction:0
|
||||
msgid "clear -> anonymized"
|
||||
msgstr "tīrs -> anonimizēts"
|
||||
|
||||
#. module: anonymization
|
||||
#: selection:ir.model.fields.anonymization,state:0
|
||||
#: selection:ir.model.fields.anonymize.wizard,state:0
|
||||
msgid "Anonymized"
|
||||
msgstr "Anonimizēta"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymization,state:0
|
||||
msgid "unknown"
|
||||
msgstr "nezināms"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymization,model_id:0
|
||||
msgid "Object"
|
||||
msgstr "Objekts"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymization.history,filepath:0
|
||||
msgid "File path"
|
||||
msgstr "Ceļš uz failu"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymization.history,date:0
|
||||
msgid "Date"
|
||||
msgstr "Datums"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymize.wizard,file_export:0
|
||||
msgid "Export"
|
||||
msgstr "Eksportēt"
|
||||
|
||||
#. module: anonymization
|
||||
#: view:ir.model.fields.anonymize.wizard:0
|
||||
msgid "Reverse the Database Anonymization"
|
||||
msgstr "Atgriezt Datubāzes Anonimizāciju"
|
||||
|
||||
#. module: anonymization
|
||||
#: view:ir.model.fields.anonymize.wizard:0
|
||||
msgid "Database Anonymization"
|
||||
msgstr "Datubāzes Anonimizācija"
|
||||
|
||||
#. module: anonymization
|
||||
#: model:ir.ui.menu,name:anonymization.menu_administration_anonymization_wizard
|
||||
msgid "Anonymize database"
|
||||
msgstr "Anonimizēt datubāzi"
|
||||
|
||||
#. module: anonymization
|
||||
#: view:ir.model.fields.anonymization.history:0
|
||||
#: field:ir.model.fields.anonymization.history,field_ids:0
|
||||
msgid "Fields"
|
||||
msgstr "Lauki"
|
||||
|
||||
#. module: anonymization
|
||||
#: selection:ir.model.fields.anonymization,state:0
|
||||
#: selection:ir.model.fields.anonymize.wizard,state:0
|
||||
msgid "Clear"
|
||||
msgstr "Notīrīt"
|
||||
|
||||
#. module: anonymization
|
||||
#: view:ir.model.fields.anonymize.wizard:0
|
||||
#: field:ir.model.fields.anonymize.wizard,summary:0
|
||||
msgid "Summary"
|
||||
msgstr "Kopsavilkums"
|
||||
|
||||
#. module: anonymization
|
||||
#: view:ir.model.fields.anonymization:0
|
||||
msgid "Anonymized Field"
|
||||
msgstr "Anonimizēts lauks"
|
||||
|
||||
#. module: anonymization
|
||||
#: selection:ir.model.fields.anonymize.wizard,state:0
|
||||
msgid "Unstable"
|
||||
msgstr "Nestabīls"
|
||||
|
||||
#. module: anonymization
|
||||
#: selection:ir.model.fields.anonymization.history,state:0
|
||||
msgid "Exception occured"
|
||||
msgstr "Notikusī kļūda"
|
||||
|
||||
#. module: anonymization
|
||||
#: selection:ir.model.fields.anonymization,state:0
|
||||
#: selection:ir.model.fields.anonymize.wizard,state:0
|
||||
msgid "Not Existing"
|
||||
msgstr "Neeksistē"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymization,model_name:0
|
||||
msgid "Object Name"
|
||||
msgstr "Objekta nosaukums"
|
||||
|
||||
#. module: anonymization
|
||||
#: model:ir.actions.act_window,name:anonymization.action_ir_model_fields_anonymization_history_tree
|
||||
#: view:ir.model.fields.anonymization.history:0
|
||||
#: model:ir.ui.menu,name:anonymization.menu_administration_anonymization_history
|
||||
msgid "Anonymization History"
|
||||
msgstr "Anonimizācijas Vēsture"
|
||||
|
||||
#. module: anonymization
|
||||
#: model:ir.model,name:anonymization.model_ir_model_fields_anonymization_history
|
||||
msgid "ir.model.fields.anonymization.history"
|
||||
msgstr "ir.model.fields.anonymization.history"
|
||||
|
||||
#. module: anonymization
|
||||
#: model:ir.actions.act_window,name:anonymization.action_ir_model_fields_anonymize_wizard
|
||||
#: view:ir.model.fields.anonymize.wizard:0
|
||||
msgid "Anonymize Database"
|
||||
msgstr "Anonimizēt Datubāzi"
|
||||
|
||||
#. module: anonymization
|
||||
#: field:ir.model.fields.anonymize.wizard,name:0
|
||||
msgid "File Name"
|
||||
msgstr "Faila nosaukums"
|
||||
|
||||
#. module: anonymization
|
||||
#: selection:ir.model.fields.anonymization.history,direction:0
|
||||
msgid "anonymized -> clear"
|
||||
msgstr "anonimizēts -> tīrs"
|
||||
|
||||
#. module: anonymization
|
||||
#: selection:ir.model.fields.anonymization.history,state:0
|
||||
msgid "Started"
|
||||
msgstr "Iesākta"
|
||||
|
||||
#. module: anonymization
|
||||
#: selection:ir.model.fields.anonymization.history,state:0
|
||||
msgid "Done"
|
||||
msgstr "Izdarīts"
|
||||
|
||||
#. module: anonymization
|
||||
#: view:ir.model.fields.anonymization.history:0
|
||||
#: field:ir.model.fields.anonymization.history,msg:0
|
||||
#: field:ir.model.fields.anonymize.wizard,msg:0
|
||||
msgid "Message"
|
||||
msgstr "Ziņojums"
|
||||
|
||||
#. module: anonymization
|
||||
#: code:addons/anonymization/anonymization.py:55
|
||||
#: sql_constraint:ir.model.fields.anonymization:0
|
||||
#, python-format
|
||||
msgid "You cannot have two fields with the same name on the same object!"
|
||||
msgstr "Nevar būt divi lauki ar vienādiem nosaukumiem vienam objektam!"
|
|
@ -145,7 +145,7 @@
|
|||
<field name="name">audittrail.log.tree</field>
|
||||
<field name="model">audittrail.log</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="AuditTrail Logs">
|
||||
<tree string="AuditTrail Logs" create="false">
|
||||
<field name="timestamp"/>
|
||||
<field name="name"/>
|
||||
<field name="object_id"/>
|
||||
|
|
|
@ -4,28 +4,25 @@ import simplejson
|
|||
import werkzeug.urls
|
||||
import werkzeug.utils
|
||||
|
||||
import openerp.modules.registry
|
||||
import openerp.addons.web.controllers.main
|
||||
import openerp.addons.web.common.http as openerpweb
|
||||
from openerp import SUPERUSER_ID
|
||||
import openerp
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class OAuthController(openerpweb.Controller):
|
||||
class OAuthController(openerp.addons.web.http.Controller):
|
||||
_cp_path = '/auth_oauth'
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def list_providers(self, req, dbname):
|
||||
try:
|
||||
registry = openerp.modules.registry.RegistryManager.get(dbname)
|
||||
with registry.cursor() as cr:
|
||||
providers = registry.get('auth.oauth.provider')
|
||||
l = providers.read(cr, SUPERUSER_ID, providers.search(cr, SUPERUSER_ID, [('enabled','=',True)]))
|
||||
l = providers.read(cr, openerp.SUPERUSER_ID, providers.search(cr, openerp.SUPERUSER_ID, [('enabled','=',True)]))
|
||||
except Exception:
|
||||
l = []
|
||||
return l
|
||||
|
||||
@openerpweb.httprequest
|
||||
@openerp.addons.web.http.httprequest
|
||||
def signin(self, req, **kw):
|
||||
state = simplejson.loads(kw['state'])
|
||||
dbname = state['d']
|
||||
|
@ -34,7 +31,7 @@ class OAuthController(openerpweb.Controller):
|
|||
with registry.cursor() as cr:
|
||||
try:
|
||||
u = registry.get('res.users')
|
||||
credentials = u.auth_oauth(cr, SUPERUSER_ID, provider, kw)
|
||||
credentials = u.auth_oauth(cr, openerp.SUPERUSER_ID, provider, kw)
|
||||
cr.commit()
|
||||
return openerp.addons.web.controllers.main.login_and_redirect(req, *credentials)
|
||||
except AttributeError:
|
||||
|
@ -43,7 +40,7 @@ class OAuthController(openerpweb.Controller):
|
|||
url = "/#action=login&oauth_error=1"
|
||||
except Exception,e:
|
||||
# signup error
|
||||
_logger.exception('oops')
|
||||
_logger.exception("OAuth2: %s" % str(e))
|
||||
url = "/#action=login&oauth_error=2"
|
||||
return openerp.addons.web.controllers.main.set_cookie_and_redirect(req, url)
|
||||
|
||||
|
|
|
@ -15,13 +15,17 @@ class res_users(osv.Model):
|
|||
_inherit = 'res.users'
|
||||
|
||||
_columns = {
|
||||
'oauth_provider_id': fields.many2one('auth.oauth.provider','OAuth Provider'),
|
||||
'oauth_provider_id': fields.many2one('auth.oauth.provider', 'OAuth Provider'),
|
||||
'oauth_uid': fields.char('OAuth User ID', help="Oauth Provider user_id"),
|
||||
'oauth_access_token': fields.char('OAuth Token', readonly=True),
|
||||
'oauth_access_token': fields.char('OAuth Access Token', readonly=True),
|
||||
}
|
||||
|
||||
_sql_constraints = [
|
||||
('uniq_users_oauth_provider_oauth_uid', 'unique(oauth_provider_id, oauth_uid)', 'OAuth UID must be unique per provider'),
|
||||
]
|
||||
|
||||
def auth_oauth_rpc(self, cr, uid, endpoint, access_token, context=None):
|
||||
params = urllib.urlencode({ 'access_token': access_token })
|
||||
params = urllib.urlencode({'access_token': access_token})
|
||||
if urlparse.urlparse(endpoint)[4]:
|
||||
url = endpoint + '&' + params
|
||||
else:
|
||||
|
@ -41,22 +45,26 @@ class res_users(osv.Model):
|
|||
|
||||
validation = self.auth_oauth_rpc(cr, uid, p.validation_endpoint, access_token)
|
||||
if validation.get("error"):
|
||||
raise openerp.exceptions.AccessDenied
|
||||
raise Exception(validation['error'])
|
||||
if p.data_endpoint:
|
||||
data = self.auth_oauth_rpc(cr, uid, p.data_endpoint, access_token)
|
||||
validation.update(data)
|
||||
# required
|
||||
oauth_uid = validation['user_id']
|
||||
if not oauth_uid:
|
||||
raise openerp.exceptions.AccessDenied
|
||||
raise openerp.exceptions.AccessDenied()
|
||||
email = validation.get('email', 'provider_%d_user_%d' % (p.id, oauth_uid))
|
||||
# optional
|
||||
name = validation.get('name', email)
|
||||
res = self.search(cr, uid, [("oauth_uid", "=", oauth_uid)])
|
||||
res = self.search(cr, uid, [("oauth_uid", "=", oauth_uid), ('oauth_provider_id', '=', provider)])
|
||||
if res:
|
||||
self.write(cr, uid, res[0], { 'oauth_access_token': access_token })
|
||||
assert len(res) == 1
|
||||
self.write(cr, uid, res[0], {'oauth_access_token': access_token})
|
||||
else:
|
||||
# New user
|
||||
# New user if signup module available
|
||||
if not hasattr(self, '_signup_create_user'):
|
||||
raise openerp.exceptions.AccessDenied()
|
||||
|
||||
new_user = {
|
||||
'name': name,
|
||||
'login': email,
|
||||
|
@ -66,7 +74,9 @@ class res_users(osv.Model):
|
|||
'oauth_access_token': access_token,
|
||||
'active': True,
|
||||
}
|
||||
self.auth_signup_create(cr, uid, new_user)
|
||||
# TODO pass signup token to allow attach new user to right partner
|
||||
self._signup_create_user(cr, uid, new_user)
|
||||
|
||||
credentials = (cr.dbname, email, access_token)
|
||||
return credentials
|
||||
|
||||
|
@ -74,7 +84,7 @@ class res_users(osv.Model):
|
|||
try:
|
||||
return super(res_users, self).check_credentials(cr, uid, password)
|
||||
except openerp.exceptions.AccessDenied:
|
||||
res = self.search(cr, SUPERUSER_ID, [('id','=',uid),('oauth_access_token','=',password)])
|
||||
res = self.search(cr, SUPERUSER_ID, [('id', '=', uid), ('oauth_access_token', '=', password)])
|
||||
if not res:
|
||||
raise
|
||||
|
||||
|
|
|
@ -23,24 +23,21 @@ import logging
|
|||
import os
|
||||
import tempfile
|
||||
import urllib
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
import werkzeug.urls
|
||||
import werkzeug.exceptions
|
||||
|
||||
from openerp.modules.registry import RegistryManager
|
||||
from openerp.addons.web.controllers.main import login_and_redirect, set_cookie_and_redirect
|
||||
try:
|
||||
import openerp.addons.web.common.http as openerpweb
|
||||
except ImportError:
|
||||
import web.common.http as openerpweb # noqa
|
||||
|
||||
from openid import oidutil
|
||||
from openid.store import filestore
|
||||
from openid.consumer import consumer
|
||||
from openid.cryptutil import randomString
|
||||
from openid.extensions import ax, sreg
|
||||
|
||||
import openerp
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.modules.registry import RegistryManager
|
||||
from openerp.addons.web.controllers.main import login_and_redirect, set_cookie_and_redirect
|
||||
|
||||
from .. import utils
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
@ -70,7 +67,7 @@ class GoogleAppsAwareConsumer(consumer.GenericConsumer):
|
|||
return super(GoogleAppsAwareConsumer, self).complete(message, endpoint, return_to)
|
||||
|
||||
|
||||
class OpenIDController(openerpweb.Controller):
|
||||
class OpenIDController(openerp.addons.web.http.Controller):
|
||||
_cp_path = '/auth_openid/login'
|
||||
|
||||
_store = filestore.FileOpenIDStore(_storedir)
|
||||
|
@ -118,7 +115,7 @@ class OpenIDController(openerpweb.Controller):
|
|||
def _get_realm(self, req):
|
||||
return req.httprequest.host_url
|
||||
|
||||
@openerpweb.httprequest
|
||||
@openerp.addons.web.http.httprequest
|
||||
def verify_direct(self, req, db, url):
|
||||
result = self._verify(req, db, url)
|
||||
if 'error' in result:
|
||||
|
@ -127,7 +124,7 @@ class OpenIDController(openerpweb.Controller):
|
|||
return werkzeug.utils.redirect(result['value'])
|
||||
return result['value']
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def verify(self, req, db, url):
|
||||
return self._verify(req, db, url)
|
||||
|
||||
|
@ -157,7 +154,7 @@ class OpenIDController(openerpweb.Controller):
|
|||
form_html = request.htmlMarkup(realm, redirect_to)
|
||||
return {'action': 'post', 'value': form_html, 'session_id': req.session_id}
|
||||
|
||||
@openerpweb.httprequest
|
||||
@openerp.addons.web.http.httprequest
|
||||
def process(self, req, **kw):
|
||||
session = getattr(req.session, 'openid_session', None)
|
||||
if not session:
|
||||
|
@ -225,7 +222,7 @@ class OpenIDController(openerpweb.Controller):
|
|||
|
||||
return set_cookie_and_redirect(req, '/#action=login&loginerror=1')
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def status(self, req):
|
||||
session = getattr(req.session, 'openid_session', {})
|
||||
return {'status': session.get('status'), 'message': session.get('message')}
|
||||
|
|
|
@ -69,7 +69,7 @@ instance.web.Login = instance.web.Login.extend({
|
|||
_check_error: function() {
|
||||
var self = this;
|
||||
if (this.params.loginerror !== undefined) {
|
||||
this.rpc('/auth_openid/login/status', {}, function(result) {
|
||||
this.rpc('/auth_openid/login/status', {}).then(function(result) {
|
||||
if (_.contains(['success', 'failure'], result.status) && result.message) {
|
||||
self.do_warn('Invalid OpenID Login', result.message);
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ instance.web.Login = instance.web.Login.extend({
|
|||
|
||||
do_openid_login: function(db, openid_url) {
|
||||
var self = this;
|
||||
this.rpc('/auth_openid/login/verify', {'db': db, 'url': openid_url}, function(result) {
|
||||
this.rpc('/auth_openid/login/verify', {'db': db, 'url': openid_url}).then(function(result) {
|
||||
if (result.error) {
|
||||
self.do_warn(result.title, result.error);
|
||||
return;
|
||||
|
|
|
@ -18,20 +18,20 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.modules.registry import RegistryManager
|
||||
import openerp.addons.web.common.http as openerpweb
|
||||
import logging
|
||||
|
||||
import werkzeug
|
||||
|
||||
import logging
|
||||
import openerp
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.modules.registry import RegistryManager
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class Controller(openerpweb.Controller):
|
||||
class Controller(openerp.addons.web.http.Controller):
|
||||
_cp_path = '/auth_reset_password'
|
||||
|
||||
@openerpweb.httprequest
|
||||
@openerp.addons.web.http.httprequest
|
||||
def reset_password(self, req, dbname, login):
|
||||
""" retrieve user, and perform reset password """
|
||||
url = '/'
|
||||
|
|
|
@ -18,32 +18,31 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.modules.registry import RegistryManager
|
||||
from openerp.addons.web.controllers.main import login_and_redirect
|
||||
import openerp.addons.web.common.http as openerpweb
|
||||
import logging
|
||||
|
||||
import werkzeug
|
||||
|
||||
import logging
|
||||
import openerp
|
||||
from openerp.modules.registry import RegistryManager
|
||||
from openerp.addons.web.controllers.main import login_and_redirect
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class Controller(openerpweb.Controller):
|
||||
class Controller(openerp.addons.web.http.Controller):
|
||||
_cp_path = '/auth_signup'
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def retrieve(self, req, dbname, token):
|
||||
""" retrieve the user info (name, login or email) corresponding to a signup token """
|
||||
registry = RegistryManager.get(dbname)
|
||||
user_info = None
|
||||
with registry.cursor() as cr:
|
||||
res_partner = registry.get('res.partner')
|
||||
user_info = res_partner.signup_retrieve_info(cr, SUPERUSER_ID, token)
|
||||
user_info = res_partner.signup_retrieve_info(cr, openerp.SUPERUSER_ID, token)
|
||||
return user_info
|
||||
|
||||
@openerpweb.httprequest
|
||||
def signup(self, req, dbname, token, name, login, password):
|
||||
@openerp.addons.web.http.httprequest
|
||||
def signup(self, req, dbname, token, name, login, password, state=''):
|
||||
""" sign up a user (new or existing), and log it in """
|
||||
url = '/'
|
||||
registry = RegistryManager.get(dbname)
|
||||
|
@ -51,9 +50,9 @@ class Controller(openerpweb.Controller):
|
|||
try:
|
||||
res_users = registry.get('res.users')
|
||||
values = {'name': name, 'login': login, 'password': password}
|
||||
credentials = res_users.signup(cr, SUPERUSER_ID, values, token)
|
||||
credentials = res_users.signup(cr, openerp.SUPERUSER_ID, values, token)
|
||||
cr.commit()
|
||||
return login_and_redirect(req, *credentials)
|
||||
return login_and_redirect(req, *credentials, redirect_url='/#%s'%state)
|
||||
except Exception as e:
|
||||
# signup error
|
||||
_logger.exception('error when signup')
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
import random
|
||||
import time
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
import openerp
|
||||
from openerp.osv import osv, fields
|
||||
|
@ -25,11 +29,6 @@ from openerp import SUPERUSER_ID
|
|||
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from openerp.tools.safe_eval import safe_eval
|
||||
|
||||
import time
|
||||
import random
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
def random_token():
|
||||
# the token has an entropy of about 120 bits (6 bits/char * 20 chars)
|
||||
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||
|
@ -38,7 +37,6 @@ def random_token():
|
|||
def now():
|
||||
return time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
|
||||
|
||||
class res_partner(osv.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
|
@ -132,8 +130,6 @@ class res_partner(osv.Model):
|
|||
res['email'] = partner.email or ''
|
||||
return res
|
||||
|
||||
|
||||
|
||||
class res_users(osv.Model):
|
||||
_inherit = 'res.users'
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ openerp.auth_signup = function(instance) {
|
|||
name: name,
|
||||
login: login,
|
||||
password: password,
|
||||
state: $.param(this.params)
|
||||
};
|
||||
var url = "/auth_signup/signup?" + $.param(params);
|
||||
window.location = url;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# Latvian translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-10-16 16:11+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Latvian <lv@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-17 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16152)\n"
|
||||
|
||||
#. module: base_crypt
|
||||
#: model:ir.model,name:base_crypt.model_res_users
|
||||
msgid "res.users"
|
||||
msgstr "res.users"
|
||||
|
||||
#. module: base_crypt
|
||||
#: sql_constraint:res.users:0
|
||||
msgid "You can not have two users with the same login !"
|
||||
msgstr "Nevar būt divi lietotāji ar vienādu pieteikuma vārdu!"
|
||||
|
||||
#. module: base_crypt
|
||||
#: constraint:res.users:0
|
||||
msgid "The chosen company is not in the allowed companies for this user"
|
||||
msgstr "Izvēlētais uzņēmums nav šim lietotājam atļauto uzņēmumu sarakstā"
|
||||
|
||||
#. module: base_crypt
|
||||
#: code:addons/base_crypt/crypt.py:140
|
||||
#, python-format
|
||||
msgid "Please specify the password !"
|
||||
msgstr "Lūdzu norādiet paroli!"
|
||||
|
||||
#. module: base_crypt
|
||||
#: code:addons/base_crypt/crypt.py:140
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr "Kļūda"
|
|
@ -26,13 +26,14 @@ Re-implement openerp's file import system:
|
|||
'author': 'OpenERP SA',
|
||||
'depends': ['base'],
|
||||
'installable': True,
|
||||
'auto_install': False, # set to true and allow uninstall?
|
||||
'auto_install': True,
|
||||
'css': [
|
||||
'static/lib/select2/select2.css',
|
||||
'static/src/css/import.css',
|
||||
],
|
||||
'js': [
|
||||
'static/lib/select2/select2.js',
|
||||
'static/lib/javascript-state-machine/state-machine.js',
|
||||
'static/src/js/import.js',
|
||||
],
|
||||
'qweb': ['static/src/xml/import.xml'],
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import simplejson
|
||||
|
||||
try:
|
||||
import openerp.addons.web.common.http as openerpweb
|
||||
except ImportError:
|
||||
import web.common.http as openerpweb
|
||||
import openerp
|
||||
|
||||
class ImportController(openerpweb.Controller):
|
||||
class ImportController(openerp.addons.web.http.Controller):
|
||||
_cp_path = '/base_import'
|
||||
|
||||
@openerpweb.httprequest
|
||||
@openerp.addons.web.http.httprequest
|
||||
def set_file(self, req, file, import_id, jsonp='callback'):
|
||||
import_id = int(import_id)
|
||||
|
||||
|
|
|
@ -83,6 +83,10 @@ class ir_import(orm.TransientModel):
|
|||
}]
|
||||
fields_got = self.pool[model].fields_get(cr, uid, context=context)
|
||||
for name, field in fields_got.iteritems():
|
||||
# an empty string means the field is deprecated, @deprecated must
|
||||
# be absent or False to mean not-deprecated
|
||||
if field.get('deprecated', False) is not False:
|
||||
continue
|
||||
if field.get('readonly'):
|
||||
states = field.get('states')
|
||||
if not states:
|
||||
|
@ -97,7 +101,7 @@ class ir_import(orm.TransientModel):
|
|||
'id': name,
|
||||
'name': name,
|
||||
'string': field['string'],
|
||||
# Y U NO ALWAYS HAVE REQUIRED
|
||||
# Y U NO ALWAYS HAS REQUIRED
|
||||
'required': bool(field.get('required')),
|
||||
'fields': [],
|
||||
}
|
||||
|
@ -124,8 +128,8 @@ class ir_import(orm.TransientModel):
|
|||
"""
|
||||
csv_iterator = csv.reader(
|
||||
StringIO(record.file),
|
||||
quotechar=options['quoting'],
|
||||
delimiter=options['separator'])
|
||||
quotechar=str(options['quoting']),
|
||||
delimiter=str(options['separator']))
|
||||
csv_nonempty = itertools.ifilter(None, csv_iterator)
|
||||
# TODO: guess encoding with chardet? Or https://github.com/aadsm/jschardet
|
||||
encoding = options.get('encoding', 'utf-8')
|
||||
|
@ -307,22 +311,14 @@ class ir_import(orm.TransientModel):
|
|||
except ValueError, e:
|
||||
return [{
|
||||
'type': 'error',
|
||||
'message': str(e),
|
||||
'message': unicode(e),
|
||||
'record': False,
|
||||
}]
|
||||
|
||||
try:
|
||||
_logger.info('importing %d rows...', len(data))
|
||||
(code, record, message, _wat) = self.pool[record.res_model].import_data(
|
||||
cr, uid, import_fields, data, context=context)
|
||||
_logger.info('done')
|
||||
|
||||
except Exception, e:
|
||||
_logger.exception("Import failed")
|
||||
# TODO: remove when exceptions stop being an "expected"
|
||||
# behavior of import_data on some (most) invalid
|
||||
# input.
|
||||
code, record, message = -1, None, str(e)
|
||||
_logger.info('importing %d rows...', len(data))
|
||||
import_result = self.pool[record.res_model].load(
|
||||
cr, uid, import_fields, data, context=context)
|
||||
_logger.info('done')
|
||||
|
||||
# If transaction aborted, RELEASE SAVEPOINT is going to raise
|
||||
# an InternalError (ROLLBACK should work, maybe). Ignore that.
|
||||
|
@ -339,14 +335,4 @@ class ir_import(orm.TransientModel):
|
|||
except psycopg2.InternalError:
|
||||
pass
|
||||
|
||||
if code != -1:
|
||||
return []
|
||||
|
||||
# TODO: add key for error location?
|
||||
# TODO: error not within normal preview, how to display? Re-preview
|
||||
# with higher ``count``?
|
||||
return [{
|
||||
'type': 'error',
|
||||
'message': message,
|
||||
'record': record or False
|
||||
}]
|
||||
return import_result['messages']
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2012 Jake Gordon and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,327 @@
|
|||
Javascript Finite State Machine (v2.1.0)
|
||||
========================================
|
||||
|
||||
This standalone javascript micro-framework provides a finite state machine for your pleasure.
|
||||
|
||||
* You can find the [code here](https://github.com/jakesgordon/javascript-state-machine)
|
||||
* You can find a [description here](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/)
|
||||
* You can find a [working demo here](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/example/)
|
||||
|
||||
Download
|
||||
========
|
||||
|
||||
You can download [state-machine.js](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.js),
|
||||
or the [minified version](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.min.js)
|
||||
|
||||
Alternatively:
|
||||
|
||||
git clone git@github.com:jakesgordon/javascript-state-machine
|
||||
|
||||
|
||||
* All code is in state-machine.js
|
||||
* Minified version provided in state-machine.min.js
|
||||
* No 3rd party library is required
|
||||
* Demo can be found in /index.html
|
||||
* QUnit tests can be found in /test/index.html
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Include `state-machine.min.js` in your application.
|
||||
|
||||
In its simplest form, create a standalone state machine using:
|
||||
|
||||
var fsm = StateMachine.create({
|
||||
initial: 'green',
|
||||
events: [
|
||||
{ name: 'warn', from: 'green', to: 'yellow' },
|
||||
{ name: 'panic', from: 'yellow', to: 'red' },
|
||||
{ name: 'calm', from: 'red', to: 'yellow' },
|
||||
{ name: 'clear', from: 'yellow', to: 'green' }
|
||||
]});
|
||||
|
||||
... will create an object with a method for each event:
|
||||
|
||||
* fsm.warn() - transition from 'green' to 'yellow'
|
||||
* fsm.panic() - transition from 'yellow' to 'red'
|
||||
* fsm.calm() - transition from 'red' to 'yellow'
|
||||
* fsm.clear() - transition from 'yellow' to 'green'
|
||||
|
||||
along with the following members:
|
||||
|
||||
* fsm.current - contains the current state
|
||||
* fsm.is(s) - return true if state `s` is the current state
|
||||
* fsm.can(e) - return true if event `e` can be fired in the current state
|
||||
* fsm.cannot(e) - return true if event `e` cannot be fired in the current state
|
||||
|
||||
Multiple 'from' and 'to' states for a single event
|
||||
==================================================
|
||||
|
||||
If an event is allowed **from** multiple states, and always transitions to the same
|
||||
state, then simply provide an array of states in the `from` attribute of an event. However,
|
||||
if an event is allowed from multiple states, but should transition **to** a different
|
||||
state depending on the current state, then provide multiple event entries with
|
||||
the same name:
|
||||
|
||||
var fsm = StateMachine.create({
|
||||
initial: 'hungry',
|
||||
events: [
|
||||
{ name: 'eat', from: 'hungry', to: 'satisfied' },
|
||||
{ name: 'eat', from: 'satisfied', to: 'full' },
|
||||
{ name: 'eat', from: 'full', to: 'sick' },
|
||||
{ name: 'rest', from: ['hungry', 'satisfied', 'full', 'sick'], to: 'hungry' },
|
||||
]});
|
||||
|
||||
This example will create an object with 2 event methods:
|
||||
|
||||
* fsm.eat()
|
||||
* fsm.rest()
|
||||
|
||||
The `rest` event will always transition to the `hungry` state, while the `eat` event
|
||||
will transition to a state that is dependent on the current state.
|
||||
|
||||
>> NOTE: The `rest` event could use a wildcard '*' for the 'from' state if it should be
|
||||
allowed from any current state.
|
||||
|
||||
>> NOTE: The `rest` event in the above example can also be specified as multiple events with
|
||||
the same name if you prefer the verbose approach.
|
||||
|
||||
Callbacks
|
||||
=========
|
||||
|
||||
4 callbacks are available if your state machine has methods using the following naming conventions:
|
||||
|
||||
* onbefore**event** - fired before the event
|
||||
* onleave**state** - fired when leaving the old state
|
||||
* onenter**state** - fired when entering the new state
|
||||
* onafter**event** - fired after the event
|
||||
|
||||
You can affect the event in 3 ways:
|
||||
|
||||
* return `false` from an `onbeforeevent` handler to cancel the event.
|
||||
* return `false` from an `onleavestate` handler to cancel the event.
|
||||
* return `ASYNC` from an `onleavestate` handler to perform an asynchronous state transition (see next section)
|
||||
|
||||
For convenience, the 2 most useful callbacks can be shortened:
|
||||
|
||||
* on**event** - convenience shorthand for onafter**event**
|
||||
* on**state** - convenience shorthand for onenter**state**
|
||||
|
||||
In addition, a generic `onchangestate()` callback can be used to call a single function for _all_ state changes:
|
||||
|
||||
All callbacks will be passed the same arguments:
|
||||
|
||||
* **event** name
|
||||
* **from** state
|
||||
* **to** state
|
||||
* _(followed by any arguments you passed into the original event method)_
|
||||
|
||||
Callbacks can be specified when the state machine is first created:
|
||||
|
||||
var fsm = StateMachine.create({
|
||||
initial: 'green',
|
||||
events: [
|
||||
{ name: 'warn', from: 'green', to: 'yellow' },
|
||||
{ name: 'panic', from: 'yellow', to: 'red' },
|
||||
{ name: 'calm', from: 'red', to: 'yellow' },
|
||||
{ name: 'clear', from: 'yellow', to: 'green' }
|
||||
],
|
||||
callbacks: {
|
||||
onpanic: function(event, from, to, msg) { alert('panic! ' + msg); },
|
||||
onclear: function(event, from, to, msg) { alert('thanks to ' + msg); },
|
||||
ongreen: function(event, from, to) { document.body.className = 'green'; },
|
||||
onyellow: function(event, from, to) { document.body.className = 'yellow'; },
|
||||
onred: function(event, from, to) { document.body.className = 'red'; },
|
||||
}
|
||||
});
|
||||
|
||||
fsm.panic('killer bees');
|
||||
fsm.clear('sedatives in the honey pots');
|
||||
...
|
||||
|
||||
Additionally, they can be added and removed from the state machine at any time:
|
||||
|
||||
fsm.ongreen = null;
|
||||
fsm.onyellow = null;
|
||||
fsm.onred = null;
|
||||
fsm.onchangestate = function(event, from, to) { document.body.className = to; };
|
||||
|
||||
Asynchronous State Transitions
|
||||
==============================
|
||||
|
||||
Sometimes, you need to execute some asynchronous code during a state transition and ensure the
|
||||
new state is not entered until your code has completed.
|
||||
|
||||
A good example of this is when you transition out of a `menu` state, perhaps you want to gradually
|
||||
fade the menu away, or slide it off the screen and don't want to transition to your `game` state
|
||||
until after that animation has been performed.
|
||||
|
||||
You can now return `StateMachine.ASYNC` from your `onleavestate` handler and the state machine
|
||||
will be _'put on hold'_ until you are ready to trigger the transition using the new `transition()`
|
||||
method.
|
||||
|
||||
For example, using jQuery effects:
|
||||
|
||||
var fsm = StateMachine.create({
|
||||
|
||||
initial: 'menu',
|
||||
|
||||
events: [
|
||||
{ name: 'play', from: 'menu', to: 'game' },
|
||||
{ name: 'quit', from: 'game', to: 'menu' }
|
||||
],
|
||||
|
||||
callbacks: {
|
||||
|
||||
onentermenu: function() { $('#menu').show(); },
|
||||
onentergame: function() { $('#game').show(); },
|
||||
|
||||
onleavemenu: function() {
|
||||
$('#menu').fadeOut('fast', function() {
|
||||
fsm.transition();
|
||||
});
|
||||
return StateMachine.ASYNC; // tell StateMachine to defer next state until we call transition (in fadeOut callback above)
|
||||
},
|
||||
|
||||
onleavegame: function() {
|
||||
$('#game').slideDown('slow', function() {
|
||||
fsm.transition();
|
||||
};
|
||||
return StateMachine.ASYNC; // tell StateMachine to defer next state until we call transition (in slideDown callback above)
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
State Machine Classes
|
||||
=====================
|
||||
|
||||
You can also turn all instances of a _class_ into an FSM by applying
|
||||
the state machine functionality to the prototype, including your callbacks
|
||||
in your prototype, and providing a `startup` event for use when constructing
|
||||
instances:
|
||||
|
||||
MyFSM = function() { // my constructor function
|
||||
this.startup();
|
||||
};
|
||||
|
||||
MyFSM.prototype = {
|
||||
|
||||
onpanic: function(event, from, to) { alert('panic'); },
|
||||
onclear: function(event, from, to) { alert('all is clear'); },
|
||||
|
||||
// my other prototype methods
|
||||
|
||||
};
|
||||
|
||||
StateMachine.create({
|
||||
target: MyFSM.prototype,
|
||||
events: [
|
||||
{ name: 'startup', from: 'none', to: 'green' },
|
||||
{ name: 'warn', from: 'green', to: 'yellow' },
|
||||
{ name: 'panic', from: 'yellow', to: 'red' },
|
||||
{ name: 'calm', from: 'red', to: 'yellow' },
|
||||
{ name: 'clear', from: 'yellow', to: 'green' }
|
||||
]});
|
||||
|
||||
|
||||
This should be easy to adjust to fit your appropriate mechanism for object construction.
|
||||
|
||||
Initialization Options
|
||||
======================
|
||||
|
||||
How the state machine should initialize can depend on your application requirements, so
|
||||
the library provides a number of simple options.
|
||||
|
||||
By default, if you dont specify any initial state, the state machine will be in the `'none'`
|
||||
state and you would need to provide an event to take it out of this state:
|
||||
|
||||
var fsm = StateMachine.create({
|
||||
events: [
|
||||
{ name: 'startup', from: 'none', to: 'green' },
|
||||
{ name: 'panic', from: 'green', to: 'red' },
|
||||
{ name: 'calm', from: 'red', to: 'green' },
|
||||
]});
|
||||
alert(fsm.current); // "none"
|
||||
fsm.startup();
|
||||
alert(fsm.current); // "green"
|
||||
|
||||
If you specify the name of your initial event (as in all the earlier examples), then an
|
||||
implicit `startup` event will be created for you and fired when the state machine is constructed.
|
||||
|
||||
var fsm = StateMachine.create({
|
||||
initial: 'green',
|
||||
events: [
|
||||
{ name: 'panic', from: 'green', to: 'red' },
|
||||
{ name: 'calm', from: 'red', to: 'green' },
|
||||
]});
|
||||
alert(fsm.current); // "green"
|
||||
|
||||
If your object already has a `startup` method you can use a different name for the initial event
|
||||
|
||||
var fsm = StateMachine.create({
|
||||
initial: { state: 'green', event: 'init' },
|
||||
events: [
|
||||
{ name: 'panic', from: 'green', to: 'red' },
|
||||
{ name: 'calm', from: 'red', to: 'green' },
|
||||
]});
|
||||
alert(fsm.current); // "green"
|
||||
|
||||
Finally, if you want to wait to call the initial state transition event until a later date you
|
||||
can `defer` it:
|
||||
|
||||
var fsm = StateMachine.create({
|
||||
initial: { state: 'green', event: 'init', defer: true },
|
||||
events: [
|
||||
{ name: 'panic', from: 'green', to: 'red' },
|
||||
{ name: 'calm', from: 'red', to: 'green' },
|
||||
]});
|
||||
alert(fsm.current); // "none"
|
||||
fsm.init();
|
||||
alert(fsm.current); // "green"
|
||||
|
||||
Of course, we have now come full circle, this last example is pretty much functionally the
|
||||
same as the first example in this section where you simply define your own startup event.
|
||||
|
||||
So you have a number of choices available to you when initializing your state machine.
|
||||
|
||||
Handling Failures
|
||||
======================
|
||||
|
||||
By default, if you try to call an event method that is not allowed in the current state, the
|
||||
state machine will throw an exception. If you prefer to handle the problem yourself, you can
|
||||
define a custom `error` handler:
|
||||
|
||||
var fsm = StateMachine.create({
|
||||
initial: 'green',
|
||||
error: function(eventName, from, to, args, errorCode, errorMessage) {
|
||||
return 'event ' + eventName + ' was naughty :- ' + errorMessage;
|
||||
},
|
||||
events: [
|
||||
{ name: 'panic', from: 'green', to: 'red' },
|
||||
{ name: 'calm', from: 'red', to: 'green' },
|
||||
]});
|
||||
alert(fsm.calm()); // "event calm was naughty :- event not allowed in current state green"
|
||||
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
See [RELEASE NOTES](https://github.com/jakesgordon/javascript-state-machine/blob/master/RELEASE_NOTES.md) file.
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
See [LICENSE](https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE) file.
|
||||
|
||||
Contact
|
||||
=======
|
||||
|
||||
If you have any ideas, feedback, requests or bug reports, you can reach me at
|
||||
[jake@codeincomplete.com](mailto:jake@codeincomplete.com), or via
|
||||
my website: [Code inComplete](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
Version 2.1.0 (January 7th 2012)
|
||||
--------------------------------
|
||||
|
||||
* Wrapped in self executing function to be more easily used with loaders like `require.js` or `curl.js` (issue #15)
|
||||
* Allow event to be cancelled by returning `false` from `onleavestate` handler (issue #13) - WARNING: this breaks backward compatibility for async transitions (you now need to return `StateMachine.ASYNC` instead of `false`)
|
||||
* Added explicit return values for event methods (issue #12)
|
||||
* Added support for wildcard events that can be fired 'from' any state (issue #11)
|
||||
* Added support for no-op events that transition 'to' the same state (issue #5)
|
||||
* extended custom error callback to handle any exceptions caused by caller provided callbacks
|
||||
* added custom error callback to override exception when an illegal state transition is attempted (thanks to cboone)
|
||||
* fixed typos (thanks to cboone)
|
||||
* fixed issue #4 - ensure before/after event hooks are called even if the event doesn't result in a state change
|
||||
|
||||
Version 2.0.0 (August 19th 2011)
|
||||
--------------------------------
|
||||
|
||||
* adding support for asynchronous state transitions (see README) - with lots of qunit tests (see test/async.js).
|
||||
* consistent arguments for ALL callbacks, first 3 args are ALWAYS event name, from state and to state, followed by whatever arguments the user passed to the original event method.
|
||||
* added a generic `onchangestate(event,from,to)` callback to detect all state changes with a single function.
|
||||
* allow callbacks to be declared at creation time (instead of having to attach them afterwards)
|
||||
* renamed 'hooks' => 'callbacks'
|
||||
* [read more...](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/)
|
||||
|
||||
Version 1.2.0 (June 21st 2011)
|
||||
------------------------------
|
||||
* allows the same event to transition to different states, depending on the current state (see 'Multiple...' section in README.md)
|
||||
* [read more...](http://codeincomplete.com/posts/2011/6/21/javascript_state_machine_v1_2_0/)
|
||||
|
||||
Version 1.0.0 (June 1st 2011)
|
||||
-----------------------------
|
||||
* initial version
|
||||
* [read more...](http://codeincomplete.com/posts/2011/6/1/javascript_state_machine/)
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
desc "create minified version of state-machine.js"
|
||||
task :minify do
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), 'minifier/minifier'))
|
||||
Minifier.enabled = true
|
||||
Minifier.minify('state-machine.js')
|
||||
end
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Javascript Finite State Machine</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<link href="demo/demo.css" media="screen, print" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="demo" class='green'>
|
||||
|
||||
<h1> Finite State Machine </h1>
|
||||
|
||||
<div id="controls">
|
||||
<button id="clear" onclick="Demo.clear();">clear</button>
|
||||
<button id="calm" onclick="Demo.calm();">calm</button>
|
||||
<button id="warn" onclick="Demo.warn();">warn</button>
|
||||
<button id="panic" onclick="Demo.panic();">panic!</button>
|
||||
</div>
|
||||
|
||||
<div id="diagram">
|
||||
</div>
|
||||
|
||||
<div id="notes">
|
||||
<i>dashed lines are asynchronous state transitions (3 seconds)</i>
|
||||
</div>
|
||||
|
||||
<textarea id="output">
|
||||
</textarea>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script src="state-machine.js"></script>
|
||||
<script src="demo/demo.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,155 @@
|
|||
(function (window) {
|
||||
|
||||
StateMachine = {
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
VERSION: "2.1.0",
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
Result: {
|
||||
SUCCEEDED: 1, // the event transitioned successfully from one state to another
|
||||
NOTRANSITION: 2, // the event was successfull but no state transition was necessary
|
||||
CANCELLED: 3, // the event was cancelled by the caller in a beforeEvent callback
|
||||
ASYNC: 4, // the event is asynchronous and the caller is in control of when the transition occurs
|
||||
},
|
||||
|
||||
Error: {
|
||||
INVALID_TRANSITION: 100, // caller tried to fire an event that was innapropriate in the current state
|
||||
PENDING_TRANSITION: 200, // caller tried to fire an event while an async transition was still pending
|
||||
INVALID_CALLBACK: 300, // caller provided callback function threw an exception
|
||||
},
|
||||
|
||||
WILDCARD: '*',
|
||||
ASYNC: 'async',
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
create: function(cfg, target) {
|
||||
|
||||
var initial = (typeof cfg.initial == 'string') ? { state: cfg.initial } : cfg.initial; // allow for a simple string, or an object with { state: 'foo', event: 'setup', defer: true|false }
|
||||
var fsm = target || cfg.target || {};
|
||||
var events = cfg.events || [];
|
||||
var callbacks = cfg.callbacks || {};
|
||||
var map = {};
|
||||
|
||||
var add = function(e) {
|
||||
var from = (e.from instanceof Array) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified
|
||||
map[e.name] = map[e.name] || {};
|
||||
for (var n = 0 ; n < from.length ; n++)
|
||||
map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified
|
||||
};
|
||||
|
||||
if (initial) {
|
||||
initial.event = initial.event || 'startup';
|
||||
add({ name: initial.event, from: 'none', to: initial.state });
|
||||
}
|
||||
|
||||
for(var n = 0 ; n < events.length ; n++)
|
||||
add(events[n]);
|
||||
|
||||
for(var name in map) {
|
||||
if (map.hasOwnProperty(name))
|
||||
fsm[name] = StateMachine.buildEvent(name, map[name]);
|
||||
}
|
||||
|
||||
for(var name in callbacks) {
|
||||
if (callbacks.hasOwnProperty(name))
|
||||
fsm[name] = callbacks[name]
|
||||
}
|
||||
|
||||
fsm.current = 'none';
|
||||
fsm.is = function(state) { return this.current == state; };
|
||||
fsm.can = function(event) { return !this.transition && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); }
|
||||
fsm.cannot = function(event) { return !this.can(event); };
|
||||
fsm.error = cfg.error || function(name, from, to, args, error, msg) { throw msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3)
|
||||
|
||||
if (initial && !initial.defer)
|
||||
fsm[initial.event]();
|
||||
|
||||
return fsm;
|
||||
|
||||
},
|
||||
|
||||
//===========================================================================
|
||||
|
||||
doCallback: function(fsm, func, name, from, to, args) {
|
||||
if (func) {
|
||||
try {
|
||||
return func.apply(fsm, [name, from, to].concat(args));
|
||||
}
|
||||
catch(e) {
|
||||
return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
beforeEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbefore' + name], name, from, to, args); },
|
||||
afterEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafter' + name] || fsm['on' + name], name, from, to, args); },
|
||||
leaveState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleave' + from], name, from, to, args); },
|
||||
enterState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenter' + to] || fsm['on' + to], name, from, to, args); },
|
||||
changeState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onchangestate'], name, from, to, args); },
|
||||
|
||||
|
||||
buildEvent: function(name, map) {
|
||||
return function() {
|
||||
|
||||
var from = this.current;
|
||||
var to = map[from] || map[StateMachine.WILDCARD] || from;
|
||||
var args = Array.prototype.slice.call(arguments); // turn arguments into pure array
|
||||
|
||||
if (this.transition)
|
||||
return this.error(name, from, to, args, StateMachine.Error.PENDING_TRANSITION, "event " + name + " inappropriate because previous transition did not complete");
|
||||
|
||||
if (this.cannot(name))
|
||||
return this.error(name, from, to, args, StateMachine.Error.INVALID_TRANSITION, "event " + name + " inappropriate in current state " + this.current);
|
||||
|
||||
if (false === StateMachine.beforeEvent(this, name, from, to, args))
|
||||
return StateMachine.CANCELLED;
|
||||
|
||||
if (from === to) {
|
||||
StateMachine.afterEvent(this, name, from, to, args);
|
||||
return StateMachine.NOTRANSITION;
|
||||
}
|
||||
|
||||
// prepare a transition method for use EITHER lower down, or by caller if they want an async transition (indicated by an ASYNC return value from leaveState)
|
||||
var fsm = this;
|
||||
this.transition = function() {
|
||||
fsm.transition = null; // this method should only ever be called once
|
||||
fsm.current = to;
|
||||
StateMachine.enterState( fsm, name, from, to, args);
|
||||
StateMachine.changeState(fsm, name, from, to, args);
|
||||
StateMachine.afterEvent( fsm, name, from, to, args);
|
||||
};
|
||||
|
||||
var leave = StateMachine.leaveState(this, name, from, to, args);
|
||||
if (false === leave) {
|
||||
this.transition = null;
|
||||
return StateMachine.CANCELLED;
|
||||
}
|
||||
else if ("async" === leave) {
|
||||
return StateMachine.ASYNC;
|
||||
}
|
||||
else {
|
||||
if (this.transition)
|
||||
this.transition(); // in case user manually called transition() but forgot to return ASYNC
|
||||
return StateMachine.SUCCEEDED;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}; // StateMachine
|
||||
|
||||
//===========================================================================
|
||||
|
||||
if ("function" === typeof define) {
|
||||
define("statemachine", [], function() { return StateMachine; });
|
||||
}
|
||||
else {
|
||||
window.StateMachine = StateMachine;
|
||||
}
|
||||
|
||||
}(this));
|
||||
|
|
@ -10,7 +10,8 @@
|
|||
.oe_import .oe_import_grid,
|
||||
.oe_import .oe_import_error_report,
|
||||
.oe_import .oe_import_with_file,
|
||||
.oe_import .oe_import_noheaders {
|
||||
.oe_import .oe_import_noheaders,
|
||||
.oe_import .oe_import_report_more {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -19,7 +20,8 @@
|
|||
}
|
||||
.oe_import.oe_import_error .oe_import_error_report,
|
||||
.oe_import.oe_import_with_file .oe_import_with_file,
|
||||
.oe_import.oe_import_noheaders .oe_import_noheaders {
|
||||
.oe_import.oe_import_noheaders .oe_import_noheaders,
|
||||
.oe_import .oe_import_report_showmore .oe_import_report_more {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
@ -29,6 +31,9 @@
|
|||
.oe_import .oe_import_error_report ul .oe_import_report_warning {
|
||||
background-color: #FEFFD9;
|
||||
}
|
||||
.oe_import .oe_import_error_report ul .oe_import_report_info {
|
||||
background-color: #d3ffd3;
|
||||
}
|
||||
|
||||
.oe_import .oe_import_noheaders {
|
||||
color: #888;
|
||||
|
@ -47,7 +52,7 @@
|
|||
}
|
||||
.oe_import .oe_import_options label {
|
||||
display: inline-block;
|
||||
width: 10em;
|
||||
width: 8em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,31 +47,35 @@ openerp.base_import = function (instance) {
|
|||
this._super.apply(this, arguments);
|
||||
if(add_button) {
|
||||
this.$buttons.on('click', '.oe_list_button_import', function() {
|
||||
new instance.web.DataImport(self, self.dataset).open();
|
||||
self.do_action({
|
||||
type: 'ir.actions.client',
|
||||
tag: 'import',
|
||||
params: {
|
||||
model: self.dataset.model
|
||||
}
|
||||
}, void 0, void 0, function () {
|
||||
self.reload();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
instance.web.DataImport = instance.web.Dialog.extend({
|
||||
instance.web.client_actions.add(
|
||||
'import', 'instance.web.DataImport');
|
||||
instance.web.DataImport = instance.web.Widget.extend({
|
||||
template: 'ImportView',
|
||||
dialog_title: _lt("Import Data"),
|
||||
opts: [
|
||||
{name: 'encoding', label: _lt("Encoding:"), value: 'utf-8'},
|
||||
{name: 'separator', label: _lt("Separator:"), value: ','},
|
||||
{name: 'quoting', label: _lt("Quoting:"), value: '"'}
|
||||
],
|
||||
events: {
|
||||
'change .oe_import_grid input': 'import_dryrun',
|
||||
'change input.oe_import_file': 'file_update',
|
||||
'change input.oe_import_has_header, .oe_import_options input': 'settings_updated',
|
||||
'click a.oe_import_csv': function (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
'click a.oe_import_export': function (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
// 'change .oe_import_grid input': 'import_dryrun',
|
||||
'change .oe_import_file': 'loaded_file',
|
||||
'click .oe_import_file_reload': 'loaded_file',
|
||||
'change input.oe_import_has_header, .oe_import_options input': 'settings_changed',
|
||||
'click a.oe_import_toggle': function (e) {
|
||||
e.preventDefault();
|
||||
var $el = $(e.target);
|
||||
|
@ -79,30 +83,84 @@ openerp.base_import = function (instance) {
|
|||
? $el.next()
|
||||
: $el.parent().next())
|
||||
.toggle();
|
||||
},
|
||||
'click .oe_import_report a.oe_import_report_count': function (e) {
|
||||
e.preventDefault();
|
||||
$(e.target).parent().toggleClass('oe_import_report_showmore');
|
||||
},
|
||||
'click .oe_import_moreinfo_action a': function (e) {
|
||||
e.preventDefault();
|
||||
// #data will parse the attribute on its own, we don't like
|
||||
// that sort of things
|
||||
var action = JSON.parse($(e.target).attr('data-action'));
|
||||
// FIXME: when JS-side clean_action
|
||||
action.views = _(action.views).map(function (view) {
|
||||
var id = view[0], type = view[1];
|
||||
return [
|
||||
id,
|
||||
type !== 'tree' ? type
|
||||
: action.view_type === 'form' ? 'list'
|
||||
: 'tree'
|
||||
];
|
||||
});
|
||||
this.do_action(_.extend(action, {
|
||||
target: 'new',
|
||||
flags: {
|
||||
search_view: true,
|
||||
display_title: true,
|
||||
pager: true,
|
||||
list: {selectable: false}
|
||||
}
|
||||
}));
|
||||
},
|
||||
// buttons
|
||||
'click .oe_import_validate': 'validate',
|
||||
'click .oe_import_import': 'import',
|
||||
'click .oe_import_cancel': function (e) {
|
||||
e.preventDefault();
|
||||
this.exit();
|
||||
}
|
||||
},
|
||||
init: function (parent, dataset) {
|
||||
init: function (parent, params) {
|
||||
var self = this;
|
||||
this._super(parent, {
|
||||
buttons: [
|
||||
{text: _t("Import File"), click: function () {
|
||||
self.do_import();
|
||||
}, 'class': 'oe_import_dialog_button'}
|
||||
]
|
||||
});
|
||||
this.res_model = parent.model;
|
||||
this._super.apply(this, arguments);
|
||||
this.res_model = params.model;
|
||||
// import object id
|
||||
this.id = null;
|
||||
this.Import = new instance.web.Model('base_import.import');
|
||||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
return this.Import.call('create', [{
|
||||
'res_model': this.res_model
|
||||
}]).then(function (id) {
|
||||
self.id = id;
|
||||
self.$('input[name=import_id]').val(id);
|
||||
});
|
||||
this.setup_encoding_picker();
|
||||
|
||||
return $.when(
|
||||
this._super(),
|
||||
this.Import.call('create', [{
|
||||
'res_model': this.res_model
|
||||
}]).then(function (id) {
|
||||
self.id = id;
|
||||
self.$('input[name=import_id]').val(id);
|
||||
})
|
||||
)
|
||||
},
|
||||
setup_encoding_picker: function () {
|
||||
this.$('input.oe_import_encoding').select2({
|
||||
width: '160px',
|
||||
query: function (q) {
|
||||
var make = function (term) { return {id: term, text: term}; };
|
||||
var suggestions = _.map(
|
||||
('utf-8 utf-16 windows-1252 latin1 latin2 big5 ' +
|
||||
'gb18030 shift_jis windows-1251 koir8_r').split(/\s+/),
|
||||
make);
|
||||
if (q.term) {
|
||||
suggestions.unshift(make(q.term));
|
||||
}
|
||||
q.callback({results: suggestions});
|
||||
},
|
||||
initSelection: function (e, c) {
|
||||
return c({id: 'utf-8', text: 'utf-8'});
|
||||
}
|
||||
}).select2('val', 'utf-8');
|
||||
},
|
||||
|
||||
import_options: function () {
|
||||
|
@ -118,34 +176,52 @@ openerp.base_import = function (instance) {
|
|||
},
|
||||
|
||||
//- File & settings change section
|
||||
file_update: function (e) {
|
||||
onfile_loaded: function () {
|
||||
this.$('.oe_import_button').prop('disabled', true);
|
||||
if (!this.$('input.oe_import_file').val()) { return; }
|
||||
|
||||
this.$el.removeClass('oe_import_preview oe_import_error');
|
||||
jsonp(this.$el, {
|
||||
url: '/base_import/set_file'
|
||||
}, this.proxy('settings_updated'));
|
||||
}, this.proxy('settings_changed'));
|
||||
},
|
||||
settings_updated: function () {
|
||||
onpreviewing: function () {
|
||||
var self = this;
|
||||
this.$('.oe_import_button').prop('disabled', true);
|
||||
this.$el.addClass('oe_import_with_file');
|
||||
// TODO: test that write // succeeded?
|
||||
this.Import.call(
|
||||
'parse_preview', [this.id, this.import_options()])
|
||||
.then(this.proxy('preview'));
|
||||
},
|
||||
preview: function (result) {
|
||||
this.$el.removeClass('oe_import_preview_error oe_import_error');
|
||||
this.$el.toggleClass(
|
||||
'oe_import_noheaders',
|
||||
!this.$('input.oe_import_has_header').prop('checked'));
|
||||
if (result.error) {
|
||||
this.$el.addClass('oe_import_error');
|
||||
this.$('.oe_import_error_report').html(
|
||||
this.Import.call(
|
||||
'parse_preview', [this.id, this.import_options()])
|
||||
.then(function (result) {
|
||||
var signal = result.error ? 'preview_failed' : 'preview_succeeded';
|
||||
self[signal](result);
|
||||
});
|
||||
},
|
||||
onpreview_error: function (event, from, to, result) {
|
||||
this.$('.oe_import_options').show();
|
||||
this.$el.addClass('oe_import_preview_error oe_import_error');
|
||||
this.$('.oe_import_error_report').html(
|
||||
QWeb.render('ImportView.preview.error', result));
|
||||
return;
|
||||
}
|
||||
},
|
||||
onpreview_success: function (event, from, to, result) {
|
||||
this.$('.oe_import_import').removeClass('oe_highlight');
|
||||
this.$('.oe_import_validate').addClass('oe_highlight');
|
||||
this.$('.oe_import_button').prop('disabled', false);
|
||||
this.$el.addClass('oe_import_preview');
|
||||
this.$('table').html(QWeb.render('ImportView.preview', result));
|
||||
|
||||
if (result.headers.length === 1) {
|
||||
this.$('.oe_import_options').show();
|
||||
this.onresults(null, null, null, [{
|
||||
type: 'warning',
|
||||
message: _t("A single column was found in the file, this often means the file separator is incorrect")
|
||||
}]);
|
||||
}
|
||||
|
||||
var $fields = this.$('.oe_import_fields input');
|
||||
this.render_fields_matches(result, $fields);
|
||||
var data = this.generate_fields_completion(result);
|
||||
|
@ -180,7 +256,6 @@ openerp.base_import = function (instance) {
|
|||
width: 'resolve',
|
||||
dropdownCssClass: 'oe_import_selector'
|
||||
});
|
||||
this.import_dryrun();
|
||||
},
|
||||
generate_fields_completion: function (root) {
|
||||
var basic = [];
|
||||
|
@ -252,40 +327,116 @@ openerp.base_import = function (instance) {
|
|||
|
||||
//- import itself
|
||||
call_import: function (options) {
|
||||
var self = this;
|
||||
var fields = this.$('.oe_import_fields input.oe_import_match_field').map(function (index, el) {
|
||||
return $(el).select2('val') || false;
|
||||
}).get();
|
||||
return this.Import.call(
|
||||
'do', [this.id, fields, this.import_options()], options);
|
||||
},
|
||||
import_dryrun: function () {
|
||||
// this.call_import({ dryrun: true })
|
||||
// .then(this.proxy('render_import_errors'));
|
||||
onvalidate: function () {
|
||||
return this.call_import({ dryrun: true })
|
||||
.then(this.proxy('validated'));
|
||||
},
|
||||
do_import: function () {
|
||||
onimport: function () {
|
||||
var self = this;
|
||||
this.call_import({ dryrun: false }).then(function (errors) {
|
||||
if (_.isEmpty(errors)) {
|
||||
if (self.getParent().reload_content) {
|
||||
self.getParent().reload_content();
|
||||
}
|
||||
self.close();
|
||||
return this.call_import({ dryrun: false }).then(function (message) {
|
||||
if (!_.any(message, function (message) {
|
||||
return message.type === 'error' })) {
|
||||
self['import_succeeded']();
|
||||
return;
|
||||
}
|
||||
self.render_import_errors(errors);
|
||||
self['import_failed'](message);
|
||||
});
|
||||
},
|
||||
render_import_errors: function (errors) {
|
||||
if (_.isEmpty(errors)) {
|
||||
this.$el.removeClass('oe_import_error');
|
||||
return;
|
||||
onimported: function () {
|
||||
this.exit();
|
||||
},
|
||||
exit: function () {
|
||||
this.do_action({
|
||||
type: 'ir.actions.client',
|
||||
tag: 'history_back'
|
||||
});
|
||||
},
|
||||
onresults: function (event, from, to, message) {
|
||||
var no_messages = _.isEmpty(message);
|
||||
this.$('.oe_import_import').toggleClass('oe_highlight', no_messages);
|
||||
this.$('.oe_import_validate').toggleClass('oe_highlight', !no_messages);
|
||||
if (no_messages) {
|
||||
message.push({
|
||||
type: 'info',
|
||||
message: _t("Everything seems valid.")
|
||||
});
|
||||
}
|
||||
// import failed (or maybe just warnings, if we ever get
|
||||
// warnings?)
|
||||
// row indexes come back 0-indexed, spreadsheets
|
||||
// display 1-indexed.
|
||||
var offset = 1;
|
||||
// offset more if header
|
||||
if (this.import_options().headers) { offset += 1; }
|
||||
|
||||
this.$el.addClass('oe_import_error');
|
||||
this.$('.oe_import_error_report').html(
|
||||
QWeb.render('ImportView.error', {errors: errors}));
|
||||
QWeb.render('ImportView.error', {
|
||||
errors: _(message).groupBy('message'),
|
||||
at: function (rows) {
|
||||
var from = rows.from + offset;
|
||||
var to = rows.to + offset;
|
||||
if (from === to) {
|
||||
return _.str.sprintf(_t("at row %d"), from);
|
||||
}
|
||||
return _.str.sprintf(_t("between rows %d and %d"),
|
||||
from, to);
|
||||
},
|
||||
more: function (n) {
|
||||
return _.str.sprintf(_t("(%d more)"), n);
|
||||
},
|
||||
info: function (msg) {
|
||||
if (typeof msg === 'string') {
|
||||
return _.str.sprintf(
|
||||
'<div class="oe_import_moreinfo oe_import_moreinfo_message">%s</div>',
|
||||
_.str.escapeHTML(msg));
|
||||
}
|
||||
if (msg instanceof Array) {
|
||||
return _.str.sprintf(
|
||||
'<div class="oe_import_moreinfo oe_import_moreinfo_choices">%s <ul>%s</ul></div>',
|
||||
_.str.escapeHTML(_t("Here are the possible values:")),
|
||||
_(msg).map(function (msg) {
|
||||
return '<li>'
|
||||
+ _.str.escapeHTML(msg)
|
||||
+ '</li>';
|
||||
}).join(''));
|
||||
}
|
||||
// Final should be object, action descriptor
|
||||
return [
|
||||
'<div class="oe_import_moreinfo oe_import_moreinfo_action">',
|
||||
_.str.sprintf('<a href="#" data-action="%s">',
|
||||
_.str.escapeHTML(JSON.stringify(msg))),
|
||||
_.str.escapeHTML(
|
||||
_t("Get all possible values")),
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join('')
|
||||
},
|
||||
}));
|
||||
},
|
||||
});
|
||||
// FSM-ize DataImport
|
||||
StateMachine.create({
|
||||
target: instance.web.DataImport.prototype,
|
||||
events: [
|
||||
{ name: 'loaded_file',
|
||||
from: ['none', 'file_loaded', 'preview_error', 'preview_success', 'results'],
|
||||
to: 'file_loaded' },
|
||||
{ name: 'settings_changed',
|
||||
from: ['file_loaded', 'preview_error', 'preview_success', 'results'],
|
||||
to: 'previewing' },
|
||||
{ name: 'preview_failed', from: 'previewing', to: 'preview_error' },
|
||||
{ name: 'preview_succeeded', from: 'previewing', to: 'preview_success' },
|
||||
{ name: 'validate', from: 'preview_success', to: 'validating' },
|
||||
{ name: 'validate', from: 'results', to: 'validating' },
|
||||
{ name: 'validated', from: 'validating', to: 'results' },
|
||||
{ name: 'import', from: ['preview_success', 'results'], to: 'importing' },
|
||||
{ name: 'import_succeeded', from: 'importing', to: 'imported'},
|
||||
{ name: 'import_failed', from: 'importing', to: 'results' }
|
||||
]
|
||||
})
|
||||
};
|
||||
|
|
|
@ -2,17 +2,45 @@
|
|||
<t t-name="ImportView">
|
||||
<t t-set="_id" t-value="_.uniqueId('export')"/>
|
||||
<form action="" method="post" enctype="multipart/form-data" class="oe_import">
|
||||
<header>
|
||||
<button type="button" disabled="disabled"
|
||||
class="oe_button oe_import_button oe_import_validate oe_highlight"
|
||||
>Validate</button>
|
||||
<button type="button" disabled="disabled"
|
||||
class="oe_button oe_import_button oe_import_import"
|
||||
>Import</button>
|
||||
<span class="oe_fade">or</span>
|
||||
<a class="oe_import_cancel" href="#">Cancel</a>
|
||||
</header>
|
||||
<input type="hidden" name="session_id"
|
||||
t-att-value="widget.session.session_id"/>
|
||||
<input type="hidden" name="import_id"/>
|
||||
<h2>Upload your file</h2>
|
||||
<p>Select the <a href="#" class="oe_import_csv">.CSV</a>
|
||||
<p>Select the <a
|
||||
href="http://en.wikipedia.org/wiki/Comma-separated_values"
|
||||
class="oe_import_csv" target="_blank">.CSV</a>
|
||||
file to import. If you need a sample importable file, you
|
||||
can use <a href="#" class="oe_import_export">the export
|
||||
tool</a> to generate one.</p>
|
||||
can use the export tool to generate one.</p>
|
||||
<label t-attf-for="file_#{_id}" autofocus="autofocus">CSV File:</label>
|
||||
<input type="file" id-attf-id="file_#{_id}"
|
||||
name="file" class="oe_import_file"/>
|
||||
<button type="button" class="oe_import_file_reload">
|
||||
<img src="/web/static/src/img/icons/gtk-refresh.png"/>
|
||||
</button>
|
||||
<div class="oe_import_with_file">
|
||||
<a href="#" class="oe_import_toggle">
|
||||
File Format Options…</a>
|
||||
<div class="oe_import_toggled oe_import_options">
|
||||
<p t-foreach="widget.opts" t-as="option">
|
||||
<!-- no @name, avoid submission when file_update called -->
|
||||
<label t-attf-for="#{option.name}_#{_id}">
|
||||
<t t-esc="option.label"/></label>
|
||||
<input t-attf-id="#{option.name}_#{_id}"
|
||||
t-attf-class="oe_import_#{option.name}"
|
||||
t-att-value="option.value"/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="oe_import_with_file">
|
||||
<h2>Map your data to OpenERP</h2>
|
||||
|
@ -27,18 +55,6 @@
|
|||
|
||||
<div class="oe_import_error_report"></div>
|
||||
<table class="oe_import_grid" width="100%"/>
|
||||
<a href="#" class="oe_import_toggle">
|
||||
File Format Options…</a>
|
||||
<div class="oe_import_toggled oe_import_options">
|
||||
<p t-foreach="widget.opts" t-as="option">
|
||||
<!-- no @name, avoid submission when file_update called -->
|
||||
<label t-attf-for="#{option.name}_#{_id}">
|
||||
<t t-esc="option.label"/></label>
|
||||
<input t-attf-id="#{option.name}_#{_id}"
|
||||
t-attf-class="oe_import_#{option.name}"
|
||||
t-att-value="option.value"/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2>Frequently Asked Questions</h2>
|
||||
<dl>
|
||||
|
@ -81,17 +97,37 @@
|
|||
</tr>
|
||||
</t>
|
||||
<t t-name="ImportView.preview.error">
|
||||
<p>Import preview failed due to: <t t-esc="error"/></p>
|
||||
<p>Import preview failed due to: <t t-esc="error"/>. The issue is
|
||||
usually an incorrect file encoding.</p>
|
||||
<p>Here is the start of the file we could not import:</p>
|
||||
<pre><t t-esc="preview"/></pre>
|
||||
</t>
|
||||
<ul t-name="ImportView.error">
|
||||
<li t-foreach="errors" t-as="error" t-attf-class="oe_import_report_#{error.type}">
|
||||
<!-- can also have error.record, but may be *huge* if
|
||||
e.g. has image fields -->
|
||||
<t t-esc="error.message"/>
|
||||
<li t-foreach="errors" t-as="error"
|
||||
t-attf-class="oe_import_report oe_import_report_#{error_value[0].type}">
|
||||
<t t-call="ImportView.error.each">
|
||||
<t t-set="error" t-value="error_value[0]"/>
|
||||
</t>
|
||||
|
||||
<a href="#" class="oe_import_report_count" t-if="error_value.length gt 1">
|
||||
<t t-esc="more(error_value.length - 1)"/>
|
||||
</a>
|
||||
<ul class="oe_import_report_more" t-if="error_value.length gt 1">
|
||||
<li t-foreach="error_value.length - 1" t-as="index">
|
||||
<t t-call="ImportView.error.each">
|
||||
<t t-set="error" t-value="error_value[index + 1]"/>
|
||||
</t>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<t t-name="ImportView.error.each">
|
||||
<span class="oe_import_report_message">
|
||||
<t t-esc="error.message"/>
|
||||
</span>
|
||||
<t t-if="error.rows" t-esc="at(error.rows)"/>
|
||||
<t t-if="error.moreinfo" t-raw="info(error.moreinfo)"/>
|
||||
</t>
|
||||
<t t-extend="ListView.buttons">
|
||||
<t t-jquery="span.oe_alternative">
|
||||
this.attr('t-if', 'widget.options.import_enabled');
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from xml.etree import ElementTree
|
||||
|
||||
try:
|
||||
import openerp.addons.web.common.http as openerpweb
|
||||
from openerp.addons.web.common import nonliterals
|
||||
from openerp.addons.web.controllers.main import load_actions_from_ir_values
|
||||
except ImportError:
|
||||
import web.common.http as openerpweb # noqa
|
||||
from web.common import nonliterals # noqa
|
||||
from web.controllers.main import load_actions_from_ir_values # noqa
|
||||
import openerp
|
||||
from openerp.addons.web import nonliterals
|
||||
from openerp.addons.web.controllers.main import load_actions_from_ir_values
|
||||
|
||||
class Board(openerpweb.Controller):
|
||||
class Board(openerp.addons.web.http.Controller):
|
||||
_cp_path = '/board'
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def add_to_dashboard(self, req, menu_id, action_id, context_to_save, domain, view_mode, name=''):
|
||||
# FIXME move this method to board.board model
|
||||
to_eval = nonliterals.CompoundContext(context_to_save)
|
||||
|
|
|
@ -25,9 +25,9 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
|||
}).bind('sortstop', self.do_save_dashboard);
|
||||
|
||||
var old_title = this.__parentedParent.get('title');
|
||||
this.__parentedParent.on_record_loaded.add_last(function(){
|
||||
self.__parentedParent.set({ 'title' : old_title});
|
||||
});
|
||||
this.__parentedParent.on('load_record', self, function(){
|
||||
self.__parentedParent.set({ 'title': old_title});
|
||||
})
|
||||
// Events
|
||||
this.$el.find('.oe_dashboard_link_reset').click(this.on_reset);
|
||||
this.$el.find('.oe_dashboard_link_change_layout').click(this.on_change_layout);
|
||||
|
@ -46,7 +46,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
|||
delete(action.attrs.colspan);
|
||||
var action_id = _.str.toNumber(action.attrs.name);
|
||||
if (!_.isNaN(action_id)) {
|
||||
self.rpc('/web/action/load', {action_id: action_id}, function(result) {
|
||||
self.rpc('/web/action/load', {action_id: action_id}).then(function(result) {
|
||||
self.on_load_action(result, column_index + '_' + action_index, action.attrs);
|
||||
});
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
|||
this.rpc('/web/view/undo_custom', {
|
||||
view_id: this.view.fields_view.view_id,
|
||||
reset: true
|
||||
}, this.do_reload);
|
||||
}).then(this.do_reload);
|
||||
},
|
||||
on_change_layout: function() {
|
||||
var self = this;
|
||||
|
@ -173,7 +173,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
|||
},
|
||||
on_load_action: function(result, index, action_attrs) {
|
||||
var self = this,
|
||||
action = result.result,
|
||||
action = result,
|
||||
view_mode = action_attrs.view_mode;
|
||||
|
||||
if (action_attrs.context && action_attrs.context['dashboard_merge_domains_contexts'] === false) {
|
||||
|
@ -382,7 +382,7 @@ instance.board.AddToDashboard = instance.web.search.Input.extend({
|
|||
domain: domain,
|
||||
view_mode: view_parent.active_view,
|
||||
name: this.$el.find("input").val()
|
||||
}, function(r) {
|
||||
}).then(function(r) {
|
||||
if (r === false) {
|
||||
self.do_warn("Could not add filter to dashboard");
|
||||
} else {
|
||||
|
|
|
@ -777,7 +777,6 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
'default_user_id': uid,
|
||||
'default_section_id': opportunity.section_id and opportunity.section_id.id or False,
|
||||
'default_email_from': opportunity.email_from,
|
||||
'default_state': 'open',
|
||||
'default_name': opportunity.name,
|
||||
}
|
||||
return res
|
||||
|
|
|
@ -160,17 +160,17 @@
|
|||
<field name="street2"/>
|
||||
<div class="address_format">
|
||||
<field name="city" placeholder="City" style="width: 40%%"/>
|
||||
<field name="state_id" options='{"no_open": true}' placeholder="State" style="width: 24%%"/>
|
||||
<field name="state_id" options='{"no_open": True}' placeholder="State" style="width: 24%%"/>
|
||||
<field name="zip" placeholder="ZIP" style="width: 34%%"/>
|
||||
</div>
|
||||
<field name="country_id" placeholder="Country" options='{"no_open": true}'/>
|
||||
<field name="country_id" placeholder="Country" options='{"no_open": True}'/>
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<label for="contact_name" />
|
||||
<div>
|
||||
<field name="contact_name" class="oe_inline"/>,
|
||||
<field name="title" placeholder="Title" domain="[('domain', '=', 'contact')]" class="oe_inline" options='{"no_open": true}'/>
|
||||
<field name="title" placeholder="Title" domain="[('domain', '=', 'contact')]" class="oe_inline" options='{"no_open": True}'/>
|
||||
</div>
|
||||
<field name="email_from" widget="email"/>
|
||||
<field name="function" />
|
||||
|
@ -477,10 +477,10 @@
|
|||
<field name="street2"/>
|
||||
<div class="address_format">
|
||||
<field name="city" placeholder="City" style="width: 40%%"/>
|
||||
<field name="state_id" options='{"no_open": true}' placeholder="State" style="width: 24%%"/>
|
||||
<field name="state_id" options='{"no_open": True}' placeholder="State" style="width: 24%%"/>
|
||||
<field name="zip" placeholder="ZIP" style="width: 34%%"/>
|
||||
</div>
|
||||
<field name="country_id" placeholder="Country" options='{"no_open": true}'/>
|
||||
<field name="country_id" placeholder="Country" options='{"no_open": True}'/>
|
||||
</div>
|
||||
</group>
|
||||
|
||||
|
@ -488,7 +488,7 @@
|
|||
<label for="contact_name" />
|
||||
<div>
|
||||
<field name="contact_name" class="oe_inline"/>
|
||||
<field name="title" placeholder="Title" domain="[('domain', '=', 'contact')]" options='{"no_open": true}' class="oe_inline"/>
|
||||
<field name="title" placeholder="Title" domain="[('domain', '=', 'contact')]" options='{"no_open": True}' class="oe_inline"/>
|
||||
</div>
|
||||
<field name="function" />
|
||||
<field name="mobile"/>
|
||||
|
|
|
@ -105,7 +105,23 @@
|
|||
<field name="allow_unlink"/>
|
||||
</group>
|
||||
<separator string="Team Members"/>
|
||||
<field name="member_ids"/>
|
||||
<field name="member_ids" widget="many2many_kanban">
|
||||
<kanban quick_create="false" create="true">
|
||||
<field name="name"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div style="position: relative">
|
||||
<a t-if="! read_only_mode" type="delete" style="position: absolute; right: 0; padding: 4px; diplay: inline-block">X</a>
|
||||
<div class="oe_module_vignette">
|
||||
<div class="oe_module_desc">
|
||||
<field name="name"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Stages">
|
||||
<separator string="Select Stages for this Sales Team"/>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<field name="name">crm.lead.report.tree</field>
|
||||
<field name="model">crm.lead.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Leads Analysis">
|
||||
<tree string="Leads Analysis" create="false">
|
||||
<field name="creation_year" invisible="1"/>
|
||||
<field name="creation_month" invisible="1"/>
|
||||
<field name="creation_day" invisible="1"/>
|
||||
|
@ -130,7 +130,7 @@
|
|||
<field name="name">crm.lead.report.tree</field>
|
||||
<field name="model">crm.lead.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state == 'draft';black:state in ('open','pending','done');gray:state == 'cancel' " string="Opportunities Analysis">
|
||||
<tree colors="blue:state == 'draft';black:state in ('open','pending','done');gray:state == 'cancel' " create="false" string="Opportunities Analysis">
|
||||
<field name="creation_year" invisible="1"/>
|
||||
<field name="creation_month" invisible="1"/>
|
||||
<field name="creation_day" invisible="1"/>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<field name="name">crm.phonecall.report.tree</field>
|
||||
<field name="model">crm.phonecall.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Phone calls">
|
||||
<tree string="Phone calls" create="false">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="section_id" invisible="1"/>
|
||||
|
|
|
@ -32,6 +32,13 @@ class crm_configuration(osv.osv_memory):
|
|||
'group_fund_raising': fields.boolean("Manage Fund Raising",
|
||||
implied_group='crm.group_fund_raising',
|
||||
help="""Allows you to trace and manage your activities for fund raising."""),
|
||||
'module_crm_claim':fields.boolean("Manage Customer Claims",
|
||||
help="""Allows you to track your customers/suppliers claims and grievances.
|
||||
This installs the module crm_claim."""),
|
||||
'module_crm_helpdesk':fields.boolean("Manage Helpdesk and Support",
|
||||
help="""Allows you to communicate with Customer, process Customer query, and provide better help and support. This installs the module crm_helpdesk."""),
|
||||
|
||||
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -7,6 +7,22 @@
|
|||
<field name="model">sale.config.settings</field>
|
||||
<field name="inherit_id" ref="base_setup.view_sale_config_settings"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="config_sale" position="before">
|
||||
<separator string="After-Sale Services"/>
|
||||
<group>
|
||||
<label for="id" string="Features"/>
|
||||
<div>
|
||||
<div>
|
||||
<field name="module_crm_claim" class="oe_inline"/>
|
||||
<label for="module_crm_claim"/>
|
||||
</div>
|
||||
<div>
|
||||
<field name="module_crm_helpdesk" class="oe_inline"/>
|
||||
<label for="module_crm_helpdesk"/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</div>
|
||||
<group name="On Mail Client" version="7.0" position="after">
|
||||
<group>
|
||||
<label for="id" string="On Mail Server"/>
|
||||
|
|
|
@ -25,8 +25,10 @@
|
|||
'version': '1.0',
|
||||
'category': 'Customer Relationship Management',
|
||||
'description': """
|
||||
This modules allows you to track your customers/suppliers claims and grievances.
|
||||
|
||||
Manage Customer Claims.
|
||||
================================================================================
|
||||
This application allows you to track your customers/suppliers claims and grievances.
|
||||
|
||||
It is fully integrated with the email gateway so that you can create
|
||||
automatically new claims based on incoming emails.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<field name="name">crm.claim.report.tree</field>
|
||||
<field name="model">crm.claim.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Claims">
|
||||
<tree string="Claims" create="false">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="section_id" invisible="1"/>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<field name="name">crm.helpdesk.report.tree</field>
|
||||
<field name="model">crm.helpdesk.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Helpdesk">
|
||||
<tree string="Helpdesk" create="false">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="section_id" invisible="1"/>
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<field name="name">crm.lead.assign.report.tree</field>
|
||||
<field name="model">crm.lead.report.assign</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Opportunities Assignment Analysis">
|
||||
<tree string="Opportunities Assignment Analysis" create="false">
|
||||
<field name="year" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="date_assign" invisible="1"/>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<field name="name">crm.partner.assign.report.tree</field>
|
||||
<field name="model">crm.partner.report.assign</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Opportunities Assignment Analysis">
|
||||
<tree string="Opportunities Assignment Analysis" create="false">
|
||||
<field name="partner_id" invisible="1"/>
|
||||
<field name="country_id" invisible="1"/>
|
||||
<field name="grade_id" invisible="1"/>
|
||||
|
|
|
@ -170,7 +170,7 @@
|
|||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.view_res_partner_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<filter string="Salesman" position="after">
|
||||
<filter string="Salesperson" position="after">
|
||||
<filter string="Activation" context="{'group_by' : 'activation'}" domain="[]" icon="terp-personal" />
|
||||
</filter>
|
||||
</field>
|
||||
|
|
|
@ -36,8 +36,7 @@ DMS_ROOT_PATH = tools.config.get('document_path', os.path.join(tools.config['roo
|
|||
|
||||
class document_file(osv.osv):
|
||||
_inherit = 'ir.attachment'
|
||||
_rec_name = 'datas_fname'
|
||||
|
||||
_rec_name = 'name'
|
||||
|
||||
def _attach_parent_id(self, cr, uid, ids=None, context=None):
|
||||
"""Migrate ir.attachments to the document module.
|
||||
|
@ -149,29 +148,12 @@ class document_file(osv.osv):
|
|||
_sql_constraints = [
|
||||
# filename_uniq is not possible in pure SQL
|
||||
]
|
||||
def _check_duplication(self, cr, uid, vals, ids=None, op='create'):
|
||||
name = vals.get('name', False)
|
||||
parent_id = vals.get('parent_id', False)
|
||||
res_model = vals.get('res_model', False)
|
||||
res_id = vals.get('res_id', 0)
|
||||
if op == 'write':
|
||||
for file in self.browse(cr, uid, ids): # FIXME fields_only
|
||||
if not name:
|
||||
name = file.name
|
||||
if not parent_id:
|
||||
parent_id = file.parent_id and file.parent_id.id or False
|
||||
if not res_model:
|
||||
res_model = file.res_model and file.res_model or False
|
||||
if not res_id:
|
||||
res_id = file.res_id and file.res_id or 0
|
||||
res = self.search(cr, uid, [('id', '<>', file.id), ('name', '=', name), ('parent_id', '=', parent_id), ('res_model', '=', res_model), ('res_id', '=', res_id)])
|
||||
if len(res):
|
||||
return False
|
||||
if op == 'create':
|
||||
res = self.search(cr, uid, [('name', '=', name), ('parent_id', '=', parent_id), ('res_id', '=', res_id), ('res_model', '=', res_model)])
|
||||
if len(res):
|
||||
return False
|
||||
return True
|
||||
|
||||
def onchange_file(self, cr, uid, ids, datas_fname=False, context=None):
|
||||
res = {'value':{}}
|
||||
if datas_fname:
|
||||
res['value'].update({'name': datas_fname})
|
||||
return res
|
||||
|
||||
def check(self, cr, uid, ids, mode, context=None, values=None):
|
||||
"""Check access wrt. res_model, relax the rule of ir.attachment parent
|
||||
|
@ -219,8 +201,6 @@ class document_file(osv.osv):
|
|||
res = self.search(cr, uid, [('id', 'in', ids)])
|
||||
if not len(res):
|
||||
return False
|
||||
if not self._check_duplication(cr, uid, vals, ids, 'write'):
|
||||
raise osv.except_osv(_('ValidateError'), _('File name must be unique!'))
|
||||
|
||||
# if nodes call this write(), they must skip the code below
|
||||
from_node = context and context.get('__from_node', False)
|
||||
|
@ -286,22 +266,8 @@ class document_file(osv.osv):
|
|||
else:
|
||||
if vals.get('file_size'):
|
||||
del vals['file_size']
|
||||
result = self._check_duplication(cr, uid, vals)
|
||||
if not result:
|
||||
domain = [
|
||||
('res_id', '=', vals['res_id']),
|
||||
('res_model', '=', vals['res_model']),
|
||||
('datas_fname', '=', vals['datas_fname']),
|
||||
]
|
||||
attach_ids = self.search(cr, uid, domain, context=context)
|
||||
super(document_file, self).write(cr, uid, attach_ids,
|
||||
{'datas' : vals['datas']},
|
||||
context=context)
|
||||
result = attach_ids[0]
|
||||
else:
|
||||
#raise osv.except_osv(_('ValidateError'), _('File name must be unique!'))
|
||||
result = super(document_file, self).create(cr, uid, vals, context)
|
||||
return result
|
||||
|
||||
return super(document_file, self).create(cr, uid, vals, context)
|
||||
|
||||
def __get_partner_id(self, cr, uid, res_model, res_id, context=None):
|
||||
""" A helper to retrieve the associated partner from any res_model+id
|
||||
|
|
|
@ -228,6 +228,9 @@
|
|||
<field name="priority" eval="1"/>
|
||||
<field name="inherit_id" ref="base.view_attachment_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='datas_fname']" position="replace">
|
||||
<field name="datas_fname" invisible="1" on_change="onchange_file(datas_fname)"/>
|
||||
</xpath>
|
||||
<field name="url" position="after">
|
||||
<field name="user_id"/>
|
||||
</field>
|
||||
|
@ -338,15 +341,6 @@
|
|||
<field name="value" eval="'ir.actions.act_window,%d'%action_document_file_directory_form"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_attachment_form_inherit">
|
||||
<field name="name">ir.attachment.view.inherit</field>
|
||||
<field name="model">ir.attachment</field>
|
||||
<field name="inherit_id" ref="base.view_attachment_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="datas_fname" position = "replace" >
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_process_node_form_inherit1">
|
||||
<field name="name">process.node.form</field>
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
</div>
|
||||
<field name="content" placeholder="e.g. Once upon a time..." class="oe_edit_only"/>
|
||||
<div class="oe_document_page">
|
||||
<field name="display_content" widget="html" class="oe_view_only" options='{"safe": true}'/>
|
||||
<field name="display_content" widget="html" class="oe_view_only" options='{"safe": True}'/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
|
|
|
@ -7,25 +7,25 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
|
||||
"PO-Revision-Date: 2012-08-13 12:14+0000\n"
|
||||
"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n"
|
||||
"PO-Revision-Date: 2012-10-17 00:06+0000\n"
|
||||
"Last-Translator: Syllas F. de O. Neto <syllasneto@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 06:43+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-17 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16152)\n"
|
||||
|
||||
#. module: document_page
|
||||
#: field:document.page.type,template:0
|
||||
msgid "Document page Template"
|
||||
msgstr ""
|
||||
msgstr "Modelo de página de Documento"
|
||||
|
||||
#. module: document_page
|
||||
#: model:ir.actions.act_window,name:document_page.action_wiki
|
||||
#: model:ir.ui.menu,name:document_page.menu_action_wiki_wiki
|
||||
msgid "Document Pages"
|
||||
msgstr ""
|
||||
msgstr "Páginas do Documento"
|
||||
|
||||
#. module: document_page
|
||||
#: field:document.page.type,method:0
|
||||
|
@ -56,7 +56,7 @@ msgstr "Indica se estas páginas têm uma tabela de conteúdo ou não"
|
|||
#. module: document_page
|
||||
#: model:ir.model,name:document_page.model_wiki_wiki_history view:document.page.history:0
|
||||
msgid "Document page History"
|
||||
msgstr ""
|
||||
msgstr "Histórico de páginas do Documento"
|
||||
|
||||
#. module: document_page
|
||||
#: field:document.page,minor_edit:0
|
||||
|
@ -269,7 +269,7 @@ msgstr "Todas as Páginas de Históricos"
|
|||
#. module: document_page
|
||||
#: model:ir.model,name:document_page.model_wiki_wiki
|
||||
msgid "document.page"
|
||||
msgstr ""
|
||||
msgstr "document.page"
|
||||
|
||||
#. module: document_page
|
||||
#: help:document.page.type,method:0
|
||||
|
@ -284,7 +284,7 @@ msgstr "Fechar"
|
|||
#. module: document_page
|
||||
#: model:ir.model,name:document_page.model_wizard_wiki_history_show_diff
|
||||
msgid "wizard.document.page.history.show_diff"
|
||||
msgstr ""
|
||||
msgstr "wizard.document.page.history.show_diff"
|
||||
|
||||
#. module: document_page
|
||||
#: field:document.page.history,wiki_id:0
|
||||
|
@ -357,7 +357,7 @@ msgstr "Esta é uma edição Avançada ?"
|
|||
#: model:ir.model,name:document_page.model_wiki_groups
|
||||
#: model:ir.ui.menu,name:document_page.menu_action_wiki_groups view:document.page.type:0
|
||||
msgid "Document Types"
|
||||
msgstr ""
|
||||
msgstr "Tipos de Documento"
|
||||
|
||||
#. module: document_page
|
||||
#: view:document.page:0
|
||||
|
@ -374,12 +374,12 @@ msgstr "Modificado por"
|
|||
#: field:document.page,type:0
|
||||
#, python-format
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
msgstr "Tipo"
|
||||
|
||||
#. module: document_page
|
||||
#: view:document.page.type:0 view:document.page.page.open:0
|
||||
msgid "Open Document Page"
|
||||
msgstr ""
|
||||
msgstr "Página do documento aberto"
|
||||
|
||||
#. module: document_page
|
||||
#: model:ir.model,name:document_page.model_wiki_wiki_page_open
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<field name="model">wizard.document.page.history.show_diff</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Difference" version="7.0">
|
||||
<field name="diff" widget="html" options='{"safe": true}'/>
|
||||
<field name="diff" widget="html" options='{"safe": True}'/>
|
||||
<footer>
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
|
|
|
@ -4,14 +4,8 @@ import textwrap
|
|||
import simplejson
|
||||
import werkzeug.wrappers
|
||||
|
||||
try:
|
||||
# embedded
|
||||
import openerp.addons.web.common.http as openerpweb
|
||||
import openerp.addons.web.controllers.main as webmain
|
||||
except ImportError:
|
||||
# standalone
|
||||
import web.common.http as openerpweb
|
||||
import web.controllers.main as webmain
|
||||
import openerp.addons.web.http as openerpweb
|
||||
import openerp.addons.web.controllers.main as webmain
|
||||
|
||||
class EDI(openerpweb.Controller):
|
||||
# http://hostname:8069/edi/view?db=XXXX&token=XXXXXXXXXXX
|
||||
|
|
|
@ -15,7 +15,7 @@ openerp.edi.EdiView = openerp.web.Widget.extend({
|
|||
this._super();
|
||||
var self = this;
|
||||
var param = {"db": self.db, "token": self.token};
|
||||
return self.rpc('/edi/get_edi_document', param, this.on_document_loaded, this.on_document_failed);
|
||||
return self.rpc('/edi/get_edi_document', param).then(this.on_document_loaded, this.on_document_failed);
|
||||
},
|
||||
on_document_loaded: function(docs){
|
||||
this.doc = docs[0];
|
||||
|
@ -149,11 +149,11 @@ openerp.edi.EdiImport = openerp.web.Widget.extend({
|
|||
},
|
||||
|
||||
do_import: function() {
|
||||
this.rpc('/edi/import_edi_url', {url: this.url}, this.on_imported, this.on_imported_error);
|
||||
this.rpc('/edi/import_edi_url', {url: this.url}).then(this.on_imported, this.on_imported_error);
|
||||
},
|
||||
on_imported: function(response) {
|
||||
if ('action' in response) {
|
||||
this.rpc("/web/session/save_session_action", {the_action: response.action}, function(key) {
|
||||
this.rpc("/web/session/save_session_action", {the_action: response.action}).then(function(key) {
|
||||
window.location = "/#sa="+encodeURIComponent(key);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -319,7 +319,7 @@ class email_template(osv.osv):
|
|||
ext = "." + format
|
||||
if not report_name.endswith(ext):
|
||||
report_name += ext
|
||||
attachments.append(report_name, result)
|
||||
attachments.append((report_name, result))
|
||||
|
||||
# Add template attachments
|
||||
for attach in template.attachment_ids:
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<field name="email_cc" readonly="1" attrs="{'invisible':[('email_cc','=',False)]}"/>
|
||||
<field name="reply_to" readonly="1" attrs="{'invisible':[('reply_to','=',False)]}"/>
|
||||
<field name="subject" readonly="1"/>
|
||||
<field name="body_html" widget="html" readonly="1" options='{"safe": true}'/>
|
||||
<field name="body_html" widget="html" readonly="1" options='{"safe": True}'/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
attrs="{'invisible':[('use_template','=',False)]}"
|
||||
on_change="onchange_template_id(use_template, template_id, composition_mode, model, res_id, context)"/>
|
||||
</xpath>
|
||||
<xpath expr="//button[@class='oe_mail_compose_message_attachment']" position="before">
|
||||
<xpath expr="//button[@name='dummy']" position="before">
|
||||
<button icon="/email_template/static/src/img/email_template.png"
|
||||
type="object" name="toggle_template" string=""
|
||||
help="Use a message template"
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
from openerp import SUPERUSER_ID
|
||||
|
@ -267,27 +268,29 @@ class event_event(osv.osv):
|
|||
return {'value': dic}
|
||||
|
||||
def on_change_address_id(self, cr, uid, ids, address_id, context=None):
|
||||
values = {
|
||||
'street' : False,
|
||||
'street2' : False,
|
||||
'city' : False,
|
||||
'zip' : False,
|
||||
'country_id' : False,
|
||||
'state_id' : False,
|
||||
}
|
||||
if isinstance(address_id, (long, int)):
|
||||
address = self.pool.get('res.partner').browse(cr, uid, address_id, context=context)
|
||||
values.update({
|
||||
'street' : address.street,
|
||||
'street2' : address.street2,
|
||||
'city' : address.city,
|
||||
'country_id' : address.country_id and address.country_id.id,
|
||||
'state_id' : address.state_id and address.state_id.id,
|
||||
'zip' : address.zip,
|
||||
})
|
||||
|
||||
values = {}
|
||||
if not address_id:
|
||||
return values
|
||||
address = self.pool.get('res.partner').browse(cr, uid, address_id, context=context)
|
||||
values.update({
|
||||
'street' : address.street,
|
||||
'street2' : address.street2,
|
||||
'city' : address.city,
|
||||
'country_id' : address.country_id and address.country_id.id or False,
|
||||
'state_id' : address.state_id and address.state_id.id or False,
|
||||
'zip' : address.zip,
|
||||
})
|
||||
return {'value' : values}
|
||||
|
||||
def onchange_start_date(self, cr, uid, ids, date_begin=False, date_end=False, context=None):
|
||||
res = {'value':{}}
|
||||
if date_end:
|
||||
return res
|
||||
if date_begin and isinstance(date_begin, str):
|
||||
date_begin = datetime.strptime(date_begin, "%Y-%m-%d %H:%M:%S")
|
||||
date_end = date_begin + timedelta(hours=1)
|
||||
res['value'] = {'date_end': date_end.strftime("%Y-%m-%d %H:%M:%S")}
|
||||
return res
|
||||
|
||||
# ----------------------------------------
|
||||
# OpenChatter methods and notifications
|
||||
|
|
|
@ -116,30 +116,28 @@
|
|||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name"/></h1>
|
||||
</div>
|
||||
<div>
|
||||
<group>
|
||||
<group>
|
||||
<group>
|
||||
<label for="address_id" string="Location"/>
|
||||
<div>
|
||||
<field name="address_id" on_change="on_change_address_id(address_id)" />
|
||||
<field name="street" placeholder="Street..."/>
|
||||
<field name="street2"/>
|
||||
<div class="address_format">
|
||||
<field name="city" placeholder="City" style="width: 40%%"/>
|
||||
<field name="state_id" class="oe_no_button" placeholder="State" style="width: 37%%" options='{"no_open": true}'/>
|
||||
<field name="zip" placeholder="ZIP" style="width: 20%%"/>
|
||||
</div>
|
||||
<field name="country_id" placeholder="Country" class="oe_no_button" options='{"no_open": true}'/>
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<field name="type" on_change="onchange_event_type(type,context)"/>
|
||||
<field name="date_begin"/>
|
||||
<field name="date_end"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
<label for="address_id" string="Location"/>
|
||||
<div>
|
||||
<field name="address_id" on_change="on_change_address_id(address_id)" />
|
||||
<field name="street" placeholder="Street..."/>
|
||||
<field name="street2"/>
|
||||
<div class="address_format">
|
||||
<field name="city" placeholder="City" style="width: 40%%"/>
|
||||
<field name="state_id" class="oe_no_button" placeholder="State" style="width: 37%%" options='{"no_open": true}'/>
|
||||
<field name="zip" placeholder="ZIP" style="width: 20%%"/>
|
||||
</div>
|
||||
<field name="country_id" placeholder="Country" class="oe_no_button" options='{"no_open": true}'/>
|
||||
</div>
|
||||
</group>
|
||||
</div>
|
||||
<group>
|
||||
<field name="type" on_change="onchange_event_type(type,context)" />
|
||||
<field name="date_begin" on_change="onchange_start_date(date_begin,date_end)"/>
|
||||
<field name="date_end"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Email Configuration" groups="base.group_no_one">
|
||||
<group>
|
||||
|
@ -284,13 +282,13 @@
|
|||
<t t-if="record.register_avail.raw_value != 0">
|
||||
<t t-if="!record.is_subscribed.raw_value">
|
||||
<input t-att-id="record.id.raw_value" type="text" name="subscribe" class="no_of_seats" value="1" onchange="document.getElementById('btn_sub' +this.id).setAttribute('data-context',JSON.stringify({'ticket':this.value}))"/>
|
||||
<button t-att-id="'btn_sub'+record.id.raw_value" type="object" name="subscribe_to_event" class="oe_mail_button_follow">
|
||||
<button t-att-id="'btn_sub'+record.id.raw_value" type="object" name="subscribe_to_event" class="oe_subscribe_button">
|
||||
<span >Subscribe</span>
|
||||
</button>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="record.is_subscribed.raw_value">
|
||||
<button type="object" name="unsubscribe_to_event" class="oe_mail_button_unfollow">
|
||||
<button type="object" name="unsubscribe_to_event" class="oe_unsubscribe_button ">
|
||||
<span>Subscribed</span>
|
||||
<span class="unsubscribe">Unsubscribe</span>
|
||||
</button>
|
||||
|
|
|
@ -23,16 +23,16 @@ from osv import fields, osv
|
|||
import tools
|
||||
|
||||
class report_event_registration(osv.osv):
|
||||
|
||||
_name = "report.event.registration"
|
||||
_description = "Events Analysis"
|
||||
_auto = False
|
||||
_columns = {
|
||||
'event_date': fields.char('Event Start Date', size=64, readonly=True),
|
||||
'year': fields.char('Year', size=4, readonly=True),
|
||||
'month': fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
|
||||
('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
|
||||
('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
|
||||
'month': fields.selection([
|
||||
('01','January'), ('02','February'), ('03','March'), ('04','April'),
|
||||
('05','May'), ('06','June'), ('07','July'), ('08','August'),
|
||||
('09','September'), ('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
|
||||
'event_id': fields.many2one('event.event', 'Event', required=True),
|
||||
'draft_state': fields.integer(' # No of Draft Registrations', size=20),
|
||||
'confirm_state': fields.integer(' # No of Confirmed Registrations', size=20),
|
||||
|
@ -48,17 +48,18 @@ class report_event_registration(osv.osv):
|
|||
'company_id': fields.many2one('res.company', 'Company', readonly=True),
|
||||
}
|
||||
_order = 'event_date desc'
|
||||
|
||||
def init(self, cr):
|
||||
"""
|
||||
initialize the sql view for the event registration
|
||||
cr -- the cursor
|
||||
Initialize the sql view for the event registration
|
||||
"""
|
||||
tools.drop_view_if_exists(cr, 'report_event_registration')
|
||||
cr.execute("""
|
||||
CREATE OR REPLACE view report_event_registration AS (
|
||||
SELECT
|
||||
event_id,
|
||||
r.id,
|
||||
|
||||
# TOFIX this request won't select events that have no registration
|
||||
cr.execute(""" CREATE VIEW report_event_registration AS (
|
||||
SELECT
|
||||
e.id::char || '/' || coalesce(r.id::char,'') AS id,
|
||||
e.id AS event_id,
|
||||
e.user_id AS user_id,
|
||||
r.user_id AS user_id_registration,
|
||||
r.name AS name_registration,
|
||||
|
@ -72,23 +73,21 @@ class report_event_registration(osv.osv):
|
|||
CASE WHEN r.state IN ('open','done') THEN r.nb_register ELSE 0 END AS confirm_state,
|
||||
e.type AS event_type,
|
||||
e.register_max AS register_max,
|
||||
e.state AS event_state,
|
||||
r.state AS registration_state
|
||||
FROM
|
||||
e.state AS event_state,
|
||||
r.state AS registration_state
|
||||
FROM
|
||||
event_event e
|
||||
LEFT JOIN event_registration r ON (e.id=r.event_id)
|
||||
|
||||
LEFT JOIN
|
||||
event_registration r ON (e.id=r.event_id)
|
||||
|
||||
GROUP BY
|
||||
GROUP BY
|
||||
event_id,
|
||||
user_id_registration,
|
||||
e.id,
|
||||
r.id,
|
||||
registration_state,
|
||||
r.nb_register,
|
||||
event_type, e.id, e.date_begin, e.main_speaker_id,
|
||||
e.register_max,event_id, e.user_id,e.company_id,
|
||||
event_type,
|
||||
e.id,
|
||||
e.date_begin,
|
||||
e.user_id,
|
||||
event_state,
|
||||
e.company_id,
|
||||
|
@ -97,9 +96,8 @@ class report_event_registration(osv.osv):
|
|||
month,
|
||||
e.register_max,
|
||||
name_registration
|
||||
|
||||
)
|
||||
""")
|
||||
)
|
||||
""")
|
||||
|
||||
report_event_registration()
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data>
|
||||
|
||||
<!-- report , event on registration... start -->
|
||||
<!-- Report, event on registration -->
|
||||
<record model="ir.ui.view" id="report_event_registration_tree">
|
||||
<field name="name">report.event.registration.tree</field>
|
||||
<field name="model">report.event.registration</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:event_state == 'draft';black:event_state == 'confirm';gray:event_state in('done','cancel')" string="Events Analysis">
|
||||
<tree colors="blue:event_state == 'draft';black:event_state == 'confirm';gray:event_state in('done','cancel')" create="false" string="Events Analysis">
|
||||
<field name="event_date" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="speaker_id" invisible="1"/>
|
||||
|
@ -28,7 +28,6 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model ="ir.ui.view" id="report_event_registration_graph">
|
||||
<field name="name">report.event.registration.graph</field>
|
||||
<field name="model">report.event.registration</field>
|
||||
|
@ -42,8 +41,7 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Event on Registration search view -->
|
||||
|
||||
<!-- Event on Registration search view -->
|
||||
<record model="ir.ui.view" id="view_report_event_registration_search">
|
||||
<field name="name">report.event.registration.search</field>
|
||||
<field name="model">report.event.registration</field>
|
||||
|
@ -82,28 +80,28 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_report_event_registration">
|
||||
<record model="ir.actions.act_window" id="action_report_event_registration">
|
||||
<field name="name">Events Analysis</field>
|
||||
<field name="res_model">report.event.registration</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,graph</field>
|
||||
<field name="search_view_id" ref="view_report_event_registration_search"/>
|
||||
<field name="context">{"search_default_year":1,"search_default_this_month":1,"search_default_365day":1, "search_default_invoiced":1, "search_default_event":1, 'group_by_no_leaf':1, 'group_by':[]}</field>
|
||||
<field name="context">{"search_default_year":1,"search_default_this_month":1,"search_default_365day":1, "search_default_invoiced":1, "search_default_event":1, "group_by_no_leaf":1, "group_by":[]}</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window.view" id="action_report_event_registration_tree">
|
||||
<record model="ir.actions.act_window.view" id="action_report_event_registration_tree">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="report_event_registration_tree"/>
|
||||
<field name="act_window_id" ref="action_report_event_registration"/>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window.view" id="action_report_event_registration_graph">
|
||||
<record model="ir.actions.act_window.view" id="action_report_event_registration_graph">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view_mode">graph</field>
|
||||
<field name="view_id" ref="report_event_registration_graph"/>
|
||||
<field name="act_window_id" ref="action_report_event_registration"/>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
<menuitem parent="base.menu_reporting" id="menu_reporting_events" sequence="30" groups="event.group_event_manager" name="Events"/>
|
||||
<menuitem parent="menu_reporting_events" action="action_report_event_registration" id="menu_report_event_registration" sequence="3" groups="event.group_event_manager"/>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue