Commit a1bdf5d3 by 夏超

[add] 新增东联项目功能

parent 57791b52
import datetime
import json
import os
from jinja2 import FileSystemLoader, Environment
from odoo import models, fields, api, http, SUPERUSER_ID, _
from odoo.addons.roke_mes_production.controller.work_report import WorkReportKanban
import logging
import math
_logger = logging.getLogger(__name__)
class JzjxRokeRefixAutoWorkOrder(http.Controller):
@http.route('/roke/mes/work_time/get', type='json', auth="user", csrf=False, cors='*')
def get_work_time(self):
"""
获取工时树
:return:
"""
uid = http.request.uid or http.request.session.uid
if not uid:
return {"code": 1, "message": "当前位置尚未登录,请先登录", "work_hours": 0}
start_record = http.request.env(user=SUPERUSER_ID)['roke.work.start.record'].search([
("user_id", "=", uid),
("state", "=", "工作中")
], limit=1)
if not start_record:
return {"code": 1, "message": "未开工,请先开工。", "work_hours": 0}
delta = datetime.datetime.now() - start_record.start_time
work_hours = round(delta.total_seconds() / 3600, 2)
return {"code": 0, "message": "获取成功!", "work_hours": work_hours}
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
templateloader = FileSystemLoader(searchpath=BASE_DIR + "/static/src/html/view")
env = Environment(loader=templateloader)
class JzjxRokeWorkReportKanban(WorkReportKanban):
@http.route('/roke/work/report/work_order_report', type='http', auth='public', csrf=False)
def work_order_report(self):
"""工单报工"""
values = {}
# 修改Jinja2 分隔符
env.variable_start_string = '[['
env.variable_end_string = ']]'
template = env.get_template('zdy_gdbg.html')
html = template.render(values)
return html
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="fscut_app_app_id" model="ir.config_parameter">
<field name="key">fscut.app_id</field>
<field name="value">op191458064d64e10d</field>
</record>
<record id="fscut_app_secret" model="ir.config_parameter">
<field name="key">fscut.app_secret</field>
<field name="value">64a9af1225e0e10ad20d532d8037a211ea679345313969fe8f277fa78f85e92d</field>
</record>
</data>
</odoo>
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="ir_cron_sync_user_devices" model="ir.cron">
<field name="name">获取机床列表</field>
<field name="model_id" ref="model_roke_work_center"/>
<field name="state">code</field>
<field name="code">model.get_user_devices()</field>
<field name="interval_number">1</field>
<field name="interval_type">months</field>
<field name="numbercall">-1</field>
<field name="doall" eval="True"/>
<field name="active" eval="False" />
</record>
<record id="ir_cron_sync_work_logs" model="ir.cron">
<field name="name">获取机床加工记录</field>
<field name="model_id" ref="model_roke_work_center"/>
<field name="state">code</field>
<field name="code">
# 默认取当前时间前十分钟的加工记录。
# 如果需要取其它时间的价格记录,请入参开始/结束时间(格式“年-月-日 时:分:秒”);
# 如果需求取当前时间的前20分钟的加工记录,那么入参时间间隔time_interval(单位分钟)。
# 比如:model.get_work_logs(start_time="2024-01-01 0:00:00", end_time="2024-01-01 8:00:00") 或 model.get_work_logs(time_interval=20)
model.get_work_logs()
</field>
<field name="interval_number">10</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="doall" eval="True"/>
<field name="active" eval="False" />
</record>
</data>
</odoo>
\ No newline at end of file
from . import inherit_roke_work_order
from . import inherit_production_task
from . import inherit_workcenter
from . import work_log
from . import inherit_roke_routing
# import requests
#
# import re
#
#
# def process_url(web_base_url):
# # 替换 http:// 或 https://
# web_base_url = re.sub(r'^https?://', '', web_base_url)
# # 删除斜杠 /
# web_base_url = web_base_url.replace("/", "")
# return web_base_url
#
# # Uncaught (in promise) TypeError: self.keepRun is not a function
# # 测试
# web_base_url = "https://example.com/"
# processed_url = process_url(web_base_url)
#
#
# def upload_file(url, file_path, processed_url):
# try:
# files = {'file': open(file_path, 'rb')}
# print({'file': open(file_path, 'rb')})
# data = {'filePath': processed_url}
# response = requests.post(url, files=files, data=data)
# if response.status_code == 200:
# return response.json()
# else:
# return None
# except requests.exceptions.RequestException as e:
# return e
#
#
# file_path = r"C:\Users\zhangsan\Desktop\改BL320200-70S底盖(2).SLDPRT"
#
# data = upload_file(url, file_path, processed_url)
# if data:
# print("获取到的数据:", data)
# else:
# print("获取数据失败。")
# import json
# import requests
#
# url = "http://123.129.207.22:8088/cad/uploadFileUrl"
# dict_ = {
# 'ossId': "1772107631008669698",
# 'url': "http://121.37.69.162:9000/roke/localhost:8022/2024/03/25/274c6b3c80e34b059563874f5600ac20.DXF"
# }
#
# json_ = json.dumps(dict_, ensure_ascii=False)
# datas = requests.post(url, data=json_)
# content = json.loads(datas.content)
# print(content)
# dataaaa = content["data"]
# print(dataaaa)
# -*- coding: utf-8 -*-
"""
Description:
Versions:
Created by www.rokedata.com<HuChuanwei>
"""
import hashlib
import json
import time
class OpenApiHeader:
def __init__(self, app_id, timestamp, app_sign):
self.appID = app_id
self.timestamp = timestamp
self.appSign = app_sign
def to_json(self):
data = {
"app-id": self.appID,
"time-stamp": str(self.timestamp),
"app-sign": self.appSign
}
return json.dumps(data)
def to_dict(self):
return {
"app-id": self.appID,
"time-stamp": self.timestamp,
"app-sign": self.appSign
}
class OpenApiHeaderHelper:
def __init__(self, app_id, app_secret):
self.app_id = app_id
self.app_secret = app_secret
def gen_json(self):
openApiHeader = self._do_gen_header()
return openApiHeader.to_json()
def gen_map(self):
openApiHeader = self._do_gen_header()
return openApiHeader.to_dict()
def _do_gen_header(self):
timestamp = int(time.time() * 1000)
appSign = self._do_md5_hash(self.app_id + self.app_secret + str(timestamp))
return OpenApiHeader(self.app_id, timestamp, appSign)
@staticmethod
def _do_md5_hash(content):
hash_object = hashlib.md5(content.encode())
return hash_object.hexdigest()
\ No newline at end of file
import datetime
import pymysql
import logging
from odoo import api, models, fields
_logger = logging.getLogger(__name__)
class InheritRokeRoutingLineModel(models.Model):
_inherit = "roke.routing.line"
def write(self, vals):
res = super(InheritRokeRoutingLineModel, self).write(vals)
return res
# -*- coding: utf-8 -*-
"""
Description:
激光切割机加工记录
Versions:
Created by www.rokedata.com<HuChuanwei>
"""
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
import logging
_logger = logging.getLogger(__name__)
class RokeWorkLog(models.Model):
_name = "roke.work.log"
_description = "加工记录"
_order = "id desc"
_rec_name = "materialName"
work_center_id = fields.Many2one("roke.work.center", string="工作中心", index=True)
fileName = fields.Char(string="图纸文件路径")
portionId = fields.Char(string="排版唯一标识", index=True)
startTime = fields.Char(string="加工开始时间")
endTime = fields.Char(string="加工结束时间")
timeTaken = fields.Integer(string="实际切割用时")
tmEstimate = fields.Float(string="预计用时")
curveLength = fields.Float(string="切割长度")
moveLength = fields.Float(string="空移长度")
pierceCount = fields.Integer(string="穿孔数")
endState = fields.Selection([("0", "已完成"), ("-1", "正在加工"), ("1", "暂停"), ("2", "停止"), ("4", "未知")], string="加工状态")
material = fields.Char(string="材质", index=True)
materialName = fields.Char(string="工艺文件名", index=True)
portionName = fields.Char(string="排版名称", index=True)
thickness = fields.Integer(string="厚度(mm)")
plateSize = fields.Char(string="排版尺寸", index=True)
selected = fields.Boolean(string="是否为选中加工")
boundSize = fields.Char(string="图形边框尺寸")
syncTime = fields.Datetime(string="数据同步时间")
partAmount = fields.Integer(string="零件数量")
workUuid = fields.Char(string="加工记录标识", index=True)
taskUuid = fields.Char(string="任务标识")
part_ids = fields.One2many("roke.work.log.part", "log_id", string="零件信息")
@api.model
def create(self, vals):
res = super(RokeWorkLog, self).create(vals)
# file_list = res.fileName.split("\\")
# if not file_list:
# return res
# file_name = file_list[-1].split("_")
# if not file_name:
# return res
# task_code = file_name[0]
# task = self.env["roke.production.task"].sudo().search([("code", "=", task_code)])
# if not task:
# return res
# work_order = self.env["roke.work.order"].sudo().search([("process_id.name", "ilike", "切割")], limit=1)
# if not work_order:
# return res
# try:
# work_order.app_confirm(
# finish_qty=sum(res.part_ids.mapped("amount")),
# employee_id=self.env.user.employee_id.id,
# unqualified_qty=0,
# work_hours=round(res.timeTaken / 3600, 2),
# team_id=0,
# )
# except Exception as e:
# _logger.info(f"{e}")
return res
class RokeWorkLogPart(models.Model):
_name = "roke.work.log.part"
_description = "加工记录配件"
log_id = fields.Many2one("roke.work.log", string="加工记录", required=True, ondelete="cascade")
partId = fields.Char(string="零件唯一标识")
name = fields.Char(string="零件名称")
amount = fields.Integer(string="单种零件完成数")
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_roke_work_log_user,roke_work_log_user,model_roke_work_log,base.group_user,1,0,0,0
access_roke_work_log_part_user,roke_work_log_part_user,model_roke_work_log_part,base.group_user,1,0,0,0
access_roke_work_log_system,roke_work_log_system,model_roke_work_log,base.group_system,1,1,1,1
access_roke_work_log_part_system,roke_work_log_part_system,model_roke_work_log_part,base.group_system,1,1,1,1
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="inherit_view_roke_mes_purchase_receiving_form" model="ir.ui.view">
<field name="name">inherit.roke.mes.stock.picking.form</field>
<field name="model">roke.mes.stock.picking</field>
<field name="inherit_id" ref="roke_mes_purchase.view_roke_mes_purchase_receiving_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='partner_id']" position="replace">
<field name="partner_id" options="{'no_create': True}"
attrs="{'readonly':[('state', '!=', '草稿')]}"
domain="[('supplier', '=', True)]"/>
</xpath>
</field>
</record>
<record id="inherit_view_roke_mes_general_in_form" model="ir.ui.view">
<field name="name">inherit.roke.mes.stock.picking.form</field>
<field name="model">roke.mes.stock.picking</field>
<field name="inherit_id" ref="roke_mes_stock.view_roke_mes_general_in_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='partner_id']" position="replace">
<field name="partner_id" options="{'no_create': True}"
attrs="{'readonly':[('state', '!=', '草稿')]}"
domain="[('supplier', '=', True)]"/>
</xpath>
</field>
</record>
<record id="inherit_view_roke_mes_sale_deliver_form" model="ir.ui.view">
<field name="name">inherit.roke.mes.stock.picking</field>
<field name="model">roke.mes.stock.picking</field>
<field name="inherit_id" ref="roke_mes_sale.view_roke_mes_sale_deliver_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='partner_id']" position="replace">
<field name="partner_id" options="{'no_create': True}"
attrs="{'readonly':[('state', '!=', '草稿')]}"
domain="[('customer', '=', True)]"/>
</xpath>
</field>
</record>
<record id="inherit_view_roke_mes_general_out_form" model="ir.ui.view">
<field name="name">inherit.roke.mes.stock.picking</field>
<field name="model">roke.mes.stock.picking</field>
<field name="inherit_id" ref="roke_mes_stock.view_roke_mes_general_out_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='partner_id']" position="replace">
<field name="partner_id" options="{'no_create': True}"
attrs="{'readonly':[('state', '!=', '草稿')]}"
domain="[('customer', '=', True)]"/>
</xpath>
</field>
</record>
</odoo>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="jzjx_inherit_work_center_kanban_view" model="ir.ui.view">
<field name="name">jzjx.inherit.roke.work.center.kanban.view</field>
<field name="model">roke.work.center</field>
<field name="inherit_id" ref="roke_mes_production.roke_work_center_kanban_view"/>
<field name="arch" type="xml">
<xpath expr="//div[@id='work_center_wo']" position="replace">
<div id="jzjx_work_center_state" class="row" style="display:flex;justify-content: center;align-items: center;font-size: 30px;">
<p style="color:#dee2e6;"><field name="deviceState"/></p>
</div>
</xpath>
<xpath expr="//div[@id='work_center_empty']" position="replace">
<div/>
</xpath>
</field>
</record>
<record id="jzjx_inherit_base_work_center_form_view" model="ir.ui.view">
<field name="name">jzjx.inherit.base.roke.work.center.form.view</field>
<field name="model">roke.work.center</field>
<field name="inherit_id" ref="roke_mes_base.view_roke_work_center_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='type_id']" position="after">
<field name="filename" readonly="1"/>
</xpath>
<xpath expr="//notebook" position="inside">
<page string="机床切割系统状态">
<group col="8">
<field name="axisX" readonly="1"/>
<field name="axisY" readonly="1"/>
<field name="axisZ" readonly="1"/>
<field name="workTimeStr" readonly="1"/>
<field name="workSpeed" readonly="1"/>
<field name="cutPercent" readonly="1"/>
<field name="laserPower" readonly="1"/>
<field name="pwmFreq" readonly="1"/>
<field name="gasType" readonly="1"/>
<field name="gasPressure" readonly="1"/>
<field name="pwmRatio" readonly="1"/>
<field name="targetHeight" readonly="1"/>
<field name="diodeCurrent" readonly="1"/>
</group>
</page>
</xpath>
</field>
</record>
<record id="jzjx_inherit_wc_work_center_form_view" model="ir.ui.view">
<field name="name">jzjx.inherit.wc.work.center.form.view</field>
<field name="model">roke.work.center</field>
<field name="inherit_id" ref="roke_mes_work_center.view_roke_production_wc_inherit_work_center_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='stock_location_id']" position="after">
<field name="portionId" readonly="1"/>
</xpath>
</field>
</record>
<!--TODO 模块没依赖roke_mes_workshop_inspect-->
<record id="jzjx_inherit_inspect_work_center_form_view" model="ir.ui.view">
<field name="name">jzjx.inherit.inspect.roke.work.center.form.view</field>
<field name="model">roke.work.center</field>
<field name="inherit_id" ref="roke_mes_workshop_inspect.view_roke_wi_inherit_work_center_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='before_inspect_scheme_id']" position="after">
<field name="startTime" readonly="1"/>
</xpath>
</field>
</record>
</odoo>
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--切割机加工记录-->
<!--search-->
<record id="view_roke_work_log_search" model="ir.ui.view">
<field name="name">roke.work.log.search</field>
<field name="model">roke.work.log</field>
<field name="arch" type="xml">
<search string="切割机加工记录">
<field name="work_center_id"/>
<field name="portionId"/>
<field name="material"/>
<field name="materialName"/>
<field name="portionName"/>
<field name="plateSize"/>
<field name="workUuid"/>
<filter name="endState_0" string="已完成" domain="[('endState', '=', '0')]"/>
<filter name="endState_-1" string="正在加工" domain="[('endState', '=', '-1')]"/>
<filter name="endState_1" string="暂停" domain="[('endState', '=', '1')]"/>
<filter name="endState_2" string="停止" domain="[('endState', '=', '2')]"/>
<separator/>
<filter name="filter_startTime" date="startTime" default_period="this_month"/>
<filter name="filter_endTime" date="endTime" default_period="this_month"/>
<filter name="filter_syncTime" date="syncTime" default_period="this_month"/>
<group expand="0" string="Group By">
<filter string="材质" name="group_material" context="{'group_by': 'material'}"/>
<filter string="加工状态" name="group_endState" context="{'group_by': 'endState'}"/>
</group>
</search>
</field>
</record>
<!--tree-->
<record id="view_roke_work_log_tree" model="ir.ui.view">
<field name="name">roke.work.log.tree</field>
<field name="model">roke.work.log</field>
<field name="priority">1000</field><!--数越大优先级越小-->
<field name="arch" type="xml">
<tree string="切割机加工记录" create="false" edit="false" delete="false" duplicate="false">
<field name="work_center_id" optional="show"/>
<field name="fileName" optional="show"/>
<field name="portionId" optional="show"/>
<field name="startTime" optional="show"/>
<field name="endTime" optional="show"/>
<field name="timeTaken" optional="show"/>
<field name="endState" optional="show"/>
<field name="tmEstimate" optional="hide"/>
<field name="curveLength" optional="hide"/>
<field name="moveLength" optional="hide"/>
<field name="pierceCount" optional="hide"/>
<field name="material" optional="show"/>
<field name="materialName" optional="show"/>
<field name="portionName" optional="show"/>
<field name="thickness" optional="show"/>
<field name="plateSize" optional="hide"/>
<field name="selected" optional="hide"/>
<field name="boundSize" optional="hide"/>
<field name="syncTime" optional="hide"/>
<field name="partAmount" optional="show"/>
<field name="workUuid" optional="hide"/>
<field name="taskUuid" optional="hide"/>
</tree>
</field>
</record>
<!--form-->
<record id="view_roke_work_log_form" model="ir.ui.view">
<field name="name">roke.work.log.form</field>
<field name="model">roke.work.log</field>
<field name="arch" type="xml">
<form string="切割机加工记录" create="false" edit="false" delete="false" duplicate="false">
<header>
<field name="endState" widget="statusbar"/>
</header>
<group id="g1" col="4">
<group>
<field name="work_center_id" optional="show"/>
<field name="fileName" optional="show"/>
<field name="portionId" optional="show"/>
<field name="startTime" optional="show"/>
<field name="endTime" optional="show"/>
</group>
<group>
<field name="timeTaken" optional="show"/>
<field name="tmEstimate" optional="hide"/>
<field name="curveLength" optional="hide"/>
<field name="moveLength" optional="hide"/>
<field name="pierceCount" optional="hide"/>
</group>
<group>
<field name="material" optional="show"/>
<field name="materialName" optional="show"/>
<field name="portionName" optional="show"/>
<field name="thickness" optional="show"/>
</group>
<group>
<field name="selected" optional="hide"/>
<field name="boundSize" optional="hide"/>
<field name="syncTime" optional="hide"/>
<field name="workUuid" optional="hide"/>
</group>
</group>
<notebook>
<page string="零件信息">
<field name="part_ids">
<tree>
<field name="log_id" invisible="1"/>
<field name="partId"/>
<field name="name"/>
<field name="amount"/>
</tree>
<form>
<group>
<group>
<field name="log_id"/>
<field name="partId"/>
</group>
<group>
<field name="name"/>
<field name="amount"/>
</group>
</group>
</form>
</field>
</page>
</notebook>
</form>
</field>
</record>
<!--action-->
<record id="view_roke_work_log_action" model="ir.actions.act_window">
<field name="name">切割机加工记录</field>
<field name="res_model">roke.work.log</field>
<field name="view_mode">tree,form</field>
<field name="type">ir.actions.act_window</field>
<field name="domain">[]</field>
<field name="context">{'create': False, 'edit': False, 'delete': False}</field>
</record>
<menuitem id="roke_work_log_menu" name="切割机加工记录" parent="roke_mes_production.roke_production_report_menu"
action="view_roke_work_log_action" sequence="100"/>
</odoo>
from . import models
from . import controller
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': '生产-收入支出',
'depends': ['base', 'roke_mes_production'],
'author': 'www.rokedata.com',
'website': 'http://www.rokedata.com',
'description': """
""",
'data': [
'security/ir.model.access.csv',
'views/roke_product_income_expense.xml',
'views/template.xml',
],
'demo': [
# 'data/demo.xml',
],
'qweb':[
'static/src/xml/roke_product_income_expense_iframe.xml'
],
'application': True,
'installable': True,
'auto_install': False,
}
# -*- coding: utf-8 -*-
from . import main
import datetime
from odoo import http, tools
import os
from jinja2 import FileSystemLoader, Environment
import logging
_logger = logging.getLogger(__name__)
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
templateloader = FileSystemLoader(searchpath=BASE_DIR + "/static/src/js")
env = Environment(loader=templateloader)
class ProductIncomeExpenseIframe(http.Controller):
@http.route("/roke/pub/product_income_expense_iframe", type="http", auth='user', cors='*', csrf=False)
def product_income_expense_iframe(self, **kwargs):
_self = http.request
user_id = _self.env.user.id
user_name = _self.env.user.name
template = env.get_template('index.html')
data = {"code": 1, "message": "请求通过", "user_id": user_id, "user_name": user_name}
return template.render(data)
@http.route("/roke/product/product_income_expense/create", type="json", auth='none', cors='*', csrf=False)
def product_income_expense_create(self):
_self = http.request
data_list = _self.jsonrequest.get("data_list", [])
for v in data_list:
data = {
"business_date": v.get("business_date", False),
"abstract": v.get("abstract", False),
"income": v.get("income", False),
"expenditure": v.get("expenditure", False)
}
_self.env(user=v.get("user_id"))["roke.product.income.expense"].create(data)
return {"code": 0, "message": "创建成功!"}
@http.route("/roke/product/product_income_expense/get", type="json", auth='none', cors='*', csrf=False)
def product_income_expense_get_list(self):
_self = http.request
limit = _self.jsonrequest.get("limit", 20)
page = _self.jsonrequest.get("page", 1)
start_date = _self.jsonrequest.get("start_date", "")
end_date = _self.jsonrequest.get("end_date", "")
domain = []
if start_date and end_date:
domain.append(("business_date", ">=", start_date))
domain.append(("business_date", "<=", end_date))
data_list = _self.env["roke.product.income.expense"].sudo().search(domain, limit=limit,
offset=(page - 1) * limit,
order="business_date desc, create_date desc")
count = _self.env["roke.product.income.expense"].sudo().search_count(domain)
data = []
for v in data_list:
data.append({
"id": v.id,
"business_date": v.business_date and v.business_date.strftime('%Y-%m-%d'),
"abstract": v.abstract or "",
"income": v.income or 0,
"expenditure": v.expenditure or 0,
"balance": v.balance or 0,
"user_name": v.create_uid.name or "",
"create_date": (v.create_date + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M'),
})
return {"code": 0, "message": "获取成功!", "data": data, "count": count}
@http.route("/roke/product/product_income_expense/delete", type="json", auth='none', cors='*', csrf=False)
def product_income_expense_delete(self):
_self = http.request
del_id = _self.jsonrequest.get("del_id", False)
if not del_id:
return {"code": 1, "message": "删除失败,没找到对应数据。"}
data = _self.env["roke.product.income.expense"].sudo().search([("id", "=", del_id)])
if not data:
return {"code": 1, "message": "删除失败,没找到对应数据。"}
data.unlink()
return {"code": 0, "message": "删除成功!"}
import calendar
import requests
import datetime as date_time
from datetime import datetime
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
class ProductIncomeExpense(models.Model):
_name = "roke.product.income.expense"
business_date = fields.Date(string="业务日期")
abstract = fields.Text(string="摘要")
income = fields.Float(string="收入")
expenditure = fields.Float(string="支出")
balance = fields.Float(string="结余", compute="_compute_balance")
@api.depends("income", "expenditure")
def _compute_balance(self):
data = self.search([("id", "in", self.ids)], order="business_date asc, create_date asc")
for v in data:
last_data = self.search([
"|",
"&",
("business_date", "=", v.business_date),
("create_date", "<", v.create_date),
("business_date", "<", v.business_date),
("id", "!=", v.id)
], limit=1, order="business_date desc, create_date desc")
if not last_data:
v.balance = 0 + v.income - v.expenditure
else:
v.balance = last_data.balance + v.income - v.expenditure
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_roke_product_income_expense,roke_product_income_expense,model_roke_product_income_expense,base.group_system,1,1,1,1
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
odoo.define('roke_product_income_expense.product_income_expense_iframe', function (require) {
"use strict";
var core = require('web.core');
var session = require('web.session');
var AbstractAction = require('web.AbstractAction');
var ProductIncomeExpenseIFrame = AbstractAction.extend({
template: 'ProductIncomeExpenseIFrame',
init: function (parent, action, params) {
this.add_sum = 0
this.key = ""
this.old_data = {}
this.action_controller = `${action.params.controller}?user_id=${session.uid}&user_name=${session.name}`
return this._super.apply(this, arguments);
},
});
core.action_registry.add('product_income_expense_iframe', ProductIncomeExpenseIFrame);
return ProductIncomeExpenseIFrame;
});
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="ProductIncomeExpenseIFrame">
<iframe id="ProductIncomeExpenseIFrame" t-attf-src="#{widget.action_controller}" style="width: 100%;height: 100%;border: none;"></iframe>
</t>
</templates>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="roke_product_income_expense_iframe_action" model="ir.actions.client">
<field name="name">财务收支记录</field>
<field name="tag">product_income_expense_iframe</field>
<field name="target">current</field>
<field name="params" eval="{'controller': '/roke/pub/product_income_expense_iframe'}"/>
</record>
<menuitem
id="roke_product_income_expense_iframe_menu"
name="收入支出表"
action="roke_product_income_expense_iframe_action"
parent="roke_mes_production.roke_production_business_menu"
sequence="60"
groups="base.group_system"
/>
</odoo>
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!--id 为自定义,唯一标识符 ,inherit_id 是继承自哪里,为固定写法-->
<template id="product_income_expense_id" inherit_id="web.assets_backend">
<!--我们用xpath 找到我们要放置的地方-->
<xpath expr="." position="inside">
<script type="text/javascript" src="/roke_product_income_expense/static/src/js/roke_product_income_expense_iframe.js"/>
</xpath>
</template>
</odoo>
\ No newline at end of file
# -*- coding: utf-8 -*-
from . import models
from . import controllers
from . import wizard
# -*- coding: utf-8 -*-
{
'name': '融科-玖姿机械',
'name': '融科-大东联石油',
'version': '14.0',
'category': 'mes',
'depends': ['roke_mes_purchase', 'roke_mes_sale', 'roke_mes_documents', 'roke_mes_stock', 'roke_workstation_api',
......@@ -11,15 +11,11 @@
玖姿机械
""",
'data': [
'datas/config_parameter_data.xml',
'datas/cron_data.xml',
'security/ir.model.access.csv',
'views/inherit_roke_mes_stock_picking_views.xml',
'views/inherit_roke_production_task.xml',
'views/button_js.xml',
'views/iniherit_work_order_view.xml',
'views/roke_work_log_views.xml',
'views/iniherit_work_center_view.xml',
'views/inherit_roke_product.xml'
],
'qweb': [
"static/src/xml/roke_craft_design.xml",
......
......@@ -168,8 +168,7 @@ class RokeWorkstationWorkOrderModel(http.Controller):
for line in lines:
if line["type"] == "delete":
line_id = line["line_id"]
routing_obj.line_ids.filtered(
lambda l: l.id == line_id).unlink()
routing_obj.line_ids.filtered(lambda l: l.id == line_id).unlink()
elif line["type"] == "add":
sequence = line["sequence"]
process_id = line["process_id"]
......
from . import inherit_roke_work_order
from . import inherit_production_task
from . import inherit_roke_routing_line
from . import inherit_roke_product
......@@ -13,12 +13,6 @@ class InheritProductionTask(models.Model):
_inherit = "roke.production.task"
file_ids = fields.Many2many("ir.attachment", "roke_production_task_ir_attachment", "pro_id", "att_id")
taskName = fields.Char(string="任务名称")
UploadMsg = fields.Char(string="上传状态")
TaskUUID = fields.Char(string="任务UUID")
spare_parts_qty = fields.Float(string="切割零部件数", default=0)
press_riveting_qty = fields.Float(string="压铆零部件数", default=0)
bending_qty = fields.Float(string="折弯零部件数", default=0)
work_order_hours = fields.Float(string="总报工时", compute="_compute_work_order_hours")
......@@ -27,23 +21,6 @@ class InheritProductionTask(models.Model):
for record in self:
record.work_order_hours = sum(record.work_order_ids.mapped("work_hours"))
def upload_task(self):
"""
上传任务 TODO 任务数量取计划数还是计划数-完成数?上传一次后还能再上传不?多个加工文件时,上传第一个还是最后一个?
:return:
"""
self.ensure_one()
if not self.work_center_id:
raise ValidationError("未指派工作中心,禁止上传")
if not self.work_center_id.card_id:
raise ValidationError("当前工作中心无控制卡信息,无法上传")
if not self.file_ids:
raise ValidationError("当前任务无加工文件,无法上传")
if not self.taskName:
raise ValidationError("必须填写任务名称")
attachment = self.file_ids[:1]
self.work_center_id.upload_task(self, attachment)
def write(self, vals):
res = super(InheritProductionTask, self).write(vals)
if vals.get('file_ids'):
......@@ -56,10 +33,6 @@ class InheritProductionTask(models.Model):
self.document_ids = [(4, a.id)]
return res
@api.onchange("routing_id", "product_id", "plan_qty", "type", "spare_parts_qty", "press_riveting_qty", "bending_qty")
def _onchange_routing_id(self):
return super(InheritProductionTask, self)._onchange_routing_id()
def change_routing_id_work_order(self, routing):
product = self.product_id
plan_qty = self.plan_qty
......@@ -75,8 +48,7 @@ class InheritProductionTask(models.Model):
work_order_data['planned_start_time'] = date
work_order_data['plan_date'] = date
work_order_data['priority'] = self.priority
work_orders.append(
(0, 0, work_order_data))
work_orders.append((0, 0, work_order_data))
else:
num = work_order_num // date_num
if num < 1:
......@@ -95,55 +67,9 @@ class InheritProductionTask(models.Model):
work_order_data['planned_start_time'] = date
work_order_data['plan_date'] = date
work_order_data['priority'] = self.priority
work_orders.append(
(0, 0, work_order_data))
work_orders.append((0, 0, work_order_data))
return work_orders
def _create_work_order_get_values(self, task, routing_line):
"""
任务生成工单获取工单数据
:return:
"""
res = super(InheritProductionTask, self)._create_work_order_get_values(task, routing_line)
rounding_type = self.env['ir.config_parameter'].sudo().get_param('e_bom.material.demand.rounding',
default="精确计算")
if "切割" in routing_line.process_id.name:
plan_qty = task.spare_parts_qty
elif "压铆" in routing_line.process_id.name:
plan_qty = task.press_riveting_qty
elif "折弯" in routing_line.process_id.name:
plan_qty = task.bending_qty
else:
plan_qty = task.plan_qty * routing_line.multiple
if rounding_type == "向上取整":
plan_qty = math.ceil(plan_qty)
elif rounding_type == "向下取整":
plan_qty = int(plan_qty)
res.update({"plan_qty": plan_qty})
return res
def _get_new_work_order_data(self, routing_line, product, plan_qty, task_type):
"""
onchang获取工单数据
:return:
"""
res = super(InheritProductionTask, self)._get_new_work_order_data(routing_line, product, plan_qty, task_type)
rounding_type = self.env['ir.config_parameter'].sudo().get_param('e_bom.material.demand.rounding', default="精确计算")
if "切割" in routing_line.process_id.name:
plan_qty = self.spare_parts_qty
elif "压铆" in routing_line.process_id.name:
plan_qty = self.press_riveting_qty
elif "折弯" in routing_line.process_id.name:
plan_qty = self.bending_qty
else:
plan_qty = self.plan_qty * routing_line.multiple
if rounding_type == "向上取整":
plan_qty = math.ceil(plan_qty)
elif rounding_type == "向下取整":
plan_qty = int(plan_qty)
res.update({"plan_qty": plan_qty})
return res
def craft_design(self):
if self.record_ids and not self.routing_id.routing_task_id:
raise ValidationError("该任务已报工,无法生成新的工艺设计。")
......
from datetime import timedelta
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
class InheritProductionTask(models.Model):
_inherit = "roke.product"
standard_hours = fields.Float(string='标准工时', help='产品的标准工时(小时)')
from odoo import models, fields, api, _
class InheritRokeRoutingLine(models.Model):
_inherit = "roke.routing.line"
rated_working_hours = fields.Float(string='标准工时', help='工序的标准工时(小时)')
class InheritRokeProcess(models.Model):
_inherit = "roke.process"
rated_working_hours = fields.Float(string='标准工时', help='工序的标准工时(小时)')
......@@ -30,52 +30,3 @@ class InheritWorkOrder(models.Model):
v.next_wo_id = v.repair_wr_id.work_order_id.id
else:
v.next_wo_id = next_wo[0].id
def _get_production_multiple(self, previous):
"""
获取当前生产倍数
:param previous:
:return:
"""
judge = "切割" in self.process_id.name or "压铆" in self.process_id.name or "折弯" in self.process_id.name
if not self.routing_line_id and not judge:
# 无工艺明细直接返回
return 1
if "切割" in self.process_id.name and self.task_id:
multiple = self.task_id.spare_parts_qty / self.task_id.plan_qty
elif "压铆" in self.process_id.name and self.task_id:
multiple = self.task_id.press_riveting_qty / self.task_id.plan_qty
elif "折弯" in self.process_id.name and self.task_id:
multiple = self.task_id.bending_qty / self.task_id.plan_qty
else:
multiple = self.routing_line_id.multiple
if len(previous) > 1:
# 取到最小数对应的前道工单
rel_previous = self._multi_previous_get_min_finished(previous)
rel_previous_judge = "切割" in rel_previous.process_id.name or "压铆" in rel_previous.process_id.name \
or "折弯" in rel_previous.process_id.name
if not rel_previous.routing_line_id.multiple and not rel_previous_judge: # 无倍数直接返回
return 1
if "切割" in rel_previous.process_id.name:
rel_previous_multiple = rel_previous.task_id.spare_parts_qty / rel_previous.task_id.plan_qty
elif "压铆" in rel_previous.process_id.name:
rel_previous_multiple = rel_previous.task_id.press_riveting_qty / rel_previous.task_id.plan_qty
elif "折弯" in rel_previous.process_id.name:
rel_previous_multiple = rel_previous.task_id.bending_qty / rel_previous.task_id.plan_qty
else:
rel_previous_multiple = rel_previous.routing_line_id.multiple
return multiple / rel_previous_multiple
if not previous.routing_line_id.multiple and not judge: # 无倍数直接返回
return 1
elif not previous and judge:
return 1
if "切割" in previous.process_id.name and self.task_id and previous.task_id:
previous_multiple = previous.task_id.spare_parts_qty / self.task_id.plan_qty
elif "压铆" in previous.process_id.name and self.task_id and previous.task_id:
previous_multiple = previous.task_id.press_riveting_qty / self.task_id.plan_qty
elif "折弯" in previous.process_id.name and self.task_id and previous.task_id:
previous_multiple = previous.task_id.bending_qty / self.task_id.plan_qty
else:
previous_multiple = previous.routing_line_id.multiple
return (multiple / previous_multiple) if previous_multiple else 0
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
,,,,,,,
\ No newline at end of file
......@@ -7,14 +7,14 @@
<!-- 禁止界面缩放 -->
<meta content="width=device-width,initial-scale=1.0, maximum-scale=1.0,user-scalable=0" name="viewport" />
<!-- 引入本地文件--Vue、axios、element-ui的样式文件、element-ui的JS文件-->
<link rel="stylesheet" href="/jzjx_project/static/src/html/element-ui/index.css" />
<link rel="stylesheet" href="/jzjx_project/static/src/html/assets/iconfont/iconfont.css" />
<script src="/jzjx_project/static/src/html/js/vue.js"></script>
<script src="/jzjx_project/static/src/html/js/axios.min.js"></script>
<script src="/jzjx_project/static/src/html/js/Sortable.min.js"></script>
<script src="/jzjx_project/static/src/html/js/vuedraggable.umd.min.js"></script>
<script src="/jzjx_project/static/src/html/element-ui/index.js"></script>
<script src="/jzjx_project/static/src/html/assets/iconfont/iconfont.js"></script>
<link rel="stylesheet" href="/sdddl_project/static/src/html/element-ui/index.css" />
<link rel="stylesheet" href="/sdddl_project/static/src/html/assets/iconfont/iconfont.css" />
<script src="/sdddl_project/static/src/html/js/vue.js"></script>
<script src="/sdddl_project/static/src/html/js/axios.min.js"></script>
<script src="/sdddl_project/static/src/html/js/Sortable.min.js"></script>
<script src="/sdddl_project/static/src/html/js/vuedraggable.umd.min.js"></script>
<script src="/sdddl_project/static/src/html/element-ui/index.js"></script>
<script src="/sdddl_project/static/src/html/assets/iconfont/iconfont.js"></script>
</head>
<body id="bodyId" style="display: none;">
......
odoo.define('jzjx_project.roke_craft_design', function (require) {
odoo.define('sdddl_project.roke_craft_design', function (require) {
"use strict";
var core = require('web.core');
......@@ -7,7 +7,7 @@ odoo.define('jzjx_project.roke_craft_design', function (require) {
const Dialog = require("web.Dialog");
var RokeCraftDesign = AbstractAction.extend({
template: 'jzjx_project.roke_craft_design',
template: 'sdddl_project.roke_craft_design',
init: function (parent, action, params) {
this.action_controller = `${action.params.controller}&user_id=${session.uid}`;
......@@ -74,6 +74,6 @@ odoo.define('jzjx_project.roke_craft_design', function (require) {
}
});
core.action_registry.add('jzjx_project.roke_craft_design', RokeCraftDesign);
core.action_registry.add('sdddl_project.roke_craft_design', RokeCraftDesign);
return RokeCraftDesign;
});
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="roke_routing_settings_template" xml:space="preserve">
<t t-name="jzjx_project.roke_craft_design">
<t t-name="sdddl_project.roke_craft_design">
<iframe id="roke_craft_design.xml_iframe" t-attf-src="#{widget.action_controller}" frameBorder="no" width="100%" height="100%" />
</t>
</templates>
\ No newline at end of file
......@@ -3,8 +3,8 @@
<template id="roke_jz_jx_templates" inherit_id="web.assets_backend" name="roke_jz_jx">
<xpath expr="script[last()]" position="after">
<!-- <script type="text/javascript" src="/roke_pub_wx_notice/static/src/js/sync_wx_btn.js"/>-->
<script type="text/javascript" src="/jzjx_project/static/src/js/button.js"/>
<script type="text/javascript" src="/jzjx_project/static/src/js/roke_craft_design.js"/>
<script type="text/javascript" src="/sdddl_project/static/src/js/button.js"/>
<script type="text/javascript" src="/sdddl_project/static/src/js/roke_craft_design.js"/>
</xpath>
</template>
</odoo>
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_roke_product_form_inherit_standard_hours" model="ir.ui.view">
<field name="name">roke.product.form.inherit.standard.hours</field>
<field name="model">roke.product</field>
<field name="inherit_id" ref="roke_workstation_api.capacity_inherit_view_roke_product_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='capacity']" position="after">
<field name="standard_hours"/>
</xpath>
</field>
</record>
</data>
</odoo>
\ No newline at end of file
......@@ -8,21 +8,10 @@
<xpath expr="//page/group[@name='attachment']" position="after">
<field name="file_ids" widget="many2many_pic_preview" string="上传作业指导"/>
</xpath>
<xpath expr="//field[@name='sum_unqualified_qty']" position="after">
<field name="taskName"/>
</xpath>
<xpath expr="//field[@name='pass_rate']" position="after">
<field name="UploadMsg" readonly="1"/>
<field name="work_order_hours" readonly="1"/>
</xpath>
<xpath expr="//field[@name='type']" position="after">
<field name="spare_parts_qty"/>
<field name="press_riveting_qty"/>
<field name="bending_qty"/>
</xpath>
<xpath expr="//header" position="inside">
<button name="upload_task" type="object" string="上传任务" class="btn btn-primary"
attrs="{'invisible': [('UploadMsg', '=', 'OK')]}"/>
<field name="record_ids" invisible="1"/>
<button name="craft_design" type="object" string="工艺设计" class="btn btn-primary"/>
</xpath>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment