diff --git a/sf_base/models/__init__.py b/sf_base/models/__init__.py
index f7d50427..82ed80c1 100644
--- a/sf_base/models/__init__.py
+++ b/sf_base/models/__init__.py
@@ -5,3 +5,4 @@ from . import fixture
from . import functional_fixture
from . import tool_other_features
from . import basic_parameters_fixture
+from . import ir_sequence
diff --git a/sf_base/models/ir_sequence.py b/sf_base/models/ir_sequence.py
new file mode 100644
index 00000000..5a39cb5e
--- /dev/null
+++ b/sf_base/models/ir_sequence.py
@@ -0,0 +1,69 @@
+import calendar
+from datetime import timedelta
+
+from odoo import models, fields
+
+
+class IrSequence(models.Model):
+ _inherit = 'ir.sequence'
+
+ date_range_period = fields.Selection(
+ [('day', '每日'), ('month', '每月'), ('year', '每年')],
+ string='日期期间',
+ )
+
+ def _next(self, sequence_date=None):
+ """ Returns the next number in the preferred sequence in all the ones given in self."""
+ if not self.use_date_range:
+ return self._next_do()
+ # date mode
+ dt = sequence_date or self._context.get('ir_sequence_date', fields.Date.today())
+ seq_date = self.env['ir.sequence.date_range'].search(
+ [('sequence_id', '=', self.id), ('date_from', '<=', dt), ('date_to', '>=', dt)], limit=1)
+ if not seq_date:
+ if self.date_range_period:
+ seq_date = self._create_date_range_seq_by_period(dt, self.date_range_period)
+ else:
+ seq_date = self._create_date_range_seq(dt)
+ return seq_date.with_context(ir_sequence_date_range=seq_date.date_from)._next()
+
+ def _create_date_range_seq_by_period(self, date, period):
+ if period == 'year':
+ year = fields.Date.from_string(date).strftime('%Y')
+ date_from = '{}-01-01'.format(year)
+ date_to = '{}-12-31'.format(year)
+ if period == 'month':
+ # 计算当前月份的第一天和最后一天
+ year = fields.Date.from_string(date).strftime('%Y')
+ month = fields.Date.from_string(date).strftime('%m')
+ date_from = fields.Date.from_string(date).strftime('%Y-%m-01')
+ date_to = '{}-{}-{}'.format(year, month, calendar.monthrange(int(year), int(month))[1])
+ if period == 'day':
+ date_from = date
+ date_to = date
+ date_range = self.env['ir.sequence.date_range'].search(
+ [
+ ('sequence_id', '=', self.id),
+ ('date_to', '>=', date_from),
+ ('date_to', '<=', date),
+ ('date_range_period', '=', period)
+ ],
+ order='date_to desc', limit=1)
+ if date_range:
+ date_from = date_range.date_to + timedelta(days=1)
+ seq_date_range = self.env['ir.sequence.date_range'].sudo().create({
+ 'date_from': date_from,
+ 'date_to': date_to,
+ 'sequence_id': self.id,
+ 'date_range_period': period,
+ })
+ return seq_date_range
+
+
+class IrSequenceDateRange(models.Model):
+ _inherit = 'ir.sequence.date_range'
+
+ date_range_period = fields.Selection(
+ [('day', '每日'), ('month', '每月'), ('year', '每年')],
+ string='日期期间',
+ )
diff --git a/sf_manufacturing/data/agv_scheduling_data.xml b/sf_manufacturing/data/agv_scheduling_data.xml
index f9dc6362..44878ade 100644
--- a/sf_manufacturing/data/agv_scheduling_data.xml
+++ b/sf_manufacturing/data/agv_scheduling_data.xml
@@ -9,6 +9,7 @@
1
standard
True
+ day
diff --git a/sf_manufacturing/models/agv_scheduling.py b/sf_manufacturing/models/agv_scheduling.py
index 1ee9c36d..f2ac517b 100644
--- a/sf_manufacturing/models/agv_scheduling.py
+++ b/sf_manufacturing/models/agv_scheduling.py
@@ -23,7 +23,7 @@ class AgvScheduling(models.Model):
return self.env['sf.agv.task.route'].fields_get(['route_type'])['route_type']['selection']
agv_route_type = fields.Selection(selection=_get_agv_route_type_selection, string='任务类型', required=True)
- agv_route_name = fields.Char('任务路线名称')
+ agv_route_id = fields.Many2one('sf.agv.task.route', '任务路线')
start_site_id = fields.Many2one('sf.agv.site', '起点接驳站', required=True)
end_site_id = fields.Many2one('sf.agv.site', '终点接驳站', tracking=True)
site_state = fields.Selection([
@@ -125,7 +125,7 @@ class AgvScheduling(models.Model):
idle_route = None
if len(agv_routes) == 1:
idle_route = agv_routes[0]
- vals.update({'end_site_id': idle_route.end_site_id.id, 'agv_route_name': idle_route.name})
+ vals.update({'end_site_id': idle_route.end_site_id.id, 'agv_route_id': idle_route.id})
else:
# 判断终点接驳站是否为空闲
idle_routes = agv_routes.filtered(lambda r: r.end_site_id.state == '空闲')
@@ -133,7 +133,7 @@ class AgvScheduling(models.Model):
# 将空闲的路线按照终点接驳站名称排序
idle_routes = sorted(idle_routes, key=lambda r: r.end_site_id.name)
idle_route = idle_routes[0]
- vals.update({'end_site_id': idle_route.end_site_id.id, 'agv_route_name': idle_route.name})
+ vals.update({'end_site_id': idle_route.end_site_id.id, 'agv_route_id': idle_route.id})
try:
scheduling = self.env['sf.agv.scheduling'].sudo().create(vals)
# 触发空闲接驳站状态更新,触发新任务下发
@@ -226,12 +226,12 @@ class AgvScheduling(models.Model):
if rec.state != '待下发':
return False
_logger.info('AGV任务调度:下发调度任务,路线为%s' % agv_task_route)
- # rec._delivery_avg()
+ rec._delivery_avg()
rec.state = '配送中'
rec.task_delivery_time = fields.Datetime.now()
rec.site_state = '空闲'
rec.end_site_id = agv_task_route.end_site_id.id
- rec.agv_route_name = agv_task_route.name
+ rec.agv_route_id = agv_task_route.id
# 更新接驳站状态
rec.env['sf.agv.site'].update_site_state({rec.end_site_id.name: '占用'}, False)
@@ -240,7 +240,18 @@ class AgvScheduling(models.Model):
if vals['state'] == '已取消':
self.env['sf.workpiece.delivery'].search([('agv_scheduling_id', '=', self.id)]).write({'status': '待下发'})
elif vals['state'] == '已配送':
- self.env['sf.workpiece.delivery'].search([('agv_scheduling_id', '=', self.id)]).write({'status': '已配送'})
+ self.env['sf.workpiece.delivery'].search([('agv_scheduling_id', '=', self.id)]).write({
+ 'status': '已配送',
+ 'feeder_station_destination_id': self.end_site_id,
+ 'route_id': self.agv_route_id.id,
+ 'task_completion_time': fields.Datetime.now()
+ })
+ elif vals['state'] == '配送中':
+ self.env['sf.workpiece.delivery'].search([('agv_scheduling_id', '=', self.id)]).write({
+ 'feeder_station_destination_id': self.end_site_id,
+ 'route_id': self.agv_route_id.id,
+ 'task_delivery_time': fields.Datetime.now()
+ })
return super().write(vals)
diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py
index c4eb21dc..466e9a62 100644
--- a/sf_manufacturing/models/mrp_production.py
+++ b/sf_manufacturing/models/mrp_production.py
@@ -808,7 +808,8 @@ class MrpProduction(models.Model):
'target': 'new',
'context': {
'default_production_id': self.id,
- 'default_programming_state': cloud_programming['programming_state'],
+ 'default_programming_state': '编程中' if cloud_programming[
+ 'programming_state'] != '已下发' else '已下发',
'default_is_reprogramming': True if cloud_programming['programming_state'] in ['已下发'] else False
}
}
@@ -986,15 +987,20 @@ class MrpProduction(models.Model):
move = self.env['stock.move'].search([('origin', '=', productions.name)], order='id desc')
for mo in move:
print(mo.id)
- if mo.name in ['/', '拉']:
+ if mo.procure_method == 'make_to_order' and mo.name != productions.name:
if mo.name == '/':
domain = [('barcode', '=', 'WH-PC'), ('sequence_code', '=', 'PC')]
elif mo.name == '拉':
domain = [('barcode', '=', 'WH-INTERNAL'), ('sequence_code', '=', 'INT')]
picking_type = self.env['stock.picking.type'].search(domain)
- mo.picking_type_id = picking_type.id
+ mo.write({'picking_type_id': picking_type.id})
mo._assign_picking()
- mo.reference = mo.picking_id.name
+ else:
+ if mo.reference != productions.name:
+ mo.reference = productions.name
+ if mo.production_id:
+ if mo.production_id != productions:
+ mo.production_id = False
productions.write({'programming_no': self.programming_no, 'is_remanufacture': True})
productions.procurement_group_id.mrp_production_ids.move_dest_ids.write(
{'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])})
@@ -1066,46 +1072,6 @@ class MrpProduction(models.Model):
production_item)
else:
productions.programming_state = '编程中'
- for production in productions:
- origin_production = production.move_dest_ids and production.move_dest_ids[
- 0].raw_material_production_id or False
- orderpoint = production.orderpoint_id
- if orderpoint and orderpoint.create_uid.id == SUPERUSER_ID and orderpoint.trigger == 'manual':
- production.message_post(
- body=_('This production order has been created from Replenishment Report.'),
- message_type='comment',
- subtype_xmlid='mail.mt_note')
- elif orderpoint:
- production.message_post_with_view(
- 'mail.message_origin_link',
- values={'self': production, 'origin': orderpoint},
- subtype_id=self.env.ref('mail.mt_note').id)
- elif origin_production:
- production.message_post_with_view(
- 'mail.message_origin_link',
- values={'self': production, 'origin': origin_production},
- subtype_id=self.env.ref('mail.mt_note').id)
-
- '''
- 创建生产计划
- '''
- # 工单耗时
- workorder_duration = 0
- for workorder in productions.workorder_ids:
- workorder_duration += workorder.duration_expected
-
- if sale_order:
- # sale_order.mrp_production_ids |= productions
- self.env['sf.production.plan'].sudo().with_company(self.company_id).create({
- 'name': productions.name,
- 'order_deadline': sale_order.deadline_of_delivery,
- 'production_id': productions.id,
- 'date_planned_start': productions.date_planned_start,
- 'origin': productions.origin,
- 'product_qty': productions.product_qty,
- 'product_id': productions.product_id.id,
- 'state': 'draft',
- })
return productions
# 在之前的销售单上重新生成制造订单
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index 479a56bc..98631c41 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -1264,7 +1264,6 @@ class ResMrpWorkOrder(models.Model):
'is_trayed': False
})
-
# 将FTP的检测报告文件下载到临时目录
def download_reportfile_tmp(self, workorder, reportpath):
logging.info('reportpath/ftp地址:%s' % reportpath)
@@ -1651,7 +1650,7 @@ class WorkPieceDelivery(models.Model):
type = fields.Selection(selection=_get_agv_route_type_selection, string='类型')
delivery_duration = fields.Float('配送时长', compute='_compute_delivery_duration')
status = fields.Selection(
- [('待下发', '待下发'), ('已下发', '已下发'), ('已配送', '已配送'), ('已取消', '已取消')], string='状态',
+ [('待下发', '待下发'), ('已下发', '待配送'), ('已配送', '已配送'), ('已取消', '已取消')], string='状态',
default='待下发', tracking=True)
is_cnc_program_down = fields.Boolean('程序是否下发', default=False, tracking=True)
is_manual_work = fields.Boolean('人工操作', default=False)
@@ -1659,7 +1658,6 @@ class WorkPieceDelivery(models.Model):
agv_scheduling_id = fields.Many2one('sf.agv.scheduling', 'AGV任务调度')
-
@api.model
def create(self, vals):
if vals.get('route_id') and vals.get('type') is None:
@@ -1749,7 +1747,6 @@ class WorkPieceDelivery(models.Model):
'default_confirm_button': '确认配送'
}}
-
# 验证agv站点是否可用
def _check_avgsite_state(self):
is_free = False
@@ -1854,7 +1851,6 @@ class WorkPieceDelivery(models.Model):
obj.delivery_duration = 0.0
-
class CMMprogram(models.Model):
_name = 'sf.cmm.program'
_description = "CMM程序"
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index db07ab91..f53d7056 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -178,7 +178,8 @@ class StockRule(models.Model):
# create the move as SUPERUSER because the current user may not have the rights to do it (mto product
# launched by a sale for example)
logging.info(moves_values)
- moves = self.env['stock.move'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(moves_values)
+ moves = self.env['stock.move'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(
+ moves_values)
logging.info(moves)
# Since action_confirm launch following procurement_group we should activate it.
moves._action_confirm()
diff --git a/sf_manufacturing/views/agv_scheduling_views.xml b/sf_manufacturing/views/agv_scheduling_views.xml
index ef932e54..c24cdf94 100644
--- a/sf_manufacturing/views/agv_scheduling_views.xml
+++ b/sf_manufacturing/views/agv_scheduling_views.xml
@@ -15,7 +15,7 @@
/>
-
+
@@ -43,7 +43,7 @@
-
+
diff --git a/sf_manufacturing/wizard/rework_wizard.py b/sf_manufacturing/wizard/rework_wizard.py
index 4525cb7f..53fd2965 100644
--- a/sf_manufacturing/wizard/rework_wizard.py
+++ b/sf_manufacturing/wizard/rework_wizard.py
@@ -71,9 +71,9 @@ class ReworkWizard(models.TransientModel):
lambda ap: ap.processing_panel == panel.name and ap.state != 'rework')
if panel_workorder:
panel_workorder.write({'state': 'rework'})
- panel_workorder.filtered(
- lambda wo: wo.routing_type == '装夹预调').workpiece_delivery_ids.filtered(
- lambda wd: wd.status == '待下发').write({'status': '已取消'})
+ # panel_workorder.filtered(
+ # lambda wo: wo.routing_type == '装夹预调').workpiece_delivery_ids.filtered(
+ # lambda wd: wd.status == '待下发').write({'status': '已取消'})
# workpiece = self.env['sf.workpiece.delivery'].search([('status', '=', '待下发'), (
# 'workorder_id', '=',
# panel_workorder.filtered(lambda wd: wd.routing_type == '装夹预调').id)])