mirror of
https://github.com/ForgeFlow/stock-rma.git
synced 2025-01-21 12:57:49 +02:00
[MIG] rma_analytic: Migration to 15.0
This commit is contained in:
committed by
AaronHForgeFlow
parent
cdf617e159
commit
ce82c55804
@@ -1,5 +1,5 @@
|
||||
.. image:: https://img.shields.io/badge/license-LGPLv3-blue.svg
|
||||
:target: https://www.gnu.org/licenses/lgpl.html
|
||||
.. image:: https://img.shields.io/badge/license-LGPL--3-blue.png
|
||||
:target: https://www.gnu.org/licenses/lgpl
|
||||
:alt: License: LGPL-3
|
||||
|
||||
==========================
|
||||
@@ -25,11 +25,12 @@ Usage
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Aaron Henriquez <ahenriquez@eficent.com>
|
||||
* Aaron Henriquez <ahenriquez@forgeflow.com>
|
||||
* Juany Davila <juany.davila@forgeflow.com>
|
||||
* Serpent Consulting Services Pvt. Ltd. <support@serpentcs.com>
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
This module is maintained by Eficent.
|
||||
This module is maintained by ForgeFlow.
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
from . import models
|
||||
from . import wizards
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# Copyright 2023 ForgeFlow S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
{
|
||||
"name": "Analytic Account in RMA",
|
||||
"version": "10.0.1.0.0",
|
||||
"author": "Eficent," "Odoo Community Association (OCA)",
|
||||
"license": "LGPL-3",
|
||||
"version": "15.0.1.0.0",
|
||||
"author": "ForgeFlow," "Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"website": "https://github.com/ForgeFlow/stock-rma",
|
||||
"category": "Analytic",
|
||||
"depends": ["rma", "procurement_analytic", "stock_analytic"],
|
||||
"depends": [
|
||||
"rma_account",
|
||||
"stock_analytic",
|
||||
"procurement_mto_analytic",
|
||||
],
|
||||
"data": ["views/rma_order_line_view.xml"],
|
||||
"installable": True,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
from . import rma_order_line
|
||||
from . import procurement
|
||||
from . import stock_rule
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# © 2018 Eficent Business and IT Consulting Services S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
from odoo import _, api, exceptions, models
|
||||
|
||||
|
||||
class ProcurementOrder(models.Model):
|
||||
|
||||
_inherit = "procurement.order"
|
||||
|
||||
@api.constrains("account_analytic_id")
|
||||
def check_analytic(self):
|
||||
for order in self:
|
||||
if order.rma_line_id and (
|
||||
order.account_analytic_id != order.rma_line_id.analytic_account_id
|
||||
):
|
||||
raise exceptions.ValidationError(
|
||||
_(
|
||||
"The analytic account in the procurement it's not the "
|
||||
"same as in the rma line"
|
||||
)
|
||||
)
|
||||
@@ -1,7 +1,7 @@
|
||||
# © 2018 Eficent Business and IT Consulting Services S.L.
|
||||
# Copyright 2023 ForgeFlow S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class RmaOrderLine(models.Model):
|
||||
@@ -13,9 +13,8 @@ class RmaOrderLine(models.Model):
|
||||
string="Analytic Account",
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def _prepare_rma_line_from_inv_line(self, line):
|
||||
res = super(RmaOrderLine, self)._prepare_rma_line_from_inv_line(line)
|
||||
if line.account_analytic_id:
|
||||
res.update(analytic_account_id=line.account_analytic_id.id)
|
||||
if line.analytic_account_id:
|
||||
res.update(analytic_account_id=line.analytic_account_id.id)
|
||||
return res
|
||||
|
||||
33
rma_analytic/models/stock_rule.py
Normal file
33
rma_analytic/models/stock_rule.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# Copyright (C) 2017-22 ForgeFlow S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class StockRule(models.Model):
|
||||
_inherit = "stock.rule"
|
||||
|
||||
def _get_stock_move_values(
|
||||
self,
|
||||
product_id,
|
||||
product_qty,
|
||||
product_uom,
|
||||
location_id,
|
||||
name,
|
||||
origin,
|
||||
company_id,
|
||||
values,
|
||||
):
|
||||
res = super()._get_stock_move_values(
|
||||
product_id,
|
||||
product_qty,
|
||||
product_uom,
|
||||
location_id,
|
||||
name,
|
||||
origin,
|
||||
company_id,
|
||||
values,
|
||||
)
|
||||
if "analytic_account_id" in values:
|
||||
res["analytic_account_id"] = values.get("analytic_account_id")
|
||||
return res
|
||||
@@ -1,3 +1 @@
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||
from . import test_rma_analytic
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# Copyright 2017-23 ForgeFlow S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from odoo import fields
|
||||
from odoo.tests import Form
|
||||
|
||||
from odoo.addons.rma.tests import test_rma
|
||||
|
||||
|
||||
@@ -8,45 +11,65 @@ class TestRmaAnalytic(test_rma.TestRma):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestRmaAnalytic, cls).setUpClass()
|
||||
cls.rma_add_invoice_wiz = cls.env["rma_add_invoice"]
|
||||
cls.rma_add_invoice_wiz = cls.env["rma_add_account_move"]
|
||||
cls.rma_refund_wiz = cls.env["rma.refund"]
|
||||
cls.rma_obj = cls.env["rma.order"]
|
||||
cls.rma_op_obj = cls.env["rma.operation"]
|
||||
cls.rma_route_cust = cls.env.ref("rma.route_rma_customer")
|
||||
cls.cust_refund_op = cls.env.ref("rma_account.rma_operation_customer_refund")
|
||||
cls.rma_group_customer = cls.rma_obj.create(
|
||||
{"partner_id": cls.partner_id.id, "type": "customer"}
|
||||
)
|
||||
cls.operation_1 = cls.rma_op_obj.create(
|
||||
{
|
||||
"code": "TEST",
|
||||
"name": "Refund and receive",
|
||||
"type": "customer",
|
||||
"receipt_policy": "ordered",
|
||||
"refund_policy": "ordered",
|
||||
"in_route_id": cls.rma_route_cust.id,
|
||||
"out_route_id": cls.rma_route_cust.id,
|
||||
}
|
||||
)
|
||||
cls.product_1.update(
|
||||
{
|
||||
"rma_customer_operation_id": cls.operation_1.id,
|
||||
"rma_supplier_operation_id": cls.cust_refund_op.id,
|
||||
}
|
||||
)
|
||||
products2move = [
|
||||
(cls.product_1, 3),
|
||||
(cls.product_2, 5),
|
||||
(cls.product_3, 2),
|
||||
]
|
||||
cls.rma_add_invoice_wiz = cls.env["rma_add_invoice"]
|
||||
cls.rma_ana_id = cls._create_rma_from_move(
|
||||
products2move,
|
||||
"supplier",
|
||||
cls.env.ref("base.res_partner_2"),
|
||||
dropship=False,
|
||||
)
|
||||
receivable_type = cls.env.ref("account.data_account_type_receivable")
|
||||
# Create Invoices:
|
||||
customer_account = (
|
||||
cls.env["account.account"]
|
||||
.search([("user_type_id", "=", receivable_type.id)], limit=1)
|
||||
.id
|
||||
)
|
||||
cls.inv_customer = cls.env["account.invoice"].create(
|
||||
cls.company_id = cls.env.user.company_id
|
||||
cls.anal = cls.env["account.analytic.account"].create({"name": "Name"})
|
||||
cls.inv_customer = cls.env["account.move"].create(
|
||||
{
|
||||
"partner_id": cls.partner_id.id,
|
||||
"account_id": customer_account,
|
||||
"type": "out_invoice",
|
||||
}
|
||||
)
|
||||
cls.anal = cls.env["account.analytic.account"].create({"name": "Name"})
|
||||
cls.inv_line_1 = cls.env["account.invoice.line"].create(
|
||||
{
|
||||
"name": cls.partner_id.name,
|
||||
"product_id": cls.product_1.id,
|
||||
"quantity": 12.0,
|
||||
"price_unit": 100.0,
|
||||
"account_analytic_id": cls.anal.id,
|
||||
"invoice_id": cls.inv_customer.id,
|
||||
"uom_id": cls.product_1.uom_id.id,
|
||||
"account_id": customer_account,
|
||||
"move_type": "out_invoice",
|
||||
"invoice_date": fields.Date.from_string("2023-01-01"),
|
||||
"currency_id": cls.company_id.currency_id,
|
||||
"invoice_line_ids": [
|
||||
(
|
||||
0,
|
||||
None,
|
||||
{
|
||||
"name": cls.partner_id.name,
|
||||
"product_id": cls.product_1.id,
|
||||
"product_uom_id": cls.product_1.uom_id.id,
|
||||
"quantity": 12.0,
|
||||
"price_unit": 100.0,
|
||||
"analytic_account_id": cls.anal.id,
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
@@ -61,49 +84,6 @@ class TestRmaAnalytic(test_rma.TestRma):
|
||||
res.update({"analytic_account_id": analytic_1.id})
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def _create_rma_analytic(cls, products2move, partner):
|
||||
picking_in = cls._create_picking(partner)
|
||||
moves = []
|
||||
for item in products2move:
|
||||
move_values = cls._prepare_anal_move(
|
||||
item[0],
|
||||
item[1],
|
||||
cls.stock_location,
|
||||
cls.customer_location,
|
||||
picking_in,
|
||||
cls.analytic_1,
|
||||
)
|
||||
moves.append(cls.env["stock.move"].create(move_values))
|
||||
|
||||
rma_id = cls.rma_model.create(
|
||||
{
|
||||
"reference": "0001",
|
||||
"type": "customer",
|
||||
"partner_id": partner.id,
|
||||
"company_id": cls.env.ref("base.main_company").id,
|
||||
}
|
||||
)
|
||||
for move in moves:
|
||||
wizard = cls.rma_add_stock_move.with_context(
|
||||
{
|
||||
"stock_move_id": move.id,
|
||||
"customer": True,
|
||||
"active_ids": rma_id.id,
|
||||
"active_model": "rma.order",
|
||||
}
|
||||
).create({})
|
||||
data = wizard._prepare_rma_line_from_stock_move(move)
|
||||
wizard.add_lines()
|
||||
|
||||
if move.product_id.rma_customer_operation_id:
|
||||
move.product_id.rma_customer_operation_id.in_route_id = False
|
||||
move.product_id.categ_id.rma_customer_operation_id = False
|
||||
move.product_id.rma_customer_operation_id = False
|
||||
wizard._prepare_rma_line_from_stock_move(move)
|
||||
cls.line = cls.rma_line_model.create(data)
|
||||
return rma_id
|
||||
|
||||
def test_analytic(self):
|
||||
for line in self.rma_ana_id.rma_line_ids:
|
||||
for move in line.move_ids:
|
||||
@@ -115,31 +95,21 @@ class TestRmaAnalytic(test_rma.TestRma):
|
||||
|
||||
def test_invoice_analytic(self):
|
||||
"""Test wizard to create RMA from a customer invoice."""
|
||||
rma_line = (
|
||||
self.env["rma.order.line"]
|
||||
.with_context(customer=True)
|
||||
.new(
|
||||
{
|
||||
"partner_id": self.partner_id.id,
|
||||
"product_id": self.product_1.id,
|
||||
"operation_id": self.env.ref(
|
||||
"rma.rma_operation_customer_replace"
|
||||
).id,
|
||||
"in_route_id": self.env.ref("rma.route_rma_customer"),
|
||||
"out_route_id": self.env.ref("rma.route_rma_customer"),
|
||||
"in_warehouse_id": self.env.ref("stock.warehouse0"),
|
||||
"out_warehouse_id": self.env.ref("stock.warehouse0"),
|
||||
"location_id": self.env.ref("stock.stock_location_stock"),
|
||||
"type": "customer",
|
||||
"invoice_line_id": self.inv_line_1.id,
|
||||
"uom_id": self.product_1.uom_id.id,
|
||||
}
|
||||
)
|
||||
)
|
||||
rma_line._onchange_invoice_line_id()
|
||||
rma_line_form = Form(self.env["rma.order.line"].with_context(customer=True))
|
||||
rma_line_form.partner_id = self.partner_id
|
||||
rma_line_form.product_id = self.product_1
|
||||
rma_line_form.operation_id = self.env.ref("rma.rma_operation_customer_replace")
|
||||
rma_line_form.in_route_id = self.env.ref("rma.route_rma_customer")
|
||||
rma_line_form.out_route_id = self.env.ref("rma.route_rma_customer")
|
||||
rma_line_form.in_warehouse_id = self.env.ref("stock.warehouse0")
|
||||
rma_line_form.out_warehouse_id = self.env.ref("stock.warehouse0")
|
||||
rma_line_form.location_id = self.env.ref("stock.stock_location_stock")
|
||||
rma_line_form.account_move_line_id = self.inv_customer.invoice_line_ids[0]
|
||||
rma_line_form.uom_id = self.product_1.uom_id
|
||||
rma_line = rma_line_form.save()
|
||||
self.assertEqual(
|
||||
rma_line.analytic_account_id,
|
||||
self.inv_line_1.account_analytic_id,
|
||||
self.inv_customer.invoice_line_ids[0].analytic_account_id,
|
||||
)
|
||||
|
||||
def test_invoice_analytic02(self):
|
||||
@@ -159,58 +129,37 @@ class TestRmaAnalytic(test_rma.TestRma):
|
||||
)
|
||||
)
|
||||
add_inv = self.rma_add_invoice_wiz.with_context(
|
||||
{
|
||||
"customer": True,
|
||||
"active_ids": [rma_order.id],
|
||||
"active_model": "rma.order",
|
||||
}
|
||||
).create({"invoice_line_ids": [(6, 0, self.inv_customer.invoice_line_ids.ids)]})
|
||||
customer=True,
|
||||
active_ids=[rma_order.id],
|
||||
active_model="rma.order",
|
||||
).create({"line_ids": [(6, 0, self.inv_customer.invoice_line_ids.ids)]})
|
||||
add_inv.add_lines()
|
||||
|
||||
self.assertEqual(
|
||||
rma_order.mapped("rma_line_ids.analytic_account_id"),
|
||||
self.inv_line_1.account_analytic_id,
|
||||
self.inv_customer.invoice_line_ids[0].analytic_account_id,
|
||||
)
|
||||
|
||||
def test_refund_analytic(self):
|
||||
self.product_1.rma_customer_operation_id = self.env.ref(
|
||||
"rma_account.rma_operation_customer_refund"
|
||||
).id
|
||||
rma_line = (
|
||||
self.env["rma.order.line"]
|
||||
.with_context(customer=True)
|
||||
.create(
|
||||
{
|
||||
"partner_id": self.partner_id.id,
|
||||
"product_id": self.product_1.id,
|
||||
"operation_id": self.env.ref(
|
||||
"rma_account.rma_operation_customer_refund"
|
||||
).id,
|
||||
"in_route_id": self.env.ref("rma.route_rma_customer").id,
|
||||
"out_route_id": self.env.ref("rma.route_rma_customer").id,
|
||||
"in_warehouse_id": self.env.ref("stock.warehouse0").id,
|
||||
"out_warehouse_id": self.env.ref("stock.warehouse0").id,
|
||||
"location_id": self.env.ref("stock.stock_location_stock").id,
|
||||
"type": "customer",
|
||||
"invoice_line_id": self.inv_line_1.id,
|
||||
"delivery_policy": "no",
|
||||
"receipt_policy": "ordered",
|
||||
"uom_id": self.product_1.uom_id.id,
|
||||
}
|
||||
)
|
||||
add_inv = self.rma_add_invoice_wiz.with_context(
|
||||
customer=True,
|
||||
active_ids=[self.rma_group_customer.id],
|
||||
active_model="rma.order",
|
||||
).create({"line_ids": [(6, 0, self.inv_customer.invoice_line_ids.ids)]})
|
||||
add_inv.add_lines()
|
||||
rma_line = self.rma_group_customer.rma_line_ids.filtered(
|
||||
lambda r: r.product_id == self.product_1
|
||||
)
|
||||
rma_line._onchange_invoice_line_id()
|
||||
rma_line._onchange_account_move_line_id()
|
||||
rma_line.action_rma_to_approve()
|
||||
rma_line.action_rma_approve()
|
||||
make_refund = self.rma_refund_wiz.with_context(
|
||||
{
|
||||
"customer": True,
|
||||
"active_ids": rma_line.ids,
|
||||
"active_model": "rma.order.line",
|
||||
}
|
||||
customer=True,
|
||||
active_ids=rma_line.ids,
|
||||
active_model="rma.order.line",
|
||||
).create({"description": "Test refund"})
|
||||
make_refund.invoice_refund()
|
||||
self.assertEqual(
|
||||
rma_line.mapped("analytic_account_id"),
|
||||
rma_line.mapped("refund_line_ids.account_analytic_id"),
|
||||
rma_line.mapped("refund_line_ids.analytic_account_id"),
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!-- Copyright 2018 Eficent Business and IT Consulting Services S.L.
|
||||
<!-- Copyright 2023 ForgeFlow S.L.
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
|
||||
<odoo>
|
||||
<record id="view_rma_line_tree" model="ir.ui.view">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# © 2018 Eficent Business and IT Consulting Services S.L.
|
||||
# Copyright 2023 ForgeFlow S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from . import rma_add_stock_move
|
||||
from . import rma_make_picking
|
||||
from . import rma_add_invoice
|
||||
from . import rma_add_account_move
|
||||
from . import rma_refund
|
||||
|
||||
14
rma_analytic/wizards/rma_add_account_move.py
Normal file
14
rma_analytic/wizards/rma_add_account_move.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# Copyright 2023 ForgeFlow S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class RmaAddAccountMove(models.TransientModel):
|
||||
_inherit = "rma_add_account_move"
|
||||
|
||||
def _prepare_rma_line_from_inv_line(self, line):
|
||||
res = super(RmaAddAccountMove, self)._prepare_rma_line_from_inv_line(line)
|
||||
if line.analytic_account_id:
|
||||
res.update(analytic_account_id=line.analytic_account_id.id)
|
||||
return res
|
||||
@@ -1,4 +1,4 @@
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# Copyright 2023 ForgeFlow S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from odoo import models
|
||||
@@ -9,6 +9,6 @@ class RmaAddInvoice(models.TransientModel):
|
||||
|
||||
def _prepare_rma_line_from_inv_line(self, line):
|
||||
res = super(RmaAddInvoice, self)._prepare_rma_line_from_inv_line(line)
|
||||
if line.account_analytic_id:
|
||||
res.update(analytic_account_id=line.account_analytic_id.id)
|
||||
if line.analytic_account_id:
|
||||
res.update(analytic_account_id=line.analytic_account_id.id)
|
||||
return res
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# © 2018 Eficent Business and IT Consulting Services S.L.
|
||||
# Copyright 2023 ForgeFlow S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from odoo import api, models
|
||||
from odoo import models
|
||||
|
||||
|
||||
class RmaAddStockMove(models.TransientModel):
|
||||
_inherit = "rma_add_stock_move"
|
||||
_description = "Wizard to add rma lines from pickings"
|
||||
|
||||
@api.model
|
||||
def _prepare_rma_line_from_stock_move(self, sm, lot=False):
|
||||
data = super(RmaAddStockMove, self)._prepare_rma_line_from_stock_move(sm, lot)
|
||||
data.update(analytic_account_id=sm.analytic_account_id.id)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © 2018 Eficent Business and IT Consulting Services S.L.
|
||||
# Copyright 2023 ForgeFlow S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from odoo import api, models
|
||||
@@ -6,12 +6,11 @@ from odoo import api, models
|
||||
|
||||
class RmaMakePicking(models.TransientModel):
|
||||
_inherit = "rma_make_picking.wizard"
|
||||
_description = "Wizard to create pickings from rma lines"
|
||||
|
||||
@api.model
|
||||
def _get_procurement_data(self, item, group, qty, picking_type):
|
||||
procurement_data = super(RmaMakePicking, self)._get_procurement_data(
|
||||
item, group, qty, picking_type
|
||||
)
|
||||
procurement_data.update(account_analytic_id=item.line_id.analytic_account_id.id)
|
||||
procurement_data.update(analytic_account_id=item.line_id.analytic_account_id.id)
|
||||
return procurement_data
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © 2017 Eficent Business and IT Consulting Services S.L.
|
||||
# Copyright 2023 ForgeFlow S.L.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
from odoo import api, models
|
||||
@@ -8,8 +8,8 @@ class RmaRefund(models.TransientModel):
|
||||
_inherit = "rma.refund"
|
||||
|
||||
@api.model
|
||||
def prepare_refund_line(self, item, refund):
|
||||
res = super(RmaRefund, self).prepare_refund_line(item, refund)
|
||||
def prepare_refund_line(self, item):
|
||||
res = super(RmaRefund, self).prepare_refund_line(item)
|
||||
if item.line_id.analytic_account_id:
|
||||
res.update(account_analytic_id=item.line_id.analytic_account_id.id)
|
||||
res.update(analytic_account_id=item.line_id.analytic_account_id.id)
|
||||
return res
|
||||
|
||||
Reference in New Issue
Block a user