Accept Merge Request #149: (feature/一键打印功能 -> develop)
Merge Request: sf更新代码 Created By: @龚启豪 Accepted By: @龚启豪 URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/149?initial=true
This commit is contained in:
32
Dockerfile
Normal file
32
Dockerfile
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
FROM jikimo-hn-docker.pkg.coding.net/jikimo_sfs/odoo-sf/odoo-sf:1.0
|
||||||
|
USER root:root
|
||||||
|
|
||||||
|
ADD . /app
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY ./requirements.txt /app
|
||||||
|
|
||||||
|
RUN sed -i 's#http://deb.debian.org#http://mirrors.aliyun.com#g' /etc/apt/sources.list
|
||||||
|
# Install some deps, lessc and less-plugin-clean-css, and wkhtmltopdf
|
||||||
|
|
||||||
|
# 系统更新
|
||||||
|
RUN apt-get update
|
||||||
|
# RUN apt-get do-release-upgrade
|
||||||
|
|
||||||
|
# 更新python的依赖
|
||||||
|
#RUN pip3 install --upgrade pip
|
||||||
|
RUN pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
|
||||||
|
|
||||||
|
# 设置时区
|
||||||
|
RUN rm -rf /etc/localtime
|
||||||
|
RUN ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||||
|
|
||||||
|
# 拷贝代码到工作目录
|
||||||
|
COPY . /mnt/extra-addons
|
||||||
|
|
||||||
|
# 拷贝配置文件到配置目录
|
||||||
|
COPY ./odoo.conf /etc/odoo
|
||||||
|
|
||||||
|
# 启动odoo
|
||||||
|
#COPY ./entrypoint.sh /
|
||||||
1
__init__.py
Normal file
1
__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# -*-coding:utf-8-*-
|
||||||
1
jikimo_model_viewer/__init__.py
Normal file
1
jikimo_model_viewer/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import models
|
||||||
22
jikimo_model_viewer/__manifest__.py
Normal file
22
jikimo_model_viewer/__manifest__.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "Jikimo 3D模型展示模块",
|
||||||
|
"summary": "Jikimo 3D模型展示模块。",
|
||||||
|
"description": "Jikimo 3D模型展示模块(限odoo16)",
|
||||||
|
"author": "Van",
|
||||||
|
"website": "https://jikimo.com",
|
||||||
|
"category": "Tutorials",
|
||||||
|
"version": "16.0.0.1",
|
||||||
|
"depends": ['web','sale','sale_management'],
|
||||||
|
"demo": [],
|
||||||
|
"data": [
|
||||||
|
'views/views.xml', #这是为了测试的效果,可以删除
|
||||||
|
],
|
||||||
|
'assets': {
|
||||||
|
'web.assets_qweb': [
|
||||||
|
'jikimo_model_viewer/static/src/js/3d_viewer.xml',
|
||||||
|
],
|
||||||
|
'web.assets_backend': [
|
||||||
|
'jikimo_model_viewer/static/src/js/*',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
1
jikimo_model_viewer/models/__init__.py
Normal file
1
jikimo_model_viewer/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import sale_order
|
||||||
15
jikimo_model_viewer/models/sale_order.py
Normal file
15
jikimo_model_viewer/models/sale_order.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from odoo import models,fields
|
||||||
|
from odoo.tools import populate, groupby
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SaleOrder(models.Model):
|
||||||
|
_inherit = "sale.order"
|
||||||
|
|
||||||
|
step_file = fields.Binary("Step File")
|
||||||
25
jikimo_model_viewer/readme.md
Normal file
25
jikimo_model_viewer/readme.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# 演示DEMO
|
||||||
|
## 先给销售订单添加一个Binary字段
|
||||||
|
|
||||||
|
class SaleOrder(models.Model):
|
||||||
|
_inherit = "sale.order"
|
||||||
|
|
||||||
|
step_file = fields.Binary("Step File")
|
||||||
|
|
||||||
|
## 然后在销售订单详情的表单视中增加一个带有widget的标签
|
||||||
|
|
||||||
|
<record id="sale_order_form_inherit" model="ir.ui.view">
|
||||||
|
<field name="name">sale.order.form.inherit</field>
|
||||||
|
<field name="model">sale.order</field>
|
||||||
|
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<!-- 以下仅用于演示效果 widget必需放在保存GLB文件内容的字段上 -->
|
||||||
|
<field name="payment_term_id" position="after">
|
||||||
|
<field name="step_file" widget="Viewer3D"/>
|
||||||
|
</field>
|
||||||
|
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
## 然后就可以到销售订单页面上查看效果
|
||||||
|

|
||||||
BIN
jikimo_model_viewer/static/src/images/img.png
Normal file
BIN
jikimo_model_viewer/static/src/images/img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 140 KiB |
62
jikimo_model_viewer/static/src/js/3d_viewer.js
Normal file
62
jikimo_model_viewer/static/src/js/3d_viewer.js
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/** @odoo-module **/
|
||||||
|
|
||||||
|
import { registry } from "@web/core/registry";//注册
|
||||||
|
import { _lt } from "@web/core/l10n/translation";//翻译
|
||||||
|
import { standardFieldProps } from "@web/views/fields/standard_field_props";
|
||||||
|
import { useInputField } from "@web/views/fields/input_field_hook";
|
||||||
|
import { FileUploader } from "@web/views/fields/file_handler";
|
||||||
|
import { session } from "@web/session";//登录会话
|
||||||
|
import { useService } from "@web/core/utils/hooks";
|
||||||
|
import { isBinarySize } from "@web/core/utils/binary";
|
||||||
|
import { download } from "@web/core/network/download";
|
||||||
|
import utils from 'web.utils';
|
||||||
|
|
||||||
|
import core from 'web.core';
|
||||||
|
import rpc from 'web.rpc';
|
||||||
|
|
||||||
|
var QWeb = core.qweb;
|
||||||
|
|
||||||
|
import { Component, onWillUpdateProps, useState, useRef, useEffect } from "@odoo/owl";
|
||||||
|
|
||||||
|
export class StepViewer extends Component {
|
||||||
|
setup() {
|
||||||
|
this.props.url = this.formatUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
formatUrl(){
|
||||||
|
var url = '';
|
||||||
|
if (this.props.value) {
|
||||||
|
if (utils.is_bin_size(this.props.value)) {
|
||||||
|
var url_props = {
|
||||||
|
base_url: session['web.base.url'],
|
||||||
|
model: this.props.record.resModel,
|
||||||
|
id: JSON.stringify(this.props.record.data['id']),
|
||||||
|
field: this.props.name}
|
||||||
|
url = url_props['base_url']+'/web/content/'+url_props['model']+'/'+url_props['id']+'/'+url_props['field']+'?download=true'
|
||||||
|
|
||||||
|
} else {
|
||||||
|
url = "data:model/gltf-binary;base64," + this.props.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
StepViewer.template = "jikimo_model_viewer.BinaryField3d";
|
||||||
|
|
||||||
|
StepViewer.displayName = _lt("3D File");
|
||||||
|
StepViewer.supportedTypes = ["binary"];
|
||||||
|
|
||||||
|
StepViewer.props = {
|
||||||
|
...standardFieldProps,
|
||||||
|
url: { type: String, optional: true },
|
||||||
|
};
|
||||||
|
|
||||||
|
StepViewer.extractProps = ({ attrs }) => {
|
||||||
|
return {
|
||||||
|
url: attrs.options.url,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
registry.category("fields").add("Viewer3D", StepViewer);
|
||||||
43
jikimo_model_viewer/static/src/js/3d_viewer.xml
Normal file
43
jikimo_model_viewer/static/src/js/3d_viewer.xml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
|
||||||
|
<t t-name="jikimo_model_viewer.BinaryField3d" owl="1">
|
||||||
|
|
||||||
|
<model-viewer
|
||||||
|
t-att-src='props.url'
|
||||||
|
name="3D model"
|
||||||
|
alt="3D model"
|
||||||
|
auto-rotate="1"
|
||||||
|
camera-controls="1"
|
||||||
|
style="
|
||||||
|
background-color: #0b009d;
|
||||||
|
--poster-color: #ffffff00;"
|
||||||
|
>
|
||||||
|
<!-- <div class="text-center mt-4 mb-4 mr-4">-->
|
||||||
|
<!-- <span-->
|
||||||
|
<!-- id="model-viewer-fullscreen"-->
|
||||||
|
<!-- title="View fullscreen"-->
|
||||||
|
<!-- role="img"-->
|
||||||
|
<!-- aria-label="Fullscreen"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <i class="fa fa-arrows-alt fa-2x"/>-->
|
||||||
|
<!-- </span>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
</model-viewer>
|
||||||
|
|
||||||
|
<!-- <model-viewer-->
|
||||||
|
<!-- src='/jikimo_model_viewer/static/src/js/3d_viewer/test.glb'-->
|
||||||
|
<!-- name="Test 3D model"-->
|
||||||
|
<!-- alt="Test 3D model"-->
|
||||||
|
<!-- auto-rotate="1"-->
|
||||||
|
<!-- camera-controls="1"-->
|
||||||
|
<!-- />-->
|
||||||
|
|
||||||
|
<script type="module"
|
||||||
|
src="/jikimo_model_viewer/static/src/lib/model-viewer.min.js">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</t>
|
||||||
|
|
||||||
|
|
||||||
|
</templates>
|
||||||
0
jikimo_model_viewer/static/src/js/test.glb
Normal file
0
jikimo_model_viewer/static/src/js/test.glb
Normal file
18
jikimo_model_viewer/views/views.xml
Normal file
18
jikimo_model_viewer/views/views.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="sale_order_form_inherit" model="ir.ui.view">
|
||||||
|
<field name="name">sale.order.form.inherit</field>
|
||||||
|
<field name="model">sale.order</field>
|
||||||
|
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="payment_term_id" position="after">
|
||||||
|
<!-- <field name="create_date" widget="show_units" options="{'units':'UTC'}" string="Create Date"/>-->
|
||||||
|
<!-- <group class="o_partner_order_summary" col="2"/>-->
|
||||||
|
<field name="step_file" widget="Viewer3D"/>
|
||||||
|
</field>
|
||||||
|
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
43
requirements.txt
Normal file
43
requirements.txt
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
Babel==2.9.1 # min version = 2.6.0 (Focal with security backports)
|
||||||
|
chardet==3.0.4
|
||||||
|
cryptography==3.4.8
|
||||||
|
decorator==4.4.2
|
||||||
|
docutils==0.16
|
||||||
|
ebaysdk==2.1.5
|
||||||
|
freezegun==0.3.15; python_version >= '3.8'
|
||||||
|
gevent==1.5.0 ; python_version == '3.7'
|
||||||
|
gevent==21.8.0 ; python_version > '3.9' # (Jammy)
|
||||||
|
greenlet==1.1.2 ; python_version > '3.9' # (Jammy)
|
||||||
|
idna==2.8
|
||||||
|
Jinja2==2.11.3 # min version = 2.10.1 (Focal - with security backports)
|
||||||
|
libsass==0.18.0
|
||||||
|
lxml==4.6.5 # min version = 4.5.0 (Focal - with security backports)
|
||||||
|
MarkupSafe==1.1.0
|
||||||
|
num2words==0.5.6
|
||||||
|
ofxparse==0.21; python_version > '3.9' # (Jammy)
|
||||||
|
passlib==1.7.3 # min version = 1.7.2 (Focal with security backports)
|
||||||
|
Pillow==9.0.1 # min version = 7.0.0 (Focal with security backports)
|
||||||
|
polib==1.1.0
|
||||||
|
psutil==5.6.7 # min version = 5.5.1 (Focal with security backports)
|
||||||
|
psycopg2==2.8.6; sys_platform == 'win32' or python_version >= '3.8'
|
||||||
|
pydot==1.4.1
|
||||||
|
pyopenssl==19.0.0
|
||||||
|
PyPDF2==1.26.0
|
||||||
|
pypiwin32 ; sys_platform == 'win32'
|
||||||
|
pyserial==3.4
|
||||||
|
python-dateutil==2.7.3
|
||||||
|
python-ldap==3.4.0 ; sys_platform != 'win32' # min version = 3.2.0 (Focal with security backports)
|
||||||
|
python-stdnum==1.13
|
||||||
|
pytz==2019.3
|
||||||
|
pyusb==1.0.2
|
||||||
|
qrcode==6.1
|
||||||
|
reportlab==3.5.59 # version < 3.5.54 are not compatible with Pillow 8.1.2 and 3.5.59 is bullseye
|
||||||
|
requests==2.25.1 # versions < 2.25 aren't compatible w/ urllib3 1.26. Bullseye = 2.25.1. min version = 2.22.0 (Focal)
|
||||||
|
urllib3==1.26.5 # indirect / min version = 1.25.8 (Focal with security backports)
|
||||||
|
vobject==0.9.6.1
|
||||||
|
Werkzeug==0.16.1 ; python_version <= '3.9'
|
||||||
|
Werkzeug==2.0.2 ; python_version > '3.9' # (Jammy)
|
||||||
|
xlrd==1.2.0; python_version >= '3.8'
|
||||||
|
XlsxWriter==1.1.2
|
||||||
|
xlwt==1.3.*
|
||||||
|
zeep==3.4.0
|
||||||
@@ -49,6 +49,7 @@ class MrsProductionProcess(models.Model):
|
|||||||
processing_order_ids = fields.One2many('sf.processing.order', 'production_process_id', string='工序')
|
processing_order_ids = fields.One2many('sf.processing.order', 'production_process_id', string='工序')
|
||||||
partner_process_ids = fields.Many2many('res.partner', 'process_ids', '加工工厂')
|
partner_process_ids = fields.Many2many('res.partner', 'process_ids', '加工工厂')
|
||||||
active = fields.Boolean('有效', default=True)
|
active = fields.Boolean('有效', default=True)
|
||||||
|
parameter_ids = fields.One2many('sf.production.process.parameter', 'process_id', string='可选参数')
|
||||||
|
|
||||||
|
|
||||||
class MrsProcessingTechnology(models.Model):
|
class MrsProcessingTechnology(models.Model):
|
||||||
@@ -96,3 +97,12 @@ class SupplierSort(models.Model):
|
|||||||
('supplier_sort_uniq', 'unique (partner_id,materials_model_id)', '排序不能重复!')
|
('supplier_sort_uniq', 'unique (partner_id,materials_model_id)', '排序不能重复!')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class MrsProductionProcessParameter(models.Model):
|
||||||
|
_name = 'sf.production.process.parameter'
|
||||||
|
_description = '可选参数'
|
||||||
|
name = fields.Char('参数名')
|
||||||
|
active = fields.Boolean('有效', default=True)
|
||||||
|
price = fields.Float('单价')
|
||||||
|
process_id = fields.Many2one('sf.production.process', string='表面工艺')
|
||||||
|
materials_model_ids = fields.Many2many('sf.materials.model', 'applicable_material', string='适用材料')
|
||||||
|
code = fields.Char("编码")
|
||||||
@@ -14,7 +14,7 @@ access_sf_processing_technology,sf_processing_technology,model_sf_processing_tec
|
|||||||
access_sf_tray,sf_tray,model_sf_tray,base.group_user,1,1,1,1
|
access_sf_tray,sf_tray,model_sf_tray,base.group_user,1,1,1,1
|
||||||
access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,base.group_user,1,1,1,1
|
access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,base.group_user,1,1,1,1
|
||||||
|
|
||||||
|
access_sf_production_process_parameter,sf_production_process_parameter,model_sf_production_process_parameter,base.group_user,1,1,1,1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
|
@@ -74,6 +74,32 @@
|
|||||||
</form>
|
</form>
|
||||||
</field>
|
</field>
|
||||||
</page>
|
</page>
|
||||||
|
<page string="可选参数">
|
||||||
|
<field name="parameter_ids">
|
||||||
|
<tree force_save="1">
|
||||||
|
<field name="code" readonly="1" force_save="1"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="price"/>
|
||||||
|
<field name='process_id' default="default" invisible="1"/>
|
||||||
|
</tree>
|
||||||
|
<form>
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<field name="code" readonly="1" force_save="1"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="price"/>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="适用材料">
|
||||||
|
<field name="materials_model_ids"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
<group>
|
<group>
|
||||||
<field name="remark"/>
|
<field name="remark"/>
|
||||||
|
|||||||
@@ -164,14 +164,20 @@ class MrpProduction(models.Model):
|
|||||||
|
|
||||||
#工单排序
|
#工单排序
|
||||||
def _reset_work_order_sequence1(self, k):
|
def _reset_work_order_sequence1(self, k):
|
||||||
|
sequen = 0
|
||||||
for rec in self:
|
for rec in self:
|
||||||
current_sequence = 1
|
current_sequence = 10
|
||||||
for work in rec.workorder_ids:
|
for work in rec.workorder_ids:
|
||||||
work.sequence = current_sequence
|
work.sequence = current_sequence
|
||||||
current_sequence += 1
|
current_sequence += 10
|
||||||
sfa = rec
|
if work.name == '后置三元质量检测' and work.processing_panel == k:
|
||||||
for a in sfa:
|
sequen = work.sequence
|
||||||
print(a)
|
|
||||||
|
for work in rec.workorder_ids:
|
||||||
|
if work.name == '后置三元质量检测(返工)' and work.processing_panel == k:
|
||||||
|
work.sequence = sequen + 2
|
||||||
|
if work.name == 'CNC加工(返工)' and work.processing_panel == k:
|
||||||
|
work.sequence = sequen + 1
|
||||||
|
|
||||||
#在制造订单上新增工单
|
#在制造订单上新增工单
|
||||||
def _create_workorder1(self, k):
|
def _create_workorder1(self, k):
|
||||||
@@ -211,6 +217,7 @@ class MrpProduction(models.Model):
|
|||||||
order='sequence asc'
|
order='sequence asc'
|
||||||
)
|
)
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
for route in routingworkcenter:
|
for route in routingworkcenter:
|
||||||
|
|
||||||
if route.routing_type == '后置三元质量检测':
|
if route.routing_type == '后置三元质量检测':
|
||||||
@@ -222,8 +229,10 @@ class MrpProduction(models.Model):
|
|||||||
self.env['mrp.workorder'].json_workorder_str1(k, production, route))
|
self.env['mrp.workorder'].json_workorder_str1(k, production, route))
|
||||||
|
|
||||||
production.workorder_ids = workorders_values
|
production.workorder_ids = workorders_values
|
||||||
for workorder in production.workorder_ids:
|
workorder = self.env['mrp.workorder'].browse(production.workorder_ids.ids)
|
||||||
workorder.duration_expected = workorder._get_duration_expected()
|
print(workorder)
|
||||||
|
# for item in workorder:
|
||||||
|
# workorder.duration_expected = workorder._get_duration_expected()
|
||||||
|
|
||||||
def _create_workorder2(self, k):
|
def _create_workorder2(self, k):
|
||||||
res = self._create_workorder1(k)
|
res = self._create_workorder1(k)
|
||||||
|
|||||||
@@ -314,8 +314,8 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
subtype_id=self.env.ref('mail.mt_note').id)
|
subtype_id=self.env.ref('mail.mt_note').id)
|
||||||
if self.test_results == '返工':
|
if self.test_results == '返工':
|
||||||
productions = self.production_id
|
productions = self.production_id
|
||||||
self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
|
# self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
|
||||||
self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
|
# self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
|
||||||
productions._create_workorder2(self.processing_panel)
|
productions._create_workorder2(self.processing_panel)
|
||||||
else:
|
else:
|
||||||
self.results = '合格'
|
self.results = '合格'
|
||||||
@@ -379,7 +379,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
'product_uom_id': production.product_uom_id.id,
|
'product_uom_id': production.product_uom_id.id,
|
||||||
'qty_producing': 0,
|
'qty_producing': 0,
|
||||||
'operation_id': False,
|
'operation_id': False,
|
||||||
'name': route.route_workcenter_id.name,
|
'name': '%s(返工)' % route.route_workcenter_id.name,
|
||||||
'processing_panel': k,
|
'processing_panel': k,
|
||||||
'routing_type': route.routing_type,
|
'routing_type': route.routing_type,
|
||||||
'work_state': '' if not route.routing_type == '获取CNC加工程序' else '待发起',
|
'work_state': '' if not route.routing_type == '获取CNC加工程序' else '待发起',
|
||||||
|
|||||||
@@ -131,4 +131,15 @@
|
|||||||
<field name="numbercall">-1</field>
|
<field name="numbercall">-1</field>
|
||||||
<field name="doall" eval="False"/>
|
<field name="doall" eval="False"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.cron" id="sf_cron13">
|
||||||
|
<field name="name">同步表面工艺可选参数</field>
|
||||||
|
<field name="model_id" ref="model_sf_production_process_parameter"/>
|
||||||
|
<field name="state">code</field>
|
||||||
|
<field name="code">model.sync_production_process_parameter()</field>
|
||||||
|
<field name="interval_number">1</field>
|
||||||
|
<field name="interval_type">days</field>
|
||||||
|
<field name="numbercall">-1</field>
|
||||||
|
<field name="doall" eval="False"/>
|
||||||
|
</record>
|
||||||
</odoo>
|
</odoo>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
# Part of SmartGo. See LICENSE file for full copyright and licensing details.
|
# Part of SmartGo. See LICENSE file for full copyright and licensing details.
|
||||||
import logging
|
import logging
|
||||||
from odoo import api, fields, models
|
from odoo import api, fields, models
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -19,29 +19,33 @@ class ResConfigSettings(models.TransientModel):
|
|||||||
ftp_password = fields.Char(string='FTP密码')
|
ftp_password = fields.Char(string='FTP密码')
|
||||||
|
|
||||||
def sf_all_sync(self):
|
def sf_all_sync(self):
|
||||||
self.env['sf.production.materials'].sync_all_production_materials()
|
try:
|
||||||
_logger.info("同步资源库材料")
|
self.env['sf.production.materials'].sync_all_production_materials()
|
||||||
self.env['sf.materials.model'].sync_all_materials_model()
|
_logger.info("同步资源库材料")
|
||||||
_logger.info("同步资源库材料型号")
|
self.env['sf.materials.model'].sync_all_materials_model()
|
||||||
self.env['sf.production.process'].sync_all_production_process()
|
_logger.info("同步资源库材料型号")
|
||||||
_logger.info("同步资源库表面工艺")
|
self.env['sf.production.process'].sync_all_production_process()
|
||||||
self.env['sf.processing.technology'].sync_all_processing_technology()
|
_logger.info("同步资源库表面工艺")
|
||||||
_logger.info("同步资源库加工工艺")
|
self.env['sf.processing.technology'].sync_all_processing_technology()
|
||||||
self.env['sf.machine.brand.tags'].sync_all_machine_brand_tags()
|
_logger.info("同步资源库加工工艺")
|
||||||
_logger.info("同步资源库品牌类别")
|
self.env['sf.machine.brand.tags'].sync_all_machine_brand_tags()
|
||||||
self.env['sf.machine.brand'].sync_all_machine_brand()
|
_logger.info("同步资源库品牌类别")
|
||||||
_logger.info("同步资源库品牌")
|
self.env['sf.machine.brand'].sync_all_machine_brand()
|
||||||
self.env['sf.machine.control_system'].sync_all_machine_tool_type_control_system()
|
_logger.info("同步资源库品牌")
|
||||||
_logger.info("同步资源库控制系统")
|
self.env['sf.machine.control_system'].sync_all_machine_tool_type_control_system()
|
||||||
# self.env['sf.machine_tool'].sync_all_machine_tool()
|
_logger.info("同步资源库控制系统")
|
||||||
# _logger.info("同步机床行业编码")
|
self.env['sf.machine_tool.type'].sync_all_machine_tool_type()
|
||||||
self.env['sf.machine_tool.type'].sync_all_machine_tool_type()
|
_logger.info("同步资源库机床型号")
|
||||||
_logger.info("同步资源库机床型号")
|
self.env['sf.cutting_tool.category'].sync_all_cutting_tool_category()
|
||||||
self.env['sf.cutting_tool.category'].sync_all_cutting_tool_category()
|
_logger.info("同步资源库刀具类别")
|
||||||
_logger.info("同步资源库刀具类别")
|
self.env['sf.cutting_tool.type'].sync_all_cutting_tool_type()
|
||||||
self.env['sf.cutting_tool.type'].sync_all_cutting_tool_type()
|
_logger.info("同步资源库刀具")
|
||||||
_logger.info("同步资源库刀具")
|
self.env['sf.production.process.parameter'].sync_all_production_process_parameter()
|
||||||
# self.env['sf.processing.order'].sync_all_processing_order()
|
_logger.info("同步表面工艺参数")
|
||||||
|
except Exception as e:
|
||||||
|
_logger.info("捕获错误信息:%s" % e)
|
||||||
|
raise ValidationError("数据错误导致同步失败,请联系管理员")
|
||||||
|
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def get_values(self):
|
def get_values(self):
|
||||||
|
|||||||
@@ -948,3 +948,75 @@ class sfProcessingOrder(models.Model):
|
|||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
raise ValidationError("认证未通过")
|
raise ValidationError("认证未通过")
|
||||||
|
|
||||||
|
class sfProductionProcessParameter(models.Model):
|
||||||
|
_inherit = 'sf.production.process.parameter'
|
||||||
|
_description = '表面工艺可选参数'
|
||||||
|
url = '/api/production_process_parameter/list'
|
||||||
|
|
||||||
|
# 定时同步每日表面工艺
|
||||||
|
def sync_production_process_parameter(self):
|
||||||
|
sf_sync_config = self.env['res.config.settings'].get_values()
|
||||||
|
token = sf_sync_config['token']
|
||||||
|
sf_secret_key = sf_sync_config['sf_secret_key']
|
||||||
|
headers = Common.get_headers(self, token, sf_secret_key)
|
||||||
|
|
||||||
|
strUrl = sf_sync_config['sf_url'] + self.url
|
||||||
|
r = requests.post(strUrl, json={}, data=None, headers=headers)
|
||||||
|
r = r.json()
|
||||||
|
result = json.loads(r['result'])
|
||||||
|
if result['status'] == 1:
|
||||||
|
for item in result['mrs_production_process_parameter_yesterday_list']:
|
||||||
|
if item:
|
||||||
|
brand = self.env['sf.production.process.parameter'].search(
|
||||||
|
[("code", '=', item['code'])])
|
||||||
|
if brand:
|
||||||
|
brand.name = item['name'],
|
||||||
|
brand.code = item['code'],
|
||||||
|
brand.active = item['active'],
|
||||||
|
brand.price = item['price'],
|
||||||
|
else:
|
||||||
|
self.env['sf.production.process.parameter'].create({
|
||||||
|
"name": item['name'],
|
||||||
|
"code": item['code'],
|
||||||
|
"active": item['active'],
|
||||||
|
"price" : item['price'],
|
||||||
|
"process_id": self.env['sf.production.process'].search(
|
||||||
|
[('process_encode', '=', item['process_id_code'])]).id,
|
||||||
|
'materials_model_ids': self.env['sf.materials.model'].search(
|
||||||
|
[('materials_no', 'in', item['materials_model_ids_codes'])])
|
||||||
|
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
raise ValidationError("认证未通过") # 定时同步表面工艺
|
||||||
|
|
||||||
|
# 同步所有表面工艺
|
||||||
|
def sync_all_production_process_parameter(self):
|
||||||
|
sf_sync_config = self.env['res.config.settings'].get_values()
|
||||||
|
token = sf_sync_config['token']
|
||||||
|
sf_secret_key = sf_sync_config['sf_secret_key']
|
||||||
|
headers = Common.get_headers(self, token, sf_secret_key)
|
||||||
|
|
||||||
|
strUrl = sf_sync_config['sf_url'] + self.url
|
||||||
|
r = requests.post(strUrl, json={}, data=None, headers=headers)
|
||||||
|
r = r.json()
|
||||||
|
result = json.loads(r['result'])
|
||||||
|
if result['status'] == 1:
|
||||||
|
for item in result['mrs_production_process_parameter_all_list']:
|
||||||
|
if item:
|
||||||
|
brand = self.env['sf.production.process.parameter'].search(
|
||||||
|
[("code", '=', item['code'])])
|
||||||
|
if not brand:
|
||||||
|
self.env['sf.production.process.parameter'].create({
|
||||||
|
"name": item['name'],
|
||||||
|
"code": item['code'],
|
||||||
|
"price": item['price'],
|
||||||
|
"active": item['active'],
|
||||||
|
"process_id": self.env['sf.production.process'].search(
|
||||||
|
[('process_encode', '=', item['process_id_code'])]).id,
|
||||||
|
'materials_model_ids': self.env['sf.materials.model'].search(
|
||||||
|
[('materials_no', 'in', item['materials_model_ids_codes'])])
|
||||||
|
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
raise ValidationError("认证未通过")
|
||||||
3
zpl_print/__init__.py
Normal file
3
zpl_print/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*-coding:utf-8-*-
|
||||||
|
from .import models
|
||||||
|
from .import controllers
|
||||||
23
zpl_print/__manifest__.py
Normal file
23
zpl_print/__manifest__.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
{
|
||||||
|
'name': '一键打印功能',
|
||||||
|
'version': '1.0',
|
||||||
|
'summary': '一件打印',
|
||||||
|
'sequence': 1,
|
||||||
|
'description': """
|
||||||
|
在本模块,实现了一键打印功能
|
||||||
|
""",
|
||||||
|
'category': 'sf',
|
||||||
|
'website': 'https://www.sf.jikimo.com',
|
||||||
|
'depends': ['base', 'web'],
|
||||||
|
'data': [
|
||||||
|
],
|
||||||
|
'demo': [
|
||||||
|
],
|
||||||
|
'qweb': [
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
'application': False,
|
||||||
|
'auto_install': False,
|
||||||
|
}
|
||||||
2
zpl_print/controllers/__init__.py
Normal file
2
zpl_print/controllers/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# -*-coding:utf-8-*-
|
||||||
|
from .import report
|
||||||
60
zpl_print/controllers/report.py
Normal file
60
zpl_print/controllers/report.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import werkzeug
|
||||||
|
import werkzeug.exceptions
|
||||||
|
import werkzeug.utils
|
||||||
|
import werkzeug.wrappers
|
||||||
|
import werkzeug.wsgi
|
||||||
|
from werkzeug.urls import url_parse
|
||||||
|
|
||||||
|
from odoo import http
|
||||||
|
from odoo.http import content_disposition, request
|
||||||
|
from odoo.tools.safe_eval import safe_eval, time
|
||||||
|
from odoo.addons.web.controllers.report import ReportController
|
||||||
|
from ..models.common import Common
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ZplReportController(ReportController):
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------------------------
|
||||||
|
# Report controllers
|
||||||
|
#------------------------------------------------------
|
||||||
|
@http.route([
|
||||||
|
'/report/<converter>/<reportname>',
|
||||||
|
'/report/<converter>/<reportname>/<docids>',
|
||||||
|
], type='http', auth='user', website=True)
|
||||||
|
def report_routes(self, reportname, docids=None, converter=None, **data):
|
||||||
|
report = request.env['ir.actions.report']
|
||||||
|
context = dict(request.env.context)
|
||||||
|
|
||||||
|
if docids:
|
||||||
|
docids = [int(i) for i in docids.split(',')]
|
||||||
|
if data.get('options'):
|
||||||
|
data.update(json.loads(data.pop('options')))
|
||||||
|
if data.get('context'):
|
||||||
|
data['context'] = json.loads(data['context'])
|
||||||
|
context.update(data['context'])
|
||||||
|
if converter == 'html':
|
||||||
|
html = report.with_context(context)._render_qweb_html(reportname, docids, data=data)[0]
|
||||||
|
return request.make_response(html)
|
||||||
|
elif converter == 'pdf':
|
||||||
|
pdf = report.with_context(context)._render_qweb_pdf(reportname, docids, data=data)[0]
|
||||||
|
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
|
||||||
|
return request.make_response(pdf, headers=pdfhttpheaders)
|
||||||
|
elif converter == 'text':
|
||||||
|
text = report.with_context(context)._render_qweb_text(reportname, docids, data=data)[0]
|
||||||
|
text_str = text.decode()
|
||||||
|
Common.print_zpl(self, text_str)
|
||||||
|
texthttpheaders = [('Content-Type', 'text/plain'), ('Content-Length', len(text))]
|
||||||
|
return request.make_response(text, headers=texthttpheaders)
|
||||||
|
else:
|
||||||
|
raise werkzeug.exceptions.HTTPException(description='Converter %s not implemented.' % converter)
|
||||||
0
zpl_print/libs/TSCLIB.dll
Normal file
0
zpl_print/libs/TSCLIB.dll
Normal file
2
zpl_print/models/__init__.py
Normal file
2
zpl_print/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# -*-coding:utf-8-*-
|
||||||
|
from .import common
|
||||||
24
zpl_print/models/common.py
Normal file
24
zpl_print/models/common.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from odoo import models
|
||||||
|
import ctypes
|
||||||
|
|
||||||
|
|
||||||
|
class Common(models.Model):
|
||||||
|
_name = 'sf.sync.common'
|
||||||
|
_description = u'公用类'
|
||||||
|
|
||||||
|
def print_zpl(self, zpl_str):
|
||||||
|
WinDll_path = "D://桌面//pythonZPL//tsc_python_sdk_example//TSC_Python_SDK_Example//tsc_sample//libs//TSCLIB.dll"
|
||||||
|
try:
|
||||||
|
tsclibrary = ctypes.WinDLL(WinDll_path)
|
||||||
|
tsclibrary.openportW("USB")
|
||||||
|
print(zpl_str)
|
||||||
|
tsclibrary.sendcommandW(zpl_str)
|
||||||
|
print('111222')
|
||||||
|
tsclibrary.printlabelW("0", "1");
|
||||||
|
tsclibrary.closeport();
|
||||||
|
except Exception as e:
|
||||||
|
raise UserWarning("错误警告")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user