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 = '
... Loading pad ...
'; - this.pad_loading_request = $.get(value+'/export/html') - .done(function(data){ + this.pad_loading_request = $.get(value + '/export/html').done(function(data) { groups = /\<\s*body\s*\>(.*?)\<\s*\/body\s*\>/.exec(data); data = (groups || []).length >= 2 ? groups[1] : ''; self.$('.oe_pad_content').html('
'); self.$('.oe_pad_readonly').html(data); - }).error(function(){ + }).fail(function() { self.$('.oe_pad_content').text('Unable to load pad'); }); } } - this._super(); - this.$('.oe_pad_content').html(this.content); - this.$('.oe_pad_switch').click(function(){ - self.$el.toggleClass('oe_pad_fullscreen'); - }); }, }); diff --git a/addons/pad/static/src/xml/pad.xml b/addons/pad/static/src/xml/pad.xml index bd3e296f9b3..f915e867b35 100644 --- a/addons/pad/static/src/xml/pad.xml +++ b/addons/pad/static/src/xml/pad.xml @@ -5,32 +5,25 @@ - -
-

- You must configure the etherpad through the menu Settings > Companies > Companies, in the configuration tab of your company. -

-
-
- - +
+

+ You must configure the etherpad through the menu Settings > Companies > Companies, in the configuration tab of your company. +

-
-
-
+
+ +
+ &Ntilde; +
+
+
+
+
+ + - -
-
- &Ntilde; -
-
-
-
-
-
diff --git a/addons/product/partner.py b/addons/product/partner.py index 159c687bedf..fbfee76d0b2 100644 --- a/addons/product/partner.py +++ b/addons/product/partner.py @@ -36,6 +36,9 @@ class res_partner(osv.osv): help="This pricelist will be used, instead of the default one, for sales to the current partner"), } + def _commercial_fields(self, cr, uid, context=None): + return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['property_product_pricelist'] + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product/partner_view.xml b/addons/product/partner_view.xml index acb087533ac..5117da6044e 100644 --- a/addons/product/partner_view.xml +++ b/addons/product/partner_view.xml @@ -8,9 +8,12 @@ - + +
+

Pricelists are managed on

diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index ef5b42aef02..6fc926980dd 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -234,7 +234,10 @@ class product_pricelist(osv.osv): qty, context=context)[res['base_pricelist_id']] ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id uom_price_already_computed = True - price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False) + price = currency_obj.compute(cr, uid, + ptype_src, res['currency_id'], + price_tmp, round=False, + context=context) elif res['base'] == -2: # this section could be improved by moving the queries outside the loop: where = [] diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index a016c46e0e0..298355d4c82 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -189,7 +189,7 @@ - + diff --git a/addons/project/report/project_report_view.xml b/addons/project/report/project_report_view.xml index 10f3f4a8c7c..d9650e165ce 100644 --- a/addons/project/report/project_report_view.xml +++ b/addons/project/report/project_report_view.xml @@ -69,7 +69,7 @@ - + diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml index f888ff9da77..f15355e9cc8 100644 --- a/addons/project_issue/project_issue_view.xml +++ b/addons/project_issue/project_issue_view.xml @@ -146,7 +146,7 @@ project.issue - + @@ -154,10 +154,11 @@ - + + diff --git a/addons/project_issue/report/project_issue_report_view.xml b/addons/project_issue/report/project_issue_report_view.xml index e56c6612e0d..a885dcd8a7f 100644 --- a/addons/project_issue/report/project_issue_report_view.xml +++ b/addons/project_issue/report/project_issue_report_view.xml @@ -55,7 +55,7 @@ - + diff --git a/addons/purchase/partner.py b/addons/purchase/partner.py index ad17a1dbae9..5e5af0815e3 100644 --- a/addons/purchase/partner.py +++ b/addons/purchase/partner.py @@ -43,6 +43,9 @@ class res_partner(osv.osv): super(res_partner, self).copy(cr, uid, id, default=default, context=context) + def _commercial_fields(self, cr, uid, context=None): + return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['property_product_pricelist_purchase'] + _columns = { 'property_product_pricelist_purchase': fields.property( 'product.pricelist', diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index 731e17426c1..4432d2b3200 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -270,7 +270,7 @@ - + @@ -297,7 +297,7 @@ - + @@ -481,7 +481,7 @@ - + diff --git a/addons/sale/res_partner_view.xml b/addons/sale/res_partner_view.xml index 54a9813eea9..40ac119fdee 100644 --- a/addons/sale/res_partner_view.xml +++ b/addons/sale/res_partner_view.xml @@ -63,14 +63,34 @@ sale.group_delivery_invoice_address - - False False + sale.group_delivery_invoice_address - + + False + sale.group_delivery_invoice_address + + + False + sale.group_delivery_invoice_address + + + False + sale.group_delivery_invoice_address + + + False + sale.group_delivery_invoice_address + + + False + sale.group_delivery_invoice_address + + + False sale.group_delivery_invoice_address diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 76b0f9c2159..210e4dd3be6 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -320,10 +320,6 @@ class sale_order(osv.osv): return {'value': {'partner_invoice_id': False, 'partner_shipping_id': False, 'payment_term': False, 'fiscal_position': False}} part = self.pool.get('res.partner').browse(cr, uid, part, context=context) - #if the chosen partner is not a company and has a parent company, use the parent to choose the delivery, the - #invoicing addresses and all the fields related to the partner. - if part.parent_id and not part.is_company: - part = part.parent_id addr = self.pool.get('res.partner').address_get(cr, uid, [part.id], ['delivery', 'invoice', 'contact']) pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False payment_term = part.property_payment_term and part.property_payment_term.id or False @@ -1024,4 +1020,16 @@ class account_invoice(osv.Model): sale_order_obj.message_post(cr, uid, so_ids, body=_("Invoice paid"), context=context) return res + def unlink(self, cr, uid, ids, context=None): + """ Overwrite unlink method of account invoice to send a trigger to the sale workflow upon invoice deletion """ + invoice_ids = self.search(cr, uid, [('id', 'in', ids), ('state', 'in', ['draft', 'cancel'])], context=context) + #if we can't cancel all invoices, do nothing + if len(invoice_ids) == len(ids): + #Cancel invoice(s) first before deleting them so that if any sale order is associated with them + #it will trigger the workflow to put the sale order in an 'invoice exception' state + wf_service = netsvc.LocalService("workflow") + for id in ids: + wf_service.trg_validate(uid, 'account.invoice', id, 'invoice_cancel', cr) + return super(account_invoice, self).unlink(cr, uid, ids, context=context) + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 9a4866d14f1..e24a6e45fe0 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -156,7 +156,7 @@ - + @@ -308,7 +308,7 @@ - + @@ -329,7 +329,6 @@ tree,form,calendar,graph { - 'show_address': 1, 'search_default_my_sale_orders_filter': 1 } @@ -376,7 +375,7 @@ form tree,form,calendar,graph - {'show_address': 1, 'search_default_my_sale_orders_filter': 1} + {'search_default_my_sale_orders_filter': 1} [('state','in',('draft','sent','cancel'))] @@ -477,7 +476,7 @@ - + @@ -503,7 +502,7 @@ - + diff --git a/addons/sale_journal/sale_journal.py b/addons/sale_journal/sale_journal.py index 32db3a7c86e..9e10c826898 100644 --- a/addons/sale_journal/sale_journal.py +++ b/addons/sale_journal/sale_journal.py @@ -52,6 +52,10 @@ class res_partner(osv.osv): help = "This invoicing type will be used, by default, to invoice the current partner."), } + def _commercial_fields(self, cr, uid, context=None): + return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['property_invoice_type'] + + class picking(osv.osv): _inherit = "stock.picking" _columns = { diff --git a/addons/sale_journal/sale_journal_view.xml b/addons/sale_journal/sale_journal_view.xml index bcd83b5be84..9d41103252e 100644 --- a/addons/sale_journal/sale_journal_view.xml +++ b/addons/sale_journal/sale_journal_view.xml @@ -146,7 +146,7 @@ - + diff --git a/addons/sale_stock/stock.py b/addons/sale_stock/stock.py index e1070998ae8..ad19684c4cf 100644 --- a/addons/sale_stock/stock.py +++ b/addons/sale_stock/stock.py @@ -54,7 +54,7 @@ class stock_picking(osv.osv): We select the partner of the sales order as the partner of the customer invoice """ if picking.sale_id: - return picking.sale_id.partner_id + return picking.sale_id.partner_invoice_id return super(stock_picking, self)._get_partner_to_invoice(cr, uid, picking, context=context) def _get_comment_invoice(self, cursor, user, picking): diff --git a/addons/sale_stock/test/picking_order_policy.yml b/addons/sale_stock/test/picking_order_policy.yml index 92cdac4a85c..afffda1ef21 100644 --- a/addons/sale_stock/test/picking_order_policy.yml +++ b/addons/sale_stock/test/picking_order_policy.yml @@ -5,6 +5,12 @@ - !assert {model: sale.order, id: sale.sale_order_6, string: The amount of the Quotation is not correctly computed}: - sum([l.price_subtotal for l in order_line]) == amount_untaxed +- + I set an explicit invoicing partner that is different from the main SO Customer +- + !python {model: sale.order, id: sale.sale_order_6}: | + order = self.browse(cr, uid, ref("sale.sale_order_6")) + order.write({'partner_invoice_id': ref('base.res_partner_address_29')}) - I confirm the quotation with Invoice based on deliveries policy. - @@ -110,13 +116,13 @@ !python {model: sale.order}: | order = self.browse(cr, uid, ref("sale.sale_order_6")) assert order.invoice_ids, "Invoice is not created." - ac = order.partner_id.property_account_receivable.id + ac = order.partner_invoice_id.property_account_receivable.id journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'sale'), ('company_id', '=', order.company_id.id)]) for invoice in order.invoice_ids: assert invoice.type == 'out_invoice',"Invoice should be Customer Invoice." assert invoice.account_id.id == ac,"Invoice account is not correspond." assert invoice.reference == order.client_order_ref or order.name,"Reference is not correspond." - assert invoice.partner_id.id == order.partner_id.id,"Customer is not correspond." + assert invoice.partner_id.id == order.partner_invoice_id.id,"Customer does not correspond." assert invoice.currency_id.id == order.pricelist_id.currency_id.id, "Currency is not correspond." assert invoice.comment == (order.note or ''),"Note is not correspond." assert invoice.journal_id.id in journal_ids,"Sales Journal is not link on Invoice." diff --git a/addons/stock/report/report_stock_move_view.xml b/addons/stock/report/report_stock_move_view.xml index 4f3e256389c..fcf99f6e51e 100644 --- a/addons/stock/report/report_stock_move_view.xml +++ b/addons/stock/report/report_stock_move_view.xml @@ -149,7 +149,7 @@ - + diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 6162d073fde..6097885175b 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -817,7 +817,7 @@ - + @@ -944,6 +944,7 @@ + @@ -1069,6 +1070,7 @@ + @@ -1380,7 +1382,7 @@ - +