[FIX] sale, purchase, product: show sale warning in catalog
Currently, when adding a product to a quotation with the catalog, no warning message will appear when adding a poduct that has a warning or blocking message. Steps to reproduce: ------------------- * Go to **Sales** app -> Configuration -> Settings * Enable **Sale Warnings** * Go to **Products** -> Products * Create a new product * Under **Sales** tab: * For warning, select either warning or blocking message * Write a message * Go to **Orders** -> Quotations * Create a new quotation * Select the **Catalog** to add products * Add the newly created product Why the fix: ------------ The first version of this fix was a python exclusive change. It was a bit hacky; it was raising an error when the product had a blocking warning and sending a message on the bus when the product had a non-blocking warning. The second version was changing the return value of `_update_order_line_info` to return the price and the warning if any. The warning was shown inside JS with `_updateQuantity`. This change was not good for a stable verion as it was changing the signature of a public method. This fix automatically changes the data that is loaded to the catalog. It adds the warning message if any and changes the `readOnly` field accordingly. Warning/blocking messages will be automatically displayed in the catalog, on the product informations. Products with blocking messages will me marked as readonly to avoid being able to add the product to the sale order (this is the original behavior for blocking messages). Regarding the field `readOnly` and ẁarning`: * We can't write `res[product.id]['readOnly'] = product.sale_line_warn == "block"' because readOnly is set to True by default if the sale order is cancelled and doing this would overide that value later. See: https://github.com/odoo/odoo/blob/21c25a7ccd0ba2d6574ddbcfbcf50dbbc03a1e6c/addons/product/models/product_catalog_mixin.py#L97-L99 * We're also sending the warning only if there is one because of this: ```python <span t-elif="props.readOnly" class="my-2 pt-3 border-top" t-out="props.warning"> You can't edit this product in the catalog. </span> ``` Because in the case where readOnly is True for another reason than the product having a blocking warning, the initial message will be displyed. Since the module purchase also uses the warning on products, this fix is extended to include it. opw-3631511 closes odoo/odoo#149155 Signed-off-by: Valentin Chevalier <vcr@odoo.com> Co-authored-by: Valentin Chevalier <vcr@odoo.com>
This commit is contained in:
committed by
Sarah Bellefroid
co-authored by
Valentin Chevalier
parent
21317e3fe5
commit
a60cced448
@@ -8,7 +8,7 @@
|
||||
t-on-click="onGlobalClick"
|
||||
t-ref="root">
|
||||
<div class="d-flex flex-column h-100"
|
||||
t-att-class="{'o_product_added': productCatalogData.quantity || productCatalogData.readOnly}">
|
||||
t-att-class="{'o_product_added': productCatalogData.quantity}">
|
||||
<t t-call="{{ templates[this.constructor.KANBAN_BOX_ATTRIBUTE] }}"
|
||||
t-call-context="this.renderingContext"/>
|
||||
<t t-component="orderLineComponent" productId="props.record.resId" t-props="productCatalogData"/>
|
||||
|
||||
@@ -9,7 +9,8 @@ export class ProductCatalogOrderLine extends Component {
|
||||
quantity: Number,
|
||||
price: Number,
|
||||
readOnly: { type: Boolean, optional: true },
|
||||
}
|
||||
warning: { type: String, optional: true},
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
|
||||
@@ -6,10 +6,19 @@
|
||||
<t t-portal="`#product-${props.productId}-price`">
|
||||
<span class="o_product_catalog_price">Unit price: <t t-out="price"/></span>
|
||||
</t>
|
||||
<span t-if="props.readOnly" class="my-2 pt-3 border-top">
|
||||
<div
|
||||
t-if="props.readOnly and props.warning"
|
||||
class="text-danger text-truncate my-2 pt-3 border-top">
|
||||
<i class="fa fa-warning" t-att-title="props.warning"/>
|
||||
<span
|
||||
class="px-1"
|
||||
t-att-title="props.warning"
|
||||
t-out="props.warning"/>
|
||||
</div>
|
||||
<span t-elif="props.readOnly" class="my-2 pt-3 border-top" t-out="props.warning">
|
||||
You can't edit this product in the catalog.
|
||||
</span>
|
||||
<div t-else="" class="d-flex justify-content-end">
|
||||
<div t-else="" class="d-flex justify-content-end align-items-center">
|
||||
<div t-if="isInOrder()"
|
||||
class="input-group o_product_catalog_quantity o_product_catalog_cancel_global_click w-50">
|
||||
<button class="btn btn-primary border"
|
||||
@@ -27,7 +36,16 @@
|
||||
<i class="fa fa-plus"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="ms-auto o_product_catalog_buttons o_product_catalog_cancel_global_click">
|
||||
<t t-elif="props.warning">
|
||||
<i class="fa fa-warning text-warning" t-att-title="props.warning"/>
|
||||
<span
|
||||
class="text-truncate text-warning px-1"
|
||||
t-att-title="props.warning"
|
||||
t-out="props.warning"/>
|
||||
</t>
|
||||
<div
|
||||
class="ms-auto o_product_catalog_buttons o_product_catalog_cancel_global_click"
|
||||
style="min-width: max-content;">
|
||||
<button t-if="!isInOrder()"
|
||||
t-on-click.stop="() => this.env.addProduct()"
|
||||
class="btn btn-secondary">
|
||||
|
||||
@@ -869,6 +869,10 @@ class PurchaseOrder(models.Model):
|
||||
'id': product.uom_id.id,
|
||||
},
|
||||
}
|
||||
if product.purchase_line_warn_msg:
|
||||
product_infos['warning'] = product.purchase_line_warn_msg
|
||||
if product.purchase_line_warn == "block":
|
||||
product_infos['readOnly'] = True
|
||||
if product.uom_id != product.uom_po_id:
|
||||
product_infos['purchase_uom'] = {
|
||||
'display_name': product.uom_po_id.display_name,
|
||||
|
||||
@@ -482,7 +482,8 @@ class PurchaseOrderLine(models.Model):
|
||||
the product is read-only or not.
|
||||
|
||||
A product is considered read-only if the order is considered read-only (see
|
||||
``PurchaseOrder._is_readonly`` for more details) or if `self` contains multiple records.
|
||||
``PurchaseOrder._is_readonly`` for more details) or if `self` contains multiple records
|
||||
or if it has purchase_line_warn == "block".
|
||||
|
||||
Note: This method cannot be called with multiple records that have different products linked.
|
||||
|
||||
@@ -496,6 +497,7 @@ class PurchaseOrderLine(models.Model):
|
||||
'uom': dict,
|
||||
'purchase_uom': dict,
|
||||
'packaging': dict,
|
||||
'warning': String,
|
||||
}
|
||||
"""
|
||||
if len(self) == 1:
|
||||
|
||||
@@ -1811,7 +1811,14 @@ class SaleOrder(models.Model):
|
||||
date=self.date_order,
|
||||
**kwargs,
|
||||
)
|
||||
return {product_id: {'price': price} for product_id, price in pricelist.items()}
|
||||
res = {}
|
||||
for product in products:
|
||||
res[product.id] = {'price': pricelist.get(product.id)}
|
||||
if product.sale_line_warn_msg:
|
||||
res[product.id]['warning'] = product.sale_line_warn_msg
|
||||
if product.sale_line_warn == "block":
|
||||
res[product.id]['readOnly'] = True
|
||||
return res
|
||||
|
||||
def _get_product_catalog_record_lines(self, product_ids):
|
||||
grouped_lines = defaultdict(lambda: self.env['sale.order.line'])
|
||||
|
||||
@@ -1194,7 +1194,8 @@ class SaleOrderLine(models.Model):
|
||||
the product is read-only or not.
|
||||
|
||||
A product is considered read-only if the order is considered read-only (see
|
||||
``SaleOrder._is_readonly`` for more details) or if `self` contains multiple records.
|
||||
``SaleOrder._is_readonly`` for more details) or if `self` contains multiple records
|
||||
or if it has sale_line_warn == "block".
|
||||
|
||||
Note: This method cannot be called with multiple records that have different products linked.
|
||||
|
||||
@@ -1205,19 +1206,24 @@ class SaleOrderLine(models.Model):
|
||||
'quantity': float,
|
||||
'price': float,
|
||||
'readOnly': bool,
|
||||
'warning': String
|
||||
}
|
||||
"""
|
||||
if len(self) == 1:
|
||||
return {
|
||||
res = {
|
||||
'quantity': self.product_uom_qty,
|
||||
'price': self.price_unit,
|
||||
'readOnly': self.order_id._is_readonly(),
|
||||
'readOnly': self.order_id._is_readonly() or (self.product_id.sale_line_warn == "block"),
|
||||
'warning': self.product_id.sale_line_warn_msg,
|
||||
}
|
||||
if self.product_id.sale_line_warn_msg:
|
||||
res['warning'] = self.product_id.sale_line_warn_msg
|
||||
return res
|
||||
elif self:
|
||||
self.product_id.ensure_one()
|
||||
order_line = self[0]
|
||||
order = order_line.order_id
|
||||
return {
|
||||
res = {
|
||||
'readOnly': True,
|
||||
'price': order.pricelist_id._get_product_price(
|
||||
product=order_line.product_id,
|
||||
@@ -1233,8 +1239,11 @@ class SaleOrderLine(models.Model):
|
||||
to_unit=line.product_id.uom_id,
|
||||
)
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
if self.product_id.sale_line_warn_msg:
|
||||
res['warning'] = self.product_id.sale_line_warn_msg
|
||||
return res
|
||||
else:
|
||||
return {
|
||||
'quantity': 0,
|
||||
|
||||
Reference in New Issue
Block a user