• odoo 项目经验1


    1.在xml中的domain表达式解析:|,&,!以及表示此意义的符号,都是遵从栈的规则(后进先出),右为栈底,所以从最左端的符号开始判断。

    2.xml中也可以进行时间计算,比如在一周内的为即将开始等等等。

    可参照https://www.cnblogs.com/hellojesson/p/8144474.html

     <filter string="执行阶段" name="execute_stage" domain="[('state','in',['preparing','doing','done'])]"/>
                        <filter string="即将开始" domain="['&amp;', ('state','=','preparing'), ('plan_date', '&lt;=', (context_today()+datetime.timedelta(days=7)).strftime('%Y-%m-%d'))]"/>
                        <filter string="开始延期" domain="['&amp;', ('state','=','preparing'), ('plan_date', '&lt;=', (context_today()+datetime.timedelta(days=0)).strftime('%Y-%m-%d'))]"/>
                        <filter string="即将完成" domain="['&amp;', ('state','=','doing'), ('plan_done_date', '&lt;=', (context_today()+datetime.timedelta(days=7)).strftime('%Y-%m-%d'))]"/>
                        <filter string="执行延期" domain="['&amp;', ('state','=','doing'), ('plan_done_date', '&lt;=', (context_today()+datetime.timedelta(days=0)).strftime('%Y-%m-%d'))]"/>
                        <filter string="我的任务" domain="['&amp;',('operator_id','=',uid),'|',('state','=','inquiring'),('state','=','doing')]"/>

     </filter>

    2.5 Odoo中本日、本月、上月过滤器实现方法

    <filter string="今日订单" name="today" invisible="0" domain="[('date','=', current_date)]"/>
    <filter string="本月订单" name="month" invisible="0" domain="[('date','&gt;=', time.strftime('%Y-%m-01')),('date','&lt;',  (context_today() + relativedelta(months=1)).strftime('%Y-%m-01') ) ]"/>
    <filter string="上月订单" name="month2" invisible="0" domain="[('date','&lt;', time.strftime('%Y-%m-01')),('date','&gt;=',  (context_today() - relativedelta(months=1)).strftime('%Y-%m-01') ) ]"/>
    <filter string="本年订单" name="year" invisible="0" domain="[('date','&lt;=', time.strftime('%Y-12-31')),('date','&gt;=', time.strftime('%Y-01-01'))]"/>

    Odoo过滤器中可以使用的时间变量

          <filter name="not_filled_in_last_week" string="Not Filled in Last Week" domain="[('state','=','draft'),('date_to', '&gt;=', ((context_today()+relativedelta(weeks=-2, days=1, weekday=0)).strftime('%Y-%m-%d'))),('date_to', '&lt;=', ((context_today()+relativedelta(weeks=-1, weekday=6)).strftime('%Y-%m-%d')))]"/>
          <filter name="not_filled_in_last_month" string="Not Filled in Last Month" domain="[('state','=','draft'),('date_to', '&lt;', time.strftime('%Y-%m-01')),('date_to','&gt;=', (context_today() - relativedelta(months=1)).strftime('%Y-%m-01'))]"/>
          <filter name="not_filled_in_this_month" string="Not Filled in This Month" domain="[('state','=','draft'),('date_to', 'like', time.strftime('%Y-%m'))]"/>
       datetime: datetime,
       context_today: context_today,
       time: time,
       relativedelta: relativedelta,
       current_date

    3.在定义字段时,related为强关联,若只为引用(可以用m2m,o2m,m2o关系)时,为了不造成反写(修改)被引用的原有字段(且若无权限修改,则会报错提醒),一定要加上readonly=True加以限制;store=True视情况而定,若报错信息为以下,则多半是不能加store=True。

    ProgrammingError: relation "none" does not exist 
    _______________or_________________
    Exception during JSON request handling.

    4.流水号

    <!--xml文件:此为4位年号,2位月和日号,三位随机数字类型,2位年为%(Y)s,name="code"是model找到这个规则的标志,noupdate="0"代表每次加载都更新,一般加上,如果刚开始是1,之后改为0,得手动到浏览器删除这个序列号,否则不生效--> 
    <data noupdate="0">
        <record id="sequence_xx_product_certification_test_order" model="ir.sequence">
            <field name="name">xx Product Certification Test Order Sequence</field>
            <field name="code">xx.product.certification.test.order.code</field>
            <field name="prefix">CRT%(year)s%(month)s%(day)s</field>
            <field name="padding">3</field>
        </record>
    </data>
    # Python文件:
    @api.model
        def create(self, vals):
            vals['name'] = self.env['ir.sequence'].next_by_code('xx.product.certification.apply.order.code') or ''
            res = super(xxProductCertificationApply, self).create(vals)
            return res

    5.弹出向导

    # Python文件:   
        def create_test(self):
            """"创建可靠性测试需求,若已创建认证需求,则为完成申请状态"""
            if self.state == 'create_certification':
                current_state = 'done'
            else:
                current_state = 'create_test'
    
            ctx = {
            #此为一些默认值,需要加载到前端默认显示,相应的要在xml中进行接收,同时这个ctx字典内容会直接放到wizard的self.env.context里面,可以对内容加以保存(可保存到任意表),default_为固定格式
                'default_ca_name': self.name,
                'default_create_uid': self.env.user.id,
                'default_department_id': self.env.user.department_id.id,
                'default_cert_apply_id': self.id,
                'default_project_id': self.project_id.id,
                # 'default_ct_type': 'test',
                'default_product_center_product_id': self.product_center_product_id.id,
                'default_product_model': self.product_model,
                'default_categ_id': self.categ_id.id,
                'default_submit_date': self.commit_date_time,
                'default_product_detail_text': self.product_detail_text,
                'default_sales_regions': [(6, 0, self.sales_regions.ids)],
                'default_wireless_protocol': [(6, 0, self.wireless_protocol.ids)],
                'default_project_user': self.project_user.id,
                'default_product_manager_ids': [(6, 0, self.product_manager_ids.ids)],
                'current_state': current_state
            }
    
            view = self.env.ref('xx_product_center.xx_pct_order_view') #找到要渲染的view视图
            res = {
                'res_model': 'xx.pct.oder.wizard', #指明要加载的model模型,有什么字段就可以选择加载什么字段,可以做成form视图和tree视图
                'view_type': 'form',
                'view_mode': 'form',
                'view_id': view.id, #获取视图id
                'name': _('Create Test'), #_(")要翻译的内容
                'type': 'ir.actions.act_window', #类型
                'target': 'new', # 新打开一个页面
                'context': ctx,
                'views': [(view.id, 'form')]
            }
            return res         # return给前端
    <?xml version="1.0" encoding="utf-8"?>
    <odoo>
        <data>
            <!--认证&测试-->
            <record id="xx_pct_order_view" model="ir.ui.view">
                <field name="name">xx.pct.order.wizard.form</field>
                <field name="model">xx.pct.oder.wizard</field>
                <field name="arch" type="xml">
                    <form>
    
                        <group>
    
                            <group>
                                <field name="ca_name" invisible="1"/>
                                <field name="create_uid" invisible="1"/>
                                <field name="department_id" invisible="1"/>
                                <field name="cert_apply_id" invisible="1"/>
                                <field name="project_id" invisible="1"/>
                                <!--<field name="ct_type" invisible="1"/>-->
                                <field name="product_center_product_id" invisible="1"/>
    
                                <field name="product_center_product_id"/>
                                <field name="product_model"/>
                                <field name="categ_id"/>
                                <field name="submit_date"/>
                                <field name="product_detail_text"/>
                            </group>
    
                            <group>
                                <field name="sales_regions"/>
                                <field name="wireless_protocol"/>
                                <field name="project_user"/>
                                <field name="product_manager_ids"/>
                            </group>
    
                        </group>
    
                            <notebook>
                                <page string="Certification or Reliability Testing">
                                    <field name="certification_test_order_lines">
                                        <tree editable="0">
                                            <field name="cert_test_conf_id" required="1"/>
                                            <field name="ct_type" required="1"/>
                                            <field name="required_text" required="0"/>
                                        </tree>
                                    </field>
                                </page>
                            </notebook>
    
                        <footer>
                            <button string="Cancel" class="btn-default" special="cancel"/>
                            <button string="Save" type="object" name="execute" class="oe_highlight"/>
                        </footer>
                    </form>
                </field>
            </record>
        </data>
    </odoo>

     

     6.服务器动作(不明白为什么这样叫,就是选择几个记录时,动作中可以有一个按钮,按完可以弹向导),效果如下:

     

     

     思路:tree视图中多选完,弹出选择时间的wizard,所以必须自己新建一个TransientModel,里面有plan_start_date字段,当选择完时间以后点击提交按钮,触发这个model中的函数,需要处理选择的多行记录,所以我们又在此model中创建一个字段,多对多关联到原tree视图主model,然后在原主model context中传入 {'default_certification_test_order_ids': [(6, 0, ids)]},并建立多对多关系(ids为包含多行被选记录的id列表),接收到前端但不显示(<field name="certification_test_order_ids" invisible="1"/>

    ),这样点击提交按钮,回到在这个TransientModel函数中,就可以直接self点出来了,然后for循环,一一处理。等处理完,收集完问题数据,然后再return一个wizard,所以又需要再创建一个TransientModel,有error_thingerror_info两个字段,只让确定不让取消,确定的函数只需要pass即可,取消会可能把所有的wizard都取消,产生冲突。

    <!--主model的tree视图,可以触发多选后的动作按钮-->
    <record model="ir.actions.server" id="action_start_preparing"> 
                <field name="name">Start Preparing</field>
                <field name="model_id" ref="model_xx_product_certification_test_order"/>
                <field name="code">
                if records:    直接调用Python方法
                    action = records.action_start_preparing()
                </field>
            </record>
    
            <record model="ir.values" id="action_start_preparing_new"> 上下id不一致
                <field name="model_id" ref="model_xx_product_certification_test_order" />
                <field name="name">Start Preparing</field>
                <field name="key2">client_action_multi</field>
                <field name="value" eval="'ir.actions.server,' +str(ref('action_start_preparing'))" />关联上id
                <field name="key">action</field>
                <field name="model">xx.product.certification.test.order</field>适用model,tree主model
                <field name="groups" eval="[(4, ref('group_xx_product_center_certified_engineer')),(4, ref('group_xx_product_center_reliability_engineer'))]"/> 权限
            </record>
        @api.multi
        def action_start_preparing(self):
            ids = self.env.context.get('active_ids', []) #找到所有选择的记录id
            view = self.env.ref('xx_product_center.xx_pcto_plan_time_view') # 找到要渲染出的视图
            res = {
                'res_model': 'xx.pcto.quote.plan.time', # 用哪个model去渲染
                'view_type': 'form',
                'view_mode': 'form',
                'view_id': view.id, # 关联视图
                'name': _('Plan Start Time'),
                'type': 'ir.actions.act_window',
                'target': 'new',
                'context': {'default_certification_test_order_ids': [(6, 0, ids)]}, # 创建多对多关系
                'views': [(view.id, 'form')]
            }
            return res
    # 两个wizard,一上一下
    class xxPCTOQuotePlanTime(models.TransientModel):
        _name = 'xx.pcto.quote.plan.time'
        _description = "Product Certification Test Oder Wizard"
    
        plan_start_date = fields.Datetime(string='Plan Start Date Time', track_visibility='onchange')
        certification_test_order_ids = fields.Many2many(string='Certification Test Order',
                                                        relation='xx_pct_order_plan_time_table',
                                                        comodel_name='xx.product.certification.test.order')
    
        @api.multi
        def execute(self):
         #处理过程不用看
            error_list = []
            val = {
                'plan_start_date': self.plan_start_date,
                'state': 'preparing'
            }
            for record in self.certification_test_order_ids:
                if record.state == 'approved':
                    record.write(val)
                else:
                    error_thing = str(record.product_center_product_id.name or record.other_product_text) + ' ' + str(record.cert_test_conf_id.name or '')
                    error_list.append(error_thing)
                    continue
    
            error_things = '
    '.join(list(set(error_list)))
            view = self.env.ref('xx_product_center.xx_pcto_plan_time_error_view')
            err_msg = {'default_error_thing': error_things,
                       'default_error_info': _('Is not in the completed quote stage. Cannot start planning, please adjust the stage before planning!')}
            return {
                'res_model': 'xx.pcto.quote.plan.time.error',
                'view_type': 'form',
                'view_mode': 'form',
                'view_id': view.id,
                'name': _('Plan Start Time Error'),
                'type': 'ir.actions.act_window',
                'target': 'new',
                'context': err_msg,
                'views': [(view.id, 'form')]
            }
    
    
    class xxPCTOQuotePlanTimeError(models.TransientModel):
        _name = 'xx.pcto.quote.plan.time.error'
        _description = "Product Certification Test Oder Wizard Error"
    
        error_thing = fields.Text(string='Error Thing', readonly=True)
        error_info = fields.Text(string='Error Info', readonly=True)
    
        @api.multi
        def execute(self):
            pass
    选择时间的wizard:
    <field name="name">xx.pcto.quote.plan.time.form</field>
                <field name="model">xx.pcto.quote.plan.time</field>
                <field name="arch" type="xml">
                    <form>
                        <group>
                            <field name="certification_test_order_ids" invisible="1"/>
                            <field name="plan_start_date"/>
                        </group>
                        <footer>
                            <button string="Submit" type="object" name="execute" class="oe_highlight"/>
                        </footer>
                    </form>
     </field>
    错误提醒的wizard:
    <field name="name">xx.pcto.quote.plan.time.error.form</field>
                <field name="model">xx.pcto.quote.plan.time.error</field>
                <field name="arch" type="xml">
                    <form>
                        <group>
                            <field name="error_thing" readonly="1"/>
                            <field name="error_info" readonly="1"/>
                        </group>
                        <footer>
                            <button string="Submit" type="object" name="execute" class="oe_highlight"/>
                        </footer>
                    </form>
       </field>
  • 相关阅读:
    MySQL-简述
    APP测试-Solo Pi工具-性能测试
    APP测试-弱网测试
    iOS 认识runtime 中的三个指针 isa , IMP , SEL
    iOS 什么是函数式编程
    iOS 根据农历日期 获取当前的农历年份 即 干支纪年法算农历年
    iOS 当公司有人向你提问,你该如何应对?
    Mac 环境 下使用Charles 抓包Http/Https请求
    iOS iPhone X 适配启动图片
    iOS11 仿大标题 导航栏
  • 原文地址:https://www.cnblogs.com/liangsha0/p/12018367.html
Copyright © 2020-2023  润新知