[PATCH] Upstream patch - 15032022

This commit is contained in:
Parthiv Patel
2022-03-15 08:36:13 +00:00
parent 13b7737410
commit 6a06d0f680
8 changed files with 116 additions and 24 deletions

View File

@@ -146,7 +146,11 @@ class Digest(models.Model):
# create a mail_mail based on values, without attachments
mail_values = {
'auto_delete': True,
'email_from': self.company_id.partner_id.email_formatted if self.company_id else self.env.user.email_formatted,
'email_from': (
self.company_id.partner_id.email_formatted
or self.env.user.email_formatted
or self.env.ref('base.user_root').email_formatted
),
'email_to': user.email_formatted,
'body_html': full_mail,
'state': 'outgoing',

View File

@@ -9,7 +9,7 @@ class ReplenishmentReport(models.AbstractModel):
def _compute_draft_quantity_count(self, product_template_ids, product_variant_ids, wh_location_ids):
res = super()._compute_draft_quantity_count(product_template_ids, product_variant_ids, wh_location_ids)
domain = [('state', 'in', ['draft', 'sent'])]
domain = [('state', 'in', ['draft', 'sent', 'to approve'])]
domain += self._product_purchase_domain(product_template_ids, product_variant_ids)
warehouse_id = self.env.context.get('warehouse', False)
if warehouse_id:

View File

@@ -2,6 +2,7 @@
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
from flectra.tests.common import Form
from flectra.addons.mail.tests.common import mail_new_test_user
from flectra.addons.stock.tests.test_report import TestReportsCommon
@@ -145,3 +146,35 @@ class TestPurchaseStockReports(TestReportsCommon):
self.assertEqual(draft_picking_qty_in, 0)
self.assertEqual(draft_purchase_qty, 0)
self.assertEqual(pending_qty_in, 0)
def test_approval_and_forecasted_qty(self):
"""
When a PO is waiting for an approval, its quantities should be included
in the draft quantity count
"""
self.env.company.po_double_validation = 'two_step'
self.env.company.po_double_validation_amount = 0
basic_purchase_user = mail_new_test_user(
self.env,
login='basic_purchase_user',
groups='base.group_user,purchase.group_purchase_user',
)
po_form = Form(self.env['purchase.order'])
po_form.partner_id = self.partner
with po_form.order_line.new() as line:
line.product_id = self.product
line.product_qty = 50
po_form.save()
po_form = Form(self.env['purchase.order'])
po_form.partner_id = self.partner
with po_form.order_line.new() as line:
line.product_id = self.product
line.product_qty = 100
po = po_form.save()
po.with_user(basic_purchase_user).button_confirm()
docs = self.get_report_forecast(product_template_ids=self.product_template.ids)[1]
self.assertEqual(docs['draft_purchase_qty'], 150)

View File

@@ -3,7 +3,7 @@
from datetime import timedelta
from flectra import api, fields, models, _
from flectra import api, fields, models, _, SUPERUSER_ID
from flectra.exceptions import UserError, ValidationError
@@ -152,7 +152,7 @@ class SaleOrder(models.Model):
res = super(SaleOrder, self).action_confirm()
for order in self:
if order.sale_order_template_id and order.sale_order_template_id.mail_template_id:
self.sale_order_template_id.mail_template_id.send_mail(order.id)
order.sale_order_template_id.mail_template_id.with_user(SUPERUSER_ID).send_mail(order.id)
return res
def get_access_action(self, access_uid=None):

View File

@@ -3,7 +3,7 @@
from flectra import api, fields, models, _
from flectra.exceptions import UserError
from flectra.tools import float_is_zero, float_repr
from flectra.tools import float_is_zero, float_repr, float_compare
from flectra.exceptions import ValidationError
from collections import defaultdict
@@ -221,7 +221,7 @@ class ProductProduct(models.Model):
if product.cost_method not in ('standard', 'average'):
continue
quantity_svl = product.sudo().quantity_svl
if float_is_zero(quantity_svl, precision_rounding=product.uom_id.rounding):
if float_compare(quantity_svl, 0.0, precision_rounding=product.uom_id.rounding) <= 0:
continue
diff = new_price - product.standard_price
value = company_id.currency_id.round(quantity_svl * diff)

View File

@@ -2806,6 +2806,60 @@ class TestStockValuation(SavepointCase):
self.assertEqual(move7.stock_valuation_layer_ids.value, 100.0)
self.assertEqual(self.product1.standard_price, 10)
def test_average_automated_with_cost_change(self):
""" Test of the handling of a cost change with a negative stock quantity with FIFO+AVCO costing method"""
self.product1.categ_id.property_cost_method = 'average'
self.product1.categ_id.property_valuation = 'real_time'
# Step 1: Sell (and confirm) 10 units we don't have @ 100
self.product1.standard_price = 100
move1 = self.env['stock.move'].create({
'name': 'Sale 10 units',
'location_id': self.stock_location.id,
'location_dest_id': self.customer_location.id,
'product_id': self.product1.id,
'product_uom': self.uom_unit.id,
'product_uom_qty': 10.0,
})
move1._action_confirm()
move1.quantity_done = 10.0
move1._action_done()
self.assertAlmostEqual(self.product1.quantity_svl, -10.0)
self.assertEqual(move1.stock_valuation_layer_ids.value, -1000.0)
self.assertAlmostEqual(self.product1.value_svl, -1000.0)
# Step2: Change product cost from 100 to 10 -> Nothing should appear in inventory
# valuation as the quantity is negative
self.product1.standard_price = 10
self.assertEqual(self.product1.value_svl, -1000.0)
# Step 3: Make an inventory adjustment to set to total counted value at 0 -> Inventory
# valuation should be at 0 with a compensation layer at 900 (1000 - 100)
inventory_location = self.product1.property_stock_inventory
inventory_location.company_id = self.env.company.id
move2 = self.env['stock.move'].create({
'name': 'Adjustment of 10 units',
'location_id': inventory_location.id,
'location_dest_id': self.stock_location.id,
'product_id': self.product1.id,
'product_uom': self.uom_unit.id,
'product_uom_qty': 10.0,
})
move2._action_confirm()
move2._action_assign()
move2.move_line_ids.qty_done = 10.0
move2._action_done()
# Check if the move adjustment has correctly been done
self.assertAlmostEqual(self.product1.quantity_svl, 0.0)
self.assertAlmostEqual(move2.stock_valuation_layer_ids.value, 100.0)
# Check if the compensation layer is as expected, with final inventory value being 0
self.assertAlmostEqual(self.product1.stock_valuation_layer_ids.sorted()[-1].value, 900.0)
self.assertAlmostEqual(self.product1.value_svl, 0.0)
def test_average_manual_1(self):
''' Set owner on incoming move => no valuation '''
self.product1.categ_id.property_cost_method = 'average'
@@ -3310,41 +3364,41 @@ class TestStockValuation(SavepointCase):
self.assertEqual(self.product1.quantity_svl, 15)
self.assertEqual(self.product1.value_svl, 75)
# send 20
# send 10
move4 = self.env['stock.move'].create({
'name': 'out 10',
'location_id': self.stock_location.id,
'location_dest_id': self.customer_location.id,
'product_id': self.product1.id,
'product_uom': self.uom_unit.id,
'product_uom_qty': 20,
'product_uom_qty': 10,
})
move4._action_confirm()
move4._action_assign()
move4.move_line_ids.qty_done = 20
move4.move_line_ids.qty_done = 10
move4._action_done()
move4.date = date6
move4.stock_valuation_layer_ids._write({'create_date': date6})
self.assertEqual(self.product1.quantity_svl, -5)
self.assertEqual(self.product1.value_svl, -25)
self.assertEqual(self.product1.quantity_svl, 5)
self.assertEqual(self.product1.value_svl, 25.0)
# set the standard price to 7.5
self.product1.standard_price = 7.5
self.product1.stock_valuation_layer_ids.sorted()[-1]._write({'create_date': date7})
# receive 100
# receive 90
move5 = self.env['stock.move'].create({
'name': 'in 10',
'location_id': self.supplier_location.id,
'location_dest_id': self.stock_location.id,
'product_id': self.product1.id,
'product_uom': self.uom_unit.id,
'product_uom_qty': 100,
'product_uom_qty': 90,
})
move5._action_confirm()
move5._action_assign()
move5.move_line_ids.qty_done = 100
move5.move_line_ids.qty_done = 90
move5._action_done()
move5.date = date8
move5.stock_valuation_layer_ids._write({'create_date': date8})
@@ -3358,8 +3412,8 @@ class TestStockValuation(SavepointCase):
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date3)).quantity_svl, 30)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date4)).quantity_svl, 15)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date5)).quantity_svl, 15)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date6)).quantity_svl, -5)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date7)).quantity_svl, -5)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date6)).quantity_svl, 5)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date7)).quantity_svl, 5)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date8)).quantity_svl, 95)
# Valuation at date
@@ -3368,7 +3422,7 @@ class TestStockValuation(SavepointCase):
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date3)).value_svl, 300)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date4)).value_svl, 150)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date5)).value_svl, 75)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date6)).value_svl, -25)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date6)).value_svl, 25)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date8)).value_svl, 712.5)
# edit the done quantity of move1, decrease it
@@ -3383,16 +3437,16 @@ class TestStockValuation(SavepointCase):
# but the change is still only visible right now
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date2)).value_svl, 100)
# edit move 4, send 15 instead of 20
# edit move 4, send 15 instead of 10
move4.quantity_done = 15
# -(20*5) + (5*7.5)
self.assertEqual(sum(move4.stock_valuation_layer_ids.mapped('value')), -62.5)
# -(10*5) - (5*7.5)
self.assertEqual(sum(move4.stock_valuation_layer_ids.mapped('value')), -87.5)
# the change is only visible right now
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date6)).value_svl, -25)
self.assertEqual(self.product1.with_context(to_date=Datetime.to_string(date6)).value_svl, 25)
self.assertEqual(self.product1.quantity_svl, 95)
self.assertEqual(self.product1.value_svl, 712.5)
self.assertEqual(self.product1.quantity_svl, 85)
self.assertEqual(self.product1.value_svl, 637.5)
def test_at_date_fifo_1(self):
""" Make some operations at different dates, check that the results of the valuation at

View File

@@ -468,6 +468,7 @@
coerce_types = { 'true': !0, 'false': !1, 'null': null };
// Iterate over all name=value pairs.
if (params.indexOf('__proto__') !== -1) { return obj; }
$.each( params.replace( /\+/g, ' ' ).split( '&' ), function(j,v){
var param = v.split( '=' ),
key = decode( param[0] ),

View File

@@ -262,7 +262,7 @@ jQuery.extend = jQuery.fn.extend = function() {
copy = options[ name ];
// Prevent never-ending loop
if ( target === copy ) {
if ( name === '__proto__' || target === copy ) {
continue;
}