diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..2f3e7869 --- /dev/null +++ b/Dockerfile @@ -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 / \ No newline at end of file diff --git a/jikimo_model_viewer/static/src/js/test.glb b/jikimo_model_viewer/static/src/js/test.glb index c4a6352b..e69de29b 100644 Binary files a/jikimo_model_viewer/static/src/js/test.glb and b/jikimo_model_viewer/static/src/js/test.glb differ diff --git a/jikimo_model_viewer/views/views.xml b/jikimo_model_viewer/views/views.xml index 2baada6e..91c83f17 100644 --- a/jikimo_model_viewer/views/views.xml +++ b/jikimo_model_viewer/views/views.xml @@ -13,7 +13,6 @@ - \ No newline at end of file diff --git a/owl_demo/__init__.py b/owl_demo/__init__.py deleted file mode 100644 index e046e49f..00000000 --- a/owl_demo/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import controllers diff --git a/owl_demo/__manifest__.py b/owl_demo/__manifest__.py deleted file mode 100644 index 8011e065..00000000 --- a/owl_demo/__manifest__.py +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "OWL开发演示", - "summary": "示例OWL开发模块。", - "description": "用于演示OWL模块的开发。", - "author": "Van", - "website": "https://topodoo.com", - "category": "Tutorials", - "version": "15.0.0.1", - "depends": ["sale", "sale_management","web_widget_model_viewer"], - "demo": [], - "data": [ - #'report/test_sale_report.xml', - 'views/views.xml', - ], - 'assets': { - 'web.assets_qweb': [ - # 'owl_demo/static/src/xml/MyComponent.xml', - - #'owl_demo/static/src/js/html_template/template_demo_field.xml', - 'owl_demo/static/src/js/3d_viewer/3d_viewer.xml', - ], - 'web.assets_backend': [ - # 'owl_demo/static/src/xml/MyComponent.xml', - # 'owl_demo/static/src/js/components/MyComponent.js', - # 'owl_demo/static/src/js/services/*', - - #'owl_demo/static/src/js/html_template/*', - 'owl_demo/static/src/js/3d_viewer/*', - 'owl_demo/static/src/lib/model-viewer.min.js', - ], - } -} \ No newline at end of file diff --git a/owl_demo/controllers/__init__.py b/owl_demo/controllers/__init__.py deleted file mode 100644 index deec4a8b..00000000 --- a/owl_demo/controllers/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import main \ No newline at end of file diff --git a/owl_demo/controllers/main.py b/owl_demo/controllers/main.py deleted file mode 100644 index 5ecd7bc3..00000000 --- a/owl_demo/controllers/main.py +++ /dev/null @@ -1,266 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. -import base64 -import io -import json -import os - -from odoo import _ -from odoo import http -from odoo.http import request - - -class Viewer3d(http.Controller): - - @http.route(['/Viewer3d/'], type='http', auth="None") - def viewer3d(self, attachment_id, **kwargs): - attachment = self._attachment_get(attachment_id) - return attachment - - def _attachment_get(self, attachment_id): - attachment = request.env['ir.attachment'].sudo().browse(attachment_id) - if not attachment: - return - return attachment.datas - - def stl_to_gltf(binary_stl_path, out_path, is_binary): - import struct - - gltf2 = ''' - { - "scenes" : [ - { - "nodes" : [ 0 ] - } - ], - "nodes" : [ - { - "mesh" : 0 - } - ], - "meshes" : [ - { - "primitives" : [ { - "attributes" : { - "POSITION" : 1 - }, - "indices" : 0 - } ] - } - ], - "buffers" : [ - { - %s - "byteLength" : %d - } - ], - "bufferViews" : [ - { - "buffer" : 0, - "byteOffset" : 0, - "byteLength" : %d, - "target" : 34963 - }, - { - "buffer" : 0, - "byteOffset" : %d, - "byteLength" : %d, - "target" : 34962 - } - ], - "accessors" : [ - { - "bufferView" : 0, - "byteOffset" : 0, - "componentType" : 5125, - "count" : %d, - "type" : "SCALAR", - "max" : [ %d ], - "min" : [ 0 ] - }, - { - "bufferView" : 1, - "byteOffset" : 0, - "componentType" : 5126, - "count" : %d, - "type" : "VEC3", - "min" : [%f, %f, %f], - "max" : [%f, %f, %f] - } - ], - "asset" : { - "version" : "2.0" - } - } - ''' - - header_bytes = 80 - unsigned_long_int_bytes = 4 - float_bytes = 4 - vec3_bytes = 4 * 3 - spacer_bytes = 2 - num_vertices_in_face = 3 - - vertices = {} - indices = [] - - if not is_binary: - out_bin = os.path.join(out_path, "out.bin") - out_gltf = os.path.join(out_path, "out.gltf") - else: - out_bin = out_path - - unpack_face = struct.Struct("<12fH").unpack - face_bytes = float_bytes * 12 + 2 - - with open(path_to_stl, "rb") as f: - f.seek(header_bytes) # skip 80 bytes headers - - num_faces_bytes = f.read(unsigned_long_int_bytes) - number_faces = struct.unpack(" maxx: maxx = x - if y < miny: miny = y - if y > maxy: maxy = y - if z < minz: minz = z - if z > maxz: maxz = z - - # f.seek(spacer_bytes, 1) # skip the spacer - - number_vertices = len(vertices) - vertices_bytelength = number_vertices * vec3_bytes # each vec3 has 3 floats, each float is 4 bytes - unpadded_indices_bytelength = number_vertices * unsigned_long_int_bytes - - out_number_vertices = len(vertices) - out_number_indices = len(indices) - - unpadded_indices_bytelength = out_number_indices * unsigned_long_int_bytes - indices_bytelength = (unpadded_indices_bytelength + 3) & ~3 - - out_bin_bytelength = vertices_bytelength + indices_bytelength - - if is_binary: - out_bin_uir = "" - else: - out_bin_uir = '"uri": "out.bin",' - - gltf2 = gltf2 % (out_bin_uir, - # buffer - out_bin_bytelength, - - # bufferViews[0] - indices_bytelength, - - # bufferViews[1] - indices_bytelength, - vertices_bytelength, - - # accessors[0] - out_number_indices, - out_number_vertices - 1, - - # accessors[1] - out_number_vertices, - minx, miny, minz, - maxx, maxy, maxz - ) - - glb_out = bytearray() - if is_binary: - gltf2 = gltf2.replace(" ", "") - gltf2 = gltf2.replace("\n", "") - - scene = bytearray(gltf2.encode()) - - scene_len = len(scene) - padded_scene_len = (scene_len + 3) & ~3 - body_offset = padded_scene_len + 12 + 8 - - file_len = body_offset + out_bin_bytelength + 8 - - # 12-byte header - glb_out.extend(struct.pack(' - - - \ No newline at end of file diff --git a/owl_demo/static/src/css/MyWidget.css b/owl_demo/static/src/css/MyWidget.css deleted file mode 100644 index 12e077c3..00000000 --- a/owl_demo/static/src/css/MyWidget.css +++ /dev/null @@ -1,30 +0,0 @@ -.o_int_colorpicker { - .o_color_pill { - display: inline-block; - height: 25px; - width: 25px; - margin: 4px; - border-radius: 25px; - position: relative; - @for $size from 1 through length($o-colors) { - &.o_color_#{$size - 1} { - background-color: nth($o-colors, $size); - &:not(.readonly):hover { - transform: scale(1.2); - transition: 0.3s; - cursor: pointer; - } - &.active:after{ - content: "\f00c"; - display: inline-block; - font: normal normal normal 14px/1 FontAwesome; - font-size: inherit; - color: #fff; - position: absolute; - padding: 4px; - font-size: 16px; - } - } - } - } -} \ No newline at end of file diff --git a/owl_demo/static/src/js/3d_viewer/3d_viewer.js b/owl_demo/static/src/js/3d_viewer/3d_viewer.js deleted file mode 100644 index 08e76570..00000000 --- a/owl_demo/static/src/js/3d_viewer/3d_viewer.js +++ /dev/null @@ -1,127 +0,0 @@ -/** @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.notification = useService("notification"); - this.state = useState({ - fileName: this.props.record.data[this.props.fileNameField] || "", - }); - onWillUpdateProps((nextProps) => { - if (nextProps.readonly) { - this.state.fileName = nextProps.record.data[nextProps.fileNameField] || ""; - } - }); - - this.show_template = useRef('showStepViewer') - useInputField({ - getValue: () => this.props.value || "" - }); - - useEffect( - (el) => { - if (!el) { - return; - } - return this.formatTemplate($(el)); - }, - () => [this.show_template.el], - ) - } - - formatTemplate($el) { - console.log($el) - var self=this; - if (this.props.readonly && this.props.value) { - var url = "/owl_demo/static/src/js/3d_viewer/test.glb"; -// var session = this.getSession(); -// if (this.props.value) { -// if (utils.is_bin_size(this.props.value)) { -// url = session.url("/web/content", { -// model: this.model, -// id: JSON.stringify(this.props.record.res_id), -// field: this.props.record.name, -// }); -// } else { -// url = "data:model/gltf-binary;base64," + this.propsvalue.value; -// } -// } - return $el.html(QWeb.render("owl_demo.StepViewer",{'url':url})) - - } - } - - get fileName() { - return this.state.fileName || this.props.value || ""; - } - - - update({ data, name }) { - this.state.fileName = name || ""; - const { fileNameField, record } = this.props; - const changes = { [this.props.name]: data || false }; - if (fileNameField in record.fields && record.data[fileNameField] !== name) { - changes[fileNameField] = name || false; - } - return this.props.record.update(changes); - } - - async onFileDownload() { - await download({ - data: { - model: this.props.record.resModel, - id: this.props.record.resId, - field: this.props.name, - filename_field: this.fileName, - filename: this.fileName || "", - download: true, - data: isBinarySize(this.props.value) ? null : this.props.value, - }, - url: "/web/content", - }); - } - -} - -StepViewer.template = "owl_demo.BinaryField3d"; - -StepViewer.displayName = _lt("3D File"); -StepViewer.supportedTypes = ["binary"]; - -StepViewer.components = { - FileUploader, -}; -StepViewer.props = { - ...standardFieldProps, - acceptedFileExtensions: { type: String, optional: true }, - fileNameField: { type: String, optional: true }, -}; -StepViewer.defaultProps = { - acceptedFileExtensions: "*.stp", -}; - -StepViewer.extractProps = ({ attrs }) => { - return { - acceptedFileExtensions: attrs.options.accepted_file_extensions, - fileNameField: attrs.filename, - }; -}; - -registry.category("fields").add("Viewer3D", StepViewer); diff --git a/owl_demo/static/src/js/3d_viewer/3d_viewer.xml b/owl_demo/static/src/js/3d_viewer/3d_viewer.xml deleted file mode 100644 index dd277106..00000000 --- a/owl_demo/static/src/js/3d_viewer/3d_viewer.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - -
- - -
-
- - - -
- - - -
-
-
-
-
-
- - - -
- - - -
- - - - - - -
-
- -
diff --git a/owl_demo/static/src/js/3d_viewer/stl2gltf.py b/owl_demo/static/src/js/3d_viewer/stl2gltf.py deleted file mode 100644 index 1bdcc942..00000000 --- a/owl_demo/static/src/js/3d_viewer/stl2gltf.py +++ /dev/null @@ -1,277 +0,0 @@ -import os - -def stl_to_gltf(binary_stl_path, out_path, is_binary): - import struct - - gltf2 = ''' -{ - "scenes" : [ - { - "nodes" : [ 0 ] - } - ], - "nodes" : [ - { - "mesh" : 0 - } - ], - "meshes" : [ - { - "primitives" : [ { - "attributes" : { - "POSITION" : 1 - }, - "indices" : 0 - } ] - } - ], - "buffers" : [ - { - %s - "byteLength" : %d - } - ], - "bufferViews" : [ - { - "buffer" : 0, - "byteOffset" : 0, - "byteLength" : %d, - "target" : 34963 - }, - { - "buffer" : 0, - "byteOffset" : %d, - "byteLength" : %d, - "target" : 34962 - } - ], - "accessors" : [ - { - "bufferView" : 0, - "byteOffset" : 0, - "componentType" : 5125, - "count" : %d, - "type" : "SCALAR", - "max" : [ %d ], - "min" : [ 0 ] - }, - { - "bufferView" : 1, - "byteOffset" : 0, - "componentType" : 5126, - "count" : %d, - "type" : "VEC3", - "min" : [%f, %f, %f], - "max" : [%f, %f, %f] - } - ], - "asset" : { - "version" : "2.0" - } -} -''' - - header_bytes = 80 - unsigned_long_int_bytes = 4 - float_bytes = 4 - vec3_bytes = 4 * 3 - spacer_bytes = 2 - num_vertices_in_face = 3 - - vertices = {} - indices = [] - - if not is_binary: - out_bin = os.path.join(out_path, "out.bin") - out_gltf = os.path.join(out_path, "out.gltf") - else: - out_bin = out_path - - unpack_face = struct.Struct("<12fH").unpack - face_bytes = float_bytes*12 + 2 - - with open(path_to_stl, "rb") as f: - f.seek(header_bytes) # skip 80 bytes headers - - num_faces_bytes = f.read(unsigned_long_int_bytes) - number_faces = struct.unpack(" maxx: maxx = x - if y < miny: miny = y - if y > maxy: maxy = y - if z < minz: minz = z - if z > maxz: maxz = z - - # f.seek(spacer_bytes, 1) # skip the spacer - - number_vertices = len(vertices) - vertices_bytelength = number_vertices * vec3_bytes # each vec3 has 3 floats, each float is 4 bytes - unpadded_indices_bytelength = number_vertices * unsigned_long_int_bytes - - out_number_vertices = len(vertices) - out_number_indices = len(indices) - - unpadded_indices_bytelength = out_number_indices * unsigned_long_int_bytes - indices_bytelength = (unpadded_indices_bytelength + 3) & ~3 - - out_bin_bytelength = vertices_bytelength + indices_bytelength - - if is_binary: - out_bin_uir = "" - else: - out_bin_uir = '"uri": "out.bin",' - - gltf2 = gltf2 % ( out_bin_uir, - #buffer - out_bin_bytelength, - - # bufferViews[0] - indices_bytelength, - - # bufferViews[1] - indices_bytelength, - vertices_bytelength, - - # accessors[0] - out_number_indices, - out_number_vertices - 1, - - # accessors[1] - out_number_vertices, - minx, miny, minz, - maxx, maxy, maxz - ) - - glb_out = bytearray() - if is_binary: - gltf2 = gltf2.replace(" ", "") - gltf2 = gltf2.replace("\n", "") - - scene = bytearray(gltf2.encode()) - - scene_len = len(scene) - padded_scene_len = (scene_len + 3) & ~3 - body_offset = padded_scene_len + 12 + 8 - - file_len = body_offset + out_bin_bytelength + 8 - - # 12-byte header - glb_out.extend(struct.pack(' 3: - is_binary = True - else: - is_binary = False - - if out_path.lower().endswith(".glb"): - print("Use binary mode since output file has glb extension") - is_binary = True - else: - if is_binary: - print("output file should have glb extension but not %s", out_path) - - if not os.path.exists(path_to_stl): - print("stl file does not exists %s" % path_to_stl) - - if not is_binary: - if not os.path.isdir(out_path): - os.mkdir(out_path) - - stl_to_gltf(path_to_stl, out_path, is_binary) \ No newline at end of file diff --git a/owl_demo/static/src/js/3d_viewer/test.glb b/owl_demo/static/src/js/3d_viewer/test.glb deleted file mode 100644 index c4a6352b..00000000 Binary files a/owl_demo/static/src/js/3d_viewer/test.glb and /dev/null differ diff --git a/owl_demo/static/src/js/components/MyComponent.js b/owl_demo/static/src/js/components/MyComponent.js deleted file mode 100644 index 7000aa9e..00000000 --- a/owl_demo/static/src/js/components/MyComponent.js +++ /dev/null @@ -1,25 +0,0 @@ -/** @odoo-module **/ - -const { Component, useState, mount, whenReady, xml } = owl; - -export class MyComponent extends Component { - static template = 'owl_demo.my_component' - - - setup() { - this.state = useState({ is_show:true}); - } - - onRemove(ev) { - this.state.is_show = false; - } - -} - -//MyComponent.template = 'owl_demo.MyComponent'; - -whenReady(() => { - var my_component = new MyComponent(); - mount(my_component, document.body); - //$("#myModal").modal('show'); -}); \ No newline at end of file diff --git a/owl_demo/static/src/js/components/PartnerOrderSummary.js b/owl_demo/static/src/js/components/PartnerOrderSummary.js deleted file mode 100644 index 39cce4ba..00000000 --- a/owl_demo/static/src/js/components/PartnerOrderSummary.js +++ /dev/null @@ -1,84 +0,0 @@ -/** @odoo-module **/ - -const { Component, useState, mount, xml } = owl; - -import { registry } from "@web/core/registry"; -import { formView } from "@web/views/form/form_view"; -import { FormCompiler } from "@web/views/form/form_compiler"; -import { FormRenderer } from '@web/views/form/form_renderer'; - -class PartnerOrderSummary extends Component { - partner = useState({}); - constructor(self, partner) { - super(); - this.partner = partner; - } -}; - -PartnerOrderSummary.template = "owl_demo.PartnerOrderSummary"; - - -function compilePartner(el, params) { -// this._rpc({ -// model: "res.partner", -// method: "read", -// args: [[this.state.data.partner_id.res_id]] -// }).then(data => { -// (new ComponentWrapper(this, -// PartnerOrderSummary, -// useState(data[0]) -// )).mount(element); -// }); - - return "

hello world

"; -} - -function compileForm() { - const res = this.compileForm(...arguments); - res.classList.append("test111"); - return res; -} - -export class SaleOrderFormCompiler extends FormCompiler { - setup() { - super.setup(); - this.compilers.unshift( - { selector: "form", fn: compileForm }, - { selector: "div .o_partner_order_summary", fn: compilePartner } - ); - } -} - -export class SaleOrderFormRenderer extends FormRenderer { } - -SaleOrderFormRenderer.components = { - ...FormRenderer.components, - PartnerOrderSummary, -}; - -registry.category('views').add('sale.view_order_form', { - ...formView, - Compiler: SaleOrderFormCompiler, - Renderer: SaleOrderFormRenderer, -}); - - -/*** 重载表单渲染器,对任何包含o_partner_order_summary这一class 的div挂载当前组件 */ -//FormRenderer.include({ -// _render: async function() { -// await this._super(...arguments); -// for (const element of this.el.querySelectorAll(".o_partner_order_summary")) { -// this._rpc({ -// model: "res.partner", -// method: "read", -// args: [[this.state.data.partner_id.res_id]] -// }).then(data => { -// (new ComponentWrapper(this, -// PartnerOrderSummary, -// useState(data[0]) -// )).mount(element); -// }); -// } -// } -//}); - diff --git a/owl_demo/static/src/js/html_template/template_demo_field.xml b/owl_demo/static/src/js/html_template/template_demo_field.xml deleted file mode 100644 index 43b015d1..00000000 --- a/owl_demo/static/src/js/html_template/template_demo_field.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - -
    -
  • Cras justo odio
  • -
  • Dapibus ac facilisis in
  • -
  • Morbi leo risus
  • -
  • Porta ac consectetur ac
  • -
  • Vestibulum at eros
  • -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- - - -
- - - - - - - - - - - - - -
diff --git a/owl_demo/static/src/js/html_template/template_field.js b/owl_demo/static/src/js/html_template/template_field.js deleted file mode 100644 index 90b2425c..00000000 --- a/owl_demo/static/src/js/html_template/template_field.js +++ /dev/null @@ -1,97 +0,0 @@ -/** @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 { session } from "@web/session"; -import core from 'web.core'; -import rpc from 'web.rpc'; - -var QWeb = core.qweb; - -import { Component,useRef,useEffect } from "@odoo/owl"; - -export class CTemplateField extends Component { - setup() { - this.show_template = useRef('showTemplate') - useInputField({ - getValue: () => this.props.value || "" - }); - - useEffect( - (el) => { - if (!el) { - return; - } - return this.formatTemplate($(el)); - }, - () => [this.show_template.el], - ) - } - - formatTemplate($el) { - console.log($el) - var self=this; - if (this.props.readonly && this.props.value) { - //value = this.props.value + ' | ' + this.props.template_xml_id; - if (this.props.type == 'one2many' || this.props.type == 'many2many'){ - // 如果是one2many或many2many,就重新获取对象列表 - rpc.query({ - model: this.props.value.resModel, - method: 'read', - args: [this.props.value.currentIds,[]], - }).then((result) => { - console.log(result); - return $el.html(QWeb.render(this.props.template_xml_id,{'record':this.props.record,'current_field':result})) - }); - } - else if (this.props.type == 'many2one'){ - // 如果是one2many或many2many,就重新获取对象列表 - rpc.query({ - model: this.props.record.fields[this.props.name].relation, - method: 'read', - args: [this.props.value[0],[]], - }).then((result) => { - console.log(result); - return $el.html(QWeb.render(this.props.template_xml_id,{'record':this.props.record,'current_field':result[0]})) - }); - } - else{ - if (this.props.template_xml_id === undefined) - { - return $el.html(this.props.value); - }else{ - return $el.html(QWeb.render(this.props.template_xml_id,{'record':this.props.record,'current_field':this.props.value})); - } - - } - } - - // - } - -} - -CTemplateField.template = "owl_demo.CTemplateField"; -CTemplateField.props = { - ...standardFieldProps, - template_xml_id: { type: String, optional: true }, - placeholder: { type: String, optional: true }, -}; -CTemplateField.defaultProps = { -// hideSymbol: false, -// inputType: "text", -}; - -CTemplateField.supportedTypes = ["many2one","char"]; -CTemplateField.displayName = _lt("CTemplate"); - -CTemplateField.extractProps = ({ attrs }) => { - return { - template_xml_id: attrs.options.template, - placeholder: attrs.placeholder, - }; -}; - -registry.category("fields").add("CTemplate", CTemplateField); diff --git a/owl_demo/static/src/js/html_template/template_field.scss b/owl_demo/static/src/js/html_template/template_field.scss deleted file mode 100644 index 021ef387..00000000 --- a/owl_demo/static/src/js/html_template/template_field.scss +++ /dev/null @@ -1,3 +0,0 @@ -.o_field_widget.o_field_template { - display: block; -} diff --git a/owl_demo/static/src/js/html_template/template_field.xml b/owl_demo/static/src/js/html_template/template_field.xml deleted file mode 100644 index fbeb7274..00000000 --- a/owl_demo/static/src/js/html_template/template_field.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - -
- - - diff --git a/owl_demo/static/src/js/services/notification.js b/owl_demo/static/src/js/services/notification.js deleted file mode 100644 index 2096cd3a..00000000 --- a/owl_demo/static/src/js/services/notification.js +++ /dev/null @@ -1,25 +0,0 @@ -/** @odoo-module **/ - -import { registry } from "@web/core/registry"; - -const serviceRegistry = registry.category("services"); - -const myService = { - dependencies: ["notification","title","effect"], - start(env, { notification, title,effect }) { - -// let counter = 1; -// setInterval(() => { -// var tik_str = `Tick Tock ${counter++}`; -// notification.add(tik_str); -// title.setParts({ odoo: tik_str, fruit: tik_str }); -// effect.add({ -// type: "rainbow_man", // can be omitted, default type is already "rainbow_man" -// message: "Boom! Team record for the past 30 days." + tik_str, -// }); -// }, 5000); - - } -}; - -serviceRegistry.add("myService", myService); \ No newline at end of file diff --git a/owl_demo/static/src/js/widgets/MyWidget.js b/owl_demo/static/src/js/widgets/MyWidget.js deleted file mode 100644 index 49452cc6..00000000 --- a/owl_demo/static/src/js/widgets/MyWidget.js +++ /dev/null @@ -1,50 +0,0 @@ -/** @odoo-module **/ - -import AbstractField from 'web.AbstractField'; -import fieldRegistry from 'web.field_registry'; - -export const ShowUnitsWidgetField = AbstractField.extend({ - supportedFieldTypes: ['float','char','datetime'], - - /** - * @override - */ -// init: function () { -// this._super.apply(this, arguments); -// this.units = this.nodeOptions && this.nodeOptions.units || ''; -// }, - - /** - * @override - */ - _renderReadonly() { - this.units = this.nodeOptions && this.nodeOptions.units || ''; - this.$el.empty().html(this._formatValue(this.value) + " "+this.units+""); - }, - -}); - -fieldRegistry.add('show_units', ShowUnitsWidgetField); - -export const ShowUnitsWidgetField = AbstractField.extend({ - supportedFieldTypes: ['float','char','datetime'], - - /** - * @override - */ -// init: function () { -// this._super.apply(this, arguments); -// this.units = this.nodeOptions && this.nodeOptions.units || ''; -// }, - - /** - * @override - */ - _renderReadonly() { - this.units = this.nodeOptions && this.nodeOptions.units || ''; - this.$el.empty().html(this._formatValue(this.value) + " "+this.units+""); - }, - -}); - -fieldRegistry.add('show_units', ShowUnitsWidgetField); \ No newline at end of file diff --git a/owl_demo/static/src/xml/MyComponent.xml b/owl_demo/static/src/xml/MyComponent.xml deleted file mode 100644 index 6db9e2b2..00000000 --- a/owl_demo/static/src/xml/MyComponent.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - -
- -
-
- -
\ No newline at end of file diff --git a/owl_demo/static/src/xml/MyWidget.xml b/owl_demo/static/src/xml/MyWidget.xml deleted file mode 100644 index 00a6b92c..00000000 --- a/owl_demo/static/src/xml/MyWidget.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/owl_demo/static/src/xml/PartnerOrderSummary.xml b/owl_demo/static/src/xml/PartnerOrderSummary.xml deleted file mode 100644 index 1f1c5664..00000000 --- a/owl_demo/static/src/xml/PartnerOrderSummary.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - -
- - -

- -

- - - -

- -
-
-

- -

-

Orders

-
-
-

- -

-

Total Sales

-
-
-
-
-
\ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..983276ee --- /dev/null +++ b/requirements.txt @@ -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 \ No newline at end of file diff --git a/sf_base/models/common.py b/sf_base/models/common.py index 9c025a57..a1c33521 100644 --- a/sf_base/models/common.py +++ b/sf_base/models/common.py @@ -49,6 +49,7 @@ class MrsProductionProcess(models.Model): processing_order_ids = fields.One2many('sf.processing.order', 'production_process_id', string='工序') partner_process_ids = fields.Many2many('res.partner', 'process_ids', '加工工厂') active = fields.Boolean('有效', default=True) + parameter_ids = fields.One2many('sf.production.process.parameter', 'process_id', string='可选参数') class MrsProcessingTechnology(models.Model): @@ -96,3 +97,12 @@ class SupplierSort(models.Model): ('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("编码") \ No newline at end of file diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index d4441085..c9e93e5b 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -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_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 diff --git a/sf_base/views/common_view.xml b/sf_base/views/common_view.xml index 3b4e7935..be899852 100644 --- a/sf_base/views/common_view.xml +++ b/sf_base/views/common_view.xml @@ -74,6 +74,32 @@ + + + + + + + + +
+ + + + + + + + + + + + + + +
+
+
diff --git a/sf_mrs_connect/data/ir_cron_data.xml b/sf_mrs_connect/data/ir_cron_data.xml index 94109b13..7e9d2e86 100644 --- a/sf_mrs_connect/data/ir_cron_data.xml +++ b/sf_mrs_connect/data/ir_cron_data.xml @@ -131,4 +131,15 @@ -1 + + + 同步表面工艺可选参数 + + code + model.sync_production_process_parameter() + 1 + days + -1 + + \ No newline at end of file diff --git a/sf_mrs_connect/models/res_config_setting.py b/sf_mrs_connect/models/res_config_setting.py index 7473c5c9..9a61ce8d 100644 --- a/sf_mrs_connect/models/res_config_setting.py +++ b/sf_mrs_connect/models/res_config_setting.py @@ -2,7 +2,7 @@ # Part of SmartGo. See LICENSE file for full copyright and licensing details. import logging from odoo import api, fields, models - +from odoo.exceptions import ValidationError _logger = logging.getLogger(__name__) @@ -19,29 +19,33 @@ class ResConfigSettings(models.TransientModel): ftp_password = fields.Char(string='FTP密码') def sf_all_sync(self): - self.env['sf.production.materials'].sync_all_production_materials() - _logger.info("同步资源库材料") - self.env['sf.materials.model'].sync_all_materials_model() - _logger.info("同步资源库材料型号") - self.env['sf.production.process'].sync_all_production_process() - _logger.info("同步资源库表面工艺") - self.env['sf.processing.technology'].sync_all_processing_technology() - _logger.info("同步资源库加工工艺") - self.env['sf.machine.brand.tags'].sync_all_machine_brand_tags() - _logger.info("同步资源库品牌类别") - self.env['sf.machine.brand'].sync_all_machine_brand() - _logger.info("同步资源库品牌") - self.env['sf.machine.control_system'].sync_all_machine_tool_type_control_system() - _logger.info("同步资源库控制系统") - # self.env['sf.machine_tool'].sync_all_machine_tool() - # _logger.info("同步机床行业编码") - self.env['sf.machine_tool.type'].sync_all_machine_tool_type() - _logger.info("同步资源库机床型号") - self.env['sf.cutting_tool.category'].sync_all_cutting_tool_category() - _logger.info("同步资源库刀具类别") - self.env['sf.cutting_tool.type'].sync_all_cutting_tool_type() - _logger.info("同步资源库刀具") - # self.env['sf.processing.order'].sync_all_processing_order() + try: + self.env['sf.production.materials'].sync_all_production_materials() + _logger.info("同步资源库材料") + self.env['sf.materials.model'].sync_all_materials_model() + _logger.info("同步资源库材料型号") + self.env['sf.production.process'].sync_all_production_process() + _logger.info("同步资源库表面工艺") + self.env['sf.processing.technology'].sync_all_processing_technology() + _logger.info("同步资源库加工工艺") + self.env['sf.machine.brand.tags'].sync_all_machine_brand_tags() + _logger.info("同步资源库品牌类别") + self.env['sf.machine.brand'].sync_all_machine_brand() + _logger.info("同步资源库品牌") + self.env['sf.machine.control_system'].sync_all_machine_tool_type_control_system() + _logger.info("同步资源库控制系统") + self.env['sf.machine_tool.type'].sync_all_machine_tool_type() + _logger.info("同步资源库机床型号") + self.env['sf.cutting_tool.category'].sync_all_cutting_tool_category() + _logger.info("同步资源库刀具类别") + self.env['sf.cutting_tool.type'].sync_all_cutting_tool_type() + _logger.info("同步资源库刀具") + self.env['sf.production.process.parameter'].sync_all_production_process_parameter() + _logger.info("同步表面工艺参数") + except Exception as e: + _logger.info("捕获错误信息:%s" % e) + raise ValidationError("数据错误导致同步失败,请联系管理员") + @api.model def get_values(self): diff --git a/sf_mrs_connect/models/sync_common.py b/sf_mrs_connect/models/sync_common.py index 08ee61f3..6cdd98ba 100644 --- a/sf_mrs_connect/models/sync_common.py +++ b/sf_mrs_connect/models/sync_common.py @@ -948,3 +948,75 @@ class sfProcessingOrder(models.Model): }) else: 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("认证未通过") \ No newline at end of file