Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
大多數框架一樣,odoo模型層也是 Odoo技術框架最核心的部分了。了解了它的編寫規則,可以說 Odoo的神秘面紗基本也會被掀開一半。
上面這是一段證書管理的 model 代碼,下面來詳細解釋下 model 層各個字段
01
創建模型
創建類繼承自 models.Model
_name : 創建 odoo模型內部標志符(數據表名稱,名稱以_連接存入數據庫),必須是全局唯一的
_description: 描述,方便用戶的模型記錄解釋
_inherit : 繼承 (設置繼承自另外那個表,可以進行字段方法的添加修改)
02
字段類型
可以定義字段的類型
1.Char :
單行文本
name=fields.Char(string=u'單據編號')
2.Text :
多行文本
note=fields.Text(u'備注')
3.Html:
存儲為帶格式的文本字段
html=fields.Html()
4.Datetime:
日期時間類型
date_order=fields.Datetime(string=u'訂單日期')
5.Date
delivery_date=fields.Date(u'交貨日期')
6.Selection:
下拉選擇列表(前一個參數是存儲在數據庫的值,后一個參數是前端展示的描述)
type=fields.Selection([ (u'default', u'默認')], string=u'類型', default=u'default')
7.Boolean:
布爾類型
active=fields.Boolean(default=True, string=u'是否歸檔')
8.Integer:
整型
sequence=fields.Integer(string=u'排序', default=10)
9.Binary:
存儲為二進制文件
files=fields.Binary(u'文件',filters='*.xlsx', required=True)
10.Float:
浮點型
amount=fields.Float(string=u'總計')
11.Monetary:
與浮點型類似,但帶有貨幣的特殊處理
price_subtotal=fields.Monetary(compute='_compute_amount', string=u'小計', readonly=True)
12.Many2one:
多對一
order_id=fields.Many2one('sale.order', string=u'銷售訂單', ondelete='cascade', index=True, copy=False)
13.One2many:
一對多
One2many 是一個一對多的關聯字段,與 Many2one 對應
order_line=fields.One2many('sale.order.line', 'order_id', string=u'銷售明細',states=READONLY_STATES,copy=True)
14.Many2many:
多對多
一本書可以有多個作者,一個作者可以有多本書class Book(models.Model):
author_ids=fields.Many2many(‘res.partner’, string=‘Authors’)
class Partner(models.Model):
book_ids=fields.Many2many(‘library.book’, string=‘Authored Books’)
03
字段屬性
# string 字段顯示名label,任意字符串
# help='str' 用于懸掛幫助信息提示
# readonly=True 本字段是否只讀,缺省值:False
# required=True 本字段是否必須的,缺省值:False。
# index=True 設置字段創建索引
# select=True 相關聯字段下拉列表
# default 設置字段的默認值
name=fields.Char(default="Unknown")
user_id=fields.Many2one('res.users', default=lambda self:self.env.user)
# states 定義特定state才生效的屬性,格式為:{'name_of_the_state': list_of_attributes},
其中list_of_attributes是形如[('name_of_attribute', value), ...]的tuples列表。
例子(參見account.transfer): 'partner_id': fields.many2one('res.partner', 'Partner',
states={'posted':[('readonly',True)]}),
# groups 設置權限組訪問可見,值為列表形式,元素是組的xml ids(也就是外部標識符)
# copy=False 設置字段不能被復制,普通字段是True, 在 one2many是默認是False
# oldname='field' 當一個字段在新版本重命名了,指定老的字段,老的字段的數據會自動拷貝到新的字段中
# compute 給定一個方法名計算出該字段
# inverse 給定一個方法名反轉該字段 (為了在計算字段設置值)
document=fields.Char(compute='_get_document', inverse='_set_document')
def _get_document(self):
for record in self:
with open(record.get_document_path) as f:
record.document=f.read()
def _set_document(self):
for record in self:
if not record.document: continue
with open(record.get_document_path()) as f:
f.write(record.document)
# search 給定一個方法名搜索該字段 (用在計算字段)
upper_name=field.Char(compute='_compute_upper', search='_search_upper')
def _search_upper(self, operator, value):
if operator=='like':
operator='ilike'
return [('name', operator, value)]
# store 設定該字段是否存在數據表中,在用了compute時為False ,其它默認是True
# compute_sudo 設定是否要超級用戶來計算該字段,默認是False
# related 序列的字段名,用于關聯字段,默認不存數據表中,可以store=True來存,
nickname=fields.Char(related='user_id.partner_id.name', store=True)
這里看出前面定義了user_id字段,這里是接著關聯到 user_id這個字段把所要的信息提取出來
# company_dependent 定義該字段是不是公司依賴
# change_default 別的字段的缺省值是否可依賴于本字段,缺省值為:False。
例子(參見res.partner.address) 'zip': fields.char('Zip', change_default=True, size=24),
這個例子中,可以根據zip的值設定其它字段的缺省值,例如,可以通過程序代碼,
如果zip為200000則city設為“上海”,如果zip為100000則city為“北京”。
# domain: 域條件,缺省值:[]。在many2many和many2one類型中,字段值是關聯表的id,
域條件用于過濾關聯表的record。例子: 'default_credit_account_id': fields.many2one('account.account',
'Default Credit Account', domain="[('type','!=','view')]"),
本例表示,本字段關聯到對象('account.account')中的,type不是'view'的record。
# context 上下文
# invisible: 本字段是否可見,即是否在界面上顯示本字段,缺省值True。
# selection: 只用于reference字段類型,參見前文reference的說明。
# size 只用于Char 設置可最大接收字符數
# translate=true 用于Text Char Html 本字段值(不是字段的顯示名)是否可翻譯,缺省值:False。
# ondelete 用于關聯字段,定義刪除方式
# manual
# deprecated=True 當用這個字段,日志會記錄警告,主要是版本升級一些過渡字段
# password="True" 密碼星號顯示
# nolabel="1" 隱藏標簽
# attr屬性 可以定義多條件這段只讀顯示
# digits 格式化浮點數
<field digits="(14,3)" name="volume" attrs="{readonly:[('type','=','service')]}"
# default_focus 新開窗口光標位置
# Widget 多種部件顯示格式 widget="one2many_list"
one2one_list, one2many_list, many2one_list, many2many,Url,Email,Image,float_time,reference
04
ORM裝飾器
@api.multi
默認裝飾器,如果我們需要自定義方法來對記錄集執行一些操作。用這個,方法的邏輯通常包括對 self 的遍歷
@api.one
用于操作單條記錄(單例),棄用了。用@api.multi,在代碼頂部添加一行 self.ensure_one(),來確保操作單條記錄
@api.model
類靜態方法,self作為模型的引用,無需包含實際記錄。注意,不能從用戶界面中的按鈕使用這種類型的方法。
@api.onchange(‘字段值')
當用戶編輯指定字段值時,立即執行一段業務邏輯。可用于執行驗證,向用戶顯示消息或修改表單中的其他字段
@api.depends(field1,...)
用于計算字段函數,用于確保(重新)計算改變被觸發
@api.constrains(field1,...)
用于驗證函數,用于確保哪些約束生效被觸發
以上~
隨著企業信息化不斷地深入和應用,無論大中小型企業,通過信息化甚至數智化,不斷提高企業內部的運營效率,人財物達到最優配置,從而不斷增加企業核心競爭力,有些行業領先的企業,要求管理層必須懂IT,一崗雙責,否則就無法勝任現有管理崗位,全員信息化或數字化。特別對于制造企業來說,業務隨著外部市場的變化也隨時需要更新升級系統,以符合最新的企業管理模式,從系統開發角度來說,如何隨需而變并進行快速響應用戶的需求,這個是一個現實又重要的課題,通過Odoo可以很好地支持業務隨時變化的需求,由于Odoo配置功能很強大,完成可以作為企業內部的低代碼開發平臺,筆者后續會針對Odoo寫一系列的文章進行一些經驗和實踐的分享。
什么是Odoo?Odoo由OpenERP發展而來,Odoo現在有一套完整的業務應用,滿足所有的業務需求,從網站/電子商務到制造,庫存和會計,所有的領域無縫集成。這是第一次一個軟件系統,被設計成能達到這么全面的功能覆蓋。Odoo的底層結構很強大,所有模塊都可以根據需要進行安裝和御載,所以客戶能像搭積木一樣建構自己期望的系統。即使完全不安裝與ERP相關的模塊,僅利用 Odoo 自身的底層框架,也能構建出適合各種用途的系統,純粹 B/S 架構。而這一切都是免費的,并且不受限于源代碼,也不受限于用戶數。
Odoo總部位于歐洲比利時,擁有1700名員工,11個全球辦事處和超過700萬的全球用戶。過去10年,每年的增長率超過50%。
Odoo的進化史,如下:
2005, TinyERP 1.0(2月), 2.0(5月),3.0(9月),基于 GPL協議。GPL,是GNU General Public License的縮寫,是GNU通用公共授權非正式的中文翻譯,AGPL是GPL的一個補充, 在GPL的基礎上加了一些限制。
2006, TinyERP 4.0(9月),仍然是GPL協議
----------------------第一次改名-------------------------------------------------
2009 OpenERP 5.0(4月),第一次重大改進,歷時三年時間。
2011 OpenERP 6.0(1月), 基本web 的客戶端,協議從GPL變為AGPL。
2012 OpenERP 6.2(2月), GTK客戶端停止開發,引入Ajax。
2012 OpenERP 7.0(12 ), 增強了可用性。
------------------------第二次改名---------------------------------------------------
2014 Odoo 8.0(10月) 重寫了倉庫和WMS,引入了電商、POS、BI。
2015 Odoo 9.0(10月) 開啟社區版和企業版雙版本戰略,社區版免費,企業版按用戶收費 費,LGPL協議。
2016 Odoo 10.0(10月) 重寫了 MRP模塊,引入 MPS\PLM 概念,企業版按用戶和模塊收費。
2017 Odoo 11.0(10月) 重寫了 Report,重寫了Studio,支持Python 3,提升了速度和性能。
2018 Odoo 12.0(10月) 引入 物聯網盒子,機器學習,報表設計器。
2019 Odoo 13.0(10月) 更強大的會計模塊,更令人驚嘆的網站設計,更實用的在線學習,更靈活地制造模塊管理。
2020 Odoo 14.0(10月) 從功能上來說,也確實在ERP核心功能之外的網站、電商、HR等方面有不少功能增添,同時引入了全新前端框架OWL。
2021 Odoo 15.0(10月) OWL表單2.0發布,電子表格實時提供ERP數據。公式助手、編輯欄、查找和替換等(企業版功能)。
Odoo 15是一系列開源商業應用程序套裝,此套裝可滿足中小型企業的一切應用需求,例如,企業基本的進銷存、采購、銷售、MRP生產制造、品保質量保障、企業招聘、員工合同、休假、午餐管理、內部論壇、車隊管理、內部聊天IM溝通、客訴追溯管理、CRM客戶關系管理、VOIP、E-Shop電子商務、網店、企業官方網站,財務會計、銀行對賬、資產管理、HR工資管理、預算管理、WMS倉庫庫存管理、POS街邊小攤、社區商店、項目管理、條碼、PLM等等。
從Odoo 11開始,定位不僅僅是開源ERP,已覆蓋到企業的CRM、PLM、WMS、HR等全領域,一個應用滿足所有中小企業需求,ODOO的應用界面,如下圖:
Odoo是基于開源技術進行構建的,數據庫采用開源老牌的數據庫Postgresql,開發語言基于目前主流的Python等一系列開源技術和產品,并構建成熟穩定的架構,提供了強大的配置,定制和在線開發工具,確保通用化產品和靈活定制之間的平衡。
PostgreSQL 的歷史簡介:
PostgreSQL是一個功能強大的開源對象關系數據庫系統,它使用并擴展了SQL語言,并結合了許多安全存儲和擴展最復雜數據工作負載的功能。PostgreSQL的起源可以追溯到1986年,作為加州大學伯克利分校POSTGRES項目的一部分,并在核心平臺上進行了30多年的積極開發。
PostgreSQL憑借其經過驗證的架構,可靠性,數據完整性,強大的功能集,可擴展性以及軟件背后的開源社區的奉獻精神贏得了良好的聲譽,以始終如一地提供高性能和創新的解決方案。PostgreSQL在所有主要操作系統上運行,自2001年以來一直是符合ACID標準的,并且具有強大的附加功能,例如流行的PostGIS地理空間數據庫擴展器。毫無疑問,PostgreSQL已經成為許多人和組織的首選開源關系數據庫。
開始使用PostgreSQL從未如此簡單 - 選擇您想要構建的項目,并讓PostgreSQL安全可靠地存儲您的數據。
Python:
1、 Python是一種計算機程序設計語言。是一種動態的、面向對象的腳本語言,最初被設計用于編寫自動化腳本(shell),隨著版本的不斷更新和語言新功能的添加,越來越多被用于獨立的、大型項目的開發。
2、Python就為我們提供了非常完善的基礎代碼庫,覆蓋了網絡、文件、GUI、數據庫、文本等大量內容,被形象地稱作“內置電池(batteries included)”。用 Python開發,許多功能不必從零編寫,直接使用現成的即可。
3、除了內置的庫外,Python還有大量的第三方庫,也就是別人開發的,供你直接使用的東西。當然,如果你開發的代碼通過很好的封裝,也可以作為第三方庫給別人使用。
4、許多大型網站就是用Python開發的,例如YouTube、Instagram,還有國內的豆瓣。很多大公司,包括Google、Yahoo等,甚至NASA(美國航空航天局)都大量地使用Python。
同時Odoo不僅具有10多年的發展歷史,Odoo官方每年都會發布更新一個大的全新版本,每次都會有很多新特性或新功能,而且具有強大的生態圈,目前Odoo官網的應用商店已超過3萬+擴展模塊插件,其中一半插件是完全免費的,同時Odoo社區OCA也提供了很多免費好用的插件,對于我來說,通過Odoo自帶的項目模塊,并通過下載一些項目相關的免費插件,像搭積木一樣構建了一個功能完整的項目管理系統,同時項目管理相關的一些報表是通過開發實現的,其他基本都是通過配置實現。
Odoo價格優勢:
在帶寬和服務器硬件允許的情況下,社區版沒有使用用戶數的限制,客戶端不用額外安裝軟件只要用新版的chrome瀏覽器或者firefox瀏覽器即可。
對于生產和大多數企業來說,二次開發本來就不可避免,由于有大量預開發模塊,Odoo在二次開發的速度和價格上有非常大的優勢。
即使金蝶,用友,Sap,甲骨文的ERP是免費的,一旦你需要二次開發,動輒幾十萬幾百萬甚至上千萬的價格還是讓很多企業承受不起。
相對很多軟件使用微軟的sql,微軟的Server系統和操作系統,微軟的office,這些軟件如果買正版,也是一筆不小的開銷。
很多企業雖然買了正版的用友,金蝶,但微軟的服務器系統,微軟的數據庫都是盜版,這為以后埋下不少隱患。
而Odoo用的服務器系統是Ubuntu Server他目前是自由免費的,PostgreSQL也是免費的。
如果自己找團隊去開發Odoo這樣一套系統,估計至少20個人開發5年,也就是差不多至少300萬的開銷。
投資成本分析 | |||
傳統ERP項目 | Odoo企業版 | Odoo社區版 | |
咨詢培訓 | 數萬 | 低 | 低 |
軟件許可 | 10-100萬 | 每月12-72美元 | 免費 |
軟件升級 | 3-30萬 | 無 | 無 或 低 |
年服務費 | 合同15-30% | 無 | 無 或 低 |
實現 | 合同65% - 75% | 無 | 合同65% - 75% |
Odoo產品優勢:
Odoo的前端用了較多的Javascript代碼,這樣保證了用戶體驗較好:輸入關鍵字即出現的產品及聯系人選項,大大提高了操作速度,(有不少軟件都需要多操作一步搜索)。
非常強大的過濾及高級搜索功能 可以根據電話號碼地址等字段搜索,可以根據客戶或者產品來索引出此客戶或者產品的銷售情況,服務情況 。
方便查看各類單據了解產品的成本,售價的變化。比如可以顯示現有庫存量,查看產品的所有采購情況。
快速上線:不像其他軟件,必須弄很多初始數據,有些初始數據比如產品名,會計期初帳OpenERP可以在后期慢慢弄,
更直觀的數據:具有柱狀,餅狀,雷達,曲線等 直觀的數據透視圖表顯示,有些模塊還具有甘特圖。
Odoo技術優勢:
B/S(瀏覽器-服務器)架構(方便了更新和二次開發),跨操作系統方面很有優勢,平板,手機默認都可以用。采用Module為開發單元,采用MVC的架構,支持繼承。B/S架構,支持各種操作系統和瀏覽器。
先進的數據庫PostgreSQL,先進的語言Python,大量的預開發代碼可以實現快速進行二次開發。
可以部署在云端(企業可以自己建云,建立一個更大的數據庫)云計算特性很容易能把上下游整個供應鏈的資源都整合到Odoo中來。(通過更改Odoo設置還可以開放客戶接口和供應商接口)
內置了社交系統:消息系統。并在各個模塊都擁有非常靈活的搜索和高級搜索界面。
Odoo開源優勢:
幾十人的團隊開發十多年(目前官方團隊有1700多人,至少還大約有6000名志愿者參與,用戶數量超過700萬)。
模塊齊全,涵蓋了個人助理,企業內部交流,客戶關系管理CRM,進銷存管理,生產管理,人力資源管理等等(以8.0來說目前已有4000多個功能模塊已經適合絕大多數企業),并且Odoo不斷的有新功能和新模塊來適應更多的企業去運用。
它還是個很好的二次開發的平臺,如果你不需要其自帶的模塊,你完全可以按照官方模塊的寫法,寫自己的模塊。
流程設計合理,除了初始化的數據(產品,客戶,供應商)及少數單據(報價單,銷售訂單),大部分單據(出入庫單,會計憑證)都是系統自動生成,只需要對應的人員進行核查及確認即可,大大降低了工作強度和出錯幾率。
單據的流程可以根據企業的實際情況定制和修改,可以在系統里面改變工作流程滿足企業需求。
具有多語言,多幣種,對于貿易類企業OE現有的模塊基本可以滿足企業90%或更多的應用需求。
雖然是開源軟件,Odoo8.0依然是個長期支持的版本,基本每天都有更新,修復各種漏洞,截止2013年已經有200萬用戶下載了Odoo。成功案例估計成千上萬其中不乏美國AT&T ,法國電信,達能集團這樣的巨型公司。
請大家點擊左上角關注+評論,也歡迎私信跟我交流!
順便幫忙轉發一下
ir.actions.client 是odoo actions事件的一種,觸發一個在客戶端實現(即js文件中定義的函數,通過core.action_registry.add(tag,函數名) 注冊到odoo中)動作
在 項目目錄/static/src/js 建立 m_custome_list.js 文件
odoo.define('custom_page.demo', function (require) {
"use strict";
var AbstractAction=require('web.AbstractAction');
var core=require('web.core');
var CustomPageDemo=AbstractAction.extend({
// 對某個類關聯click事件
events: {'click .demo-submit': '_onSubmitClick',
'click .db_add_data': '_onAddData'},
// 初始化,可以在action 里傳入參數
init: function (parent, action, option) {
// 保存傳遞的參數
this.params=action.params;
this._super.apply(this, arguments);
},
// 渲染視圖
renderElement: function () {
this._super.apply(this, arguments);
// 渲染qwb 視圖,并傳值
this.$('.o_content').html(
core.qweb.render('DemoPage',
{'params':this.params}));
},
_onSubmitClick: function (e) {
e.stopPropagation();
alert('Submit clicked!');
},
// 添加一條數據
_onAddData: (e)=> {
e.stopPropagation();
window.alert('添加成功');
},
});
// add方法對動作進行注冊,第一個參數表示注冊的動作名,
第二個參數是要注冊的動作對象;
core.action_registry
.add('custom_page.demo',CustomPageDemo);
return CustomPageDemo;
});
在 項目目錄/static/src/xml 建立 m_custome_list.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="DemoPage">
<div style="margin:0 auto;
text-align:center;"class="o_content">
<table class="table table-striped">
<tr>
<th>標題</th>
<th>內容</th>
<th>創建日期</th>
</tr>
<t t-foreach="params.contentList" t-as="item">
<tr>
<td><t t-esc="item.title"/></td>
<td><t t-esc="item.content"/></td>
<td><t t-esc="item.date"/></td>
</tr>
</t>
</table>
<button type="button"
class="db_add_data btn btn-primary">增加數據</button>
</div>
</t>
</templates>
model 調用client方法, 在model關聯的xml視圖頁面,增加一個按鈕,綁定show_list方法,也可以在任何方法中返回client和返回actions.window 一樣
def show_list(self):
content_list=[
{'title': '內容一', 'content': '我是內容一一,
在想看看1', 'date': '2021-08-08'},
{'title': '內容二', 'content': '我是內容二二,
在想看看2', 'date': '2021-08-09'},
{'title': '內容三', 'content': '我是內容三三,
在想看看3', 'date': '2021-08-10'},
{'title': '內容四', 'content': '我是內容四四,
在想看看4', 'date': '2021-08-11'},
]
info={
'title': '測試列表循環',
'contentList': content_list
}
return {
'type': 'ir.actions.client',
'name': '列表信息',
'tag': 'custom_page.demo',
# custom_page.demo就是前面js中定義的事件名
'params': info,
'target': 'new',
}
在 項目目錄/views/ 建立 js_and_css.xml 文件, 用來加載自己寫的js,別忘了在mainfast.py 中加載這個js_and_css.xml
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<template id="assets_end"
inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script src="/customtree/static/
src/js/m_custome_list.js"
type="text/javascript"/>
</xpath>
</template>
</odoo>
*請認真填寫需求信息,我們會在24小時內與您取得聯系。