การรวม Commits Github

การรวม Commits Github

การรวม Commits Github

การเก็บ source code ในปัจจุบัน ส่วนใหญ่จะเก็บไว้ที่ cloud service ซึ่งก็มีผู้ให้บริการที่หลากหลาย อย่างเช่น git ซึ่งในการพัฒนา code จะต้องมีการส่ง source code ขึ้นไปและระบบจะเก็บ history ไว้ ฟังแล้วก็ดูดี แต่ถ้าหาก source code ชุดนั้นมีการพัฒนามาหลายปีแล้ว แน่นอนว่า history ของ source code นั้นก็จะยาวมาก และคนที่อยากดู history ของ source code ชุดนี้ก็คงจะปวดหัวไม่น้อย หรือเราอาจจะมีการส่ง source code ไปแล้ว แต่พึ่งเจอว่าเป็นบัค ก็จะต้องแก้ไขแล้วส่งเพิ่มไปอีก หากยังเจออีกก็ต้องแก้แล้วส่งไปอีก ซึ่งการพัฒนา code ควรจะส่งเป็นหัวข้อ หัวข้อละ 1 commit เพื่อให้ง่ายในการหาและทำความเข้าใจ

Credit : https://medium.com/corrado-cavalli/squash-commits-in-visual-studio-b469ef021436

จากรูปคือบทสรุปของเนื้อหาบทนี้

  • จุดสีขาว คือ Master
  • จุดสีฟ้า คือ การแก้ไข code แล้วมีการ commit ขึ้นไปยัง Master ซึ่งในตัวอย่างคือมีการ commit 3 ครั้ง แต่ใน 3 ครั้งนี้อาจจะเป็นเรื่องเดียวกันแต่แก้ไขของ commit ก่อนหน้านี้จนมี 3 commit ก่อนที่จะ merge code ในส่วนของชุดนี้ก็ควรจะทำการรวม commit ทั้ง 3 commits เข้าด้วยกันเป็นเรื่องเดียว
วิธีการรวม commits ให้เหลือ commit เดียว โดยใช้คำสั่งใน terminal (Ubuntu)
# git rebase -i <REPO : ORIGIN>/<BRANCH : MASTER>

จะเห็น commit ที่ผ่านมาของ source code นั้น

หากต้องการที่จะรวม 2 commits ล่างสุดให้เหลือ commit เดียว ให้เปลี่ยนจากคำว่า pick เป็น s หรือ squash เพื่อทำการ commit รวมกับ commit ก่อนหน้า

จากนั้นกดออก (ctrl + x) ระบบจะทำการรวม commit ที่ใส่ข้อความ s กับ commit ก่อนหน้าให้ โดยจะขึ้นให้เลือกว่าต้องการที่จะใช้ชื่อ commit ไหน

จากนั้นให้กดออกและ save อีกทีหนึ่ง ระบบจะทำการวม commit ให้
ตรวจสอบดูอีกครั้ง จะพบว่า commit !fixup ได้ถูกรวมกับ commit ก่อนหน้าเรียบร้อยแล้ว

เพียงเท่านี้ commit ที่เราแก้ไขหลาย commit ก็จะถูกรวมเหลือเพียง 1 commit เท่านั้น

การใช้งาน Restful API

การใช้งาน Restful API

การใช้งาน Restful API

หลายคนคงรู้จักกับ Web Service API ในลักษณะของ XMLRPC หรือ JSONRPC มาบ้างจากเอกสารของ Odoo
https://www.odoo.com/documentation/13.0/webservices/odoo.html

แต่ในปัจจุบัน Restful API เป็นที่นิยมใช้กันมากกว่า แม้ว่าจะไม่อยู่ใน Odoo ตามมาตรฐาน OCA ก็มีคำตอบให้เราเหมือนเช่นเคย 🙂

ด้วย OCA Restful Framework – https://github.com/OCA/rest-framework

  • base_rest :: เป็นโมดูลพื้นฐานที่สามารถนำไปสร้าง RESTFUL API ได้อย่างง่ายๆ
  • base_rest_demo :: ตัวอย่างในการสร้าง ทั้งแบบ public และ private API
  • Youtube และ Slide
โดยหลังจากที่ติดั้งโมดูลทั้งสองระบบจะมี Icon REST api ซึ่งจะแสดงหน้าต่างการทดสอบ API ทั้งหมดที่มี Odoo ได้ทันที

สำหรับตัวอย่างเต็มสำหรับ partner ลองดูได้ที่ไฟล์ base_rest_demo/services/partner_services.py ซึ่งหากเราลองทำโดยเลียนแบบก็จะไม่ได้ยากอะไร แต่ผมมีข้อสังเกตุเพิ่มเติมดังนี้
  • REST API ทำงานได้กับทั้ง GET, POST, PUT และ DELETE แต่หากลองทำเราจะได้เห็นว่า สำหรับ method GET ระบบจะให้ใช้ได้กับ เฉพาะ get กับ search เท่านั้น ทั้งนี้เป็นเพราะการเขียน route ไว้ที่นี่ https://github.com/OCA/rest-framework/tree/12.0/base_rest#usage โดยให้ดูในส่วน ResController
  • ทุก API จะต้องมีการเขียน function _validate กำกับไว้ด้วยเพื่อให้แน่ใจว่าได้ schema ทั้ง input และ output ตามชุดข้อมูลที่ควรเป็น
  • ในโหมดปกติจะไม่มี detailed error message เวลาเกิดปัญหา ถ้าต้องการให้รันใน debug mode โดยประกาศไว้ที่ Odoo config file
[base_rest]
dev_mode=True
  • สำหรับ private method การ authenticate ทำได้ตามตัวอย่างนี้
import requests

# create a session
sess = requests.session()

# login into odoo
data = {"jsonrpc": "2.0", "method": "call", "params": {"db":"odoo-base_rest_product","login":"admin","password":"admin"}}
sess.post('http://localhost:8069/web/session/authenticate', json=data)

# use this session to call your services (in this case I've a product service implementing search withour required params)
res = sess.get('http://localhost:8069/rest_api/private/product/search')
print(res.json())
ตอนนี้คงไม่ได้เขียนลงรายละเอียดมากนักนะครับ เพราะตัวโมดูลเอง และตัวอย่างก็ดูค่อนง่ายอยู่แล้ว หากได้ใช้งานในเคสจริง และมีข้อสังเกตุเพิ่มเติมจะนำมาใส่ไว้ตอนนี้
การหยิบยืม commit จากคนอื่นใน github (cherry-pick)

การหยิบยืม commit จากคนอื่นใน github (cherry-pick)

การหยิบยืม commit จากคนอื่นใน github (cherry-pick)

credit : http://pilpag.blogspot.com/2016/04/cherry-pick-what-amazing-command.html

การทำ Cherry-pick ใน git อาจจะเป็นเรื่องที่หลายๆคนไม่รู้จัก หรือไม่ค่อยได้ใช้ แต่ประโยชน์ของมันค่อนข้างเยอะ อย่างเช่น ใช้ในการ update code ของผู้อื่นที่เป็น contributor เข้า project ของเราโดยที่ไม่ต้อง copy/ paste code ซึ่งมีโอกาสผิดพลาดได้

ตัวอย่างการใช้ cherry-pick

Credit : https://www.farreachinc.com/blog/far-reach/2017/03/16/git-cherry-pick-why-and-how

จากตัวอย่าง Node H คือ code ล่าสุดของ Production ส่วนของนักพัฒนาจะเป็น code ที่กำลังพัฒนา

สมมติไปเจอ code ของคนอื่น(Node I) โดยปกติแล้วหากต้องการใช้ code ส่วนนี้ จะต้องทำการ copy มาวางที่ code ของเรา ซึ่งมีโอกาส copy ได้ไม่ครบ หาก I มีการแก้ไขเยอะ ทำให้ระบบ error หรือเกิด bug ได้ ฉะนั้นวิธีการแก้คือการใช้ cherry-pick จาก I เข้าสู่ C โดยที่จะมั่นใจได้ว่า C จะมี code ที่ copy มาจาก I + code ที่แก้ไขใน D

วิธีการใช้งาน จากตัวอย่างการ Migration Source Code OCA
สมมติว่าเรากำลัง Migration Module hr_calendar_rest_time จาก version 12 ไป version 13
pr : https://github.com/OCA/hr/tree/12.0/hr_calendar_rest_time

แต่มีคนแก้ไข bug บางอย่างใน version 12 และยังไม่ถูก merge เข้า master
pr : https://github.com/OCA/hr/pull/803

วิธีแก้โดยปกติแล้วก็คงใช้การ copy/paste code ที่มีการแก้ไขเข้า code ของเราโดยตรงเลย แต่ปัญหาที่จะเกิดขึ้นตามมาคือ ใน version 13 จะไม่มี commit ของคนที่แก้ไข code นี้
โดย commit ที่ควรจะเป็นควรจะเป็นอย่างนี้
[12.0][MIG] hr_calendar_rest_time    –> version 12 ก่อนแก้ไข
[12.0][FIX] hr_calendar_rest_time     –> version 12 แก้ไขบัค
[13.0][MIG] hr_calendar_rest_time    –> version 13

แต่ถ้าเรา copy/paste code ของเขามาวางใน version 13 ของเราเลยจะกลายเป็นแบบนี้
[12.0][MIG] hr_calendar_rest_time    –> version 12 ก่อนแก้ไข
[13.0][MIG] hr_calendar_rest_time    –> version 13 (แก้ไขแล้วแต่ไม่มี commit แก้ไข)

และเราไม่สามารถใช้ git pull ได้ เพราะว่า code ที่แก้ไขยังไม่ถูก merge เข้า master
ฉะนั้นวิธีแก้ไขสำหรับกรณีนี้คือการใช้ cherry-pick commit [12.0][FIX] hr_calendar_rest_time มาใส่ใน code ของเราที่เป็น version 13 โดยมีขั้นตอนดังนี้

  1. ทำการ migration code ขึ้น version 13 ตามปกติก่อน จะได้ commit ดังนี้
    [12.0][MIG] hr_calendar_rest_time    –> version 12
    [13.0][MIG] hr_calendar_rest_time    –> version 13
  2. เมื่อพบเจอการแก้บัคที่ version 12 แต่ยังไม่ถูก merge เข้า master ให้ remote ไปที่ branch ของเจ้าของก่อน แล้วใช้ fetch เพื่อ update branch ให้เป็นล่าสุด
    # git remote add <name> <url git> (git remote add tegin https://github.com/tegin/hr.git)
    # git fetch <name> (git fetch tegin)
  3. เลือก commit ที่ต้องการใช้ และ copy หมายเลข commit
  4. # git cherry-pick <name>/<commit>
    (git cherry-pick tegin/0fb171f2c2b3cb96de6d566b377032dd4a17df46)
    เพียงเท่านี้ ระบบก็จะไป copy code จาก commit ที่เราเลือกมาใส่ใน branch ของเราเรียบร้อย โดยจะมีการเรียงลำดับดังนี้
    [12.0][MIG] hr_calendar_rest_time    –> version 12
    [13.0][MIG] hr_calendar_rest_time    –> version 13
    [12.0][FIX] hr_calendar_rest_time     –> cherry-pick

    หากต้องการให้เรียงสวยงามจะต้องทำการ cherry-pick ก่อนแก้ไข version 13

กรณีที่ใช้ cherry-pick แล้วเกิด conflict file ให้แก้ไขก่อนแล้วใช้คำสั่ง
# git cherry-pick –continue
ถ้ายัง conflict file ให้แก้ไขเหมือนเดิมแล้วใช้คำสั่งวนไปเรื่อยๆ สาเหตุเกิดจาก code บางส่วนที่ cherry-pick มากับที่เราแก้ไขมีการ conflict กัน
https://ecosoft-odoo.blogspot.com/2020/03/commit-github-cherry-pick.html
การเขียน Code Python ให้มีประสิทธิภาพ

การเขียน Code Python ให้มีประสิทธิภาพ

การเขียน Code Python ให้มีประสิทธิภาพ

Python Language เป็นภาษาสมัยใหม่ที่สามารถเข้าใจได้ไม่ยากนัก มีรูปแบบการเขียนที่คล้ายภาษามนุษย์ จึงทำให้ปัจจุบันภาษา Python ค่อนข้างเป็นที่นิยมสำหรับการเริ่มต้นเขียน Program แต่สิ่งหนึ่งที่เป็นสิ่งสำคัญและ programmer ส่วนใหญ่อาจจะยังไม่ค่อยสนใจเท่าที่ควร นั่นคือ การเขียน code ให้มีประสิทธิภาพ (Performance Turning) สาเหตุอาจจะเป็นเพราะการทดสอบระบบที่มีข้อมูลน้อย หรือไม่ซับซ้อนมากนัก ทำให้ยังไม่เห็นความสำคัญมากเท่าที่ควร
หากข้อมูลเริ่มมีขนาดที่ใหญ่ขึ้น เวลาการทำงานของระบบก็จะยาวนานตามไปด้วย ทำให้ผลกระทบถูกส่งต่อเป็นทอดๆ เพื่อแก้ไขปัญหานี้ควรจะเขียน code ให้มีประสิทธิภาพตั้งแต่ต้นจะช่วยเราประหยัดเวลาได้เยอะเลยทีเดียว
การวน Loops
สิ่งที่แทบทุกคนน่าจะรู้จัก ใช้กันเยอะที่สุดและมีปัญหาความเร็วตรงส่วนนี้มากที่สุด คือการวน for loop แต่การวน for loop บางครั้งเราสามารถใช้คำสั่งอื่นเพื่อให้มีประสิทธิภาพได้
Straightforward
ส่วนใหญ่แล้วน่าจะคุ้นชินกับการใช้ for loop ด้วยวิธีนี้ เพราะเป็นวิธีที่ง่ายที่สุด
def test_straightforward(oldlist):
    newlist = []
    for word in oldlist:
        newlist.append(word.upper())

List comprehensions

วิธีนี้จะคล้ายกับก่อนหน้านี้ เพียงแต่กำหนดให้เป็น list อยู่แล้วจึงไม่ต้องใช้ append
def test_list_comprehensions(oldlist):
    newlist = [word.upper() for word in oldlist]
Generator Expressions
วิธีนี้เขียนคล้ายกับ List comprehensions แต่ return ค่าเป็น generator object

def test_list_comprehensions(oldlist):
    newlist = (word.upper() for word in oldlist)

Map
วิธีนี้จะใช้ได้เมื่อเราอยากให้ทุกค่าถูกเปลี่ยนด้วยหลักเดียวกัน เช่น แปลง string ให้เป็นตัวพิมพ์ใหญ่ทุกตัว

def test_map(oldlist):
    newlist = map(str.upper, oldlist)

ทดสอบเวลาการทำงาน

จะเห็นว่า function map จะทำงานได้เร็วที่สุด แต่ทั้งนี้ทั้งนั้น ขึ้นอยู่กับการใช้งานจริงในแต่ละงานมากกว่า เช่น map ถึงแม้จะมีความเร็วมาก แต่ก็เหมาะกับการใช้งานที่จำกัด และประยุกต์ใช้ค่อนข้างยากกว่า function อื่น หรือ Straightforward ที่ช้าที่สุดแต่มีความยืดหยุ่นมาก จึงเหมาะสำหรับการทำบางอย่างให้แต่ละค่าที่ไม่เหมือนกัน

หลีกเลี่ยงการใช้จุดใน for loop
การวน for loop หากเราใช้ function เดียวกันซ้ำๆ ไม่จำเป็นที่จะต้องเขียน function ใน loops เพื่อลดการทำงานของระบบได้ อย่างเช่น ตัวอย่าง Straightforward จะเห็นว่ามีการใช้ .append ซ้ำกันทุกครั้ง หากเป็นปกติแล้วระบบจะต้องเรียก append ทุก loops ยิ่งมีเยอะก็ยิ่งช้า ฉะนั้นวิธีแก้ไขคือเรียกใช้ append ไว้ตั้งแต่ก่อนวน loops และ upper ที่มีการทำซ้ำทุก loops

def test_straightforward(oldlist):
    newlist = []
    upper = str.upper
    append = newlist.append
    for word in oldlist:
        append(upper())

ทดสอบเวลาการทำงาน

จะสังเกตว่าการใช้ dot ใน for loops จะไม่ค่อยเห็นผล หากข้อมูลไม่ได้มีการ loops ที่เยอะ ฉะนั้นขึ้นอยู่กับการใช้งานของแต่ละคนมากกว่า


การ loops นอก function หลัก
การเรียก function ใน loops เป็นสิ่งหนึ่งที่มีผลกับความเร็ว

def new_function(word):
    return word.upper()

def main(oldlist):
    newlist = []
    for word in oldlist:
        newlist.append(new_function(word))

จากตัวอย่างด้านบนระบบจะต้อง loops แต่ละครั้งและเรียก function new_function ทุก loops ทำให้ 1 loop เรียก 1 function ถ้ามี 100 loops ก็ต้องเรียก 100 function วิธีแก้คือการ สร้าง function ใหม่และส่งค่าที่ต้องการวน loops เข้าไปด้วย เพื่อวน loops ใน function ใหม่ทีเดียว

def new_function(oldlist):
    newlist = []
    for word in oldlist:
        newlist.append(word.upper())
    return newlist

def main(oldlist):
    newlist = new_function(oldlist)

ทดสอบเวลาการทำงาน

การใช้ continue ใน loops เพื่อลดการทำงาน
ในการวน loops บางค่าเราอาจจะไม่จำเป็นต้องทำ แต่เพราะอยู่ใน loops เลยหลีกเลี่ยงไม่ได้ ซึ่งวิธีแก้ไขคือการใช้ continue เพื่อข้ามการทำงานนี้ไป ก่อนจะใช้ continue จะต้องมั่นใจก่อนว่าค่าข้างใน loops เราจำเป็นต้องใช้หรือไม่ เพราะการใช้ continue ไม่ถูกจังหวะอาจจะทำให้ค่าที่เราต้องการเปลี่ยนแปลงไปได้

ตัวอย่าง
การใช้ continue ก่อนที่จะทำ function จะทำให้ x มีค่าเท่ากับ จำนวนใน wdict ที่มี word

def loops_continue_before(words):
    wdict = {}
    x = 0
    for word in words:
        if word not in wdict:
            continue
        x += 1

การใช้ continue หลังจากทำ function จะทำให้ x มีค่าเท่ากับจำนวนใน words

def loops_continue_after(words):
    wdict = {}
    x = 0
    for word in words:
        x += 1
        if word not in wdict:
            continue

ทดสอบเวลาการทำงาน

ทั้งนี้ทั้งนั้นขึ้นอยู่กับการใช้งานของแต่ละคนว่าควรจะใช้ continue (หรือ return, break) ในจังหวะไหน แต่ควรใช้ให้อยู่บนที่สุดเท่าที่จะทำได้ เพื่อลดการทำงาน function อื่นๆที่ไม่จำเป็น

การสร้างค่าโดยใช้ Dictionary แบบมีเงื่อนไข
เปรียบเทียบวิธีการเขียน loops สร้าง ค่าใน dictionary โดยมีเงื่อนไขตามที่เราต้องการ โดยจะมีวิธีการสร้างได้หลากหลายวิธี ซึ่งแต่ละวิธีจะได้ผลลัพธ์เหมือนกัน แต่ประสิทธิภาพแตกต่างกัน

การสร้างค่าโดยใช้ Condition

def create_dict_if(words):
    wdict = {}
    for word in words:
        if word not in wdict:
            wdict[word] = 0
        wdict[word] += 1

วิธีแรก การตรวจสอบเงื่อนไข หากไม่ตรงกันก็จะไม่ต้องทำ function ภายใน ซึ่งจะช่วยลดภาระในการทำงานบางส่วนที่ไม่จำเป็นได้

การสร้างค่าโดยใช้ Try Catch

def create_dict_try_catch(words):
    wdict = {}
    for word in words:
        try:
            wdict[word] += 1
        except KeyError:
            wdict[word] = 1

วิธีที่สอง การใช้ try catch ซึ่งระบบจะเริ่มต้นทำ try ก่อน แต่เมื่อทำแล้วเกิด error ตามที่เขียนไว้ใน except ระบบก็จะเปลี่ยนมาทำใน except แทน วิธีนี้จะเป็นการแก้ไข error แบบกว้างๆ

การสร้างค่าโดย get จากค่าเดิม

def create_dict_get(word):
    wdict = {}
    get = wdict.get
    for word in words:
        wdict[word] = get(word, 0) + 1

วิธีนี้จะเขียนค่อนข้างง่าย คือ การดึงค่าเดิมมาบวกกับค่าใหม่ ซึ่งหากค่าเดิมไม่มีค่าก็จะ get 0 มาแทน

การสร้างค่าโดยใช้ Defaultdict

from collections import defaultdict

def create_dict_defaultdict(word):
    wdict = defaultdict(int)
    for word in words:
        wdict[word] += 1

วิธีนี้จะใช้ package ของ python ในการช่วย lookup data ที่เราต้องการใน dict ก่อน ถ้าไม่มีก็จะ return 0 เก็บใน wdict แล้วใช้วิธีวน loops เพื่อเพิ่มค่าเข้าไปอีกครั้งหนึ่ง

ทดสอบเวลาการทำงาน

Try catch จะทำงานได้ช้าสุด เพราะว่า ต้องทำใน try ก่อน หากไม่สำเร็จก็จะต้องกลับมาทำ except อีกรอบหนึ่ง จึงเหมือนระบบทำงาน 2 ครั้ง แต่ถ้ากรณีที่ไม่ต้องเข้า except ก็จะทำงานได้เร็วขึ้น แต่ไม่เท่ากับการใช้ get

Odoo Database Manager

Odoo Database Manager

Odoo Database Manager

ในบทความนี้ ผมจะแนะนำ odoo database manager ซึ่งสามารถเข้าได้โดยการคลิก Manage Databases บนหน้า login

ผู้อ่านจะเห็น button ทั้งหมด 6 button คือ Create Database, Backup Database, Restore Database, Duplicate Database, Delete Database, Set Master Password โดยผมอธิบายแต่ละ button ดังนี้

1. Create Database
เมื่อผู้อ่านทำการคลิก Create Database ระบบจะขึ้นหน้า pop up ให้ใส่ข้อมูลเกี่ยวกับ new database ดังรูป

  • Master Password คือ master password ของ odoo
  • Database Name คือ ชื่อ database ที่ทำการสร้าง
  • Email คือ user name ของ admin user
  • Password คือ password ของ admin user
  • Phone number คือ หมายเลขโทรศัพท์ของ Company
  • Language คือ ภาษาที่ถูกติดตั้งโดย default ตอนสร้าง new database
  • Country คือ Country ของ Company ซึ่งระบบจะทำการ config ค่าบางอย่าง เช่น company currency
  • Demo data คือ demo data บนระบบ ถ้าทำการเลือก ตอนที่ install module และมี demo data ระบบจะโหลดเข้ามาด้วย เหมาะกับการ test ก่อนขึ้น production
หลังจากใส่ข้อมูลเรียบร้อยให้ทำการคลิก Continue ระบบจะ redirect ไปที่หน้า login odoo ดังรูป
ข้อมูลที่ใส่ก็จะปรากฎใน Users & Companies
2. Backup Database
เมื่อผู้อ่านทำการคลิก Backup ระบบจะขึ้นหน้า pop up ให้ใส่ Master Password และ Backup Format มี 2 ตัวเลือกคือ zip (includes filestore) และ pg_dump custom format (without filestore) ซึ่งส่วนตัวผมแนะนำ Backup Format แบบ zip มากกว่า pg_dump เพราะว่าสามารถดูดพวก file store ลงมา และ restore กลับเข้าไปได้
จากนั้นคลิก Backup และให้ผู้อ่านทำการ save file เข้าไปใน directory ที่ต้องการ
ถ้าเข้าไปดู database file (zip) ที่ backup ลงมาจะเห็นทั้ง filestore และ database file (sql)
3. Restore Database
เมื่อผู้อ่านทำการคลิก Restore Database ระบบจะขึ้นหน้า pop up ให้ใส่ Master Password, Database file และ Database Name ดังรูป
จากนั้นคลิก Continue ระบบจะทำการ restore database ขึ้นมา
4. Duplicate Database
เมื่อผู้อ่านทำการคลิก Duplicate ระบบจะขึ้นหน้า pop up ให้ใส่ข้อมูล Master Password และชื่อ database ที่ต้องการสร้าง (New Name)
จากนั้นคลิก Continue ผู้อ่านจะเห็น database ที่เพิ่มขึ้นมา
5. Delete Database
เมื่อผู้อ่านทำการคลิก Delete ระบบจะขึ้น pop up ให้ใส่ Master Password
จากนั้นคลิก Delete ระบบจะลบ database นั้นทิ้ง
6. Set Master Password
เมื่อผู้อ่านทำการคลิก Set Master Password ระบบจะขึ้นหน้า pop up ให้ใส่รหัสผ่านใหม่ (New Master Password) และรหัสผ่านเดิม (Master Password)
การแปลงตัวเลขเป็นตัวหนังสือใน odoo13 (python)

การแปลงตัวเลขเป็นตัวหนังสือใน odoo13 (python)

การแปลงตัวเลขเป็นตัวหนังสือใน odoo13 (python)

Python Language มี package สำหรับการแปลงตัวเลขเป็นตัวหนังสือ นั่นคือ num2words ซึ่งรองรับภาษาไทยตั้งแต่ version 0.5.7 ขึ้นไป สำหรับ odoo มีการใช้ package นี้ร่วมด้วย ซึ่งอยู่ใน function amount_to_text ของสกุลเงิน (res.currency)

วิธีการใช้งาน amount_to_text ใน odoo13
1. Upgrade package num2word version 0.5.7 ขึ้นไป (Core odoo จะ default ที่ version 0.5.6)
2. Install module l10n_th_amount_text
3. เรียกใช้งานผ่าน res.currency หากต้องการภาษาไทยให้ส่ง context : ‘lang’ = ‘th_TH’ ไปด้วย

ตัวอย่างการแปลงตัวเลขด้วย qweb

<t t-foreach="docs" t-as="o">
    <t t-set="currency_id" t-value="o.currency_id"/>
    <t t-esc="currency_id.with_context({'lang': 'th_TH'}).amount_to_text(45.75)"/>
<t>
– ถ้าต้องการให้ระบบแปลงเป็นภาษาอังกฤษ ไม่ต้องใส่  with_context
– สกุลเงินขึ้นอยู่กับ currency นั้นๆ
– l10n_th_amount_to_text รองรับการแปลงสกุลเงินต่างประเทศ 2 สกุลเงิน คือ USD และ EUR
กรณีใส่ with_context

สกุลเงินไทย         : “สี่สิบห้าบาทเจ็ดสิบห้าสตางค์”

สกุลเงินยูโร         : “สี่สิบห้ายูโรเจ็ดสิบห้าเซนต์”
สกุลเงินดอลลาร์ : “สี่สิบห้าดอลลาร์เจ็ดสิบห้าเซนต์”
กรณีไม่ใส่ with_context

สกุลเงินไทย         : “Forty-Five Baht Seventy-Five Satang”

สกุลเงินยูโร         : “Forty-Five Euros Seventy-Five Cents”
สกุลเงินดอลลาร์ : “Forty-Five Dollors Seventy-Five Cents”
การใช้ Function เดิมจาก Odoo

ใน odoo13 จะมีการแปลงตัวเลขเป็นตัวหนังสือ ซึ่งระบบจะอิงจากภาษาของ User แต่จะมีการแปลงที่ผิดเพี้ยน

ตัวอย่าง การใช้ Function amount_to_text ดั้งเดิม : สกุลเงินภาษาไทย
– User ที่มีการตั้งค่าเป็นภาษาไทย      : “สี่สิบห้า Baht และ เจ็ดสิบห้า Satang”
    – User ที่มีการตั้งค่าเป็นภาษาอังกฤษ : “Forty-Five Baht and Seventy-Five Satang”

จะสังเกตเห็นว่า ระบบจะแปลงตัวหนังสือเป็นภาษาไทยถูกต้อง แต่สกุลเงินที่ระบบจะแสดงเป็นภาษาอังกฤษ ซึ่งส่วนนี้มาจาก Database เก็บสกุลเงินเป็นภาษาอังกฤษ เลยทำให้ระบบแปลงออกมาผสมทั้ง 2 ภาษา ดังนั้น module l10n_th_amount_to_text จึงทำมาเพื่อแก้ไขในส่วนของสกุลเงินให้ถูกต้อง

การแสดง Sequence ในระบบ Odoo เป็น พ.ศ.

การแสดง Sequence ในระบบ Odoo เป็น พ.ศ.

การแสดง Sequence ในระบบ Odoo เป็น พ.ศ.

Source Code : https://github.com/OCA/server-ux/pull/177

การแสดงปีในระบบ Odoo จะใช้ปีคริสต์ศักราช (ค.ศ.) ซึ่งเป็นปีสากล แต่ในหลาย ๆ ประเทศอาจใช้ปีอื่นที่ไม่ใช่ ค.ศ. อย่างเช่น พุทธศักราช (พ.ศ.), ฮิจเราะห์ศักราช (ฮ.ศ.) และ อื่น ๆ ฉะนั้นโมดูล
sequence_display_year จะช่วยในการแสดงปีในรูปแบบที่เรากำหนดได้

การตั้งค่าเพื่อกำหนดปีศักราช
  1. ไปที่เมนู Settings > Technical > Sequence & Identifiers > Sequences
  2. เลือก sequence ที่ต้องการให้ระบบแสดงเป็นปีอื่น ๆ
  3. ที่ Number Of Year ให้ใส่ตัวเลขที่ต้องการ +/- กับปี ค.ศ. เช่น
    – พ.ศ. ให้ใส่ 543 ระบบจะแสดงผลเป็นปีพุทธศักราช 2563 (2020 + 543 = 2563)
    – ฮ.ศ. ให้ใส่ -579 ระบบจะแสดงผลเป็นปีฮิจเราะห์ศักราช 1441 (2020 – 579 = 1441)

หากมีการสร้างเอกสารด้วย sequence นั้น และกำหนด prefix ด้วยปี ระบบจะนำตัวเลขจาก Number Of Year ไป +/- กับปี ค.ศ. ออกมาเป็นปีที่เราต้องการให้ระบบแสดงผล
เพียงเท่านี้การออกเลขเอกสารก็จะใช้ปีศักราชได้ตามที่เราตั้งค่าแล้ว สำหรับปีในส่วนอื่น ๆ จะยังคงเป็นปี ค.ศ. อยู่เช่นเดิม
https://ecosoft-odoo.blogspot.com/2020/07/sequence-odoo.html
การทำภาษีหัก ณ ที่จ่าย (Withholding Tax) ในระบบ Odoo13

การทำภาษีหัก ณ ที่จ่าย (Withholding Tax) ในระบบ Odoo13

การทำภาษีหัก ณ ที่จ่าย (Withholding Tax) ในระบบ Odoo13

Source Code :
Withholding Tax – การทำภาษีหัก ณ ที่จ่ายในระบบ
Withholding Tax Multi – การทำภาษีหัก ณ ที่จ่าย กรณีมีภาษีมากกว่า 1 บรรทัด
Withholding Tax Cert – การทำเอกสารใบกำกับภาษี ณ ที่จ่ายในระบบ
Withholding Tax Cert Form – การออกเอกสารใบกำกับภาษี ณ ที่จ่าย (ใบ 50 ทวิ)
Withholding Tax Report – การออกรายงานใบกำกับภาษี ณ ที่จ่าย
ความหมายของ ภาษีหัก ณ ที่จ่าย
ในระบบ odoo มาตรฐานจะมีการรองรับ withholding tax อยู่แล้ว แต่ไม่ครอบคลุมกับการทำภาษีหัก ณ ที่จ่ายของประเทศไทย ดังนั้นจึงต้องมีการติดตั้ง module เพิ่มเติม ซึ่ง module ที่จำเป็นในการออกภาษี ณ ที่จ่ายจะมีอยู่ 3 module ได้แก่
  1. Withholding Tax
  2. Withholding Tax Cert
  3. Withholding Tax Cert Form
ส่วนที่เหลือจะเป็นส่วนที่เพิ่มเติมขึ้นมา ใช้สำหรับบางกรณี อาจจะติดตั้งหรือไม่ก็ได้

การตั้งค่า / สร้างเอกสารภาษีหัก ณ ที่จ่าย

ให้ติดตั้ง module Withholding Tax และ Withholding Tax Cert จาก source code ด้านบน
เมื่อติดตั้งเสร็จสิ้น ระบบจะสามารถตั้งค่าเลือก Account ที่ต้องการให้เป็น Withholding Tax ได้ เผื่อกรณีที่ต้องการให้ระบบหักภาษี ณ ที่จ่ายแบบอัตโนมัติ โดยมีวิธีดังนี้ (Optional)
  1. ไปที่เมนู Invoicing > Configuration > Accounting > Chart of Accounts
  2. เลือก Account ที่ต้องการให้ทำเป็น Withholding Tax > ติ๊กถูกที่ Field WT Account
  3. ไปที่เมนู Invoicing > Configuration > Invoicing > Withholding Tax
  4. สร้างเอกสารใหม่ แล้วกำหนดค่าต่าง ๆ ที่ต้องการหักภาษี > Save

    – Name : ชื่อที่จะแสดง
    – Amount : ร้อยละที่ต้องการหักภาษี
    – Withholding Tax Account : account ที่เป็น withholding tax เท่านั้น (กำหนดจากข้อ 2)

ในกรณีที่ต้องการให้ระบบคำนวณภาษี เมื่อเลือกสินค้าที่ต้องการ สามารถตั้งค่าได้ดังนี้
  1. ไปที่เมนู Invoicing > Vendors > Products
  2. เลือก Product ที่ต้องการหักภาษี ณ ที่จ่าย
  3. คลิก Purchase Tab > เลือก Withholding Tax > Save
หมายเหตุ : หากไม่เลือก WT Account ระบบไม่คำนวณการหักภาษี ณ ที่จ่ายให้อัตโนมัติ แต่สามารถให้ผู้ใช้งานเป็นคนกรอกข้อมูลในส่วนนี้ได้

ขั้นตอนการทำภาษีหัก ณ ที่จ่ายในระบบ

กระบวนการทำภาษีหัก ณ ที่จ่ายสามารถทำได้ที่หน้า Payment กับ Journal Entries (สร้างตรง)
กรณีที่มีการทำภาษีหัก ณ ที่จ่ายมากกว่า 1 บรรทัดในเอกสาร 1 ใบ
จะต้องติดตั้ง module Withholding Tax Multi เพื่อให้ระบบสามารถทำภาษีได้มากกว่า 1
 

การทำภาษีหัก ณ ที่จ่ายที่หน้า Payment

 สามารถให้ระบบคำนวณให้อัตโนมัติ หรือจะคำนวณเองก็ได้ ถ้าต้องการคำนวณเองไม่ต้องทำข้อ 3 และ 4  ซึ่งขั้นตอนการคำนวณภาษีที่หน้า Payment จะมีดังนี้

    1. ไปที่เมนู Invoicing > Vendors > Bills
    2. สร้างเอกสารที่ทำการซื้อและมีภาษีหัก ณ ที่จ่าย
    3. คลิกที่ 3 จุดตรง Invoice Lines > แสดง WT
    4. เลือก WT ที่ต้องการจากการตั้งค่าก่อนหน้านี้ ในกรณีที่มีการตั้งค่า Withholding Tax ใน Product นั้น ระบบจะเลือก WT ให้อัตโนมัติ
    5. Save > Post > Register Payment
    6. ระบบจะคำนวณตัวเลขให้อัตโนมัติ ในกรณีที่คำนวณเองให้ใส่จำนวนหลังหักภาษีที่ช่อง Amount และส่วนต่างให้เลือก Account Withholding Tax
      1. กรณีที่ Invoices มีภาษีหัก ณ ที่จ่ายตัวเดียว ระบบจะเลือก Mark invoice as fully paid
      2. กรณีที่ Invoices มีภาษีหัก ณ ที่จ่ายมากกว่า 1 และติดตั้ง module Withholding Tax Multi ระบบจะเลือก Mark invoice as fully paid (multi deduct) หากต้องการคำนวณเองแบบมี Withholding Tax มากกว่า 1 สามารถทำได้โดยการติดตั้ง module https://github.com/OCA/account-payment/tree/13.0/account_payment_multi_deduction แทน module Withholding Tax Multi
        ตัวอย่างเอกสารที่มี Withholding Tax มากกว่า 1
    7. Validate
    8. ไปที่เมนู Invoicing > Vendors > Payments > เลือกเอกสารที่ทำรายการ
    9. คลิกปุ่ม Action > Create Withholding Tax Cert.
    10. ระบบจะเลือก Account Withholding Tax ให้อัตโนมัติ ในกรณีที่มีการตั้งค่าไว้ แต่ถ้าไม่มีผู้ใช้งานจะต้องเลือก Account เอง > Create
    11. ระบบจะสร้างภาษีหัก ณ ที่จ่ายให้ แล้วให้ผู้ใช้งานกรอกข้อมูลในส่วนที่ต้องการให้ครบ
    12. Save > Done

การทำภาษีหัก ณ ที่จ่ายที่หน้า Journal Entries

ในบางครั้งอาจมีกรณีที่มีภาษีหัก ณ ที่จ่าย โดยที่ไม่ได้มาจาก Vendor Bills ก็สามารถทำได้ แต่ระบบจะไม่มีการคำนวณให้อัตโนมัติ โดยจะมีขั้นตอนดังนี้

    1. ไปที่เมนู Invoicing > Accounting > Miscellaneous > Journal Entries
    2. สร้าง / เลือก เอกสารที่มี Journal Type เป็น Miscellaneous เท่านั้น
    3. คลิกปุ่ม Action > Create Withholding Tax Cert.
    4. เลือก Account Withholding Tax > Create
    5. ระบบจะสร้างภาษีหัก ณ ที่จ่ายให้ แล้วให้ผู้ใช้งานกรอกข้อมูลในส่วนที่ต้องการให้ครบ
    6. Save > Done

การออก Withholding Tax Cert ทดแทนใบเดิม

ระบบสามารถออก Withholding Tax Cert ใบใหม่ทดแทนเอกสารใบเดิมได้ โดยมีขั้นตอนดังนี้

 

    1. สร้างเอกสารใหม่ที่ถูกต้องและทำ Withholding Tax แบบปกติ
    2. คลิกปุ่ม Action > Create Withholding Tax Cert.
    3. เลือก Substitute > เลือกเอกสาร Withholding Tax ใบที่ผิดพลาด โดยจะต้องมีสถานะเป็น Done เท่านั้น > Create
    4. ระบบจะสร้างภาษีหัก ณ ที่จ่ายให้ แล้วให้ผู้ใช้งานกรอกข้อมูลในส่วนที่ต้องการให้ครบ
    5.  Save > เมื่อคลิกปุ่ม Done ระบบจะไปยกเลิกเอกสารใบเก่าให้
 

การเรียกดูเอกสาร Withholding Tax สามารถดูได้ที่เมนู Invoicing > Vendors > WT Certificates ซึ่งการทำที่หน้า Payment หรือ Journal Entries ในระบบจะออกเอกสารที่เดียวกัน

การออกหนังสือรับรองการหักภาษี ณ ที่จ่าย (ใบ 50 ทวิ)

หลังจากทำภาษีหัก ณ ที่จ่ายในระบบเสร็จเรียบร้อยแล้ว จะต้องมีการยื่นหนังสือรับรองการหักภาษี ณ ที่จ่าย (ใบ 50 ทวิ) ให้กรมสรรพกร ซึ่งในระบบ Odoo จะใช้ฟอร์มมาตรฐานที่ทางสรรพกรกำหนด โดยมีขั้นตอนดังนี้
  1. ติดตั้ง module Withholding Tax Cert Form จาก source code ด้านบน
  2. ไปที่เมนู Invoicing > Vendors > WT Certificates
  3. เลือกเอกสารที่ต้องการออกหนังสือรับรอง > คลิกปุ่ม Print > Withholding Cert (pdf)
เมื่อ Print Withholding Tax Cert ที่มีสถานะยกเลิก (State ‘Cancelled’) ระบบจะแสดงข้อความ “ยกเลิก” คาดกลางเอกสาร
เมื่อ Print Withholding Tax Cert ที่เป็นใบทดแทนใบเดิมจะมีข้อความด้านบนขวากำกับว่า “ออกแทนเอกสารเลขที่ ……………’
หมายเหตุ : ข้อที่ให้ระบุข้อความ สามารถใส่ได้ที่ Income Description

การออกรายงานการหักภาษี ณ ที่จ่าย

สำหรับผู้บริหาร หรือนักบัญชีที่ต้องการดูรายละเอียดการทำรายการภาษีหัก ณ ที่จ่าย สามารถทำได้โดยมีขั้นตอนดังนี้
  1. ติดตั้ง module Withholding Tax Report จาก source code ด้านบน
  2. ไปที่เมนู Invocing > Reporting > WT Income Tax Report
  3. เลือกประเภทเอกสารที่ต้องการดู (ปัจจุบันรองรับเฉพาะ PND3, PND53 เท่านั้น) และช่วงเวลา
  4. เลือกประเภทรายงานที่ต้องการ โดยจะมีอยู่ 4 ประเภทคือ

    – View : แสดงข้อมูลในระบบ Odoo
    – Export PDF : แสดงข้อมูลเป็นไฟล์ PDF
    – Export XLSX : แสดงข้อมูลเป็นไฟล์ XLSX
    – Export TXT : แสดงข้อมูลเป็นไฟล์ TEXT

หมายเหตุ รายงานที่เป็น Text File ในส่วนของ ที่อยู่ จะออกตามการตั้งค่าในระบบ โดยสามารถแก้ไขได้ที่เมนู Contacts > Configuration > Localization > Countries > Layout in Reports

ในส่วนของการทำภาษีหัก ณ ที่จ่ายด้วยระบบ Odoo สำหรับประเทศไทยจะมีหลักการและขั้นตอนประมาณนี้ หากผู้อ่านมี idea ที่เหมาะสมสำหรับการพัฒนาการทำงานให้ดีขึ้น สามารถเสนอ และเปิด Issue ใหม่ได้ที่ https://github.com/OCA/l10n-thailand/issues

https://ecosoft-odoo.blogspot.com/2020/09/withholding-tax-odoo.html

ตรวจสอบข้อมูลบนหน้าเอกสารด้วยโมดูล Base Exception

ตรวจสอบข้อมูลบนหน้าเอกสารด้วยโมดูล Base Exception

ตรวจสอบข้อมูลบนหน้าเอกสารด้วยโมดูล Base Exception

ระหว่างที่กำลังทำ Code Review ให้กับโมดูลใน OCA ได้เห็นโมดูลชุดนึงชื่อแปลกๆเช่น base_exception, purchase_exception, sale_exception เพิ่งจะได้มีโอกาสมารีวิวรู้สึกว่ามันเจ๋งดีเลยอยากเอามาแชร์

เป็นเหมือนกันไม๊ครับ เวลาทำระบบให้ลูกค้า ลูกค้ามักจะขอให้เพิ่มการตรวจสอบค่าต่างๆบนหน้าเอกสารต่างๆก่อนการยืนยัน  ยากบ้าง ง่ายบ้าง เช่น ให้ Purchase Order ต้องมีการใส่วันกำหนดส่งเสมอ, Sales Order ให้ช่วยเตือนหากเผลอบันทึกราคาเป็นศูนย์ หรือให้ช่วยเช็คด้วยว่า Partner ที่เลือกมีตั้ง email ไว้หรือไม่

ซึ่งการตรวจสอบเหล่านี้เป็นหนึ่งในเรื่องที่เราต้องเขียนโค้ดเพิ่มเติม อาจเขียน Python และ raise ValidationError เมื่อทดสอบไม่ผ่าน หรือเขียนปรับ View ให้ required=True และอื่นๆอีก บ่อยครั้งที่ logic เหล่านี้กระจัดกระจายไปตามโมดูลต่างๆที่เราเขียนเพิ่ม

** ไม่นับว่าการ raise Exception เหล่านี้จะทำให้เกิดปัญหาในการ import ข้อมูลเข้าระบบด้วย เพราะมันจะไม่ผ่านการ Import Check ตั้งแต่ต้น

ซึ่งโมดูลที่ผมกำลังจะเล่าให้ฟังนี้น่าจะช่วยแก้ปัญหานี้ได้โดยตรง เราไปทดสอบพร้อมๆกันเลยครับ

สมมุติผมต้องการจัดการการ Validation บนหน้าต่าง Purchase Order โมดูลที่ผมต้องใช้คือ

 

  • base_exception :: abstract module สำหรับ extend ไปยังโมเดลต่างๆ
  • purchase_exception :: extend base_exception สำหรับ purchase.order, purchase.order.line

Note: โหลดได้จาก https://odoo-community.org/shop

การตั้งค่า

หลังจากติดตั้งแล้วให้ไปที่เซตสิทธิ์ผู้ใช้งานเป็น Exception Manager แล้วเข้าไปที่ Menu: Settings > Technical > Exception Rules

Exception Rules จะมีตัวอย่างให้ 2 rules โดยเราสามารถเพิ่มได้เองภายหลัง

โดยการเซต Rule เราสามารถทำได้ทั้งแบบกำหนด Domain (เช่น [(‘product_qty’, ‘<‘, 0)]) หรือเขียนเป็น python code ซึ่งจะยืดหยุ่นมากกว่า

ตัวอย่างเช่น Quantity not negative คือไม่ต้องการให้ Quantity บน Purchase Order Line ติดลบ ตัวอย่างนี้ใช้ Python code

การใช้งาน

ถึงตอนใช้งาน สมมุติเราสร้าง Purchase Order โดยใส่ Quantity แบบติดลบ และเลือก Partner ที่ยังไม่เซต email เมื่อทำการ Confirm Order ระบบจะแสดงปัญหาทั้งหมดที่ตรวจสอบเจอ

หากเลือกปล่อยผ่านด้วย Ignore Exception เอกสารนี้ก็จะถูก Confirm ได้ตามปกติ แต่ถ้าไม่ปล่อยผ่าน เอกสารนี้ก็จะยังค้างอยู่ที่ Draft และมีการขึ้นคำเตือนให้ที่หน้าเอกสาร ทั้งบน Form และ List View ซึ่งจะสะดวกสำหรับการมาปรับแก้ในภายหลังอีกด้วย

เป็นไงครับ กับโมดูลเล็กๆจาก OCA ที่น่าจะมีประโยชน์ไม่น้อยทีเดียว ผมคงต้องลองเอาไปใช้ในโปรเจคที่จะทำบ้างแล้ว น่าจะช่วยประหยัดเวลา และให้งานเป็นระเบียบได้ดีเลยครับ 🙂

Field Service Management (FSM) ด้วย Odoo

Field Service Management (FSM) ด้วย Odoo

Source Code: https://github.com/OCA/field-service

อย่างที่เราทราบกัน เมื่อรวมข้อดีของความเป็น Open Source บวกกับความยืดหยุ่นของ Platform แบบ Modular ของ Odoo ทำให้เกิดนวัตกรรมมากมาย รวมไปถึงฟีเจอร์ใหม่ๆเพื่อต่อยอดภาคธุรกิจได้แทบไม่มีข้อจำกัด

ถ้าพูดถึงธุรกิจทุกวันนี้ที่แข่งขันกันอย่างดุเดือด ปัจจัยที่จะให้บริษัทอยู่เหนือกว่าคู่แข่งแทบจะหนีไม่พ้นการบริการหลังการขาย เพราะสินค้าและราคาอาจไม่ต่างกัน ความแตกต่างจะวัดกันที่การบริการ วันนี้เราจะมาพูดถึงอีกโมดูลสำคัญที่ต่อยอด Odoo ERP ให้ตอบความท้ายนี้ นั่นคือ Field Service Management (FSM) หนึ่งในโมดูลคุณภาพจาก OCA

Field Service Management (FSM) คืออะไร?

FSM เกี่ยวข้องกับการส่งมอบสิ้นค้าอย่างมีคุณภาพ บริการที่ทันใจ และบริการหลังการขายที่ยอดเยี่ยม ในมุมของลูกค้า ประสพการณ์โดยรวมที่ได้รับจากผู้ขายเป็นสิ่งสำคัญ เมื่อบริษัทยังไม่ใหญ่มาก การให้บริการที่ดีอาจไม่ใช่เรื่องยาก แต่เมื่อธุรกิจเติบใหญ่ ทีมงานก็เติบโต การควบคุมประสิทธิภาพและคุณภาพของการดูแลลูกค้าให้คู่ไปกับการเติบโตไม่ใช่เรื่องง่ายเลย ไหนจะเรื่องประกันสินค้า การส่งต่องาน การจัดลำดับงาน หรือเส้นทางการขนส่งที่มีประสิทธิภาพ

องค์กรที่ไม่ได้คิดเรื่องการบริหารเชิงสารสนเทศอย่างเป็นระบบมาตั้งแต่ต้น เมื่อเติบโตขึ้นมักเจอกับอุปสรรคสำคัญนี้ ระบบไอทีทางด้าน Field Service ที่ดีจะช่วยเชื่อมโยงเรื่องราวต่างๆที่เคยแยกจากกัน เรียงร้อยเป็น Business Process ขององค์การ ที่สามารถมองเห็นข้อมูลได้แบบทันที และสามารถใส่การควบคุมเข้าไปตามจุดสำคัญๆ

ระบบ Field Service Management ที่ดีต้องไม่ใช่ระบบโดดเดี่ยว แต่ต้องสามารถเชื่อมโยงเป็นหนึ่งเดียวกับระบบ ERP, CRM, WMS และอื่นๆ เพื่อให้การทำงานทั้งระบบไม่สะดุดและลดการป้อนข้อมูลซ้ำซ้อน

วงจรการทำงานที่ดีของ Field Service Management ประกอบไปด้วย:

  • การเตรียมความพร้อม (Strategic Planning)  ความรวดเร็วในการสั่งการ การจัดการทรัพยากรให้พร้อมทั้งบุคลากรและสินค้าคงคลัง พร้อมเสมอเมื่อลูกค้าเรียกหา
  • การวางแผนงาน (Tactical Planning) — ระบบช่วยด้านการวางแผนงานที่ซับซ้อนเพื่อลดความผิดพลาดหรือการออกงานซ้ำซ้อน
  • การดำเนินงานและการปรับแผน (Operations) — ระบบอาจช่วยทำงานส่วนใหญ่เช่นการวางแผนเส้นทาง การขัดลำดับความสำคัญ ในขณะเดียวกันระบบก็ต้องพร้อมเสมอสำหรับการเปลี่ยนแปลงหน้างานจากเหตุการณ์ที่ไม่คาดคิด
  • การวิเคราะห์ข้อมูลย้อนกลับ (Analysis) — สามารถใช้ข้อมูลและประวัติการทำงาน ทำรายงานเชิงวิเคราะห์ เพื่อให้เห็นข้อผิดพลาดและปรับปรุงการทำงานให้ดีขึ้น

การทำงานทั้งหมดนี้หาได้จาก Odoo ERP + FSM โมดูล ซึ่งได้รับการออกแบบใช้งานและปรับปรุงจาก ผู้ใช้งานจริงทั่วโลก และด้วยความเป็น Open Source Software ไม่มีการจำกัดด้าน License หมดห่วงเรื่องการขยายทีมงานในอนาคต การเตรียมความพร้อมและความใส่ใจแต่เนิ่นๆจะช่วยให้ธุรกิจเติบโตได้อย่างมั่นคง และ FSM คือหนึ่งในตัวช่วยนั้น ได้ยินแบบนี้แล้วจะต้องรออะไร :

ที่มา : https://ecosoft-odoo.blogspot.com/2019/05/field-service-management-fsm-odoo.html