# Available variables:
# - env: environment on which the action is triggered
# - model: model of the record on which the action is triggered; is a void recordset
# - record: record on which the action is triggered; may be void
# - records: recordset of all records on which the action is triggered in multi-mode; may be void
# - time, datetime, dateutil, timezone: useful Python libraries
# - float_compare: utility function to compare floats based on specific precision
# - b64encode, b64decode: functions to encode/decode binary data
# - log: log(message, level='info'): logging function to record debug information in ir.logging table
# - _logger: _logger.info(message): logger to emit messages in server logs
# - UserError: exception class for raising user-facing warning messages
# - Command: x2many commands namespace
# To return an action, assign: action = {...}
html_body = '''<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多语言黑白表格 (576px 宽度)</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:[email protected]&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Khmer:[email protected]&display=swap" rel="stylesheet">
<style>
/* CSS 样式 */
body {
/* Prioritize Noto Sans Khmer first for broad support, then Noto Sans SC, then a generic sans-serif */
font-family: 'Noto Sans Khmer', 'Noto Sans SC', sans-serif;
background-color: #FFFFFF;
display: flex;
justify-content: center;
align-items: flex-start;
min-height: 100vh;
margin: 0;
padding: 0px;
box-sizing: border-box;
}
.page-container {
max-width: 576px;
width: 100%;
background-color: #FFFFFF;
padding: 5px;
box-sizing: border-box;
}
table {
border-collapse: collapse;
width: 100%;
background-color: #FFFFFF;
color: #000000;
font-size: 24px;
}
th, td {
border: 1px solid #000000;
padding: 1px 3px;
text-align: left;
}
th {
background-color: #000000;
font-weight: bold;
color: #FFFFFF;
}
.col-qty {
width: 30px;
text-align: center;
}
.col-product {
width: auto;
/* No specific font rule here, it inherits from body */
}
</style>
</head>
<body>
<div><h2 style="text-align: center; font-size: 28px;">下单菜品(Table <TABLE_NUMBER/>)</h2></div>
<div class="page-container">
<table>
<thead>
<tr>
<th class="col-qty">QTY</th>
<th class="col-product">Product</th>
</tr>
</thead>
<tbody>
<TABLE_BODY/>
</tbody>
</table>
</div>
<div style="padding-left: 15px; font-size: 24px;"><p><ORDER_TIME/></p></div>
</body>
</html>'''
order_number = env.context.get("order_number","")
pos_id = env.context.get("pos_id", 0)
order = env['pos.order'].search(domain=[("session_id.config_id", "=", pos_id),("tracking_number", "=", order_number)], order='id desc', limit=1)
if order:
tbody = ''
for line in order.lines:
tbody += f'''<tr>
<td class="col-qty">{int(line.qty)}</td>
<td class="col-product">{line.full_product_name}</td>
</tr>'''
html_body = html_body.replace('<TABLE_BODY/>', tbody)
now = datetime.datetime.now() + datetime.timedelta(hours=7)
formatted_time = now.strftime("%Y-%m-%d %H:%M:%S")
html_body = html_body.replace('<ORDER_TIME/>', formatted_time)
html_body = html_body.replace('<TABLE_NUMBER/>', str(order.table_id.table_number))
toimage = env['ir.actions.report']._run_wkhtmltoimage
images = toimage(bodies=[html_body], width=576, height=0, image_format='png')
img = b64encode(images[0]).decode("utf-8")
action = {'img': img}
import sys
import os
import time
import requests
import base64
import json
def main():
if len(sys.argv) < 2:
print(f"用法: {sys.argv[0]} <三位订单编号>")
sys.exit(1)
order_number = sys.argv[1]
output_image = "/tmp/output_image.png"
# 删除旧的图片文件
if os.path.exists(output_image):
os.remove(output_image)
# 构造POST数据
payload = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"service": "object",
"method": "execute_kw",
"args": [
"datang-erp-test26",
2,
"e343a__*****___yourapikey___*****___d64923",
"ir.actions.server",
"run",
[[1036]],
{"context": {"order_number": order_number, "pos_id": 2}}
],
"kwargs": {}
},
"id": int(time.time())
}
headers = {'Content-Type': 'application/json'}
url = "https://datang-erp-test26.odoo.com/jsonrpc"
# 发送POST请求
response = requests.post(url, headers=headers, data=json.dumps(payload))
response.raise_for_status()
result = response.json()
# 提取图片并解码
img_base64 = result.get('result', {}).get('img')
if not img_base64:
print("未获取到图片数据")
sys.exit(1)
with open(output_image, "wb") as f:
f.write(base64.b64decode(img_base64))
# 第二个POST请求
print_url = "https://localhost.ip.hogantech.net:1443/eprint/png"
print_payload = {
"x_printer": "usb",
"x_url": f"file:{output_image}"
}
print_headers = {'Content-Type': 'application/json'}
requests.post(print_url, headers=print_headers, data=json.dumps(print_payload), verify=True)
if __name__ == "__main__":
main()