odoo中的生成唯一不重复的序列号

odoo中可以生成利用'ir.sequence'模型来生成单据的序列号,每次生成单据的时候都会自动生成,用起来还是非常方便的。这里主要介绍两种方式生成序列号,一种是借助XML。另一种是全python代码,但是本质都是通过操作'ir.sequence'模型来完成。

第一种:借助XML方式,一般是在项目的data文件夹下面创建一个ir_sequence.xml文件。

<record id="sequence_hg_contract" model="ir.sequence">
    <field name="name">合同的序号规则</field>
    <field name="code">yf.contract</field>
    <field name="prefix">YF%(year)s-%(month)s-%(day)s</field>
    <field name="padding">4</field>
    <field name="number_next">1</field>
    <field name="number_increment">1</field>
 </record>

name: 名字随便取

code:这个是用来获取序列号的,需保证唯一性

prefix:前缀,可以是固定的字面量也可以是组合参数

padding:流水号位数

number_increment: 步长,即序列号增长的长度,默认值为1。

number_next: 下一序列号数字。

在模型中获取序列号,一般是写在create方法中,使用next_by_code()方法来获取序列号,此方法有两个参数,第一个是就是在xml中的code,第二个是序列日期。

@api.model
    def create(self, values):
        """
        生成用访合同号
        """
        times = fields.Date.today()
        values['name'] = self.env['ir.sequence'].next_by_code('hg.contract', times)
        return super(HgSparePartsContract, self).create(values)

比较常用的是通过XML这种方式,但是笔者觉得纯代码的方式更好一些,简单介绍一下:

@api.model
def create(self, vals):
    now_date = (datetime.datetime.utcnow() + datetime.timedelta(hours=8)).date()
    name = vals.get('name')
    if not name:
        vals['name'] = self._pro_name(vals.get('purchase_type'), vals.get('department_id'))
    new_id = super(PurchaseOrder, self).create(vals)
def _pro_name(self, purchase_type, department):
    code = 'purchase.order'
    pre = '%(y)s-%(month)s-'
    if purchase_type == 'reagent':
        department_name = self.env['hr.department'].sudo().search([('id', '=', department)]).name
        code = 'purchase.order' + '.' + str(department_name)
        pre = str(department_name) + '-%(y)s-%(month)s-'
    new_sn = self.env['ir.sequence'].get(code)
    if new_sn:
        return new_sn
    else:
        try:
            self.env['ir.sequence'].sudo().create({'name': u'采购单', 'code': code,
                                            'prefix': pre,
                                            'padding': 4,
                                            'number_increment': 1, 'number_next_actual': 1,
                                            'implementation': 'standard',
                                            'active': True, 'company_id': False})
        except Exception as e:
            print(e)
        new_sn = self.env['ir.sequence'].get(code)
        if new_sn:
            return new_sn

先说一下具体需求:采购单分成两类,动物采购和其他采购。如果是动物采购序号规则是:年-月-日-四位流水;如果是其他采购序列号规则是:部门名称-年-月-四位流水(一个部门一套流水号)。

简单说一下这两部分代码,单据在创建的时候去创建序列号,_pro_name()方法是用来生成序列号的,之所以要传入两个值,根据purchase_type来判断采购单的类型,默认为动物采购,如果是动物采购,那么code就是'purchase.order',prefix的值为'%(y)s-%(month)s-',其次在判断当前code是否存在,如果存在则返回,不存在则新建;对于其他采购来说,code为'purchase.order.部门名称',prefix的值为'部门名称-%(y)s-%(month)s-',这样的话,就能实现每一个部门都有自己一套流水,同时还能区分采购单的类型。

在介绍一种每个月重置流水号(每个月的流水号从1开始)

def resetting(self, day=1):
    if (datetime.datetime.now() + datetime.timedelta(hours=8)).day == day:
        result = self.env['ir.sequence'].search([('code', 'like', 'purchase.order')])
        dt = datetime.datetime.utcnow() + relativedelta.relativedelta(months=1)
        for rec in result:
            if rec.code == 'yi.purchase.order':
                rec.prefix = f'{dt.year}-{dt.month:02}-'
                rec.number_next_actual = 1
            else:
                pre = str(rec.code.split('.')[-1])
                rec.prefix = f'{pre}-{dt.year}-{dt.month:02}-'
                rec.number_next_actual = 1

这个写一个定时任务就可以实现,只要输入day的值就能实现在几月几号实现序列号重置:因为笔者采购单分为两种类型,其中部门还有自己的流水,所以在获取的时候进行了like,然后循环判断处理每一个序列号。

在odoo的技术--》设置--》序号中可以对序列号进行管理

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一年级的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值