Дуже частою є задача вести послідовність в залежності від значення поля або полів. Наприклад рахунки на замовника, відвантаження від складу.
Або вже реалізований в Odoo механізм в записах в журнали, в залежності від журналу або банківської виписки від рахунку.
Цей механізм реалізується в модулі account за допомогою sequence.mixin
Приклад створення і застосування простої послідовності описаний у статті Як застосувати Послідовність номерів в Odoo
Розглянемо приклад, де послідовність створюється в залежності від номеру Sale Order, року та місяця
class Sample(models.Model):
_name = 'sample'
_inherit = ['sequence.mixin', ]
_description = 'Sample'
name = fields.Char(
required=True, copy=False, readonly=True,
index=True, default='-')
active = fields.Boolean(
default=True, )
date = fields.Date(
default=fields.Date.today, )
sale_order_id = fields.Many2one(
comodel_name='sale.order', readonly=False, )
@api.model
def create(self, vals):
result = super().create(vals)
result._set_next_sequence()
return result
def _get_last_sequence_domain(self, relaxed=False):
self.ensure_one()
where_string = \
"WHERE sale_order_id = %(sale_order_id)s AND name != '-' " \
"AND name != %(new_name)s "
param = {'sale_order_id': self.sale_order_id.id, 'new_name': _('New')}
if not relaxed:
domain = [
('sale_order_id', '=', self.sale_order_id.id),
('id', '!=', self.id or self._origin.id),
('name', '!=', False), ]
previous_name = self.search(
domain + [('date', '<', self.date)],
order='date desc', limit=1).name
if not previous_name:
previous_name = self.search(
domain, order='date desc', limit=1).name
sequence_number_reset = \
self._deduce_sequence_number_reset(previous_name)
if sequence_number_reset == 'year':
where_string += \
" AND date_trunc('year', date) = " \
"date_trunc('year', %(date)s) "
param['date'] = self.date
elif sequence_number_reset == 'month':
where_string += \
" AND date_trunc('month', date) = " \
"date_trunc('month', %(date)s) "
param['date'] = self.date
return where_string, param
def _get_starting_sequence(self):
self.ensure_one()
return "%s %04d/%02d/00000" % (self.sale_order_id.name, self.date.year, self.date.month)
Що потрібно зробити
1. Наслідувати модель ві sequence.mixin
2. Додати поля name, date, sale_order_id
3. Перевизначити методи _get_last_sequence_domain, _get_starting_sequence та create
Приклад нумерації, що не залежить від дати
class Sample(models.Model):
_name = 'sample'
_inherit = ['sequence.mixin', ]
_description = 'Sample'
name = fields.Char(
required=True, copy=False, readonly=True,
index=True, default='-')
sale_order_id = fields.Many2one(
comodel_name='sale.order', readonly=False, )
@api.model
def create(self, vals):
result = super().create(vals)
result._set_next_sequence()
return result
def _get_last_sequence_domain(self, relaxed=False):
self.ensure_one()
where_string = \
"WHERE sale_order_id = %(sale_order_id)s AND name != '-' " \
"AND name != %(new_name)s "
param = {'sale_order_id': self.sale_order_id.id, 'new_name': _('New')}
return where_string, param
def _get_starting_sequence(self):
self.ensure_one()
return "%s-0" % self.sale_order_id.name