2020年2月27日 星期四

Odoo教育訓練學習筆記 (6)

  由於轉換職場跑道的緣故,許久沒有撰寫學習筆記或書摘心得等文章,原本自學內容以Python為核心,著重資料科學的技術與應用,但由於新工作的需求,必須轉而學習開放原始碼ERP系統-Odoo的開發,對於僅有類似系統分析經驗的我而言,這是非常難得的機會,可以讓我真正跨入系統工程師的領域。

  由於自己並非資訊相關科系畢業,基礎知識與技能相當貧乏,透過此次學習Odoo系統基礎建置與開發,我才初次接觸了如何在Windows系統透過VM來使用Linux系統,以及終端機指令的操作,來一步一步建置Odoo系統,包括所需的Python套件、PostgreSQL資料庫系統、pgAdmin資料庫管理工具、Odoo系統資料夾結構、Odoo系統設定文件、PyCharm整合開發環境、系統更新與維護方式等等,需要了解與學習的技術非常非常的多,自己也僅學習使用了一小部分的工具與技巧而已。

  系統開發由於牽涉到許多資料夾結構與不同文件如csvpyxml等,因此未來使用Git做為示範檔案存放空間的需求或許也將越來越迫切,現階段仍純粹在網誌整理、發布文章;本系列一共六篇學習筆記,為花費大量時間綜合整理Peter Wu老師課堂教學、《Odoo快速入門與實戰》簡體書,以及零散的網路教學文章而得,前五篇的學習筆記完全操作使用Odoo社群版,第六篇的學習筆記則加入「康虎雲報表」的安裝與教學,可至「康虎軟件工作室」官方網站下載相關軟體,配合學習筆記的說明來安裝使用。

  自學Odoo系統的建置開發相當不容易:在台灣,Odoo系統的知名度與普及性遠不如SAP、鼎新、Oracle等大廠,資訊廠商與開發人員的數量也相對稀少,就連參考書籍也完全沒有繁體中文的版本,僅有少數英文書與簡體書可以購買(而且這些書都寫得很糟),加上這幾年Odoo系統的快速發展,不同的版本之間有不小的變動,學會的技術可能過幾年就完全不能用了…。綜合上述許多原因,即便本系列學習筆記已經整理很清楚了,對於完全零經驗的開發者而言,相信仍舊難以閱讀、理解。

  目前Odoo系統在歐美與中國大陸的資源、社群與討論,都比台灣頻繁、密集得多,想要入門Odoo系統的學習者建議還是需要老師來帶領,才有辦法掌握操作、管理、開發的各項眉眉角角。

reports資料夾-康虎雲報表
l   習慣上,reports資料夾是一個獨立的Package,所有reports相關檔案皆放置於此。
l   Step 1安裝康虎雲報表Server工具(有分Odoo版本)
cfprint資料夾放在custom資料夾,並記得在終端機修改使用者群組,登入Odoo系統安裝後,可在Settings > Technical看到CFPrint


l   Step 2安裝康虎雲報表Client工具:
Windows系統將康虎雲報表zip檔解壓縮到選定的位置,點擊cfprint.exe並允許網路存取即可,設定方面建議選擇「預覽」、「開機自啟」、「最小化到系統托盤」等比較方便。


l   Step 3openacademy資料夾內修改__init__.py
#
原程式碼增加以下程式碼
from . import reports
l   Step 4reports資料夾內創建openacademy_studentclass_report.py
# -*- coding: utf-8 -*-
# Author: Peter Wu

from odoo import models, fields, api
from odoo.exceptions import UserError

# AbstractModel
用在離開畫面即清除資料的欄位
class openacademystudentclassreport(models.AbstractModel):
    _name = 'report.openacademy.studentclass_report'
   
    @api.model
    def _get_report_values(self, docids, data = None):
        docs = self.env['openacademy.studentclass'].browse(docids)
       
        res_doc = []
       
        #
蒐集母單資料
        for line in docs:
            line_doc = []
           
            #
蒐集子單資料
            for student_line in line.studentclass_line:
                if student_line.student_class == '1':
                    myclass = '
一年級'
                elif student_line.student_class == '2':
                    myclass = '
二年級'
                elif student_line.student_class == '3':
                    myclass = '
三年級'
                if student_line.student_fm == 'M':
                    myfm = '
'
                elif student_line.student_fm == 'F':
                    myfm = '
'
                if student_line.student_memo:
                    mymemo = student_line.student_memo.replace('\n','\\n')
                else:
                    mymemo = ' '
               
                line_temp = {
                    'student_no': student_line.student_no,
                    'student_name': student_line.student_name,
                    'student_contact': student_line.student_contact,
                    'student_class': myclass,
                    'student_fm': myfm,
                    'student_memo': mymemo}
                line_doc.append(line_temp)
           
            temp = {
                'studentclass_name': line.studentclass_name,
                'studentclass_teacher': line.studentclass_teacher.teacher_name,
                'studentclass_line': line_doc}
            res_doc.append(temp)
       
        docargs = {
            'doc_ids': docids,
            'doc_model': 'openacademy.studentclass',
            'docs': res_doc}
        return docargs
l   Step 5reports資料夾內創建__init__.py
# -*- coding: utf-8 -*-
# Author: Peter Wu

from . import openacademy_studentclass_report
l   Step 6reports資料夾內創建openacademy_report.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <report id="report_openacademy_studentclass_id"
            model="openacademy.studentclass"
            string="
學員班級報表"
            report_type="qweb-html"
            name="openacademy.studentclass_report"
            file="openacademy.studentclass_report"
            />
    </data>
</odoo>
l   Step 7reports資料夾內創建openacademy_studentclass_report.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <template id="studentclass_report">
            <t t-call="cfprint.html_container">
                <h1 class="col-12 text-center">
學員班級報表列印中...</h1>
                <h3 class="col-12 text-center">
列印中...,請等待...</h3>
                <script type="text/javascript">
                var cfprint_addr = "127.0.0.1";    //
列印伺服器監聽地址
                var _delay_close = -1;           //
列印完成後關閉視窗的延時時長(毫秒), -1則表示不關閉
                
                /*
定義主表結構*/
                var _tablestudentclass = {
                    "Name": "Studentclass",
                    "Cols": [
                        {"type": "str", "size": 20, "name": "studentclass_name", "required": false},
                        {"type": "str", "size": 50, "name": "studentclass_teacher", "required": false},
                    ],
                    "Data": [ ]
                };
               
                /*
定義從表結構*/
                var _tablestudentclassLines = {
                    "Name": "studentclassLines",
                    "Cols": [
                        {"type": "str", "size": 20, "name": "student_no", "required": false},
                        {"type": "str", "size": 20, "name": "student_name", "required": false},
                        {"type": "str", "size": 20, "name": "student_contact", "required": false},
                        {"type": "str", "size": 20, "name": "student_class", "required": false},
                        {"type": "str", "size": 10, "name": "student_fm", "required": false},
                        {"type": "str", "size": 500, "name": "student_memo", "required": false},
                    ],
                    "Data": [ ]
                };
               
                /*
增加主表記錄*/
                <t t-foreach="docs" t-as="o">
                    /*
如果t t-ifTrue,就執行t-esc的部分*/
                    _tablestudentclass.Data.push({
                    "studentclass_name":"<t t-if="o['studentclass_name']" t-esc="o['studentclass_name']"/>",
                    "studentclass_teacher":"<t t-if="o['studentclass_teacher']" t-esc="o['studentclass_teacher']"/>",
                    });
                    /*
增加從表記錄*/
                    <t t-foreach="o['studentclass_line']" t-as="lines">
                        _tablestudentclassLines.Data.push({
                        "student_no":"<t t-if="lines['student_no']" t-esc="lines['student_no']"/>",
                        "student_name":"<t t-if="lines['student_name']" t-esc="lines['student_name']"/>",
                        "student_contact":"<t t-if="lines['student_contact']" t-esc="lines['student_contact']"/>",
                        "student_class":"<t t-if="lines['student_class']" t-esc="lines['student_class']"/>",
                        "student_fm":"<t t-if="lines['student_fm']" t-esc="lines['student_fm']"/>",
                        "student_memo":"<t t-if="lines['student_memo']" t-esc="lines['student_memo']"/>",
                        });
                    </t>
                </t>
               
                var _data = {"template": "base64:<t t-esc="get_cf_template(user.env, 'studentclass_report')"/>", "ver": 4, "Copies": 1, "Duplex": 0, "Preview": 1, "Tables": []};
                _data["Tables"].push(_tablestudentclass);
                _data["Tables"].push(_tablestudentclassLines);
                var _reportData = JSON.stringify(_data);    //
轉成json字元串
                console.log(_reportData);
                //
生成資料之後,在cfprint_ext.js中會自動呼叫進行列印
                </script>
            </t>
        </template>
    </data>
</odoo>
l   Step 8openacademy資料夾內修改__manifest__.py
'data': [
    'reports/openacademy_report.xml',
    'reports/openacademy_studentclass_report.xml',
],
l   Step 9設定康虎雲報表模板:
Settings > Activate the developer mode
Settings > Technical > CFPrint Template Management > Create
Template IDName填入報表模型名稱,此例為studentclass_report,並將任一範例fr3檔上傳至Template


l   Step 10安裝或更新openacademy模組之後,回到Windows系統試著列印報表,此時會發生錯誤,請點選「設計」修改報表。


l   Step 11可開啟既有的範例報表來編輯,並點選「報表」 > 「資料」以選取報表資料集,重新編輯完成後請將fr3檔重新上傳至Template


l   Step 12回到Windows系統再次試著列印報表,若一切設定正確,應可看見預覽列印的成果。


Odoo設定
l   排程執行,Number of Calls-1表示執行次數無限:
Settings > Activate the developer mode
Settings > Technical > Scheduled Actions


l   序號規劃:
Settings > Activate the developer mode
Settings > Technical > Sequences


l   備份設定,Odoo 12 Community Version無此功能:
Settings > Activate the developer mode
Settings > Technical > Configure back-ups
l   Odoo Apps
https://apps.odoo.com/apps
有許多好用Apps,例如Muk系列的Muk Backend Theme

沒有留言:

張貼留言