From 21d052e222637669328ed2e73e9f1116b5986dea Mon Sep 17 00:00:00 2001 From: guanhuan Date: Tue, 29 Apr 2025 10:40:19 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E9=87=87=E8=B4=AD=E7=94=B3=E8=AF=B7?= =?UTF-8?q?=E6=98=8E=E7=BB=86=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_request/__manifest__.py | 11 ++--- .../models/purchase_request.py | 43 +++++++++++++++++++ .../static/src/change.scss | 3 ++ .../views/purchase_request_line_view.xml | 22 ++++++++++ ...rchase_request_line_make_purchase_order.py | 11 ++++- 5 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 jikimo_purchase_request/static/src/change.scss create mode 100644 jikimo_purchase_request/views/purchase_request_line_view.xml diff --git a/jikimo_purchase_request/__manifest__.py b/jikimo_purchase_request/__manifest__.py index dad34ddc..3221a54e 100644 --- a/jikimo_purchase_request/__manifest__.py +++ b/jikimo_purchase_request/__manifest__.py @@ -12,12 +12,13 @@ 'views/mrp_production.xml', 'views/purchase_request_view.xml', 'wizard/purchase_request_line_make_purchase_order_view.xml', + 'views/purchase_request_line_view.xml', ], - # 'assets': { - # 'web.assets_backend': [ - # 'jikimo_purchase_request/static/src/**/*' - # ], - # }, + 'assets': { + 'web.assets_backend': [ + 'jikimo_purchase_request/static/src/**/*' + ], + }, 'application': True, 'installable': True, 'auto_install': False, diff --git a/jikimo_purchase_request/models/purchase_request.py b/jikimo_purchase_request/models/purchase_request.py index 9e610612..3ecd2161 100644 --- a/jikimo_purchase_request/models/purchase_request.py +++ b/jikimo_purchase_request/models/purchase_request.py @@ -47,6 +47,19 @@ class PurchaseRequestLine(models.Model): ('outsourcing', "委外加工"), ], string='供货方式', compute='_compute_supply_method', store=True) + purchase_request_count = fields.Integer(string='采购申请数量', compute='_compute_purchase_request_count', readonly=True) + purchase_count = fields.Integer(string="采购订单数量", compute="_compute_purchase_count", readonly=True) + + @api.depends("purchase_lines") + def _compute_purchase_count(self): + for rec in self: + rec.purchase_count = len(rec.mapped("purchase_lines.order_id")) + + @api.depends('request_id') + def _compute_purchase_request_count(self): + for order in self: + order.purchase_request_count = len(order.request_id) + @api.depends('origin') def _compute_supply_method(self): for prl in self: @@ -98,3 +111,33 @@ class PurchaseRequestLine(models.Model): else: record.part_number = record.product_id.part_number record.part_name = record.product_id.part_name + + def _compute_qty_to_buy(self): + for pr in self: + qty_to_buy = sum(pr.mapped("product_qty")) - sum(pr.mapped("qty_done")) - sum(pr.mapped("qty_in_progress")) + pr.qty_to_buy = qty_to_buy > 0.0 + pr.pending_qty_to_receive = qty_to_buy + + def action_view_purchase_request(self): + action = self.env["ir.actions.actions"]._for_xml_id("purchase_request.purchase_request_form_action") + action.update({ + 'res_id': self.request_id.id, + 'views': [[False, 'form']], + }) + return action + + def action_view_purchase_order(self): + action = self.env["ir.actions.actions"]._for_xml_id("purchase.purchase_rfq") + lines = self.mapped("purchase_lines.order_id") + if len(lines) > 1: + action["domain"] = [("id", "in", lines.ids)] + elif lines: + action["views"] = [ + (self.env.ref("purchase.purchase_order_form").id, "form") + ] + action["res_id"] = lines.id + origin_context = ast.literal_eval(action['context']) + if 'search_default_draft' in origin_context: + origin_context.pop('search_default_draft') + action['context'] = origin_context + return action diff --git a/jikimo_purchase_request/static/src/change.scss b/jikimo_purchase_request/static/src/change.scss new file mode 100644 index 00000000..be14ac07 --- /dev/null +++ b/jikimo_purchase_request/static/src/change.scss @@ -0,0 +1,3 @@ +th[data-name=keep_description] { + min-width: 220px; +} \ No newline at end of file diff --git a/jikimo_purchase_request/views/purchase_request_line_view.xml b/jikimo_purchase_request/views/purchase_request_line_view.xml new file mode 100644 index 00000000..51b9e09e --- /dev/null +++ b/jikimo_purchase_request/views/purchase_request_line_view.xml @@ -0,0 +1,22 @@ + + + purchase.request.line.sf.form + purchase.request.line + + + +
+ + +
+
+ +
+
+
diff --git a/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py b/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py index 16248b7b..81722ec5 100644 --- a/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py +++ b/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py @@ -104,7 +104,16 @@ class PurchaseRequestLineMakePurchaseOrder(models.TransientModel): # 去掉合并必须同一采购组的限制 pass - + def get_items(self, request_line_ids): + request_line_obj = self.env["purchase.request.line"] + items = [] + request_lines = request_line_obj.browse(request_line_ids).filtered(lambda line: line.pending_qty_to_receive > 0) + self._check_valid_request_line(request_line_ids) + self.check_group(request_lines) + for line in request_lines: + items.append([0, 0, self._prepare_item(line)]) + return items + class PurchaseRequestLineMakePurchaseOrderItem(models.TransientModel): _inherit = "purchase.request.line.make.purchase.order.item" From 8fd0c4e1f1584431772e46aee72a604277b1686f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Tue, 6 May 2025 15:21:45 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E8=B4=A7=E4=BD=8D=E7=9A=84=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E5=87=8F=E5=B0=91=E5=BE=AA=E7=8E=AF=E6=AC=A1=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_warehouse/models/model.py | 71 ++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index 65cca601..f47421ef 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -812,40 +812,49 @@ class SfStockMoveLine(models.Model): # # 从目标stock.move对象获取目标stock.picking对象 # dest_picking = dest_move.picking_id if dest_move else False # # 现在,dest_picking就是current_picking的下一步 + # 添加所有需要的依赖字段 @api.depends('location_id') def _compute_current_location_id(self): + # 批量获取所有相关记录的picking + pickings = self.mapped('picking_id') + + # 构建源picking的移库行与目标位置的映射 + origin_location_map = {} + for picking in pickings: + # 获取源picking + origin_move = picking.move_ids[:1].move_orig_ids[:1] + if not origin_move: + continue + + origin_picking = origin_move.picking_id + if not origin_picking: + continue + + # 为每个picking构建lot_id到location的映射 + origin_location_map[picking.id] = { + move_line.lot_id.id: move_line.destination_location_id + for move_line in origin_picking.move_line_ids.filtered( + lambda ml: ml.destination_location_id and ml.lot_id + ) + } + + # 批量更新current_location_id for record in self: - # 使用record代替self来引用当前遍历到的记录 - logging.info('record.picking_id.name: %s' % record.picking_id.name) - logging.info('record.env: %s' % record.env['stock.picking'].search([('name', '=', record.picking_id.name)])) - - # 获取当前的stock.picking对象 - current_picking = record.env['stock.picking'].search([('name', '=', record.picking_id.name)], limit=1) - - # 获取当前picking的第一个stock.move对象 - current_move = current_picking.move_ids[0] if current_picking.move_ids else False - - # 如果存在相关的stock.move对象 - if current_move: - # 获取源stock.move对象 - origin_move = current_move.move_orig_ids[0] if current_move.move_orig_ids else False - - # 从源stock.move对象获取源stock.picking对象 - origin_picking = origin_move.picking_id if origin_move else False - - # 如果前一个调拨单有目标货位 - if origin_picking: - for i in current_picking.move_line_ids: - for j in origin_picking.move_line_ids: - if j.destination_location_id and i.lot_id == j.lot_id: - # 更新当前记录的current_location_id字段 - record.current_location_id = j.destination_location_id - # # 获取目标stock.move对象 - # dest_move = current_move.move_dest_ids[0] if current_move.move_dest_ids else False - # - # # 从目标stock.move对象获取目标stock.picking对象 - # dest_picking = dest_move.picking_id if dest_move else False - # # 现在,dest_picking就是current_picking的下一步 + current_picking = record.picking_id + if not current_picking: + record.current_location_id = False + continue + + # 获取当前picking对应的lot_location映射 + lot_dest_map = origin_location_map.get(current_picking.id, {}) + + # 查找匹配的lot_id + for move_line in current_picking.move_line_ids: + if move_line.lot_id and move_line.lot_id.id in lot_dest_map: + record.current_location_id = lot_dest_map[move_line.lot_id.id] + break + else: + record.current_location_id = False # 是一张单据一张单据往下走的,所以这里的目标货位是上一张单据的当前货位,且这样去计算是可以的。 @api.depends('location_dest_id') From 2bf43ae9a1c9cf901338b30863195ba1997adee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Wed, 7 May 2025 08:47:33 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=B0=86=E6=88=90=E5=93=81=E7=9A=84?= =?UTF-8?q?=E8=BF=BD=E6=BA=AF=E5=A4=8D=E5=88=B6=E5=88=B0product=E4=B8=8A?= =?UTF-8?q?=EF=BC=8C=E5=B0=86=E5=9D=AF=E6=96=99=E7=9A=84=E8=BF=BD=E6=BA=AF?= =?UTF-8?q?=E5=90=8C=E6=88=90=E5=93=81=E7=9A=84=E8=BF=BD=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/product_template.py | 1 + sf_manufacturing/models/sale_order.py | 1 + 2 files changed, 2 insertions(+) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 41637123..775df50e 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -1030,6 +1030,7 @@ class ResProductMo(models.Model): 'single_manufacturing': product_id.single_manufacturing, 'is_bfm': True, 'active': True, + 'tracking': finish_product.tracking, # 坯料的跟踪方式跟随成品 } # 外协和采购生成的坯料需要根据材料型号绑定供应商 if route_type == 'subcontract' or route_type == 'purchase': diff --git a/sf_manufacturing/models/sale_order.py b/sf_manufacturing/models/sale_order.py index c8cc129d..4ce8750c 100644 --- a/sf_manufacturing/models/sale_order.py +++ b/sf_manufacturing/models/sale_order.py @@ -59,6 +59,7 @@ class SaleOrder(models.Model): line.product_id.product_tmpl_id.copy_template(product_template_id) # 将模板上的single_manufacturing属性复制到成品上 line.product_id.single_manufacturing = product_template_id.single_manufacturing + line.product_id.tracking = product_template_id.tracking order_id = self product = line.product_id