Install
openclaw skills install @minhduongqngai/taohopdongTạo hợp đồng: tra cứu thông tin doanh nghiệp từ masothue.com và ghi vào Google Sheet (sheet Hợp đồng). Use when user asks to: tra cứu mã số thuế, ghi thông tin công ty vào sheet, tạo hợp đồng, thêm dữ liệu doanh nghiệp từ masothue, hoặc yêu cầu format: "MST + Số tiền + Dịch vụ" để điền sheet.
openclaw skills install @minhduongqngai/taohopdongTra cứu thông tin doanh nghiệp từ masothue.com và ghi vào Google Sheet Hợp đồng.
Yêu cầu:
gogCLI đã authenticated, envGOG_ACCOUNTđược set, và Odoo connector sẵn sàng (~/clawd/skills/odoo-connector).
(gid:)| Cột | Nội dung | Ví dụ |
|---|---|---|
| A | Mã (MST) | 0316863281 |
| C | Mã hợp đồng | W231224/SEO |
| D | Tên doanh nghiệp | CÔNG TY CP CN WIFIM |
| E | Địa chỉ | ... |
| F | Mã số thuế | 00316863281 |
| G | Người đại diện | Nguyễn Lê Minh Dương |
| H | SĐT | (trống nếu không có) |
| I | Số tiền | 14.000.000 |
| J | Dịch vụ | SEO |
Dùng gog để đọc/ghi sheet. Set env GOG_ACCOUNT trước:
export GOG_ACCOUNT=""
Đọc dữ liệu hiện có:
gog sheets get "Hợp đồng!A4:J" --json --no-input
Ghi (cập nhật specific range):
gog sheets update \
"Hợp đồng!A5:J5" \
--values-json '[["0312712411","","W231224/SEO","TÊN CÔNG TY","Địa chỉ","0312712411","NGƯỜI ĐD","","14.000.000","SEO"]]' \
--input USER_ENTERED \
--no-input
Lưu ý:
gogtự xử lý encoding tên sheet tiếng Việt, không cần URL-encode thủ công.
User có thể cung cấp thông tin theo các format sau:
Link masothue.com đầy đủ: `
Chỉ MST (tự động ghép URL):
0314927902 → https://masothue.com/{mst}
Cú pháp đầy đủ 1 dòng:
{Mã HĐ} {URL/MST} {Số tiền} {Dịch vụ}
Ví dụ: W231224/SEO https://masothue.com/0314927902... 14.000.000 SEO
https://masothue.com/Search/?q={mst}&type=masothue
→ web_fetch sẽ tự redirect sang slug đúngLưu ý: URL trần
https://masothue.com/{mst}(chỉ số) không redirect — sẽ 404. Luôn dùng search URL hoặc slug đầy đủ.
Dùng web_fetch với URL masothue (search URL hoặc full slug). Parse kết quả để lấy:
| Field | Pattern trong web_fetch output |
|---|---|
| Tên công ty | Dòng đầu tiên sau title (thường là tên in hoa) |
| Mã số thuế | Dòng có Mã số thuế → value bên dưới |
| Địa chỉ | Dòng Địa chỉ (không phải Địa chỉ Thuế) → value |
| Người đại diện | Dòng có Người đại diện → tên trong [] |
Ưu tiên Địa chỉ (address thật) hơn Địa chỉ Thuế (tax address).
Dùng gog để đọc dữ liệu hiện tại:
gog sheets get "Hợp đồng!A4:J" --json --no-input
Tìm dòng cuối có dữ liệu trong cột A (MST). Dòng tiếp theo là rowNum = lastRow + 1.
Ghi range Hợp đồng!A{rowNum}:J{rowNum} với:
values = [[
mst, # A - Mã (MST)
"", # B - (nếu có)
ma_hop_dong, # C - Mã hợp đồng
ten_cong_ty, # D - Tên doanh nghiệp
dia_chi, # E - Địa chỉ
mst, # F - Mã số thuế (lặp lại)
nguoi_dai_dien,# G - Người đại diện
"", # H - SĐT
so_tien, # I - Số tiền
dich_vu # J - Dịch vụ
]]
Lệnh gog:
gog sheets update \
"Hợp đồng!A${rowNum}:J${rowNum}" \
--values-json '[[mst,"",ma_hop_dong,ten_cong_ty,dia_chi,mst,nguoi_dai_dien,"",so_tien,dich_vu]]' \
--input USER_ENTERED \
--no-input
Cảnh báo: Luôn ghi đủ A:J để giữ nguyên các cột D-G (tên, địa chỉ, MST, người đại diện) đã có. Không ghi range C:J riêng lẻ.
Đọc lại dòng vừa ghi để xác nhận:
gog sheets get \
"Hợp đồng!A${rowNum}:J${rowNum}" --json --no-input
Thông báo ngắn gọn: Dòng {rowNum} Đã thêm thành công
Sau khi ghi sheet, tự động tạo (hoặc cập nhật) khách hàng (res.partner) trên Odoo với thông tin doanh nghiệp vừa tra cứu.
Kiểm tra trùng: Tra cứu res.partner theo vat (MST) trước. Nếu đã tồn tại thì bỏ qua, không tạo trùng.
import sys
sys.path.insert(0, '~/clawd/skills/odoo-connector')
from odoo_skill.client import OdooClient
client = OdooClient()
# Kiểm tra đã có partner với MST này chưa
existing = client.search_read('res.partner', [['vat', '=', mst]], fields=['id', 'name'])
if not existing:
partner_id = client.create('res.partner', {
'name': ten_cong_ty,
'vat': mst,
'street': dia_chi,
'phone': sdt or '', # nếu có SĐT từ masothue
'is_company': True,
'company_type': 'company',
})
print(f'✅ Odoo Partner #{partner_id}: {ten_cong_ty}')
else:
print(f'ℹ️ Đã tồn tại partner #{existing[0]["id"]}: {existing[0]["name"]} — bỏ qua')
Lưu ý: Nếu user có cung cấp SĐT riêng (trong input), ưu tiên dùng SĐT đó thay vì SĐT từ masothue.
Sau khi tạo (hoặc tìm thấy) partner, tự động tạo một crm.lead (opportunity) ở stage Hợp Đồng Mẫu (ID: 5) để theo dõi hợp đồng này.
import sys
sys.path.insert(0, '~/clawd/skills/odoo-connector')
from odoo_skill.client import OdooClient
client = OdooClient()
opp_id = client.create('crm.lead', {
'name': f'{ma_hop_dong} - {dich_vu} - {ten_cong_ty_ngan}', # VD: "W21/256565/SEO - SEO - Bao Bì Rồng Việt"
'partner_id': partner_id, # ID từ Bước 6
'contact_name': nguoi_dai_dien or '',
'type': 'opportunity',
'stage_id': 5, # Hợp Đồng Mẫu
'expected_revenue': so_tien_so, # số tiền dạng số, VD: 14000000
'probability': 50,
})
print(f'✅ Odoo Opp #{opp_id}: {ma_hop_dong} - {dich_vu} - {ten_cong_ty_ngan}')
Lưu ý:
so_tien_solà số tiền dạng integer (VD:14000000), parse từso_tienstring (VD:"14.000.000").ten_cong_ty_nganlà tên công ty rút gọn (bỏ "CÔNG TY TNHH"... để tên opportunity gọn hơn) — có thể lấy nguyên tên đầy đủ nếu muốn đơn giản. Tên opportunity theo format{Mã HĐ} - {Dịch vụ} - {Tên}.
0312712411): Google Sheets có thể ăn mất số 0 nếu ghi dạng số. Luôn dùng --input USER_ENTERED và truyền dạng string "0312712411" để giữ nguyên số 0."mã số thuế {mst}" hoặc báo user.