mirror of
				https://github.com/brain-tec/account_ebics.git
				synced 2025-11-04 07:00:35 +00:00 
			
		
		
		
	[13.0]generic order type
This commit is contained in:
		@@ -3,7 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    'name': 'EBICS banking protocol',
 | 
					    'name': 'EBICS banking protocol',
 | 
				
			||||||
    'version': '13.0.1.2.1',
 | 
					    'version': '13.0.1.3.0',
 | 
				
			||||||
    'license': 'LGPL-3',
 | 
					    'license': 'LGPL-3',
 | 
				
			||||||
    'author': 'Noviat',
 | 
					    'author': 'Noviat',
 | 
				
			||||||
    'website': 'www.noviat.com',
 | 
					    'website': 'www.noviat.com',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
# Copyright 2009-2020 Noviat.
 | 
					# Copyright 2009-2020 Noviat.
 | 
				
			||||||
# License LGPL-3 or later (http://www.gnu.org/licenses/lpgl).
 | 
					# License LGPL-3 or later (http://www.gnu.org/licenses/lpgl).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from odoo import api, fields, models
 | 
					from odoo import fields, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EbicsFileFormat(models.Model):
 | 
					class EbicsFileFormat(models.Model):
 | 
				
			||||||
@@ -9,17 +9,19 @@ class EbicsFileFormat(models.Model):
 | 
				
			|||||||
    _description = 'EBICS File Formats'
 | 
					    _description = 'EBICS File Formats'
 | 
				
			||||||
    _order = 'type,name'
 | 
					    _order = 'type,name'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    name = fields.Selection(
 | 
					    name = fields.Char(
 | 
				
			||||||
        selection=lambda self: self._selection_name(),
 | 
					        string='Request Type',
 | 
				
			||||||
        string='Request Type', required=True)
 | 
					        required=True,
 | 
				
			||||||
 | 
					        help="E.g. camt.053.001.02.stm, camt.xxx.cfonb120.stm, "
 | 
				
			||||||
 | 
					             "pain.001.001.03.sct (check your EBICS contract).\n")
 | 
				
			||||||
    type = fields.Selection(
 | 
					    type = fields.Selection(
 | 
				
			||||||
        selection=[('down', 'Download'),
 | 
					        selection=[('down', 'Download'),
 | 
				
			||||||
                   ('up', 'Upload')],
 | 
					                   ('up', 'Upload')],
 | 
				
			||||||
        required=True)
 | 
					        required=True)
 | 
				
			||||||
    order_type = fields.Selection(
 | 
					    order_type = fields.Char(
 | 
				
			||||||
        selection=lambda self: self._selection_order_type(),
 | 
					 | 
				
			||||||
        string='Order Type',
 | 
					        string='Order Type',
 | 
				
			||||||
        help="For most banks is France you should use the "
 | 
					        help="E.g. C53 (check your EBICS contract).\n"
 | 
				
			||||||
 | 
					             "For most banks in France you should use the "
 | 
				
			||||||
             "format neutral Order Types 'FUL' for upload "
 | 
					             "format neutral Order Types 'FUL' for upload "
 | 
				
			||||||
             "and 'FDL' for download.")
 | 
					             "and 'FDL' for download.")
 | 
				
			||||||
    signature_class = fields.Selection(
 | 
					    signature_class = fields.Selection(
 | 
				
			||||||
@@ -36,45 +38,3 @@ class EbicsFileFormat(models.Model):
 | 
				
			|||||||
        required=True,
 | 
					        required=True,
 | 
				
			||||||
        help="Specify the filename suffix for this File Format."
 | 
					        help="Specify the filename suffix for this File Format."
 | 
				
			||||||
             "\nE.g. camt.053.xml")
 | 
					             "\nE.g. camt.053.xml")
 | 
				
			||||||
 | 
					 | 
				
			||||||
    @api.model
 | 
					 | 
				
			||||||
    def _selection_order_type(self):
 | 
					 | 
				
			||||||
        up = self._supported_upload_order_types()
 | 
					 | 
				
			||||||
        down = self._supported_download_order_types()
 | 
					 | 
				
			||||||
        selection = [(x, x) for x in up + down]
 | 
					 | 
				
			||||||
        return selection
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _supported_upload_order_types(self):
 | 
					 | 
				
			||||||
        return ['FUL', 'CCT', 'CDD', 'CDB', 'XE2', 'XE3']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _supported_download_order_types(self):
 | 
					 | 
				
			||||||
        return ['FDL', 'C52', 'C53', 'C54']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @api.model
 | 
					 | 
				
			||||||
    def _selection_name(self):
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        List of supported EBICS Request Types.
 | 
					 | 
				
			||||||
        Extend this method via a custom module when testing
 | 
					 | 
				
			||||||
        a new Request Type and make a PR for the
 | 
					 | 
				
			||||||
        account_ebics module when this new Request Type
 | 
					 | 
				
			||||||
        is working correctly.
 | 
					 | 
				
			||||||
        This PR should include at least updates to
 | 
					 | 
				
			||||||
        - 'data/ebics_file_format.xml'
 | 
					 | 
				
			||||||
        - 'models/ebics_file_format.py'
 | 
					 | 
				
			||||||
        An overview of the EBICS Request Types can be found in
 | 
					 | 
				
			||||||
        the doc folder of this module (EBICS_Annex2).
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        request_types = [
 | 
					 | 
				
			||||||
            'camt.052.001.02.stm',
 | 
					 | 
				
			||||||
            'camt.053.001.02.stm',
 | 
					 | 
				
			||||||
            'pain.001.001.03.sct',
 | 
					 | 
				
			||||||
            'pain.008.001.02.sdd',
 | 
					 | 
				
			||||||
            'pain.008.001.02.sbb',
 | 
					 | 
				
			||||||
            'camt.xxx.cfonb120.stm',
 | 
					 | 
				
			||||||
            'pain.001.001.02.sct',
 | 
					 | 
				
			||||||
            'camt.053',
 | 
					 | 
				
			||||||
            'pain.001',
 | 
					 | 
				
			||||||
            'pain.008',
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
        selection = [(x, x) for x in request_types]
 | 
					 | 
				
			||||||
        return selection
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,12 +64,10 @@ class EbicsXfer(models.TransientModel):
 | 
				
			|||||||
    format_id = fields.Many2one(
 | 
					    format_id = fields.Many2one(
 | 
				
			||||||
        comodel_name='ebics.file.format',
 | 
					        comodel_name='ebics.file.format',
 | 
				
			||||||
        string='EBICS File Format',
 | 
					        string='EBICS File Format',
 | 
				
			||||||
        help="Select EBICS File Format to upload/download."
 | 
					        help="Select EBICS File Format to upload/download.")
 | 
				
			||||||
             "\nLeave blank to download all available files.")
 | 
					    order_type = fields.Char(
 | 
				
			||||||
    order_type = fields.Selection(
 | 
					 | 
				
			||||||
        selection=lambda self: self._selection_order_type(),
 | 
					 | 
				
			||||||
        string='Order Type',
 | 
					        string='Order Type',
 | 
				
			||||||
        help="For most banks is France you should use the "
 | 
					        help="For most banks in France you should use the "
 | 
				
			||||||
             "format neutral Order Types 'FUL' for upload "
 | 
					             "format neutral Order Types 'FUL' for upload "
 | 
				
			||||||
             "and 'FDL' for download.")
 | 
					             "and 'FDL' for download.")
 | 
				
			||||||
    test_mode = fields.Boolean(
 | 
					    test_mode = fields.Boolean(
 | 
				
			||||||
@@ -91,10 +89,6 @@ class EbicsXfer(models.TransientModel):
 | 
				
			|||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return cfg_mod
 | 
					            return cfg_mod
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @api.model
 | 
					 | 
				
			||||||
    def _selection_order_type(self):
 | 
					 | 
				
			||||||
        return self.env['ebics.file.format']._selection_order_type()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @api.onchange('ebics_config_id')
 | 
					    @api.onchange('ebics_config_id')
 | 
				
			||||||
    def _onchange_ebics_config_id(self):
 | 
					    def _onchange_ebics_config_id(self):
 | 
				
			||||||
        ebics_userids = self.ebics_config_id.ebics_userid_ids
 | 
					        ebics_userids = self.ebics_config_id.ebics_userid_ids
 | 
				
			||||||
@@ -166,63 +160,56 @@ class EbicsXfer(models.TransientModel):
 | 
				
			|||||||
        self.note = ''
 | 
					        self.note = ''
 | 
				
			||||||
        client = self._setup_client()
 | 
					        client = self._setup_client()
 | 
				
			||||||
        if client:
 | 
					        if client:
 | 
				
			||||||
            download_formats = self.format_id \
 | 
					 | 
				
			||||||
                or self.ebics_config_id.ebics_file_format_ids.filtered(
 | 
					 | 
				
			||||||
                    lambda r: r.type == 'down')
 | 
					 | 
				
			||||||
            ebics_files = self.env['ebics.file']
 | 
					            ebics_files = self.env['ebics.file']
 | 
				
			||||||
            for df in download_formats:
 | 
					            success = False
 | 
				
			||||||
                success = False
 | 
					            order_type = self.order_type or 'FDL'
 | 
				
			||||||
                order_type = df.order_type or 'FDL'
 | 
					            date_from = self.date_from and self.date_from.isoformat() or None
 | 
				
			||||||
                params = {}
 | 
					            date_to = self.date_to and self.date_to.isoformat() or None
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
                if order_type == 'FDL':
 | 
					                if order_type == 'FDL':
 | 
				
			||||||
                    params['filetype'] = df.name
 | 
					                    data = client.FDL(self.format_id.name, date_from, date_to)
 | 
				
			||||||
                if order_type in ['FDL', 'C52', 'C53', 'C54']:
 | 
					 | 
				
			||||||
                    params.update({
 | 
					 | 
				
			||||||
                        'start':
 | 
					 | 
				
			||||||
                            self.date_from and self.date_from.isoformat()
 | 
					 | 
				
			||||||
                            or None,
 | 
					 | 
				
			||||||
                        'end':
 | 
					 | 
				
			||||||
                            self.date_to and self.date_to.isoformat()
 | 
					 | 
				
			||||||
                            or None,
 | 
					 | 
				
			||||||
                    })
 | 
					 | 
				
			||||||
                kwargs = {k: v for k, v in params.items() if v}
 | 
					 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    method = getattr(client, order_type)
 | 
					 | 
				
			||||||
                    data = method(**kwargs)
 | 
					 | 
				
			||||||
                    ebics_files += self._handle_download_data(data, df)
 | 
					 | 
				
			||||||
                    success = True
 | 
					 | 
				
			||||||
                except EbicsFunctionalError:
 | 
					 | 
				
			||||||
                    e = exc_info()
 | 
					 | 
				
			||||||
                    self.note += '\n'
 | 
					 | 
				
			||||||
                    self.note += _("EBICS Functional Error:")
 | 
					 | 
				
			||||||
                    self.note += '\n'
 | 
					 | 
				
			||||||
                    self.note += '%s (code: %s)' % (e[1].message, e[1].code)
 | 
					 | 
				
			||||||
                except EbicsTechnicalError:
 | 
					 | 
				
			||||||
                    e = exc_info()
 | 
					 | 
				
			||||||
                    self.note += '\n'
 | 
					 | 
				
			||||||
                    self.note += _("EBICS Technical Error:")
 | 
					 | 
				
			||||||
                    self.note += '\n'
 | 
					 | 
				
			||||||
                    self.note += '%s (code: %s)' % (e[1].message, e[1].code)
 | 
					 | 
				
			||||||
                except EbicsVerificationError:
 | 
					 | 
				
			||||||
                    self.note += '\n'
 | 
					 | 
				
			||||||
                    self.note += _("EBICS Verification Error:")
 | 
					 | 
				
			||||||
                    self.note += '\n'
 | 
					 | 
				
			||||||
                    self.note += _("The EBICS response could not be verified.")
 | 
					 | 
				
			||||||
                except UserError as e:
 | 
					 | 
				
			||||||
                    self.note += '\n'
 | 
					 | 
				
			||||||
                    self.note += _("Warning:")
 | 
					 | 
				
			||||||
                    self.note += '\n'
 | 
					 | 
				
			||||||
                    self.note += e.name
 | 
					 | 
				
			||||||
                except Exception:
 | 
					 | 
				
			||||||
                    self.note += '\n'
 | 
					 | 
				
			||||||
                    self.note += _("Unknown Error")
 | 
					 | 
				
			||||||
                    tb = ''.join(format_exception(*exc_info()))
 | 
					 | 
				
			||||||
                    self.note += '\n%s' % tb
 | 
					 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    # mark received data so that it is not included in further
 | 
					                    params = None
 | 
				
			||||||
                    # downloads
 | 
					                    if date_from and date_to:
 | 
				
			||||||
                    trans_id = client.last_trans_id
 | 
					                        params = {'DateRange': {
 | 
				
			||||||
                    client.confirm_download(trans_id=trans_id, success=success)
 | 
					                            'Start': date_from,
 | 
				
			||||||
 | 
					                            'End': date_to,
 | 
				
			||||||
 | 
					                        }}
 | 
				
			||||||
 | 
					                    data = client.download(order_type, params=params)
 | 
				
			||||||
 | 
					                ebics_files += self._handle_download_data(data, self.format_id)
 | 
				
			||||||
 | 
					                success = True
 | 
				
			||||||
 | 
					            except EbicsFunctionalError:
 | 
				
			||||||
 | 
					                e = exc_info()
 | 
				
			||||||
 | 
					                self.note += '\n'
 | 
				
			||||||
 | 
					                self.note += _("EBICS Functional Error:")
 | 
				
			||||||
 | 
					                self.note += '\n'
 | 
				
			||||||
 | 
					                self.note += '%s (code: %s)' % (e[1].message, e[1].code)
 | 
				
			||||||
 | 
					            except EbicsTechnicalError:
 | 
				
			||||||
 | 
					                e = exc_info()
 | 
				
			||||||
 | 
					                self.note += '\n'
 | 
				
			||||||
 | 
					                self.note += _("EBICS Technical Error:")
 | 
				
			||||||
 | 
					                self.note += '\n'
 | 
				
			||||||
 | 
					                self.note += '%s (code: %s)' % (e[1].message, e[1].code)
 | 
				
			||||||
 | 
					            except EbicsVerificationError:
 | 
				
			||||||
 | 
					                self.note += '\n'
 | 
				
			||||||
 | 
					                self.note += _("EBICS Verification Error:")
 | 
				
			||||||
 | 
					                self.note += '\n'
 | 
				
			||||||
 | 
					                self.note += _("The EBICS response could not be verified.")
 | 
				
			||||||
 | 
					            except UserError as e:
 | 
				
			||||||
 | 
					                self.note += '\n'
 | 
				
			||||||
 | 
					                self.note += _("Warning:")
 | 
				
			||||||
 | 
					                self.note += '\n'
 | 
				
			||||||
 | 
					                self.note += e.name
 | 
				
			||||||
 | 
					            except Exception:
 | 
				
			||||||
 | 
					                self.note += '\n'
 | 
				
			||||||
 | 
					                self.note += _("Unknown Error")
 | 
				
			||||||
 | 
					                tb = ''.join(format_exception(*exc_info()))
 | 
				
			||||||
 | 
					                self.note += '\n%s' % tb
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                # mark received data so that it is not included in further
 | 
				
			||||||
 | 
					                # downloads
 | 
				
			||||||
 | 
					                trans_id = client.last_trans_id
 | 
				
			||||||
 | 
					                client.confirm_download(trans_id=trans_id, success=success)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ctx['ebics_file_ids'] = ebics_files._ids
 | 
					            ctx['ebics_file_ids'] = ebics_files._ids
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -271,7 +258,7 @@ class EbicsXfer(models.TransientModel):
 | 
				
			|||||||
            ef_format = self.format_id
 | 
					            ef_format = self.format_id
 | 
				
			||||||
            OrderID = False
 | 
					            OrderID = False
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                order_type = ef_format.order_type or 'FUL'
 | 
					                order_type = self.order_type or 'FUL'
 | 
				
			||||||
                method = hasattr(client, order_type) \
 | 
					                method = hasattr(client, order_type) \
 | 
				
			||||||
                    and getattr(client, order_type)
 | 
					                    and getattr(client, order_type)
 | 
				
			||||||
                if order_type == 'FUL':
 | 
					                if order_type == 'FUL':
 | 
				
			||||||
@@ -285,12 +272,8 @@ class EbicsXfer(models.TransientModel):
 | 
				
			|||||||
                    OrderID = method(ef_format.name, upload_data, **kwargs)
 | 
					                    OrderID = method(ef_format.name, upload_data, **kwargs)
 | 
				
			||||||
                elif order_type in ['CCT', 'CDD', 'CDB']:
 | 
					                elif order_type in ['CCT', 'CDD', 'CDB']:
 | 
				
			||||||
                    OrderID = method(upload_data)
 | 
					                    OrderID = method(upload_data)
 | 
				
			||||||
                elif order_type in ['XE2', 'XE3']:
 | 
					 | 
				
			||||||
                    OrderID = client.upload(order_type, upload_data)
 | 
					 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    # TODO: investigate if it makes sense to support
 | 
					                    OrderID = client.upload(order_type, upload_data)
 | 
				
			||||||
                    # a generic upload for a non-predefined order_type
 | 
					 | 
				
			||||||
                    pass
 | 
					 | 
				
			||||||
                if OrderID:
 | 
					                if OrderID:
 | 
				
			||||||
                    self.note += '\n'
 | 
					                    self.note += '\n'
 | 
				
			||||||
                    self.note += _(
 | 
					                    self.note += _(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@
 | 
				
			|||||||
          <field name="date_from"/>
 | 
					          <field name="date_from"/>
 | 
				
			||||||
          <field name="date_to"/>
 | 
					          <field name="date_to"/>
 | 
				
			||||||
          <field name="format_id"/>
 | 
					          <field name="format_id"/>
 | 
				
			||||||
 | 
					          <field name="order_type"/>
 | 
				
			||||||
        </group>
 | 
					        </group>
 | 
				
			||||||
        <footer>
 | 
					        <footer>
 | 
				
			||||||
          <button name="ebics_download" string="Download Files" type="object" class="oe_highlight"/>
 | 
					          <button name="ebics_download" string="Download Files" type="object" class="oe_highlight"/>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user