def update_checksum(self): missing = [] for record in self: file_path = record._build_path() with opened_w_error(file_path, "rb") as (file_handler, exception): if exception: missing.append(file_path) _logger.error("Failed to read the file (%s): %s" % (file_path, str(exception))) else: file = file_handler.read() record.checksum = record._compute_checksum(file) if missing: message = _("Something went wrong! Seems that some files are missing.\n") for path in missing: message += "\n - %s" % path raise MissingError(message)
def get_property_fields(self, object, properties): """ This method must be redefined by modules that introduce property fields in the relevant models. It intends to be used to compute the value of property fields. The models that implement this method will define the the logic to obtain the value of the property field for a certain object. If it is not defined by the models, will raise an error message. @param object: actual object for which we intend to get the property values. @param properties: ir.property recordset, including in the context the company for which we intend to obtain the value for the given object. @returns: Does not expect to return anything """ raise MissingError(_('It must be redefined'))
def _document_check_access(self, model_name, document_id, access_token=None): document = request.env[model_name].browse([document_id]) document_sudo = document.with_user(SUPERUSER_ID).exists() if not document_sudo: raise MissingError(_("This document does not exist.")) try: document.check_access_rights('read') document.check_access_rule('read') except AccessError: if not access_token or not document_sudo.access_token or not consteq( document_sudo.access_token, access_token): raise return document_sudo
def validate_invoice_header(self): # extract the data lines from the specified absolute path # print "##### FILE NAME ",self.invoice_file_path data = self.read_file(self.invoice_file_path) # read the header attributes file_header = self.sanitize_row(data[0]).split(';') # validate header attributes for key in self.invoice_header: # print("key ",key) # print("### HEADER ",file_header) if key not in file_header: raise MissingError("Missing attribute invoice_header %s" % key) # remove the header data.pop(0) # store the data in object attribute self.invoice_data = [self.sanitize_row(row).split(';') for row in data]
def check_report(self): """.""" query = self.offering church = ('church_id', '=', self.env.user.company_id.id) services = self.env['ng_church.offering'].search([('service_id', '=', query.id), church]) offering_line = self.env['ng_church.offering_line'] for offering in services: offering_line += offering_line.search([('offering_id', '=', offering.id), church]) offerings = self._report_range(offering_line, self.date_from, self.date_to) if len(offerings) > 0: return self.env['report'].get_action( offerings, 'ng_church.church_offering_report') raise MissingError('Record not found')
def _prepare_claim(self, params): categ = self.env['crm.case.categ'].search([('id', '=', params['subject_id'])]) claim_type = self.env.ref('crm_claim_type.crm_claim_type_customer').id backend_id = self.backend_record.id vals = { 'categ_id': params['subject_id'], 'name': categ.name, 'description': params['message'], 'partner_id': self.partner.id, 'claim_type': claim_type, 'shopinvader_backend_id': backend_id, 'claim_line_ids': [] } vals = self.env['crm.claim'].play_onchanges(vals, ['partner_id']) order = False for line in params['sale_order_line']: if not line['qty']: continue so_line = self.env['sale.order.line'].search([ ('id', '=', line['id']), ('order_id.partner_id', '=', self.partner.id), ('order_id.shopinvader_backend_id', '=', backend_id) ]) if not so_line: raise MissingError( _('The sale order line %s does not exist') % line['id']) if not order: order = so_line.order_id vals['ref'] = 'sale.order,%s' % order.id elif order != so_line.order_id: raise UserError( _('All sale order lines must' 'come from the same sale order')) if order.invoice_ids and not vals.get('invoice_id', False): vals['invoice_id'] = order.invoice_ids[0].id vals['claim_line_ids'].append((0, 0, { 'product_id': so_line.product_id.id, 'product_returned_quantity': line['qty'], 'claim_origin': 'none' })) if not vals['claim_line_ids']: raise UserError(_('You have to select an item')) return vals
def _get_report_values(self, docids, data=None): partner_obj = self.env["res.partner"] student_ids = self.env.context.get("active_ids", []) students = partner_obj.browse(student_ids or docids) template = self.env.company.school_leaving_template if not template: raise MissingError("School Leaving Report Template is empty.") contents = {} for student in students: vals = { "date_today": fields.Date.context_today(self), } student_vals = student.read()[0] for key, value in student_vals.items(): vals["student_" + key] = value parent = student.family_ids.member_ids.filtered( lambda m: m.person_type == "parent") if parent: parent_vals = parent[0].read()[0] for key, value in parent_vals.items(): vals["parent_" + key] = value if student.grade_level_id: grade_level_vals = student.grade_level_id.read()[0] for key, value in grade_level_vals.items(): vals["grade_level_" + key] = value for key, value in vals.items(): new_value = str(value) if isinstance(value, date): new_value = format_date(self.env, value) elif isinstance(value, datetime): new_value = format_datetime(self.env, value) vals[key] = new_value try: contents[student.id] = template % vals except: raise ValidationError( "An error has occurred while formatting the school leaving report template." ) return { "doc_ids": student_ids, "doc_model": "res.partner", "docs": students, "contents": contents, }
def find(self, env, path, model=None): if model: return self._find(env, path, model) else: result = [] try: result.append(self._find(env, path, 'muk_dms.directory')) except MissingError: pass try: result.append(self._find(env, path, 'muk_dms.file')) except MissingError: pass if result: return result else: raise MissingError(_("The record is missing!"))
def _read_file(self, file_path): with opened_w_error(file_path, "rb") as (file_handler, exception): if exception: _logger.error("Failed to read the file (%s): %s" % (file_path, str(exception))) raise MissingError( _("Something went wrong! Seems that the file (%s) is missing or broken.") % os.path.basename(file_path)) else: file = file_handler.read() encode_file = base64.b64encode(file) if self._check_file(file, self.checksum): return encode_file else: _logger.error( "Failed to read the file (%s): The file has been altered outside of the system." % os.path.basename(file_path)) raise ValidationError(_("The file (%s) is corrupted.") % os.path.basename(file_path))
def _ticket_check_access(self, model_name, document_id, access_token=None): document_search = request.env[model_name].sudo().search([ ('id', '=', document_id), ('partner_id.id', '=', request.env.user.partner_id.id) ]) document = request.env[model_name].sudo().browse([document_id]) document_sudo = document.sudo().exists() if not document_sudo or not document_search: raise MissingError("This document does not exist.") try: document.check_access_rights('read') document.check_access_rule('read') except AccessError: if not access_token or not consteq(document_sudo.access_token, access_token): raise return document_sudo
def _document_check_access(self, model_name, document_id, access_token=None): document = request.env[model_name].browse([document_id]) _logger.info("document: " + str(document)) document_sudo = document.sudo().exists() if not document_sudo: raise MissingError("This document does not exist.") try: document.check_access_rights('read') document.check_access_rule('read') except AccessError: if not access_token or not consteq(document_sudo.access_token, access_token): raise return document_sudo
def _find_from_reference(self, reference): """Find a task from the given reference. :param reference: the task reference for which to find a task. :return: a project.task record if any found, otherwise None """ if not reference.task_id: return None task = self.browse(reference.task_id) if not task.exists(): raise MissingError( _('The task referenced by {ref} does not exist. ' 'No task found for the database ID {id}.').format( ref=reference, id=reference.task_id)) return task
def get(self, _id, size): """ Get partner's image """ field = 'image' if size == 'small': field = 'image_small' elif size == 'medium': field = 'image_medium' status, headers, content = self.env['ir.http'].binary_content( model='res.partner', id=_id, field=field, env=self.env) if not content: raise MissingError(_('No image found for partner %s') % _id) image_base64 = base64.b64decode(content) headers.append(('Content-Length', len(image_base64))) response = request.make_response(image_base64, headers) response.status_code = status return response
def _prepare_second_account_move_line(self, move_id): if self.journal_id.default_debit_account_id.id == False: raise MissingError( '{} default debit and credit are not set.'.format( self.journal_id.name)) payload = { 'name': self.description, 'account_id': self.journal_id.default_debit_account_id.id, 'move_id': move_id, 'partner_id': parish(self), 'quantity': 1, 'debit': abs(self.amount), 'credit': 0.0, 'date': self.date, } account_move_line = self.env['account.move.line'].with_context( check_move_validity=False) account_move_line.create(payload)
def get(self, _id, size): """ Get partner's image """ field = "image" if size == "small": field = "image_small" elif size == "medium": field = "image_medium" status, headers, content = self.env["ir.http"].binary_content( model="res.partner", id=_id, field=field, env=self.env) if not content: raise MissingError(_("No image found for partner %s") % _id) image_base64 = base64.b64decode(content) headers.append(("Content-Length", len(image_base64))) response = request.make_response(image_base64, headers) response.status_code = status return response
def apply_discount(self): for order_id in self: write_lines = [] partner_id = order_id.student_id if order_id.student_id else order_id.partner_id discount_ids = partner_id.discount_ids for order_line_id in order_id.order_line: # If there is a student, our priority is the student invoice_line_categories = get_parent_category( order_line_id.product_id.categ_id) discount_applicable = discount_ids.filtered( lambda discount: discount.category_id in invoice_line_categories) for discount in discount_applicable: percent = discount.percent discount_count = -order_line_id.price_subtotal * (percent / 100) if not discount.product_id: raise MissingError( "There is no product set for the discount %s" % discount.name) order_line_create = { "product_id": discount.product_id.get_single_product_variant().get( "product_id", False), "price_unit": discount_count, # "analytic_account_id": discount.analytic_account_id.id, } if order_line_id.tax_id: order_line_create.update( {"tax_id": [(6, 0, order_line_id.tax_id.ids)]}) write_lines.append((0, 0, order_line_create)) order_id.write({"order_line": write_lines})
def aeroo_report(self, docids, data): self.name = self._context.get('report_name') report = self.env['ir.actions.report']._get_report_from_name(self.name) # TODO #_logger.info("Start Aeroo Reports %s (%s)" % (name, ctx.get('active_model')), logging.INFO) # debug mode if 'tz' not in self._context: self = self.with_context(tz=self.env.user.tz) # TODO we should propagate context in the proper way, just with self # agregamos el process_sep aca ya que necesitamos el doc convertido # para poder unirlos if report.process_sep and len(docids) > 1: # por ahora solo soportamos process_sep para pdf, en version # anterior tambien soportaba algun otro code = report.out_format.code if code != 'oo-pdf': raise MissingError( _('Process_sep not compatible with selected output format') ) results = [] for docid in docids: results.append( self.assemble_tasks([docid], data, report, self._context)) output = PdfFileWriter() for r in results: reader = PdfFileReader(BytesIO(r[0])) for page in range(reader.getNumPages()): output.addPage(reader.getPage(page)) s = BytesIO() output.write(s) data = s.getvalue() res = self._context.get('return_filename') and\ (data, results[0][1], results[0][2]) or (data, results[0][1]) else: res = self.assemble_tasks(docids, data, report, self._context) # TODO #_logger.info("End Aeroo Reports %s (%s), total elapsed time: %s" % (name, model), time() - aeroo_print.start_total_time), logging.INFO) # debug mode return res
def action_print_report_xlsx(self): self.create_report_view() self._cr.execute("SELECT * FROM hotel_report") docs = self._cr.fetchall() if not docs: raise MissingError("Record does not exist or has been deleted.") return { 'type': 'ir.actions.report', 'data': { 'model': 'report.hotel_management.report_xlsx', 'options': json.dumps(self.get_data(), default=date_utils.json_default), 'output_format': 'xlsx', 'report_name': 'Hotel Management Report', }, 'report_type': 'xlsx', }
def _get_commerce_partner(self): if self._jwt_payload: partner_email = self._jwt_payload.get("email") backend = self._get_backend() if partner_email: commerce_partner = self._find_partner(backend, partner_email) if len(commerce_partner) == 1: self._validate_partner(backend, commerce_partner) return commerce_partner else: _logger.warning("Wrong email, jwt payload ignored") if len(commerce_partner) > 1: _logger.warning( "More than one commerce.partner found for:" " backend_id={} email={}".format( backend.id, partner_email)) # Could be because the email is not related to a partner or # because the partner is inactive raise MissingError(_("The given partner is not found!")) return super()._get_commerce_partner()
def _get_partner_from_headers(cls, headers): partner_model = request.env["shopinvader.partner"] partner_email = headers.get("HTTP_PARTNER_EMAIL") backend = cls._get_shopinvader_backend_from_request() if partner_email: partner = cls._find_partner(backend, partner_email) if len(partner) == 1: cls._validate_partner(backend, partner) return partner.record_id else: _logger.warning("Wrong HTTP_PARTNER_EMAIL, header ignored") if len(partner) > 1: _logger.warning( "More than one shopinvader.partner found for:" " backend_id={} email={}".format( backend.id, partner_email)) # Could be because the email is not related to a partner or # because the partner is inactive raise MissingError(_("The given partner is not found!")) return partner_model.browse([]).record_id
def _get_commerce_partner(self): headers = self.request.httprequest.environ partner_model = self.env["commerce.partner"] partner_email = headers.get("HTTP_PARTNER_EMAIL") backend = self._get_backend() if partner_email: partner = self._find_partner(backend, partner_email) if len(partner) == 1: self._validate_partner(backend, partner) return partner else: _logger.warning("Wrong HTTP_PARTNER_EMAIL, header ignored") if len(partner) > 1: _logger.warning( "More than one commerce.partner found for:" " backend_id={} email={}".format(backend.id, partner_email) ) # Could be because the email is not related to a partner or # because the partner is inactive raise MissingError(_("The given partner is not found!")) return partner_model.browse([])
def validate_counter_header(self): # extract the data lines from the specified absolute path data = self.read_file(self.counter_file_path) # read the header attributes file_header = self.sanitize_row(data[0]).split(';') # validate header attributes for key in self.counter_header: if key not in file_header: raise MissingError("Missing attribute counter_header %s" % key) # remove the header data.pop(0) # store the data in object attribute self.counter_data = [self.sanitize_row(row).split(';') for row in data] record_id = self.env['file.compteur'].search([]) if record_id: record_id.unlink() for rec in self.counter_data: vals = { 'CodeConcession': rec[self.counter_header.index('CodeConcession')], 'NomConcession': rec[self.counter_header.index('NomConcession')], 'CodeClient': rec[self.counter_header.index('CodeClient')], 'NumeroSerie': rec[self.counter_header.index('NuméroSérie')], 'DateLimite': rec[self.counter_header.index('DateLimite')], 'CodeCompteur1': rec[self.counter_header.index('CodeCompteur1')], 'CodeCompteur2': rec[self.counter_header.index('CodeCompteur2')], 'DernierCompteur1': rec[self.counter_header.index('DernierCompteur1')], 'DernierCompteur2': rec[self.counter_header.index('DernierCompteur2')], } self.env['file.compteur'].create(vals)
def _get_deduction_lines(self): self.ensure_one() res = [] if not self.employee_id.address_home_id: raise MissingError("Private address of {} is not set. Set the private address in the employee form.".format(employee.name)) partner = self.employee_id.address_home_id results, total, amls = self.env["report.account.report_agedpartnerbalance"].with_context( partner_ids=partner)._get_partner_move_lines( ["receivable"], fields.Date.context_today(self), "posted", 30) remaining_wage = self.net_wage for aml in amls.get(partner.id, []): if aml["amount"] <= 0 or (self.struct_id.type_id.invoice_payment_scope == "overdue" and aml["period"] >= 6): continue residual_amount = min(aml["amount"], remaining_wage) deduction_vals = { "move_line_id": aml["line"].id, "amount": residual_amount, } res.append(deduction_vals) remaining_wage -= residual_amount if not remaining_wage: break return res
def get_facebook_access_token(self): self.execute() get_param = self.env['ir.config_parameter'].sudo().get_param base_url = 'http://localhost' # get_param('web.base.url', 'http://localhost') https_url = base_url.replace("http://", "https://") canvas_url = https_url + "/config-save-token" perms = get_param('omi.fb_permission', '').split(',') app_id = self.fb_app_id if app_id and canvas_url and perms: graph = facebook.GraphAPI(version=3.1) auth_url = "%s&response_type=token" % graph.get_auth_url( app_id, canvas_url, perms) return { 'type': 'ir.actions.act_url', 'url': auth_url, 'target': 'self', 'target_type': 'public', } raise MissingError(_('Require "Facebook App ID" and "Permissions"'))
def _find_record( self, xmlid=None, res_model='ir.attachment', res_id=None, access_token=None, ): """ Find and return a record either using an xmlid either a model+id pair. This method is an helper for the ``/web/content`` and ``/web/image`` controllers and should not be used in other contextes. :param Optional[str] xmlid: xmlid of the record :param Optional[str] res_model: model of the record, ir.attachment by default. :param Optional[id] res_id: id of the record :param Optional[str] access_token: access token to use instead of the access rights and access rules. :returns: single record :raises MissingError: when no record was found. """ record = None if xmlid: record = self.env.ref(xmlid, False) elif res_id is not None and res_model in self.env: record = self.env[res_model].browse(res_id).exists() if not record: raise MissingError( f"No record found for xmlid={xmlid}, res_model={res_model}, id={res_id}" ) if record._name == 'ir.attachment': record = record.validate_access(access_token) return record
def init_postgis(cr): """ Initialize postgis Add PostGIS support to the database. PostGIS is a spatial database extender for PostgreSQL object-relational database. It adds support for geographic objects allowing location queries to be run in SQL. """ cr.execute(""" SELECT tablename FROM pg_tables WHERE tablename='spatial_ref_sys'; """) check = cr.fetchone() if check: return {} try: cr.execute(""" CREATE EXTENSION postgis; CREATE EXTENSION postgis_topology; """) except Exception: raise MissingError( _( "Error, can not automatically initialize spatial postgis" " support. Database user may have to be superuser and" " postgres/postgis extensions with their devel header have" " to be installed. If you do not want Odoo to connect with a" " super user you can manually prepare your database. To do" " this, open a client to your database using a super user and" " run:\n" "CREATE EXTENSION postgis;\n" "CREATE EXTENSION postgis_topology;\n" ) )
def _get_report_values(self, docids, data=None): payment_obj = self.env["pos_pr.invoice.payment"] pos_session_id = data["form"]["pos_session_id"][0] grouping = data["form"]["grouping"] payments = payment_obj.search([("pos_session_id", "=", pos_session_id) ]) if not payments: raise MissingError( "There are no invoice payments related to this session.") if grouping == "method": groups = payments.mapped("payment_method_id") else: groups = payments.mapped("payment_group_id") return { "doc_ids": payments.ids, "doc_model": "pos_pr.invoice.payment", "docs": payments, "groups": groups, "grouping": grouping, "session": self.env["pos.session"].browse(pos_session_id), "getattr": getattr, }
def validate_statement_header(self): # extract the data lines from the specified absolute path data = self.read_file(self.statement_file_path) # read the header attributes file_header = self.sanitize_row(data[0]).split(';') # validate header attributes for key in self.statement_header: if key not in file_header: raise MissingError("Missing attribute statement_header %s" % key) # remove the header data.pop(0) # store the data in object attribute self.statement_data = [ self.sanitize_row(row).split(';') for row in data ] record_id = self.env['file.releve'].search([]) if record_id: record_id.unlink() for rec in self.statement_data: vals = { 'TypeReleve': rec[1], 'TypeCompteur': rec[2], 'NumeroSerie': rec[3], 'NumContrat': rec[4], 'NumeroFacture': rec[5], 'NumeroReleve': rec[6], 'DateReleve': rec[7], 'DateDebutPeriode': rec[8], 'DateFinPeriode': rec[9], 'CompteurReleve': rec[10], 'Consommation': rec[11], 'VolumeDepassement': rec[12], } self.env['file.releve'].create(vals)
def _check_name_within_range(self): for move in self.filtered(lambda m: m.journal_id.is_honduras_invoice and m.state == "posted" and m.type == "out_invoice"): if not all([move.journal_id.cai, move.journal_id.prefix, move.journal_id.authorized_range_from, move.journal_id.authorized_range_to, move.journal_id.issue_limit_date]): raise MissingError("CAI, Prefix, Issue Limit Date, or Authorized Range fields are not set in Journal") if fields.Date.context_today(self) > move.journal_id.issue_limit_date: raise ValidationError("Invoice issue limit date of %s is exceeded!" % move.journal_id.issue_limit_date) prefix = move.journal_id.prefix padding = move.journal_id.sequence_id.padding lower_limit = prefix + str(move.journal_id.authorized_range_from).zfill(padding) upper_limit = prefix + str(move.journal_id.authorized_range_to).zfill(padding) current_number = int(move.name.replace(prefix, "")) if move.journal_id.authorized_range_from > current_number or current_number > move.journal_id.authorized_range_to: raise ValidationError("Invoice number %s is outside of range (%s, %s)" % (move.name, lower_limit, upper_limit)) move.cai = move.journal_id.cai move.authorized_range_from = lower_limit move.authorized_range_to = upper_limit move.issue_limit_date = move.journal_id.issue_limit_date warning_limit = prefix + str(move.journal_id.authorized_range_warning).zfill(padding) if move.name == warning_limit: self.env.ref("honduras_invoices.account_journal_mail_template_authorized_range_warn").send_mail(move.journal_id.id)
def _get_partner_from_headers(cls, headers): partner_model = request.env["shopinvader.partner"] partner_email = headers.get("HTTP_PARTNER_EMAIL") backend = cls._get_shopinvader_backend_from_request() if partner_email: partner_domain = [ ("partner_email", "=", partner_email), ("backend_id", "=", backend.id), ] partner = partner_model.search(partner_domain) if len(partner) == 1: return partner.record_id else: _logger.warning("Wrong HTTP_PARTNER_EMAIL, header ignored") if len(partner) > 1: _logger.warning( "More than one shopinvader.partner found for domain:" " %s", partner_domain, ) # Could be because the email is not related to a partner or # because the partner is inactive raise MissingError("The given partner is not found!") return partner_model.browse([]).record_id