跳转至内容

Odoo 培训

37 主题 87 帖子

No decsciption available

  • pip安装Odoo模块

    odoo 安装 odoo技术
    2
    0 赞同
    2 帖子
    3k 浏览
    厉害
  • pip快速安装Odoo

    odoo 安装 odoo 培训
    1
    1 赞同
    1 帖子
    1k 浏览
    D
    请看到最后,视频的最后有完整安装过程的文档 看完此视频请继续观看pip 安装Odoo模块
  • Odoo V14社区版财务的核销界面没有了?!

    odoo-on-the-go
    1
    1
    0 赞同
    1 帖子
    1k 浏览
    D
    最近在给客户的演示中才突然发现在Odoo 14.0以前的社区版中出现并不断升级优化的应收/应付款的核销界面尽然不见了。很好用的批量核销的功能被彻底的移入了企业版。 不过社友们也不必“放下筷子”,只管放心吃肉 。因为勤劳的Odoo开源社区已经为我们准备好了替代方案:OCA的Reconciliation Widget [image: 1629259605594-8081629247300_.pic_hd.jpg]
  • Odoo的异步队列神器-queue_job

    odoo技术 异步队列 queuejob
    19
    0 赞同
    19 帖子
    13k 浏览
    H
    @hui 请问,新建库重启问题如何处理的?有解决方案吗?
  • Odoo的基本操作演示(视频)

    odoo 培训
    3
    6 赞同
    3 帖子
    7k 浏览
    D
    @whnoob 谢谢提醒,原来上传的视频链接都失效了。等有空了换个视频网站上传。
  • 1 赞同
    1 帖子
    1k 浏览
    D
    在V13以前,我们可以用下面的方法来为浮点数字段设置预设的数字精度: import odoo.addons.decimal_precision as dp xxx = fields.Float(digits=dp.get_precision("Account")) 这个定义对用户很友好,这表示xxx字段可以使用一个叫Account的浮点数的小数点位数的定义。如果用户对xxx字段的精度不满意,就可以找到Account这个预设精度,改变精度值,xxx字段的精度也相应改变了。没有这个设计,改变浮点数精度必须依赖程序员修改代码。 V13把目前的这个定义方式淘汰了,变得更加简单: xxx = fields.Float(digits="Account") 注意没有了import, 和dp.get_precision
  • Selection字段的ondelete属性

    odoo技术 selection字段
    1
    0 赞同
    1 帖子
    1k 浏览
    D
    当我们在自己模块里继承了某个模型并且通过selection_add对这个模型的Selection类型字段添加了新的选项。系统中的记录也选择了我们定义的选项。然后,由于某些情况,我们需要卸载这个模块,那么这些选择了我们新的选项的记录这时候应该怎么处理,尤其是如果这个选项类型的字段还是“Required"的字段,那就更会引起错误了。 如fields.Many2one字段一样,为了处理fields.Selection出现上诉的问题,我们也要为这个字段添加ondelete属性。ondelete属性对应一个python字典。 当该字段的required=True时,ondelete属性是必须设置的,并且不能其值设置为null 比如: my_selection = fields.Selection(selection_add=[ ('pikachu', "Pikachu"), ('eevee', "Eevee"), ], ondelete={'pikachu': 'default', 'eevee': 'set bar'}) 从上面的例子可以看到,这个ondelete字典的key是新添的选项,其值就是当新添的选项删除时(模块卸载时)需要处理的动作,这些动作包括: 'null' --默认值,当对应选项删除时会将该字段的值设为False。如上所诉,当该字段的required=True时ondelete不能使用这个动作。 'cascade' -- 所有选择当前选项的记录,当选项被删除时,记录一并被删除。 'default' -- 选择该选项的所有记录,当选项被删除时,该字段恢复为默认值。 'set ' -- 选择该选项的所有记录,当选项被删除时,该字段的值设为这里的设定值,这里的设定值必须有效存在。 <callable> -- 可以定义一个方法来返回结果,这个函数只有一个唯一参数对应所有包含该选项的记录。
  • 1 赞同
    1 帖子
    1k 浏览
    D
    我们知道Odoo的Selection字段的选项值为包含多个元组的一个列表,其中每个元组包含两个字符串成员,第一个成员为内部保存值,第二个用来界面显示,比如 class TestModel(model.Model): _name = 'test.model' myselection = fields.Selection([('a', 'A'), ('b', 'B')], string='MySelection') 当在新的模块里需要继承修改这个Selection字段的选项时,我们可以使用selection_add, 比如: class TestModel(model.Model): _inherit = 'test.model' myselection = fields.Selection(selection_add=[('c', 'C')]) 问题是这样的继承得到的结果是[('a', 'A'), ('b', 'B'), ('c', 'C')],新添加的选项在列表的尾端。那有没有办法指定新添加选项在列表中的位置呢?在Odoo13以后实际上我们可以在选项值后面添加由单个成员组成的元组来确认新选项的插入位置,比如上例中: selection_add = [('c', 'C'), ('b',)] > result = [('a', 'A'), ('c', 'C'), ('b', 'B')]
  • Odoo 错误:Exception("bus.Bus unavailable") 是什么鬼?

    odoo技术 odoo exception
    2
    0 赞同
    2 帖子
    3k 浏览
    H
    @digitalsatori 我就本地测试的话,不用nginx,有办法处理掉这个错误吗?
  • queue_job 充分发挥多核服务器并发优势

    queuejob 异步队列
    2
    1
    0 赞同
    2 帖子
    2k 浏览
    A
    @digitalsatori 不错 消息队列的作用不小
  • 计算字段中的compute_sudo

    odoo技术 compute字段
    1
    0 赞同
    1 帖子
    1k 浏览
    D
    我们在定义一个计算字段时往往会忽略这个计算字段被触发重算的环境。尤其是这个字段depends其它对象的字段,或者我们的运行环境是 多公司的环境。这时候很可能一个没有权限用户对某个字段的修改触发了计算字段的重算,但是因为权限关系这个重算无法完成,从而会出现权限错误。 当你在遇到这种情况时,就要考虑给计算字段加compute_sudo的属性,比如: total_cost = fields.Float('Total Cost', compute='_compute_total', store=True, compute_sudo=True) 注意这种用法只对,store=True的计算字段有效。
  • Odoo对临近保质期的产品如何提醒

    odoo应用 保质期
    1
    2
    0 赞同
    1 帖子
    1k 浏览
    D
    Odoo系统自带产品的保质期管理。当产品需要进行保质期管理时,只要在库存设置里激活”批号/条码跟踪“ 和 ”保质期管理“即可: [image: 1573520375438-new_-_odoo.png] 然后在需要进行保质期管理的产品维护界面里选择“批号或条码跟踪”,并配置产品的保质期期限。这样在产成品入库或者采购产品入库时输入的批次号上就自动包含了产品的保质期到期日,警告日等信息。可是估计很少有人知道到期前提醒是如何执行的。 事实上在每个批次号上除了保质期到期日以外,还有一个保质期告警日期,这两个日期都是可以根据产品上的日期期限自动生成,也可以手动设定。到了某个产品批次的告警日期,系统会自动会为该批次打上报警标签,并向该产品的负责人发送提醒信息。 所以,如果希望收到及时的保质期报警信息请在产品的维护界面为产品设置“产品负责人” [image: 1573521982997-odoo-resized.png]
  • Odoo部署的服务器配置选择

    odoo技术 odoo部署
    1
    0 赞同
    1 帖子
    2k 浏览
    D
    Odoo默认工作在“线程”模式下。当并发用户增加时,线程模式因为Python的GIL全局锁的限制,导致它无法分配现今多核服务器的其它内核来处理运算请求。所以,当有比较多的并发用户时,我们要将Odoo设置为“多进程”的模式,以充分利用服务器多核的计算资源。 所谓让Odoo工作在“多进程模式“,就是给启动参数workers设置一个非0的数值,那设多少合适呢? 首先,我们要知道:一个worker大致能并发处理6~10用户请求,所以比如60用户并发,那就大致需要配置10个worker Odoo的worker的值的设置还与服务器的内核数量有关,因为这些worker的负载最后是要由CPU内核运算单元来消化的。所以比如一个普通的单CPU,4核服务器,可以支持的workers的数量就是 2 * Cores + 1 = 9, 8个http worker, 1个cron job worker。 与上面的10个worker的需求接近,所以处理60用户并发我们可以选一台拥有4核的服务器,Odoo配置: workers = 8 max_cron_threads = 1 那么内存应该配置多少呢?一般一个任务繁重的worker占用1G内存,而大多数轻载的worker占用内存为150M左右。而在实际的应用中遵守2/8法则,即重载worker和轻载worker的存在比例时20%/80%, 所以9个worker的内存需求为: 9 * (0.8 * 150 + 0.2 * 1024)≂ 3 G RAM 由此可以看出,Odoo还是一个并不怎么消耗服务器资源的平台。
  • Odoo的XML-ID

    xml-id 外部id odoo技术
    3
    0 赞同
    3 帖子
    2k 浏览
    D
    哈哈,还真有人回应我的问题。 这句话是关键: 事实上你所定义的模型和字段也有自己的XML-ID的 你的截图中的XML-ID对应的是保存在res_partner表中的一条记录。而sale.field_sale_order__partner_id 对应的是保存在ir_model_fields表中的一条记录。 你现在应该能说得清这条记录的含义了吧?
  • Odoo多计量单位之发货篇

    odoo应用 多计量单位
    1
    0 赞同
    1 帖子
    1k 浏览
    D
    上回我们介绍了OCA的多计量单位模块,以及在销售订单上可以灵活选择主/辅两种计量单位下单的模块:https://shine-it.net/topic/5678/odoo的多计量单位 最近我们又把OCA的 sale_stock_secondary_unit 成功升级到了12.0。这个模块的用处是:当在订单中选择了辅助计量,则在对应发货单中可以使用辅助计量单位来发货。并且该模块的依赖模块:stock_secondary_unit 可以让你在查看库存时同时显示主、辅计量单位对应的库存量。
  • Odoo的Binary字段如何设置默认值?

    binary field odoo技术
    1
    0 赞同
    1 帖子
    1k 浏览
    D
    Odoo的Binary字段默认保存的是Base64转码后的字符串。那么我们该如何为Binary字段设置默认值呢?比如一个默认的图片。答案当然是将图片文件的内容用Base64转码后赋给这个字段的default属性。 方法1 : 比如你可以把一个图片用在线工具转码为Base64格式字符串: data:image/png;base64,iVRORw0KGgoBBBNSUhEUgAAAAEAAAABCAIAAACQd1PeAAAA..................... 去掉头部的data:image/png;base64,信息,把剩余的内容保存为默认值 DEFAULT_IMG = 'iVRORw0KGgoBBBNSUhEUgAAAAEAAAABCAIAAACQd1PeAAAA.....................' class MyModel(models.Model): _name = 'my.model' field_binary = fields.Binary(default=DEFAULT_IMG) 方法2: 将图片文件保存在模块目录下,比如: /my_module/static/img/my_image.png 设置默认值: import base64 from odoo import models, fields from odoo import modules def get_default_img(): with open(modules.get_module_resource('my_module', 'static/img', 'my_image.png'), 'rb') as f: return base64.b64encode(f.read()) class MyModel(models.Model): _name = 'my.model' field_binary = fields.Binary(default=get_default_img())
  • Odoo的Binary字段如何保存文件名

    odoo技术 binary field
    1
    0 赞同
    1 帖子
    1k 浏览
    D
    我们定义一个fields.Binary类型的字段就可以上传文件并保存。但是,这仅仅保存了文件的内容,下载时的文件的名称为该模型的名称而不是原上传文件的文件名。我们在代码中也无法引用该上传文件的文件名。那我们如何才能做到既保存上传文件的文件内容又保存其文件名呢? 首先, 我们要另外定义一个保存文件名的字符字段,比如 test_img = fields.Binary('Test Image') test_img_file_name = fields.Char('File name') 然后在视图中跟Binary字段做关联: <field name="test_img" filename="test_img_file_name"/> <field name="test_img_file_name" invisible="1"/>
  • 如何下载Odoo的Binary字段的文件内容

    binary field odoo技术
    1
    1
    0 赞同
    1 帖子
    1k 浏览
    D
    这个问题似乎很奇怪,当然是在对象表单视图的对应字段上点击那个下载按钮: [image: 1572574611168-image_btn.png] 但是,比如我有一个需求,需要创建一个下载所有的对象的Binary字段中的文件的页面,该如何做呢? 实际上对象上的Binary对象的链接是下面这样的: http://127.0.0.1:8069/web/content?model=<module_name>&field<field_name>&filename_field=<field_filename>&id=<object_id> 其中: module_name - Binary字段对应的模型名称 field_name - Binary字段的名称 object_id - 对应的记录id. field_filename - Binary字段对应的文件名称的字段(非必选项) 所以我们要创建一个按钮,点击下载文件的代码如下: file_url = "http://127.0.0.1:8069/web/content?model=<module_name>&field=<field_name>&filename_field=<field_filename>&id=<object_id>" return { 'type': 'ir.actions.act_url', 'url': file_url, 'target': 'new' } 而在Qweb报表或web页面中,我们可以这样处理: <t t-foreach="files" t-as="f"> <tr> <td><t t-esc="f.name"/></td> <td><a t-attf-href="/web/content?model=<module_name>&field=<field_name>&filename_field=<field_filename>&id=<object_id>">Download</a></td> </tr> </t>
  • 至死都被误解的ODOO的API

    api.one api.multi api.model
    1
    0 赞同
    1 帖子
    1k 浏览
    D
    api.one api.multi 已淘汰 首先需要澄清,随着当前最新的Odoo版本V13.0发布以后。 api.one 和 api.multi 作为Odoo的实体类方法的装饰器的用法已经淘汰。在V13.0以后的Odoo版本中使用这两个装饰器,系统会报错。 很多人会说,你这不是闲得没事干吗?讨论一个已经淘汰的语法应用有什么意义呢?其实,这些语法虽然被淘汰了,但是要知道最新版本的Odoo的实体类方法默认就是工作在过去 api.multi 这种模式下,而 api.model 也继续在工作。所以,我们对这些淘汰语法的讨论可以加深对当前新语法的认识。 api.one - Odoo最被误解的语法 api.one 的用法是Odoo中最被误解的一个。以至于到V9.0发布的时候Odoo就建议大家放弃吧,不要再乱用了, 全部用 api.multi 就好。如果不做点解释这个语法是妥妥的带着完全的误解走入坟墓的那个。 对这个装饰器的错误理解我认为主要是因为其名字的误导,而且还存在一个跟它相对的 api.multi 。所以,大多数的人的直觉就是认为 api.one 装饰的方法就是工作在只有单个Record的情况下。而事实是正相反, api.one 设计的初衷正是为了简化处理多实例的Record Set的。比如: class Category(models.Model): _name = 'test_new_api.category' name = fields.Char(required=True) parent = fields.Many2one('test_new_api.category', ondelete='cascade') display_name = fields.Char(compute='_compute_display_name', inverse='_inverse_display_name') @api.one @api.depends('name', 'parent.display_name') # this definition is recursive def _compute_display_name(self): if self.parent: self.display_name = self.parent.display_name + ' / ' + self.name else: self.display_name = self.name 在上面这个简单的例子中,display_name 是一个计算字段,作用是将所有上级分类的名称连接显示。当在分类对象的表单视图上时 self 就是单个记录,而在Tree视图时,self 就是包含多个记录的记录集。上面的例子如果换成 api.multi 的话就要保证方法内一定要做循环,否则在Tree视图时就会报错,也就是: @api.multi @api.depends('name', 'parent.display_name') # this definition is recursive def _compute_display_name(self): for rec in self: if rec.parent: rec.display_name = rec.parent.display_name + ' / ' + rec.name else: rec.display_name = rec.name 而 api.one 则可以**“假装”** self 是单条记录这样处理,装饰器会自动对记录集做循环,并将函数结果归集到列表中。这其实的确会让程序员省事不少,因为在Odoo中绝大多数情况类方法要考虑对多记录的循环处理的。所以因为起名不慎,导致了其早夭。以后开发者就老老实实的,不厌其烦的象上面这样循环吧。 api.multi 和 self.ensure_one() 比如下面的例子: @api.multi def action_done(self): self.ensure_one() self.state = 'done' .... 上面这段代码又是 multi (多个), 又是 ensure_one (保证一个) ,好分裂啊。可见,multi 并不是说我们都是工作在多实例的记录集上,而是既可能是单例记录也可能是多例记录集。比如上面例子中,这是一个表单上的确认按钮对应的方法,所以我们需要确保 self 只能是单例(否则就要做循环),这个 self.ensure_one 就是用来确保 self 不是多例的。 幸亏在V13之后我们不用再写 @api.multi 装饰器了,默认就是工作在它所指定的方式下。否则,这种分裂语言在Odoo中真的会触目惊心。 api.model 的用法 搞明白了上面的概念, api.model 就不复杂了。 api.model 使用的方法一直没有发生变化。上面的使用 api.one 或 api.multi 装饰器装饰的方法,或者最新的不带装饰器(实际就是 api.multi)的方法中的 self 都是记录集,就是model所对应的数据库表中的记录。而 api.model 所装饰的方法中的 self 是指model本身。比如: @api.model def create(self): ... def write(self): ... 上面 create 方法就要用 api.model 装饰,因为在调用 create 方法时还没有记录集呢。而 write 方法当然是对已有记录集的更新,所以不加装饰器(也就是隐性的 api.multi 装饰的方法)。 希望上面的解释对您理解Odoo的API有帮助。
  • Odoo的多计量单位

    secondaryunit 多计量单位
    1
    0 赞同
    1 帖子
    1k 浏览
    D
    Odoo并不具备真正意义的多计量单位管理功能。比如产品A的一箱包含20个产品,而产品B的一箱包含50公斤产品。这种形式的多计量单位需要第三方模块支持。OCA 的#product_secondary_unit# 就是这样的模块。我们最近也把#sale_order_secondary_unit#升级到了支持Odoo 12.0 : https://github.com/OCA/sale-workflow/pull/970 ,该模块用处就是在订单录入时可以选择主计量单位或者辅助计量单位,数量可以按照转换率互相转换