bemade_multiple_billing_contacts: Updated view to address a bug.
This commit is contained in:
parent
e374c53e63
commit
ecd5e2b55e
8 changed files with 0 additions and 221 deletions
|
|
@ -1 +0,0 @@
|
||||||
from . import models
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
#
|
|
||||||
# Bemade Inc.
|
|
||||||
#
|
|
||||||
# Copyright (C) June 2023 Bemade Inc. (<https://www.bemade.org>).
|
|
||||||
# Author: mdurepos (Contact : it@bemade.org)
|
|
||||||
#
|
|
||||||
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
|
|
||||||
# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
|
|
||||||
# or modified copies of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
# DEALINGS IN THE SOFTWARE.
|
|
||||||
#
|
|
||||||
{
|
|
||||||
'name': 'bemade_multiple_billing_contacts',
|
|
||||||
'version': '15.0.1.0.1',
|
|
||||||
'summary': 'Send invoices to multiple contacts by default.',
|
|
||||||
'description': """By default, newly created invoices add all invoice addresses for the given partner as
|
|
||||||
followers on the invoice. If billing contacts are set manually on the sales order, those billing
|
|
||||||
contacts are added as followers on the invoice instead.""",
|
|
||||||
'category': 'Invoicing Management',
|
|
||||||
'author': 'Bemade Inc.',
|
|
||||||
'website': 'https://www.bemade.org',
|
|
||||||
'license': 'OPL-1',
|
|
||||||
'depends': ['sale',
|
|
||||||
'account',
|
|
||||||
'bemade_partner_root_ancestor',
|
|
||||||
],
|
|
||||||
'data': [],
|
|
||||||
'demo': [],
|
|
||||||
'installable': True,
|
|
||||||
'auto_install': False,
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
from . import res_partner
|
|
||||||
from . import sale_order
|
|
||||||
from . import account_move
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
from odoo import models, fields, api
|
|
||||||
|
|
||||||
|
|
||||||
class AccountMove(models.Model):
|
|
||||||
_inherit = 'account.move'
|
|
||||||
|
|
||||||
billing_contacts = fields.Many2many(comodel_name='res.partner',
|
|
||||||
string="Billing Contacts",
|
|
||||||
compute='_compute_billing_contacts',
|
|
||||||
inverse='_inverse_billing_contacts',
|
|
||||||
store=True)
|
|
||||||
|
|
||||||
@api.depends('line_ids.sale_line_ids.order_id', 'partner_id')
|
|
||||||
def _compute_billing_contacts(self):
|
|
||||||
for rec in self:
|
|
||||||
order_id = rec.line_ids and rec.line_ids.mapped('sale_line_ids').mapped('order_id')
|
|
||||||
if order_id and len(order_id) == 1 and order_id.billing_contacts:
|
|
||||||
rec.billing_contacts = order_id.billing_contacts
|
|
||||||
else:
|
|
||||||
rec.billing_contacts = rec.partner_id.billing_contacts
|
|
||||||
|
|
||||||
def _inverse_billing_contacts(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _post(self, soft=True):
|
|
||||||
# Override the original method to subscribe the partner's billing contacts instead of self.partner_id
|
|
||||||
initial_subscribers = self.message_partner_ids.ids
|
|
||||||
final_subscribers = initial_subscribers + self.billing_contacts.ids
|
|
||||||
posted = super()._post()
|
|
||||||
self.message_unsubscribe([s.id for s in self.message_partner_ids if s not in initial_subscribers])
|
|
||||||
self.message_subscribe(final_subscribers)
|
|
||||||
return posted
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
from odoo import models, fields, api, _, Command
|
|
||||||
|
|
||||||
|
|
||||||
class Partner(models.Model):
|
|
||||||
_inherit = 'res.partner'
|
|
||||||
|
|
||||||
billing_contacts = fields.Many2many(string='Default Billing Contacts',
|
|
||||||
comodel_name='res.partner',
|
|
||||||
compute='_compute_billing_contacts',
|
|
||||||
inverse='_inverse_billing_contacts')
|
|
||||||
|
|
||||||
@api.depends('child_ids.type')
|
|
||||||
def _compute_billing_contacts(self):
|
|
||||||
for rec in self:
|
|
||||||
rec.billing_contacts = rec.child_ids.filtered(lambda r: r.type == 'invoice')
|
|
||||||
|
|
||||||
@api.depends('billing_contacts')
|
|
||||||
def _inverse_billing_contacts(self):
|
|
||||||
for partner in self.mapped('billing_contacts'):
|
|
||||||
partner.type = 'invoice'
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
from odoo import models, fields, api, _, Command
|
|
||||||
|
|
||||||
|
|
||||||
class SaleOrder(models.Model):
|
|
||||||
_inherit = 'sale.order'
|
|
||||||
|
|
||||||
billing_contacts = fields.Many2many(comodel_name='res.partner',
|
|
||||||
string='Billing Contacts',
|
|
||||||
compute='_compute_billing_contacts',
|
|
||||||
inverse='_inverse_billing_contacts',
|
|
||||||
store=True)
|
|
||||||
|
|
||||||
@api.depends('partner_id')
|
|
||||||
def _compute_billing_contacts(self):
|
|
||||||
for rec in self:
|
|
||||||
rec.billing_contacts = rec.partner_id.billing_contacts
|
|
||||||
|
|
||||||
def _inverse_billing_contacts(self):
|
|
||||||
pass
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
from . import test_billing_contacts
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
from odoo.tests import TransactionCase, tagged
|
|
||||||
from odoo import Command
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
|
|
||||||
@tagged('-at_install', 'post_install')
|
|
||||||
class TestBillingContacts(TransactionCase):
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
super().setUpClass()
|
|
||||||
partner = cls.env['res.partner'].create
|
|
||||||
cls.parent_co = partner({
|
|
||||||
'name': 'Partner',
|
|
||||||
'company_type': 'company',
|
|
||||||
})
|
|
||||||
cls.billing_contact1 = partner({
|
|
||||||
'name': 'Billing Contact 1',
|
|
||||||
'company_type': 'person',
|
|
||||||
'email': 'billingcontact1@partner.co',
|
|
||||||
'parent_id': cls.parent_co.id,
|
|
||||||
'type': 'invoice',
|
|
||||||
})
|
|
||||||
cls.billing_contact2 = partner({
|
|
||||||
'name': 'Billing Contact 2',
|
|
||||||
'company_type': 'person',
|
|
||||||
'email': 'billingcontact2@partner.co',
|
|
||||||
'parent_id': cls.parent_co.id,
|
|
||||||
'type': 'invoice',
|
|
||||||
})
|
|
||||||
cls.non_billing_contact = partner({
|
|
||||||
'name': 'Non-billing contact',
|
|
||||||
'company_type': 'person',
|
|
||||||
'email': 'not_billing@partner.co',
|
|
||||||
'parent_id': cls.parent_co.id,
|
|
||||||
'type': 'contact',
|
|
||||||
})
|
|
||||||
cls.product = cls.env['product.product'].with_company(cls.parent_co.company_id).create({
|
|
||||||
'name': 'Product',
|
|
||||||
'categ_id': cls.env['product.category'].create({'name': 'Product Category'}).id,
|
|
||||||
'list_price': 100.0,
|
|
||||||
'type': 'service',
|
|
||||||
'uom_id': cls.env.ref('uom.product_uom_unit').id,
|
|
||||||
'uom_po_id': cls.env.ref('uom.product_uom_unit').id,
|
|
||||||
'default_code': 'PRODUCT-X',
|
|
||||||
'invoice_policy': 'order',
|
|
||||||
'expense_policy': 'no',
|
|
||||||
'taxes_id': [(6, 0, [])],
|
|
||||||
'supplier_taxes_id': [(6, 0, [])],
|
|
||||||
})
|
|
||||||
|
|
||||||
cls.sale_order = cls.env['sale.order'].create({
|
|
||||||
'partner_id': cls.parent_co.id,
|
|
||||||
'client_order_ref': 'abc123',
|
|
||||||
})
|
|
||||||
|
|
||||||
cls.env['sale.order.line'].create({
|
|
||||||
'product_id': cls.product.id,
|
|
||||||
'name': cls.product.name,
|
|
||||||
'product_uom_qty': 2,
|
|
||||||
'product_uom': cls.product.uom_id.id,
|
|
||||||
'price_unit': cls.product.list_price,
|
|
||||||
'order_id': cls.sale_order.id,
|
|
||||||
'tax_id': False,
|
|
||||||
'qty_delivered_manual': 2,
|
|
||||||
})
|
|
||||||
|
|
||||||
def test_billing_contacts_structure(self):
|
|
||||||
self.assertTrue(self.billing_contact1 in self.parent_co.billing_contacts)
|
|
||||||
self.assertTrue(self.billing_contact2 in self.parent_co.billing_contacts)
|
|
||||||
self.assertTrue(self.non_billing_contact not in self.parent_co.billing_contacts)
|
|
||||||
|
|
||||||
def test_sale_order_default_billing_contacts(self):
|
|
||||||
self.assertTrue(self.sale_order.billing_contacts == self.parent_co.billing_contacts)
|
|
||||||
|
|
||||||
def test_sale_order_change_contacts(self):
|
|
||||||
# Test that changing the billing contacts on an SO doesn't change them on the partner
|
|
||||||
# Validate that changing them manually on the SO transfers to the invoice
|
|
||||||
self.sale_order.write({'billing_contacts': [Command.link(self.non_billing_contact.id)]})
|
|
||||||
self.assertTrue(all([c in self.sale_order.billing_contacts for c in self.parent_co.billing_contacts]))
|
|
||||||
self.assertTrue(self.non_billing_contact not in self.parent_co.billing_contacts)
|
|
||||||
self.assertTrue(self.non_billing_contact in self.sale_order.billing_contacts)
|
|
||||||
|
|
||||||
def test_sale_order_to_invoice_contacts(self):
|
|
||||||
# Test that the invoices created from sales orders take the billing contacts configured on the SO
|
|
||||||
|
|
||||||
self.sale_order.write({'billing_contacts': [Command.link(self.non_billing_contact.id)]})
|
|
||||||
self.sale_order.action_confirm()
|
|
||||||
|
|
||||||
wiz = self.env['sale.advance.payment.inv'].create({})
|
|
||||||
invoice = wiz._create_invoice(self.sale_order,self.sale_order.order_line[0],self.sale_order.order_line.price_total)
|
|
||||||
self.assertTrue(invoice)
|
|
||||||
self.assertTrue(invoice.billing_contacts == self.sale_order.billing_contacts)
|
|
||||||
|
|
||||||
def test_direct_invoice_contacts(self):
|
|
||||||
invoice = self.env['account.move'].create({
|
|
||||||
'move_type': 'out_invoice',
|
|
||||||
'partner_id': self.parent_co,
|
|
||||||
})
|
|
||||||
self.assertTrue(self.parent_co.billing_contacts == invoice.billing_contacts)
|
|
||||||
|
|
||||||
def test_invoice_followers_on_validate(self):
|
|
||||||
self.sale_order.action_confirm()
|
|
||||||
wiz = self.env['sale.advance.payment.inv'].create({})
|
|
||||||
invoice = wiz._create_invoice(self.sale_order,self.sale_order.order_line[0],self.sale_order.order_line.price_total)
|
|
||||||
invoice.write({'date': datetime.date.today()})
|
|
||||||
invoice.action_post()
|
|
||||||
self.assertTrue(all([r in invoice.message_partner_ids for r in self.parent_co.billing_contacts]))
|
|
||||||
Loading…
Reference in a new issue