def order(self): """ The order_line is ordered to the vendor but isn't received yet """ if self.user_has_groups("lunch.group_lunch_manager"): self.write({'state': 'ordered'}) order = { 'supplier': False, 'company': False, 'currency': False, } group_lines = {} for line in self: if not line.supplier: # do not send emails for products with no suppliers continue if order['supplier'] and line.supplier != order['supplier']: raise ValidationError(_("Validate order for one supplier at a time to send emails (mixed orders from %s and %s)") % ( order['supplier'].display_name, line.supplier.display_name)) order['supplier'] = line.supplier if order['company'] and line.order_id.company_id != order['company']: raise ValidationError(_("Validate order for one company at a time to send emails (mixed orders from %s and %s)") % ( order['company'].name, line.order_id.company_id.name)) order['company'] = line.order_id.company_id if order['currency'] and line.currency_id != order['currency']: raise ValidationError(_("Validate order for one currency at a time to send emails (mixed orders from %s and %s)") % ( order['currency'].name, line.currency_id.name)) order['currency'] = line.currency_id # group the order by products and note key = (line.product_id, line.note) group_lines.setdefault(key, 0) group_lines[key] += 1 order['company_name'] = order['company'].name order['currency_id'] = order['currency'].id order['supplier_id'] = order['supplier'].id order['supplier_name'] = order['supplier'].name order['supplier_email'] = order['supplier'].email_formatted lines = [] # sort by product name, note for product, note in sorted(group_lines, key=lambda k: (k[0].name, bool(k[1]))): quantity = group_lines[(product, note)] lines.append({ 'product': product.name, 'note': note or '', 'quantity': quantity, 'price': product.price * quantity, }) order['amount_total'] = sum(l['price'] for l in lines) template = self.env.ref('lunch.lunch_order_mail_supplier', raise_if_not_found=False) ctx = dict( default_composition_mode='mass_mail', default_use_template=bool(template), default_template_id=template.id, default_lang=order['supplier'].lang or self.env.user.lang, order=order, lines=lines, ) return { 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'mail.compose.message', 'target': 'new', 'context': ctx, } else: raise AccessError(_("Only your lunch manager processes the orders."))
def _check_allow_timesheet(self): for project in self: if project.allow_timesheets and not project.analytic_account_id: raise ValidationError(_('To allow timesheet, your project %s should have an analytic account set.' % (project.name,)))
def check_product_id(self): if any(elem.product_id.type != 'product' for elem in self): raise ValidationError( _('Quants cannot be created for consumables or services.'))
def _check_parent_id(self): if not self._check_recursion(): raise ValidationError( _('Error! You cannot create recursive menus.'))
def _check_subtask_level(self): for task in self: if task.parent_id and task.child_ids: raise ValidationError(_('Task %s cannot have several subtask levels.' % (task.name,)))
def _check_sale_line_type(self): for task in self.sudo(): if task.sale_line_id: if not task.sale_line_id.is_service or task.sale_line_id.is_expense: raise ValidationError(_('You cannot link the order item %s - %s to this task because it is a re-invoiced expense.' % (task.sale_line_id.order_id.id, task.sale_line_id.product_id.name)))
def check_dates(self): for rec in self: if rec.start_date > rec.end_date: raise ValidationError( _("Start date must be Anterior to end date"))
def _check_date_time(self): if self.start_date > self.end_date: raise ValidationError( _('End Date cannot be set before Start Date.'))
def _check_parent_id(self): if not self._check_recursion(): raise ValidationError( _('You cannot create recursive Partner hierarchies.'))
def _check_main_currency_rounding(self): if any(precision.name == 'Account' and tools.float_compare(self.env.company.currency_id.rounding, 10 ** - precision.digits, precision_digits=6) == -1 for precision in self): raise ValidationError(_("You cannot define the decimal precision of 'Account' as greater than the rounding factor of the company's main currency")) return True
def _check_marks(self): if self.total_marks <= 0.0 or self.min_marks <= 0.0: raise ValidationError(_('Enter proper marks!')) if self.min_marks > self.total_marks: raise ValidationError(_( "Passing Marks can't be greater than Total Marks"))
def _check_optional_product_company_id(self): for order in self: companies = order.sale_order_option_ids.product_id.company_id if companies and companies != order.company_id: bad_products = order.sale_order_option_ids.product_id.filtered(lambda p: p.company_id and p.company_id != order.company_id) raise ValidationError((_("Your quotation contains products from company %s whereas your quotation belongs to company %s. \n Please change the company of your quotation or remove the products from other companies (%s).") % (', '.join(companies.mapped('display_name')), order.company_id.display_name, ', '.join(bad_products.mapped('display_name')))))
def _check_discount(self): for line in self: if line.discount > 100: raise ValidationError( _("Discount should be less or equal to 100"))
def _check_company_id(self): for voucher in self: if not voucher.company_id: raise ValidationError(_("Missing Company")) if not voucher.currency_id: raise ValidationError(_("Missing Currency"))
def _check_name(self): # dummy constraint to check on computed field for message in self: if message.name.startswith("[X]"): raise ValidationError("No way!")
def _check_pec(self): for record in self: if record.l10n_it_is_pec and record.type != 'imap': raise ValidationError("PEC mail server must be of type IMAP.")
def _check_birthdate(self): for record in self: if record.birth_date > fields.Date.today(): raise ValidationError( _("Birth Date can't be greater than current date!"))
def _check_active(self): # do not check during installation if self.env.registry.ready and not self.search_count([]): raise ValidationError(_('At least one language must be active.'))
def unlink(self): if any(task.sale_line_id for task in self): raise ValidationError(_('You have to unlink the task from the sale order item in order to delete it.')) return super(ProjectTask, self).unlink()
def _check_marks(self): for res in self: if (res.total_pass < 0.0) or (res.total_failed < 0.0): raise ValidationError(_('Enter proper pass or fail!'))
def _check_valid_video_url(self): for image in self: if image.video_url and not image.embed_code: raise ValidationError(_("Provided video URL for '%s' is not valid. Please enter a valid video URL.") % image.name)
def wrapper(___dbname, *args, **kwargs): """ Wraps around OSV functions and normalises a few exceptions """ dbname = ___dbname # NOTE: this forbid to use "___dbname" as arguments in http routes def tr(src, ttype): # We try to do the same as the _(), but without the frame # inspection, since we aready are wrapping an osv function # trans_obj = self.get('ir.translation') cannot work yet :( ctx = {} if not kwargs: if args and isinstance(args[-1], dict): ctx = args[-1] elif isinstance(kwargs, dict): if 'context' in kwargs: ctx = kwargs['context'] elif 'kwargs' in kwargs and kwargs['kwargs'].get('context'): # http entry points such as call_kw() ctx = kwargs['kwargs'].get('context') else: try: from eagle.http import request ctx = request.env.context except Exception: pass lang = ctx and ctx.get('lang') if not (lang or hasattr(src, '__call__')): return src # We open a *new* cursor here, one reason is that failed SQL # queries (as in IntegrityError) will invalidate the current one. cr = False try: cr = eagle.sql_db.db_connect(dbname).cursor() res = translate(cr, name=False, source_type=ttype, lang=lang, source=src) if res: return res else: return src finally: if cr: cr.close() def _(src): return tr(src, 'code') tries = 0 while True: try: if eagle.registry(dbname)._init and not eagle.tools.config[ 'test_enable']: raise eagle.exceptions.Warning( 'Currently, this database is not fully loaded and can not be used.' ) return f(dbname, *args, **kwargs) except (OperationalError, QWebException) as e: if isinstance(e, QWebException): cause = e.qweb.get('cause') if isinstance(cause, OperationalError): e = cause else: raise # Automatically retry the typical transaction serialization errors if e.pgcode not in PG_CONCURRENCY_ERRORS_TO_RETRY: raise if tries >= MAX_TRIES_ON_CONCURRENCY_FAILURE: _logger.info("%s, maximum number of tries reached" % errorcodes.lookup(e.pgcode)) raise wait_time = random.uniform(0.0, 2**tries) tries += 1 _logger.info("%s, retry %d/%d in %.04f sec..." % (errorcodes.lookup(e.pgcode), tries, MAX_TRIES_ON_CONCURRENCY_FAILURE, wait_time)) time.sleep(wait_time) except IntegrityError as inst: registry = eagle.registry(dbname) for key in registry._sql_error.keys(): if key in inst.pgerror: raise ValidationError( tr(registry._sql_error[key], 'sql_constraint') or inst.pgerror) if inst.pgcode in (errorcodes.NOT_NULL_VIOLATION, errorcodes.FOREIGN_KEY_VIOLATION, errorcodes.RESTRICT_VIOLATION): msg = _('The operation cannot be completed:') _logger.debug("IntegrityError", exc_info=True) try: # Get corresponding model and field model = field = None for name, rclass in registry.items(): if inst.diag.table_name == rclass._table: model = rclass field = model._fields.get( inst.diag.column_name) break if inst.pgcode == errorcodes.NOT_NULL_VIOLATION: # This is raised when a field is set with `required=True`. 2 cases: # - Create/update: a mandatory field is not set. # - Delete: another model has a not nullable using the deleted record. msg += '\n' msg += _( '- Create/update: a mandatory field is not set.\n' '- Delete: another model requires the record being deleted. If possible, archive it instead.' ) if model: msg += '\n\n{} {} ({}), {} {} ({})'.format( _('Model:'), model._description, model._name, _('Field:'), field.string if field else _('Unknown'), field.name if field else _('Unknown'), ) elif inst.pgcode == errorcodes.FOREIGN_KEY_VIOLATION: # This is raised when a field is set with `ondelete='restrict'`, at # unlink only. msg += _( ' another model requires the record being deleted. If possible, archive it instead.' ) constraint = inst.diag.constraint_name if model or constraint: msg += '\n\n{} {} ({}), {} {}'.format( _('Model:'), model._description if model else _('Unknown'), model._name if model else _('Unknown'), _('Constraint:'), constraint if constraint else _('Unknown'), ) except Exception: pass raise ValidationError(msg) else: raise ValidationError(inst.args[0])
def _answered_or_skipped(self): for uil in self: if not uil.skipped != bool(uil.answer_type): raise ValidationError( _('This question cannot be unanswered or skipped.'))
def _must_have_analytical_or_budgetary_or_both(self): if not self.analytic_account_id and not self.general_budget_id: raise ValidationError( _("You have to enter at least a budgetary position or analytic account on a budget line." ))
def _check_parent_id(self): for task in self: if not task._check_recursion(): raise ValidationError(_('Error! You cannot create recursive hierarchy of task(s).'))
def _check_exam_session(self): for record in self: for exam in record.exam_session_id.exam_ids: if exam.state != 'done': raise ValidationError( _('All subject exam should be done.'))
def check_location_id(self): for quant in self: if quant.location_id.usage == 'view': raise ValidationError( _('You cannot take products from or deliver products to a location of type "view".' ))
def _check_author(self): for message in self.with_context(active_test=False): if message.discussion and message.author not in message.discussion.participants: raise ValidationError( _("Author must be among the discussion participants."))
def unlink(self): """Return warning if the Record is in done state""" for rec in self: if rec.state == 'done': raise ValidationError(_("Cannot delete Record in Done state"))
def _check_supplier_availibility(self): products = self.mapped('product_id') if not all(product.available for product in products): supplier_name = ", ".join(product.supplier.display_name for product in products if not product.available) raise ValidationError(_("Vendor(s) '%s' is not available today") % supplier_name)