From 0bd04079ade3e7a989c2adc85c3dd7977155f99d Mon Sep 17 00:00:00 2001 From: DavidJForgeFlow Date: Wed, 27 Sep 2023 11:18:11 +0200 Subject: [PATCH 1/4] [REF] rma: change rules by routes in warehouse --- rma/models/stock_warehouse.py | 222 +++++++++++++++++++--------------- rma/tests/test_rma.py | 26 +++- 2 files changed, 152 insertions(+), 96 deletions(-) diff --git a/rma/models/stock_warehouse.py b/rma/models/stock_warehouse.py index 6273c7714..a9420795d 100644 --- a/rma/models/stock_warehouse.py +++ b/rma/models/stock_warehouse.py @@ -1,7 +1,7 @@ # Copyright (C) 2017-20 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import _, fields, models +from odoo import _, api, fields, models class StockWarehouse(models.Model): @@ -28,19 +28,22 @@ class StockWarehouse(models.Model): help="If set, it will create RMA location, picking types and routes " "for this warehouse.", ) - rma_customer_in_pull_id = fields.Many2one( - comodel_name="stock.rule", string="RMA Customer In Rule" + rma_customer_pull_id = fields.Many2one( + comodel_name="stock.location.route", + string="RMA Customer Route", ) - rma_customer_out_pull_id = fields.Many2one( - comodel_name="stock.rule", string="RMA Customer Out Rule" - ) - rma_supplier_in_pull_id = fields.Many2one( - comodel_name="stock.rule", string="RMA Supplier In Rule" - ) - rma_supplier_out_pull_id = fields.Many2one( - comodel_name="stock.rule", string="RMA Supplier Out Rule" + rma_supplier_pull_id = fields.Many2one( + comodel_name="stock.location.route", + string="RMA Supplier Route", ) + @api.returns("self") + def _get_all_routes(self): + routes = super()._get_all_routes() + routes |= self.rma_customer_pull_id + routes |= self.rma_supplier_pull_id + return routes + def _get_rma_types(self): return [ self.rma_cust_out_type_id, @@ -78,18 +81,16 @@ def write(self, vals): for r_type in wh._get_rma_types(): if r_type: r_type.active = True - # RMA rules: - wh._create_or_update_rma_pull() + # RMA routes: + wh._create_rma_pull() else: for wh in self: for r_type in wh._get_rma_types(): if r_type: r_type.active = False # Unlink rules: - self.mapped("rma_customer_in_pull_id").unlink() - self.mapped("rma_customer_out_pull_id").unlink() - self.mapped("rma_supplier_in_pull_id").unlink() - self.mapped("rma_supplier_out_pull_id").unlink() + self.mapped("rma_customer_pull_id").unlink() + self.mapped("rma_supplier_pull_id").unlink() return super(StockWarehouse, self).write(vals) def _create_rma_picking_types(self): @@ -175,90 +176,121 @@ def _create_rma_picking_types(self): ) return True - def get_rma_rules_dict(self): + def get_rma_route_customer(self): self.ensure_one() - rma_rules = dict() - customer_loc, supplier_loc = self._get_partner_locations() - rma_rules["rma_customer_in"] = { - "name": self._format_rulename(self, customer_loc, self.lot_rma_id.name), - "action": "pull", - "warehouse_id": self.id, - "company_id": self.company_id.id, - "location_src_id": customer_loc.id, - "location_id": self.lot_rma_id.id, - "procure_method": "make_to_stock", - "route_id": self.env.ref("rma.route_rma_customer").id, - "picking_type_id": self.rma_cust_in_type_id.id, - "active": True, - } - rma_rules["rma_customer_out"] = { - "name": self._format_rulename(self, self.lot_rma_id, customer_loc.name), - "action": "pull", - "warehouse_id": self.id, - "company_id": self.company_id.id, - "location_src_id": self.lot_rma_id.id, - "location_id": customer_loc.id, - "procure_method": "make_to_stock", - "route_id": self.env.ref("rma.route_rma_customer").id, - "picking_type_id": self.rma_cust_out_type_id.id, - "active": True, - } - rma_rules["rma_supplier_in"] = { - "name": self._format_rulename(self, supplier_loc, self.lot_rma_id.name), - "action": "pull", - "warehouse_id": self.id, - "company_id": self.company_id.id, - "location_src_id": supplier_loc.id, - "location_id": self.lot_rma_id.id, - "procure_method": "make_to_stock", - "route_id": self.env.ref("rma.route_rma_supplier").id, - "picking_type_id": self.rma_sup_in_type_id.id, - "active": True, - } - rma_rules["rma_supplier_out"] = { - "name": self._format_rulename(self, self.lot_rma_id, supplier_loc.name), - "action": "pull", - "warehouse_id": self.id, - "company_id": self.company_id.id, - "location_src_id": self.lot_rma_id.id, - "location_id": supplier_loc.id, - "procure_method": "make_to_stock", - "route_id": self.env.ref("rma.route_rma_supplier").id, - "picking_type_id": self.rma_sup_out_type_id.id, - "active": True, - } + customer_loc, _ = self._get_partner_locations() + rma_rules = [ + { + "name": self.name + ": Customer RMA", + "rma_selectable": True, + "rule_ids": [ + ( + 0, + 0, + { + "name": self._format_rulename( + self, customer_loc, self.lot_rma_id.name + ), + "action": "pull", + "warehouse_id": self.id, + "company_id": self.company_id.id, + "location_src_id": customer_loc.id, + "location_id": self.lot_rma_id.id, + "procure_method": "make_to_stock", + "picking_type_id": self.rma_cust_in_type_id.id, + "active": True, + }, + ), + ( + 0, + 0, + { + "name": self._format_rulename( + self, self.lot_rma_id, customer_loc.name + ), + "action": "pull", + "warehouse_id": self.id, + "company_id": self.company_id.id, + "location_src_id": self.lot_rma_id.id, + "location_id": customer_loc.id, + "procure_method": "make_to_stock", + "picking_type_id": self.rma_cust_out_type_id.id, + "active": True, + }, + ), + ], + } + ] return rma_rules - def _create_or_update_rma_pull(self): - rule_obj = self.env["stock.rule"] - for wh in self: - rules_dict = wh.get_rma_rules_dict() - if wh.rma_customer_in_pull_id: - wh.rma_customer_in_pull_id.write(rules_dict["rma_customer_in"]) - else: - wh.rma_customer_in_pull_id = rule_obj.create( - rules_dict["rma_customer_in"] - ) - - if wh.rma_customer_out_pull_id: - wh.rma_customer_out_pull_id.write(rules_dict["rma_customer_out"]) - else: - wh.rma_customer_out_pull_id = rule_obj.create( - rules_dict["rma_customer_out"] - ) + def get_rma_route_supplier(self): + self.ensure_one() + _, supplier_loc = self._get_partner_locations() + rma_route = [ + { + "name": self.name + ": Supplier RMA", + "rma_selectable": True, + "rule_ids": [ + ( + 0, + 0, + { + "name": self._format_rulename( + self, supplier_loc, self.lot_rma_id.name + ), + "action": "pull", + "warehouse_id": self.id, + "company_id": self.company_id.id, + "location_src_id": supplier_loc.id, + "location_id": self.lot_rma_id.id, + "procure_method": "make_to_stock", + "picking_type_id": self.rma_sup_in_type_id.id, + "active": True, + }, + ), + ( + 0, + 0, + { + "name": self._format_rulename( + self, self.lot_rma_id, supplier_loc.name + ), + "action": "pull", + "warehouse_id": self.id, + "company_id": self.company_id.id, + "location_src_id": self.lot_rma_id.id, + "location_id": supplier_loc.id, + "procure_method": "make_to_stock", + "picking_type_id": self.rma_sup_out_type_id.id, + "active": True, + }, + ), + ], + } + ] + return rma_route - if wh.rma_supplier_in_pull_id: - wh.rma_supplier_in_pull_id.write(rules_dict["rma_supplier_in"]) - else: - wh.rma_supplier_in_pull_id = rule_obj.create( - rules_dict["rma_supplier_in"] + def _create_rma_pull(self): + route_obj = self.env["stock.location.route"] + for wh in self: + if not wh.rma_customer_pull_id: + wh.rma_customer_pull_id = ( + route_obj.create(self.get_rma_route_customer()) + if wh + not in self.env.ref("rma.route_rma_customer").rule_ids.mapped( + "warehouse_id" + ) + else self.env.ref("rma.route_rma_customer") ) - if wh.rma_supplier_out_pull_id: - wh.rma_supplier_out_pull_id.write(rules_dict["rma_supplier_out"]) - else: - wh.rma_supplier_out_pull_id = rule_obj.create( - rules_dict["rma_supplier_out"] + if not wh.rma_supplier_pull_id: + wh.rma_supplier_pull_id = ( + route_obj.create(self.get_rma_route_supplier()) + if wh + not in self.env.ref("rma.route_rma_supplier").rule_ids.mapped( + "warehouse_id" + ) + else self.env.ref("rma.route_rma_supplier") ) return True diff --git a/rma/tests/test_rma.py b/rma/tests/test_rma.py index 558deabfa..1f6f34dce 100644 --- a/rma/tests/test_rma.py +++ b/rma/tests/test_rma.py @@ -1112,7 +1112,31 @@ def test_08_customer_rma_multi_step(self): ) self.env["stock.rule"].create( { - "name": "Output->RMA", + "name": "Output->Customer", + "action": "pull", + "warehouse_id": self.wh.id, + "location_src_id": self.output_location.id, + "location_id": self.customer_location.id, + "procure_method": "make_to_order", + "route_id": self.customer_route.id, + "picking_type_id": self.env.ref("stock.picking_type_internal").id, + } + ) + self.env["stock.rule"].create( + { + "name": "Customer->Input", + "action": "pull", + "warehouse_id": self.wh.id, + "location_src_id": self.customer_location.id, + "location_id": self.input_location.id, + "procure_method": "make_to_stock", + "route_id": self.customer_route.id, + "picking_type_id": self.env.ref("stock.picking_type_internal").id, + } + ) + self.env["stock.rule"].create( + { + "name": "Input->RMA", "action": "pull", "warehouse_id": self.wh.id, "location_src_id": self.input_location.id, From d7278b493267a495bca443d933af797d441fdefb Mon Sep 17 00:00:00 2001 From: DavidJForgeFlow Date: Wed, 27 Sep 2023 16:00:51 +0200 Subject: [PATCH 2/4] [FIX] rma_account: create correctly two-step rules in test --- rma_account/tests/test_rma_stock_account.py | 26 ++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/rma_account/tests/test_rma_stock_account.py b/rma_account/tests/test_rma_stock_account.py index 65b2f3028..a42ddfb37 100644 --- a/rma_account/tests/test_rma_stock_account.py +++ b/rma_account/tests/test_rma_stock_account.py @@ -273,7 +273,31 @@ def test_04_cost_from_move_multi_step(self): ) self.env["stock.rule"].create( { - "name": "Output->RMA", + "name": "Output->Customer", + "action": "pull", + "warehouse_id": self.wh.id, + "location_src_id": self.output_location.id, + "location_id": self.customer_location.id, + "procure_method": "make_to_order", + "route_id": self.customer_route.id, + "picking_type_id": self.env.ref("stock.picking_type_internal").id, + } + ) + self.env["stock.rule"].create( + { + "name": "Customer->Input", + "action": "pull", + "warehouse_id": self.wh.id, + "location_src_id": self.customer_location.id, + "location_id": self.input_location.id, + "procure_method": "make_to_stock", + "route_id": self.customer_route.id, + "picking_type_id": self.env.ref("stock.picking_type_internal").id, + } + ) + self.env["stock.rule"].create( + { + "name": "Input->RMA", "action": "pull", "warehouse_id": self.wh.id, "location_src_id": self.input_location.id, From 3e7018948a673870464c8f6c99fa31d19b0b572e Mon Sep 17 00:00:00 2001 From: AaronHForgeFlow Date: Fri, 27 Oct 2023 15:54:09 +0200 Subject: [PATCH 3/4] [IMP] rma: default warehouse and routes in rma operation --- rma/models/rma_operation.py | 26 ++++++++++++++++--- rma/models/rma_order_line.py | 7 +++-- rma/models/stock_warehouse.py | 4 +-- rma/tests/test_rma.py | 18 +++++++------ rma/views/stock_warehouse.xml | 3 +++ .../rma_order_line_make_supplier_rma.py | 2 +- 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/rma/models/rma_operation.py b/rma/models/rma_operation.py index 104dc9bfa..bf3a75f07 100644 --- a/rma/models/rma_operation.py +++ b/rma/models/rma_operation.py @@ -12,7 +12,7 @@ class RmaOperation(models.Model): def _default_warehouse_id(self): company_id = self.env.user.company_id.id warehouse = self.env["stock.warehouse"].search( - [("company_id", "=", company_id)], limit=1 + [("company_id", "=", company_id)], order="sequence asc", limit=1 ) return warehouse @@ -24,13 +24,33 @@ def _default_customer_location_id(self): def _default_supplier_location_id(self): return self.env.ref("stock.stock_location_suppliers") or False + @api.onchange("in_warehouse_id") + def onchange_warehouse_id(self): + op_type = self.env.context.get("default_type") + if op_type == "customer": + warehouse = self.in_warehouse_id + if not warehouse or not warehouse.rma_customer_pull_id: + return + self.in_route_id = warehouse.rma_customer_pull_id + self.out_route_id = warehouse.rma_customer_pull_id + elif op_type == "supplier": + warehouse = self.out_warehouse_id + if not warehouse or not warehouse.rma_supplier_pull_id: + return + self.in_route_id = warehouse.rma_supplier_pull_id + self.out_route_id = warehouse.rma_supplier_pull_id + @api.model def _default_routes(self): + company_id = self.env.user.company_id.id + warehouse = self.env["stock.warehouse"].search( + [("company_id", "=", company_id)], limit=1 + ) op_type = self.env.context.get("default_type") if op_type == "customer": - return self.env.ref("rma.route_rma_customer") + return warehouse.rma_customer_pull_id.id elif op_type == "supplier": - return self.env.ref("rma.route_rma_supplier") + return warehouse.rma_supplier_pull_id.id name = fields.Char("Description", required=True) code = fields.Char("Code", required=True) diff --git a/rma/models/rma_order_line.py b/rma/models/rma_order_line.py index be10aeb41..146db69e2 100644 --- a/rma/models/rma_order_line.py +++ b/rma/models/rma_order_line.py @@ -24,11 +24,14 @@ def _get_default_type(self): @api.model def _default_warehouse_id(self): rma_id = self.env.context.get("default_rma_id", False) - warehouse = self.env["stock.warehouse"] + company_id = self.env.user.company_id.id + warehouse = self.env["stock.warehouse"].search( + [("company_id", "=", company_id)], order="sequence asc", limit=1 + ) if rma_id: rma = self.env["rma.order"].browse(rma_id) warehouse = self.env["stock.warehouse"].search( - [("company_id", "=", rma.company_id.id)], limit=1 + [("company_id", "=", rma.company_id.id)], order="sequence asc", limit=1 ) return warehouse diff --git a/rma/models/stock_warehouse.py b/rma/models/stock_warehouse.py index a9420795d..a148b9bfc 100644 --- a/rma/models/stock_warehouse.py +++ b/rma/models/stock_warehouse.py @@ -89,8 +89,8 @@ def write(self, vals): if r_type: r_type.active = False # Unlink rules: - self.mapped("rma_customer_pull_id").unlink() - self.mapped("rma_supplier_pull_id").unlink() + self.mapped("rma_customer_pull_id").active = False + self.mapped("rma_supplier_pull_id").active = False return super(StockWarehouse, self).write(vals) def _create_rma_picking_types(self): diff --git a/rma/tests/test_rma.py b/rma/tests/test_rma.py index 1f6f34dce..b8dea15a6 100644 --- a/rma/tests/test_rma.py +++ b/rma/tests/test_rma.py @@ -26,7 +26,6 @@ def setUpClass(cls): cls.rma_cust_replace_op_id = cls.env.ref("rma.rma_operation_customer_replace") cls.rma_sup_replace_op_id = cls.env.ref("rma.rma_operation_supplier_replace") cls.rma_ds_replace_op_id = cls.env.ref("rma.rma_operation_ds_replace") - cls.customer_route = cls.env.ref("rma.route_rma_customer") cls.input_location = cls.env.ref("stock.stock_location_company") cls.output_location = cls.env.ref("stock.stock_location_output") cls.category = cls._create_product_category( @@ -44,7 +43,10 @@ def setUpClass(cls): cls.partner_id = cls.env.ref("base.res_partner_2") cls.stock_location = cls.env.ref("stock.stock_location_stock") cls.wh = cls.env.ref("stock.warehouse0") + cls.wh.rma_in_this_wh = False + cls.wh.rma_in_this_wh = True cls.stock_rma_location = cls.wh.lot_rma_id + cls.customer_route = cls.wh.rma_customer_pull_id cls.customer_location = cls.env.ref("stock.stock_location_customers") cls.supplier_location = cls.env.ref("stock.stock_location_suppliers") cls.product_uom_id = cls.env.ref("uom.product_uom_unit") @@ -380,9 +382,7 @@ def test_01_rma_order_line(self): # check assert if call reference_move_id onchange self.assertEqual(line.product_id, line.reference_move_id.product_id) self.assertEqual(line.product_qty, line.reference_move_id.product_uom_qty) - self.assertEqual( - line.location_id.location_id, line.reference_move_id.location_id - ) + self.assertEqual(line.location_id, line.in_warehouse_id.lot_rma_id) self.assertEqual(line.origin, line.reference_move_id.picking_id.name) self.assertEqual( line.delivery_address_id, line.reference_move_id.picking_partner_id @@ -1087,8 +1087,10 @@ def test_08_customer_rma_multi_step(self): """ # Alter the customer RMA route to make it multi-step # Get rid of the duplicated rule - self.env.ref("rma.rule_rma_customer_out_pull").active = False - self.env.ref("rma.rule_rma_customer_in_pull").active = False + self.customer_route.rule_ids.active = False + # to be able to receive in in WH + self.wh.reception_steps = "two_steps" + self.wh.delivery_steps = "pick_ship" cust_in_pull_rule = self.customer_route.rule_ids.filtered( lambda r: r.location_id == self.stock_rma_location ) @@ -1103,7 +1105,7 @@ def test_08_customer_rma_multi_step(self): "name": "RMA->Output", "action": "pull", "warehouse_id": self.wh.id, - "location_src_id": self.env.ref("rma.location_rma").id, + "location_src_id": self.wh.lot_rma_id.id, "location_id": self.output_location.id, "procure_method": "make_to_stock", "route_id": self.customer_route.id, @@ -1140,7 +1142,7 @@ def test_08_customer_rma_multi_step(self): "action": "pull", "warehouse_id": self.wh.id, "location_src_id": self.input_location.id, - "location_id": self.env.ref("rma.location_rma").id, + "location_id": self.wh.lot_rma_id.id, "procure_method": "make_to_order", "route_id": self.customer_route.id, "picking_type_id": self.env.ref("stock.picking_type_internal").id, diff --git a/rma/views/stock_warehouse.xml b/rma/views/stock_warehouse.xml index 701edd8e8..8a63900cd 100644 --- a/rma/views/stock_warehouse.xml +++ b/rma/views/stock_warehouse.xml @@ -10,6 +10,9 @@ + + + diff --git a/rma/wizards/rma_order_line_make_supplier_rma.py b/rma/wizards/rma_order_line_make_supplier_rma.py index aa8d2119f..0b26c6641 100644 --- a/rma/wizards/rma_order_line_make_supplier_rma.py +++ b/rma/wizards/rma_order_line_make_supplier_rma.py @@ -135,7 +135,7 @@ def _prepare_supplier_rma_line(self, rma, item): "location_id": ( operation.location_id.id or operation.in_warehouse_id.lot_rma_id.id - or warehouse.lot_rma_id.id + or item.line_id.in_warehouse_id.lot_rma_id.id ), } return data From 8acb57ab541c034a52db4d145d02b33ccda4f98b Mon Sep 17 00:00:00 2001 From: AaronHForgeFlow Date: Mon, 30 Oct 2023 13:42:09 +0100 Subject: [PATCH 4/4] [FIX] rma: bad field reference in rma line --- rma/models/rma_order_line.py | 1 - rma_account/models/rma_order_line.py | 4 +--- rma_account/wizards/rma_add_account_move.py | 4 +--- rma_purchase/models/rma_order_line.py | 4 +--- rma_purchase/wizards/rma_add_purchase.py | 4 +--- rma_sale/models/rma_order_line.py | 4 +--- 6 files changed, 5 insertions(+), 16 deletions(-) diff --git a/rma/models/rma_order_line.py b/rma/models/rma_order_line.py index 146db69e2..e958bc00b 100644 --- a/rma/models/rma_order_line.py +++ b/rma/models/rma_order_line.py @@ -582,7 +582,6 @@ def _prepare_rma_line_from_stock_move(self, sm, lot=False): operation.location_id.id or operation.in_warehouse_id.lot_rma_id.id or operation.out_warehouse_id.lot_rma_id.id - or warehouse.lot_rma_id.id ), } return data diff --git a/rma_account/models/rma_order_line.py b/rma_account/models/rma_order_line.py index b6c152d66..57496bdc7 100644 --- a/rma_account/models/rma_order_line.py +++ b/rma_account/models/rma_order_line.py @@ -227,9 +227,7 @@ def _prepare_rma_line_from_inv_line(self, line): "in_route_id": operation.in_route_id.id or route.id, "out_route_id": operation.out_route_id.id or route.id, "location_id": ( - operation.location_id.id - or operation.in_warehouse_id.lot_rma_id.id - or warehouse.lot_rma_id.id + operation.location_id.id or operation.in_warehouse_id.lot_rma_id.id ), } return data diff --git a/rma_account/wizards/rma_add_account_move.py b/rma_account/wizards/rma_add_account_move.py index 642bda4a4..a8af9232f 100644 --- a/rma_account/wizards/rma_add_account_move.py +++ b/rma_account/wizards/rma_add_account_move.py @@ -100,9 +100,7 @@ def _prepare_rma_line_from_inv_line(self, line): "in_route_id": operation.in_route_id.id or route.id, "out_route_id": operation.out_route_id.id or route.id, "location_id": ( - operation.location_id.id - or operation.in_warehouse_id.lot_rma_id.id - or warehouse.lot_rma_id.id + operation.location_id.id or operation.in_warehouse_id.lot_rma_id.id ), } return data diff --git a/rma_purchase/models/rma_order_line.py b/rma_purchase/models/rma_order_line.py index 3a7842385..c6810a829 100644 --- a/rma_purchase/models/rma_order_line.py +++ b/rma_purchase/models/rma_order_line.py @@ -172,9 +172,7 @@ def _prepare_rma_line_from_po_line(self, line): "receipt_policy": operation.receipt_policy, "currency_id": line.currency_id.id, "location_id": ( - operation.location_id.id - or operation.in_warehouse_id.lot_rma_id.id - or warehouse.lot_rma_id.id + operation.location_id.id or operation.in_warehouse_id.lot_rma_id.id ), "refund_policy": operation.refund_policy, "delivery_policy": operation.delivery_policy, diff --git a/rma_purchase/wizards/rma_add_purchase.py b/rma_purchase/wizards/rma_add_purchase.py index 26aed30a7..18550a78e 100644 --- a/rma_purchase/wizards/rma_add_purchase.py +++ b/rma_purchase/wizards/rma_add_purchase.py @@ -97,9 +97,7 @@ def _prepare_rma_line_from_po_line(self, line): "out_route_id": operation.out_route_id.id or route, "receipt_policy": operation.receipt_policy, "location_id": ( - operation.location_id.id - or operation.in_warehouse_id.lot_rma_id.id - or warehouse.lot_rma_id.id + operation.location_id.id or operation.in_warehouse_id.lot_rma_id.id ), "refund_policy": operation.refund_policy, "delivery_policy": operation.delivery_policy, diff --git a/rma_sale/models/rma_order_line.py b/rma_sale/models/rma_order_line.py index 0d06b8c9f..64ac58bd7 100644 --- a/rma_sale/models/rma_order_line.py +++ b/rma_sale/models/rma_order_line.py @@ -160,9 +160,7 @@ def _prepare_rma_line_from_sale_order_line(self, line): "receipt_policy": operation.receipt_policy, "currency_id": line.currency_id.id, "location_id": ( - operation.location_id.id - or operation.in_warehouse_id.lot_rma_id.id - or warehouse.lot_rma_id.id + operation.location_id.id or operation.in_warehouse_id.lot_rma_id.id ), "refund_policy": operation.refund_policy, "delivery_policy": operation.delivery_policy,