跳转至内容
  • 版块
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(Flatly)
  • 不使用皮肤
折叠

Odoo 中文社区

  1. 主页
  2. 版块
  3. Odoo 新手求助
  4. OpenERP几个小机制介绍:Request, Sequence and Scheduler

OpenERP几个小机制介绍:Request, Sequence and Scheduler

已定时 已固定 已锁定 已移动 Odoo 新手求助
9 帖子 5 发布者 9.1k 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • N 离线
    N 离线
    NewZN
    写于 最后由 编辑
    #1

    本帖先说Request。什么是Request?简单的说,OpenERP的Request就是在线消息。举例来说,你通过OpenERP提交了一张请假单,你希望主管快点审批。这时,你可以使用OE给主管发送一个Request,Request里写明你的请求。如果请假模块是你自己开发的,当有人提交请假单时,你也可以在模块中自动发送Request给主管,并且以附件的形式添加请假单到Request中。当主管登录OE时,他能立即看见Request,主管可以回复Request,或者关闭Request。OE会自动记录Request的发送、回复、关闭等操作历史。
    Request的操作。在Web Client的右上角,或者GUI Client的“用户”菜单下,可以发送、接收、查看Request。
    [attach]532[/attach]
    点击Request,进入Request的列表画面,继续点击,进入Request的表单画面。
    [attach]533[/attach]

    [attach]534[/attach]

    Request的字段介绍,From:发送人;To:接收人,接收人登录OE时,会看到消息提示(注意,消息提示不是即时显示,而是在登录系统时显示);Subject:消息主题;Request:消息内容;Trigger Date:系统当前未使用,仅供显示,没其它特别含义;References:相当于附件,可以引用其它对象的数据(资源);Status:有('draft','draft'),('waiting','waiting'),('active','active'),('closed','closed') 几个状态。
    Request对象的源代码参考serverbinaddonsbaseresres_request.py。

    [[i] 本帖最后由 NewZN 于 2010-4-19 08:23 编辑 [/i]]

    1 条回复 最后回复
    0
    • N 离线
      N 离线
      NewZN
      写于 最后由 编辑
      #2

      Request的代码中(res_request.py),两个Reference字段的定义如下。
      [code]
      'ref_doc1':fields.reference('Document Ref 1', selection=_links_get, size=128, states={'closed':[('readonly',True)]}),
      'ref_doc2':fields.reference('Document Ref 2', selection=_links_get, size=128, states={'closed':[('readonly',True)]}),
      [/code]References字段,表示引用别的对象的资源(或者说,引用别的数据表的一条记录),数据库中的存储形式是(对象名,ID),如(product.product,3)表示引用对象product.product(数据表product_product)中id=3的数据。References字段在界面上的显示通常是,一个下拉框,用于选择对象名,一个查找框,用于选择该对象的具体记录。记录在界面上显示的是name,不是ID。如(product.product,3),id=3,但显示的是“[PC1] Basic PC”,这是id=3的product的name。
      上述定义中的“selection=_links_get”表示,通过函数_links_get取得一序列列表,该序列列表是诸如这样的东西:[(product.product,Product),(crm.case,Case),(account.invoice,Invoice)],即(对象名,对象显示名)的列表,该列表的内容即是界面上的下拉框中显示的内容。该列表的内容来自对象"res.request.link"(数据表 res_request_link),对象res.request.link的数据来自各个模块,如(product.product,Product),在product模块的文件product_data.xml中,有如下数据导入代码。
      [code]
      <record id="req_link_product" model="res.request.link">
      <field name="name">Product</field>
      <field name="object">product.product</field>
      </record>
      [/code]
      该代码导入(name=Product, object=product.product)的记录到数据表res_request_link中,这样,Request中便可以引用Product对象的数据。如果希望Request中可以引用请假单对象,则请假模块中必须将请假单对象导入到res_request_link中。
      代码中states={'closed':[('readonly',True)]} 的意思是,Request的状态为closed时,本字段只读。

      [[i] 本帖最后由 NewZN 于 2010-4-18 18:05 编辑 [/i]]

      1 条回复 最后回复
      0
      • N 离线
        N 离线
        NewZN
        写于 最后由 编辑
        #3

        OpenERP的Sequence,是序号生成器,类似于数据库中常见的id生成器。例如,发票和会计凭证,它们都需要序号,而且,这个序号通常不是简单的数字,而是按一定规则组合的字母和数字。在软件开发中,需要序号的情况很多,OpenERP的Sequence就是满足这种需要的东西。
        Sequence的配置。OpenERP中,可以添加任意多的序号生成器,每一序号生成器可以配置前缀、后缀、序号间隔等。即序号的一般格式是(前缀 序号 后缀),其中,序号为按一定间隔递增的数字。Sequence配置画面是,Administrator --> Configuration --> Sequences --> Sequences ,如下。
        [attach]535[/attach]

        本例中,Account Journal的序列生成器生成的序列格式形如:1004-001,即前缀为年月(%(y)s%(month)s-),序列长度为8位(Number padding=8),序列间隔为1(Increment Number)。
        Fiscal Years是account模块添加的。安装account模块后,OpenERP的序列生成器可以按会计年度定义分别采用不同的序列生成器,即不同会计年度,按不同规则采集序列。序列生成器的代码参见:serverbinaddonsbaseirir_sequence.py,account 模块对Sequence的修改参见:serverbinaddonsaccountsequence.py, 对Sequence配置画面的修改参见:serverbinaddonsaccountsequence_view.xml 。
        在sequence.py 中,继承对象ir.sequence,在原对象中增加字段fiscal_ids。该字段为不同的会计年度定义不同的序列生成器。而后,覆盖原对象的序列采集函数get_id,根据参数给定的会计年度,调用该年度的序列生成器采集序列。如果参数未指定会计年度,或者指定的会计年度没有定义生成器,则仍调用原来的序列生成器。
        在sequence_view.xml 中,继承原来的配置Form,添加了Fiscal Years的Page,用于配置各会计年度的生成器。
        按中国的会计制度,凭证号必须按月编号。一个可取的实现办法是,修改sequence.py和sequence_view.xml,将按年定义生成器改成按月定义生成器,这样就能让凭证的序号生成器每个月都启用新的编号器。
        生成新的序列号的代码示例如下:
        [code]
        c = {'fiscalyear_id': move.period_id.fiscalyear_id.id}
        new_name = self.pool.get('ir.sequence').get_id(cr, uid, journal.sequence_id.id, context=c)
        [/code]本例中,取得凭证的会计年度,从对象池中取得对象ir.sequence,指定序号生成器id(journal.sequence_id.id,本例即为Account Journal的序列生成器),调用gei_id方法取得一个新序号。

        [[i] 本帖最后由 NewZN 于 2010-4-18 19:05 编辑 [/i]]

        1 条回复 最后回复
        0
        • M 离线
          M 离线
          mrshelly
          写于 最后由 编辑
          #4

          不错.. 很赞这个 sequence 的分析....

          收藏.....
          谢谢....

          顶.....

          1 条回复 最后回复
          0
          • N 离线
            N 离线
            NewZN
            写于 最后由 编辑
            #5

            OpenERP的Scheduler。软件系统中,经常有些需要定期自动运行的任务。在unix中,支持这种需求的是cron命令,在Windows中,是附件中的任务计划程序。在OpenERP中,例如,如果设置了最小库存规则,系统需要每天自动检查产品库存,如果低于设定的最小库存值,则自动产生该产品的供应单。又如,系统每天自动检查收付款条件,到了收付款日,或收付款前后多少天,系统自动产生Request或EMail提醒相关人。诸如这样的任务,需要一个任务调度器,即Scheduler。OpenERP的Scheduler就是满足此类需求的东西。
            OpenERP的Scheduler的配置画面,Administrator --> Configuration --> Scheduler --> Scheduled Actions,画面如下。
            [attach]536[/attach]

            [attach]537[/attach]

            该配置画面上,可以配置任务每隔多少时间调用一次(Interval Number和Interval Unit),下次调用时间(Next Call Date,每次调用任务后,当前时间加上间隔时间,算出下次调用时间),调用多少次后停止调用(Number of Calls),是否重复过去的调用(Repeat Missed,例如,有一段时间服务器未启动,当启动后,是否重复补充未启动期间的作业),自动调用的函数(Technical Data)。本例中,系统每天调用对象mrp.procurement的方法run_scheduler,参数是(False,)。注意,OE中方法的前三个参数总是(self, cr, uid),因此,本例的实际调用形式是run_scheduler(cr,uid,False)。方法run_scheduler在serverbin addonsmrpmrp.py中。
            OpenERP的Scheduler的代码参见:serverbinaddonsbaseir ir_cron.py。其中,函数_poolJobs 实现任务的定期调用,关键代码行是:
            self.setAlarm(self._poolJobs, int(time.time()) + next_call, db_name, db_name)
            ir_cron继承自 netsvc.Agent,setAlarm定义在netsvc.Agent中。netsvc.Agent的代码参见serverbin netsvc.py,其中定义了一个timer:
            [code]
            timer = threading.Timer(wait, fn, args, kwargs)
            timer.start()
            [/code]
            上述代码相当于启动了一个线程,该线程会等待wait时间后调用fn函数,这里的fn是ir_cron的_poolJobs 方法。关于threading.Timer的详细解释,参考Python的threading模块说明。
            综上分析,ir_cron的实现原理是,每当新建、修改一个定期Job的时候,系统第一次调用_poolJobs,_poolJobs启动一个新线程。该线程等待Job中设定的间隔时间后激活,激活后再次调用_poolJobs,_poolJobs再次设定下次激活时间,如此反复,即实现了作业的定期调用。

            [[i] 本帖最后由 NewZN 于 2010-4-19 08:20 编辑 [/i]]

            1 条回复 最后回复
            0
            • L 离线
              L 离线
              linyaohui
              写于 最后由 编辑
              #6

              认真学习,非常感谢老xiao

              1 条回复 最后回复
              0
              • wjfonhandW 离线
                wjfonhandW 离线
                wjfonhand
                写于 最后由 编辑
                #7

                对于request,我希望它能发送给多个收件人,或者group
                对于编号,我希望能支持python代码
                对于scheduler,记得上次shelly发的自动备份模块,似乎它这个Timer是根据客户端触发。也就是说到了那个时点必须至少有一个用户在线它才会运行

                以上均是个人理解,请各位不吝赐教

                GoodERP -- Odoo China fork

                1 条回复 最后回复
                0
                • JoshuaJ 离线
                  JoshuaJ 离线
                  Joshua 管理员
                  写于 最后由 编辑
                  #8

                  我遇到过sequence的问题,就是同一个id被用户错误设定了3个sequence,然后3个sequence轮流起作用

                  【上海先安科技】(joshua AT openerp.cn),欢迎关注公众号:openerp_cn

                  1 条回复 最后回复
                  0

                  • 登录

                  • 没有帐号? 注册

                  • 登录或注册以进行搜索。
                  • 第一个帖子
                    最后一个帖子
                  0
                  • 版块
                  • 标签
                  • 热门
                  • 用户
                  • 群组