合并企业版代码(未测试,先提交到测试分支)

This commit is contained in:
qihao.gong@jikimo.com
2023-04-14 17:42:23 +08:00
parent 7a7b3d7126
commit d28525526a
1300 changed files with 513579 additions and 5426 deletions

View File

@@ -0,0 +1,5 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import change_production_qty
from . import additional_product
from . import propose_change

View File

@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, api, fields
class MrpWorkorderAdditionalProduct(models.TransientModel):
_name = "mrp_workorder.additional.product"
_description = "Additional Product"
product_id = fields.Many2one(
'product.product',
'Product',
required=True,
domain="[('company_id', 'in', (company_id, False)), ('type', '!=', 'service')]")
product_tracking = fields.Selection(related='product_id.tracking')
product_qty = fields.Float('Quantity', default=1, required=True)
product_uom_id = fields.Many2one('uom.uom', domain="[('category_id', '=', product_uom_category_id)]")
product_uom_category_id = fields.Many2one(related='product_id.uom_id.category_id')
type = fields.Selection([
('component', 'Component'),
('byproduct', 'By-Product')])
workorder_id = fields.Many2one(
'mrp.workorder', required=True,
default=lambda self: self.env.context.get('active_id', None),
)
company_id = fields.Many2one(related='workorder_id.company_id')
@api.onchange('product_id')
def _onchange_product_id(self):
if self.product_id:
self.product_uom_id = self.product_id.uom_id
if self.product_tracking == 'serial':
self.product_qty = 1
def add_product(self):
"""Create workorder line for the additional product."""
wo = self.workorder_id
if self.type == 'component':
test_type = self.env.ref('mrp_workorder.test_type_register_consumed_materials')
move = self.env['stock.move'].create(
wo.production_id._get_move_raw_values(
self.product_id,
self.product_qty,
self.product_id.uom_id,
operation_id=wo.operation_id.id,
)
)
else:
test_type = self.env.ref('mrp_workorder.test_type_register_byproducts')
move = self.env['stock.move'].create(
wo.production_id._get_move_finished_values(
self.product_id.id,
self.product_qty,
self.product_id.uom_id.id,
operation_id=wo.operation_id.id,
)
)
move = move._action_confirm()
check = {
'workorder_id': wo.id,
'component_id': self.product_id.id,
'product_id': wo.product_id.id,
'company_id': self.company_id.id,
'team_id': self.env['quality.alert.team'].search([], limit=1).id,
'finished_product_sequence': wo.qty_produced,
'test_type_id': test_type.id,
'qty_done': self.product_qty,
'move_id': move.id,
}
additional_check = self.env['quality.check'].create(check)
# Insert the quality check in the chain. The process is slightly different
# if we are between two quality checks or at the summary step.
if wo.current_quality_check_id:
additional_check._insert_in_chain('before', wo.current_quality_check_id)
wo._change_quality_check(position='previous')
else:
last_check = wo.check_ids.filtered(
lambda c: not c.next_check_id and
c.finished_product_sequence == wo.qty_produced and
c != additional_check
)
additional_check._insert_in_chain('after', last_check)
wo._change_quality_check(position='last')

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_mrp_workorder_additional_product_wizard" model="ir.ui.view">
<field name="name">MRP Additional Product</field>
<field name="model">mrp_workorder.additional.product</field>
<field name="arch" type="xml">
<form string="Add product">
<group>
<group>
<field name="company_id" invisible="1"/>
<field name="product_tracking" invisible="1"/>
<field name="type" invisible="1"/>
<field name="product_uom_category_id" invisible="1"/>
<field name="product_id"/>
<label for="product_qty" string="Quantity" />
<div class="o_row">
<field name="product_qty" attrs="{'readonly': [('product_tracking', '=', 'serial')]}"/>
<field name="product_uom_id" groups="uom.group_uom" attrs="{'readonly': [('product_tracking', '=', 'serial')]}"/>
</div>
</group>
</group>
<footer>
<button name="add_product" type="object" string="Add Component" attrs="{'invisible': [('type', '=', 'byproduct')]}" class="btn-primary" data-hotkey="q"/>
<button name="add_product" type="object" string="Add By-Product" attrs="{'invisible': [('type', '=', 'component')]}" class="btn-primary" data-hotkey="q"/>
<button string="Discard" class="btn-default btn-secondary" special="cancel" data-hotkey="z"/>
</footer>
</form>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, _
from odoo.exceptions import ValidationError
class ChangeProductionQty(models.TransientModel):
_inherit = "change.production.qty"
def change_prod_qty(self):
super(ChangeProductionQty, self).change_prod_qty()
# if there are quality checks, we should create new checks/update the quantities, etc.
# if we want to make this feature work, a task should be done to deal with all the possible cases:
# types of quality check, quantity processed, etc. In the meantime, we block this feature.
for wizard in self:
done_checks = self.env['quality.check'].search([
'&', ('control_date', '!=', False),
'|', ('production_id', '=', wizard.mo_id.id), ('workorder_id', 'in', wizard.mo_id.workorder_ids.ids),
])
if done_checks:
raise ValidationError(_("You cannot update the quantity to do of an ongoing "
"manufacturing order for which quality checks have been performed."))

View File

@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from markupsafe import Markup
from odoo import SUPERUSER_ID, api, fields, models, _
class ProposeChange(models.TransientModel):
_name = 'propose.change'
_description = 'Propose a change in the production'
workorder_id = fields.Many2one(
'mrp.workorder', 'Workorder', required=True, ondelete='cascade')
title = fields.Char('title')
step_id = fields.Many2one('quality.check', 'Step to change')
note = fields.Html('New Instruction')
comment = fields.Char('Comment')
picture = fields.Binary('Picture')
change_type = fields.Selection([
('update_step', 'Update Current Step'),
('remove_step', 'Remove Current Step'),
('set_picture', 'Set Picture')], 'Type of Change')
def default_get(self, fields_list):
defaults = super().default_get(fields_list)
if 'step_id' in defaults:
step = self.env['quality.check'].browse(defaults.get('step_id'))
defaults['title'] = step.title
return defaults
def process(self):
for wizard in self:
if wizard.title != wizard.step_id.title:
wizard.step_id.title = wizard.title
if wizard.change_type == 'update_step':
wizard._do_update_step()
elif wizard.change_type == 'remove_step':
wizard._do_remove_step()
elif wizard.change_type == 'set_picture':
wizard._do_set_picture()
def _workorder_name(self):
return self.env.user.name
def _do_update_step(self, notify_bom=True):
self.ensure_one()
self.step_id.note = self.note
if notify_bom and self.workorder_id.production_id.bom_id:
body = Markup(_("<b>New Instruction suggested by %s</b><br/>%s<br/><b>Reason: %s</b>")) % (self._workorder_name(), self.note, self.comment)
self.env['mail.activity'].sudo().create({
'res_model_id': self.env.ref('mrp.model_mrp_bom').id,
'res_id': self.workorder_id.production_id.bom_id.id,
'user_id': self.workorder_id.product_id.responsible_id.id or SUPERUSER_ID,
'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id,
'summary': _('BoM feedback %s (%s)', self.step_id.title, self.workorder_id.production_id.name),
'note': body,
})
def _do_remove_step(self, notify_bom=True):
self.ensure_one()
if not self.step_id.point_id and not(self.step_id.test_type.startswith('register_')):
# remove additionmal step
self.step_id.workorder_id._change_quality_check('next')
self.step_id.unlink()
self.step_id.is_deleted = True
bom = self.step_id.workorder_id.production_id.bom_id
if notify_bom and bom:
body = Markup(_("<b>%s suggests to delete this instruction</b>")) % self._workorder_name()
self.env['mail.activity'].sudo().create({
'res_model_id': self.env.ref('mrp.model_mrp_bom').id,
'res_id': bom.id,
'user_id': self.workorder_id.product_id.responsible_id.id or SUPERUSER_ID,
'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id,
'summary': _('BoM feedback %s (%s)', self.step_id.title, self.workorder_id.production_id.name),
'note': body,
})
@api.model
def image_url(self, record, field):
""" Returns a local url that points to the image field of a given browse record. """
return '/web/image/%s/%s/%s' % (record._name, record.id, field)
def _do_set_picture(self, notify_bom):
self.ensure_one()
self.step_id.worksheet_document = self.picture
bom = self.step_id.workorder_id.production_id.bom_id
if notify_bom and bom:
body = Markup(_("<b>%s suggests to use this document as instruction</b><br/><img style='max-width: 75%%' class='img-fluid' src=%s/>"))\
% (self._workorder_name(), self.image_url(self, 'picture'))
self.env['mail.activity'].sudo().create({
'res_model_id': self.env.ref('mrp.model_mrp_bom').id,
'res_id': bom.id,
'user_id': self.workorder_id.product_id.responsible_id.id or SUPERUSER_ID,
'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id,
'summary': _('BoM feedback %s (%s)', self.step_id.title, self.workorder_id.production_id.name),
'note': body,
})

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_propose_change_wizard" model="ir.ui.view">
<field name="name">workorder_propose_change</field>
<field name="model">propose.change</field>
<field name="arch" type="xml">
<form string="Propose Change">
<group>
<group>
<field name="change_type" invisible="1"/>
<field name="step_id" invisible="1"/>
<field name="title" attrs="{'invisible': [('change_type', '!=', 'update_step')]}"/>
<field name="note" attrs="{'invisible': [('change_type', '!=', 'update_step')]}"/>
<field name="comment" attrs="{'invisible': [('change_type', '=', 'set_picture')]}"/>
<field name="picture" attrs="{'invisible': [('change_type', '!=', 'set_picture')]}" widget="image"/>
</group>
</group>
<footer>
<button name="process" class="btn btn-primary" type="object" string="Propose Change"/>
<button string="Discard" class="btn-default btn-secondary" special="cancel" data-hotkey="z"/>
</footer>
</form>
</field>
</record>
</odoo>