Ejemplo n.º 1
0
 def post(self):
     # OVERRIDE
     # On the validation of an invoice, send the different corrected fields to iap to improve the ocr algorithm.
     res = super(AccountMove, self).post()
     for record in self.filtered(lambda move: move.is_invoice()):
         if record.extract_state == 'waiting_validation':
             endpoint = self.env['ir.config_parameter'].sudo().get_param(
                 'account_invoice_extract_endpoint',
                 'https://iap-extract.odoo.com'
             ) + '/iap/invoice_extract/validate'
             values = {
                 'total':
                 record.get_validation('total'),
                 'subtotal':
                 record.get_validation('subtotal'),
                 'global_taxes':
                 record.get_validation('global_taxes'),
                 'global_taxes_amount':
                 record.get_validation('global_taxes_amount'),
                 'date':
                 record.get_validation('date'),
                 'due_date':
                 record.get_validation('due_date'),
                 'invoice_id':
                 record.get_validation('invoice_id'),
                 'partner':
                 record.get_validation('supplier'),
                 'VAT_Number':
                 record.get_validation('VAT_Number'),
                 'currency':
                 record.get_validation('currency'),
                 'merged_lines':
                 self.env.company.extract_single_line_per_tax,
                 'invoice_lines':
                 record.get_validation('invoice_lines')
             }
             params = {
                 'document_id': record.extract_remote_id,
                 'version': CLIENT_OCR_VERSION,
                 'values': values
             }
             try:
                 jsonrpc(endpoint, params=params)
                 record.extract_state = 'done'
             except AccessError:
                 pass
     # we don't need word data anymore, we can delete them
     self.mapped('extract_word_ids').unlink()
     return res
Ejemplo n.º 2
0
 def _get_twitter_oauth_signature_from_iap(self,
                                           method,
                                           url,
                                           params,
                                           oauth_token_secret=''):
     params['oauth_nonce'] = str(params['oauth_nonce'])
     json_params = {
         'method':
         method,
         'url':
         url,
         'params':
         params,
         'oauth_token_secret':
         oauth_token_secret,
         'db_uuid':
         self.env['ir.config_parameter'].sudo().get_param('database.uuid')
     }
     social_iap_endpoint = self.env['ir.config_parameter'].sudo().get_param(
         'social.social_iap_endpoint',
         self.env['social.media']._DEFAULT_SOCIAL_IAP_ENDPOINT)
     try:
         return jsonrpc(url_join(social_iap_endpoint,
                                 'iap/social_twitter/get_signature'),
                        params=json_params)
     except AccessError:
         return None
Ejemplo n.º 3
0
 def _snailmail_estimate_from_documents(self, res_model, res_ids, partner_field=None):
     endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
     docs = self.env[res_model].browse(res_ids)
     doc_list = []
     for doc in docs:
         if partner_field:
             country_code = doc[partner_field].country_id.code
         else:
             country_code = doc.country_id.code
         val = {
         'pages': 1,
         'address': {
             'country_code': country_code,
             },
         }
         doc_list.append(val)
     params = {
         'account_token': "",
         'documents': doc_list,
         'options': {
             'color': self.env.user.company_id.snailmail_color,
             'duplex': self.env.user.company_id.snailmail_duplex,
             'currency_name': 'EUR',
         },
     }
     req = jsonrpc(endpoint + '/iap/snailmail/1/estimate', params=params)
     return req['total_cost']
Ejemplo n.º 4
0
    def _snailmail_print(self):
        """
        get response
        {
            'request_code': RESPONSE_OK, # because we receive 200 if good or fail
            'total_cost': total_cost,
            'credit_error': credit_error,
            'request': {
                'documents': documents,
                'options': options
                }
            }
        }
        """
        self.write({'state': 'pending'})
        endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('print')
        response = jsonrpc(endpoint + PRINT_ENDPOINT, params=params)
        for doc in response['request']['documents']:
            letter = self.browse(doc['letter_id'])
            record = self.env[doc['res_model']].browse(doc['res_id'])
            if doc.get('sent') and response['request_code'] == 200:
                if hasattr(record, '_message_log'):
                    message = _('The document was correctly sent by post.<br>The tracking id is %s' % doc['send_id'])
                    record._message_log(body=message)
                    letter.write({'info_msg': message, 'state': 'sent'})
            else:
                # look for existing activities related to snailmail to update or create a new one.
                # TODO: in following versions, Add a link to a specifc activity on the letter
                note = _('An error occured when sending the document by post.<br>Error: %s' % \
                    self._get_error_message(doc['error'] if response['request_code'] == 200 else response['reason']))

                domain = [
                    ('summary', 'ilike', '[SNAILMAIL]'),
                    ('res_id', '=', letter.res_id),
                    ('res_model_id', '=', self.env['ir.model']._get(letter.model).id),
                    ('activity_type_id', '=', self.env.ref('mail.mail_activity_data_warning').id),
                ]
                MailActivity = self.env['mail.activity']
                activity = MailActivity.search(domain, limit=1)

                activity_data = {
                    'activity_type_id': self.env.ref('mail.mail_activity_data_warning').id,
                    'summary': '[SNAILMAIL] ' + _('Post letter: an error occured.'),
                    'note': note,
                    'date_deadline': fields.Date.today()
                }
                if activity:
                    activity.update(activity_data)
                else:
                    activity_data.update({
                        'user_id': letter.user_id.id,
                        'res_id': letter.res_id,
                        'res_model_id': self.env['ir.model']._get(letter.model).id,
                    })
                    MailActivity.create(activity_data)

                letter.write({'info_msg': note, 'state': 'error'})

        self.env.cr.commit()
Ejemplo n.º 5
0
    def _snailmail_estimate(self):
        """
        Send a request to estimate the cost of sending all the documents with
        the differents options.

        The JSON object sent is the one generated from self._snailmail_create()

        arguments sent:
        {
            "documents":[{
                pages: int,
                res_id: int (client_side, optional),
                res_model: int (client_side, optional),
                address: {
                    country_code: char (country name)
                }
            }],
            'color': # color on the letter,
            'duplex': # one/two side printing,
        }

        The answer of the server is the same JSON object with some additionnal fields:
        {
            "total_cost": integer,      //The cost of sending ALL the documents
            body: JSON object (same as body param except new param 'cost' in each documents)
        }
        """
        endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('estimate')
        req = jsonrpc(endpoint + '/iap/snailmail/1/estimate', params=params)

        return req['total_cost']
Ejemplo n.º 6
0
    def _snailmail_estimate(self):
        """
        Send a request to estimate the cost of sending all the documents with
        the differents options.

        The JSON object sent is the one generated from self._snailmail_create()

        arguments sent:
        {
            "documents":[{
                pages: int,
                res_id: int (client_side, optional),
                res_model: int (client_side, optional),
                address: {
                    country_code: char (country name)
                }
            }],
            'color': # color on the letter,
            'duplex': # one/two side printing,
        }

        The answer of the server is the same JSON object with some additionnal fields:
        {
            "total_cost": integer,      //The cost of sending ALL the documents
            body: JSON object (same as body param except new param 'cost' in each documents)
        }
        """
        endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('estimate')
        req = jsonrpc(endpoint + '/iap/snailmail/1/estimate', params=params)
        # The cost is sent in hunderth of eurocents, we change it to euros and then convert it to the company currency
        cost = int(req['total_cost'])/10000.0
        currency_eur = self.env.ref('base.EUR')

        return currency_eur._convert(cost, self[0].company_id.currency_id, self[0].company_id, fields.Datetime.now())
Ejemplo n.º 7
0
    def _snailmail_print_valid_address(self):
        """
        get response
        {
            'request_code': RESPONSE_OK, # because we receive 200 if good or fail
            'total_cost': total_cost,
            'credit_error': credit_error,
            'request': {
                'documents': documents,
                'options': options
                }
            }
        }
        """
        endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('print')
        response = jsonrpc(endpoint + PRINT_ENDPOINT, params=params)
        for doc in response['request']['documents']:
            if doc.get('sent') and response['request_code'] == 200:
                note = _('The document was correctly sent by post.<br>The tracking id is %s' % doc['send_id'])
                letter_data = {'info_msg': note, 'state': 'sent', 'error_code': False}
            else:
                error = doc['error'] if response['request_code'] == 200 else response['reason']

                note = _('An error occured when sending the document by post.<br>Error: %s' % self._get_error_message(error))
                letter_data = {
                    'info_msg': note,
                    'state': 'error',
                    'error_code': error if error in ERROR_CODES else 'UNKNOWN_ERROR'
                }

            letter = self.browse(doc['letter_id'])
            letter.write(letter_data)
        self.send_snailmail_update()
Ejemplo n.º 8
0
 def convert(self, binary, mimetype=None, filename=None, export="binary", doctype="document", format="pdf"):
     """ Converts a binary value to the given format.
     
         :param binary: The binary value.
         :param mimetype: The mimetype of the binary value.
         :param filename: The filename of the binary value.
         :param export: The output format (binary, file, base64).
         :param doctype: Specify the document type (document, graphics, presentation, spreadsheet).
         :param format: Specify the output format for the document.
         :return: Returns the output depending on the given format.
         :raises ValueError: The file extension could not be determined or the format is invalid.
     """
     params = {
         'format': format,
         'doctype': doctype,
         'mimetype': mimetype,
         'filename': filename,
         'content': base64.b64encode(binary),
     }
     result = jsonrpc(self.endpoint(CONVERTER_ENDPOINT_CONVERT), params=self.payload(params))
     if export == 'base64':
         return result
     if export == 'file':
         output = io.BytesIO()
         output.write(base64.b64decode(result))
         output.close()
         return output
     else:
         return base64.b64decode(result)
Ejemplo n.º 9
0
 def _snailmail_estimate_from_documents(self, res_model, res_ids, partner_field=None):
     endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
     docs = self.env[res_model].browse(res_ids)
     doc_list = []
     for doc in docs:
         if partner_field:
             country_code = doc[partner_field].country_id.code
         else:
             country_code = doc.country_id.code
         val = {
         'pages': 1,
         'address': {
             'country_code': country_code,
             },
         }
         doc_list.append(val)
     params = {
         'account_token': "",
         'documents': doc_list,
         'options': {
             'color': self.env.company_id.snailmail_color,
             'duplex': self.env.company_id.snailmail_duplex,
             'currency_name': 'EUR',
         },
     }
     req = jsonrpc(endpoint + '/iap/snailmail/1/estimate', params=params)
     return req['total_cost']
Ejemplo n.º 10
0
    def _snailmail_print_valid_address(self):
        """
        get response
        {
            'request_code': RESPONSE_OK, # because we receive 200 if good or fail
            'total_cost': total_cost,
            'credit_error': credit_error,
            'request': {
                'documents': documents,
                'options': options
                }
            }
        }
        """
        endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('print')
        response = jsonrpc(endpoint + PRINT_ENDPOINT, params=params)
        for doc in response['request']['documents']:
            if doc.get('sent') and response['request_code'] == 200:
                note = _('The document was correctly sent by post.<br>The tracking id is %s' % doc['send_id'])
                letter_data = {'info_msg': note, 'state': 'sent', 'error_code': False}
            else:
                error = doc['error'] if response['request_code'] == 200 else response['reason']

                note = _('An error occured when sending the document by post.<br>Error: %s' % self._get_error_message(error))
                letter_data = {
                    'info_msg': note,
                    'state': 'error',
                    'error_code': error if error in ERROR_CODES else 'UNKNOWN_ERROR'
                }

            letter = self.browse(doc['letter_id'])
            letter.write(letter_data)
        self.send_snailmail_update()
Ejemplo n.º 11
0
 def message_post(self, **kwargs):
     """When a message is posted on an account.invoice, send the attachment to iap-ocr if
     the res_config is on "auto_send" and if this is the first attachment."""
     res = super(AccountInvoice, self).message_post(**kwargs)
     if self.env.user.company_id.extract_show_ocr_option_selection == 'auto_send':
         account_token = self.env['iap.account'].get('invoice_ocr')
         for record in self:
             if record.type in ["out_invoice", "out_refund"]:
                 return res
             if record.extract_state == "no_extract_requested":
                 attachments = res.attachment_ids
                 if attachments:
                     endpoint = self.env['ir.config_parameter'].sudo().get_param(
                         'account_invoice_extract_endpoint', 'https://iap-extract.odoo.com') + '/iap/invoice_extract/parse'
                     params = {
                         'account_token': account_token.account_token,
                         'version': CLIENT_OCR_VERSION,
                         'dbuuid': self.env['ir.config_parameter'].sudo().get_param('database.uuid'),
                         'documents': [x.datas.decode('utf-8') for x in attachments],
                         'file_names': [x.datas_fname for x in attachments],
                     }
                     try:
                         result = jsonrpc(endpoint, params=params)
                         if result[1] == "Not enough credits":
                             record.extract_state = 'not_enough_credit'
                         elif result[0] == -1:
                             record.extract_state = 'error_status'
                         else:
                             record.extract_remoteid = result[0]
                             record.extract_state = 'waiting_extraction'
                     except AccessError:
                         record.extract_state = 'error_status'
     for record in self:
         record._compute_show_resend_button()
     return res
Ejemplo n.º 12
0
 def retry_ocr(self):
     """Retry to contact iap to submit the first attachment in the chatter"""
     if self.env.user.company_id.extract_show_ocr_option_selection == 'no_send':
         return False
     attachments = self.message_main_attachment_id
     if attachments and attachments.exists() and self.extract_state in ['no_extract_requested', 'not_enough_credit', 'error_status', 'module_not_up_to_date']:
         account_token = self.env['iap.account'].get('invoice_ocr')
         endpoint = self.env['ir.config_parameter'].sudo().get_param(
             'account_invoice_extract_endpoint', 'https://iap-extract.odoo.com')  + '/iap/invoice_extract/parse'
         params = {
             'account_token': account_token.account_token,
             'version': CLIENT_OCR_VERSION,
             'dbuuid': self.env['ir.config_parameter'].sudo().get_param('database.uuid'),
             'documents': [x.datas.decode('utf-8') for x in attachments], 
             'file_names': [x.datas_fname for x in attachments],
         }
         try:
             result = jsonrpc(endpoint, params=params)
             if result[1] == "Not enough credits":
                 self.extract_state = 'not_enough_credit'
             elif result[0] == -1:
                 self.extract_state = 'error_status'
                 _logger.warning('There was an issue while doing the OCR operation on this file. Error: -1')
             else:
                 self.extract_state = 'waiting_extraction'
                 self.extract_remoteid = result[0]
         except AccessError:
             self.extract_state = 'error_status'
Ejemplo n.º 13
0
 def invoice_validate(self):
     """On the validation of an invoice, send the differents corrected fields to iap to improve
     the ocr algorithm"""
     res = super(AccountInvoice, self).invoice_validate()
     for record in self:
         if record.type in ["out_invoice", "out_refund"]:
             return
         if record.extract_state == 'waiting_validation':
             endpoint = self.env['ir.config_parameter'].sudo().get_param(
                 'account_invoice_extract_endpoint', 'https://iap-extract.odoo.com')  + '/iap/invoice_extract/validate'
             values = {
                 'total': record.get_validation('total'),
                 'date': record.get_validation('date'),
                 'due_date': record.get_validation('due_date'),
                 'invoice_id': record.get_validation('invoice_id'),
                 'partner': record.get_validation('supplier'),
                 'VAT_Number': record.get_validation('VAT_Number'),
                 'currency': record.get_validation('currency')
             }
             params = {
                 'document_id': record.extract_remoteid, 
                 'version': CLIENT_OCR_VERSION,
                 'values': values
             }
             try:
                 _logger.warning(params) #TODO remove
                 result = jsonrpc(endpoint, params=params)
                 record.extract_state = 'done'
             except AccessError:
                 pass
     #we don't need word data anymore, we can delete them
     self.extract_word_ids.unlink()
     return res
Ejemplo n.º 14
0
    def _create_supplier_from_vat(self, vat_number_ocr):
        url = '%s/check_vat' % PARTNER_REMOTE_URL
        params = {
            'db_uuid':
            self.env['ir.config_parameter'].sudo().get_param('database.uuid'),
            'vat':
            vat_number_ocr,
        }
        try:
            response = jsonrpc(url=url, params=params)
        except Exception as exception:
            _logger.error('Check VAT error: %s' % str(exception))
            return False

        if response and response.get('name'):
            country_id = self.env['res.country'].search([
                ('code', '=', response.pop('country_code', ''))
            ])
            values = {
                field: response.get(field, None)
                for field in ['name', 'vat', 'street', 'city', 'zip']
            }
            values.update({
                'is_company': True,
                'country_id': country_id and country_id.id,
            })
            new_partner = self.env["res.partner"].with_context(
                clean_context(self.env.context)).create(values)
            return new_partner
        return False
Ejemplo n.º 15
0
    def _snailmail_print(self):
        """
        get response
        {
            'request_code': RESPONSE_OK, # because we receive 200 if good or fail
            'total_cost': total_cost,
            'credit_error': credit_error,
            'request': {
                'documents': documents,
                'options': options
                }
            }
        }
        """
        self.write({'state': 'pending'})
        endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('print')
        response = jsonrpc(endpoint + PRINT_ENDPOINT, params=params)
        for doc in response['request']['documents']:
            letter = self.browse(doc['letter_id'])
            record = self.env[doc['res_model']].browse(doc['res_id'])
            if doc.get('sent') and response['request_code'] == 200:
                if hasattr(record, '_message_log'):
                    message = _('The document was correctly sent by post.<br>The tracking id is %s' % doc['send_id'])
                    record._message_log(body=message)
                    letter.write({'info_msg': message, 'state': 'sent'})
            else:
                # look for existing activities related to snailmail to update or create a new one.
                # TODO: in following versions, Add a link to a specifc activity on the letter
                note = _('An error occured when sending the document by post.<br>Error: %s <br>Go to \'Configuration > Management > Snailmail Letters\' to see all letters awaiting dispatch to Snailmail.' % \
                    self._get_error_message(doc['error'] if response['request_code'] == 200 else response['reason']))

                domain = [
                    ('summary', 'ilike', '[SNAILMAIL]'),
                    ('res_id', '=', letter.res_id),
                    ('res_model_id', '=', self.env['ir.model']._get(letter.model).id),
                    ('activity_type_id', '=', self.env.ref('mail.mail_activity_data_warning').id),
                ]
                activity = letter.activity_id

                activity_data = {
                    'activity_type_id': self.env.ref('mail.mail_activity_data_warning').id,
                    'summary': '[SNAILMAIL] ' + _('Post letter: an error occured.'),
                    'note': note,
                    'date_deadline': fields.Date.today()
                }
                if activity:
                    activity.update(activity_data)
                else:
                    activity_data.update({
                        'user_id': letter.user_id.id,
                        'res_id': letter.res_id,
                        'res_model_id': self.env['ir.model']._get(letter.model).id,
                    })
                    activity = self.env['mail.activity'].create(activity_data)
                    letter.write({'activity_id': activity.id})

                letter.write({'info_msg': note, 'state': 'error'})

        self.env.cr.commit()
Ejemplo n.º 16
0
 def _rpc_remote_api(self, action, params, timeout=15):
     if self.env.registry.in_test_mode():
         return False, 'Insufficient Credit'
     url = '%s/%s' % (self.get_endpoint(), action)
     account = self.env['iap.account'].get('partner_autocomplete')
     params.update({
         'db_uuid':
         self.env['ir.config_parameter'].sudo().get_param('database.uuid'),
         'account_token':
         account.account_token,
         'country_code':
         self.env.user.company_id.country_id.code,
         'zip':
         self.env.user.company_id.zip,
     })
     try:
         return jsonrpc(url=url, params=params, timeout=timeout), False
     except (ConnectionError, HTTPError,
             exceptions.AccessError) as exception:
         _logger.error('Autocomplete API error: %s' % str(exception))
         return False, str(exception)
     except InsufficientCreditError as exception:
         _logger.warning(
             'Insufficient Credits for Autocomplete Service: %s' %
             str(exception))
         return False, 'Insufficient Credit'
Ejemplo n.º 17
0
 def _perform_reveal_service(self, server_payload):
     result = False
     account_token = self.env['iap.account'].get('reveal')
     endpoint = self.env['ir.config_parameter'].sudo().get_param(
         'reveal.endpoint', DEFAULT_ENDPOINT) + '/iap/clearbit/1/reveal'
     params = {
         'account_token': account_token.account_token,
         'data': server_payload
     }
     result = jsonrpc(endpoint, params=params, timeout=300)
     for res in result.get('reveal_data', []):
         if not res.get('not_found'):
             lead = self._create_lead_from_response(res)
             self.env['crm.reveal.view'].search([('reveal_ip', '=',
                                                  res['ip'])]).unlink()
         else:
             self.env['crm.reveal.view'].search([
                 ('reveal_ip', '=', res['ip'])
             ]).write({'reveal_state': 'not_found'})
     if result.get('credit_error'):
         self.env['crm.iap.lead.helpers'].notify_no_more_credit(
             'reveal', self._name, 'reveal.already_notified')
         return False
     else:
         self.env['ir.config_parameter'].sudo().set_param(
             'reveal.already_notified', False)
     return True
Ejemplo n.º 18
0
 def _perform_request(self):
     """
     This will perform the request and create the corresponding leads.
     The user will be notified if he hasn't enough credits.
     """
     server_payload = self._prepare_iap_payload()
     reveal_account = self.env['iap.account'].get('reveal')
     dbuuid = self.env['ir.config_parameter'].sudo().get_param(
         'database.uuid')
     endpoint = self.env['ir.config_parameter'].sudo().get_param(
         'reveal.endpoint',
         DEFAULT_ENDPOINT) + '/iap/clearbit/1/lead_mining_request'
     params = {
         'account_token': reveal_account.account_token,
         'dbuuid': dbuuid,
         'data': server_payload
     }
     try:
         response = jsonrpc(endpoint, params=params, timeout=300)
         return response['data']
     except InsufficientCreditError as e:
         self.error = 'Insufficient credits. Recharge your account and retry.'
         self.state = 'error'
         self._cr.commit()
         raise e
Ejemplo n.º 19
0
 def _l10n_in_edi_connect_to_server(self, company, url_path, params):
     user_token = self.env["iap.account"].get("l10n_in_edi")
     params.update({
         "account_token": user_token.account_token,
         "dbuuid": self.env["ir.config_parameter"].sudo().get_param("database.uuid"),
         "username": company.sudo().l10n_in_edi_username,
         "gstin": company.vat,
     })
     if company.sudo().l10n_in_edi_production_env:
         default_endpoint = DEFAULT_IAP_ENDPOINT
     else:
         default_endpoint = DEFAULT_IAP_TEST_ENDPOINT
     endpoint = self.env["ir.config_parameter"].sudo().get_param("l10n_in_edi.endpoint", default_endpoint)
     url = "%s%s" % (endpoint, url_path)
     try:
         return jsonrpc(url, params=params, timeout=25)
     except AccessError as e:
         _logger.warning("Connection error: %s", e.args[0])
         return {
             "error": [{
                 "code": "404",
                 "message": _("Unable to connect to the online E-invoice service."
                     "The web service may be temporary down. Please try again in a moment.")
             }]
         }
Ejemplo n.º 20
0
 def _rpc_remote_api(self, action, params=None, timeout=15):
     url = '%s/%s' % ('http://127.0.0.1:5001', action)
     try:
         return jsonrpc(url=url, params=params, timeout=timeout), False
     except (ConnectionError, HTTPError) as exception:
         _logger.error('API error: %s' % str(exception))
         return False, str(exception)
Ejemplo n.º 21
0
    def _snailmail_estimate(self):
        """
        Send a request to estimate the cost of sending all the documents with
        the differents options.

        The JSON object sent is the one generated from self._snailmail_create()

        arguments sent:
        {
            "documents":[{
                pages: int,
                res_id: int (client_side, optional),
                res_model: int (client_side, optional),
                address: {
                    country_code: char (country name)
                }
            }],
            'color': # color on the letter,
            'duplex': # one/two side printing,
        }

        The answer of the server is the same JSON object with some additionnal fields:
        {
            "total_cost": integer,      //The cost of sending ALL the documents
            body: JSON object (same as body param except new param 'cost' in each documents)
        }
        """
        endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('estimate')
        req = jsonrpc(endpoint + '/iap/snailmail/1/estimate', params=params)

        return req['total_cost']
Ejemplo n.º 22
0
    def _firebase_send_message_from_iap(self, data, visitors):
        social_iap_endpoint = self.env['ir.config_parameter'].sudo().get_param(
            'social.social_iap_endpoint',
            self.env['social.media']._DEFAULT_SOCIAL_IAP_ENDPOINT
        )
        batch_size = 100

        tokens = visitors.mapped('push_token')
        data.update({'db_uuid': self.env['ir.config_parameter'].sudo().get_param('database.uuid')})
        for i in range(int((len(visitors) / batch_size)) + 1):
            tokens_batch = tokens[(i * batch_size):((i + 1) * batch_size)]
            batch_data = dict(data)
            batch_data['tokens'] = tokens_batch
            jsonrpc(url_join(social_iap_endpoint, '/iap/social_push_notifications/firebase_send_message'), params=batch_data)

        return []
Ejemplo n.º 23
0
 def _send_notification_to_partners(self, pids, message, msg_vals):
     """
     Send the notification to a list of partners
     :param pids: list of partners
     :param message: current mail.message record
     :param msg_vals: dict values for current notification
     """
     if pids:
         receiver_ids = self.env['res.partner'].sudo().search([
             ('id', 'in', list(pids)), ('ocn_token', '!=', False)
         ])
         if receiver_ids:
             endpoint = self.env['res.config.settings']._get_endpoint()
             chunks = self._ocn_prepare_payload(receiver_ids, message,
                                                msg_vals)
             for chunk in chunks:
                 jsonrpc(endpoint + '/iap/ocn/send', params=chunk)
Ejemplo n.º 24
0
 def _contact_iap(self, local_endpoint, params):
     account = self.env['iap.account'].get('reveal')
     dbuuid = self.env['ir.config_parameter'].sudo().get_param(
         'database.uuid')
     params['account_token'] = account.account_token
     params['dbuuid'] = dbuuid
     return iap.jsonrpc(self._DEFAULT_ENDPOINT + local_endpoint,
                        params=params,
                        timeout=300)
Ejemplo n.º 25
0
    def _notify_recipients(self, rdata, record, msg_vals, **kwargs):
        """ We want to send a Cloud notification for every mentions of a partner
        and every direct message. We have to take into account the risk of
        duplicated notifications in case of a mention in a channel of `chat` type.
        """
        super(MailMessage, self)._notify_recipients(rdata, record, msg_vals,
                                                    **kwargs)

        notif_pids = [r['id'] for r in rdata['partners']]
        chat_cids = [r['id'] for r in rdata['channels'] if r['type'] == 'chat']

        if not notif_pids and not chat_cids:
            return

        self_sudo = self.sudo()
        msg_type = msg_vals.get('message_type') or self_sudo.message_type

        if msg_type == 'comment':
            # Create Cloud messages for needactions, but ignore the needaction if it is a result
            # of a mention in a chat. In this case the previously created Cloud message is enough.

            if chat_cids:
                channel_partner_ids = self.env['mail.channel'].sudo().search([
                    ('id', 'in', chat_cids),
                ]).mapped("channel_partner_ids").ids
            else:
                channel_partner_ids = []
            pids = (set(notif_pids) | set(channel_partner_ids)) - set(
                self_sudo.author_id.ids)
            if pids:
                receiver_ids = self.env['res.partner'].sudo().search([
                    ('id', 'in', list(pids))
                ])
                identities = receiver_ids.filtered(
                    lambda receiver: receiver.ocn_token).mapped('ocn_token')
                if identities:
                    endpoint = self.env['res.config.settings']._get_endpoint()
                    params = {
                        'ocn_tokens': identities,
                        'data': self._ocn_prepare_payload(self)
                    }
                    jsonrpc(endpoint + '/iap/ocn/send', params=params)
Ejemplo n.º 26
0
    def action_snailmail_print(self):
        """
        get response
        {
            'request_code': RESPONSE_OK, # 200 if good or fail
            'total_cost': total_cost,
            'credit_error': credit_error,
            'request': {
                'documents': documents,
                'options': options
                }
            }
        }
        """
        self.ensure_one()
        endpoint = self.env['ir.config_parameter'].sudo().get_param(
            'snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('print', batch=True)
        response = jsonrpc(endpoint + PRINT_ENDPOINT, params=params)

        error = False
        doc = response['request']['documents'][0]
        record = self.env[self.model].browse(self.res_id)
        if doc.get('sent') and response['request_code'] == 200:
            if hasattr(record, '_message_log'):
                message = _(
                    'The document was correctly sent by post.<br>The tracking id is %s'
                    % doc['send_id'])
                record._message_log(body=message)
        else:
            activity_data = {
                'res_id': self.res_id,
                'res_model_id': self.env['ir.model']._get(self.model).id,
                'activity_type_id': self.env.ref('snailmail.mail_activity_data_snailmail').id,
                'summary': _('Post letter: an error occured.'),
                'note': _('An error occured when sending the document by post.<br>Error: %s' % \
                self._get_error_message(doc['error'] if response['request_code'] == 200 else response['reason'])),
                'user_id': self.env.user.id,
            }
            self.env['mail.activity'].create(activity_data)
            error = True
        if not error:
            notification = _('Post letter: document sent.')
        else:
            notification = _(
                'Post letter: an error occured. Please check the document for more information.'
            )
        # as we interact with the exterior world, we commit
        self.env.cr.commit()
        self._update_company()
        return {
            'error': error,
            'message': notification,
        }
Ejemplo n.º 27
0
 def register_device(self, device_key, device_name):
     if self.env['ir.config_parameter'].sudo().get_param('ocn.ocn_push_notification', False):
         values = {
             'ocn_uuid': self._get_ocn_uuid(),
             'user_name': self.env.user.partner_id.name,
             'user_login': self.env.user.login,
             'device_name': device_name,
             'device_key': device_key
         }
         result = jsonrpc(self._get_endpoint() + '/iap/ocn/register_device', params=values)
         if result:
             self.env.user.partner_id.ocn_token = result
     return False
Ejemplo n.º 28
0
    def _snailmail_print(self):
        """
        get response
        {
            'request_code': RESPONSE_OK, # because we receive 200 if good or fail
            'total_cost': total_cost,
            'credit_error': credit_error,
            'request': {
                'documents': documents,
                'options': options
                }
            }
        }
        """
        self.write({'state': 'pending'})
        endpoint = self.env['ir.config_parameter'].sudo().get_param(
            'snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('print')
        response = jsonrpc(endpoint + PRINT_ENDPOINT, params=params)
        for doc in response['request']['documents']:
            letter = self.browse(doc['letter_id'])
            record = self.env[doc['res_model']].browse(doc['res_id'])
            if doc.get('sent') and response['request_code'] == 200:
                if hasattr(record, '_message_log'):
                    message = _(
                        'The document was correctly sent by post.<br>The tracking id is %s'
                        % doc['send_id'])
                    record._message_log(body=message)
                    letter.write({'info_msg': message, 'state': 'sent'})
            else:
                note = _('An error occured when sending the document by post.<br>Error: %s' % \
                    self._get_error_message(doc['error'] if response['request_code'] == 200 else response['reason']))
                activity_data = {
                    'res_id':
                    letter.res_id,
                    'res_model_id':
                    self.env['ir.model']._get(letter.model).id,
                    'activity_type_id':
                    self.env.ref('snailmail.mail_activity_data_snailmail').id,
                    'summary':
                    _('Post letter: an error occured.'),
                    'note':
                    note,
                    'user_id':
                    letter.user_id.id,
                }
                self.env['mail.activity'].create(activity_data)
                letter.write({'info_msg': note})

        self.env.cr.commit()
Ejemplo n.º 29
0
    def retry_ocr(self):
        """Retry to contact iap to submit the first attachment in the chatter"""
        if self.env.company.extract_show_ocr_option_selection == 'no_send':
            return False
        attachments = self.message_main_attachment_id
        if attachments and attachments.exists() and self.extract_state in [
                'no_extract_requested', 'not_enough_credit', 'error_status',
                'module_not_up_to_date'
        ]:
            account_token = self.env['iap.account'].get('invoice_ocr')
            endpoint = self.env['ir.config_parameter'].sudo().get_param(
                'account_invoice_extract_endpoint',
                'https://iap-extract.odoo.com') + '/iap/invoice_extract/parse'
            user_infos = {
                'user_company_VAT': self.company_id.vat,
                'user_company_name': self.company_id.name,
                'user_company_country_code': self.company_id.country_id.code,
                'user_lang': self.env.user.lang,
                'user_email': self.env.user.email,
            }
            params = {
                'account_token':
                account_token.account_token,
                'version':
                CLIENT_OCR_VERSION,
                'dbuuid':
                self.env['ir.config_parameter'].sudo().get_param(
                    'database.uuid'),
                'documents': [x.datas.decode('utf-8') for x in attachments],
                'file_names': [x.name for x in attachments],
                'user_infos':
                user_infos,
            }
            try:
                result = jsonrpc(endpoint, params=params)
                self.extract_status_code = result['status_code']
                if result['status_code'] == SUCCESS:
                    self.extract_state = 'waiting_extraction'
                    self.extract_remote_id = result['document_id']
                elif result['status_code'] == ERROR_NOT_ENOUGH_CREDIT:
                    self.extract_state = 'not_enough_credit'
                else:
                    self.extract_state = 'error_status'
                    _logger.warning(
                        'There was an issue while doing the OCR operation on this file. Error: -1'
                    )

            except AccessError:
                self.extract_state = 'error_status'
                self.extract_status_code = ERROR_NO_CONNECTION
Ejemplo n.º 30
0
 def register_device(self, device_key, device_name):
     values = {
         'ocn_uuid': self._get_ocn_uuid(),
         'user_name': self.env.user.partner_id.name,
         'user_login': self.env.user.login,
         'device_name': device_name,
         'device_key': device_key,
     }
     result = jsonrpc(self._get_endpoint() + '/iap/ocn/register_device',
                      params=values)
     if result:
         self.env.user.partner_id.ocn_token = result
         return result
     return False
Ejemplo n.º 31
0
    def action_snailmail_print(self):
        """
        get response
        {
            'request_code': RESPONSE_OK, # 200 if good or fail
            'total_cost': total_cost,
            'credit_error': credit_error,
            'request': {
                'documents': documents,
                'options': options
                }
            }
        }
        """
        self.ensure_one()
        endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('print', batch=True)
        response = jsonrpc(endpoint + PRINT_ENDPOINT, params=params)

        error = False
        doc = response['request']['documents'][0]
        record = self.env[self.model].browse(self.res_id)
        if doc.get('sent') and response['request_code'] == 200:
            if hasattr(record, '_message_log'):
                message = _('The document was correctly sent by post.<br>The tracking id is %s' % doc['send_id'])
                record._message_log(body=message)
        else:
            activity_data = {
                'res_id': self.res_id,
                'res_model_id': self.env['ir.model']._get(self.model).id,
                'activity_type_id': self.env.ref('snailmail.mail_activity_data_snailmail').id,
                'summary': _('Post letter: an error occured.'),
                'note': _('An error occured when sending the document by post.<br>Error: %s' % \
                self._get_error_message(doc['error'] if response['request_code'] == 200 else response['reason'])),
                'user_id': self.env.user.id,
            }
            self.env['mail.activity'].create(activity_data)
            error = True
        if not error:
            notification = _('Post letter: document sent.')
        else:
            notification = _('Post letter: an error occured. Please check the document for more information.')
        # as we interact with the exterior world, we commit
        self.env.cr.commit()
        self._update_company()
        return {
            'error': error,
            'message': notification,
        }
Ejemplo n.º 32
0
    def fetch_book_data(self):
        self.ensure_one()
        if not self.isbn:
            raise UserError("Please add  ISBN number")

        user_token = self.env['iap.account'].get('book_isbn')
        params = {
            'account_token': user_token.account_token,
            'isbn_number': self.isbn
        }
        service_endpoint = 'http://localhost:8070'
        result = jsonrpc(service_endpoint + '/get_book_data', params=params)
        if result.get('status') == 'found':
            self.write(self.process_result(result['data']))
        return True
Ejemplo n.º 33
0
 def create(self, vals):
     ir_params = self.env['ir.config_parameter'].sudo()
     if vals.get('ocn_push_notification') and not ir_params.get_param('odoo_ocn.project_id'):
         # Every time when user change setting, we need to validate ocn service
         params = {
             'ocnuuid': self._get_ocn_uuid(),
             'server_version': odoo.release.version,
             'db': self.env.cr.dbname,
             'company_name': self.env.user.company_id.name,
             'url': ir_params.get_param('web.base.url')
         }
         # Register instance to ocn service. Unique with ocn.uuid
         project_id = jsonrpc(self._get_endpoint() + '/iap/ocn/enable_service', params=params)
         # Storing project id for generate token
         ir_params.set_param('odoo_ocn.project_id', project_id)
     return super(ResConfigSettings, self).create(vals)
Ejemplo n.º 34
0
 def get_fcm_project_id(self):
     ir_params_sudo = self.env['ir.config_parameter'].sudo()
     project_id = ir_params_sudo.get_param('odoo_ocn.project_id')
     if not project_id:
         params = {
             'ocnuuid': self._get_ocn_uuid(),
             'server_version': odoo.release.version,
             'db': self.env.cr.dbname,
             'company_name': self.env.company.name,
             'url': ir_params_sudo.get_param('web.base.url')
         }
         # Register instance to ocn service. Unique with ocn.uuid
         project_id = jsonrpc(self._get_endpoint() +
                              '/iap/ocn/enable_service',
                              params=params)
         # Storing project id for generate token
         ir_params_sudo.set_param('odoo_ocn.project_id', project_id)
     return project_id
Ejemplo n.º 35
0
 def _rpc_remote_api(self, action, params, timeout=15):
     if self.env.registry.in_test_mode() :
         return False, 'Insufficient Credit'
     url = '%s/%s' % (self.get_endpoint(), action)
     account = self.env['iap.account'].get('partner_autocomplete')
     params.update({
         'db_uuid': self.env['ir.config_parameter'].sudo().get_param('database.uuid'),
         'account_token': account.account_token,
         'country_code': self.env.company.country_id.code,
         'zip': self.env.company.zip,
     })
     try:
         return jsonrpc(url=url, params=params, timeout=timeout), False
     except (ConnectionError, HTTPError, exceptions.AccessError) as exception:
         _logger.error('Autocomplete API error: %s' % str(exception))
         return False, str(exception)
     except InsufficientCreditError as exception:
         _logger.warning('Insufficient Credits for Autocomplete Service: %s' % str(exception))
         return False, 'Insufficient Credit'
Ejemplo n.º 36
0
    def _snailmail_print(self):
        """
        get response
        {
            'request_code': RESPONSE_OK, # because we receive 200 if good or fail
            'total_cost': total_cost,
            'credit_error': credit_error,
            'request': {
                'documents': documents,
                'options': options
                }
            }
        }
        """
        self.write({'state': 'pending'})
        endpoint = self.env['ir.config_parameter'].sudo().get_param('snailmail.endpoint', DEFAULT_ENDPOINT)
        params = self._snailmail_create('print')
        response = jsonrpc(endpoint + PRINT_ENDPOINT, params=params)
        for doc in response['request']['documents']:
            letter = self.browse(doc['letter_id'])
            record = self.env[doc['res_model']].browse(doc['res_id'])
            if doc.get('sent') and response['request_code'] == 200:
                if hasattr(record, '_message_log'):
                    message = _('The document was correctly sent by post.<br>The tracking id is %s' % doc['send_id'])
                    record._message_log(body=message)
                    letter.write({'info_msg': message, 'state': 'sent'})
            else:
                note = _('An error occured when sending the document by post.<br>Error: %s' % \
                    self._get_error_message(doc['error'] if response['request_code'] == 200 else response['reason']))
                activity_data = {
                    'res_id': letter.res_id,
                    'res_model_id': self.env['ir.model']._get(letter.model).id,
                    'activity_type_id': self.env.ref('snailmail.mail_activity_data_snailmail').id,
                    'summary': _('Post letter: an error occured.'),
                    'note': note,
                    'user_id': letter.user_id.id,
                }
                self.env['mail.activity'].create(activity_data)
                letter.write({'info_msg': note})

        self.env.cr.commit()
Ejemplo n.º 37
0
 def _perform_request(self):
     """
     This will perform the request and create the corresponding leads.
     The user will be notified if he hasn't enough credits.
     """
     server_payload = self._prepare_iap_payload()
     reveal_account = self.env['iap.account'].get('reveal')
     dbuuid = self.env['ir.config_parameter'].sudo().get_param('database.uuid')
     endpoint = self.env['ir.config_parameter'].sudo().get_param('reveal.endpoint', DEFAULT_ENDPOINT) + '/iap/clearbit/1/lead_mining_request'
     params = {
         'account_token': reveal_account.account_token,
         'dbuuid': dbuuid,
         'data': server_payload
     }
     try:
         response = jsonrpc(endpoint, params=params, timeout=300)
         return response['data']
     except InsufficientCreditError as e:
         self.error = 'Insufficient credits. Recharge your account and retry.'
         self.state = 'error'
         self._cr.commit()
         raise e
Ejemplo n.º 38
0
 def check_status(self):
     """contact iap to get the actual status of the ocr request"""
     for record in self:
         if record.extract_state not in ["waiting_extraction", "extract_not_ready"]:
             continue
         endpoint = self.env['ir.config_parameter'].sudo().get_param(
             'account_invoice_extract_endpoint', 'https://iap-extract.odoo.com')  + '/iap/invoice_extract/get_result'
         params = {
             'version': CLIENT_OCR_VERSION,
             'document_id': record.extract_remoteid
         }
         result = jsonrpc(endpoint, params=params)
         if result == "Not ready":
             record.extract_state = "extract_not_ready"
         elif result == "An error occured":
             record.extract_state = "error_status"
         else:
             record.extract_state = "waiting_validation"
             self.extract_word_ids.unlink()
             if "supplier" in result: #be sure to execut supplier in first as it set some other values in invoice
                 self.set_field_with_text("supplier", result["supplier"]["selected_text"][0])
             for feature, value in result.items():
                 if feature != "supplier":
                     self.set_field_with_text(feature, value["selected_text"][0])
                 data = []
                 for word in value["words"]:
                     data.append((0, 0, {
                         "field": feature,
                         "selected_status": 1 if value["selected_text"] == word else 0,
                         "word_text": word[0],
                         "word_page": word[1],
                         "word_box_midX": word[2][0],
                         "word_box_midY": word[2][1],
                         "word_box_width": word[2][2],
                         "word_box_height": word[2][3],
                         "word_box_angle": word[2][4],
                     }))
                 self.write({'extract_word_ids': data})
Ejemplo n.º 39
0
 def _perform_reveal_service(self, server_payload):
     result = False
     account_token = self.env['iap.account'].get('reveal')
     endpoint = self.env['ir.config_parameter'].sudo().get_param('reveal.endpoint', DEFAULT_ENDPOINT) + '/iap/clearbit/1/reveal'
     params = {
         'account_token': account_token.account_token,
         'data': server_payload
     }
     result = jsonrpc(endpoint, params=params)
     for res in result.get('reveal_data', []):
         if not res.get('not_found'):
             lead = self._create_lead_from_response(res)
             self.env['crm.reveal.view'].search([('reveal_ip', '=', res['ip'])]).unlink()
         else:
             self.env['crm.reveal.view'].search([('reveal_ip', '=', res['ip'])]).write({
                 'reveal_state': 'not_found'
             })
     if result.get('credit_error'):
         self._notify_no_more_credit()
         return False
     else:
         self.env['ir.config_parameter'].sudo().set_param('reveal.already_notified', False)
     return True
Ejemplo n.º 40
0
    def _check_status(self):
        self.ensure_one()
        endpoint = self.env['ir.config_parameter'].sudo().get_param(
            'account_invoice_extract_endpoint',
            'https://iap-extract.odoo.com') + '/iap/invoice_extract/get_result'

        params = {
            'version': CLIENT_OCR_VERSION,
            'document_id': self.extract_remote_id
        }
        result = jsonrpc(endpoint, params=params)
        self.extract_status_code = result['status_code']
        if result['status_code'] == SUCCESS:
            self.extract_state = "waiting_validation"
            ocr_results = result['results'][0]
            self.extract_word_ids.unlink()

            # We still want to save all other fields when there is a duplicate vendor reference
            try:
                # Savepoint so the transactions don't go through if the save raises an exception
                with self.env.cr.savepoint():
                    self._save_form(ocr_results)
            # Retry saving without the ref, then set the error status to show the user a warning
            except ValidationError as e:
                self._save_form(ocr_results, no_ref=True)
                self.extract_status_code = WARNING_DUPLICATE_VENDOR_REFERENCE
                self.duplicated_vendor_ref = ocr_results['invoice_id'][
                    'selected_value'][
                        'content'] if 'invoice_id' in ocr_results else ""

            fields_with_boxes = [
                'supplier', 'date', 'due_date', 'invoice_id', 'currency',
                'VAT_Number'
            ]
            for field in fields_with_boxes:
                if field in ocr_results:
                    value = ocr_results[field]
                    data = []
                    for word in value["words"]:
                        data.append((0, 0, {
                            "field":
                            field,
                            "selected_status":
                            1 if value["selected_value"] == word else 0,
                            "word_text":
                            word['content'],
                            "word_page":
                            word['page'],
                            "word_box_midX":
                            word['coords'][0],
                            "word_box_midY":
                            word['coords'][1],
                            "word_box_width":
                            word['coords'][2],
                            "word_box_height":
                            word['coords'][3],
                            "word_box_angle":
                            word['coords'][4],
                        }))
                    self.write({'extract_word_ids': data})
        elif result['status_code'] == NOT_READY:
            self.extract_state = 'extract_not_ready'
        else:
            self.extract_state = 'error_status'