[MERGE] from trunk

bzr revid: fva@openerp.com-20120925135557-09s58wkbt038yxpo
This commit is contained in:
Frédéric van der Essen 2012-09-25 15:55:57 +02:00
commit aa17d5cf7a
363 changed files with 171918 additions and 100604 deletions

View File

@ -63,6 +63,8 @@ for a particular financial year and for preparation of vouchers there is a modul
'wizard/account_use_model_view.xml',
'account_installer.xml',
'wizard/account_period_close_view.xml',
'wizard/account_reconcile_view.xml',
'wizard/account_unreconcile_view.xml',
'account_view.xml',
'account_report.xml',
'account_financial_report_data.xml',
@ -85,14 +87,12 @@ for a particular financial year and for preparation of vouchers there is a modul
'wizard/account_journal_select_view.xml',
'wizard/account_change_currency_view.xml',
'wizard/account_validate_move_view.xml',
'wizard/account_unreconcile_view.xml',
'wizard/account_report_general_ledger_view.xml',
'wizard/account_invoice_state_view.xml',
'wizard/account_report_partner_balance_view.xml',
'wizard/account_report_account_balance_view.xml',
'wizard/account_report_aged_partner_balance_view.xml',
'wizard/account_report_partner_ledger_view.xml',
'wizard/account_reconcile_view.xml',
'wizard/account_reconcile_partner_process_view.xml',
'wizard/account_automatic_reconcile_view.xml',
'wizard/account_financial_report_view.xml',
@ -126,6 +126,14 @@ for a particular financial year and for preparation of vouchers there is a modul
'res_config_view.xml',
'account_pre_install.yml'
],
'js': [
'static/src/js/account_move_reconciliation.js',
],
'qweb' : [
"static/src/xml/account_move_reconciliation.xml",
],
'css':['static/src/css/account_move_reconciliation.css'
],
'demo': [
'demo/account_demo.xml',
'project/project_demo.xml',

View File

@ -836,6 +836,8 @@ class account_journal(osv.osv):
@return: Returns a list of tupples containing id, name
"""
if not ids:
return []
if isinstance(ids, (int, long)):
ids = [ids]
result = self.browse(cr, user, ids, context=context)

View File

@ -1103,10 +1103,10 @@ class account_invoice(osv.osv):
if not ids:
return []
types = {
'out_invoice': 'CI: ',
'in_invoice': 'SI: ',
'out_refund': 'OR: ',
'in_refund': 'SR: ',
'out_invoice': 'Invoice ',
'in_invoice': 'Sup. Invoice ',
'out_refund': 'Refund ',
'in_refund': 'Supplier Refund ',
}
return [(r['id'], (r['number']) or types[r['type']] + (r['name'] or '')) for r in self.read(cr, uid, ids, ['type', 'number', 'name'], context, load='_classic_write')]

View File

@ -30,7 +30,7 @@
<menuitem id="menu_analytic" parent="menu_analytic_accounting" name="Accounts" groups="analytic.group_analytic_accounting"/>
<menuitem id="menu_journals" sequence="15" name="Journals" parent="menu_finance_configuration" groups="group_account_manager"/>
<menuitem id="menu_configuration_misc" name="Miscellaneous" parent="menu_finance_configuration" sequence="55"/>
<menuitem id="base.menu_action_currency_form" parent="menu_configuration_misc" sequence="20" groups="base.group_no_one"/>
<menuitem id="base.menu_action_currency_form" name="Currencies" parent="menu_configuration_misc" sequence="20" groups="base.group_no_one"/>
<menuitem id="menu_finance_generic_reporting" name="Generic Reporting" parent="menu_finance_reports" sequence="100"/>
<menuitem id="menu_finance_entries" name="Journal Entries" parent="menu_finance" sequence="5" groups="group_account_user,group_account_manager"/>
<menuitem id="menu_account_reports" name="Financial Reports" parent="menu_finance_configuration" sequence="30" />

View File

@ -215,8 +215,10 @@ class account_move_line(osv.osv):
def _default_get(self, cr, uid, fields, context=None):
if context is None:
context = {}
if not context.get('journal_id', False) and context.get('search_default_journal_id', False):
if not context.get('journal_id', False):
context['journal_id'] = context.get('search_default_journal_id')
if not context.get('period_id', False):
context['period_id'] = context.get('search_default_period_id')
account_obj = self.pool.get('account.account')
period_obj = self.pool.get('account.period')
journal_obj = self.pool.get('account.journal')
@ -226,6 +228,9 @@ class account_move_line(osv.osv):
partner_obj = self.pool.get('res.partner')
currency_obj = self.pool.get('res.currency')
context = self.convert_to_period(cr, uid, context)
#pass the right context when search_defaul_journal_id
if context.get('search_default_journal_id',False):
context['journal_id'] = context.get('search_default_journal_id')
# Compute simple values
data = super(account_move_line, self).default_get(cr, uid, fields, context=context)
# Starts: Manual entry from account.move form
@ -480,7 +485,7 @@ class account_move_line(osv.osv):
'debit': fields.float('Debit', digits_compute=dp.get_precision('Account')),
'credit': fields.float('Credit', digits_compute=dp.get_precision('Account')),
'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade", domain=[('type','<>','view'), ('type', '<>', 'closed')], select=2),
'move_id': fields.many2one('account.move', 'Move', ondelete="cascade", help="The move of this entry line.", select=2, required=True),
'move_id': fields.many2one('account.move', 'Journal Entry', ondelete="cascade", help="The move of this entry line.", select=2, required=True),
'narration': fields.related('move_id','narration', type='text', relation='account.move', string='Internal Note'),
'ref': fields.related('move_id', 'ref', string='Reference', type='char', size=64, store=True),
'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1),
@ -703,7 +708,9 @@ class account_move_line(osv.osv):
context = {}
if context and context.get('next_partner_only', False):
if not context.get('partner_id', False):
partner = self.get_next_partner_only(cr, uid, offset, context)
partner = self.list_partners_to_reconcile(cr, uid, context=context)
if partner:
partner = partner[0]
else:
partner = context.get('partner_id', False)
if not partner:
@ -711,26 +718,26 @@ class account_move_line(osv.osv):
args.append(('partner_id', '=', partner[0]))
return super(account_move_line, self).search(cr, uid, args, offset, limit, order, context, count)
def get_next_partner_only(self, cr, uid, offset=0, context=None):
def list_partners_to_reconcile(self, cr, uid, context=None):
cr.execute(
"""
SELECT p.id
FROM res_partner p
RIGHT JOIN (
SELECT l.partner_id AS partner_id, SUM(l.debit) AS debit, SUM(l.credit) AS credit
SELECT partner_id
FROM (
SELECT l.partner_id, p.last_reconciliation_date, SUM(l.debit) AS debit, SUM(l.credit) AS credit
FROM account_move_line l
LEFT JOIN account_account a ON (a.id = l.account_id)
LEFT JOIN res_partner p ON (l.partner_id = p.id)
RIGHT JOIN account_account a ON (a.id = l.account_id)
RIGHT JOIN res_partner p ON (l.partner_id = p.id)
WHERE a.reconcile IS TRUE
AND l.reconcile_id IS NULL
AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date)
AND l.state <> 'draft'
GROUP BY l.partner_id
) AS s ON (p.id = s.partner_id)
GROUP BY l.partner_id, p.last_reconciliation_date
) AS s
WHERE debit > 0 AND credit > 0
ORDER BY p.last_reconciliation_date LIMIT 1 OFFSET %s""", (offset, )
)
return cr.fetchone()
ORDER BY last_reconciliation_date""")
ids = cr.fetchall()
ids = len(ids) and [x[0] for x in ids] or []
return self.pool.get('res.partner').name_get(cr, uid, ids, context=context)
def reconcile_partial(self, cr, uid, ids, type='auto', context=None, writeoff_acc_id=False, writeoff_period_id=False, writeoff_journal_id=False):
move_rec_obj = self.pool.get('account.move.reconcile')
@ -910,8 +917,8 @@ class account_move_line(osv.osv):
if lines and lines[0]:
partner_id = lines[0].partner_id and lines[0].partner_id.id or False
if partner_id and context and context.get('stop_reconcile', False):
partner_obj.write(cr, uid, [partner_id], {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')})
if not partner_obj.has_something_to_reconcile(cr, uid, partner_id, context=context):
partner_obj.mark_as_reconciled(cr, uid, [partner_id], context=context)
return r_id
def view_header_get(self, cr, user, view_id, view_type, context=None):
@ -926,6 +933,8 @@ class account_move_line(osv.osv):
return res
if (not context.get('journal_id', False)) or (not context.get('period_id', False)):
return False
if context.get('search_default_journal_id', False):
context['journal_id'] = context.get('search_default_journal_id')
cr.execute('SELECT code FROM account_journal WHERE id = %s', (context['journal_id'], ))
j = cr.fetchone()[0] or ''
cr.execute('SELECT code FROM account_period WHERE id = %s', (context['period_id'], ))

View File

@ -101,28 +101,29 @@
<field name="model">account.period</field>
<field name="arch" type="xml">
<form string="Account Period" version="7.0">
<header>
<button name="action_draft" states="done" string="Set to Draft" type="object" groups="account.group_account_manager"/>
<field name="state" widget="statusbar" nolabel="1"/>
</header>
<sheet>
<group>
<group>
<field name="name"/>
<field name="fiscalyear_id" widget="selection"/>
<label for="date_start" string="Duration"/>
<div>
<field name="date_start" class="oe_inline" nolabel="1"/> -
<field name="date_stop" nolabel="1" class="oe_inline"/>
</div>
</group>
<group>
<field name="code"/>
<field name="special"/>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
</group>
</group>
</sheet>
<header>
<button string="Close Period" name="%(account.action_account_period_close)d" type="action" class="oe_highlight" states="draft"/>
<button name="action_draft" states="done" string="Set to Draft" type="object" groups="account.group_account_manager"/>
<field name="state" widget="statusbar" nolabel="1"/>
</header>
<sheet>
<group>
<group>
<field name="name"/>
<field name="fiscalyear_id" widget="selection"/>
<label for="date_start" string="Duration"/>
<div>
<field name="date_start" class="oe_inline" nolabel="1"/> -
<field name="date_stop" nolabel="1" class="oe_inline"/>
</div>
</group>
<group>
<field name="code"/>
<field name="special"/>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
@ -1038,7 +1039,26 @@
Entries lines
-->
<record id="view_move_line_tree" model="ir.ui.view">
<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">
<field name="date"/>
<field name="move_id"/>
<field name="ref"/>
<field name="name"/>
<field name="partner_id"/>
<field name="account_id"/>
<field name="reconcile_partial_id"/>
<field name="debit" sum="Total debit"/>
<field name="credit" sum="Total credit"/>
</tree>
</field>
</record>
<record id="view_move_line_tree" model="ir.ui.view">
<field name="name">account.move.line.tree</field>
<field name="model">account.move.line</field>
<field eval="4" name="priority"/>
@ -1073,64 +1093,64 @@
<field name="arch" type="xml">
<form string="Journal Item" version="7.0">
<sheet>
<group>
<group>
<field name="name"/>
<field name="ref"/>
<field name="partner_id" on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
</group>
<group>
<field name="journal_id"/>
<field name="period_id"/>
<field name="company_id" required="1" groups="base.group_multi_company"/>
</group>
</group>
<notebook colspan="4">
<page string="Information">
<group>
<group string="Amount">
<field name="account_id" domain="[('company_id', '=', company_id), ('type','&lt;&gt;','view'), ('type','&lt;&gt;','consolidation')]"/>
<field name="debit"/>
<field name="credit"/>
<field name="quantity"/>
</group>
<group string="Accounting Documents">
<field name="invoice" readonly="True"/>
<field name="move_id" required="False"/>
<field name="statement_id" readonly="True"/>
</group>
<group string="Dates">
<field name="date"/>
<field name="date_maturity"/>
<field name="date_created" readonly="True"/>
</group>
<group string="Taxes">
<field name="tax_code_id"/>
<field name="tax_amount"/>
<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"/>
</group>
<group string="Reconciliation">
<field name="reconcile_id"/>
<field name="reconcile_partial_id"/>
</group>
<group string="States">
<field name="state"/>
<field name="blocked"/>
</group>
<group groups="analytic.group_analytic_accounting" string="Analytic">
<field name="analytic_account_id" domain="[('parent_id','!=',False)]"/>
</group>
</group>
<field name="narration" colspan="4" nolabel="1" placeholder="Add an internal note..."/>
</page>
<page string="Analytic Lines" groups="analytic.group_analytic_accounting">
<field name="analytic_lines" context="{'default_general_account_id':account_id, 'default_name': name, 'default_date':date, 'amount': (debit or 0.0)-(credit or 0.0)}"/>
</page>
</notebook>
<group>
<group>
<field name="name"/>
<field name="ref"/>
<field name="partner_id" on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
</group>
<group>
<field name="journal_id"/>
<field name="period_id"/>
<field name="company_id" required="1" groups="base.group_multi_company"/>
</group>
</group>
<notebook colspan="4">
<page string="Information">
<group>
<group string="Amount">
<field name="account_id" domain="[('company_id', '=', company_id), ('type','&lt;&gt;','view'), ('type','&lt;&gt;','consolidation')]"/>
<field name="debit"/>
<field name="credit"/>
<field name="quantity"/>
</group>
<group string="Accounting Documents">
<field name="invoice" readonly="True"/>
<field name="move_id" required="False"/>
<field name="statement_id" readonly="True"/>
</group>
<group string="Dates">
<field name="date"/>
<field name="date_maturity"/>
<field name="date_created" readonly="True"/>
</group>
<group string="Taxes">
<field name="tax_code_id"/>
<field name="tax_amount"/>
<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"/>
</group>
<group string="Reconciliation">
<field name="reconcile_id"/>
<field name="reconcile_partial_id"/>
</group>
<group string="States">
<field name="state"/>
<field name="blocked"/>
</group>
<group groups="analytic.group_analytic_accounting" string="Analytic">
<field name="analytic_account_id" domain="[('parent_id','!=',False)]"/>
</group>
</group>
<field name="narration" colspan="4" nolabel="1" placeholder="Add an internal note..."/>
</page>
<page string="Analytic Lines" groups="analytic.group_analytic_accounting">
<field name="analytic_lines" context="{'default_general_account_id':account_id, 'default_name': name, 'default_date':date, 'amount': (debit or 0.0)-(credit or 0.0)}"/>
</page>
</notebook>
</sheet>
</form>
</field>
@ -1512,7 +1532,6 @@
<record id="action_move_line_search" model="ir.actions.act_window">
<field name="name">Journal Items</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.move.line</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
@ -1531,15 +1550,31 @@
<field name="act_window_id" ref="action_move_line_search"/>
</record>
<act_window
context="{'search_default_next_partner':1,'view_mode':True}"
id="action_account_manual_reconcile" name="Journal Items"
res_model="account.move.line"
view_id="view_move_line_tree"/>
<record id="action_account_manual_reconcile" model="ir.actions.act_window">
<field name="context">{'search_default_unreconciled': 1,'view_mode':True}</field>
<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="help" type="html">
<p>
Good job!
</p><p>
There is nothing to reconcile. All invoices and payments
have been reconciled, your partner balance is clean.
</p>
</field>
</record>
<menuitem
name="Journal Items to Reconcile"
action="action_account_manual_reconcile"
id="menu_manual_reconcile_bank"
sequence="20"
parent="account.menu_finance_bank_and_cash"/>
<menuitem
name="Manual Reconciliation" icon="STOCK_EXECUTE"
name="Manual Reconciliation"
action="action_account_manual_reconcile"
id="menu_manual_reconcile"
parent="account.periodical_processing_reconciliation"/>
@ -1718,8 +1753,10 @@
<field name="model">account.payment.term.line</field>
<field name="arch" type="xml">
<form string="Payment Term" version="7.0">
<field name="name"/>
<field name="sequence"/>
<group>
<field name="name"/>
<field name="sequence"/>
</group>
<group>
<group string="Amount Computation">
<field name="value"/>
@ -1767,12 +1804,11 @@
<field name="model">account.payment.term</field>
<field name="arch" type="xml">
<form string="Payment Term" version="7.0">
<group>
<group col="4">
<field name="name"/>
<field name="active"/>
</group>
<separator string="Description on Invoices"/>
<field name="note"/>
<field name="note" placeholder="Note fo the invoice..."/>
<separator string="Computation"/>
<field name="line_ids"/>
</form>

View File

@ -20,8 +20,8 @@
##############################################################################
from operator import itemgetter
from osv import fields, osv
import time
class account_fiscal_position(osv.osv):
_name = 'account.fiscal.position'
@ -145,6 +145,29 @@ class res_partner(osv.osv):
def _debit_search(self, cr, uid, obj, name, args, context=None):
return self._asset_difference_search(cr, uid, obj, name, 'payable', args, context=context)
def has_something_to_reconcile(self, cr, uid, partner_id, context=None):
'''
at least a debit, a credit and a line older than the last reconciliation date of the partner
'''
cr.execute('''
SELECT l.partner_id, SUM(l.debit) AS debit, SUM(l.credit) AS credit
FROM account_move_line l
RIGHT JOIN account_account a ON (a.id = l.account_id)
RIGHT JOIN res_partner p ON (l.partner_id = p.id)
WHERE a.reconcile IS TRUE
AND p.id = %s
AND l.reconcile_id IS NULL
AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date)
AND l.state <> 'draft'
GROUP BY l.partner_id''', (partner_id,))
res = cr.dictfetchone()
if res:
return bool(res['debit'] and res['credit'])
return False
def mark_as_reconciled(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')}, context=context)
_columns = {
'credit': fields.function(_credit_debit_get,
fnct_search=_credit_search, string='Total Receivable', multi='dc', help="Total amount this customer owes you."),
@ -185,7 +208,7 @@ class res_partner(osv.osv):
help="This payment term will be used instead of the default one for the current partner"),
'ref_companies': fields.one2many('res.company', 'partner_id',
'Companies that refers to partner'),
'last_reconciliation_date': fields.datetime('Latest Reconciliation Date', help='Date on which the partner accounting entries were reconciled last time')
'last_reconciliation_date': fields.datetime('Latest Reconciliation Date', help='Date on which the partner accounting entries were fully reconciled last time. It differs from the date of the last reconciliation made for this partner, as here we depict the fact that nothing more was to be reconciled at this date. This can be achieved in 2 ways: either the last debit/credit entry was reconciled, either the user pressed the button "Fully Reconciled" in the manual reconciliation process')
}
res_partner()

View File

@ -12,7 +12,7 @@
<field name="active"/>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
</group>
<separator string="Mapping"/>
<separator string="Taxes Mapping"/>
<field name="tax_ids" widget="one2many_list">
<tree string="Tax Mapping" editable="bottom">
<field name="tax_src_id" domain="[('parent_id','=',False)]"/>
@ -23,6 +23,7 @@
<field name="tax_dest_id" domain="[('parent_id','=',False)]"/>
</form>
</field>
<separator string="Accounts Mapping"/>
<field name="account_ids" widget="one2many_list">
<tree string="Account Mapping" editable="bottom">
<field name="account_src_id"/>
@ -93,8 +94,10 @@
</group>
<field name="bank_ids">
<form string="Bank account" version="7.0">
<field name="state"/>
<field name="acc_number"/>
<group col="4">
<field name="state"/>
<field name="acc_number"/>
</group>
<group>
<group name="owner" string="Bank Account Owner">
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>

View File

@ -0,0 +1,19 @@
.openerp .oe_account_reconciliation {
border-bottom: 1px solid #CACACA;
padding: 5px;
}
.openerp .oe_account_reconciliation button {
margin: 3px;
}
.openerp .oe_account_reconciliation>div {
display: table;
width: 100%;
}
.openerp .oe_account_reconciliation>div>div {
display: table-cell;
width: 50%:
}

View File

@ -0,0 +1,124 @@
openerp.account = function (instance) {
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
instance.web.account = {};
instance.web.views.add('account_reconciliation_list', 'instance.web.account.ReconciliationListView');
instance.web.account.ReconciliationListView = instance.web.ListView.extend({
init: function() {
this._super.apply(this, arguments);
var self = this;
this.current_partner = null;
this.do_select.add(function() {
if (self.get_selected_ids().length === 0) {
self.$(".oe_account_recon_reconcile").attr("disabled", "");
} else {
self.$(".oe_account_recon_reconcile").removeAttr("disabled");
}
});
},
on_loaded: function() {
var self = this;
var tmp = this._super.apply(this, arguments);
if (this.partners) {
this.$el.prepend(QWeb.render("AccountReconciliation", {widget: this}));
this.$(".oe_account_recon_previous").click(function() {
self.current_partner = (self.current_partner - 1) % self.partners.length;
self.search_by_partner();
});
this.$(".oe_account_recon_next").click(function() {
self.current_partner = (self.current_partner + 1) % self.partners.length;
self.search_by_partner();
});
this.$(".oe_account_recon_reconcile").click(function() {
self.reconcile();
});
this.$(".oe_account_recom_mark_as_reconciled").click(function() {
self.mark_as_reconciled();
});
}
return tmp;
},
do_search: function(domain, context, group_by) {
var self = this;
this.last_domain = domain;
this.last_context = context;
this.last_group_by = group_by;
this.old_search = _.bind(this._super, this);
var mod = new instance.web.Model("account.move.line", context, domain);
return mod.call("list_partners_to_reconcile", []).pipe(function(result) {
var current = self.current_partner !== null ? self.partners[self.current_partner][0] : null;
self.partners = result;
var index = _.find(_.range(self.partners.length), function(el) {
if (current === self.partners[el][0])
return true;
});
if (index !== undefined)
self.current_partner = index;
else
self.current_partner = self.partners.length == 0 ? null : 0;
self.search_by_partner();
});
},
search_by_partner: function() {
var self = this;
var fct = function() {
return self.old_search(new instance.web.CompoundDomain(self.last_domain,
[["partner_id", "in", self.current_partner === null ? [] :
[self.partners[self.current_partner][0]] ]]), self.last_context, self.last_group_by);
};
if (self.current_partner === null) {
self.last_reconciliation_date = _t("Never");
return fct();
} else {
return new instance.web.Model("res.partner").call("read",
[self.partners[self.current_partner][0], ["last_reconciliation_date"]]).pipe(function(res) {
self.last_reconciliation_date =
instance.web.format_value(res.last_reconciliation_date, {"type": "datetime"}, _t("Never"));
return fct();
});
}
},
reconcile: function() {
var self = this;
var ids = this.get_selected_ids();
if (ids.length === 0) {
instance.web.dialog($("<div />").text(_t("You must choose at least one record.")), {
title: _t("Warning"),
modal: true
});
return false;
}
new instance.web.Model("ir.model.data").call("get_object_reference", ["account", "action_view_account_move_line_reconcile"]).pipe(function(result) {
var additional_context = _.extend({
active_id: ids[0],
active_ids: ids,
active_model: self.model
});
return self.rpc("/web/action/load", {
action_id: result[1],
context: additional_context
}, function (result) {
result = result.result;
result.context = _.extend(result.context || {}, additional_context);
result.flags = result.flags || {};
result.flags.new_window = true;
return self.do_action(result, function () {
self.do_search(self.last_domain, self.last_context, self.last_group_by);
});
});
});
},
mark_as_reconciled: function() {
var self = this;
var id = self.partners[self.current_partner][0];
new instance.web.Model("res.partner").call("mark_as_reconciled", [[id]]).pipe(function() {
self.do_search(self.last_domain, self.last_context, self.last_group_by);
});
},
});
};

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="AccountReconciliation">
<div class="oe_account_reconciliation">
<t t-if="widget.current_partner === null">
There is no pending reconciliation.
</t>
<t t-if="widget.current_partner !== null">
<div>
<div>
<button class="oe_account_recon_previous oe_button" href="javascript:void(0)">&lt;</button>
<t t-esc="'' + widget.partners[widget.current_partner][1] + ' (' + (widget.current_partner + 1) + '/' + widget.partners.length + ')'"/>
<button class="oe_account_recon_next oe_button" href="javascript:void(0)">&gt;</button>
</div>
<div>
Last Reconciliation: <t t-esc="widget.last_reconciliation_date" />
</div>
</div>
<div>
<button class="oe_account_recon_reconcile oe_button oe_highlight" href="javascript:void(0)"
disabled="">Reconcile</button>
<button class="oe_account_recom_mark_as_reconciled oe_button" href="javascript:void(0)">Nothing to reconcile</button>
</div>
</t>
</div>
</t>
</templates>

View File

@ -92,7 +92,7 @@ class account_move_journal(osv.osv_memory):
journal = False
if journal_id:
journal = journal_pool.read(cr, uid, journal_id, ['name'], context=context).name
journal = journal_pool.read(cr, uid, journal_id, ['name'], context=context).get('name',False)
journal_string = _("Journal: %s") % tools.ustr(journal)
else:
journal_string = _("Journal: All")

View File

@ -86,19 +86,6 @@ class account_move_line_reconcile(osv.osv_memory):
ids = period_obj.find(cr, uid, dt=date, context=context)
if ids:
period_id = ids[0]
#stop the reconciliation process by partner (manual reconciliation) only if there is nothing more to reconcile for this partner
if 'active_ids' in context and context['active_ids']:
tmp_ml_id = account_move_line_obj.browse(cr, uid, context['active_ids'], context)[0]
partner_id = tmp_ml_id.partner_id and tmp_ml_id.partner_id.id or False
debit_ml_ids = account_move_line_obj.search(cr, uid, [('partner_id', '=', partner_id), ('account_id.reconcile', '=', True), ('reconcile_id', '=', False), ('debit', '>', 0)], context=context)
credit_ml_ids = account_move_line_obj.search(cr, uid, [('partner_id', '=', partner_id), ('account_id.reconcile', '=', True), ('reconcile_id', '=', False), ('credit', '>', 0)], context=context)
for ml_id in context['active_ids']:
if ml_id in debit_ml_ids:
debit_ml_ids.remove(ml_id)
if ml_id in credit_ml_ids:
credit_ml_ids.remove(ml_id)
if not debit_ml_ids and credit_ml_ids:
context.update({'stop_reconcile': True})
account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id,
period_id, journal_id, context=context)
return {'type': 'ir.actions.act_window_close'}
@ -166,7 +153,6 @@ class account_move_line_reconcile_writeoff(osv.osv_memory):
if ids:
period_id = ids[0]
context.update({'stop_reconcile': True})
account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id,
period_id, journal_id, context=context)
return {'type': 'ir.actions.act_window_close'}

View File

@ -57,10 +57,10 @@ class account_partner_reconcile_process(osv.osv_memory):
def _get_partner(self, cr, uid, context=None):
move_line_obj = self.pool.get('account.move.line')
partner = move_line_obj.get_next_partner_only(cr, uid, offset=1, context=context)
partner = move_line_obj.list_partners_to_reconcile(cr, uid, context=context)
if not partner:
return False
return partner[0]
return partner[0][0]
def data_get(self, cr, uid, to_reconcile, today_reconciled, context=None):
return {'progress': (100 / (float(to_reconcile + today_reconciled) or 1.0)) * today_reconciled}
@ -100,4 +100,4 @@ class account_partner_reconcile_process(osv.osv_memory):
account_partner_reconcile_process()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -36,6 +36,7 @@ Adds menu to show relevant information to each manager.You can also view the rep
'depends': ['hr_timesheet_invoice', 'sale'], #although sale is technically not required to install this module, all menuitems are located under 'Sales' application
'data': [
'security/ir.model.access.csv',
'security/account_analytic_analysis_security.xml',
'account_analytic_analysis_view.xml',
'account_analytic_analysis_menu.xml',
'account_analytic_analysis_cron.xml',

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="res.users" id="base.user_root">
<field eval="[(4,ref('sale.group_analytic_accounting'))]" name="groups_id"/>
</record>
</data>
</openerp>

View File

@ -129,7 +129,7 @@
</group>
</page>
<page string="Depreciation Board">
<field name="depreciation_line_ids" mode="tree,graph">
<field name="depreciation_line_ids" mode="tree">
<tree string="Depreciation Lines" colors="blue:(move_check == False);black:(move_check == True)">
<field name="depreciation_date"/>
<field name="sequence" invisible="1"/>
@ -159,11 +159,6 @@
</group>
</group>
</form>
<graph type="bar">
<field name="name"/>
<field name="amount"/>
<field name="depreciated_value"/>
</graph>
</field>
<button type="object" name="compute_depreciation_board" string="Compute" icon="terp-stock_format-scientific" colspan="2" attrs="{'invisible':[('state','=','close')]}"/>
</page>

View File

@ -62,12 +62,7 @@
<field name="account_ids"/>
</page>
<page string="Budget Lines">
<field name="crossovered_budget_line" widget="one2many_list" mode="graph,tree">
<graph type="bar" string="Lines">
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
<field name="planned_amount" operator="+"/>
<field group="True" name="general_budget_id"/>
</graph>
<field name="crossovered_budget_line" widget="one2many_list" mode="tree">
<tree string="Budget Lines" editable="top">
<field name="crossovered_budget_id"/>
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" domain="[('parent_id','!=',False)]"/>

View File

@ -22,6 +22,10 @@
<field eval="True" name="global"/>
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
</record>
<record model="res.users" id="base.user_root">
<field eval="[(4,ref('analytic.group_analytic_accounting'))]" name="groups_id"/>
</record>
</data>
</openerp>

View File

@ -404,9 +404,9 @@
<field name="name"/>
<field name="statement_id" readonly="1"/>
<field name="ref" readonly="1"/>
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
<field name="type" on_change="onchange_type(partner_id, type)"/>
<field name="account_id" domain="[('journal_id','=',parent.journal_id)]"/>
<field name="partner_id" />
<field name="type" />
<field name="account_id" />
<field name="amount" readonly="1" sum="Total Amount"/>
<field name="globalisation_id" string="Glob. Id"/>
<field name="globalisation_amount" string="Glob. Am."/>
@ -426,9 +426,9 @@
<field name="val_date"/>
<field name="name"/>
<field name="ref" readonly="0"/>
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
<field name="type" on_change="onchange_type(partner_id, type)"/>
<field domain="[('journal_id', '=', parent.journal_id), ('type', '&lt;&gt;', 'view')]" name="account_id"/>
<field name="partner_id"/>
<field name="type" />
<field domain="[('type', '&lt;&gt;', 'view')]" name="account_id"/>
<field name="amount"/>
<field name="globalisation_id"/>
<field name="sequence" readonly="0"/>

View File

@ -47,16 +47,18 @@
<field name="state" widget="statusbar" statusbar_visible="draft,posted" statusbar_colors='{"proforma":"blue"}'/>
</header>
<sheet string="Accounting Voucher">
<group col="6" colspan="4">
<group col="4" colspan="4">
<field name="partner_id" required="1" on_change="onchange_journal_voucher(line_ids, tax_id, amount, partner_id, journal_id, type)"/>
<field name="payment_rate_currency_id" invisible="1"/>
<field name="date" on_change="onchange_date(date, currency_id, payment_rate_currency_id, amount, company_id)"/>
<field name="journal_id" widget="selection" on_change="onchange_journal_voucher(line_ids, tax_id, amount, partner_id, journal_id, type)"/>
<field name="type" required="1"/>
<field name="name" colspan="2"/>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
<field name="reference"/>
<field name="number"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="account_id" widget="selection" invisible="True"/>
<field name="payment_rate_currency_id" invisible="1"/>
</group>
<notebook colspan="4">
<page string="Voucher Entry">
@ -69,20 +71,16 @@
<field name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
</tree>
</field>
<group col="3">
<group string="Internal Notes">
<field name="narration" colspan="2" nolabel="1"/>
</group>
<group string="Other Information">
<field name="number"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</group>
<group col="4" attrs="{'invisible':[('type','in',['payment', 'receipt', False])]}">
<separator string="Total" colspan="4"/>
<field name="tax_id" on_change="onchange_price(line_ids, tax_id, partner_id)" widget="selection"/>
<group>
<field name="narration" nolabel="1" placeholder="Internal Notes"/>
<group class="oe_subtotal_footer oe_right" attrs="{'invisible':[('type','in',['payment', 'receipt', False])]}">
<field name="tax_id" on_change="onchange_price(line_ids, tax_id, partner_id)" widget="selection" nolabel="1"/>
<field name="tax_amount" nolabel="1"/>
<button type="object" icon="terp-stock_format-scientific" name="compute_tax" string="Compute Tax" attrs="{'invisible': [('state','!=','draft')]}"/>
<label colspan="1" string=""/><field name="amount" string="Total"/>
<div class="oe_subtotal_footer_separator">
<label for="amount"/>
<button type="object" icon="terp-stock_format-scientific" name="compute_tax" class="oe_link oe_edit_only" string="(Update)" attrs="{'invisible': [('state','!=','draft')]}"/>
</div>
<field name="amount" class="oe_subtotal_footer_separator" nolabel="1"/>
</group>
</group>
</page>

View File

@ -140,7 +140,7 @@ class account_analytic_account(osv.osv):
'name': fields.char('Account/Contract Name', size=128, required=True),
'complete_name': fields.function(_complete_name_calc, type='char', string='Full Account Name'),
'code': fields.char('Reference', size=24, select=True),
'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Project')], 'Type of Account', required=True,
'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Project')], 'Type of Account', required=True,
help="If you select the View Type, it means you won\'t allow to create journal entries using that account.\n"\
"The type 'Analytic account' stands for usual accounts that you only want to use in accounting.\n"\
"If you select Contract or Project, it offers you the possibility to manage the validity and the invoicing options for this account.\n"\
@ -168,7 +168,7 @@ class account_analytic_account(osv.osv):
'res.company': (_get_analytic_account, ['currency_id'], 10),
}, string='Currency', type='many2one', relation='res.currency'),
}
def on_change_template(self, cr, uid, ids, template_id, context=None):
if not template_id:
return {}
@ -179,7 +179,7 @@ class account_analytic_account(osv.osv):
res['value']['quantity_max'] = template.quantity_max
res['value']['description'] = template.description
return res
def on_change_partner_id(self, cr, uid, ids,partner_id, name, context={}):
res={}
if partner_id:
@ -222,8 +222,10 @@ class account_analytic_account(osv.osv):
def copy(self, cr, uid, id, default=None, context=None):
if not default:
default = {}
analytic = self.browse(cr, uid, id, context=context)
default['code'] = False
default['line_ids'] = []
default['name'] = analytic['name'] + ' (' + _('copy') + ')'
return super(account_analytic_account, self).copy(cr, uid, id, default, context=context)
def on_change_company(self, cr, uid, id, company_id):

View File

@ -68,8 +68,10 @@ class ir_model_fields_anonymization(osv.osv):
return state
def _check_write(self, cr, uid, context=None):
# check that the field is created from the menu and not from an database update
# otherwise the database update can crash:
"""check that the field is created from the menu and not from an database update
otherwise the database update can crash:"""
if context is None:
context = {}
if context.get('manual'):
global_state = self._get_global_state(cr, uid, context=context)
@ -295,10 +297,10 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, *args, **kwargs):
state = self.pool.get('ir.model.fields.anonymization')._get_global_state(cr, uid, context=context)
if context is None:
context = {}
step = context.get('step', 'new_window')
res = super(ir_model_fields_anonymize_wizard, self).fields_view_get(cr, uid, view_id, view_type, context, *args, **kwargs)

View File

@ -13,7 +13,7 @@
<field name="groups_id" eval="[(5,)]"/>
</record>
<record id="default_template_user" model="ir.config_parameter">
<record id="default_template_user_config" model="ir.config_parameter">
<field name="key">auth_signup.template_user_id</field>
<field name="value" ref="default_template_user"/>
</record>

View File

@ -20,7 +20,7 @@
##############################################################################
{
'name': 'Calendar Layer',
'name': 'Calendar',
'version': '1.0',
'depends': ['base', 'base_status', 'mail', 'base_action_rule'],
'description': """
@ -51,6 +51,7 @@ If you need to manage your meetings, you should install the CRM module.
],
'test' : ['test/base_calendar_test.yml'],
'installable': True,
'application': True,
'auto_install': False,
'certificate': '00694071962960352821',
'images': ['images/base_calendar1.jpeg','images/base_calendar2.jpeg','images/base_calendar3.jpeg','images/base_calendar4.jpeg',],

View File

@ -1431,7 +1431,10 @@ rule or repeating pattern of time to exclude from the recurring rule."),
if r['class']=='private':
for f in r.keys():
if f not in ('id','date','date_deadline','duration','user_id','state'):
r[f] = False
if isinstance(r[f], list):
r[f] = []
else:
r[f] = False
if f=='name':
r[f] = _('Busy')

View File

@ -418,7 +418,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">calendar.event</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar</field>
<field name="view_mode">calendar,tree,form</field>
<field name="search_view_id" ref="view_calendar_event_filter"/>
</record>
@ -428,5 +428,6 @@
name="Events" parent="base.menu_calendar_configuration"
sequence="15" action="action_view_event"/>
<menuitem name="Agenda" id="mail_menu_agenda" parent="mail.mail_my_stuff" sequence="10" action="action_view_event"/>
</data>
</openerp>

View File

@ -53,7 +53,7 @@ class crm_meeting(base_state, osv.Model):
'partner_ids': fields.many2many('res.partner', 'crm_meeting_partner_rel', 'meeting_id','partner_id',
string='Attendees', states={'done': [('readonly', True)]}),
'state': fields.selection(
[('draft', 'Unconfirmed'), ('open', 'Confirmed'), ('cancel', 'Cancelled'), ('done', 'Done')],
[('draft', 'Unconfirmed'), ('open', 'Confirmed')],
string='Status', size=16, readonly=True),
# Meeting fields
'name': fields.char('Meeting Subject', size=128, required=True, states={'done': [('readonly', True)]}),

View File

@ -69,9 +69,7 @@
<field name="model">crm.meeting</field>
<field name="arch" type="xml">
<form string="Meetings" version="7.0">
<header>
<field name="state" invisible="True"/>
</header>
<field name="state" invisible="True"/>
<sheet>
<div class="oe_title">
<div class="oe_edit_only">

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -9,14 +9,11 @@
<field name="inherit_id" ref="base.res_partner_kanban_view"/>
<field name="arch" type="xml">
<xpath expr="//div[@class='oe_kanban_partner_categories']" position="inside">
<span class="oe_kanban_list_many2many" data-model="res.partner.category">
<t t-foreach="record.category_id.raw_value" t-as="category">
<span class="oe_tag" t-att-data-list_id="category"/>
</t>
<span class="oe_kanban_list_many2many">
<field name="category_id"/>
</span>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -69,7 +69,7 @@ class base_stage(object):
return False
return uid
def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
def onchange_partner_address_id(self, cr, uid, ids, add, email=False, context=None):
""" This function returns value of partner email based on Partner Address
:param add: Id of Partner's address
:param email: Partner's email ID
@ -77,10 +77,20 @@ class base_stage(object):
data = {'value': {'email_from': False, 'phone':False}}
if add:
address = self.pool.get('res.partner').browse(cr, uid, add)
data['value'] = {'email_from': address and address.email or False ,
'phone': address and address.phone or False}
if 'phone' not in self._columns:
del data['value']['phone']
data['value'] = {'partner_name': address and address.name or False,
'email_from': address and address.email or False,
'phone': address and address.phone or False,
'street': address and address.street or False,
'street2': address and address.street2 or False,
'city': address and address.city or False,
'state_id': address.state_id and address.state_id.id or False,
'zip': address and address.zip or False,
'country_id': address.country_id and address.country_id.id or False,
}
fields = self.fields_get(cr, uid, context=context or {})
for key in data['value'].keys():
if key not in fields:
del data['value'][key]
return data
def onchange_partner_id(self, cr, uid, ids, part, email=False):

View File

@ -1,3 +1,36 @@
.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_0 {
width: 100%;
}
.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_1, .openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_2 {
display: none;
}
.openerp .oe_dashboard_layout_1-1 .oe_dashboard_column {
width: 50%;
}
.openerp .oe_dashboard_layout_1-1 .oe_dashboard_column.index_2 {
display: none;
}
.openerp .oe_dashboard_layout_1-1-1 .oe_dashboard_column {
width: 33%;
}
.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_0 {
width: 70%;
}
.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_1 {
width: 30%;
}
.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_2 {
display: none;
}
.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_0 {
width: 30%;
}
.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_1 {
width: 70%;
}
.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_2 {
display: none;
}
.openerp .oe_dashboard_layout_selector ul {
white-space: nowrap;
}

View File

@ -9,6 +9,31 @@
box-shadow: $bsval
.openerp
.oe_dashboard_layout_1 .oe_dashboard_column
&.index_0
width: 100%
&.index_1, &.index_2
display: none
.oe_dashboard_layout_1-1 .oe_dashboard_column
width: 50%
&.index_2
display: none
.oe_dashboard_layout_1-1-1 .oe_dashboard_column
width: 33%
.oe_dashboard_layout_2-1 .oe_dashboard_column
&.index_0
width: 70%
&.index_1
width: 30%
&.index_2
display: none
.oe_dashboard_layout_1-2 .oe_dashboard_column
&.index_0
width: 30%
&.index_1
width: 70%
&.index_2
display: none
.oe_dashboard_layout_selector
ul
white-space: nowrap
@ -98,3 +123,4 @@
> tbody
tr:nth-child(odd)
background: transparent

View File

@ -24,6 +24,10 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
scroll: false
}).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});
});
// 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);
@ -165,8 +169,6 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
this.rpc('/web/view/add_custom', {
view_id: this.view.fields_view.view_id,
arch: arch
}, function() {
self.$el.find('.oe_dashboard_link_reset').show();
});
},
on_load_action: function(result, index, action_attrs) {

View File

@ -1,7 +1,7 @@
<template>
<t t-name="DashBoard">
<div class="oe_dashboard_links">
<button type="button" class="button oe_dashboard_link_reset" title="Reset Layout.." t-att-style="view.fields_view.custom_view_id ? null : 'display: none'">
<button type="button" class="button oe_dashboard_link_reset" title="Reset Layout.." t-att-style="view.fields_view.custom_view_id || session.debug ? null : 'display: none'">
<img src="/board/static/src/img/layout_2-1.png" width="16" height="16"/>
<span> Reset </span>
</button>

View File

@ -30,7 +30,9 @@ Create a claim from a delivery order.
Adds a Claim link to the delivery order.
""",
'data' : ['claim_delivery_view.xml'],
'data' : [
'claim_delivery_view.xml',
'claim_delivery_data.xml',],
'auto_install': False,
'installable': True,
'certificate' : '001101649349223746957',

View File

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<openerp>
<data>
<record model="res.request.link" id="request_link_claim_from_delivery">
<field name="name">Delivery Order</field>
<field name="object">stock.picking.out</field>
</record>
</data>
</openerp>

View File

@ -1,11 +1,27 @@
<openerp>
<data>
<act_window id="action_claim_from_delivery" name="Claim"
domain="[]" target="current"
context="{'default_partner_id': partner_id}"
view_mode="form" res_model="crm.claim"
src_model="stock.picking" />
<record id="action_claim_from_delivery" model="ir.actions.act_window">
<field name="name">Claim From Delivery</field>
<field name="res_model">crm.claim</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm_claim.crm_case_claims_tree_view"/>
<field name="context">{'default_ref': 'stock.picking.out,'+str(context.get('active_id', False))}</field>
<field name="domain">[('ref','=','stock.picking.out,'+str(context.get('active_id',False)))]</field>
</record>
<record id="crm_claim_from_delivery" model="ir.ui.view">
<field name="name">crm.claim.from_delivery.form</field>
<field name="model">stock.picking.out</field>
<field name="inherit_id" ref="stock.view_picking_out_form"/>
<field name="arch" type="xml">
<xpath expr="/form/sheet/h1" position="before">
<div class="oe_right oe_button_box">
<button name="%(action_claim_from_delivery)d" string="Claims" type="action"/>
</div>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

View File

@ -18,28 +18,27 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv
class res_company(osv.osv):
_inherit = "res.company"
_description = 'Company'
def _get_default_ad(self, addresses):
name = email = phone = city = post_code = address = country_code = ""
for ads in addresses:
if ads.type == 'default':
city = ads.city or ""
post_code = ads.zip or ""
if ads.street:
address = ads.street or ""
if ads.street2:
address += " " + ads.street2
if ads.country_id:
country_code = ads.country_id and ads.country_id.code or ""
name = ads.name or ""
email = ads.email or ""
phone = ads.phone or ""
return name, email, phone, city, post_code, address, country_code
res_company()
{
'name': 'Address Book',
'version': '1.0',
'category': 'Tools',
'description': """
This module gives you a quick view of your address book, accessible from your home page.
You can track your suppliers, customers and other contacts.
""",
'author': 'OpenERP SA',
'website': 'http://openerp.com',
'summary': 'Contacts, People and Companies',
'depends': [
'mail',
],
'data': [
'contacts_view.xml',
],
'installable': True,
'application': True,
'auto_install': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,53 @@
<?xml version="1.0" ?>
<openerp>
<data>
<record id="action_contacts" model="ir.actions.act_window">
<field name="name">Contacts</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="search_view_id" ref="base.view_res_partner_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a contact in your address book.
</p><p>
OpenERP helps you easily track all activities related to
a customer; discussions, history of business opportunities,
documents, etc.
</p>
</field>
</record>
<record id="action_contacts_view_kanban" model="ir.actions.act_window.view">
<field eval="0" name="sequence"/>
<field name="view_mode">kanban</field>
<field name="view_id" ref="base.res_partner_kanban_view"/>
<field name="act_window_id" ref="action_contacts"/>
</record>
<record id="action_contacts_view_tree" model="ir.actions.act_window.view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="base.view_partner_tree"/>
<field name="act_window_id" ref="action_contacts"/>
</record>
<record id="action_contacts_view_form" model="ir.actions.act_window.view">
<field eval="2" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="base.view_partner_form"/>
<field name="act_window_id" ref="action_contacts"/>
</record>
<menuitem name="Contacts"
id="menu_contacts"
parent="mail.mail_my_stuff"
sequence="11"
action="action_contacts"
groups="base.group_user,base.group_partner_manager"/>
</data>
</openerp>

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -25,7 +25,7 @@
'version': '1.0',
'category': 'Customer Relationship Management',
'sequence': 2,
'summary': 'Leads, Opportunities, Agenda',
'summary': 'Leads, Opportunities, Phone Calls',
'description': """
The generic OpenERP Customer Relationship Management
=====================================================

View File

@ -92,9 +92,10 @@ class crm_case_stage(osv.osv):
_defaults = {
'sequence': lambda *args: 1,
'probability': lambda *args: 0.0,
'state': 'draft',
'state': 'open',
'fold': False,
'type': 'both',
'case_default': True,
}
class crm_case_section(osv.osv):

View File

@ -132,8 +132,6 @@
<header>
<button name="%(crm.action_crm_lead2opportunity_partner)d" string="Convert to Opportunity" type="action"
states="draft,open,pending" help="Convert to Opportunity" class="oe_highlight"/>
<button name="case_escalate" string="Escalate" type="object"
states="draft,open,pending"/>
<button name="case_reset" string="Reset" type="object"
states="cancel"/>
<button name="case_cancel" string="Cancel" type="object"
@ -188,7 +186,11 @@
</group>
<group>
<field name="user_id"/>
<field name="section_id"/>
<label for="section_id"/>
<div>
<field name="section_id"/>
<button name="case_escalate" string="Escalate" type="object" states="draft,open,pending"/>
</div>
<field name="type" invisible="1"/>
</group>
<group>
@ -402,8 +404,6 @@
states="draft,open,pending" class="oe_highlight"/>
<button name="case_mark_lost" string="Mark Lost" type="object"
states="draft,open" class="oe_highlight"/>
<button name="case_escalate" string="Escalate" type="object"
states="open" />
<field name="stage_id" widget="statusbar" clickable="True"/>
</header>
<sheet>
@ -449,7 +449,11 @@
<group>
<field name="user_id"/>
<field name="section_id" colspan="1" widget="selection"/>
<label for="section_id"/>
<div>
<field name="section_id" widget="selection"/>
<button name="case_escalate" string="Escalate" type="object" states="draft,open,pending" />
</div>
</group>
<group>
<field name="categ_ids"

View File

@ -104,56 +104,55 @@
<field name="arch" type="xml">
<form string="Phone Call" version="7.0">
<header>
<button name="case_close" string="Held" type="object" class="oe_highlight"
<button name="case_close" string="Call Done" type="object" class="oe_highlight"
states="open,pending"/>
<button name="case_reset" string="Reset to Todo" type="object"
states="cancel"/>
<button string="Convert to Opportunity"
name="%(phonecall2opportunity_act)d"
type="action"
attrs="{'invisible':[ '|', ('opportunity_id','!=',False), ('state','!=', 'open')]}"/>
<button string="Convert to Opportunity" class="oe_highlight"
name="%(phonecall2opportunity_act)d"
type="action"
attrs="{'invisible':[ '|', ('opportunity_id','!=',False), ('state','!=', 'done')]}"/>
<button string="Schedule Other Call"
name="%(phonecall_to_phonecall_act)d"
type="action"/>
<button string="Schedule a Meeting" name="action_make_meeting" type="object"/>
<button name="case_cancel" string="Cancel" type="object"
states="draft,open,pending"/>
<field name="state" widget="statusbar" nolabel="1" statusbar_visible="open,done"/>
</header>
<sheet string="Phone Call">
<div class="oe_title">
<div class="oe_edit_only">
<label for="name" string="Title"/>
</div>
<h1><field name="name" required="1"/></h1>
<div class="oe_edit_only">
<label for="partner_phone" string="Phone"/>
</div>
<h2><field name="partner_phone"/></h2>
</div>
<group col="4">
<field name="date"/>
<field name="user_id"/>
<field name="duration" widget="float_time"/>
<field name="section_id" colspan="1" widget="selection"/>
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
<field name="categ_id" widget="selection"
domain="[('object_id.model', '=', 'crm.phonecall')]"/>
<field name="partner_mobile"/>
<field name="priority"/>
<field name="opportunity_id"/>
</group>
<sheet string="Phone Call">
<div class="oe_right">
<button string="Convert to Opportunity"
name="%(phonecall2opportunity_act)d"
type="action"
attrs="{'invisible':[ '|', ('opportunity_id','!=',False), ('state', 'not in', ('open', 'done'))]}"/>
<button string="Schedule Other Call"
name="%(phonecall_to_phonecall_act)d"
type="action"/>
<button string="Schedule a Meeting" name="action_make_meeting" type="object"/>
</div>
<div class="oe_title">
<div class="oe_edit_only">
<label for="name" string="Title"/>
</div>
<h1><field name="name" required="1"/></h1>
<div class="oe_edit_only">
<label for="partner_phone" string="Phone"/>
</div>
<h2><field name="partner_phone"/></h2>
</div>
<group col="4">
<field name="date"/>
<field name="user_id"/>
<field name="duration" widget="float_time"/>
<field name="section_id" colspan="1" widget="selection"/>
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
<field name="categ_id" widget="selection"
domain="[('object_id.model', '=', 'crm.phonecall')]"/>
<field name="partner_mobile"/>
<field name="priority"/>
<field name="opportunity_id"/>
</group>
<field name="description" placeholder="Description..."/>
</sheet>
<div class="oe_chatter">
<field name="message_ids" widget="mail_thread"/>
<field name="message_follower_ids" widget="mail_followers"/>
</div>
<field name="description" placeholder="Description..."/>
</sheet>
<div class="oe_chatter">
<field name="message_ids" widget="mail_thread"/>
<field name="message_follower_ids" widget="mail_followers"/>
</div>
</form>
</field>
</record>

View File

@ -130,10 +130,10 @@
<field name="arch" type="xml">
<xpath expr="//div[@name='buttons']" position="inside">
<button type="action"
string="Schedule a Meeting"
string="Meetings"
name="%(base_calendar.action_crm_meeting)d"
context="{'search_default_partner_ids': active_id, 'default_partner_ids' : [active_id]}"/>
<button type="action" string="Schedule a Call"
<button type="action" string="Calls"
name="%(crm.crm_case_categ_phone_create_partner)d"
context="{'search_default_partner_id': active_id, 'default_duration': 1.0}" />
<button type="action" string="Opportunities" attrs="{'invisible': [('customer', '=', False)]}"

View File

@ -259,10 +259,10 @@
<record id="view_picking_withweight_internal_move_form" model="ir.ui.view">
<field name="name">stock.picking_withweight.internal.move.form.view</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_move_picking_tree"/>
<field name="arch" type="xml">
<xpath expr="/form/sheet/notebook/page/field[@name='move_lines']/tree/field[@name='product_uom']" position="after">
<xpath expr="//field[@name='product_uom']" position="after">
<field name="weight"/>
<field name="weight_net" groups="base.group_no_one"/>
</xpath>
@ -306,7 +306,7 @@
<record id="view_delivery_order_inherit_stock" model="ir.ui.view">
<field name="name">stock.picking.out.form</field>
<field name="model">stock.picking</field>
<field name="model">stock.picking.out</field>
<field name="inherit_id" ref="stock.view_picking_out_form"/>
<field name="arch" type="xml">
<xpath expr="/form/header//button[@string='Create Invoice/Refund']" position="after">

View File

@ -44,10 +44,6 @@ Web pages
'auto_install': False,
'certificate': '0086363630317',
'images': [],
'js': [
'static/src/lib/wiky/wiky.js',
'static/src/js/document_page.js'
],
'css' : ['static/src/css/document_page.css'],
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -23,24 +23,28 @@ Additional ressources
<field name="name">OpenERP 6.1. Functional Demo</field>
<field name="parent_id" ref="demo_category1"/>
<field name="content">
The news is out, OpenERP's latest version 6.1. is here. It's more
user-friendly, even more business oriented and efficient to manage your company
How to discover the latest version 6.1.?
Demo : [http://demo.openerp.com]
Online: [http://openerp.com/online]
Download: [http://openerp.com/downloads]
We have also put together a functional demo that presents 6.1. Watch this video
to learn directly from us what OpenERP 6.1. can do for you. Share it in your
company, with your clients and implement it now for your business.
==Watch on Youtube!==
[[Video:http://www.youtube.com/embed/7jES2jxKMso ]]
<![CDATA[
<br>
<br>
The news is out, OpenERP's latest version 6.1. is here. It's more<br>
user-friendly, even more business oriented and efficient to manage your company<br>
<br>
How to discover the latest version 6.1.?<br>
<br>
Demo : <a target="http://demo.openerp.com" href="http://demo.openerp.com" style="background: url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFZJREFUeF59z4EJADEIQ1F36k7u5E7ZKXeUQPACJ3wK7UNokVxVk9kHnQH7bY9hbDyDhNXgjpRLqFlo4M2GgfyJHhjq8V4agfrgPQX3JtJQGbofmCHgA/nAKks+JAjFAAAAAElFTkSuQmCC&quot;) no-repeat scroll right center transparent;padding-right: 13px;"></a><br>
Online: <a target="http://openerp.com/online" href="http://openerp.com/online" style="background: url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFZJREFUeF59z4EJADEIQ1F36k7u5E7ZKXeUQPACJ3wK7UNokVxVk9kHnQH7bY9hbDyDhNXgjpRLqFlo4M2GgfyJHhjq8V4agfrgPQX3JtJQGbofmCHgA/nAKks+JAjFAAAAAElFTkSuQmCC&quot;) no-repeat scroll right center transparent;padding-right: 13px;"></a><br>
Download: <a target="http://openerp.com/downloads" href="http://openerp.com/downloads" style="background: url(&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFZJREFUeF59z4EJADEIQ1F36k7u5E7ZKXeUQPACJ3wK7UNokVxVk9kHnQH7bY9hbDyDhNXgjpRLqFlo4M2GgfyJHhjq8V4agfrgPQX3JtJQGbofmCHgA/nAKks+JAjFAAAAAElFTkSuQmCC&quot;) no-repeat scroll right center transparent;padding-right: 13px;"></a><br>
<br>
We have also put together a functional demo that presents 6.1. Watch this video<br>
to learn directly from us what OpenERP 6.1. can do for you. Share it in your<br>
company, with your clients and implement it now for your business.<br>
<br>
<h3>Watch on Youtube!</h3><br>
<br>
<iframe width="480" height="390" src="http://www.youtube.com/embed/7jES2jxKMso " frameborder="0" allowfullscreen=""></iframe><br>
<br>
<br>
]]>
</field>
</record>
@ -48,36 +52,40 @@ company, with your clients and implement it now for your business.
<field name="name">Personalise Dashboards</field>
<field name="parent_id" ref="demo_category1"/>
<field name="content">
You like OpenERP, but feel like you want to personalise it more? Now, OpenERP
goes a step further and lets you customize your dashboard. Thanks to a new
feature that allows you to customize your dashboard by adding new boards of any
search view.
==How is it done?==
Step 1: access one search view
Step 2: apply the filter you want to see at each connection to the application
(eg. on sales, manufacturing, etc)
Step 3: add it into the dashboard in the same space where you can save the filter
Step 4: choose the application you want it visible on and the name of the array
Look at this simple example below from Purchase, where I want to put on the
application's dashboard "Purchases to Approve". After I access the search view
and apply the filter for "Purchases to Approve", I can add it immediately to my
Purchase dashboard.
[[File:http://www.openerp.com/sites/default/files/fileattach/dashboard2_1(1).png ]]
In less than a minute, the search view is visible on the dashboard
[[File:http://www.openerp.com/sites/default/files/fileattach/dashboard2_2.png ]]
Of course, you are free to delete what you don't need or like, but just in case
you change your mind there is a reset button to return to the default view.
<![CDATA[
<br>
You like OpenERP, but feel like you want to personalise it more? Now, OpenERP<br>
goes a step further and lets you customize your dashboard. Thanks to a new<br>
feature that allows you to customize your dashboard by adding new boards of any<br>
search view.<br>
<br>
<h3>How is it done?</h3><br>
<br>
Step 1: access one search view <br>
<br>
Step 2: apply the filter you want to see at each connection to the application<br>
(eg. on sales, manufacturing, etc)<br>
<br>
Step 3: add it into the dashboard in the same space where you can save the filter<br>
<br>
Step 4: choose the application you want it visible on and the name of the array<br>
<br>
Look at this simple example below from Purchase, where I want to put on the<br>
application's dashboard "Purchases to Approve". After I access the search view<br>
and apply the filter for "Purchases to Approve", I can add it immediately to my<br>
Purchase dashboard.<br>
<br>
<img src="http://www.openerp.com/sites/default/files/fileattach/dashboard2_1(1).png" alt=""><br>
<br>
In less than a minute, the search view is visible on the dashboard<br>
<br>
<img src="http://www.openerp.com/sites/default/files/fileattach/dashboard2_2.png" alt=""><br>
<br>
Of course, you are free to delete what you don't need or like, but just in case<br>
you change your mind there is a reset button to return to the default view.<br>
<br>
<br>
]]>
</field>
</record>
@ -85,36 +93,36 @@ you change your mind there is a reset button to return to the default view.
<field name="name">Touchscreen Point of Sale</field>
<field name="parent_id" ref="demo_category1"/>
<field name="content">
The brand new OpenERP touchscreen point of sale available with 6.1 allows you
to manage your shop sales very easily. It's fully web based so that you don't
have to install or deploy any software and all the sales shops can be easily
consolidated. It works in connected and disconnected modes so that you can
continue to sell if you lose your internet connection.
[[File:http://www.openerp.com/sites/default/files/fileattach/POS(2).png ]]
==Here's a summary of its main features and benefits:==
100% WEB based
* available for any touchscreen device (ipod, ipad, any tablet)mobile (with portable devices)
* no installation required
* no synchronization needed, completely integrated
* continue working even when your connection is down if you close your browser, data won't be lost
* fully web based with a clean interface smart interface
You have different options to select your products. You can do it through the
barcode reader, just browse through the categories you have put in place (ie.
drinks, snacks, meals, etc.), or text search in case neither of the other
options work for you. If you need to use the POS for your restaurant, for
example, your employees can record at the same time multiple tickets without
having to wait to do one transaction at a time. Along, to facilitate payment,
the application allows multiple payment methods.
The POS application is so simple and accessible to use that your shop or
restaurant will never need any other tool to manage orders. Due to its smart
and user-friendly interface you don't need any training to learn how to use it.
Think of it as an out-of-the-box solution to boost your business' productivity.
<![CDATA[
<br>
The brand new OpenERP touchscreen point of sale available with 6.1 allows you<br>
to manage your shop sales very easily. It's fully web based so that you don't<br>
have to install or deploy any software and all the sales shops can be easily<br>
consolidated. It works in connected and disconnected modes so that you can<br>
continue to sell if you lose your internet connection.<br>
<br>
<img src="http://www.openerp.com/sites/default/files/fileattach/POS(2).png" alt=""><br>
<br>
<h3>Here's a summary of its main features and benefits:</h3><br>
<br>
100% WEB based<br>
<br>
<ul><li>available for any touchscreen device (ipod, ipad, any tablet)mobile (with portable devices)</li><li>no installation required</li><li>no synchronization needed, completely integrated</li><li>continue working even when your connection is down if you close your browser, data won't be lost</li><li>fully web based with a clean interface smart interface</li></ul><br>
<br>
You have different options to select your products. You can do it through the<br>
barcode reader, just browse through the categories you have put in place (ie.<br>
drinks, snacks, meals, etc.), or text search in case neither of the other<br>
options work for you. If you need to use the POS for your restaurant, for<br>
example, your employees can record at the same time multiple tickets without<br>
having to wait to do one transaction at a time. Along, to facilitate payment,<br>
the application allows multiple payment methods.<br>
<br>
The POS application is so simple and accessible to use that your shop or<br>
restaurant will never need any other tool to manage orders. Due to its smart<br>
and user-friendly interface you don't need any training to learn how to use it.<br>
Think of it as an out-of-the-box solution to boost your business' productivity.<br>
<br>
]]>
</field>
</record>

View File

@ -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="text_wiki" class="oe_view_only"/>
<field name="display_content" widget="html" class="oe_view_only" options='{"safe": true}'/>
</div>
</form>
</field>

View File

@ -1,18 +0,0 @@
openerp.document_page = function (openerp) {
openerp.web.form.widgets.add('text_wiki', 'openerp.web.form.FieldTextWiki');
openerp.web.form.FieldTextWiki = openerp.web.form.FieldText.extend({
render_value: function() {
var show_value = openerp.web.format_value(this.get('value'), this, '');
if (!this.get("effective_readonly")) {
this.$textarea.val(show_value);
if (show_value && this.view.options.resize_textareas) {
this.do_resize(this.view.options.resize_textareas);
}
} else {
var wiki_value = wiky.process(show_value || '');
this.$el.html(wiki_value);
}
},
});
};

View File

@ -1,41 +0,0 @@
Wiky.js - a javascript library to convert Wiki Markup language to HTML.
=======================
(It is buggy, please use with care)
Wiky.js is a javascript library that converts Wiki Markup language to HTML.
How to use it
-------------------
Include wiki.js into your HTML file. Wiky.js has only one function, which is wiky.process(wikitext).
Please see index.html for an example.
*wiky.js does not depend on jQuery, which is included for testing purpose.
Supported Syntax
-------------------
* == Heading ==
* === Subheading ===
* [http://www.url.com Name of URLs]
* [[File:http://www.url.com/image.png Alternative Text]]
* -------------------- (Horizontal line)
* : (Indentation)
* # Ordered bullet point
* * Unordered bullet point
License
------------------
Creative Commons 3.0
Contributors
-------------------
Tanin Na Nakorn
Tanun Niyomjit (Designer)

View File

@ -1,56 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="wiky.js"></script>
<title>Untitled Document</title>
<link href="wiky.css" rel="stylesheet" type="text/css">
</head>
<body>
<textarea id="textarea" onchange="$('#preview').html(wiky.process($(this).val()));" cols="60" rows="20">=== Heading ===
Some content
I would like to add another line
== Subheading ==
Some more content
Some more lines1
:A line with indent
:: A 2-indented line
:: more
:back to 1-indented line
This is Taeyeon.
[[File:http://www.oknation.net/blog/home/blog_data/12/2012/images/ty4.jpg Taeyeon]]
Taeyeon is so cute.
This is a link:[http://www.google.com Google].
This is a bold link:'''[http://www.google.com Google]'''.
This is a bold-italic link:'''''[http://www.google.com Google]'''''.
This is '''bold''', '''''bold-italic''''', and ''italic''
[[Video:http://www.youtube.com/embed/ovVfLancwys]]
# First
# secon
## Second-First
*** First Point
*** Second Point
#### z
#### y
#### x
*** Third Point
## Second-Second [ftp://www.facebook.com FacebookFTP]
## Second-Third [http://www.google.com Google Here]
# third
</textarea>
<br/>
<span style="display:block;width:600px;border:1px solid #999999;">
<span style="display:block;margin:10px 10px 10px 10px;" class="wiky_preview_area" id="preview">
</span>
</span>
</body>
</html>
<script language="javascript">
$('#preview').html(wiky.process($('#textarea').val()));
</script>

View File

@ -1,35 +0,0 @@
=== Heading ===
Some content
I would like to add another line
== Subheading ==
Some more content
Some more lines1
:A line with indent
:: A 2-indented line
:: more
:back to 1-indented line
This is Taeyeon.
[[File:http://www.oknation.net/blog/home/blog_data/12/2012/images/ty4.jpg Taeyeon]]
Taeyeon is so cute.
This is a link:[http://www.google.com Google].
This is a bold link:'''[http://www.google.com Google]'''.
This is a bold-italic link:'''''[http://www.google.com Google]'''''.
This is '''bold''', '''''bold-italic''''', and ''italic''
# First
# second
## Second-First
*** First Point
*** Second Point
#### z
#### y
#### x
*** Third Point
## Second-Second [ftp://www.facebook.com FacebookFTP]
## Second-Third [http://www.google.com Google Here]
# third

View File

@ -1,79 +0,0 @@
@charset "UTF-8";
.wiky_preview_area {
font-family: "Helvetica Neue", Arial, Helvetica, 'Liberation Sans', FreeSans, sans-serif;
font-size: 13px;
line-height: 1.5em;
color: #666;
font-weight:350;
width:600px;
display:block;
}
.wiky_preview_area h2{
font-size:24px;
color:#333;
font-weight:400;
text-shadow:0 1px 0 rgba(000, 000, 000, .4);
}
.wiky_preview_area h3{
font-size:18px;
color:#555;
font-weight:400;
text-shadow:0 1px 0 rgba(000, 000, 000, .4);
}
.wiky_preview_area img{
background-repeat: repeat;
width: 400px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, .8);
-moz-box-shadow:0 1px 3px rgba(0, 0, 0, .8);
box-shadow:0 1px 3px rgba(0, 0, 0, .8);
}
.wiky_preview_area a{
padding:5px;
font-weight:400;
background: #999; /* for non-css3 browsers */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#000000'); /* for IE */
background: -webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000)); /* for webkit browsers */
background: -moz-linear-gradient(top, #ccc, #000); /* for firefox 3.6+ */
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
-webkit-box-shadow:none;
-moz-box-shadow:none;
box-shadow:none;
text-shadow:0 1px 0 rgba(255, 255, 255, 1);
}
.wiky_preview_area a:hover{
color:#333;
padding:5px;
font-weight:400;
text-decoration:none;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, .3);
-moz-box-shadow:0 1px 3px rgba(0, 0, 0, .3);
box-shadow:0 1px 3px rgba(0, 0, 0, .3);
text-shadow:0 1px 0 rgba(255, 255, 255, 1);
}
.wiky_preview_area > ol,
.wiky_preview_area > ul,
.wiky_preview_area > ul > li,
.wiky_preview_area > ol > li {
list-style: disc inside none;
}

View File

@ -1,303 +0,0 @@
/**
* Wiky.js - Javascript library to converts Wiki MarkUp language to HTML.
* You can do whatever with it. Please give me some credits (Apache License)
* - Tanin Na Nakorn
*/
var wiky = {};
wiky.process = function(wikitext) {
var lines = wikitext.split(/\r?\n/);
var start;
var html = "";
for (var i=0;i<lines.length;i++)
{
var line = lines[i];
if (line.match(/^===/)!=null && line.match(/===$/)!=null)
{
html += "<h2>"+line.substring(3,line.length-3)+"</h2>";
}
else if (line.match(/^==/)!=null && line.match(/==$/)!=null)
{
html += "<h3>"+line.substring(2,line.length-2)+"</h3>";
}
else if (line.match(/^:+/)!=null)
{
// find start line and ending line
start = i;
while (i < lines.length && lines[i].match(/^:+/)!=null) i++;
i--;
html += wiky.process_indent(lines,start,i);
}
else if (line.match(/^----+(\s*)$/)!=null)
{
html += "<hr/>";
}
else if (line.match(/^(\*+) /)!=null)
{
// find start line and ending line
start = i;
while (i < lines.length && lines[i].match(/^(\*+|##+):? /)!=null) i++;
i--;
html += wiky.process_bullet_point(lines,start,i);
}
else if (line.match(/^(#+) /)!=null)
{
// find start line and ending line
start = i;
while (i < lines.length && lines[i].match(/^(#+|\*\*+):? /)!=null) i++;
i--;
html += wiky.process_bullet_point(lines,start,i);
}
else
{
html += wiky.process_normal(line);
}
html += "<br/>\n";
}
return html;
};
wiky.process_indent = function(lines,start,end) {
var html = "<dl>";
for(var i=start;i<=end;i++) {
html += "<dd>";
var this_count = lines[i].match(/^(:+)/)[1].length;
html += wiky.process_normal(lines[i].substring(this_count));
var nested_end = i;
for (var j=i+1;j<=end;j++) {
var nested_count = lines[j].match(/^(:+)/)[1].length;
if (nested_count <= this_count) break;
else nested_end = j;
}
if (nested_end > i) {
html += wiky.process_indent(lines,i+1,nested_end);
i = nested_end;
}
html += "</dd>";
}
html += "</dl>";
return html;
};
wiky.process_bullet_point = function(lines,start,end) {
var html = (lines[start].charAt(0)=='*')?"<ul>":"<ol>";
for(var i=start;i<=end;i++) {
html += "<li>";
var this_count = lines[i].match(/^(\*+|#+) /)[1].length;
html += wiky.process_normal(lines[i].substring(this_count+1));
// continue previous with #:
{
var nested_end = i;
for (var j = i + 1; j <= end; j++) {
var nested_count = lines[j].match(/^(\*+|#+):? /)[1].length;
if (nested_count < this_count)
break;
else {
if (lines[j].charAt(nested_count) == ':') {
html += "<br/>" + wiky.process_normal(lines[j].substring(nested_count + 2));
nested_end = j;
} else {
break;
}
}
}
i = nested_end;
}
// nested bullet point
{
var nested_end = i;
for (var j = i + 1; j <= end; j++) {
var nested_count = lines[j].match(/^(\*+|#+):? /)[1].length;
if (nested_count <= this_count)
break;
else
nested_end = j;
}
if (nested_end > i) {
html += wiky.process_bullet_point(lines, i + 1, nested_end);
i = nested_end;
}
}
// continue previous with #:
{
var nested_end = i;
for (var j = i + 1; j <= end; j++) {
var nested_count = lines[j].match(/^(\*+|#+):? /)[1].length;
if (nested_count < this_count)
break;
else {
if (lines[j].charAt(nested_count) == ':') {
html += wiky.process_normal(lines[j].substring(nested_count + 2));
nested_end = j;
} else {
break;
}
}
}
i = nested_end;
}
html += "</li>";
}
html += (lines[start].charAt(0)=='*')?"</ul>":"</ol>";
return html;
};
wiky.process_url = function(txt) {
var index = txt.indexOf(" ");
if (index == -1)
{
return "<a target='"+txt+"' href='"+txt+"' style='background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFZJREFUeF59z4EJADEIQ1F36k7u5E7ZKXeUQPACJ3wK7UNokVxVk9kHnQH7bY9hbDyDhNXgjpRLqFlo4M2GgfyJHhjq8V4agfrgPQX3JtJQGbofmCHgA/nAKks+JAjFAAAAAElFTkSuQmCC\") no-repeat scroll right center transparent;padding-right: 13px;'></a>";
}
else
{
var url = txt.substring(0,index);
var label = txt.substring(index+1);
return "<a target='"+url+"' href='"+url+"' style='background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFZJREFUeF59z4EJADEIQ1F36k7u5E7ZKXeUQPACJ3wK7UNokVxVk9kHnQH7bY9hbDyDhNXgjpRLqFlo4M2GgfyJHhjq8V4agfrgPQX3JtJQGbofmCHgA/nAKks+JAjFAAAAAElFTkSuQmCC\") no-repeat scroll right center transparent;padding-right: 13px;'>"+label+"</a>";
}
};
wiky.process_image = function(txt) {
var index = txt.indexOf(" ");
var url = txt;
var label = "";
if (index > -1)
{
url = txt.substring(0,index);
label = txt.substring(index+1);
}
return "<img src='"+url+"' alt=\""+label+"\" />";
};
wiky.process_video = function(url) {
if (url.match(/^(https?:\/\/)?(www.)?youtube.com\//) == null)
{
return "<b>"+url+" is an invalid YouTube URL</b>";
}
var result;
if ((result = url.match(/^(https?:\/\/)?(www.)?youtube.com\/watch\?(.*)v=([^&]+)/)) != null)
{
url = "http://www.youtube.com/embed/"+result[4];
}
return '<iframe width="480" height="390" src="'+url+'" frameborder="0" allowfullscreen></iframe>';
};
wiky.process_normal = function(wikitext) {
// Image
{
var index = wikitext.indexOf("[[File:");
var end_index = wikitext.indexOf("]]", index + 7);
while (index > -1 && end_index > -1) {
wikitext = wikitext.substring(0,index)
+ wiky.process_image(wikitext.substring(index+7,end_index))
+ wikitext.substring(end_index+2);
index = wikitext.indexOf("[[File:");
end_index = wikitext.indexOf("]]", index + 7);
}
}
// Video
{
var index = wikitext.indexOf("[[Video:");
var end_index = wikitext.indexOf("]]", index + 8);
while (index > -1 && end_index > -1) {
wikitext = wikitext.substring(0,index)
+ wiky.process_video(wikitext.substring(index+8,end_index))
+ wikitext.substring(end_index+2);
index = wikitext.indexOf("[[Video:");
end_index = wikitext.indexOf("]]", index + 8);
}
}
// URL
var protocols = ["http","ftp","news"];
for (var i=0;i<protocols.length;i++)
{
var index = wikitext.indexOf("["+protocols[i]+"://");
var end_index = wikitext.indexOf("]", index + 1);
while (index > -1 && end_index > -1) {
wikitext = wikitext.substring(0,index)
+ wiky.process_url(wikitext.substring(index+1,end_index))
+ wikitext.substring(end_index+1);
index = wikitext.indexOf("["+protocols[i]+"://",end_index+1);
end_index = wikitext.indexOf("]", index + 1);
}
}
var count_b = 0;
var index = wikitext.indexOf("'''");
while(index > -1) {
if ((count_b%2)==0) wikitext = wikitext.replace(/'''/,"<b>");
else wikitext = wikitext.replace(/'''/,"</b>");
count_b++;
index = wikitext.indexOf("'''",index);
}
var count_i = 0;
var index = wikitext.indexOf("''");
while(index > -1) {
if ((count_i%2)==0) wikitext = wikitext.replace(/''/,"<i>");
else wikitext = wikitext.replace(/''/,"</i>");
count_i++;
index = wikitext.indexOf("''",index);
}
wikitext = wikitext.replace(/<\/b><\/i>/g,"</i></b>");
return wikitext;
};

View File

@ -38,7 +38,7 @@ when you confirm your sale order it will automatically create a registration for
this event.
""",
'author': 'OpenERP SA',
'depends': ['event','sale','sale_crm'],
'depends': ['event', 'sale_crm'],
'data': ['event_sale_view.xml'],
'demo': ['event_demo.xml'],
'test': ['test/confirm.yml'],

333
addons/fetchmail/i18n/mk.po Normal file
View File

@ -0,0 +1,333 @@
# Macedonian 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-09-18 16:07+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Macedonian <mk@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-09-19 04:37+0000\n"
"X-Generator: Launchpad (build 15966)\n"
#. module: fetchmail
#: selection:fetchmail.server,state:0
msgid "Confirmed"
msgstr "Потврдено"
#. module: fetchmail
#: field:fetchmail.server,server:0
msgid "Server Name"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,script:0
msgid "Script"
msgstr ""
#. module: fetchmail
#: help:fetchmail.server,priority:0
msgid "Defines the order of processing, lower values mean higher priority"
msgstr ""
#. module: fetchmail
#: help:fetchmail.server,is_ssl:0
msgid ""
"Connections are encrypted with SSL/TLS through a dedicated port (default: "
"IMAPS=993, POP3S=995)"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,attach:0
msgid "Keep Attachments"
msgstr ""
#. module: fetchmail
#: help:fetchmail.server,original:0
msgid ""
"Whether a full original copy of each email should be kept for referenceand "
"attached to each processed message. This will usually double the size of "
"your message database."
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,priority:0
msgid "Server Priority"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,state:0
msgid "State"
msgstr "Состојба"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "POP"
msgstr "POP"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Fetch Now"
msgstr ""
#. module: fetchmail
#: model:ir.actions.act_window,name:fetchmail.action_email_server_tree
#: model:ir.ui.menu,name:fetchmail.menu_action_fetchmail_server_tree
msgid "Incoming Mail Servers"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,port:0
msgid "Port"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "POP/IMAP Servers"
msgstr "POP/IMAP сервери"
#. module: fetchmail
#: selection:fetchmail.server,type:0
msgid "Local Server"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,user:0
msgid "Username"
msgstr ""
#. module: fetchmail
#: model:ir.model,name:fetchmail.model_fetchmail_server
msgid "POP/IMAP Server"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Reset Confirmation"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "SSL"
msgstr ""
#. module: fetchmail
#: model:ir.model,name:fetchmail.model_mail_message
msgid "Email Message"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,date:0
msgid "Last Fetch Date"
msgstr ""
#. module: fetchmail
#: help:fetchmail.server,action_id:0
msgid ""
"Optional custom server action to trigger for each incoming mail, on the "
"record that was created or updated by this mail"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "# of emails"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,original:0
msgid "Keep Original"
msgstr ""
#. module: fetchmail
#: code:addons/fetchmail/fetchmail.py:155
#, python-format
msgid ""
"Here is what we got instead:\n"
" %s"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
#: field:fetchmail.server,configuration:0
msgid "Configuration"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Incoming Mail Server"
msgstr ""
#. module: fetchmail
#: code:addons/fetchmail/fetchmail.py:155
#, python-format
msgid "Connection test failed!"
msgstr ""
#. module: fetchmail
#: help:fetchmail.server,server:0
msgid "Hostname or IP of the mail server"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Server type IMAP."
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,name:0
msgid "Name"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,is_ssl:0
msgid "SSL/TLS"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Test & Confirm"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,action_id:0
msgid "Server Action"
msgstr ""
#. module: fetchmail
#: field:mail.message,fetchmail_server_id:0
msgid "Inbound Mail Server"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,message_ids:0
#: model:ir.actions.act_window,name:fetchmail.act_server_history
msgid "Messages"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Search Incoming Mail Servers"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,active:0
msgid "Active"
msgstr ""
#. module: fetchmail
#: help:fetchmail.server,attach:0
msgid ""
"Whether attachments should be downloaded. If not enabled, incoming emails "
"will be stripped of any attachments before being processed"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Advanced Options"
msgstr ""
#. module: fetchmail
#: selection:fetchmail.server,type:0
msgid "IMAP Server"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "IMAP"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Server type POP."
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,password:0
msgid "Password"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Actions to Perform on Incoming Mails"
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,type:0
msgid "Server Type"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Login Information"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Server Information"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "If SSL required."
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Advanced"
msgstr ""
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Server & Login"
msgstr ""
#. module: fetchmail
#: help:fetchmail.server,object_id:0
msgid ""
"Process each incoming mail as part of a conversation corresponding to this "
"document type. This will create new documents for new conversations, or "
"attach follow-up emails to the existing conversations (documents)."
msgstr ""
#. module: fetchmail
#: field:fetchmail.server,object_id:0
msgid "Create a New Record"
msgstr ""
#. module: fetchmail
#: selection:fetchmail.server,state:0
msgid "Not Confirmed"
msgstr "Непотврдено"
#. module: fetchmail
#: selection:fetchmail.server,type:0
msgid "POP Server"
msgstr ""
#. module: fetchmail
#: view:mail.message:0
msgid "Mail Server"
msgstr ""
#~ msgid "Confirm"
#~ msgstr "Потврди"
#~ msgid "Group By..."
#~ msgstr "Групирај по..."
#~ msgid "Type"
#~ msgstr "Вид"
#~ msgid ""
#~ "Warning! Record for selected Model can not be created\n"
#~ "Please choose valid Model"
#~ msgstr ""
#~ "Предупредување! Записот за избраниот Модел не може да се креира\n"
#~ "Изберете валиден Модел"

View File

@ -0,0 +1,33 @@
# Icelandic 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-09-19 10:00+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Icelandic <is@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-09-20 04:43+0000\n"
"X-Generator: Launchpad (build 15985)\n"
#. module: google_map
#: view:res.partner:0
msgid "Map"
msgstr "Landakort"
#. module: google_map
#: model:ir.model,name:google_map.model_res_partner_address
msgid "Partner Addresses"
msgstr "Heimilisfang viðskiptaaðila"
#. module: google_map
#: view:res.partner:0
msgid "Street2 : "
msgstr "Gata2 : "

View File

@ -261,7 +261,6 @@ class hr_employee(osv.osv):
_defaults = {
'active': 1,
'image': _get_default_image,
'marital': 'single',
'color': 0,
}

View File

@ -180,7 +180,7 @@
<field name="name">Employees</field>
<field name="res_model">hr.employee</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" eval="False"/>
<field name="search_view_id" ref="view_employee_filter"/>
</record>

View File

@ -17,7 +17,7 @@
<field name="name">Payroll</field>
<field name="res_model">ir.module.module</field>
<field name="view_mode">kanban,tree,form</field>
<field name="context" eval="{'search_default_category_id': ref('base.module_category_localization'), 'search_default_name': 'payroll'}"/>
<field name="context" eval="{'search_default_category_id': ref('base.module_category_localization')}"/>
<field name="search_view_id" ref="base.view_module_filter"/>
</record>

View File

@ -21,7 +21,7 @@
<field name="arch" type="xml">
<data>
<xpath expr="//div[@name='button_box']" position="inside">
<button name="%(act_hr_employee_2_hr_contract)d" string="Contracts" type="action"/>
<button name="%(act_hr_employee_2_hr_contract)d" string="Contracts" type="action" groups="base.group_hr_manager"/>
</xpath>
<xpath expr="//field[@name='coach_id']" position="after">
<field name="manager"/>

View File

@ -392,12 +392,6 @@ Once the form had been filled, the employee send it to his supervisor.
<field name="type">char</field>
<field eval="5" name="sequence"/>
</record>
<record id="survey_answer_98" model="survey.answer">
<field name="answer">Title</field>
<field name="question_id" ref="survey_question_2"/>
<field name="type">char</field>
<field eval="6" name="sequence"/>
</record>
<record id="survey_question_column_heading_4" model="survey.question.column.heading">
<field name="in_visible_rating_weight">1</field>
<field name="in_visible_menu_choice">1</field>

View File

@ -239,7 +239,7 @@
<field name="name">Appraisal</field>
<field name="res_model">hr_evaluation.evaluation</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,graph</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="hr_evaluation.evaluation_search"/>
<field name="context">{"search_default_next_month":1}</field>
<field name="help" type="html">

View File

@ -39,4 +39,4 @@ access_survey_response_hr_employee,survey.response.employee,survey.model_survey_
access_survey_question_column_heading_hr_employee,survey.question.column.heading.employee,survey.model_survey_question_column_heading,base.group_user,1,0,0,0
access_survey_response_line_hr_employee,survey.response.line.employee,survey.model_survey_response_line,base.group_user,1,1,1,0
access_survey_response_answer_hr_employee,survey.response.answer.hr.employee,survey.model_survey_response_answer,base.group_user,1,1,1,0
access_survey_tbl_column_heading_hr_employee,survey.tbl.column.heading,survey.model_survey_tbl_column_heading,base.group_user,1,1,1,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
39 access_survey_question_column_heading_hr_employee survey.question.column.heading.employee survey.model_survey_question_column_heading base.group_user 1 0 0 0
40 access_survey_response_line_hr_employee survey.response.line.employee survey.model_survey_response_line base.group_user 1 1 1 0
41 access_survey_response_answer_hr_employee survey.response.answer.hr.employee survey.model_survey_response_answer base.group_user 1 1 1 0
42 access_survey_tbl_column_heading_hr_employee survey.tbl.column.heading survey.model_survey_tbl_column_heading base.group_user 1 1 1 0

View File

@ -54,7 +54,6 @@
str(ref("survey_question_2")) +"_" +str(ref("survey_answer_20")) + "_multi" :'3',
str(ref("survey_question_2")) +"_" +str(ref("survey_answer_25")) + "_multi" :'2011-12-02 16:42:00',
str(ref("survey_question_2")) +"_" +str(ref("survey_answer_43")) + "_multi" :'HR',
str(ref("survey_question_2")) +"_" +str(ref("survey_answer_98")) + "_multi" :'tpa review'
}, context = ctx)
-
I close this Evaluation survey by giving answer of questions.

View File

@ -130,7 +130,7 @@
</page>
<page string="Other Info">
<group>
<group string="Accounting Data">
<group string="Accounting Data" groups="account.group_account_user">
<field name="journal_id" widget="selection" domain="[('type', '=', 'purchase')]"/>
<field name="voucher_id" context="{'form_view_ref': 'account_voucher.view_purchase_receipt_form'}"/>
</group>

View File

@ -92,7 +92,7 @@
<header>
<button string="Approve" name="validate" states="confirm" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button string="Validate" name="second_validate" states="validate1" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button string="Refuse" name="refuse" states="confirm,validate1,validate" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button string="Refuse" name="refuse" states="confirm,validate1,validate" type="workflow" groups="base.group_hr_user"/>
<button string="Reset to New" name="set_to_draft" states="refuse" type="object" groups="base.group_hr_user" />
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,validate" statusbar_colors='{"confirm":"blue","validate1":"blue","refuse":"red"}'/>
</header>
@ -137,7 +137,7 @@
<header>
<button string="Approve" name="validate" states="confirm" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button string="Validate" name="second_validate" states="validate1" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button string="Refuse" name="refuse" states="confirm,validate,validate1" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button string="Refuse" name="refuse" states="confirm,validate,validate1" type="workflow" groups="base.group_hr_user"/>
<button string="Reset to New" name="set_to_draft" states="cancel,refuse" type="object" groups="base.group_hr_user" />
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,validate" statusbar_colors='{"confirm":"blue","validate1":"blue","refuse":"red"}'/>
</header>
@ -483,6 +483,7 @@
<record id="hr_holidays_leaves_assign_tree_view" model="ir.ui.view">
<field name="name">hr.employee.leave.tree</field>
<field name="model">hr.employee</field>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<tree string="Assign Leaves" editable="bottom">
<field name="name" string="Employee"/>
@ -522,7 +523,7 @@
</group>
</xpath>
<xpath expr="//div[@name='button_box']" position="inside">
<button name="%(act_hr_employee_holiday_request)d" string="Leaves" type="action"/>
<button name="%(act_hr_employee_holiday_request)d" string="Leaves" type="action" groups="base.group_hr_user"/>
</xpath>
</field>
</record>

View File

@ -669,26 +669,26 @@ class hr_payslip(osv.osv):
if not context.get('contract', False):
#fill with the first contract of the employee
contract_ids = self.get_contract(cr, uid, employee_id, date_from, date_to, context=context)
res['value'].update({
'struct_id': contract_ids and contract_obj.read(cr, uid, contract_ids[0], ['struct_id'], context=context)['struct_id'][0] or False,
'contract_id': contract_ids and contract_ids[0] or False,
})
else:
if contract_id:
#set the list of contract for which the input have to be filled
contract_ids = [contract_id]
#fill the structure with the one on the selected contract
contract_record = contract_obj.browse(cr, uid, contract_id, context=context)
res['value'].update({
'struct_id': contract_record.struct_id.id,
'contract_id': contract_id
})
else:
#if we don't give the contract, then the input to fill should be for all current contracts of the employee
contract_ids = self.get_contract(cr, uid, employee_id, date_from, date_to, context=context)
if not contract_ids:
return res
if not contract_ids:
return res
contract_record = contract_obj.browse(cr, uid, contract_ids[0], context=context)
res['value'].update({
'contract_id': contract_record and contract_record.id or False
})
struct_record = contract_record and contract_record.struct_id or False
if not struct_record:
return res
res['value'].update({
'struct_id': struct_record.id,
})
#computation of the salary input
worked_days_line_ids = self.get_worked_day_lines(cr, uid, contract_ids, date_from, date_to, context=context)
input_line_ids = self.get_inputs(cr, uid, contract_ids, date_from, date_to, context=context)

View File

@ -234,7 +234,7 @@
</h2>
</div>
<group col="4">
<field name="contract_id" domain="[('employee_id','=',employee_id)]" on_change="onchange_contract_id(date_from, date_to, employee_id, contract_id)"/>
<field name="contract_id" domain="[('employee_id','=',employee_id)]" on_change="onchange_contract_id(date_from, date_to, employee_id, contract_id)" context="{'default_employee_id': employee_id}"/>
<field name="number"/>
<field name="struct_id" attrs="{'required':[('contract_id','&lt;&gt;',False)]}"/>
<field name="name"/>
@ -369,7 +369,7 @@
<field name="view_id" ref="view_hr_payslip_tree"/>
<field name="search_view_id" ref="view_hr_payslip_filter"/>
</record>
<menuitem action="action_view_hr_payslip_form" id="menu_department_tree" parent="menu_hr_root_payroll"/>
<menuitem action="action_view_hr_payslip_form" id="menu_department_tree" parent="menu_hr_root_payroll" groups="base.group_hr_user"/>
<act_window name="Payslips"
context="{'search_default_employee_id': [active_id], 'default_employee_id': active_id}"
res_model="hr.payslip"
@ -386,7 +386,7 @@
<field name="arch" type="xml">
<data>
<xpath expr="//div[@name='button_box']" position="inside">
<button name="%(act_hr_employee_payslip_list)d" string="Payslips" type="action"/>
<button name="%(act_hr_employee_payslip_list)d" string="Payslips" type="action" groups="base.group_hr_user"/>
</xpath>
</data>
</field>

View File

@ -314,9 +314,7 @@
</div>
<div class="oe_kanban_footer_left" style="margin-top:5px;">
<div class="oe_left oe_tags">
<t t-foreach="record.categ_ids.raw_value" t-as="categ_id">
<span class="oe_tag" t-att-data-categ_id="categ_id"></span>
</t>
<field name="categ_ids"/>
</div>
</div>
</div>

View File

@ -187,7 +187,7 @@
</record>
<menuitem action="act_hr_timesheet_sheet_form" id="menu_act_hr_timesheet_sheet_form" parent="hr_attendance.menu_hr_time_tracking"
sequence="2" groups="base.group_hr_user,base.group_hr_manager"/>
sequence="2" groups="base.group_hr_user"/>
<!--
Company inheritancy
@ -350,7 +350,7 @@
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_employee_extd_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='button_box']" position="inside">
<button name="%(act_hr_employee_2_hr_timesheet)d" string="Timesheets" type="action"/>
<button name="%(act_hr_employee_2_hr_timesheet)d" string="Timesheets" type="action" groups="base.group_hr_manager"/>
</xpath>
</field>
</record>

View File

@ -444,11 +444,9 @@ class sugar_import(import_framework):
import Tasks
"""
task_state = {
'Completed' : 'done',
'Completed' : 'open',
'Not Started':'draft',
'In Progress': 'open',
'Pending Input': 'draft',
'deferred': 'cancel'
}
def import_task(self, val):

View File

@ -19,7 +19,6 @@
#
##############################################################################
import company
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -45,8 +45,8 @@ class l10n_be_vat_declaration(osv.osv_memory):
'tax_code_id': fields.many2one('account.tax.code', 'Tax Code', domain=[('parent_id', '=', False)], required=True),
'msg': fields.text('File created', size=64, readonly=True),
'file_save': fields.binary('Save File'),
'ask_restitution': fields.boolean('Ask Restitution',help='It indicates whether a restitution is to made or not?'),
'ask_payment': fields.boolean('Ask Payment',help='It indicates whether a payment is to made or not?'),
'ask_restitution': fields.boolean('Ask Restitution',help='It indicates whether a restitution is to make or not?'),
'ask_payment': fields.boolean('Ask Payment',help='It indicates whether a payment is to make or not?'),
'client_nihil': fields.boolean('Last Declaration, no clients in client listing', help='Tick this case only if it concerns only the last statement on the civil or cessation of activity: ' \
'no clients to be included in the client listing.'),
'comments': fields.text('Comments'),
@ -70,6 +70,7 @@ class l10n_be_vat_declaration(osv.osv_memory):
obj_tax_code = self.pool.get('account.tax.code')
obj_acc_period = self.pool.get('account.period')
obj_user = self.pool.get('res.users')
obj_partner = self.pool.get('res.partner')
mod_obj = self.pool.get('ir.model.data')
if context is None:
@ -83,7 +84,7 @@ class l10n_be_vat_declaration(osv.osv_memory):
obj_company = obj_user.browse(cr, uid, uid, context=context).company_id
vat_no = obj_company.partner_id.vat
if not vat_no:
raise osv.except_osv(_('Insufficient Data!'), _('No VAT Number Associated with Main Company.'))
raise osv.except_osv(_('insufficient data!'), _('No VAT number associated with your company.'))
vat_no = vat_no.replace(' ','').upper()
vat = vat_no[2:]
@ -93,8 +94,9 @@ class l10n_be_vat_declaration(osv.osv_memory):
ctx['period_id'] = data['period_id'][0]
tax_info = obj_tax_code.read(cr, uid, tax_code_ids, ['code','sum_period'], context=ctx)
name = email = phone = address = post_code = city = country_code = ''
name, email, phone, city, post_code, address, country_code = self.pool.get('res.company')._get_default_ad(obj_company.partner_id)
default_address = obj_partner.address_get(cr, uid, [obj_company.partner_id.id])
default_address_id = default_address.get("default", obj_company.partner_id.id)
address_id= obj_partner.browse(cr, uid, default_address_id, context)
account_period = obj_acc_period.browse(cr, uid, data['period_id'][0], context=context)
issued_by = vat_no[:2]
@ -106,21 +108,21 @@ class l10n_be_vat_declaration(osv.osv_memory):
ending_month = account_period.date_stop[5:7]
quarter = str(((int(starting_month) - 1) / 3) + 1)
if not email:
if not address_id.email:
raise osv.except_osv(_('Insufficient Data!'),_('No email address associated with the company.'))
if not phone:
if not address_id.phone:
raise osv.except_osv(_('Insufficient Data!'),_('No phone associated with the company.'))
file_data = {
'issued_by': issued_by,
'vat_no': vat_no,
'only_vat': vat_no[2:],
'cmpny_name': obj_company.name,
'address': address,
'post_code': post_code,
'city': city,
'country_code': country_code,
'email': email,
'phone': phone.replace('.','').replace('/','').replace('(','').replace(')','').replace(' ',''),
'address': "%s %s"%(address_id.street or "",address_id.street2 or ""),
'post_code': address_id.zip or "",
'city': address_id.city or "",
'country_code': address_id.country_id and address_id.country_id.code or "",
'email': address_id.email or "",
'phone': address_id.phone.replace('.','').replace('/','').replace('(','').replace(')','').replace(' ',''),
'send_ref': send_ref,
'quarter': quarter,
'month': starting_month,

View File

@ -61,7 +61,7 @@ class partner_vat(osv.osv_memory):
company_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
period_ids = obj_period.search(cr, uid, [('date_start' ,'>=', date_start), ('date_stop','<=',date_stop), ('company_id','=',company_id)])
if not period_ids:
raise osv.except_osv(_('Insufficient Data!'), _('No data for the selected year.'))
raise osv.except_osv(_('insufficient data!'), _('No data for the selected year.'))
partners = []
partner_ids = obj_partner.search(cr, uid, [('vat_subjected', '!=', False), ('vat','ilike','BE%')], context=context)
@ -87,6 +87,9 @@ class partner_vat(osv.osv_memory):
if record['turnover'] >= data['limit_amount']:
id_client = obj_vat_lclient.create(cr, uid, record, context=context)
partners.append(id_client)
if not partners:
raise osv.except_osv(_('insufficient data!'), _('No data found for the selected year.'))
context.update({'partner_ids': partners, 'year': data['year'], 'limit_amount': data['limit_amount']})
model_data_ids = obj_model_data.search(cr, uid, [('model','=','ir.ui.view'), ('name','=','view_vat_listing')])
resource_id = obj_model_data.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id']
@ -190,7 +193,7 @@ class partner_vat_list(osv.osv_memory):
phone = ads.phone.replace(' ','') or ''
email = ads.email or ''
name = ads.name or ''
city = obj_partner.get_city(cr, uid, ads.id)
city = ads.city or ''
zip = obj_partner.browse(cr, uid, ads.id, context=context).zip or ''
if not city:
city = ''

View File

@ -6,18 +6,18 @@
<field name="model">partner.vat</field>
<field name="arch" type="xml">
<form string="Partner VAT Listing" version="7.0">
<header>
<p class="oe_grey">
This wizard will create an XML file for VAT details and total invoiced amounts per partner.
</p>
<group>
<field name="year"/>
<field name="limit_amount"/>
</group>
<footer>
<button name="get_partner" string="View Customers" type="object" class="oe_highlight" />
or
<button string="Cancel" class="oe_link" special="cancel" />
</header>
<group>
<label string="This wizard will create an XML file for VAT details and total invoiced amounts per partner." colspan="4"/>
</group>
<newline/>
<field name="year"/>
<newline/>
<field name="limit_amount"/>
</footer>
</form>
</field>
</record>

View File

@ -108,7 +108,7 @@ class partner_vat_intra(osv.osv_memory):
# Get Company vat
company_vat = data_company.partner_id.vat
if not company_vat:
raise osv.except_osv(_('Insufficient Data!'),_('No VAT number associated with the company.'))
raise osv.except_osv(_('insufficient data!'),_('No VAT number associated with your company.'))
company_vat = company_vat.replace(' ','').upper()
issued_by = company_vat[:2]

View File

@ -8,7 +8,7 @@
<field name="inherit_id" ref="account.view_partner_property_form" />
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='bank_ids']/form/field[@name='acc_number']" position="before">
<xpath expr="//field[@name='bank_ids']//field[@name='acc_number']" position="before">
<newline />
<field name="bank_code" />
<field name="office" />

View File

@ -25,6 +25,7 @@ import mail_message
import mail_mail
import mail_thread
import mail_group
import mail_vote
import res_partner
import res_users
import report

View File

@ -130,6 +130,8 @@ class mail_message(osv.Model):
'unread': fields.function(_get_unread, fnct_search=_search_unread,
type='boolean', string='Unread',
help='Functional field to search for unread messages linked to uid'),
'vote_user_ids': fields.many2many('res.users', 'mail_vote', 'message_id', 'user_id', string='Votes',
help='Users that voted for this message'),
}
def _needaction_domain_get(self, cr, uid, context=None):
@ -147,12 +149,35 @@ class mail_message(osv.Model):
'body': '',
}
#------------------------------------------------------
# Vote/Like
#------------------------------------------------------
def vote_toggle(self, cr, uid, ids, user_ids=None, context=None):
''' Toggles voting '''
if not user_ids:
user_ids = [uid]
for message in self.read(cr, uid, ids, ['vote_user_ids'], context=context):
for user_id in user_ids:
has_voted = user_id in message.get('vote_user_ids')
if not has_voted:
self.write(cr, uid, message.get('id'), {'vote_user_ids': [(4, user_id)]}, context=context)
else:
self.write(cr, uid, message.get('id'), {'vote_user_ids': [(3, user_id)]}, context=context)
return True
#------------------------------------------------------
# Message loading for web interface
#------------------------------------------------------
def _message_dict_get(self, cr, uid, msg, context=None):
""" Return a dict representation of the message browse record. """
has_voted = False
vote_ids = self.pool.get('res.users').name_get(cr, uid, [user.id for user in msg.vote_user_ids], context=context)
for vote in vote_ids:
if vote[0] == uid:
has_voted = True
break
attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)]
author_id = self.pool.get('res.partner').name_get(cr, uid, [msg.author_id.id], context=context)[0]
author_user_id = self.pool.get('res.users').name_get(cr, uid, [msg.author_id.user_ids[0].id], context=context)[0]
@ -171,6 +196,8 @@ class mail_message(osv.Model):
'author_user_id': author_user_id,
'partner_ids': partner_ids,
'child_ids': [],
'vote_user_ids': vote_ids,
'has_voted': has_voted
}
def message_read_tree_flatten(self, cr, uid, messages, current_level, level, context=None):

View File

@ -9,7 +9,8 @@
sequence="10"/>
<!-- Left-side menu: Feeds -->
<menuitem id="mail_feeds" name="Feeds" parent="mail_feeds_main" groups="base.group_user" sequence="10"/>
<menuitem id="mail_feeds" name="Feeds" parent="mail.mail_feeds_main" groups="base.group_user" sequence="10"/>
<menuitem id="mail_my_stuff" name="Organizer" parent="mail.mail_feeds_main"/>
<record id="mail_wallfeeds" model="ir.ui.menu">
<field name="name">My Feeds</field>

39
addons/mail/mail_vote.py Normal file
View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012-Today OpenERP SA (<http://www.openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
##############################################################################
from osv import osv, fields
class mail_vote(osv.Model):
''' Mail vote feature allow users to like and unlike messages attached
to a document. This allows for example to build a ranking-based
displaying of messages, for FAQ. '''
_name = 'mail.vote'
_description = 'Mail Vote'
_columns = {
'message_id': fields.many2one('mail.message', 'Message', select=1,
ondelete='cascade', required=True),
'user_id': fields.many2one('res.users', 'User', select=1,
ondelete='cascade', required=True),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -73,7 +73,7 @@ class res_users(osv.Model):
def create(self, cr, uid, data, context=None):
# create default alias same as the login
if not data.get('login', False):
raise osv.except_osv(_('Invalid Action!'), _('You may not create a user.'))
raise osv.except_osv(_('Invalid Action!'), _('You may not create a user. To create new users, you should use the "Settings > Users" menu.'))
mail_alias = self.pool.get('mail.alias')
alias_id = mail_alias.create_unique_alias(cr, uid, {'alias_name': data['login']}, model_name=self._name, context=context)

View File

@ -10,3 +10,4 @@ access_mail_alias_user,mail.alias,model_mail_alias,base.group_user,1,1,1,0
access_mail_alias_system,mail.alias,model_mail_alias,base.group_system,1,1,1,1
access_mail_mail_user,mail.mail,model_mail_mail,base.group_user,1,1,1,0
access_mail_mail_manager,mail.mail,model_mail_mail,group_mail_manager,1,1,1,1
access_mail_vote_all,mail.vote.all,model_mail_vote,,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
10 access_mail_alias_system mail.alias model_mail_alias base.group_system 1 1 1 1
11 access_mail_mail_user mail.mail model_mail_mail base.group_user 1 1 1 0
12 access_mail_mail_manager mail.mail model_mail_mail group_mail_manager 1 1 1 1
13 access_mail_vote_all mail.vote.all model_mail_vote 1 1 1 1

View File

@ -258,6 +258,36 @@
display: none;
}
/*--------------------------------------------------------------*/
/* mail.vote
/*--------------------------------------------------------------*/
.openerp .oe_mail_msg_content button.oe_mail_msg_vote {
height:21px;
width: 30px;
padding: 1px;
background: #8A89BA;
margin-top: -4px;
display: none;
}
.openerp .oe_mail_msg_content button.oe_mail_msg_vote_true {
background:#DC5F59;
}
.openerp .oe_mail_msg_content button.oe_mail_msg_vote span {
color: white;
}
.openerp .oe_mail_msg_content span.oe_mail_vote_count{
color: #807FB4;
}
.openerp .oe_mail_thread_msg:hover .oe_mail_msg_notification .oe_mail_msg_content .oe_mail_msg .oe_mail_msg_footer button.oe_mail_msg_vote {
display: inline !important;
}
/* ------------------------------------------------------------ */
/* mail.compose.message form view & OpenERP hacks
/* ------------------------------------------------------------ */

View File

@ -291,6 +291,7 @@ openerp.mail = function(session) {
truncate_limit: options.truncate_limit || 250,
}
// datasets and internal vars
this.records = {};
this.ds_thread = new session.web.DataSetSearch(this, this.context.default_model);
this.ds_notification = new session.web.DataSetSearch(this, 'mail.notification');
this.ds_message = new session.web.DataSetSearch(this, 'mail.message');
@ -355,6 +356,8 @@ openerp.mail = function(session) {
'default_parent_id': parseInt(msg_id),
'default_content_subtype': 'html'} );
});
// event: click on 'Vote' button
this.$el.on('click', 'button.oe_mail_msg_vote', this.on_vote);
},
on_message_delete: function (event) {
@ -373,6 +376,16 @@ openerp.mail = function(session) {
return this.ds_notification.call('set_message_read', [parseInt(msg_id)]);
},
on_vote: function (event) {
event.stopPropagation();
var self = this;
var message_id = $(event.srcElement).parent().data().msg_id;
var vote_node = $(event.srcElement).parents('li').eq(0);
if (! message_id) { return false; }
return this.ds_message.call('vote_toggle', [[parseInt(message_id)]]).pipe(
self.toggle_vote(message_id, vote_node));
},
/**
* Override-hack of do_action: automatically reload the chatter.
* Normally it should be called only when clicking on 'Post/Send'
@ -492,6 +505,8 @@ openerp.mail = function(session) {
attach['url'] = mail.ChatterUtils.get_attachment_url(this.session, attach);
}
record.is_author = mail.ChatterUtils.is_author(this, record.author_user_id[0]);
// add to internal storage
this.records[record.id] = record;
// render, add the expand feature
var rendered = session.web.qweb.render('mail.thread.message', {'record': record, 'thread': this, 'options': this.options});
$(rendered).appendTo(this.$el.children('div.oe_mail_thread_display:first'));
@ -505,6 +520,23 @@ openerp.mail = function(session) {
});
},
// Render vote Display template.
toggle_vote: function (message_id, vote_node) {
var self = this;
var record = this.records[message_id];
if (record.has_voted) {
var idx = _.map(record.vote_user_ids, function (x) { return x[0]; }).indexOf(message_id);
record.vote_user_ids.splice(idx, 1);
}
else {
record.vote_user_ids.push([this.session.uid, 'You']);
}
record.has_voted = ! record.has_voted;
var vote_element = session.web.qweb.render('mail.thread.message.vote', {'record': record});
vote_node.empty();
vote_node.html(vote_element);
},
/** Display 'show more' button */
update_fetch_more: function (new_value) {
if (new_value) {

View File

@ -142,11 +142,9 @@
</li>
<li><a t-attf-href="#model=res.partner&amp;id=#{record.author_id[0]}"><t t-raw="record.author_id[1]"/></a></li>
<li><span t-att-title="record.date"><t t-raw="record.timerelative"/></span></li>
<t t-call="mail.thread.message.vote"/>
<li t-if="options.show_reply"><a class="oe_mail_msg_reply">Reply</a></li>
<li t-if="options.show_reply_by_email"><a class="oe_mail_msg_reply_by_email" t-attf-data-msg_id="{record.id}">Reply</a></li>
<!-- uncomment when merging vote
<li><a href="#">Like</a></li>
-->
<li t-if="record.attachment_ids.length > 0">
<a class="oe_mail_msg_view_attachments">
<t t-if="record.attachment_ids.length == 1">1 Attachment</t>
@ -180,4 +178,17 @@
</ul>
</t>
<!-- mail.thread.message.vote
Template used to display Like/Unlike in a mail.message
-->
<li t-name="mail.thread.message.vote">
<t t-if='record.vote_user_ids.length > 0'>
<span class="oe_left oe_mail_vote_count"><t t-esc="record.vote_user_ids.length"/> votes</span>
</t>
<button t-attf-class="oe_mail_msg_vote oe_mail_msg_vote_#{record.has_voted}" t-attf-data-msg_id="{record.id}">
<t t-if="! record.has_voted"><span>+1</span></t>
<t t-if="record.has_voted"><span>-1</span></t>
</button>
</li>
</template>

View File

@ -647,3 +647,33 @@ class test_mail(TestMailMockups):
msg1.refresh()
self.assertEqual(5, len(group_pigs.message_ids), 'group should contain 5 messages')
self.assertEqual(2, len(msg1.child_ids), 'msg1 should have 2 children now')
def test_60_vote(self):
""" Test designed for the vote/unvote feature. """
cr, uid = self.cr, self.uid
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
user_admin = self.res_users.browse(cr, uid, uid)
msg1 = group_pigs.message_post(body='My Body', subject='1')
msg1 = self.mail_message.browse(cr, uid, msg1)
# Create user Bert Tartopoils
user_bert_id = self.res_users.create(cr, uid, {'name': 'Bert', 'login': 'bert'})
user_bert = self.res_users.browse(cr, uid, user_bert_id)
# Test: msg1 and msg2 have void vote_user_ids
self.assertFalse(msg1.vote_user_ids, 'newly created message msg1 has not void vote_user_ids')
# Do: Admin vote for msg1
self.mail_message.vote_toggle(cr, uid, [msg1.id])
msg1.refresh()
# Test: msg1 has Admin as voter
self.assertEqual(set(msg1.vote_user_ids), set([user_admin]), 'after voting, Admin is not the voter')
# Do: Bert vote for msg1
self.mail_message.vote_toggle(cr, uid, [msg1.id], [user_bert_id])
msg1.refresh()
# Test: msg1 has Admin and Bert as voters
self.assertEqual(set(msg1.vote_user_ids), set([user_admin, user_bert]), 'after voting, Admin and Bert are not the voters')
# Do: Admin unvote for msg1
self.mail_message.vote_toggle(cr, uid, [msg1.id])
msg1.refresh()
# Test: msg1 has Bert as voter
self.assertEqual(set(msg1.vote_user_ids), set([user_bert]), 'after unvoting for Admin, Bert is not the voter')

View File

@ -30,7 +30,8 @@
icon="terp-graph"
id="menu_board_manufacturing"
parent="base.menu_reporting_dashboard"
sequence="30"/>
sequence="30"
groups="group_mrp_manager"/>
</data>
</openerp>

View File

@ -34,7 +34,7 @@ This module is the base module for other multi-company modules.
'website': 'http://www.openerp.com/',
'depends': [
'base',
'sale',
'sale_stock',
'project',
],
'data': ['res_company_view.xml'],

View File

@ -181,7 +181,7 @@
</record>
<record id="sale.sale_order_5" model="sale.order">
<field name="company_id" ref="res_company_oerp_in"/>
<field name="company_id" ref="base.main_company"/>
</record>

View File

@ -20,7 +20,7 @@
##############################################################################
{
'name': 'Memos',
'name': 'Notes',
'version': '1.0',
'category': 'Tools',
'description': """
@ -28,12 +28,12 @@ This module allows users to create their own notes inside OpenERP
=================================================================
Use notes to write meeting minutes, organize ideas, organize personnal todo
lists, etc. Each user manages his own personnal memos. Notes are available to
lists, etc. Each user manages his own personnal Notes. Notes are available to
their authors only, but they can share notes to others users so that several
people can work on the same note in real time. It's very efficient to share
meeting minutes.
Memos can be found in the 'Home' menu.
Notes can be found in the 'Home' menu.
""",
'author': 'OpenERP SA',
'website': 'http://openerp.com',

View File

@ -22,6 +22,7 @@
from openerp.osv import osv, fields
from tools.translate import _
import re
from openerp.tools.misc import html2plaintext
class note_stage(osv.osv):
""" Category of Note """
@ -62,26 +63,24 @@ class note_note(osv.osv):
def _get_note_first_line(self, cr, uid, ids, name="", args={}, context=None):
res = {}
for note in self.browse(cr, uid, ids, context=context):
text_note = (note.memo or '').strip().split('\n')[0]
text_note = re.sub(r'(\S?)(<br[ /]*>|<[/]?p>|<[/]?div>|<table>)[\s\S]*',r'\1',text_note)
text_note = re.sub(r'<[^>]+>','',text_note)
res[note.id] = text_note
res[note.id] = (note.memo and html2plaintext(note.memo) or "").strip().replace('*','').split("\n")[0]
return res
#unactivate a sticky note and record the date
def onclick_note_is_done(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, { 'active' : False, 'date_done' : fields.date.today() })
self.write(cr, uid, ids, { 'open' : False, 'date_done' : fields.date.today() })
self.message_post(cr, uid, ids[0], body='Note is done.', subject=False,
type='notification', parent_id=False, attachments=None, context=context)
return False
#activate a note
def onclick_note_not_done(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'active' : True})
self.write(cr, uid, ids, {'open' : True})
self.message_post(cr, uid, ids[0], body='Note has been activated.', subject=False,
type='notification', parent_id=False, attachments=None, context=context)
return False
#used for undisplay the follower if it's the current user
def _get_my_current_partner(self, cr, uid, ids, name, args, context=None):
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
@ -96,7 +95,8 @@ class note_note(osv.osv):
def _set_stage_per_user(self, cr, uid, id, name, value, args=None, context=None):
note = self.browse(cr, uid, id, context=context)
if not value: return False
return self.write(cr, uid, [id], {'stage_ids': [(4, value)]}, context=context)
stage_ids = [value] + [stage.id for stage in note.stage_ids if stage.user_id.id != uid ]
return self.write(cr, uid, [id], {'stage_ids': [(6, 0, stage_ids)]}, context=context)
def _get_stage_per_user(self, cr, uid, ids, name, args, context=None):
result = dict.fromkeys(ids, False)
@ -119,14 +119,14 @@ class note_note(osv.osv):
type='many2one',
relation='note.stage'),
'stage_ids': fields.many2many('note.stage','note_stage_rel','note_id','stage_id','Stages of Users'),
'active': fields.boolean('Active'),
'open': fields.boolean('Active'),
'date_done': fields.date('Date done'),
'color': fields.integer('Color Index'),
'tag_ids' : fields.many2many('note.tag','note_tags_rel','note_id','tag_id','Tags'),
'current_partner_id' : fields.function(_get_my_current_partner),
}
_defaults = {
'active' : 1,
'open' : 1,
'stage_id' : _get_default_stage_id,
}
_order = 'sequence'
@ -185,5 +185,4 @@ class note_base_config_settings(osv.osv_memory):
_columns = {
'module_note_pad': fields.boolean('Use collaborative pads (etherpad)'),
'group_note_fancy': fields.boolean('Use fancy layouts for notes', implied_group='note.group_note_fancy'),
'group_note_tags': fields.boolean('Allow setting tags on notes', implied_group='note.group_note_tags'),
}

View File

@ -4,74 +4,68 @@
<record model="note.stage" id="demo_note_stage_01">
<field name="name">Today</field>
<field name="sequence">1</field>
<field name="user_id" eval="ref('base.user_demo')"/>
<field name="user_id" ref="base.user_demo"/>
</record>
<record model="note.stage" id="demo_note_stage_02">
<field name="name">Tomorrow</field>
<field name="sequence">2</field>
<field name="user_id" eval="ref('base.user_demo')"/>
<field name="user_id" ref="base.user_demo"/>
</record>
<record model="note.stage" id="demo_note_stage_03">
<field name="name">Later</field>
<field name="sequence">3</field>
<field name="user_id" eval="ref('base.user_demo')"/>
<field name="user_id" ref="base.user_demo"/>
</record>
<record model="note.stage" id="demo_note_stage_04">
<field name="name">Notes</field>
<field name="name">Morning</field>
<field name="sequence">4</field>
<field name="user_id" eval="ref('base.user_demo')"/>
<field name="user_id" ref="base.user_root"/>
</record>
<record id="note_1" model="note.note">
<field name="name">Customer report #349872</field>
<field name="memo"><![CDATA[Customer report #349872
<field name="memo"><![CDATA[<b>Customer report #349872</b>
<br/><br/>* Calendar app in Home
<br/>* The base_calendar module should create a menu in Home, like described above.
<br/>* This module should become a main application (in the first screen at installation)
<br/>* We should use the term Calendar, not Meeting.
]]>
</field>
<field name="stage_id" ref="note_stage_01"/>
<field name="stage_id" ref="demo_note_stage_01"/>
<field name="color">2</field>
<field name="message_follower_ids" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="note_2" model="note.note">
<field name="memo"><![CDATA[Call Fabien
<field name="memo"><![CDATA[<b>Call Fabien</b>
<br/><br/>* Followed by the telephone conversation and mail about D.544.3
]]>
</field>
<field name="stage_id" ref="note_stage_01"/>
</record>
<record id="note_3" model="note.note">
<field name="memo"><![CDATA[Call Marc
<br/><br/>]]>
</field>
<field name="stage_id" ref="note_stage_01"/>
<field name="stage_id" ref="demo_note_stage_01"/>
</record>
<record id="note_4" model="note.note">
<field name="memo"><![CDATA[Project N.947.5
<field name="memo"><![CDATA[<b>Project N.947.5</b>
<br/><br/>]]>
</field>
<field name="stage_id" ref="note_stage_02"/>
</record>
<record id="note_5" model="note.note">
<field name="memo"><![CDATA[Shop for family dinner
<field name="memo"><![CDATA[<b>Shop for family dinner</b>
<br/>* stuffed turkey
<br/>* wine
]]>
</field>
<field name="stage_id" ref="note_stage_02"/>
<field name="stage_id" ref="demo_note_stage_02"/>
<field name="message_follower_ids" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="note_6" model="note.note">
<field name="memo"><![CDATA[Idea to develop
<field name="memo"><![CDATA[<b>Idea to develop</b>
<br/><br/>* Create a module note_pad
it transforms the html editable memo text field into widget='pad', similar to project_pad depends on 'memo' and 'pad' modules
]]>
@ -79,17 +73,8 @@
<field name="stage_id" ref="note_stage_02"/>
</record>
<record id="note_7" model="note.note">
<field name="memo"><![CDATA[Read some documentation about OpenERP before diving into the code
<br/><br/>* Open ERP: a modern approach to integrated business management
<br/>* Open ERP for Retail and Industrial Management
]]>
</field>
<field name="stage_id" ref="note_stage_03"/>
</record>
<record id="note_8" model="note.note">
<field name="memo"><![CDATA[New computer specs
<field name="memo"><![CDATA[<b>New computer specs</b>
<br/><br/>* Motherboard
according to processor
<br/>* Processor
@ -108,43 +93,27 @@
</field>
<field name="stage_id" ref="note_stage_03"/>
<field name="color">3</field>
<field name="message_follower_ids" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="note_9" model="note.note">
<field name="memo"><![CDATA[Read those books
<field name="memo"><![CDATA[<b>Read those books</b>
<br/><br/>* Open ERP: a modern approach to integrated business management
<br/>* Open ERP for Retail and Industrial Management
]]>
</field>
<field name="stage_id" ref="note_stage_02"/>
</record>
<record id="note_10" model="note.note">
<field name="memo"><![CDATA[Read some documentation about OpenERP before diving into the code
<br/><br/>* Open ERP: a modern approach to integrated business management
<br/>* Open ERP for Retail and Industrial Management
]]>
</field>
<field name="stage_id" ref="note_stage_03"/>
<field name="stage_id" ref="demo_note_stage_02"/>
</record>
<record id="note_12" model="note.note">
<field name="memo"><![CDATA[Read some documentation about OpenERP before diving into the code
<field name="memo"><![CDATA[<b>Read some documentation about OpenERP before diving into the code</b>
<br/><br/>* Open ERP: a modern approach to integrated business management
<br/>* Open ERP for Retail and Industrial Management
]]>
</field>
<field name="stage_id" ref="note_stage_03"/>
<field name="message_follower_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="color">7</field>
</record>
<record id="note_13" model="note.note">
<field name="memo"><![CDATA[Read those books
<br/><br/>* Open ERP: a modern approach to integrated business management
<br/>* Open ERP for Retail and Industrial Management
]]>
</field>
<field name="stage_id" ref="note_stage_03"/>
<field name="stage_ids" eval="['note_stage_03','demo_note_stage_04']"/>
</record>
</data>

View File

@ -1,9 +1,6 @@
<?xml version="1.0"?>
<openerp>
<data>
<menuitem name="Organizer" id="note_my_stuff" parent="mail.mail_feeds_main"/>
<!-- note Stage Form View -->
<record model="ir.ui.view" id="view_note_stage_form">
<field name="name">note.stage.form</field>
@ -39,8 +36,6 @@
<field name="domain">[('user_id','=',uid)]</field>
</record>
<menuitem name="Categories" id="menu_notes_stage" parent="note_my_stuff" action="action_note_stage" sequence="40" groups="base.group_no_one"/>
<!-- New note Kanban View -->
<record model="ir.ui.view" id="view_note_note_kanban">
<field name="name">note.note.kanban</field>
@ -51,7 +46,7 @@
<field name="sequence"/>
<field name="name"/>
<field name="stage_id"/>
<field name="active"/>
<field name="open"/>
<field name="memo"/>
<field name="date_done"/>
<field name="current_partner_id"/>
@ -65,8 +60,8 @@
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_global_click_edit oe_semantic_html_override oe_kanban_card #{record.group_fancy==1 ? 'oe_kanban_card_fancy' : ''}">
<div class="oe_dropdown_kanban">
<span>
<a name="onclick_note_is_done" type="object" t-if="record.active.raw_value" class="oe_e">W</a>
<a name="onclick_note_not_done" type="object" t-if="!record.active.raw_value" class="oe_e">W</a>
<a name="onclick_note_is_done" type="object" t-if="record.open.raw_value" class="oe_e">W</a>
<a name="onclick_note_not_done" type="object" t-if="!record.open.raw_value" class="oe_e">W</a>
</span>
<!-- dropdown menu -->
@ -78,13 +73,12 @@
</ul>
</div>
</div>
<!-- kanban note -->
<div t-attf-class="oe_kanban_content #{record.active.raw_value ? '' : 'note_text_line_through'}">
<div t-attf-class="oe_kanban_content #{record.open.raw_value ? '' : 'note_text_line_through'}">
<!-- title -->
<field name="name"/>
</div>
<div widget="many2many_tags" t-att-data="record.tag_ids.raw_value" model="note.tag"/>
<field name="tag_ids"/>
<div class="oe_right">
<t t-foreach="record.message_follower_ids.raw_value" t-as="follower">
<img t-if="record.current_partner_id.raw_value!=follower" t-att-src="kanban_image('res.partner', 'image_small', follower)" width="24" height="24" class="oe_kanban_avatar" t-att-data-member_id="follower"/>
@ -105,9 +99,9 @@
<field name="arch" type="xml">
<tree string="Stages">
<field name="name"/>
<field name="active"/>
<field name="open"/>
<field name="stage_id"/>
<field name="tag_ids" widget="many2many_tags" groups="note.group_note_tags"/>
<field name="tag_ids" widget="many2many_tags"/>
</tree>
</field>
</record>
@ -119,12 +113,10 @@
<field name="arch" type="xml">
<form string="Note" version="7.0">
<header>
<field name="tag_ids" widget="many2many_tags" class="oe_inline" placeholder="Tags"/>
<field name="stage_id" domain="[('user_id','=',uid)]" widget="statusbar" clickable="1"/>
</header>
<field name="memo" widget="html"/><!-- editor_width="100%%" editor_height="60%%" -->
<group groups="note.group_note_tags" col="2">
<field name="tag_ids" widget="many2many_tags"/>
</group>
<field name="message_follower_ids" widget="mail_followers"/>
<field class="oe_chatter" name="message_ids" widget="mail_thread"/>
</form>
@ -138,10 +130,9 @@
<field name="arch" type="xml">
<search string="Notes">
<field name="memo" string="Note"/>
<field name="tag_ids" groups="note.group_note_tags"/>
<field name="stage_id"/>
<filter name="active_true" string="Active" domain="['|',('active', '=', True),('date_done','=',time.strftime('%%Y-%%m-%%d'))]"/>
<filter name="active_false" string="Old" domain="[('active', '=', False)]"/>
<field name="tag_ids"/>
<filter name="open_true" string="Active" domain="['|',('open', '=', True),('date_done','=',time.strftime('%%Y-%%m-%%d'))]"/>
<filter name="open_false" string="Archive" domain="[('open', '=', False)]"/>
<group expand="0" string="Group By...">
<filter icon="terp-stock_symbol-selection" string="Stage" help="By sticky note Category" context="{'group_by':'stage_id'}"/>
</group>
@ -168,10 +159,6 @@
<field name="group_note_fancy" class="oe_inline"/>
<label for="group_note_fancy"/>
</div>
<div>
<field name="group_note_tags" class="oe_inline"/>
<label for="group_note_tags"/>
</div>
</div>
</group>
</xpath>
@ -185,10 +172,11 @@
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="search_view_id" ref="view_note_note_filter"/>
<field name="context">{'search_default_active_true':True}</field>
<field name="context">{'search_default_open_true':True}</field>
</record>
<menuitem name="Notes" id="note_notes" parent="note_my_stuff" sequence="20" action="action_note_note"/>
<menuitem name="Notes" id="menu_note_notes" parent="mail.mail_my_stuff" sequence="20" action="note.action_note_note"/>
<menuitem name="Categories" id="menu_notes_stage" parent="mail.mail_my_stuff" action="note.action_note_stage" sequence="21" groups="base.group_no_one"/>
</data>
</openerp>

View File

@ -1,12 +1,19 @@
<?xml version="1.0"?>
<openerp>
<data>
<record id="note_note_rule_global" model="ir.rule">
<field name="name">Only followers can access a sticky notes</field>
<field model="ir.model" ref="model_note_note" name="model_id"/>
<field name="domain_force">['|',('message_follower_ids','=',False),('message_follower_ids','=',user.partner_id.id)]</field>
<field eval="True" name="global"/>
</record>
<record id="note_note_rule_global" model="ir.rule">
<field name="name">Only followers can access a sticky notes</field>
<field model="ir.model" ref="model_note_note" name="model_id"/>
<field name="domain_force">[('message_follower_ids','=',user.partner_id.id)]</field>
<field eval="True" name="global"/>
</record>
<record id="note_stage_rule_global" model="ir.rule">
<field name="name">Each user have his stage name</field>
<field model="ir.model" ref="model_note_stage" name="model_id"/>
<field name="domain_force">['|',('user_id','=',False),('user_id','=',user.id)]</field>
<field eval="True" name="global"/>
</record>
</data>
</openerp>

Some files were not shown because too many files have changed in this diff Show More