[FIX] account_peppol: fix peppol ready state

- Create a Partner who is a valid Peppol participant
- Clear their UBL format - they are still displayed as valid (Bug 1)
- Create an invoice for that partner and confirm it. The Peppol state changes to 'ready'
- Erase eas or endpoint on that partner and verify - the partner is now not a valid Peppol participant
- Reset the invoice to draft, confirm again: the peppol move state is still `ready`

1. Do not set a participant as valid if a peppol-incompatible edi format has been selected
2. Only save Peppol move state if it's processing/done already. Otherwise, let users clear it by resetting to draft.
(until we implement giving them control over this field)

opw-3784945

closes odoo/odoo#159852

Signed-off-by: Laurent Smet (las) <las@odoo.com>
This commit is contained in:
aliya
2024-04-04 17:02:58 +00:00
parent cef76872f8
commit 10363b3ae1
4 changed files with 51 additions and 12 deletions
@@ -62,5 +62,11 @@ class AccountMove(models.Model):
not move.peppol_move_state,
]):
move.peppol_move_state = 'ready'
elif (
move.state == 'draft'
and move.is_sale_document(include_receipts=True)
and move.peppol_move_state not in ('processing', 'done')
):
move.peppol_move_state = False
else:
move.peppol_move_state = move.peppol_move_state
+7 -7
View File
@@ -23,7 +23,7 @@ class ResPartner(models.Model):
account_peppol_validity_last_check = fields.Date(
string="Checked on",
help="Last Peppol endpoint verification",
readonly=True,
compute="_compute_account_peppol_is_endpoint_valid", store=True,
copy=False,
)
account_peppol_verification_label = fields.Selection(
@@ -37,10 +37,10 @@ class ResPartner(models.Model):
copy=False,
) # field to compute the label to show for partner endpoint
@api.depends('peppol_eas', 'peppol_endpoint')
@api.depends('peppol_eas', 'peppol_endpoint', 'ubl_cii_format')
def _compute_account_peppol_is_endpoint_valid(self):
# Every change in peppol_eas or peppol_endpoint should set the validity back to False
self.account_peppol_is_endpoint_valid = False
for partner in self:
partner.button_account_peppol_check_partner_endpoint()
@api.depends('account_peppol_is_endpoint_valid', 'account_peppol_validity_last_check')
def _compute_account_peppol_verification_label(self):
@@ -56,8 +56,8 @@ class ResPartner(models.Model):
def _check_peppol_participant_exists(self, edi_identification):
hash_participant = md5(edi_identification.lower().encode()).hexdigest()
endpoint_participant = parse.quote_plus(f"iso6523-actorid-upis::{edi_identification}")
peppol_param = self.env['ir.config_parameter'].sudo().get_param('account_peppol.edi.mode', False)
sml_zone = 'acc.edelivery' if peppol_param == 'test' else 'edelivery'
peppol_user = self.env.company.account_edi_proxy_client_ids.filtered(lambda user: user.proxy_type == 'peppol')
sml_zone = 'acc.edelivery' if peppol_user.edi_mode == 'test' else 'edelivery'
smp_url = f"http://B-{hash_participant}.iso6523-actorid-upis.{sml_zone}.tech.ec.europa.eu/{endpoint_participant}"
try:
@@ -90,7 +90,7 @@ class ResPartner(models.Model):
"""
self.ensure_one()
if not self.peppol_eas and self.peppol_endpoint:
if not (self.peppol_eas and self.peppol_endpoint) or self.ubl_cii_format in (False, 'facturx', 'oioubl_201'):
self.account_peppol_is_endpoint_valid = False
else:
edi_identification = f'{self.peppol_eas}:{self.peppol_endpoint}'.lower()
@@ -138,7 +138,14 @@ class TestPeppolMessage(TestAccountMoveSendCommon):
def _request_handler(cls, s: Session, r: PreparedRequest, /, **kw):
response = Response()
response.status_code = 200
if r.url.endswith('/iso6523-actorid-upis%3A%3A9925%3A0000000000'):
if r.url.endswith('iso6523-actorid-upis%3A%3A0208%3A0477472701'):
response._content = b'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<smp:ServiceGroup xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:id="http://busdox.org/transport/identifiers/1.0/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:smp="http://busdox.org/serviceMetadata/publishing/1.0/"><id:ParticipantIdentifier scheme="iso6523-actorid-upis">0208:0477472701</id:ParticipantIdentifier></smp:ServiceGroup>'
return response
if r.url.endswith('iso6523-actorid-upis%3A%3A0208%3A3141592654'):
response.status_code = 404
return response
if r.url.endswith('iso6523-actorid-upis%3A%3A0208%3A2718281828'):
response._content = b'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<smp:ServiceGroup xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:id="http://busdox.org/transport/identifiers/1.0/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:smp="http://busdox.org/serviceMetadata/publishing/1.0/"><id:ParticipantIdentifier scheme="iso6523-actorid-upis">0208:2718281828</id:ParticipantIdentifier></smp:ServiceGroup>'
return response
proxy_documents, responses = cls._get_mock_data(cls.env.context.get('error'))
@@ -294,3 +301,29 @@ class TestPeppolMessage(TestAccountMoveSendCommon):
'peppol_move_state': 'done',
'move_type': 'in_invoice',
}])
def test_validate_partner(self):
new_partner = self.env['res.partner'].create({
'name': 'Deanna Troi',
'city': 'Namur',
'country_id': self.env.ref('base.be').id,
})
self.assertRecordValues(
new_partner, [{
'account_peppol_verification_label': 'not_verified',
'account_peppol_is_endpoint_valid': False,
'peppol_eas': '0208',
'peppol_endpoint': False,
}])
new_partner.peppol_endpoint = '0477472701'
self.assertRecordValues(
new_partner, [{
'account_peppol_verification_label': 'valid',
'account_peppol_is_endpoint_valid': True, # should validate automatically
'peppol_eas': '0208',
'peppol_endpoint': '0477472701',
}])
new_partner.ubl_cii_format = False
self.assertFalse(new_partner.account_peppol_is_endpoint_valid)
+4 -4
View File
@@ -472,7 +472,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
test_record, test_template = self._create_test_records()
test_template.write({'attachment_ids': [(5, 0)]})
with self.assertQueryCount(admin=27, employee=27): # tm 16/16 / com 26/26
with self.assertQueryCount(admin=28, employee=28): # tm 16/16 / com 26/26
composer = self.env['mail.compose.message'].with_context({
'default_composition_mode': 'comment',
'default_model': test_record._name,
@@ -496,7 +496,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
def test_mail_composer_w_template_attachments(self):
test_record, test_template = self._create_test_records()
with self.assertQueryCount(admin=28, employee=28): # tm 17/17 / com 27/27
with self.assertQueryCount(admin=29, employee=29): # tm 17/17 / com 27/27
composer = self.env['mail.compose.message'].with_context({
'default_composition_mode': 'comment',
'default_model': test_record._name,
@@ -525,7 +525,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
test_template.write({'attachment_ids': [(5, 0)]})
customer = self.env['res.partner'].browse(self.customer.ids)
with self.assertQueryCount(admin=34, employee=34): # tm 23/23 / com 33/33
with self.assertQueryCount(admin=35, employee=35): # tm 23/23 / com 33/33
composer_form = Form(
self.env['mail.compose.message'].with_context({
'default_composition_mode': 'comment',
@@ -555,7 +555,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
test_record, test_template = self._create_test_records()
customer = self.env['res.partner'].browse(self.customer.ids)
with self.assertQueryCount(admin=34, employee=34): # tm 23/23 / com 32/32
with self.assertQueryCount(admin=35, employee=35): # tm 23/23 / com 32/32
composer_form = Form(
self.env['mail.compose.message'].with_context({
'default_composition_mode': 'comment',