diff --git a/jikimo_frontend/__manifest__.py b/jikimo_frontend/__manifest__.py index 5808f8eb..2711118a 100644 --- a/jikimo_frontend/__manifest__.py +++ b/jikimo_frontend/__manifest__.py @@ -36,6 +36,7 @@ # 'jikimo_frontend/static/src/list/custom_import.js', # 'jikimo_frontend/static/src/list/custom_width.js', 'jikimo_frontend/static/src/views/list_nums/extent_purchase.xml', + # 'jikimo_frontend/static/src/css/list_border_styles.css', ], diff --git a/jikimo_frontend/static/src/css/list_border_styles.css b/jikimo_frontend/static/src/css/list_border_styles.css new file mode 100644 index 00000000..bca5499e --- /dev/null +++ b/jikimo_frontend/static/src/css/list_border_styles.css @@ -0,0 +1,3 @@ +.o_list_renderer .o_list_table tbody > tr > td:not(.o_list_record_selector):not(.o_handle_cell):not(.o_list_button):not(.o_list_record_remove){ + border:1px solid #dee2e6 !important; +} \ No newline at end of file diff --git a/jikimo_frontend/static/src/scss/custom_style.scss b/jikimo_frontend/static/src/scss/custom_style.scss index 766cca31..12e18c1c 100644 --- a/jikimo_frontend/static/src/scss/custom_style.scss +++ b/jikimo_frontend/static/src/scss/custom_style.scss @@ -79,9 +79,9 @@ td.o_required_modifier { } .oe_kanban_card.kanban_color_1 { - background-color: #27FEA9 !important; + background-color: #fff !important; opacity: 0.7; - color: #fff; + color: #777; } .oe_kanban_card.kanban_color_3 { @@ -135,7 +135,7 @@ td.o_required_modifier { .text-truncate { overflow: unset !important; text-overflow: unset !important; - white-space: nowrap!important; + //white-space: nowrap!important; } .o_list_renderer .o_list_table tbody > tr > td:not(.o_list_record_selector):not(.o_handle_cell):not(.o_list_button):not(.o_list_record_remove) { @@ -383,7 +383,9 @@ div:has(.o_required_modifier) > label::before { } } } - +.oe_kanban_details li.o_text_overflow { + display: block; +} .o_stock_kanban .o_kanban_card_content { .row { align-items: center; @@ -400,4 +402,51 @@ div:has(.o_required_modifier) > label::before { // 机床换刀申请表格宽度设置 .o_list_table_ungrouped { min-width: 1089px; +} +// 加工能力\冷却方式 竖列展示改为横列展示 +.processingMethod { + .o_cell.flex-grow-1.flex-sm-grow-0 { + width: 100%!important; + } +} +@media (min-width: 576px) { + .o_inner_group.processingMethod { + grid-template-columns: auto; + } +} + +// 设置所有表格序号列padding为0 +.o_form_view .o_notebook > .tab-content > .tab-pane > :first-child:not(.o_group) .o_field_x2many.o_field_x2many_list tr > :first-child, .o_form_view .o_notebook > .tab-content > .tab-pane > :first-child.o_invisible_modifier + .o_field_widget .o_field_x2many.o_field_x2many_list tr > :first-child { + padding: 0; + text-align: center; +} + +// 设置剩余number类型数据表格列 left +.o_list_renderer .o_list_table thead .o_list_number_th { + text-align:left; +} +.o_list_renderer .o_list_table tbody > tr > td:not(.o_list_record_selector).o_list_number { + text-align: left; +} +.o_list_renderer .flex-row-reverse { + flex-direction: unset!important; +} + +.o_list_renderer .flex-row-reverse > .text-end { + text-align: left!important; +} + +// 设置modal弹窗样式 +.modal.o_technical_modal { + .modal-lg { + @media (min-width: 992px) { + max-width: 1200px; + } + @media (min-width: 576px) { + .o_form_view .o_inner_group { + grid-template-columns: auto; + } + } + + } } \ No newline at end of file diff --git a/jikimo_frontend/static/src/scss/rowno_in_tree.scss b/jikimo_frontend/static/src/scss/rowno_in_tree.scss index c244ad7d..5f8a2648 100644 --- a/jikimo_frontend/static/src/scss/rowno_in_tree.scss +++ b/jikimo_frontend/static/src/scss/rowno_in_tree.scss @@ -1,4 +1,4 @@ .row_no { - width: 3.2% !important; + width: 35px !important; vertical-align: middle; } diff --git a/jikimo_hide_options/__init__.py b/jikimo_hide_options/__init__.py new file mode 100644 index 00000000..c5145b22 --- /dev/null +++ b/jikimo_hide_options/__init__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +from . import models +from odoo import api, SUPERUSER_ID + + +def uninstall_hook(cr, registry): + # 使用cr来执行数据库操作 + with api.Environment.manage(): + env = api.Environment(cr, SUPERUSER_ID, {}) + # 执行数据清理操作 + access_rights = env['access.right'].search([]) + access_rights.unlink() + followers = env['mail.followers'].search([('res_model', '=', 'access.right')]) + followers.unlink() diff --git a/jikimo_hide_options/__manifest__.py b/jikimo_hide_options/__manifest__.py new file mode 100644 index 00000000..6a4c41a8 --- /dev/null +++ b/jikimo_hide_options/__manifest__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +{ + 'name': '机企猫 隐藏项目', + 'version': '16.0.1.0.0', + 'category': 'Extra Tools, Productivity', + 'summary': """ Can hide options from user """, + 'description': """ By using this module we can hide the options like create, + delete,export,and archive/un archive in the model which we want. Here we + are also able to select the user groups except Administrator which we want + to apply the above hiding functionality """, + 'author': '机企猫-MGW', + 'company': '机企猫', + 'depends': ['base_setup', 'mail'], + 'data': [ + 'security/security.xml', + 'security/ir.model.access.csv', + 'views/model_access_rights_views.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'jikimo_hide_options/static/src/js/form_controller.js', + 'jikimo_hide_options/static/src/js/list_controller.js', + 'jikimo_hide_options/static/src/js/kanban_controller.js' + ] + }, + 'images': ['static/description/banner.jpg'], + 'license': 'LGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, + 'uninstall_hook': 'uninstall_hook', +} diff --git a/jikimo_hide_options/models/__init__.py b/jikimo_hide_options/models/__init__.py new file mode 100644 index 00000000..0950faaf --- /dev/null +++ b/jikimo_hide_options/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +from . import model_access_rights +from . import models + diff --git a/jikimo_hide_options/models/model_access_rights.py b/jikimo_hide_options/models/model_access_rights.py new file mode 100644 index 00000000..ca808557 --- /dev/null +++ b/jikimo_hide_options/models/model_access_rights.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +from odoo import api, fields, models, _ + + +class ModelAccessRights(models.Model): + """This class is used to detect, which all options want to hide from the + specified group and model""" + _name = 'access.right' + _inherit = 'mail.thread' + _description = 'Manage Modules Access Control' + _rec_name = 'model_id' + + model_id = fields.Many2one('ir.model', ondelete='cascade', required=True, + help="select the model") + groups_id = fields.Many2one('res.groups', required=True, + help="select the group") + is_delete = fields.Boolean(string="Delete", help="hide the delete option") + is_export = fields.Boolean(string="Export", + help="hide the 'Export All'" + " option from list view") + is_create_or_update = fields.Boolean(string="Create/Update", + help="hide the create option from list" + " as well as form view") + is_archive = fields.Boolean(string="Archive/UnArchive", + help="hide the archive option") + + @api.model + def hide_buttons(self): + """This function contains a query that detects which all options want + to hide, in which model,and to which user groups""" + access_right_rec = self.sudo().search_read([], ['model_id', 'is_delete', + 'is_export', + 'is_create_or_update', + 'is_archive', + 'groups_id']) + for dic in access_right_rec: + model = self.env['ir.model'].sudo().browse(dic['model_id'][0]).model + group_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', dic['groups_id'][0]) + ]).name + + module_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', dic['groups_id'][0]) + ]).module + dic.update({ + 'model': model, + 'group_name': group_name, + 'module': module_name + }) + return access_right_rec + # @api.model + # def hide_buttons(self): + # """This function contains a query that detects which all options want + # to hide, in which model,and to which user groups""" + # access_right_rec = self.sudo().search_read([], ['model_id', 'is_delete', + # 'is_export', + # 'is_create_or_update', + # 'is_archive', + # 'groups_id']) + # for dic in access_right_rec: + # model = self.env['ir.model'].sudo().browse(dic['model_id']).model + # group_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', dic['groups_id']) + # ]).name + # module_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', dic['groups_id']) + # ]).module + # dic.update({ + # 'model': model, + # 'group_name': group_name, + # 'module': module_name + # }) + # return access_right_rec + + +# class AccessRightCleanup(models.Model): +# _name = 'access.right.cleanup' # 定义一个新的模型名 +# _description = 'Access Right Cleanup' + + + + # @api.model + # def _module_uninstall(self): + # """在模块卸载时执行清理操作""" + # super(AccessRightCleanup, self)._module_uninstall() + # # 这里执行你的清理逻辑 + # + # # 获取access.right模型的所有记录 + # access_rights = self.env['access.right'].search([]) + # for access_right in access_rights: + # # 删除access.right模型的所有记录 + # access_right.unlink() + # + # # 查找所有关联到access.right模型的关注者记录 + # followers = self.env['mail.followers'].search([('res_model', '=', 'access.right')]) + # for follower in followers: + # # 删除关注者记录 + # follower.unlink() + # + # # # 示例:删除自定义数据表(确保先检查外键约束等) + # # self.env.cr.execute('DROP TABLE IF EXISTS access_right CASCADE;') + # + # # 其他清理工作... diff --git a/jikimo_hide_options/models/models.py b/jikimo_hide_options/models/models.py new file mode 100644 index 00000000..72046dca --- /dev/null +++ b/jikimo_hide_options/models/models.py @@ -0,0 +1,353 @@ +# -*- coding: utf-8 -*- +from collections import defaultdict +from operator import attrgetter +from odoo import api, _ +from odoo.exceptions import UserError +from odoo.models import BaseModel, _unlink, LOG_ACCESS_COLUMNS, \ + INSERT_BATCH_SIZE, SQL_DEFAULT +# from odoo.tools import OrderedSet, split_every, attrgetter, clean_context +from odoo.tools import OrderedSet, split_every, clean_context + + +@api.model +def _create(self, data_list): + """ Create records from the stored field values in ``data_list``. """ + assert data_list + cr = self.env.cr + + # insert rows in batches of maximum INSERT_BATCH_SIZE + ids = [] # ids of created records + other_fields = OrderedSet() # non-column fields + + for data_sublist in split_every(INSERT_BATCH_SIZE, data_list): + stored_list = [data['stored'] for data in data_sublist] + fnames = sorted({name for stored in stored_list for name in stored}) + + columns = [] + rows = [[] for _ in stored_list] + for fname in fnames: + field = self._fields[fname] + if field.column_type: + columns.append(fname) + for stored, row in zip(stored_list, rows): + if fname in stored: + colval = field.convert_to_column(stored[fname], self, + stored) + if field.translate is True and colval: + if 'en_US' not in colval.adapted: + colval.adapted['en_US'] = next( + iter(colval.adapted.values())) + row.append(colval) + else: + row.append(SQL_DEFAULT) + else: + other_fields.add(field) + + if field.type == 'properties': + # force calling fields.create for properties field because + # we might want to update the parent definition + other_fields.add(field) + + if not columns: + # manage the case where we create empty records + columns = ['id'] + for row in rows: + row.append(SQL_DEFAULT) + + header = ", ".join(f'"{column}"' for column in columns) + template = ", ".join("%s" for _ in rows) + cr.execute( + f'INSERT INTO "{self._table}" ({header}) VALUES {template} RETURNING "id"', + [tuple(row) for row in rows], + ) + ids.extend(id_ for id_, in cr.fetchall()) + + # put the new records in cache, and update inverse fields, for many2one + # + # cachetoclear is an optimization to avoid modified()'s cost until other_fields are processed + cachetoclear = [] + records = self.browse(ids) + inverses_update = defaultdict(list) # {(field, value): ids} + common_set_vals = set( + LOG_ACCESS_COLUMNS + [self.CONCURRENCY_CHECK_FIELD, 'id', + 'parent_path']) + for data, record in zip(data_list, records): + data['record'] = record + # DLE P104: test_inherit.py, test_50_search_one2many + vals = dict( + {k: v for d in data['inherited'].values() for k, v in d.items()}, + **data['stored']) + set_vals = common_set_vals.union(vals) + for field in self._fields.values(): + if field.type in ('one2many', 'many2many'): + self.env.cache.set(record, field, ()) + elif field.related and not field.column_type: + self.env.cache.set(record, field, + field.convert_to_cache(None, record)) + # DLE P123: `test_adv_activity`, `test_message_assignation_inbox`, `test_message_log`, `test_create_mail_simple`, ... + # Set `mail.message.parent_id` to False in cache so it doesn't do the useless SELECT when computing the modified of `child_ids` + # in other words, if `parent_id` is not set, no other message `child_ids` are impacted. + # + avoid the fetch of fields which are False. e.g. if a boolean field is not passed in vals and as no default set in the field attributes, + # then we know it can be set to False in the cache in the case of a create. + elif field.name not in set_vals and not field.compute: + self.env.cache.set(record, field, + field.convert_to_cache(None, record)) + for fname, value in vals.items(): + field = self._fields[fname] + if field.type in ('one2many', 'many2many'): + cachetoclear.append((record, field)) + else: + cache_value = field.convert_to_cache(value, record) + self.env.cache.set(record, field, cache_value) + if field.type in ('many2one', 'many2one_reference') and \ + self.pool.field_inverses[field]: + inverses_update[(field, cache_value)].append(record.id) + + for (field, value), record_ids in inverses_update.items(): + field._update_inverses(self.browse(record_ids), value) + + # update parent_path + records._parent_store_create() + + # protect fields being written against recomputation + protected = [(data['protected'], data['record']) for data in data_list] + with self.env.protecting(protected): + # mark computed fields as todo + records.modified(self._fields, create=True) + + if other_fields: + # discard default values from context for other fields + others = records.with_context(clean_context(self._context)) + for field in sorted(other_fields, key=attrgetter('_sequence')): + field.create([ + (other, data['stored'][field.name]) + for other, data in zip(others, data_list) + if field.name in data['stored'] + ]) + + # mark fields to recompute + records.modified([field.name for field in other_fields], + create=True) + + # if value in cache has not been updated by other_fields, remove it + for record, field in cachetoclear: + if self.env.cache.contains(record, + field) and not self.env.cache.get( + record, field): + self.env.cache.remove(record, field) + + # check Python constraints for stored fields + records._validate_fields( + name for data in data_list for name in data['stored']) + records.check_access_rule('create') + # This is used to restrict the access right to create a record + current_model_id = self.env['ir.model'].sudo().search( + [('model', '=', self._name)]).id + # access_right_rec = self.env['access.right'].sudo().search_read( + # [('model_id', '=', current_model_id)], + # ['model_id', 'is_create_or_update', + # 'groups_id']) + # if access_right_rec and not self.env.is_admin(): + # for rec in access_right_rec: + # group_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', rec['groups_id'][0]) + # ]).name + # module_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', rec['groups_id'][0]) + # ]).module + # group = module_name + "." + group_name + # if self.env.user.has_group(group): + # if rec['is_create_or_update']: + # raise UserError('You are restricted from performing this' + # ' operation. Please contact the' + # ' administrator.') + # 检查 'access.right' 模型是否存在于环境中 + if 'access.right' in self.env: + access_right_rec = self.env['access.right'].sudo().search_read( + [('model_id', '=', current_model_id)], + ['model_id', 'is_create_or_update', 'groups_id'] + ) + + # 如果找到相关记录,并且当前用户不是管理员 + if access_right_rec and not self.env.is_admin(): + for rec in access_right_rec: + # 获取与权限相关的用户组信息 + group_data = self.env['ir.model.data'].sudo().search_read( + [('model', '=', 'res.groups'), ('res_id', '=', rec['groups_id'][0])], + ['name', 'module'] + ) + + # 如果找到了用户组数据 + if group_data: + group_name = group_data[0]['name'] + module_name = group_data[0]['module'] + group_xml_id = f"{module_name}.{group_name}" + + # 检查当前用户是否属于该组 + if self.env.user.has_group(group_xml_id): + # 如果该用户组被限制创建或更新操作 + if rec['is_create_or_update']: + raise UserError( + _("You are restricted from performing this operation. Please contact the administrator.")) + else: + # 如果 'access.right' 模型不存在,可以在这里定义备选逻辑 + # 例如,记录日志、发送通知或者简单地跳过这部分逻辑 + pass + + return records + + +@api.model +def unlink(self): + """ unlink() + + Deletes the records in ``self``. + + :raise AccessError: if the user is not allowed to delete all the given records + :raise UserError: if the record is default property for other records + """ + if not self: + return True + + self.check_access_rights('unlink') + self.check_access_rule('unlink') + + from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG + for func in self._ondelete_methods: + # func._ondelete is True if it should be called during uninstallation + if func._ondelete or not self._context.get(MODULE_UNINSTALL_FLAG): + func(self) + + # TOFIX: this avoids an infinite loop when trying to recompute a + # field, which triggers the recomputation of another field using the + # same compute function, which then triggers again the computation + # of those two fields + for field in self._fields.values(): + self.env.remove_to_compute(field, self) + + self.env.flush_all() + + cr = self._cr + Data = self.env['ir.model.data'].sudo().with_context({}) + Defaults = self.env['ir.default'].sudo() + Property = self.env['ir.property'].sudo() + Attachment = self.env['ir.attachment'].sudo() + ir_property_unlink = Property + ir_model_data_unlink = Data + ir_attachment_unlink = Attachment + + # mark fields that depend on 'self' to recompute them after 'self' has + # been deleted (like updating a sum of lines after deleting one line) + with self.env.protecting(self._fields.values(), self): + self.modified(self._fields, before=True) + for sub_ids in cr.split_for_in_conditions(self.ids): + records = self.browse(sub_ids) + + # Check if the records are used as default properties. + refs = [f'{self._name},{id_}' for id_ in sub_ids] + if Property.search( + [('res_id', '=', False), ('value_reference', 'in', refs)], + limit=1): + raise UserError( + _('Unable to delete this document because it is used as a default property')) + + # Delete the records' properties. + ir_property_unlink |= Property.search([('res_id', 'in', refs)]) + + query = f'DELETE FROM "{self._table}" WHERE id IN %s' + cr.execute(query, (sub_ids,)) + + # Removing the ir_model_data reference if the record being deleted + # is a record created by xml/csv file, as these are not connected + # with real database foreign keys, and would be dangling references. + # + # Note: the following steps are performed as superuser to avoid + # access rights restrictions, and with no context to avoid possible + # side-effects during admin calls. + data = Data.search( + [('model', '=', self._name), ('res_id', 'in', sub_ids)]) + ir_model_data_unlink |= data + + # For the same reason, remove the defaults having some of the + # records as value + Defaults.discard_records(records) + + # For the same reason, remove the relevant records in ir_attachment + # (the search is performed with sql as the search method of + # ir_attachment is overridden to hide attachments of deleted + # records) + query = 'SELECT id FROM ir_attachment WHERE res_model=%s AND res_id IN %s' + cr.execute(query, (self._name, sub_ids)) + ir_attachment_unlink |= Attachment.browse( + row[0] for row in cr.fetchall()) + + # invalidate the *whole* cache, since the orm does not handle all + # changes made in the database, like cascading delete! + self.env.invalidate_all(flush=False) + if ir_property_unlink: + ir_property_unlink.unlink() + if ir_model_data_unlink: + ir_model_data_unlink.unlink() + if ir_attachment_unlink: + ir_attachment_unlink.unlink() + # DLE P93: flush after the unlink, for recompute fields depending on + # the modified of the unlink + self.env.flush_all() + # auditing: deletions are infrequent and leave no trace in the database + _unlink.info('User #%s deleted %s records with IDs: %r', self._uid, + self._name, self.ids) + # This is used to restrict the access right to unlink a record + current_model_id = self.env['ir.model'].sudo().search( + [('model', '=', self._name)]).id + # access_right_rec = self.env['access.right'].sudo().search_read( + # [('model_id', '=', current_model_id)], ['model_id', 'is_delete', + # 'groups_id']) + # if access_right_rec and not self.env.is_admin(): + # for rec in access_right_rec: + # group_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', rec['groups_id'][0]) + # ]).name + # module_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', rec['groups_id'][0]) + # ]).module + # group = module_name + "." + group_name + # if self.env.user.has_group(group): + # if rec['is_delete']: + # raise UserError(_('You are restricted from performing this' + # ' operation. Please contact the' + # ' administrator.')) + # 检查 'access.right' 模型是否存在于环境中 + if 'access.right' in self.env: + # current_model_id = self.env['ir.model'].sudo().search([('model', '=', self._name)]).id + access_right_rec = self.env['access.right'].sudo().search_read( + [('model_id', '=', current_model_id)], ['model_id', 'is_delete', 'groups_id'] + ) + + if access_right_rec and not self.env.is_admin(): + for rec in access_right_rec: + group_data = self.env['ir.model.data'].sudo().search_read( + [('model', '=', 'res.groups'), ('res_id', '=', rec['groups_id'][0])], + ['name', 'module'] + ) + + if group_data: + group_name = group_data[0]['name'] + module_name = group_data[0]['module'] + group_xml_id = f"{module_name}.{group_name}" + + if self.env.user.has_group(group_xml_id) and rec['is_delete']: + raise UserError( + _('You are restricted from performing this operation. Please contact the administrator.')) + else: + # 如果 'access.right' 模型不存在,可以在这里定义备选逻辑 + pass + + return True + + +BaseModel._create = _create +BaseModel.unlink = unlink diff --git a/jikimo_hide_options/security/ir.model.access.csv b/jikimo_hide_options/security/ir.model.access.csv new file mode 100644 index 00000000..ec0f6f88 --- /dev/null +++ b/jikimo_hide_options/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink +access_access_right,access.access.right,model_access_right,jikimo_hide_options.model_access_rights_groups_configure_model_access,1,1,1,1 diff --git a/jikimo_hide_options/security/security.xml b/jikimo_hide_options/security/security.xml new file mode 100644 index 00000000..23a2b818 --- /dev/null +++ b/jikimo_hide_options/security/security.xml @@ -0,0 +1,9 @@ + + + + + 配置隐藏项目 + + + + diff --git a/jikimo_hide_options/static/description/assets/icons/check.png b/jikimo_hide_options/static/description/assets/icons/check.png new file mode 100644 index 00000000..c8e85f51 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/check.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/chevron.png b/jikimo_hide_options/static/description/assets/icons/chevron.png new file mode 100644 index 00000000..2089293d Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/chevron.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/cogs.png b/jikimo_hide_options/static/description/assets/icons/cogs.png new file mode 100644 index 00000000..95d0bad6 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/cogs.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/consultation.png b/jikimo_hide_options/static/description/assets/icons/consultation.png new file mode 100644 index 00000000..8319d4ba Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/consultation.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/ecom-black.png b/jikimo_hide_options/static/description/assets/icons/ecom-black.png new file mode 100644 index 00000000..a9385ff1 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/ecom-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/education-black.png b/jikimo_hide_options/static/description/assets/icons/education-black.png new file mode 100644 index 00000000..3eb09b27 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/education-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/hotel-black.png b/jikimo_hide_options/static/description/assets/icons/hotel-black.png new file mode 100644 index 00000000..130f613b Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/hotel-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/license.png b/jikimo_hide_options/static/description/assets/icons/license.png new file mode 100644 index 00000000..a5869797 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/license.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/lifebuoy.png b/jikimo_hide_options/static/description/assets/icons/lifebuoy.png new file mode 100644 index 00000000..658d56cc Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/lifebuoy.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/manufacturing-black.png b/jikimo_hide_options/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 00000000..697eb0e9 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/manufacturing-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/pos-black.png b/jikimo_hide_options/static/description/assets/icons/pos-black.png new file mode 100644 index 00000000..97c0f90c Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/pos-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/puzzle.png b/jikimo_hide_options/static/description/assets/icons/puzzle.png new file mode 100644 index 00000000..65cf854e Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/puzzle.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/restaurant-black.png b/jikimo_hide_options/static/description/assets/icons/restaurant-black.png new file mode 100644 index 00000000..4a35eb93 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/restaurant-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/service-black.png b/jikimo_hide_options/static/description/assets/icons/service-black.png new file mode 100644 index 00000000..301ab51c Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/service-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/trading-black.png b/jikimo_hide_options/static/description/assets/icons/trading-black.png new file mode 100644 index 00000000..9398ba2f Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/trading-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/training.png b/jikimo_hide_options/static/description/assets/icons/training.png new file mode 100644 index 00000000..884ca024 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/training.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/update.png b/jikimo_hide_options/static/description/assets/icons/update.png new file mode 100644 index 00000000..ecbc5a01 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/update.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/user.png b/jikimo_hide_options/static/description/assets/icons/user.png new file mode 100644 index 00000000..6ffb23d9 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/user.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/wrench.png b/jikimo_hide_options/static/description/assets/icons/wrench.png new file mode 100644 index 00000000..6c04dea0 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/wrench.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/categories.png b/jikimo_hide_options/static/description/assets/misc/categories.png new file mode 100644 index 00000000..bedf1e0b Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/categories.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/check-box.png b/jikimo_hide_options/static/description/assets/misc/check-box.png new file mode 100644 index 00000000..42caf24b Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/check-box.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/compass.png b/jikimo_hide_options/static/description/assets/misc/compass.png new file mode 100644 index 00000000..d5fed8fa Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/compass.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/corporate.png b/jikimo_hide_options/static/description/assets/misc/corporate.png new file mode 100644 index 00000000..2eb13edb Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/corporate.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/customer-support.png b/jikimo_hide_options/static/description/assets/misc/customer-support.png new file mode 100644 index 00000000..79efc72e Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/customer-support.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/cybrosys-logo.png b/jikimo_hide_options/static/description/assets/misc/cybrosys-logo.png new file mode 100644 index 00000000..cc3cc0cc Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/cybrosys-logo.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/features.png b/jikimo_hide_options/static/description/assets/misc/features.png new file mode 100644 index 00000000..b41769f7 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/features.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/logo.png b/jikimo_hide_options/static/description/assets/misc/logo.png new file mode 100644 index 00000000..478462d3 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/logo.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/pictures.png b/jikimo_hide_options/static/description/assets/misc/pictures.png new file mode 100644 index 00000000..56d255fe Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/pictures.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/pie-chart.png b/jikimo_hide_options/static/description/assets/misc/pie-chart.png new file mode 100644 index 00000000..426e0524 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/pie-chart.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/right-arrow.png b/jikimo_hide_options/static/description/assets/misc/right-arrow.png new file mode 100644 index 00000000..730984a0 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/right-arrow.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/star.png b/jikimo_hide_options/static/description/assets/misc/star.png new file mode 100644 index 00000000..2eb9ab29 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/star.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/support.png b/jikimo_hide_options/static/description/assets/misc/support.png new file mode 100644 index 00000000..4f18b8b8 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/support.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/whatsapp.png b/jikimo_hide_options/static/description/assets/misc/whatsapp.png new file mode 100644 index 00000000..d513a535 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/whatsapp.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/1.png b/jikimo_hide_options/static/description/assets/modules/1.png new file mode 100644 index 00000000..d0f36b00 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/1.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/l2.png b/jikimo_hide_options/static/description/assets/modules/l2.png new file mode 100644 index 00000000..a3194264 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/l2.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/l3.png b/jikimo_hide_options/static/description/assets/modules/l3.png new file mode 100644 index 00000000..e894393e Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/l3.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/l4.png b/jikimo_hide_options/static/description/assets/modules/l4.png new file mode 100644 index 00000000..ed11bd81 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/l4.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/l5.png b/jikimo_hide_options/static/description/assets/modules/l5.png new file mode 100644 index 00000000..3415917c Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/l5.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/l6.png b/jikimo_hide_options/static/description/assets/modules/l6.png new file mode 100644 index 00000000..c7ea331e Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/l6.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/hero.gif b/jikimo_hide_options/static/description/assets/screenshots/hero.gif new file mode 100644 index 00000000..cb2f6b52 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/hero.gif differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_01.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_01.png new file mode 100644 index 00000000..2ca6bf0b Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_01.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_02.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_02.png new file mode 100644 index 00000000..4d800214 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_02.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_03.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_03.png new file mode 100644 index 00000000..ee165e8f Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_03.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_04.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_04.png new file mode 100644 index 00000000..d3760944 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_04.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_05.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_05.png new file mode 100644 index 00000000..7418fda6 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_05.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_06.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_06.png new file mode 100644 index 00000000..738a4160 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_06.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_07.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_07.png new file mode 100644 index 00000000..3bd2812d Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_07.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_08.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_08.png new file mode 100644 index 00000000..fa3b0387 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_08.png differ diff --git a/jikimo_hide_options/static/description/banner.jpg b/jikimo_hide_options/static/description/banner.jpg new file mode 100644 index 00000000..cc970a2b Binary files /dev/null and b/jikimo_hide_options/static/description/banner.jpg differ diff --git a/jikimo_hide_options/static/description/icon.png b/jikimo_hide_options/static/description/icon.png new file mode 100644 index 00000000..7b22e2b9 Binary files /dev/null and b/jikimo_hide_options/static/description/icon.png differ diff --git a/jikimo_hide_options/static/description/index.html b/jikimo_hide_options/static/description/index.html new file mode 100644 index 00000000..0c64834d --- /dev/null +++ b/jikimo_hide_options/static/description/index.html @@ -0,0 +1,596 @@ +
+ +
+ +
+
+ Community +
+
+ Enterprise +
+
+ Odoo.sh +
+
+
+ +
+
+
+ +

+ Hide Create|Delete|Archive|Export Options - Model Wise

+

Hide Create, Delete, Archive, Export Options in Models

+ + +
+
+
+ + +
+ + +
+
+ +
+

Explore This + Module

+
+
+
+ +
+
+ Overview + Learn + more about this + module +
+ +
+
+
+
+ +
+
+ Features + View + features of this + module +
+ +
+
+
+
+ +
+
+ Screenshots + View + screenshots of this + module +
+ +
+
+
+
+ + + +
+
+ +
+

Overview +

+
+
+
+ By using this module we can hide the options like create,delete,export,and archive/un archive in the model + which we want. Here we are also able to select the user groups except Administrator which we want to apply the + above hiding functionality
+
+ + + +
+
+ +
+

Features +

+
+
+
+
+ + Easily hide the options like Create,Delete,Export and Archive/UnArchive +
+
+ + Can hide the options for specific model +
+
+ + Can hide the options for specific user group +
+
+ + No additional configuration needed +
+
+
+ + + +
+
+ +
+

Screenshots +

+
+
+
+ +
+

Go to Settings > Users and there you can see the Configure Model Access, by enabling that + option and refresh the page, you can see a new menu named 'Restrict Access Rights'

+ +
+ +
+

User in the Purchase module

+ +
+ +
+

Select the Model, Groups and the options which we want to hide

+ +
+
+

We can see Create option is hidden in purchase.order to those who are User + in purchase module

+ +
+ +
+

User in Project module

+ +
+
+

By default, we can see Export and Archive/UnArchive options

+ +
+
+

Select the options which we want to hide

+ +
+
+

Export and Archive/UnArchive functionality are hidden

+ +
+
+
+ + +
+
+ +
+

+ Related + Products +

+
+
+
+ +
+
+ + + + +
+
+ +
+

Our Services +

+
+ +
+
+
+
+ +
+
+ Odoo + Customization
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Support
+
+ + +
+
+ +
+
+ Hire + Odoo + Developer
+
+ +
+
+ +
+
+ Odoo + Integration
+
+ +
+
+ +
+
+ Odoo + Migration
+
+ + +
+
+ +
+
+ Odoo + Consultancy
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Licensing Consultancy
+
+
+ +
+ + + + + +
+
+ +
+

Our + Industries +

+
+ +
+
+
+
+ +
+ Trading +
+

+ Easily procure + and + sell your products

+
+
+ +
+
+ +
+ POS +
+

+ Easy + configuration + and convivial experience

+
+
+ +
+
+ +
+ Education +
+

+ A platform for + educational management

+
+
+ +
+
+ +
+ Manufacturing +
+

+ Plan, track and + schedule your operations

+
+
+ +
+
+ +
+ E-commerce & Website +
+

+ Mobile + friendly, + awe-inspiring product pages

+
+
+ +
+
+ +
+ Service Management +
+

+ Keep track of + services and invoice

+
+
+ +
+
+ +
+ Restaurant +
+

+ Run your bar or + restaurant methodically

+
+
+ +
+
+ +
+ Hotel Management +
+

+ An + all-inclusive + hotel management application

+
+
+
+
+ + + + +
+
+ +
+

Support +

+
+
+
+
+
+
+ +
+
+

Need Help?

+

Got questions or need help? Get in touch.

+ +

+ odoo@cybrosys.com

+
+
+
+
+
+
+
+ +
+
+

WhatsApp

+

Say hi to us on WhatsApp!

+ +

+91 86068 + 27707

+
+
+
+
+
+
+
+ +
+
+
+ \ No newline at end of file diff --git a/jikimo_hide_options/static/src/js/form_controller.js b/jikimo_hide_options/static/src/js/form_controller.js new file mode 100644 index 00000000..f515a865 --- /dev/null +++ b/jikimo_hide_options/static/src/js/form_controller.js @@ -0,0 +1,46 @@ +/** @odoo-module */ +/** + * This file will used to hide the selected options from the form view + */ +import { FormController} from "@web/views/form/form_controller"; +import { patch} from "@web/core/utils/patch"; +var rpc = require('web.rpc'); +const { onWillStart} = owl; +patch(FormController.prototype, 'jikimo_hide_options/static/src/js/form_controller.js.FormController', { +/** + * This function will used to hide the selected options from the form view + */ + setup() { + this._super(); + onWillStart(async () => { + var self = this + var result; + await rpc.query({ + model: 'access.right', + method: 'hide_buttons', + }).then(function(data) { + result = data; + }); + for (var i = 0; i < result.length; i++) { + var group = result[i].module + "." + result[i].group_name + if (self.props.resModel == result[i].model) { + if (await self.user.hasGroup(group)) { + if (!this.user.isAdmin) { + if (result[i].is_create_or_update) { + self.canCreate = false + } + if (result[i].is_delete) { + this.archInfo.activeActions.delete = false + } + if (result[i].is_archive) { + self.archiveEnabled = false + } else { + self.archiveEnabled = true; + } + } + } + } + } + }); + } +}); diff --git a/jikimo_hide_options/static/src/js/kanban_controller.js b/jikimo_hide_options/static/src/js/kanban_controller.js new file mode 100644 index 00000000..3e7938cc --- /dev/null +++ b/jikimo_hide_options/static/src/js/kanban_controller.js @@ -0,0 +1,42 @@ +/** @odoo-module */ +/** + * This file will used to hide the selected options from the list view + */ +import { KanbanController } from '@web/views/kanban/kanban_controller'; +import { patch} from "@web/core/utils/patch"; +var rpc = require('web.rpc'); +const {onWillStart} = owl; +patch(KanbanController.prototype, 'jikimo_hide_options/static/src/js/list_controller.js.KanbanController', { +/** + * This function will used to hide the selected options from the Kanban view + */ + setup() { + this._super(); + onWillStart(async () => { + var self = this + var result; + await rpc.query({ + model: 'access.right', + method: 'hide_buttons', + }).then(function(data) { + result = data; + }); + for (var i = 0; i < result.length; i++) { + var group = result[i].module + "." + result[i].group_name + if (self.props.resModel == result[i].model) { + if (await self.model.user.hasGroup(group)) { + if (!self.model.user.isAdmin) { + if (result[i].is_create_or_update) { + self.props.archInfo.activeActions.create=false + self.props.archInfo.activeActions.edit=false + } + if (result[i].is_delete) { + self.props.archInfo.activeActions.delete=false + } + } + } + } + } + }); + } +}); diff --git a/jikimo_hide_options/static/src/js/list_controller.js b/jikimo_hide_options/static/src/js/list_controller.js new file mode 100644 index 00000000..f2e2de76 --- /dev/null +++ b/jikimo_hide_options/static/src/js/list_controller.js @@ -0,0 +1,50 @@ +/** @odoo-module */ +/** + * This file will used to hide the selected options from the list view + */ +import { ListController} from '@web/views/list/list_controller'; +import { patch} from "@web/core/utils/patch"; +var rpc = require('web.rpc'); +const {onWillStart} = owl; +patch(ListController.prototype, 'jikimo_hide_options/static/src/js/list_controller.js.ListController', { +/** + * This function will used to hide the selected options from the list view + */ + setup() { + this._super(); + onWillStart(async () => { + var self = this + var result; + await rpc.query({ + model: 'access.right', + method: 'hide_buttons', + }).then(function(data) { + result = data; + }); + for (var i = 0; i < result.length; i++) { + var group = result[i].module + "." + result[i].group_name + if (self.props.resModel == result[i].model) { + if (await self.userService.hasGroup(group)) { + if (!this.userService.isAdmin) { + if (result[i].is_create_or_update) { + self.activeActions.create = false; + } + if (result[i].is_export) { + self.isExportEnable = false + self.isExportEnable = false + } + if (result[i].is_delete) { + self.activeActions.delete = false; + } + if (result[i].is_archive) { + self.archiveEnabled = false; + } else { + self.archiveEnabled = true; + } + } + } + } + } + }); + } +}); diff --git a/jikimo_hide_options/views/model_access_rights_views.xml b/jikimo_hide_options/views/model_access_rights_views.xml new file mode 100644 index 00000000..ed4e89b1 --- /dev/null +++ b/jikimo_hide_options/views/model_access_rights_views.xml @@ -0,0 +1,58 @@ + + + + + 隐藏项目 + access.right + tree,form + + + + access.right.view.tree + access.right + + + + + + + + + + + + + + access.right.view.form + access.right + +
+ + + + + + + + + + + + + + +
+ + +
+
+
+
+ + +
diff --git a/sf_base/__init__.py b/sf_base/__init__.py index 60182bcc..d76dba0b 100644 --- a/sf_base/__init__.py +++ b/sf_base/__init__.py @@ -1,2 +1,3 @@ from . import models from . import commons +from . import controllers diff --git a/sf_base/__manifest__.py b/sf_base/__manifest__.py index e2fb731c..59ad967a 100644 --- a/sf_base/__manifest__.py +++ b/sf_base/__manifest__.py @@ -23,6 +23,7 @@ 'views/tool_basic_param.xml', 'views/tool_menu.xml', 'views/menu_fixture_view.xml', + 'views/change_base_view.xml', ], 'demo': [ diff --git a/sf_base/commons/common.py b/sf_base/commons/common.py index 05a2143f..6bf597cc 100644 --- a/sf_base/commons/common.py +++ b/sf_base/commons/common.py @@ -19,3 +19,13 @@ class Common(models.Model): 'TIMESTAMP': str(timestamp), 'checkstr': check_sf_str} return headers + + def get_add_time(self, parse_time): + """ + 把时间增加8小时 + :return: + """ + dt = datetime.datetime.strptime(parse_time, "%Y-%m-%d %H:%M:%S") + d = dt + datetime.timedelta(hours=8) + nTime = d.strftime("%Y-%m-%d %H:%M:%S") + return nTime diff --git a/sf_base/controllers/__init__.py b/sf_base/controllers/__init__.py new file mode 100644 index 00000000..e046e49f --- /dev/null +++ b/sf_base/controllers/__init__.py @@ -0,0 +1 @@ +from . import controllers diff --git a/sf_base/controllers/controllers.py b/sf_base/controllers/controllers.py new file mode 100644 index 00000000..71547a67 --- /dev/null +++ b/sf_base/controllers/controllers.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +import logging +import json +import base64 +from odoo import http +from odoo.http import request + + +class Manufacturing_Connect(http.Controller): + + @http.route('/AutoDeviceApi/MaintenanceToolGroups', type='json', auth='none', methods=['GET', 'POST'], csrf=False, + cors="*") + def get_maintenance_tool_groups_Info(self, **kw): + """ + 机床刀具组接口 + :param kw: + :return: + """ + logging.info('get_maintenance_tool_groups_Info:%s' % kw) + try: + datas = request.httprequest.data + ret = json.loads(datas) + ret = json.loads(ret['result']) + logging.info('DeviceId:%s' % ret) + tool_groups = request.env['sf.tool.groups'].sudo().search([]) + + res = {'Succeed': True, 'Datas': []} + if tool_groups: + for item in tool_groups: + device_id = '' + for equipment_id in item.equipment_ids: + device_id = '%s,%s' % (device_id, equipment_id.name) + res['Datas'].append({ + 'GroupName': item.name, + 'DeviceId': device_id + }) + except Exception as e: + res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} + logging.info('get_maintenance_tool_groups_Info error:%s' % e) + return json.JSONEncoder().encode(res) diff --git a/sf_base/models/__init__.py b/sf_base/models/__init__.py index 31dfcf95..f7d50427 100644 --- a/sf_base/models/__init__.py +++ b/sf_base/models/__init__.py @@ -4,3 +4,4 @@ from . import tool_base_new from . import fixture from . import functional_fixture from . import tool_other_features +from . import basic_parameters_fixture diff --git a/sf_base/models/base.py b/sf_base/models/base.py index 36a39f49..6fc86e94 100644 --- a/sf_base/models/base.py +++ b/sf_base/models/base.py @@ -48,7 +48,7 @@ class MachineBrand(models.Model): active = fields.Boolean('有效', default=True) -#机床 +# 机床 class MachineTool(models.Model): _name = 'sf.machine_tool' _description = '机床' @@ -92,7 +92,8 @@ class MachineTool(models.Model): type_id = fields.Many2one('sf.machine_tool.type', '型号') brand_id = fields.Many2one('sf.machine.brand', string='品牌') state = fields.Selection( - [("正常", "正常"), ("故障", "故障"), ("不可用", "不可用")], + [("正常", "正常"), ("故障停机", "故障停机"), ("计划维保", "计划维保"), ("空闲", "空闲"), + ("封存(报废)", "封存(报废)")], default='正常', string="机床状态") # 0606新增字段 machine_tool_picture = fields.Binary('图片') @@ -357,8 +358,7 @@ class MachineToolType(models.Model): lq_image_id = fields.Many2many('maintenance.equipment.image', 'lq_equipment_id', string='冷却方式', domain="[('type', '=', '冷却方式')]") - - #待删除字段 + # 待删除字段 precision_min = fields.Float('X轴定位精度min(mm)', digits=(12, 3)) precision_max = fields.Float('X轴定位精度max(mm)', digits=(12, 3)) lead_screw = fields.Char('丝杆') diff --git a/sf_base/models/basic_parameters_fixture.py b/sf_base/models/basic_parameters_fixture.py new file mode 100644 index 00000000..7bd69a35 --- /dev/null +++ b/sf_base/models/basic_parameters_fixture.py @@ -0,0 +1,252 @@ +from odoo import models, fields + + +class BasicParametersFixture(models.Model): + _name = 'sf.fixture.materials.basic.parameters' + _description = '夹具物料基本参数' + + fixture_model_id = fields.Many2one('sf.fixture.model', '夹具型号') + name = fields.Char('物料号', size=20) + length = fields.Float('长度(mm)', digits=(16, 2)) + width = fields.Float('宽度(mm)', digits=(16, 2)) + height = fields.Float('高度(mm)', digits=(16, 2)) + diameter = fields.Float('直径(mm)', digits=(16, 2)) + + # '零点卡盘' 字段 + weight = fields.Float('重量(mm)', digits=(16, 2)) + orientation_dish_diameter = fields.Float('定位盘直径(mm)', digits=(16, 2)) + clamping_diameter = fields.Float('装夹直径(mm)', digits=(16, 2)) + clamping_num = fields.Selection([('1', '1'), ('2', '2'), ('4', '4'), ('6', '6'), ('8', '8')], string='装夹单元数') + chucking_power_max = fields.Float('最大夹持力(KN)', digits=(16, 2)) + repeated_positioning_accuracy = fields.Char('重复定位精度(mm)', size=20) + boolean_transposing_hole = fields.Boolean('是否有转位孔') + unlocking_method = fields.Selection( + [('手动', '手动'), ('气动', '气动'), ('液压', '液压'), ('电动', '电动'), ('其他', '其他')], string='解锁方式') + boolean_chip_blowing_function = fields.Boolean('是否有吹屑功能') + carrying_capacity_max = fields.Float('最大承载重量(kg)', digits=(16, 2)) + rigidity = fields.Integer('硬度HRC') + materials_model_id = fields.Many2one('sf.materials.model', '夹具材质') + machine_tool_type_id = fields.Many2one('sf.machine_tool.type', '适用机床型号') + + # ’零点托盘‘ 字段 + connector_diameter = fields.Selection([('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('8', '8')], + string='连接头直径(mm)') + way_to_install = fields.Selection( + [('接口式', '接口式'), ('螺栓固定', '螺栓固定'), ('磁吸式', '磁吸式'), ('其他', '其他')], string='安装方式') + type_of_drive = fields.Selection( + [('气动式', '气动式'), ('液压式', '液压式'), ('机械式', '机械式'), ('电动式', '电动式'), ('其他', '其他')], + string='驱动方式') + + # ’气动夹具‘ 字段 + gripper_length_min = fields.Float('夹持工件最小长度(mm)', digits=(16, 2)) + gripper_width_min = fields.Float('夹持工件最小宽度(mm)', digits=(16, 2)) + gripper_height_min = fields.Float('夹持工件最小高度(mm)', digits=(16, 2)) + gripper_diameter_min = fields.Float('夹持工件最小直径(mm)', digits=(16, 2)) + gripper_length_max = fields.Float('夹持工件最大长度(mm)', digits=(16, 2)) + gripper_width_max = fields.Float('夹持工件最大宽度(mm)', digits=(16, 2)) + gripper_height_max = fields.Float('夹持工件最大高度(mm)', digits=(16, 2)) + gripper_diameter_max = fields.Float('夹持工件最大直径(mm)', digits=(16, 2)) + rated_air_pressure = fields.Float('额定气压(Mpa)', digits=(16, 2)) + interface_materials_model_id = fields.Many2one('sf.materials.model', '接口类型') + + # ‘虎钳夹具' 字段 + transverse_groove = fields.Float('横向配合槽n(mm)', digits=(16, 2)) + longitudinal_fitting_groove = fields.Float('纵向配合槽l(mm)', digits=(16, 2)) + + # '磁吸夹具' 字段 + height_tolerance_value = fields.Char('高度公差(mm)') + rated_adsorption_force = fields.Float('额定吸附力(N/cm²)', digits=(16, 2)) + magnetic_field_height = fields.Float('磁场高度(mm)', digits=(16, 2)) + magnetic_pole_plate_grinding_allowance = fields.Float('磁极板磨削余量(mm)', digits=(16, 2)) + + # '转接板(锁板)夹具' 字段 + screw_size = fields.Float('螺牙大小(mm)', digits=(16, 2)) + via_hole_diameter = fields.Float('过孔直径(mm)', digits=(16, 2)) + + # '三爪卡盘' 字段 + mounting_hole_depth = fields.Float('安装孔深度(mm)', digits=(16, 2)) + centering_diameter = fields.Float('定心直径(mm)', digits=(16, 2)) + + def _json_zero_chuck_param(self, obj): + zero_chuck_param_str = (0, '', { + 'name': obj['name'], + 'length': obj['length'], + 'width': obj['width'], + 'height': obj['height'], + 'diameter': obj['diameter'], + 'weight': obj['weight'], + 'orientation_dish_diameter': obj['orientation_dish_diameter'], + 'clamping_diameter': obj['clamping_diameter'], + 'clamping_num': obj['clamping_num'], + 'chucking_power_max': obj['chucking_power_max'], + 'repeated_positioning_accuracy': obj['repeated_positioning_accuracy'], + 'boolean_transposing_hole': obj['boolean_transposing_hole'], + 'unlocking_method': obj['unlocking_method'], + 'boolean_chip_blowing_function': obj['boolean_chip_blowing_function'], + 'carrying_capacity_max': obj['carrying_capacity_max'], + 'rigidity': obj['rigidity'], + 'materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id, + 'machine_tool_type_id': self.env['sf.machine_tool.type'].sudo().search( + [('code', '=', obj['machine_tool_type_id']), ('active', '=', True)]).id, + }) + return zero_chuck_param_str + + def _json_zero_tray_param(self, obj): + zero_tray_param_str = (0, '', { + 'name': obj['name'], + 'length': obj['length'], + 'width': obj['width'], + 'height': obj['height'], + 'diameter': obj['diameter'], + 'weight': obj['weight'], + 'clamping_diameter': obj['clamping_diameter'], + 'connector_diameter': obj['connector_diameter'], + 'chucking_power_max': obj['chucking_power_max'], + 'repeated_positioning_accuracy': obj['repeated_positioning_accuracy'], + 'boolean_chip_blowing_function': obj['boolean_chip_blowing_function'], + 'way_to_install': obj['way_to_install'], + 'type_of_drive': obj['type_of_drive'], + 'carrying_capacity_max': obj['carrying_capacity_max'], + 'materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id, + 'rigidity': obj['rigidity'], + }) + return zero_tray_param_str + + def _json_pneumatic_fixture_param(self, obj): + pneumatic_fixture_param_str = (0, '', { + 'name': obj['name'], + 'length': obj['length'], + 'width': obj['width'], + 'height': obj['height'], + 'weight': obj['weight'], + 'gripper_length_min': obj['gripper_length_min'], + 'gripper_width_min': obj['gripper_width_min'], + 'gripper_height_min': obj['gripper_height_min'], + 'gripper_diameter_min': obj['gripper_diameter_min'], + 'gripper_length_max': obj['gripper_length_max'], + 'gripper_width_max': obj['gripper_width_max'], + 'gripper_height_max': obj['gripper_height_max'], + 'gripper_diameter_max': obj['gripper_diameter_max'], + 'chucking_power_max': obj['chucking_power_max'], + 'carrying_capacity_max': obj['carrying_capacity_max'], + 'rated_air_pressure': obj['rated_air_pressure'], + 'materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id, + 'rigidity': obj['rigidity'], + 'interface_materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id, + 'type_of_drive': obj['type_of_drive'], + }) + return pneumatic_fixture_param_str + + def _json_jaw_vice_fixture_param(self, obj): + jaw_vice_fixture_param_str = (0, '', { + 'name': obj['name'], + 'length': obj['length'], + 'width': obj['width'], + 'height': obj['height'], + 'weight': obj['weight'], + 'gripper_length_min': obj['gripper_length_min'], + 'gripper_width_min': obj['gripper_width_min'], + 'gripper_height_min': obj['gripper_height_min'], + 'gripper_diameter_min': obj['gripper_diameter_min'], + 'gripper_length_max': obj['gripper_length_max'], + 'gripper_width_max': obj['gripper_width_max'], + 'gripper_height_max': obj['gripper_height_max'], + 'gripper_diameter_max': obj['gripper_diameter_max'], + 'chucking_power_max': obj['chucking_power_max'], + 'carrying_capacity_max': obj['carrying_capacity_max'], + 'transverse_groove': obj['transverse_groove'], + 'longitudinal_fitting_groove': obj['longitudinal_fitting_groove'], + 'materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id, + 'rigidity': obj['rigidity'], + 'interface_materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id, + 'type_of_drive': obj['type_of_drive'], + }) + return jaw_vice_fixture_param_str + + def _json_magnet_fixture_param(self, obj): + magnet_fixture_param_str = (0, '', { + 'name': obj['name'], + 'length': obj['length'], + 'width': obj['width'], + 'height': obj['height'], + 'height_tolerance_value': obj['height_tolerance_value'], + 'weight': obj['weight'], + 'gripper_length_min': obj['gripper_length_min'], + 'gripper_width_min': obj['gripper_width_min'], + 'gripper_height_min': obj['gripper_height_min'], + 'gripper_diameter_min': obj['gripper_diameter_min'], + 'gripper_length_max': obj['gripper_length_max'], + 'gripper_width_max': obj['gripper_width_max'], + 'gripper_height_max': obj['gripper_height_max'], + 'gripper_diameter_max': obj['gripper_diameter_max'], + 'rated_adsorption_force': obj['rated_adsorption_force'], + 'magnetic_field_height': obj['magnetic_field_height'], + 'magnetic_pole_plate_grinding_allowance': obj['magnetic_pole_plate_grinding_allowance'], + 'carrying_capacity_max': obj['carrying_capacity_max'], + 'materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id, + 'rigidity': obj['rigidity'], + 'interface_materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id, + 'type_of_drive': obj['type_of_drive'], + }) + return magnet_fixture_param_str + + def _json_adapter_board_fixture_param(self, obj): + adapter_board_fixture_param_str = (0, '', { + 'name': obj['name'], + 'length': obj['length'], + 'width': obj['width'], + 'height': obj['height'], + 'weight': obj['weight'], + 'gripper_length_min': obj['gripper_length_min'], + 'gripper_width_min': obj['gripper_width_min'], + 'gripper_height_min': obj['gripper_height_min'], + 'gripper_diameter_min': obj['gripper_diameter_min'], + 'gripper_length_max': obj['gripper_length_max'], + 'gripper_width_max': obj['gripper_width_max'], + 'gripper_height_max': obj['gripper_height_max'], + 'gripper_diameter_max': obj['gripper_diameter_max'], + 'chucking_power_max': obj['chucking_power_max'], + 'carrying_capacity_max': obj['carrying_capacity_max'], + 'materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id, + 'rigidity': obj['rigidity'], + 'screw_size': obj['screw_size'], + 'via_hole_diameter': obj['via_hole_diameter'], + 'type_of_drive': obj['type_of_drive'], + }) + return adapter_board_fixture_param_str + + def _json_scroll_chuck_param(self, obj): + scroll_chuck_param_str = (0, '', { + 'name': obj['name'], + 'length': obj['length'], + 'width': obj['width'], + 'height': obj['height'], + 'diameter': obj['diameter'], + 'weight': obj['weight'], + 'gripper_length_min': obj['gripper_length_min'], + 'gripper_width_min': obj['gripper_width_min'], + 'gripper_height_min': obj['gripper_height_min'], + 'gripper_diameter_min': obj['gripper_diameter_min'], + 'gripper_length_max': obj['gripper_length_max'], + 'gripper_width_max': obj['gripper_width_max'], + 'gripper_height_max': obj['gripper_height_max'], + 'gripper_diameter_max': obj['gripper_diameter_max'], + 'chucking_power_max': obj['chucking_power_max'], + 'carrying_capacity_max': obj['carrying_capacity_max'], + 'materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id, + 'rigidity': obj['rigidity'], + 'mounting_hole_depth': obj['mounting_hole_depth'], + 'centering_diameter': obj['centering_diameter'], + 'type_of_drive': obj['type_of_drive'], + }) + return scroll_chuck_param_str diff --git a/sf_base/models/common.py b/sf_base/models/common.py index f6e6771a..6cddafd7 100644 --- a/sf_base/models/common.py +++ b/sf_base/models/common.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- import logging from urllib.parse import urlencode -from odoo import fields, models +from odoo import fields, models, api +from odoo.exceptions import UserError + _logger = logging.getLogger(__name__) @@ -59,6 +61,14 @@ class MrsMaterialModel(models.Model): supplier_ids = fields.One2many('sf.supplier.sort', 'materials_model_id', string='供应商') active = fields.Boolean('有效', default=True) + @api.constrains('supplier_ids') + def _check_gain_way(self): + if not self.gain_way: + raise UserError("请输入获取方式") + if self.gain_way in ['外协', '采购']: + if not self.supplier_ids: + raise UserError("请添加供应商") + class MrsProductionProcessCategory(models.Model): _name = 'sf.production.process.category' diff --git a/sf_base/models/fixture.py b/sf_base/models/fixture.py index f7cb5fa8..52e2baf7 100644 --- a/sf_base/models/fixture.py +++ b/sf_base/models/fixture.py @@ -26,66 +26,65 @@ class FixtureModel(models.Model): _name = 'sf.fixture.model' _description = "夹具型号" - name = fields.Char(string="名称", size=15) - fixture_material_id = fields.Many2one('sf.fixture.material', string="夹具物料", ) - fixture_material_type = fields.Char(string="夹具物料类型", related='fixture_material_id.name', store=True) - multi_mounting_type_id = fields.Many2one('sf.multi_mounting.type', string="联装类型") - brand_id = fields.Many2one('sf.machine.brand', string="品牌", domain="[('tag_ids.name', 'ilike', '夹具')]") - clamping_way = fields.Char(string="装夹方式") - port_type = fields.Char(string="接口类型") - model_file = fields.Binary(string="3D模型图") - - length = fields.Char(string="长度(mm)") - width = fields.Char(string="宽度(mm)") - height = fields.Char(string="高度(mm)") - weight = fields.Char(string="重量(kg)") - clamp_workpiece_length_max = fields.Integer(string="夹持工件长度max(mm)") - clamp_workpiece_width_max = fields.Integer(string="夹持工件宽度max(mm)") - clamp_workpiece_height_max = fields.Integer(string="夹持工件高度max(mm)") - clamp_workpiece_diameter_max = fields.Float(string="夹持工件直径max(mm)") - maximum_carrying_weight = fields.Float(string="最大承载重量(kg)") - maximum_clamping_force = fields.Integer(string="最大夹持力(n)") - - materials_model_id = fields.Many2one('sf.materials.model', string="材料型号") - driving_way = fields.Selection([('气动', '气动'), ('液压', '液压'), ('机械', '机械')], string="驱动方式") - apply_machine_tool_type_ids = fields.Many2many('sf.machine_tool.type', 'rel_fixture_model_machine_tool_type', - string="适用机床型号") - through_hole_size = fields.Integer(string="过孔大小[mm]") - screw_size = fields.Integer(string="螺牙大小[mm]") - active = fields.Boolean('有效', default=True) - - def _get_code(self, fixture_model_type_code): - fixture_model = self.env['sf.fixture.model'].sudo().search( - [('code', 'ilike', fixture_model_type_code)], - limit=1, - order="id desc") - if not fixture_model: - num = "%03d" % 1 - else: - m = int(fixture_model.code[-3:]) + 1 - num = "%03d" % m - return "%s%s" % (fixture_model_type_code, num) + name = fields.Char(string="名称", size=50, required=True) + fixture_material_id = fields.Many2one('sf.fixture.material', string="夹具物料", required=True) + fixture_material_type = fields.Char(string="夹具物料类型", related='fixture_material_id.name') + multi_mounting_type_id = fields.Many2one('sf.multi_mounting.type', string="联装类型", required=True) + brand_id = fields.Many2one('sf.machine.brand', string="品牌") + model_file = fields.Binary(string="图片") + status = fields.Boolean('状态') + active = fields.Boolean('有效', default=False) + zero_chuck_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + string='零点卡盘基本参数') + zero_tray_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + string='零点托盘基本参数') + pneumatic_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + string='气动夹具基本参数') + jaw_vice_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + string='虎钳夹具基本参数') + magnet_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + string='磁吸夹具基本参数') + adapter_board_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + string='转接板(锁板)夹具基本参数') + scroll_chuck_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + string='三爪卡盘基本参数') code = fields.Char(string='编码', readonly=True) - def _onchange_fixture_material_id(self, fixture_material_id): - if fixture_material_id: - if fixture_material_id.name == "气动夹具": - code = self._get_code("JKM-C-JJWL-QDJJ-") - elif fixture_material_id.name == "转接板(锁板)夹具": - code = self._get_code("JKM-C-JJWL-ZJBJJ-") - elif fixture_material_id.name == "磁吸夹具": - code = self._get_code("JKM-C-JJWL-CXJJ-") - elif fixture_material_id.name == "虎钳夹具": - code = self._get_code("JKM-C-JJWL-HQJJ-") - else: - code = self._get_code("JKM-C-JJWL-LDKP-") - return code - - @api.model_create_multi - def create(self, vals): - obj = super(FixtureModel, self).create(vals) - if obj.fixture_material_id: - code = self._onchange_fixture_material_id(obj.fixture_material_id) - obj.code = code - return obj + # def _get_code(self, fixture_model_type_code): + # fixture_model = self.env['sf.fixture.model'].sudo().search( + # [('code', 'ilike', fixture_model_type_code)], + # limit=1, + # order="id desc") + # if not fixture_model: + # num = "%03d" % 1 + # else: + # m = int(fixture_model.code[-3:]) + 1 + # num = "%03d" % m + # return "%s%s" % (fixture_model_type_code, num) + # + # def _onchange_fixture_material_id(self, fixture_material_id): + # if fixture_material_id: + # if self.fixture_material_id.name == "气动夹具": + # code = self._get_code("JKM-C-JJWL-QDJJ-") + # elif self.fixture_material_id.name == "转接板(锁板)夹具": + # code = self._get_code("JKM-C-JJWL-ZJJJ-") + # elif self.fixture_material_id.name == "磁吸夹具": + # code = self._get_code("JKM-C-JJWL-CXJJ-") + # elif self.fixture_material_id.name == "虎钳夹具": + # code = self._get_code("JKM-C-JJWL-HQJJ-") + # elif self.fixture_material_id.name == "零点托盘": + # code = self._get_code("JKM-C-JJWL-LDTP-") + # elif self.fixture_material_id.name == "三爪卡盘": + # code = self._get_code("JKM-C-JJWL-SZKP-") + # else: + # code = self._get_code("JKM-C-JJWL-LDKP-") + # return code + # + # @api.model_create_multi + # def create(self, vals): + # obj = super(FixtureModel, self).create(vals) + # if obj.fixture_material_id: + # code = self._onchange_fixture_material_id(obj.fixture_material_id) + # obj.code = code + # return obj diff --git a/sf_base/models/tool_base_new.py b/sf_base/models/tool_base_new.py index e8769b80..18656c96 100644 --- a/sf_base/models/tool_base_new.py +++ b/sf_base/models/tool_base_new.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- +import json +import requests from odoo import fields, models, api +from odoo.exceptions import ValidationError +from odoo.addons.sf_base.commons.common import Common class CuttingToolMaterial(models.Model): @@ -75,6 +79,8 @@ class CuttingToolModel(models.Model): integral_coarse_medium_fine = fields.Selection([('粗', '粗'), ('中', '中'), ('精', '精')], '粗/中/精') integral_run_out_accuracy_max = fields.Char('整体式刀具端跳精度max') integral_run_out_accuracy_min = fields.Char('整体式刀具端跳精度min') + ramping_angle_ids = fields.One2many('sf.ramping.angle', 'standard_library_id', '坡铣角度', + domain=lambda self: [('standard_library_id', '=', self.id)]) fit_blade_shape_id = fields.Many2one('maintenance.equipment.image', '适配刀片形状', domain=[('type', '=', '刀片形状')]) @@ -87,8 +93,8 @@ class CuttingToolModel(models.Model): '柄部类型', domain=[('type', '=', '柄部类型')]) cutting_direction_ids = fields.Many2many('maintenance.equipment.image', 'cutting_direction_library_rel', '走刀方向', domain=[('type', '=', '走刀方向')]) - suitable_coolant_ids = fields.Many2many('maintenance.equipment.image', 'suitable_coolant_library_rel', - '适合冷却液', domain=[('type', '=', '冷却液')]) + suitable_coolant_ids = fields.Many2many('maintenance.equipment.image', 'suitable_coolants_library_rel', + '适合冷却方式', domain=[('type', '=', '冷却方式')]) compaction_way_id = fields.Many2one('maintenance.equipment.image', '压紧方式', domain=[('type', '=', '压紧方式')]) integral_tool_basic_parameters_ids = fields.One2many('sf.tool.materials.basic.parameters', @@ -104,21 +110,20 @@ class CuttingToolModel(models.Model): chuck_basic_parameters_ids = fields.One2many('sf.tool.materials.basic.parameters', 'standard_library_id', string='夹头基本参数') cutting_speed_ids = fields.One2many('sf.cutting.speed', 'standard_library_id', string='切削速度Vc') - feed_per_tooth_ids = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz', - domain=[('cutting_speed', '!=', False)]) - feed_per_tooth_ids_2 = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz', - domain=[('machining_method', '!=', False)]) - feed_per_tooth_ids_3 = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz', - domain=[('cutting_speed', '!=', False)]) - feed_per_tooth_ids_4 = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz', - domain=[('machining_method', '!=', False)]) + feed_per_tooth_ids = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz(整体式刀具)') + feed_per_tooth_ids_3 = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz(刀片)') material_model_id = fields.Many2one('sf.materials.model', '材料型号') # 适用夹头型号可以多选 - chuck_ids = fields.Many2many( + # chuck_ids = fields.Many2many( + # 'sf.cutting_tool.standard.library', + # relation='cutting_tool_type_library_handle_chuck_rel', + # column1='model_id_1', + # column2='model_id_2', + # domain="[('cutting_tool_material_id.name', '=', '夹头')]", + # string='适用夹头型号') + + chuck_id = fields.Many2one( 'sf.cutting_tool.standard.library', - relation='cutting_tool_type_library_handle_chuck_rel', - column1='model_id_1', - column2='model_id_2', domain="[('cutting_tool_material_id.name', '=', '夹头')]", string='适用夹头型号') cutter_bar_ids = fields.Many2many( @@ -138,22 +143,28 @@ class CuttingToolModel(models.Model): string='适用刀盘型号' # 使用空列表作为默认值 ) # 刀杆/参数 - blade_ids = fields.Many2many( + # blade_ids = fields.Many2many( + # 'sf.cutting_tool.standard.library', + # relation='cutting_tool_type_library_pad_blade_rel', + # column1='model_id_1', + # column2='model_id_2', + # domain="[('cutting_tool_material_id.name', '=', '刀片')]", + # string='适用刀片型号' # 使用空列表作为默认值 + # ) + + handle_id = fields.Many2one( 'sf.cutting_tool.standard.library', - relation='cutting_tool_type_library_pad_blade_rel', - column1='model_id_1', - column2='model_id_2', - domain="[('cutting_tool_material_id.name', '=', '刀片')]", - string='适用刀片型号' # 使用空列表作为默认值 - ) - handle_ids = fields.Many2many( - 'sf.cutting_tool.standard.library', - relation='cutting_tool_type_library_chuck_handle_rel', - column1='model_id_1', - column2='model_id_2', domain="[('cutting_tool_material_id.name', '=', '刀柄')]", string='适用刀柄型号' ) + # handle_ids = fields.Many2many( + # 'sf.cutting_tool.standard.library', + # relation='cutting_tool_type_library_chuck_handle_rel', + # column1='model_id_1', + # column2='model_id_2', + # domain="[('cutting_tool_material_id.name', '=', '刀柄')]", + # string='适用刀柄型号' + # ) active = fields.Boolean('有效', default=True) is_cloud = fields.Boolean('云端数据', default=False) @@ -175,7 +186,7 @@ class MaintenanceStandardImage(models.Model): image = fields.Binary(string='图文') type = fields.Selection( [('加工能力', '加工能力'), ('刀尖特征', '刀尖特征'), ('柄部类型', '柄部类型'), ('走刀方向', '走刀方向'), - ('冷却液', '冷却液'), ('压紧方式', '压紧方式'), ('刀片形状', '刀片形状'), ('冷却方式', '冷却方式')], + ('压紧方式', '压紧方式'), ('刀片形状', '刀片形状'), ('冷却方式', '冷却方式')], string='特征') equipment_id = fields.Many2many('maintenance.equipment', 'image_id', string='设备') equipment_lq_id = fields.Many2many('maintenance.equipment', 'image_lq_id', string='设备') @@ -233,3 +244,49 @@ class MaintenanceStandardImage(models.Model): else: record['image'] = "" return records + + +class ToolGroups(models.Model): + _name = 'sf.tool.groups' + _description = '刀具组' + + name = fields.Char('名称') + equipment_ids = fields.Many2many('maintenance.equipment', 'ref_maintenance_equipment', string='机台号') + remark = fields.Char('备注', size=50) + + # ==========机床刀具组接口========== + def _register_tool_groups(self, obj): + create_url = '/AutoDeviceApi/MaintenanceToolGroups' + 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(obj, token, sf_secret_key) + strurl = sf_sync_config['sf_url'] + create_url + device_id = '' + name = None + if obj: + for equipment_id in obj.equipment_ids: + device_id = '%s,%s' % (device_id, equipment_id.name) + name = obj.name + val = { + 'DeviceId': device_id, + 'GroupName': name, + } + kw = json.dumps(val, ensure_ascii=False) + r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers) + ret = r.json() + if r == 200: + return "机床刀具组发送成功" + else: + raise ValidationError("机床刀具组发送失败") + + # def write(self, vals): + # obj = super().write(vals) + # self._register_tool_groups(self) + # return obj + # + # @api.model_create_multi + # def create(self, vals_list): + # records = super(ToolGroups, self).create(vals_list) + # self._register_tool_groups(records) + # return records diff --git a/sf_base/models/tool_base_new.py.rej b/sf_base/models/tool_base_new.py.rej new file mode 100644 index 00000000..6db1f28a --- /dev/null +++ b/sf_base/models/tool_base_new.py.rej @@ -0,0 +1,10 @@ +diff a/sf_base/models/tool_base_new.py b/sf_base/models/tool_base_new.py (rejected hunks) +@@ -108,6 +108,4 @@ + cutting_speed_ids = fields.One2many('sf.cutting.speed', 'standard_library_id', string='切削速度Vc') +- feed_per_tooth_ids = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz', +- domain=[('cutting_speed', '!=', False)]) +- feed_per_tooth_ids_3 = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz', +- domain=[('cutting_speed', '!=', False)]) ++ feed_per_tooth_ids = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz') ++ feed_per_tooth_ids_3 = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz') + diff --git a/sf_base/models/tool_other_features.py b/sf_base/models/tool_other_features.py index acbb569d..7ad32bc2 100644 --- a/sf_base/models/tool_other_features.py +++ b/sf_base/models/tool_other_features.py @@ -6,6 +6,7 @@ class ToolMaterialsBasicParameters(models.Model): _description = '刀具物料基本参数' name = fields.Char('物料号', size=50) + code = fields.Char('编码', size=50) standard_library_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀具标准库') cutting_tool_type = fields.Char(related='standard_library_id.cutting_tool_type', string='刀具物料类型', store=True) @@ -13,8 +14,8 @@ class ToolMaterialsBasicParameters(models.Model): # 整体式刀具参数 total_length = fields.Float('总长度(mm)') blade_number = fields.Selection( - [('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8')], - string='刃数(个)') + [('0', '0'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8')], + string='刃数(个)', default='0') neck_diameter = fields.Float('颈部直径(mm)') neck_length = fields.Float('颈部长度(mm)') handle_diameter = fields.Float('柄部直径(mm)') @@ -40,19 +41,19 @@ class ToolMaterialsBasicParameters(models.Model): install_aperture_diameter = fields.Float('安装孔直径(mm)') chip_breaker_groove = fields.Selection([('无', '无'), ('单面', '单面'), ('双面', '双面')], string='有无断屑槽') + chip_breaker_type_code = fields.Char('断屑槽型代号') blade_teeth_model = fields.Selection( [('无', '无'), ('V牙型', 'V牙型'), ('米制全牙型', '米制全牙型'), ('美制全牙型', '美制全牙型'), ('惠氏全牙型', '惠氏全牙型'), ('BSPT全牙型', 'BSPT全牙型'), ('NPT全牙型', 'NPT全牙型'), ('UNJ全牙型', 'UNJ全牙型'), ('DIN405圆牙型', 'DIN405圆牙型'), ('ACME梯形', 'ACME梯形'), ('石油管螺纹刀片', '石油管螺纹刀片'), ('矮牙ACME梯形', '矮牙ACME梯形'), ('Trapeze30° 103', 'Trapeze30° 103')], string='刀片牙型', default='无') - blade_blade_number = fields.Selection([('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), - ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10')], - string='刀片的刃数(个)') + blade_blade_number = fields.Selection( + [('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8'), + ('9', '9'), ('10', '10')], + string='刀片的刃数(个)', default='0') main_included_angle = fields.Integer('主偏角(°)') top_angle = fields.Integer('顶角(°)') - blade_tip_dip_angle = fields.Integer('刀尖倾角(°)') - side_cutting_edge_angle = fields.Integer('侧切削角(°)') thread_model = fields.Selection([('无', '无'), ('外螺纹', '外螺纹'), ('内螺纹', '内螺纹')], string='螺纹类型', default='无') thread_num = fields.Float('每英寸螺纹数(tpi)') @@ -73,11 +74,8 @@ class ToolMaterialsBasicParameters(models.Model): is_cooling_hole = fields.Boolean('有无冷却孔') locating_slot_code = fields.Char('定位槽代号', size=20) installing_structure = fields.Char('安装结构', size=20) - blade_ids = fields.Many2many( - 'sf.cutting.tool.type', - relation='basic_param_pad_blade_rel', - column1='model_id_1', - column2='model_id_2', + blade_id = fields.Many2one( + 'sf.cutting_tool.standard.library', domain="[('cutting_tool_material_id.name', '=', '刀片')]", string='适配刀片型号' # 使用空列表作为默认值 ) @@ -90,295 +88,107 @@ class ToolMaterialsBasicParameters(models.Model): cutter_head_diameter = fields.Float('刀盘直径(mm)') interface_diameter = fields.Float('接口直径(mm)') # 刀柄参数 - flange_shank_length = fields.Float('法兰柄长(mm)') + flange_shank_length = fields.Float('法兰长(mm)') + flange_diameter = fields.Float('法兰直径(mm)') + fit_chuck_size = fields.Char('适配夹头尺寸') handle_external_diameter = fields.Float('柄部外径(mm)') handle_inside_diameter = fields.Float('柄部内径(mm)') + dynamic_balance_class = fields.Char('动平衡等级') min_clamping_diameter = fields.Float('最小夹持直径(mm)') max_clamping_diameter = fields.Float('最大夹持直径(mm)') clamping_mode = fields.Char('夹持方式', size=20) max_load_capacity = fields.Float('最大负载能力(kg)') taper = fields.Integer('锥度(°)') + shank_length = fields.Float('刀柄长度(mm)', digits=(3, 2)) + shank_diameter = fields.Float('刀柄直径(mm)') tool_changing_time = fields.Integer('换刀时间(s)') standard_rotate_speed = fields.Integer('标准转速(n/min)') max_rotate_speed = fields.Integer('最大转速(n/min)') diameter_slip_accuracy = fields.Char('径跳精度(mm)', size=20) cooling_model = fields.Char('冷却类型', size=20) - is_rough_machining = fields.Boolean('可粗加工', default=False) - is_finish_machining = fields.Boolean('可精加工', default=False) + taper_shank_model = fields.Char('锥柄型号') is_quick_cutting = fields.Boolean('可高速切削', default=False) - is_drill_hole = fields.Boolean('可钻孔', default=False) is_safe_lock = fields.Boolean('有无安全锁', default=False) + chuck_id = fields.Many2one( + 'sf.cutting_tool.standard.library', + domain="[('cutting_tool_material_id.name', '=', '夹头')]", + string='适配夹头型号' # 使用空列表作为默认值 + ) + nut = fields.Char('适配锁紧螺母型号') + # 夹头参数 er_size_model = fields.Char('ER尺寸型号', size=20) outer_diameter = fields.Float('外径(mm)') inner_diameter = fields.Float('内径(mm)') run_out_accuracy = fields.Char('跳动精度(mm)', size=20) top_diameter = fields.Float('顶部直径(mm)') - weight = fields.Float('重量(kg)', size=20) + weight = fields.Float('重量(kg)') clamping_length = fields.Float('夹持长度(mm)') clamping_tolerance = fields.Char('夹持公差(mm)', size=20) cooling_jacket = fields.Char('适用冷却套型号', size=50) - handle_ids = fields.Many2many( - 'sf.cutting.tool.type', - relation='basic_param_chuck_handle_rel', - column1='model_id_1', - column2='model_id_2', - domain="[('cutting_tool_material_id.name', '=', '刀柄')]", - string='适用刀柄型号' - ) - - def _json_integral_tool_basic_param(self, obj): - integral_tool_basic_param_str = (0, '', { - 'name': obj['name'], - 'cutting_tool_type': obj['cutting_tool_type'], - 'total_length': obj['total_length'], - 'blade_diameter': obj['blade_diameter'], - 'blade_length': obj['blade_length'], - 'blade_number': obj['blade_number'], - 'neck_length': obj['neck_length'], - 'neck_diameter': obj['neck_diameter'], - 'handle_diameter': obj['handle_diameter'], - 'handle_length': obj['handle_length'], - 'blade_tip_diameter': obj['blade_tip_diameter'], - 'blade_tip_working_size': obj['blade_tip_working_size'], - 'blade_tip_taper': obj['blade_tip_taper'], - 'blade_helix_angle': obj['blade_helix_angle'], - 'blade_width': obj['blade_width'], - 'blade_depth': obj['blade_depth'], - 'pitch': obj['pitch'], - 'cutting_depth': obj['cutting_depth'], - }) - return integral_tool_basic_param_str - - def _json_blade_basic_param(self, obj): - blade_basic_param_str = (0, '', { - 'name': obj['name'], - 'cutting_tool_type': obj['cutting_tool_type'], - 'length': obj['length'], - 'thickness': obj['thickness'], - 'width': obj['width'], - 'cutting_blade_length': obj['cutting_blade_length'], - 'relief_angle': obj['relief_angle'], - 'blade_tip_circular_arc_radius': obj['blade_tip_circular_arc_radius'], - 'inscribed_circle_diameter': obj['inscribed_circle_diameter'], - 'install_aperture_diameter': obj['install_aperture_diameter'], - 'pitch': obj['pitch'], - 'chip_breaker_groove': obj['chip_breaker_groove'], - 'blade_teeth_model': '无' if not obj['bladed_teeth_model'] else obj['bladed_teeth_model'], - 'blade_blade_number': obj['blade_blade_number'], - 'cutting_depth': obj['cutting_depth'], - 'blade_width': obj['blade_width'], - 'main_included_angle': obj['main_included_angle'], - 'top_angle': obj['top_angle'], - 'blade_tip_dip_angle': obj['blade_tip_dip_angle'], - 'side_cutting_edge_angle': obj['side_cutting_edge_angle'], - 'thread_model': '无' if not obj['thread_model'] else obj['thread_model'], - 'thread_num': obj['thread_num'], - 'blade_tip_height_tolerance': obj['blade_tip_height_tolerance'], - 'inscribed_circle_tolerance': obj['inscribed_circle_tolerance'], - 'thickness_tolerance': obj['thickness_tolerance'], - }) - return blade_basic_param_str - - def _json_cutter_arbor_basic_param(self, obj): - cutter_arbor_basic_param_str = (0, '', { - 'name': obj['name'], - 'cutting_tool_type': obj['cutting_tool_type'], - 'height': obj['height'], - 'width': obj['width'], - 'total_length': obj['total_length'], - 'knife_head_height': obj['knife_head_height'], - 'knife_head_width': obj['knife_head_width'], - 'knife_head_length': obj['knife_head_length'], - 'cutter_arbor_diameter': obj['cutter_arbor_diameter'], - 'main_included_angle': obj['main_included_angle'], - 'relief_angle': obj['relief_angle'], - 'cutting_depth': obj['cutting_depth'], - 'min_machining_aperture': obj['min_machining_aperture'], - 'install_blade_tip_num': obj['install_blade_tip_num'], - 'cutting_blade_model': obj['cutting_blade_model'], - 'is_cooling_hole': obj['is_cooling_hole'], - 'locating_slot_code': obj['locating_slot_code'], - 'installing_structure': obj['installing_structure'], - 'blade_ids': [(6, 0, [])] if not obj.get('blade_codes') else - self.evn['sf.cutting_tool.standard.library']._get_ids(obj['blade_codes']), - 'tool_shim': obj['tool_shim'], - 'cotter_pin': obj['cotter_pin'], - 'pressing_plate': obj['pressing_plate'], - 'screw': obj['screw'], - 'spanner': obj['spanner'], - }) - return cutter_arbor_basic_param_str - - def _json_cutter_head_basic_param(self, obj): - cutter_head_basic_param_str = (0, '', { - 'name': obj['name'], - 'cutting_tool_type': obj['cutting_tool_type'], - 'install_blade_tip_num': obj['install_blade_tip_num'], - 'blade_diameter': obj['blade_diameter'], - 'cutter_head_diameter': obj['cutter_head_diameter'], - 'interface_diameter': obj['interface_diameter'], - 'total_length': obj['total_length'], - 'blade_length': obj['blade_length'], - 'cutting_depth': obj['cutting_depth'], - 'main_included_angle': obj['main_included_angle'], - 'installing_structure': obj['installing_structure'], - 'blade_ids': [(6, 0, [])] if not obj.get('blade_codes') else - self.evn['sf.cutting_tool.standard.library']._get_ids(obj['blade_codes']), - 'screw': obj['screw'], - 'spanner': obj['spanner'], - 'cutting_blade_model': obj['cutting_blade_model'], - 'is_cooling_hole': obj['is_cooling_hole'], - 'locating_slot_code': obj['locating_slot_code'], - }) - return cutter_head_basic_param_str - - def _json_knife_handle_basic_param(self, obj): - knife_handle_basic_param_str = (0, '', { - 'name': obj['name'], - 'cutting_tool_type': obj['cutting_tool_type'], - 'total_length': obj['total_length'], - 'flange_shank_length': obj['flange_shank_length'], - 'handle_external_diameter': obj['handle_external_diameter'], - 'handle_inside_diameter': obj['handle_inside_diameter'], - 'min_clamping_diameter': obj['min_clamping_diameter'], - 'max_clamping_diameter': obj['max_clamping_diameter'], - 'clamping_mode': obj['clamping_mode'], - 'max_load_capacity': obj['max_load_capacity'], - 'taper': obj['taper'], - 'tool_changing_time': obj['tool_changing_time'], - 'standard_rotate_speed': obj['standard_rotate_speed'], - 'max_rotate_speed': obj['max_rotate_speed'], - 'diameter_slip_accuracy': obj['diameter_slip_accuracy'], - 'cooling_model': obj['cooling_model'], - 'is_rough_machining': obj['is_rough_machining'], - 'is_finish_machining': obj['is_finish_machining'], - 'is_quick_cutting': obj['is_quick_cutting'], - 'is_drill_hole': obj['is_drill_hole'], - 'is_safe_lock': obj['is_safe_lock'], - 'screw': obj['screw'], - 'spanner': obj['spanner'], - }) - return knife_handle_basic_param_str - - def _json_chuck_basic_param(self, obj): - chuck_basic_param_str = (0, '', { - 'name': obj['name'], - 'cutting_tool_type': obj['cutting_tool_type'], - 'er_size_model': obj['er_size_model'], - 'min_clamping_diameter': obj['min_clamping_diameter'], - 'max_clamping_diameter': obj['max_clamping_diameter'], - 'outer_diameter': obj['outer_diameter'], - 'inner_diameter': obj['inner_diameter'], - 'run_out_accuracy': obj['run_out_accuracy'], - 'total_length': obj['total_length'], - 'taper': obj['taper'], - 'run_out_accuracy': obj['run_out_accuracy'], - 'top_diameter': obj['top_diameter'], - 'weight': obj['weight'], - 'clamping_mode': obj['clamping_mode'], - 'clamping_length': obj['clamping_length'], - 'clamping_tolerance': obj['clamping_tolerance'], - 'max_load_capacity': obj['max_load_capacity'], - 'handle_ids': [(6, 0, [])] if not obj.get( - 'handle_codes') else self.evn['sf.cutting_tool.standard.library']._get_ids(obj['handle_codes']), - 'cooling_jacket': obj['cooling_jacket'], - }) - return chuck_basic_param_str + active = fields.Boolean(string='有效', default=True) class CuttingSpeed(models.Model): _name = 'sf.cutting.speed' _description = '切削速度Vc' + name = fields.Char('名称') product_template_id = fields.Many2one('product.template') standard_library_id = fields.Many2one('sf.cutting_tool.standard.library', string='标准库') + execution_standard_id = fields.Many2one('sf.international.standards', string='执行标准', store=True) material_code = fields.Char('材料代号') - material_id = fields.Many2one('sf.materials.model', '材料名称', - domain="[('standards_id', '=', execution_standard_id)]") - slope_milling_angle = fields.Integer('坡铣角度(°)') + material_name_id = fields.Many2one('sf.materials.model', '材料名称', + domain="[('standards_id', '=', execution_standard_id)]") material_grade = fields.Char('材料牌号') tensile_strength = fields.Char('拉伸强度 (N/mm²)') - hardness = fields.Integer('硬度(HRC)') - cutting_speed_n1 = fields.Char('径向切宽 ae=100%D1 ap=1*D1 切削速度Vc') - cutting_speed_n2 = fields.Char('径向切宽 ae=50%D1 ap=1.5*D1 切削速度Vc') - cutting_speed_n3 = fields.Char('径向切宽 ae=25%D1 ap=L1max 切削速度Vc') - cutting_speed_n4 = fields.Char('径向切宽 ae=15%D1 ap=L1max 切削速度Vc') - cutting_speed_n5 = fields.Char('径向切宽 ae=5%D1 ap=L1max 切削速度Vc') - rough_machining = fields.Char('粗加工 Vc(m/min)') - precision_machining = fields.Char('精加工 Vc(m/min)') - application = fields.Selection([('主应用', '主应用'), ('次应用', '次应用')], '主/次应用') + hardness = fields.Integer('硬度(hrc)') + ability_feature_library = fields.Many2one('maintenance.equipment.image', '加工方式', + domain="[('type', '=', '加工能力')]") + cutting_width_depth_id = fields.Many2one('sf.cutting.width.depth', '切削宽度和深度') + process_capability = fields.Selection([('粗加工', '粗加工'), ('精加工', '精加工')], string='粗/精加工') + cutting_speed = fields.Char('切削速度', required=True) + cutting_speed_max = fields.Float('最大值') + cutting_speed_min = fields.Float('最小值') - def _json_cutting_speed(self, obj): - cutting_speed_str = (0, '', { - 'execution_standard_id': self.env['sf.international.standards'].search( - [('code', '=', obj['execution_standard_code'])]).id, - 'material_code': obj['material_code'], - 'material_id': self.env['sf.materials.model'].search([('materials_no', '=', obj['material_name_code'])]).id, - 'material_grade': obj['material_grade'], - 'tensile_strength': obj['tensile_strength'], - 'hardness': obj['hardness'], - 'cutting_speed_n1': obj['cutting_speed_n1'], - 'cutting_speed_n2': obj['cutting_speed_n2'], - 'cutting_speed_n3': obj['cutting_speed_n3'], - 'cutting_speed_n4': obj['cutting_speed_n4'], - 'cutting_speed_n5': obj['cutting_speed_n5'], - 'rough_machining': obj['rough_machining'], - 'precision_machining': obj['precision_machining'], - 'application': obj['application'], - }) - return cutting_speed_str + application = fields.Selection([('主应用', '主应用'), ('次应用', '次应用')], '主/次应用') + active = fields.Boolean(string='有效', default=True) class FeedPerTooth(models.Model): _name = 'sf.feed.per.tooth' _description = '每齿走刀量fz' - _order = 'machining_method desc, blade_diameter, materials_type_id' + _order = 'blade_diameter,cutting_width_depth_id,materials_type_id' + name = fields.Char('名称') product_template_id = fields.Many2one('product.template') standard_library_id = fields.Many2one('sf.cutting_tool.standard.library', string='标准库') - cutting_speed = fields.Char('径向切宽 ae(mm)') - machining_method = fields.Selection([('直铣', '直铣'), ('坡铣', '坡铣')], string='加工方式') - materials_type_id = fields.Many2one('sf.materials.model', string='材料型号') blade_diameter = fields.Integer('刃部直径(mm)', readonly=True) - feed_per_tooth = fields.Char('每齿走刀量 (mm/z)') + materials_type_id = fields.Many2one('sf.materials.model', string='材料名称', readonly=True) + cutting_width_depth_id = fields.Many2one('sf.cutting.width.depth', '切削宽度和深度', readonly=True) + feed_per_tooth = fields.Char('每齿走刀量 (mm/z)', size=20) + active = fields.Boolean(string='有效', default=True) - def _json_feed_per_tooth(self, obj): - feed_per_tooth_str = (0, '', { - 'cutting_speed': obj['cutting_speed'], - 'blade_diameter': obj['blade_diameter'], - 'feed_per_tooth': obj['feed_per_tooth'], - }) - return feed_per_tooth_str - def _json_feed_per_tooth_2(self, obj): - feed_per_tooth_2_str = (0, '', { - 'machining_method': obj['machining_method'], - 'materials_type_id': self.env['sf.materials.model'].search( - [('materials_no', '=', obj['materials_type_code'])]).id, - 'blade_diameter': obj['blade_diameter'], - 'feed_per_tooth': obj['feed_per_tooth'], - }) - return feed_per_tooth_2_str - - def _json_feed_per_tooth_3(self, obj): - feed_per_tooth_3_str = (0, '', { - 'cutting_speed': obj['cutting_speed'], - 'feed_per_tooth': obj['feed_per_tooth'], - }) - return feed_per_tooth_3_str - - def _json_feed_per_tooth_4(self, obj): - feed_per_tooth_4_str = (0, '', { - 'machining_method': obj['machining_method'], - 'materials_type_id': self.env['sf.materials.model'].search( - [('materials_no', '=', obj['materials_type_code'])]).id, - 'feed_per_tooth': obj['feed_per_tooth'], - }) - return feed_per_tooth_4_str # @api.depends('product_template_id') # def _compute_product_template_id(self): # if self.product_template_id is not None: # self.blade_diameter = self.product_template_id.cutting_tool_blade_diameter + + +class CuttingWidthDepth(models.Model): + _name = 'sf.cutting.width.depth' + _description = '切削宽度和深度' + + name = fields.Char('名称') + + +class RampingAngle(models.Model): + _name = 'sf.ramping.angle' + _description = '坡铣角度' + + standard_library_id = fields.Many2one('sf.cutting_tool.standard.library', '刀具标准库') + + name = fields.Char('坡铣角度') diff --git a/sf_base/security/group_security.xml b/sf_base/security/group_security.xml index dd78c2c0..478d41b9 100644 --- a/sf_base/security/group_security.xml +++ b/sf_base/security/group_security.xml @@ -71,7 +71,7 @@ 计划总监 - + diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index 1767871b..0a319f34 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -1,34 +1,144 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_sf_machine_tool,sf_machine_tool,model_sf_machine_tool,base.group_user,1,1,1,1 -access_sf_machine_tool_type,sf_machine_tool_type,model_sf_machine_tool_type,base.group_user,1,1,1,1 -access_sf_machine_brand,sf_machine_brand,model_sf_machine_brand,base.group_user,1,1,1,1 -access_sf_machine_brand_tags,sf_machine_brand_tags,model_sf_machine_brand_tags,base.group_user,1,1,1,1 -access_sf_machine_control_system,sf_machine_control_system,model_sf_machine_control_system,base.group_user,1,1,1,1 -access_sf_processing_order,sf_processing_order,model_sf_processing_order,base.group_user,1,1,1,1 -access_sf_production_process,sf_production_process,model_sf_production_process,base.group_user,1,1,1,1 -access_sf_production_materials,sf_production_materials,model_sf_production_materials,base.group_user,1,1,1,1 -access_sf_materials_model,sf_materials_model,model_sf_materials_model,base.group_user,1,1,1,1 -access_sf_processing_technology,sf_processing_technology,model_sf_processing_technology,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 -access_sf_production_process_category,sf_production_process_category,model_sf_production_process_category,base.group_user,1,1,1,1 -access_sf_machine_tool_category,sf_machine_tool_category,model_sf_machine_tool_category,base.group_user,1,1,1,1 -access_sf_cutting_tool_material,sf_cutting_tool_material,model_sf_cutting_tool_material,base.group_user,1,1,1,1 -access_sf_cutting_tool_type,sf_cutting_tool_type,model_sf_cutting_tool_type,base.group_user,1,1,1,1 -access_sf_functional_cutting_tool,sf_functional_cutting_tool,model_sf_functional_cutting_tool,base.group_user,1,1,1,1 -access_sf_functional_cutting_tool_model,sf_functional_cutting_tool_model,model_sf_functional_cutting_tool_model,base.group_user,1,1,1,1 -access_sf_fixture_material,sf_fixture_material,model_sf_fixture_material,base.group_user,1,1,1,1 -access_sf_multi_mounting_type,sf_multi_mounting_type,model_sf_multi_mounting_type,base.group_user,1,1,1,1 -access_sf_fixture_model,sf_fixture_model,model_sf_fixture_model,base.group_user,1,1,1,1 +access_sf_machine_tool,sf_machine_tool,model_sf_machine_tool,base.group_user,1,1,1,0 +access_sf_machine_tool_admin,sf_machine_tool_admin,model_sf_machine_tool,base.group_system,1,1,1,0 +access_sf_machine_tool_type,sf_machine_tool_type,model_sf_machine_tool_type,base.group_user,1,1,1,0 +access_sf_machine_tool_type_admin,sf_machine_tool_type_admin,model_sf_machine_tool_type,base.group_system,1,1,1,0 +access_sf_machine_brand,sf_machine_brand,model_sf_machine_brand,base.group_user,1,1,1,0 +access_sf_machine_brand_admin,sf_machine_brand_admin,model_sf_machine_brand,base.group_system,1,1,1,0 +access_sf_machine_brand_tags,sf_machine_brand_tags,model_sf_machine_brand_tags,base.group_user,1,1,1,0 +access_sf_machine_brand_tags_admin,sf_machine_brand_tags_admin,model_sf_machine_brand_tags,base.group_system,1,1,1,0 +access_sf_machine_control_system,sf_machine_control_system,model_sf_machine_control_system,base.group_user,1,1,1,0 +access_sf_machine_control_system_admin,sf_machine_control_system_admin,model_sf_machine_control_system,base.group_system,1,1,1,0 +access_sf_processing_order,sf_processing_order,model_sf_processing_order,base.group_user,1,1,1,0 +access_sf_processing_order_admin,sf_processing_order_admin,model_sf_processing_order,base.group_system,1,1,1,0 +access_sf_production_process,sf_production_process,model_sf_production_process,base.group_user,1,1,1,0 +access_sf_production_process_admin,sf_production_process_admin,model_sf_production_process,base.group_system,1,1,1,0 +access_sf_production_materials,sf_production_materials,model_sf_production_materials,base.group_user,1,1,1,0 +access_sf_production_materials_admin,sf_production_materials_admin,model_sf_production_materials,base.group_system,1,1,1,0 +access_sf_materials_model,sf_materials_model,model_sf_materials_model,base.group_user,1,1,1,0 +access_sf_materials_model_admin,sf_materials_model_admin,model_sf_materials_model,base.group_system,1,1,1,0 +access_sf_processing_technology,sf_processing_technology,model_sf_processing_technology,base.group_user,1,1,1,0 +access_sf_processing_technology_admin,sf_processing_technology_admin,model_sf_processing_technology,base.group_system,1,1,1,0 +access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,base.group_user,1,1,1,0 +access_sf_supplier_sort_admin,sf_supplier_sort_admin,model_sf_supplier_sort,base.group_system,1,1,1,0 +access_sf_production_process_parameter,sf_production_process_parameter,model_sf_production_process_parameter,base.group_user,1,1,1,0 +access_sf_production_process_parameter_group_plan_director,sf_production_process_parameter_group_plan_director,model_sf_production_process_parameter,sf_base.group_plan_director,1,0,0,0 +access_sf_production_process_parameter_group_purchase_director,sf_production_process_parameter_group_purchase_director,model_sf_production_process_parameter,sf_base.group_purchase_director,1,0,0,0 +access_sf_production_process_parameter_group_sale_director,sf_production_process_parameter_group_sale_director,model_sf_production_process_parameter,sf_base.group_sale_director,1,0,0,0 +access_sf_production_process_parameter_admin,sf_production_process_parameter_admin,model_sf_production_process_parameter,base.group_system,1,1,1,0 +access_sf_production_process_category,sf_production_process_category,model_sf_production_process_category,base.group_user,1,1,1,0 +access_sf_production_process_category_admin,sf_production_process_category_admin,model_sf_production_process_category,base.group_system,1,1,1,0 +access_sf_machine_tool_category,sf_machine_tool_category,model_sf_machine_tool_category,base.group_user,1,1,1,0 +access_sf_machine_tool_category_admin,sf_machine_tool_category_admin,model_sf_machine_tool_category,base.group_system,1,1,1,0 +access_sf_cutting_tool_material,sf_cutting_tool_material,model_sf_cutting_tool_material,base.group_user,1,1,1,0 +access_sf_cutting_tool_material_admin,sf_cutting_tool_material_admin,model_sf_cutting_tool_material,base.group_system,1,1,1,0 +access_sf_cutting_tool_type,sf_cutting_tool_type,model_sf_cutting_tool_type,base.group_user,1,1,1,0 +access_sf_cutting_tool_type_admin,sf_cutting_tool_type_admin,model_sf_cutting_tool_type,base.group_system,1,1,1,0 +access_sf_cutting_tool_type_group_purchase_director,sf_cutting_tool_type_group_purchase_director,model_sf_cutting_tool_type,sf_base.group_purchase_director,1,1,0,0 +access_sf_cutting_tool_type_group_sale_director,sf_cutting_tool_type_group_sale_director,model_sf_cutting_tool_type,sf_base.group_sale_director,1,1,0,0 +access_sf_cutting_tool_type_group_plan_director,sf_cutting_tool_type_group_plan_director,model_sf_cutting_tool_type,sf_base.group_plan_director,1,1,0,0 + +access_sf_functional_cutting_tool,sf_functional_cutting_tool,model_sf_functional_cutting_tool,base.group_user,1,1,1,0 +access_sf_functional_cutting_tool_admin,sf_functional_cutting_tool_admin,model_sf_functional_cutting_tool,base.group_system,1,1,1,0 +access_sf_functional_cutting_tool_model,sf_functional_cutting_tool_model,model_sf_functional_cutting_tool_model,base.group_user,1,1,1,0 +access_sf_functional_cutting_tool_model_admin,sf_functional_cutting_tool_model_admin,model_sf_functional_cutting_tool_model,base.group_system,1,1,1,0 +access_sf_fixture_material,sf_fixture_material,model_sf_fixture_material,base.group_user,1,1,1,0 +access_sf_fixture_material_admin,sf_fixture_material_admin,model_sf_fixture_material,base.group_system,1,1,1,0 +access_sf_fixture_materials_basic_parameters,sf_fixture_materials_basic_parameters,model_sf_fixture_materials_basic_parameters,base.group_user,1,1,1,0 +access_sf_fixture_materials_basic_parameters_admin,sf_fixture_materials_basic_parameters_admin,model_sf_fixture_materials_basic_parameters,base.group_system,1,1,1,0 +access_sf_multi_mounting_type,sf_multi_mounting_type,model_sf_multi_mounting_type,base.group_user,1,1,1,0 +access_sf_multi_mounting_type_admin,sf_multi_mounting_type_admin,model_sf_multi_mounting_type,base.group_system,1,1,1,0 +access_sf_fixture_model,sf_fixture_model,model_sf_fixture_model,base.group_user,1,1,1,0 +access_sf_fixture_model_admin,sf_fixture_model_admin,model_sf_fixture_model,base.group_system,1,1,1,0 access_sf_functional_fixture_type,sf_functional_fixture_type,model_sf_functional_fixture_type,base.group_user,1,1,1,1 -access_sf_functional_fixture,sf_functional_fixture,model_sf_functional_fixture,base.group_user,1,1,1,1 -access_sf_sync_common,sf_sync_common,model_sf_sync_common,base.group_user,1,1,1,1 -access_sf_international_standards,sf_international_standards,model_sf_international_standards,base.group_user,1,1,1,1 -access_material_apply,material_apply,model_material_apply,base.group_user,1,1,1,1 -access_sf_cutting_tool_standard_library,sf_cutting_tool_standard_library,model_sf_cutting_tool_standard_library,base.group_user,1,1,1,1 -access_sf_tool_materials_basic_parameters,sf_tool_materials_basic_parameters,model_sf_tool_materials_basic_parameters,base.group_user,1,1,1,1 -access_sf_cutting_speed,sf_cutting_speed,model_sf_cutting_speed,base.group_user,1,1,1,1 -access_sf_feed_per_tooth,sf_feed_per_tooth,model_sf_feed_per_tooth,base.group_user,1,1,1,1 +access_sf_functional_fixture_type_admin,sf_functional_fixture_type_admin,model_sf_functional_fixture_type,base.group_system,1,1,1,0 +access_sf_functional_fixture,sf_functional_fixture,model_sf_functional_fixture,base.group_user,1,1,1,0 +access_sf_functional_fixture_admin,sf_functional_fixture_admin,model_sf_functional_fixture,base.group_system,1,1,1,0 +access_sf_sync_common,sf_sync_common,model_sf_sync_common,base.group_user,1,1,1,0 +access_sf_sync_common,sf_sync_common_admin,model_sf_sync_common,base.group_system,1,1,1,0 +access_sf_international_standards,sf_international_standards,model_sf_international_standards,base.group_user,1,1,1,0 +access_sf_international_standards_admin,sf_international_standards_admin,model_sf_international_standards,base.group_system,1,1,1,0 +access_material_apply,material_apply,model_material_apply,base.group_user,1,1,1,0 +access_material_apply_admin,material_apply_admin,model_material_apply,base.group_system,1,1,1,0 +access_sf_cutting_tool_standard_library,sf_cutting_tool_standard_library,model_sf_cutting_tool_standard_library,base.group_user,1,1,1,0 +access_sf_cutting_tool_standard_library_admin,sf_cutting_tool_standard_library_admin,model_sf_cutting_tool_standard_library,base.group_system,1,1,1,0 +access_sf_tool_materials_basic_parameters,sf_tool_materials_basic_parameters,model_sf_tool_materials_basic_parameters,base.group_user,1,1,1,0 +access_sf_tool_materials_basic_parameters_admin,sf_tool_materials_basic_parameters_admin,model_sf_tool_materials_basic_parameters,base.group_system,1,1,1,0 +access_sf_cutting_speed,sf_cutting_speed,model_sf_cutting_speed,base.group_user,1,1,1,0 +access_sf_cutting_speed_admin,sf_cutting_speed_admin,model_sf_cutting_speed,base.group_system,1,1,1,0 +access_sf_cutting_speed_group_purchase_director,sf_cutting_speed_group_purchase_director,model_sf_cutting_speed,sf_base.group_purchase_director,1,1,1,0 +access_sf_cutting_speed_group_sale_director,sf_cutting_speed_group_sale_director,model_sf_cutting_speed,sf_base.group_sale_director,1,1,1,0 +access_sf_cutting_speed_group_plan_director,sf_cutting_speed_group_plan_director,model_sf_cutting_speed,sf_base.group_plan_director,1,1,1,0 +access_sf_feed_per_tooth_group_purchase_director,sf_feed_per_tooth_group_purchase_director,model_sf_feed_per_tooth,sf_base.group_purchase_director,1,1,0,0 +access_sf_feed_per_tooth_group_sale_director,sf_feed_per_tooth_group_sale_director,model_sf_feed_per_tooth,sf_base.group_sale_director,1,1,0,0 +access_sf_feed_per_tooth_group_plan_director,sf_feed_per_tooth_group_plan_director,model_sf_feed_per_tooth,sf_base.group_plan_director,1,1,0,0 +access_sf_feed_per_tooth,sf_feed_per_tooth,model_sf_feed_per_tooth,base.group_user,1,1,1,0 +access_sf_feed_per_tooth_admin,sf_feed_per_tooth_admin,model_sf_feed_per_tooth,base.group_system,1,1,1,0 +access_sf_ramping_angle,sf_ramping_angle,model_sf_ramping_angle,base.group_user,1,1,1,1 +access_sf_ramping_angle_admin,sf_ramping_angle_admin,model_sf_ramping_angle,base.group_system,1,1,1,1 +access_sf_cutting_width_depth,sf_cutting_width_depth,model_sf_cutting_width_depth,base.group_user,1,1,1,1 +access_sf_cutting_width_depth_admin,sf_cutting_width_depth_admin,model_sf_cutting_width_depth,base.group_system,1,1,1,1 +access_sf_machine_tool,sf_machine_tool,model_sf_machine_tool,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_machine_tool_type,sf_machine_tool_type,model_sf_machine_tool_type,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_machine_brand,sf_machine_brand,model_sf_machine_brand,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_machine_brand_group_plan_director,sf_machine_brand_group_plan_director,model_sf_machine_brand,sf_base.group_plan_director,1,0,0,0 +access_sf_machine_brand_group_purchase_director,sf_machine_brand_group_purchase_director,model_sf_machine_brand,sf_base.group_purchase_director,1,0,0,0 +access_sf_machine_brand_group_sale_director,sf_machine_brand_group_sale_director,model_sf_machine_brand,sf_base.group_sale_director,1,0,0,0 +access_sf_machine_brand_tags,sf_machine_brand_tags,model_sf_machine_brand_tags,base.group_user,1,1,1,1 +access_sf_machine_control_system,sf_machine_control_system,model_sf_machine_control_system,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_processing_order,sf_processing_order,model_sf_processing_order,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_production_process,sf_production_process,model_sf_production_process,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_production_materials,sf_production_materials,model_sf_production_materials,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_production_materials_group_plan_director,sf_production_materials_group_plan_director,model_sf_production_materials,sf_base.group_plan_director,1,1,0,0 +access_sf_production_materials_group_purchase_director,sf_production_materials_group_purchase_director,model_sf_production_materials,sf_base.group_purchase_director,1,1,0,0 +access_sf_production_materials_group_sale_director,sf_production_materials_group_sale_director,model_sf_production_materials,sf_base.group_sale_director,1,1,0,0 +access_sf_materials_model,sf_materials_model,model_sf_materials_model,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_materials_model_group_plan_director,sf_materials_model_group_plan_director,model_sf_materials_model,sf_base.group_plan_director,1,0,0,0 +access_sf_materials_model_group_purchase_director,sf_materials_model_group_purchase_director,model_sf_materials_model,sf_base.group_purchase_director,1,0,0,0 +access_sf_materials_model_group_sale_director,sf_materials_model_group_sale_director,model_sf_materials_model,sf_base.group_sale_director,1,0,0,0 +access_sf_processing_technology,sf_processing_technology,model_sf_processing_technology,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_production_process_parameter,sf_production_process_parameter,model_sf_production_process_parameter,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_production_process_category,sf_production_process_category,model_sf_production_process_category,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_machine_tool_category,sf_machine_tool_category,model_sf_machine_tool_category,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_cutting_tool_material_group_purchase_director,sf_cutting_tool_material_group_purchase_director,model_sf_cutting_tool_material,sf_base.group_purchase_director,1,0,1,0 +access_sf_cutting_tool_material_group_sale_director,sf_cutting_tool_material_group_sale_director,model_sf_cutting_tool_material,sf_base.group_sale_director,1,0,1,0 +access_sf_cutting_tool_material_group_plan_director,sf_cutting_tool_material_group_plan_director,model_sf_cutting_tool_material,sf_base.group_plan_director,1,0,1,0 +access_sf_cutting_tool_type,sf_cutting_tool_type,model_sf_cutting_tool_type,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_functional_cutting_tool,sf_functional_cutting_tool,model_sf_functional_cutting_tool,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_functional_cutting_tool_model,sf_functional_cutting_tool_model,model_sf_functional_cutting_tool_model,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_fixture_material,sf_fixture_material,model_sf_fixture_material,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_fixture_materials_basic_parameters,sf_fixture_materials_basic_parameters,model_sf_fixture_materials_basic_parameters,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_multi_mounting_type,sf_multi_mounting_type,model_sf_multi_mounting_type,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_fixture_model,sf_fixture_model,model_sf_fixture_model,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_functional_fixture_type,sf_functional_fixture_type,model_sf_functional_fixture_type,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_functional_fixture,sf_functional_fixture,model_sf_functional_fixture,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_sync_common,sf_sync_common,model_sf_sync_common,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_international_standards,sf_international_standards,model_sf_international_standards,sf_base.group_sf_mrp_user,1,0,0,0 +access_material_apply,material_apply,model_material_apply,sf_base.group_sf_mrp_user,1,0,0,0 + +access_sf_cutting_tool_standard_library_group_sf_mrp_user,sf_cutting_tool_standard_library_group_sf_mrp_user,model_sf_cutting_tool_standard_library,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_cutting_tool_standard_library_group_purchase_director,sf_cutting_tool_standard_library_group_purchase_director,model_sf_cutting_tool_standard_library,sf_base.group_purchase_director,1,0,1,0 +access_sf_cutting_tool_standard_library_group_plan_director,sf_cutting_tool_standard_library_group_plan_director,model_sf_cutting_tool_standard_library,sf_base.group_plan_director,1,0,1,0 +access_sf_cutting_tool_standard_library_group_sale_director,sf_cutting_tool_standard_library_group_sale_director,model_sf_cutting_tool_standard_library,sf_base.group_sale_director,1,0,1,0 + +access_sf_tool_groups,sf_tool_groups,model_sf_tool_groups,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_tool_materials_basic_parameters_group_sale_director,sf_tool_materials_basic_parameters_group_sale_director,model_sf_tool_materials_basic_parameters,sf_base.group_sale_director,1,0,1,0 +access_sf_tool_materials_basic_parameters_group_plan_director,sf_tool_materials_basic_parameters_group_plan_director,model_sf_tool_materials_basic_parameters,sf_base.group_plan_director,1,0,1,0 +access_sf_tool_materials_basic_parameters_group_purchase_director,sf_tool_materials_basic_parameters_group_purchase_director,model_sf_tool_materials_basic_parameters,sf_base.group_purchase_director,1,0,1,0 + +access_sf_cutting_speed,sf_cutting_speed,model_sf_cutting_speed,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_cutting_speed_group_purchase,sf_cutting_speed_group_purchase,model_sf_cutting_speed,sf_base.group_purchase,1,0,0,0 +access_sf_cutting_speed_group_sale_salemanager,sf_cutting_speed_group_sale_salemanager,model_sf_cutting_speed,sf_base.group_sale_salemanager,1,0,0,0 + + +access_sf_feed_per_tooth,sf_feed_per_tooth,model_sf_feed_per_tooth,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_feed_per_tooth_group_purchase,sf_feed_per_tooth_group_purchase,model_sf_feed_per_tooth,sf_base.group_purchase,1,0,0,0 +access_sf_ramping_angle,sf_ramping_angle,model_sf_ramping_angle,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_ramping_angle_group_purchase,sf_ramping_angle_group_purchase,model_sf_ramping_angle,sf_base.group_purchase,1,0,0,0 +access_sf_cutting_width_depth,sf_cutting_width_depth,model_sf_cutting_width_depth,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_cutting_width_depth_group_purchase,sf_cutting_width_depth_group_purchase,model_sf_cutting_width_depth,sf_base.group_purchase,1,0,0,0 + access_maintenance_equipment_image,maintenance_equipment_image,model_maintenance_equipment_image,base.group_user,1,1,1,1 access_purchase_order_group_purchase,access_purchase_order_group_purchase,purchase.model_purchase_order,sf_base.group_purchase,1,1,1,0 access_purchase_order_group_purchase_director,access_purchase_order_group_purchase_director,purchase.model_purchase_order,sf_base.group_purchase_director,1,1,1,0 @@ -36,6 +146,9 @@ access_purchase_order_line_group_purchase,access_purchase_order_line_group_purch access_purchase_order_line_group_purchase_director,access_purchase_order_line_group_purchase_director,purchase.model_purchase_order_line,sf_base.group_purchase_director,1,1,1,0 access_spindle_taper_type,spindle_taper_type,model_spindle_taper_type,base.group_user,1,1,1,1 +access_sf_tool_groups_group_plan_dispatch,sf_tool_groups,model_sf_tool_groups,sf_base.group_plan_dispatch,1,0,0,0 +access_sf_tool_groups_group_sf_tool_user,sf_tool_groups,model_sf_tool_groups,sf_base.group_sf_tool_user,1,1,1,1 + access_purchase_order,purchase.order,purchase.model_purchase_order,sf_base.group_plan_dispatch,1,0,0,0 @@ -44,11 +157,32 @@ access_purchase_order_line,purchase.order.line,purchase.model_purchase_order_lin access_account_move_line,account.move.line,account.model_account_move_line,sf_base.group_plan_dispatch,1,0,0,0 +access_sf_machine_tool,sf_machine_tool,model_sf_machine_tool,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_machine_tool_type,sf_machine_tool_type,model_sf_machine_tool_type,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_machine_brand,sf_machine_brand,model_sf_machine_brand,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_machine_brand_tags,sf_machine_brand_tags,model_sf_machine_brand_tags,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_machine_control_system,sf_machine_control_system,model_sf_machine_control_system,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_processing_order,sf_processing_order,model_sf_processing_order,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_production_process,sf_production_process,model_sf_production_process,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_production_materials,sf_production_materials,model_sf_production_materials,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_materials_model,sf_materials_model,model_sf_materials_model,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_processing_technology,sf_processing_technology,model_sf_processing_technology,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_production_process_parameter,sf_production_process_parameter,model_sf_production_process_parameter,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_production_process_category,sf_production_process_category,model_sf_production_process_category,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_machine_tool_category,sf_machine_tool_category,model_sf_machine_tool_category,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_cutting_tool_material,sf_cutting_tool_material,model_sf_cutting_tool_material,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_cutting_tool_type,sf_cutting_tool_type,model_sf_cutting_tool_type,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_functional_cutting_tool,sf_functional_cutting_tool,model_sf_functional_cutting_tool,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_functional_cutting_tool_model,sf_functional_cutting_tool_model,model_sf_functional_cutting_tool_model,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_fixture_material,sf_fixture_material,model_sf_fixture_material,sf_base.group_sf_mrp_user,1,1,0,0 +access_sf_fixture_materials_basic_parameters,sf_fixture_materials_basic_parameters,model_sf_fixture_materials_basic_parameters,sf_base.group_sf_mrp_user,1,1,0,0 +access_mrp_production_group_sale_salemanager,mrp_production_group_sale_salemanager,mrp.model_mrp_production,sf_base.group_sale_salemanager,1,0,0,0 +access_mrp_production_group_sale_director,mrp_production_group_sale_director,mrp.model_mrp_production,sf_base.group_sale_director,1,0,0,0 - - - - - - +access_material_apply_group_plan_dispatch,material_apply,model_material_apply,sf_base.group_plan_dispatch,1,0,0,0 +access_sf_machine_brand_tags_group_plan_dispatch,sf_machine_brand_tags,model_sf_machine_brand_tags,sf_base.group_plan_dispatch,1,0,0,0 +access_ir_actions_act_window_group_plan_dispatch,ir.actions.act_window,base.model_ir_actions_act_window,sf_base.group_plan_dispatch,1,0,0,0 +access_ir_actions_act_window_view_group_plan_dispatch,ir.actions.act_window.view,base.model_ir_actions_act_window_view,sf_base.group_plan_dispatch,1,0,0,0 +access_sf_supplier_sort_group_plan_dispatch,sf.supplier.sort,model_sf_supplier_sort,sf_base.group_plan_dispatch,1,0,0,0 \ No newline at end of file diff --git a/sf_base/views/change_base_view.xml b/sf_base/views/change_base_view.xml new file mode 100644 index 00000000..3c02351a --- /dev/null +++ b/sf_base/views/change_base_view.xml @@ -0,0 +1,15 @@ + + + + + sf.base.res.partner.kanban + res.partner + + + +
  • +
    +
    +
    +
    +
    diff --git a/sf_base/views/fixture_view.xml b/sf_base/views/fixture_view.xml index 487899eb..692c3b7f 100644 --- a/sf_base/views/fixture_view.xml +++ b/sf_base/views/fixture_view.xml @@ -32,30 +32,6 @@
    - - - - - - - - - - - - - - - - - - - - - - - - 夹具物料 ir.actions.act_window @@ -96,28 +72,6 @@ - - - - - - - - - - - - - - - - - - - - - - 联装类型 ir.actions.act_window @@ -151,9 +105,9 @@ context="{'group_by' : 'multi_mounting_type_id'}"/> - - @@ -181,15 +140,19 @@

    - +

    - - + + - + + + @@ -198,67 +161,192 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/sf_base/views/tool_basic_param.xml b/sf_base/views/tool_basic_param.xml index dfe3eaf7..616905ca 100644 --- a/sf_base/views/tool_basic_param.xml +++ b/sf_base/views/tool_basic_param.xml @@ -46,8 +46,6 @@ - - @@ -73,7 +71,7 @@ - + diff --git a/sf_base/views/tool_menu.xml b/sf_base/views/tool_menu.xml index cddb7d90..82ecca18 100644 --- a/sf_base/views/tool_menu.xml +++ b/sf_base/views/tool_menu.xml @@ -92,5 +92,12 @@ action="action_maintenance_equipment_image" sequence="5"/> + + diff --git a/sf_base/views/tool_views.xml b/sf_base/views/tool_views.xml index b2994cca..5763b3a0 100644 --- a/sf_base/views/tool_views.xml +++ b/sf_base/views/tool_views.xml @@ -149,12 +149,20 @@ options="{'format': false}"/> (mm)&nbsp; + + + - + @@ -221,7 +229,7 @@ - + @@ -232,24 +240,22 @@ - - - - - + + + + - + + + + - - - - @@ -260,29 +266,29 @@ - - - - - + + + + + - + + - - - - + + + @@ -297,14 +303,14 @@ - + + - + - - + @@ -314,27 +320,25 @@ + + + - - + + + - - - - - - + + + + + - - - - - - - + + - + + - - - - - @@ -364,23 +364,20 @@ - + - + - - - - - - - - + + + + @@ -389,33 +386,18 @@ - - - - - - - - + - + - - - - - - - + - + @@ -508,34 +490,53 @@ [] - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 刀具组 + sf.tool.groups + + + + + + + + + + + + 刀具组 + ir.actions.act_window + sf.tool.groups + tree + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sf_bf_connect/controllers/controllers.py b/sf_bf_connect/controllers/controllers.py index 1a5f3fa5..aa31b8b6 100644 --- a/sf_bf_connect/controllers/controllers.py +++ b/sf_bf_connect/controllers/controllers.py @@ -33,6 +33,8 @@ class Sf_Bf_Connect(http.Controller): aa = request.env['sale.order'].sudo().search([('name', '=', order_id.name)]) logging.info('get_bfm_process_or===================================:%s' % order_id.name) aa.default_code = kw['order_number'] + if kw.get('logistics_way'): + aa.logistics_way = kw['logistics_way'] logging.info('get_bfm_process_order_listaaaaaaaaaaaaaaaaaaaaaaaaaaaa================:%s' % aa.default_code) for item in bfm_process_order_list: product = request.env['product.template'].sudo().product_create(product_id, item, order_id, diff --git a/sf_bf_connect/models/http.py b/sf_bf_connect/models/http.py index 8f546c88..ebd85439 100644 --- a/sf_bf_connect/models/http.py +++ b/sf_bf_connect/models/http.py @@ -21,6 +21,7 @@ class Http(models.AbstractModel): def _auth_method_sf_token(cls): # 从headers.environ中获取对方传过来的token,timestamp,加密的校验字符串 datas = request.httprequest.headers.environ + logging.info(datas) if 'HTTP_TOKEN' in datas: _logger.info('token:%s' % datas['HTTP_TOKEN']) # 查询密钥 @@ -40,6 +41,7 @@ class Http(models.AbstractModel): raise AuthenticationError('请求已过期') check_str = '%s%s%s' % (datas['HTTP_TOKEN'], post_time, factory_secret.sf_secret_key) check_sf_str = hashlib.sha1(check_str.encode('utf-8')).hexdigest() + _logger.info('check_str:%s' % check_sf_str) if check_sf_str != datas['HTTP_CHECKSTR']: raise AuthenticationError('数据校验不通过') else: diff --git a/sf_bf_connect/models/jd_eclp.py b/sf_bf_connect/models/jd_eclp.py index 85092b57..45fae2d8 100644 --- a/sf_bf_connect/models/jd_eclp.py +++ b/sf_bf_connect/models/jd_eclp.py @@ -42,6 +42,25 @@ class JdEclp(models.Model): # bill_show = fields.Binary(string='物流面单展示', readonly=True, related='self.bill.datas') bill_show = fields.Binary(string='物流面单展示', readonly=True) check_out = fields.Char(string='查询是否为出库单', compute='_check_is_out') + # 是否下了快递单 + is_bill = fields.Boolean(string='是否下了快递单', default=False) + # 物流状态 + logistics_status = fields.Selection([('0', '未下单'), ('1', '已下单'), ('2', '已获取物流面单'), ('3', '已打印物流单')], + string='物流状态', default='0', readonly=True) + + logistics_way = fields.Selection([('自提', '自提'), ('到付', '到付'), ('在线支付', '在线支付')], string='物流方式', readonly=True) + + def button_validate(self): + """ + 重写出库方法,获取物流面单 + """ + res = super(JdEclp, self).button_validate() + if self.check_out == 'OUT': + if self.logistics_way != '自提': + if self.logistics_status != '2': + raise ValidationError('非自提订单,必须先下物流单,并获取物流面单后才可出库!') + return res + @api.depends('name') def _check_is_out(self): @@ -68,6 +87,7 @@ class JdEclp(models.Model): # if self.receiverName and self.receiverMobile and self.receiverProvinceName and self.receiverCityName and # self.receiverCountyName and self.receiverTownName: sale_order_id = self.env['sale.order'].search([('name', '=', self.origin)]) + self.logistics_way = sale_order_id.logistics_way # stock_picking_type_id = self.enc['stock.picking.type'].search([('picking_type_id', '=', '')]) # if sale_order_id.address_of_delivery != False: # if not sale_order_id: @@ -141,6 +161,8 @@ class JdEclp(models.Model): response = requests.post(url2, json=json2, data=None) # _logger.info('调用成功2', response.json()['result']['wbNo']) self.carrier_tracking_ref = response.json()['result']['wbNo'] + self.is_bill = True + self.logistics_status = '1' # else: # raise UserError("选择京东物流才能下单呦") @@ -180,3 +202,4 @@ class JdEclp(models.Model): # 'model_name': 'stock.picking', }) _logger.info(attachment) + self.logistics_status = '2' diff --git a/sf_bf_connect/views/res_partner_view.xml b/sf_bf_connect/views/res_partner_view.xml index 70609554..d88d14aa 100644 --- a/sf_bf_connect/views/res_partner_view.xml +++ b/sf_bf_connect/views/res_partner_view.xml @@ -9,8 +9,8 @@ - - + + diff --git a/sf_bf_connect/views/view.xml b/sf_bf_connect/views/view.xml index c4f0e446..6db5cb1d 100644 --- a/sf_bf_connect/views/view.xml +++ b/sf_bf_connect/views/view.xml @@ -12,16 +12,30 @@ + + + + + + + + + + + 物流 stock.picking + + + + @@ -48,7 +56,7 @@ - + @@ -56,21 +64,25 @@ domain="[('brand_id', '=', brand_id)]"/> + - + - 货架货位 + 货位看板 ir.actions.act_window sf.shelf.location kanban,form - [('location_type', '=', '货位'),('check_state','=','enable')] + @@ -161,7 +258,7 @@ groups="sf_warehouse.group_sf_stock_user"/> - 货架货位 + 货位 ir.actions.act_window sf.shelf.location tree,form @@ -184,8 +281,8 @@ - diff --git a/sf_warehouse/views/view.xml b/sf_warehouse/views/view.xml index e4a2ea85..39d5a8c0 100644 --- a/sf_warehouse/views/view.xml +++ b/sf_warehouse/views/view.xml @@ -175,17 +175,17 @@ - - stock.location.tree.sf.inherit - stock.location - - - - - - - + + + + + + + + + + + @@ -206,17 +206,17 @@ - - stock.warehouse.tree.sf.inherit - stock.warehouse - - - - - - - + + + + + + + + + + + @@ -238,17 +238,17 @@ - - stock.route.tree.sf.inherit - stock.route - - - - - - - + + + + + + + + + + + @@ -269,17 +269,17 @@ - - stock.rule.tree.sf.inherit - stock.rule - - - - - - - + + + + + + + + + + + @@ -300,198 +300,198 @@ - - stock.picking.type.tree.sf.inherit - stock.picking.type - - - - - - - + + + + + + + + + + + - - product.category.form.sf.inherit - product.category - - - -
    - -
    + + + + + + + + + + + + + -
    -
    -
    + + + - - product.category.tree.sf.inherit - product.category - - - - - - - + + + + + + + + + + + - - uom.category.form.sf.inherit - uom.category - - - -
    - -
    + + + + + + + + + + + + + -
    -
    -
    + + + - - uom.category.tree.sf.inherit - uom.category - - - - - - - + + + + + + + + + + + - - - barcode.nomenclature.form.sf.inherit - barcode.nomenclature - - - -
    - -
    + + + + + + + + + + + + + + -
    -
    -
    + + + - - barcode.nomenclature.tree.sf.inherit - barcode.nomenclature - - - - - - - + + + + + + + + + + + - - stock.putaway.rule.tree.sf.inherit - stock.putaway.rule - - - - - + -
    - -
    - - -
    -
    + +
    + - - stock.barcode.quant.kanban - stock.quant - 1000 - - - - - - -
    - -
    -
    - - - + + stock.barcode.quant.kanban + stock.quant + 1000 + + + + + + +
    + + + +
    +
    + + + +
    -
    - - - - - + + + + + - - stock.quant.kanban.barcode - stock.quant - 1000 - - - - -
    -
    - + + stock.quant.kanban.barcode + stock.quant + 1000 + + + + +
    +
    + + + +
    +
    + + + + + +
    +
    + + +
    +
    + + +
    -
    - - - - -
    -
    - -
    -
    - -
    -
    - - - - - + + + + + - - stock_barcode.quant.tree.inherit - stock.quant - - primary - - - UoM - show - - - hide - - - hide - - - + + stock_barcode.quant.tree.inherit + stock.quant + + primary + + + UoM + show + + + hide + + + hide + + + diff --git a/stock_barcode/views/stock_picking_views.xml b/stock_barcode/views/stock_picking_views.xml index d61de200..d516844c 100644 --- a/stock_barcode/views/stock_picking_views.xml +++ b/stock_barcode/views/stock_picking_views.xml @@ -1,181 +1,174 @@ - - - stock.move.line.operations.tree.inherit - stock.move.line - - - - - - - - {'barcode_events': True} - field_float_scannable - - - + + + + stock.move.line.kanban.inherited + stock.move.line + + + + + + + + + + - - stock.move.line.kanban.inherited - stock.move.line - - - - - - - - - - - - - stock.picking.form.view.barcode - stock.picking - 1000 - -
    - - - -
    - -
    -
    + + + + + + +
    +
    + +
    + - - Open picking form - stock.picking - form - { - 'res_id': active_id, - } - - + + Open picking form + stock.picking + form + { + 'res_id': active_id, + } + + - - stock.picking.view.kanban.barcode - stock.picking - - + + stock.picking.view.kanban.barcode + stock.picking + + - - - - - - + + + + + + - - Operation Types - stock.picking.type - - - - - - - + + Operation Types + stock.picking.type + + + + + + + - - Operation Types - stock.picking.type - - - - - - - - - - - - - - - - - - - - + Operation Types + stock.picking.type + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + +