[IMP] sale: ease catalog inheritance

closes odoo/odoo#132341

Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
Victor Feyens
2023-08-24 18:37:29 +02:00
committed by Valentin Chevalier
parent 960b4c8616
commit 484210c5d3
7 changed files with 120 additions and 23 deletions
+13 -18
View File
@@ -30,27 +30,22 @@ class CatalogController(Controller):
):
if(product.id not in product_ids):
continue
if (len(lines) > 1) or lines[0].product_uom != product.uom_id:
price_unit = order.pricelist_id._get_product_price(
product=product,
quantity=1.0,
currency=order.currency_id,
date=order.date_order,
)
sale_order_line_info[product.id] = dict(
readOnly=True,
price=price_unit,
)
else:
line = lines[0]
sale_order_line_info[product.id] = dict(
quantity=line.product_uom_qty,
price=line.price_unit,
)
sale_order_line_info[product.id] = request.env['sale.order.line'].browse(
line.id for line in lines # groupby gives a list and not a recordset
)._get_catalog_info()
product_ids.remove(product.id)
default_data = request.env['sale.order.line']._get_catalog_info()
default_data['readOnly'] = order._is_readonly()
sale_order_line_info.update({
id: dict(price=price) for id, price in order.pricelist_id._get_products_price(
id: {
**default_data,
'price': price,
}
for id, price in order.pricelist_id._get_products_price(
quantity=1.0,
products=request.env['product.product'].browse(product_ids),
currency=order.currency_id,
+14
View File
@@ -1658,3 +1658,17 @@ class SaleOrder(models.Model):
# Override for correct taxcloud computation
# when using coupon and delivery
return True
#=== TOOLING ===#
def _is_readonly(self):
""" Return Whether the sale order is read-only or not based on the state or the lock status.
A sale order is considered read-only if its state is 'cancel' or if the sale order is
locked.
:return: Whether the sale order is read-only or not.
:rtype: bool
"""
self.ensure_one()
return self.state == 'cancel' or self.locked
+56
View File
@@ -1188,6 +1188,62 @@ class SaleOrderLine(models.Model):
product_catalog_digits=order.order_line._fields['price_unit'].get_digits(order.env),
)
def _get_catalog_info(self):
""" Return information about sale order lines in `self`.
If `self` is empty, this method returns only the default value(s) needed for the product
catalog. In this case, the quantity that equals 0.
Otherwise, it returns a quantity and a price based on the product of the SOL(s) and whether
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.
Note: This method cannot be called with multiple records that have different products linked.
:raise odoo.exceptions.ValueError: ``len(self.product_id) != 1``
:rtype: dict
:return: A dict with the following structure:
{
'quantity': float,
'price': float,
'readOnly': bool,
}
"""
if len(self) == 1:
return {
'quantity': self.product_uom_qty,
'price': self.price_unit,
'readOnly': self.order_id._is_readonly(),
}
elif self:
self.product_id.ensure_one()
order_line = self[0]
order = order_line.order_id
return {
'readOnly': True,
'price': order.pricelist._get_product_price(
product=order_line.product_id,
quantity=1.0,
currency=order.currency_id,
date=order.date_order,
),
'quantity': sum(
self.mapped(
lambda line: line.product_uom._compute_quantity(
qty=line.product_uom_qty,
to_unit=line.product_id.uom_id,
)
)
),
}
else:
return {
'quantity': 0,
# price will be computed in batch with pricelist utils so not given here
}
#=== TOOLING ===#
def _convert_to_sol_currency(self, amount, currency):
@@ -23,7 +23,6 @@ export class ProductCatalogKanbanModel extends RelationalModel {
});
for (const record of result.records) {
record.productCatalogData = saleOrderLinesInfo[record.id];
record.productCatalogData.quantity = record.productCatalogData.quantity || 0;
}
return result;
}
@@ -11,10 +11,7 @@
t-att-class="{'text-bg-primary': productCatalogData.quantity || productCatalogData.readOnly}">
<t t-call="{{ templates[this.constructor.KANBAN_BOX_ATTRIBUTE] }}"
t-call-context="this.renderingContext"/>
<ProductCatalogSOL productId="props.record.resId"
quantity="productCatalogData.quantity"
price="productCatalogData.price"
readOnly="productCatalogData.readOnly"/>
<ProductCatalogSOL productId="props.record.resId" t-props="productCatalogData"/>
</div>
<t t-call="{{ this.constructor.menuTemplate }}"/>
</div>
@@ -331,7 +331,32 @@ class SaleOrderLine(models.Model):
raise UserError(_('The ordered quantity cannot be decreased below the amount already delivered. Instead, create a return in your inventory.'))
super(SaleOrderLine, self)._update_line_quantity(values)
#=== HOOKS ===#
def _get_action_add_from_catalog_extra_context(self, order):
extra_context = super()._get_action_add_from_catalog_extra_context(order)
extra_context.update(warehouse=order.warehouse_id.id)
return extra_context
def _get_catalog_info(self):
""" Override of `sale` to add the delivered quantity.
:rtype: dict
:return: A dict with the following structure:
{
'deliveredQty': float,
'quantity': float,
'price': float,
'readOnly': bool,
}
"""
res = super()._get_catalog_info()
res['deliveredQty'] = sum(
self.mapped(
lambda line: line.product_uom._compute_quantity(
qty=line.qty_delivered,
to_unit=line.product_id.uom_id,
)
)
)
return res
@@ -0,0 +1,11 @@
/** @odoo-module */
import { ProductCatalogSOL } from "@sale/js/product_catalog/sale_order_line/sale_order_line";
import { patch } from "@web/core/utils/patch";
patch(ProductCatalogSOL, {
props: {
...ProductCatalogSOL.props,
deliveredQty: Number,
},
});