diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py
index b22afa3f931..c47cf70b673 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -286,7 +286,10 @@ class account_invoice(osv.osv):
'payment_ids': fields.function(_compute_lines, relation='account.move.line', type="many2many", string='Payments'),
'move_name': fields.char('Journal Entry', size=64, readonly=True, states={'draft':[('readonly',False)]}),
'user_id': fields.many2one('res.users', 'Salesperson', readonly=True, track_visibility='onchange', states={'draft':[('readonly',False)]}),
- 'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position', readonly=True, states={'draft':[('readonly',False)]})
+ 'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position', readonly=True, states={'draft':[('readonly',False)]}),
+ 'commercial_partner_id': fields.related('partner_id', 'commercial_partner_id', string='Commercial Entity', type='many2one',
+ relation='res.partner', store=True, readonly=True,
+ help="The commercial entity that will be used on Journal Entries for this invoice")
}
_defaults = {
'type': _get_type,
@@ -1261,9 +1264,7 @@ class account_invoice(osv.osv):
ref = invoice.reference
else:
ref = self._convert_ref(cr, uid, invoice.number)
- partner = invoice.partner_id
- if partner.parent_id and not partner.is_company:
- partner = partner.parent_id
+ partner = self.pool['res.partner']._find_accounting_partner(invoice.partner_id)
# Pay attention to the sign for both debit/credit AND amount_currency
l1 = {
'debit': direction * pay_amount>0 and direction * pay_amount,
@@ -1733,15 +1734,11 @@ class res_partner(osv.osv):
'invoice_ids': fields.one2many('account.invoice.line', 'partner_id', 'Invoices', readonly=True),
}
- def _find_accounting_partner(self, part):
+ def _find_accounting_partner(self, partner):
'''
Find the partner for which the accounting entries will be created
'''
- #if the chosen partner is not a company and has a parent company, use the parent for the journal entries
- #because you want to invoice 'Agrolait, accounting department' but the journal items are for 'Agrolait'
- if part.parent_id and not part.is_company:
- part = part.parent_id
- return part
+ return partner.commercial_partner_id
def copy(self, cr, uid, id, default=None, context=None):
default = default or {}
diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml
index 379fc72a953..7469c38decb 100644
--- a/addons/account/account_invoice_view.xml
+++ b/addons/account/account_invoice_view.xml
@@ -117,6 +117,7 @@
+
@@ -320,7 +321,8 @@
+ options='{"always_reload": True}'
+ domain="[('customer', '=', True)]"/>
@@ -447,19 +449,20 @@
account.invoice
-
+
-
+
-
+
+
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index 91be300f180..006e2c55f5f 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -655,13 +655,7 @@ class account_move_line(osv.osv):
}
return result
- def onchange_account_id(self, cr, uid, ids, account_id, context=None):
- res = {'value': {}}
- if account_id:
- res['value']['account_tax_id'] = [x.id for x in self.pool.get('account.account').browse(cr, uid, account_id, context=context).tax_ids]
- return res
-
- def onchange_partner_id(self, cr, uid, ids, move_id, partner_id, account_id=None, debit=0, credit=0, date=False, journal=False):
+ def onchange_partner_id(self, cr, uid, ids, move_id, partner_id, account_id=None, debit=0, credit=0, date=False, journal=False, context=None):
partner_obj = self.pool.get('res.partner')
payment_term_obj = self.pool.get('account.payment.term')
journal_obj = self.pool.get('account.journal')
@@ -675,8 +669,8 @@ class account_move_line(osv.osv):
date = datetime.now().strftime('%Y-%m-%d')
jt = False
if journal:
- jt = journal_obj.browse(cr, uid, journal).type
- part = partner_obj.browse(cr, uid, partner_id)
+ jt = journal_obj.browse(cr, uid, journal, context=context).type
+ part = partner_obj.browse(cr, uid, partner_id, context=context)
payment_term_id = False
if jt and jt in ('purchase', 'purchase_refund') and part.property_supplier_payment_term:
@@ -701,20 +695,20 @@ class account_move_line(osv.osv):
elif part.supplier:
val['account_id'] = fiscal_pos_obj.map_account(cr, uid, part and part.property_account_position or False, id1)
if val.get('account_id', False):
- d = self.onchange_account_id(cr, uid, ids, val['account_id'])
+ d = self.onchange_account_id(cr, uid, ids, account_id=val['account_id'], partner_id=part.id, context=context)
val.update(d['value'])
return {'value':val}
- def onchange_account_id(self, cr, uid, ids, account_id=False, partner_id=False):
+ def onchange_account_id(self, cr, uid, ids, account_id=False, partner_id=False, context=None):
account_obj = self.pool.get('account.account')
partner_obj = self.pool.get('res.partner')
fiscal_pos_obj = self.pool.get('account.fiscal.position')
val = {}
if account_id:
- res = account_obj.browse(cr, uid, account_id)
+ res = account_obj.browse(cr, uid, account_id, context=context)
tax_ids = res.tax_ids
if tax_ids and partner_id:
- part = partner_obj.browse(cr, uid, partner_id)
+ part = partner_obj.browse(cr, uid, partner_id, context=context)
tax_id = fiscal_pos_obj.map_tax(cr, uid, part and part.property_account_position or False, tax_ids)[0]
else:
tax_id = tax_ids and tax_ids[0].id or False
diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml
index 34440298bfd..13bc694a1cc 100644
--- a/addons/account/account_view.xml
+++ b/addons/account/account_view.xml
@@ -1112,7 +1112,7 @@
-
+
@@ -1293,7 +1293,7 @@
-
+
@@ -1357,7 +1357,7 @@
-
+
diff --git a/addons/account/partner.py b/addons/account/partner.py
index 50addd88942..f582da6b765 100644
--- a/addons/account/partner.py
+++ b/addons/account/partner.py
@@ -233,5 +233,10 @@ class res_partner(osv.osv):
'last_reconciliation_date': fields.datetime('Latest Full Reconciliation Date', help='Date on which the partner accounting entries were fully reconciled last time. It differs from the last date where a reconciliation has been 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 different ways: either the last unreconciled debit/credit entry of this partner was reconciled, either the user pressed the button "Nothing more to reconcile" during the manual reconciliation process.')
}
+ def _commercial_fields(self, cr, uid, context=None):
+ return super(res_partner, self)._commercial_fields(cr, uid, context=context) + \
+ ['debit_limit', 'property_account_payable', 'property_account_receivable', 'property_account_position',
+ 'property_payment_term', 'property_supplier_payment_term', 'last_reconciliation_date']
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/partner_view.xml b/addons/account/partner_view.xml
index 76e94fdfef4..b6fae3140b5 100644
--- a/addons/account/partner_view.xml
+++ b/addons/account/partner_view.xml
@@ -96,7 +96,7 @@
-
+
@@ -126,6 +126,11 @@
+
+
+
Accounting-related settings are managed on
+
+
diff --git a/addons/account/project/project_view.xml b/addons/account/project/project_view.xml
index aa567d2fc79..79a1e76c7e7 100644
--- a/addons/account/project/project_view.xml
+++ b/addons/account/project/project_view.xml
@@ -31,7 +31,7 @@
-
+
diff --git a/addons/account/report/account_invoice_report.py b/addons/account/report/account_invoice_report.py
index 5395d79af03..799b9b1c9fb 100644
--- a/addons/account/report/account_invoice_report.py
+++ b/addons/account/report/account_invoice_report.py
@@ -70,6 +70,7 @@ class account_invoice_report(osv.osv):
'categ_id': fields.many2one('product.category','Category of Product', readonly=True),
'journal_id': fields.many2one('account.journal', 'Journal', readonly=True),
'partner_id': fields.many2one('res.partner', 'Partner', readonly=True),
+ 'commercial_partner_id': fields.many2one('res.partner', 'Partner Company', help="Commercial Entity"),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'user_id': fields.many2one('res.users', 'Salesperson', readonly=True),
'price_total': fields.float('Total Without Tax', readonly=True),
@@ -108,7 +109,7 @@ class account_invoice_report(osv.osv):
sub.fiscal_position, sub.user_id, sub.company_id, sub.nbr, sub.type, sub.state,
sub.categ_id, sub.date_due, sub.account_id, sub.account_line_id, sub.partner_bank_id,
sub.product_qty, sub.price_total / cr.rate as price_total, sub.price_average /cr.rate as price_average,
- cr.rate as currency_rate, sub.residual / cr.rate as residual
+ cr.rate as currency_rate, sub.residual / cr.rate as residual, sub.commercial_partner_id as commercial_partner_id
"""
return select_str
@@ -170,7 +171,8 @@ class account_invoice_report(osv.osv):
LEFT JOIN account_invoice a ON a.id = l.invoice_id
WHERE a.id = ai.id)
ELSE 1::bigint
- END::numeric AS residual
+ END::numeric AS residual,
+ ai.commercial_partner_id as commercial_partner_id
"""
return select_str
@@ -193,7 +195,7 @@ class account_invoice_report(osv.osv):
ai.partner_id, ai.payment_term, ai.period_id, u.name, ai.currency_id, ai.journal_id,
ai.fiscal_position, ai.user_id, ai.company_id, ai.type, ai.state, pt.categ_id,
ai.date_due, ai.account_id, ail.account_id, ai.partner_bank_id, ai.residual,
- ai.amount_total, u.uom_type, u.category_id
+ ai.amount_total, u.uom_type, u.category_id, ai.commercial_partner_id
"""
return group_by_str
diff --git a/addons/account/report/account_invoice_report_view.xml b/addons/account/report/account_invoice_report_view.xml
index dad70f695dc..96dc948b09a 100644
--- a/addons/account/report/account_invoice_report_view.xml
+++ b/addons/account/report/account_invoice_report_view.xml
@@ -14,6 +14,7 @@
+
@@ -65,7 +66,8 @@
-
+
+
diff --git a/addons/account/static/src/js/account_move_reconciliation.js b/addons/account/static/src/js/account_move_reconciliation.js
index dbbfe3cc069..cbc0abc4f4d 100644
--- a/addons/account/static/src/js/account_move_reconciliation.js
+++ b/addons/account/static/src/js/account_move_reconciliation.js
@@ -26,7 +26,7 @@ openerp.account = function (instance) {
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.current_partner = (((self.current_partner - 1) % self.partners.length) + self.partners.length) % self.partners.length;
self.search_by_partner();
});
this.$(".oe_account_recon_next").click(function() {
diff --git a/addons/account_analytic_analysis/account_analytic_analysis_view.xml b/addons/account_analytic_analysis/account_analytic_analysis_view.xml
index 97a4bb8fac2..d31746e7e70 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis_view.xml
+++ b/addons/account_analytic_analysis/account_analytic_analysis_view.xml
@@ -213,7 +213,7 @@
-
+
diff --git a/addons/account_asset/account_asset_view.xml b/addons/account_asset/account_asset_view.xml
index c4cb17bded3..fe1fcf473ba 100644
--- a/addons/account_asset/account_asset_view.xml
+++ b/addons/account_asset/account_asset_view.xml
@@ -223,7 +223,7 @@
-
+
diff --git a/addons/account_asset/report/account_asset_report_view.xml b/addons/account_asset/report/account_asset_report_view.xml
index 4865196c4a8..c772c6e4103 100644
--- a/addons/account_asset/report/account_asset_report_view.xml
+++ b/addons/account_asset/report/account_asset_report_view.xml
@@ -49,7 +49,7 @@
-
+
diff --git a/addons/account_followup/account_followup_customers.xml b/addons/account_followup/account_followup_customers.xml
index 6be11399b68..6893abe012e 100644
--- a/addons/account_followup/account_followup_customers.xml
+++ b/addons/account_followup/account_followup_customers.xml
@@ -10,7 +10,7 @@
-
+
@@ -29,7 +29,7 @@
res.partner
-
+
diff --git a/addons/account_voucher/account_voucher_view.xml b/addons/account_voucher/account_voucher_view.xml
index f429480f656..4674d62b6a0 100644
--- a/addons/account_voucher/account_voucher_view.xml
+++ b/addons/account_voucher/account_voucher_view.xml
@@ -129,7 +129,7 @@
-
+
diff --git a/addons/account_voucher/voucher_payment_receipt_view.xml b/addons/account_voucher/voucher_payment_receipt_view.xml
index de873c9195c..109c2f9aec9 100644
--- a/addons/account_voucher/voucher_payment_receipt_view.xml
+++ b/addons/account_voucher/voucher_payment_receipt_view.xml
@@ -11,7 +11,7 @@
-
+
@@ -34,7 +34,7 @@
-
+
diff --git a/addons/account_voucher/voucher_sales_purchase_view.xml b/addons/account_voucher/voucher_sales_purchase_view.xml
index 05b783dd339..6a84a09d5e6 100644
--- a/addons/account_voucher/voucher_sales_purchase_view.xml
+++ b/addons/account_voucher/voucher_sales_purchase_view.xml
@@ -10,7 +10,7 @@
-
+
@@ -32,7 +32,7 @@
-
+
diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py
index cfb2dbd04d0..e7501334997 100644
--- a/addons/base_vat/base_vat.py
+++ b/addons/base_vat/base_vat.py
@@ -134,6 +134,9 @@ class res_partner(osv.osv):
'vat_subjected': fields.boolean('VAT Legal Statement', help="Check this box if the partner is subjected to the VAT. It will be used for the VAT legal statement.")
}
+ def _commercial_fields(self, cr, uid, context=None):
+ return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['vat_subjected']
+
def _construct_constraint_msg(self, cr, uid, ids, context=None):
def default_vat_check(cn, vn):
# by default, a VAT number is valid if:
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index d94683f895f..8c22a0a2e1c 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -330,7 +330,7 @@
-
+
@@ -548,7 +548,7 @@
-
+
diff --git a/addons/crm/crm_phonecall_view.xml b/addons/crm/crm_phonecall_view.xml
index 3efb54f98b8..6c1b31180be 100644
--- a/addons/crm/crm_phonecall_view.xml
+++ b/addons/crm/crm_phonecall_view.xml
@@ -186,7 +186,7 @@
-
+
diff --git a/addons/crm/report/crm_lead_report_view.xml b/addons/crm/report/crm_lead_report_view.xml
index 1009e1c376d..759063b3c1d 100644
--- a/addons/crm/report/crm_lead_report_view.xml
+++ b/addons/crm/report/crm_lead_report_view.xml
@@ -82,7 +82,7 @@
groups="base.group_multi_salesteams"/>
-
+
diff --git a/addons/crm/report/crm_phonecall_report_view.xml b/addons/crm/report/crm_phonecall_report_view.xml
index c27d876ddd7..070d574e0cd 100644
--- a/addons/crm/report/crm_phonecall_report_view.xml
+++ b/addons/crm/report/crm_phonecall_report_view.xml
@@ -64,7 +64,7 @@
groups="base.group_multi_salesteams"/>
-
+
diff --git a/addons/crm_claim/crm_claim_view.xml b/addons/crm_claim/crm_claim_view.xml
index 78e467a7ba8..e295bfdd250 100644
--- a/addons/crm_claim/crm_claim_view.xml
+++ b/addons/crm_claim/crm_claim_view.xml
@@ -201,7 +201,7 @@
-
+
diff --git a/addons/crm_claim/report/crm_claim_report_view.xml b/addons/crm_claim/report/crm_claim_report_view.xml
index febf9cafd73..530eb6061a3 100644
--- a/addons/crm_claim/report/crm_claim_report_view.xml
+++ b/addons/crm_claim/report/crm_claim_report_view.xml
@@ -65,7 +65,7 @@
-
+
diff --git a/addons/crm_helpdesk/crm_helpdesk_view.xml b/addons/crm_helpdesk/crm_helpdesk_view.xml
index 6769b42a7f8..6e3521be6f2 100644
--- a/addons/crm_helpdesk/crm_helpdesk_view.xml
+++ b/addons/crm_helpdesk/crm_helpdesk_view.xml
@@ -152,7 +152,7 @@
-
+
diff --git a/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml b/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
index 795ae210d8d..6ce2c60093f 100644
--- a/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
+++ b/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
@@ -62,6 +62,7 @@
+
diff --git a/addons/hr_expense/hr_expense_view.xml b/addons/hr_expense/hr_expense_view.xml
index 7a98053a6e5..10abe95d892 100644
--- a/addons/hr_expense/hr_expense_view.xml
+++ b/addons/hr_expense/hr_expense_view.xml
@@ -32,7 +32,7 @@
-
+
diff --git a/addons/l10n_be_invoice_bba/partner.py b/addons/l10n_be_invoice_bba/partner.py
index 8ae54617b98..bf8d5d7a0c3 100644
--- a/addons/l10n_be_invoice_bba/partner.py
+++ b/addons/l10n_be_invoice_bba/partner.py
@@ -44,6 +44,11 @@ class res_partner(osv.osv):
help='Select Algorithm to generate the Structured Communication on Outgoing Invoices.' ),
}
+ def _commercial_fields(self, cr, uid, context=None):
+ return super(res_partner, self)._commercial_fields(cr, uid, context=context) + \
+ ['out_inv_comm_type', 'out_inv_comm_algorithm']
+
+
_default = {
'out_inv_comm_type': 'none',
}
diff --git a/addons/l10n_ro/res_partner.py b/addons/l10n_ro/res_partner.py
index 2f1cc26faa8..96de4b4e86a 100755
--- a/addons/l10n_ro/res_partner.py
+++ b/addons/l10n_ro/res_partner.py
@@ -28,9 +28,32 @@ class res_partner(osv.osv):
_columns = {
'nrc' : fields.char('NRC', size=16, help='Registration number at the Registry of Commerce'),
}
+
+ # The SQL constraints are no-ops but present only to display the right error message to the
+ # user when the partial unique indexes defined below raise errors/
+ # The real constraints need to be implemented with PARTIAL UNIQUE INDEXES (see auto_init),
+ # due to the way accounting data is delegated by contacts to their companies in OpenERP 7.0.
_sql_constraints = [
- ('vat_uniq', 'unique (vat)', 'The vat of the partner must be unique !'),
- ('nrc_uniq', 'unique (nrc)', 'The code of the partner must be unique !')
+ ('vat_uniq', 'unique (id)', 'The vat of the partner must be unique !'),
+ ('nrc_uniq', 'unique (id)', 'The code of the partner must be unique !')
]
+ def _auto_init(self, cr, context=None):
+ result = super(res_partner, self)._auto_init(cr, context=context)
+ # Real implementation of the vat/nrc constraints: only "commercial entities" need to have
+ # unique numbers, and the condition for being a commercial entity is "is_company or parent_id IS NULL".
+ # Contacts inside a company automatically have a copy of the company's commercial fields
+ # (see _commercial_fields()), so they are automatically consistent.
+ cr.execute("""
+ DROP INDEX IF EXISTS res_partner_vat_uniq_for_companies;
+ DROP INDEX IF EXISTS res_partner_nrc_uniq_for_companies;
+ CREATE UNIQUE INDEX res_partner_vat_uniq_for_companies ON res_partner (vat) WHERE is_company OR parent_id IS NULL;
+ CREATE UNIQUE INDEX res_partner_nrc_uniq_for_companies ON res_partner (nrc) WHERE is_company OR parent_id IS NULL;
+ """)
+ return result
+
+ def _commercial_fields(self, cr, uid, context=None):
+ return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['nrc']
+
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/mrp_repair/mrp_repair_view.xml b/addons/mrp_repair/mrp_repair_view.xml
index d35a9ebcf1d..a4526b5b581 100644
--- a/addons/mrp_repair/mrp_repair_view.xml
+++ b/addons/mrp_repair/mrp_repair_view.xml
@@ -210,7 +210,7 @@
-
+
diff --git a/addons/pad/static/src/js/pad.js b/addons/pad/static/src/js/pad.js
index b96047340ad..1a2de41745b 100644
--- a/addons/pad/static/src/js/pad.js
+++ b/addons/pad/static/src/js/pad.js
@@ -1,67 +1,63 @@
openerp.pad = function(instance) {
- instance.web.form.FieldPad = instance.web.form.AbstractField.extend({
+ instance.web.form.FieldPad = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeWidgetMixin, {
template: 'FieldPad',
- configured: false,
content: "",
- start: function() {
- this._super();
- var self = this;
- this.on('change:effective_readonly',this,function(){
- self.renderElement();
+ init: function() {
+ this._super.apply(this, arguments);
+ this.set("configured", true);
+ this.on("change:configured", this, this.switch_configured);
+ },
+ initialize_content: function() {
+ this.switch_configured();
+ this.$('.oe_pad_switch').click(function() {
+ self.$el.toggleClass('oe_pad_fullscreen');
});
+ this.render_value();
+ },
+ switch_configured: function() {
+ this.$(".oe_unconfigured").toggle(! this.get("configured"));
+ this.$(".oe_configured").toggle(this.get("configured"));
},
render_value: function() {
- var self = this;
- var _super = _.bind(this._super, this);
- if (this.get("value") === false || this.get("value") === "") {
- self.view.dataset.call('pad_generate_url',{context:{
+ var self = this;
+ if (this.get("configured") && ! this.get("value")) {
+ self.view.dataset.call('pad_generate_url', {
+ context: {
model: self.view.model,
field_name: self.name,
object_id: self.view.datarecord.id
- }}).done(function(data) {
- if(data&&data.url){
- self.set({value: data.url});
- _super(data.url);
- self.renderElement();
+ },
+ }).done(function(data) {
+ if (! data.url) {
+ self.set("configured", false);
+ } else {
+ self.set("value", data.url);
}
});
- } else {
- self.renderElement();
}
- this._dirty_flag = true;
- },
- renderElement: function(){
- var self = this;
+ this.$('.oe_pad_content').html("");
var value = this.get('value');
if (this.pad_loading_request) {
this.pad_loading_request.abort();
}
- if(!_.str.startsWith(value,'http')){
- this.configured = false;
- this.content = "";
- }else{
- this.configured = true;
- if(!this.get('effective_readonly')){
- this.content = '';
- }else{
+ if (_.str.startsWith(value, 'http')) {
+ if (! this.get('effective_readonly')) {
+ var content = '';
+ this.$('.oe_pad_content').html(content);
+ this._dirty_flag = true;
+ } else {
this.content = '