[IMP] stock, purchase, sale: inventory back to basics

Applies various small changes:

- [IMP] stock, stock_account: add dates to stock move name (inventory adjustments)
- [IMP] delivery,stock: add pack type weight
- [IMP] {purchase, sale}_stock: add Incoterm Location field
- [IMP] stock_picking_batch: default show Batch Transfer
- [IMP] purchase: add supplier info with sudo qty 1
- [IMP] sale_purchase: add related PO warning
- [FIX] product: order product labels by product
- [IMP] product: default filter vendor pricelist w/ active products
- [IMP] stock: relax picking locations readonly states
- [IMP] stock: add consumables replenish button
- [IMP] stock_picking_batch: pick type auto batch not active by default
- [IMP] stock: add stock quant import template
- [FIX] sale,stock,mrp,purchase: add uom precision

Task Id: 2764771
COM PR: odoo/odoo#91640

--
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr

Signed-off-by: Tiffany Chang <tic@odoo.com>
This commit is contained in:
Odoo's Mergebot
2022-06-03 12:02:09 +02:00
committed by GitHub
32 changed files with 127 additions and 131 deletions
+2 -2
View File
@@ -308,7 +308,7 @@ class DeliveryCarrier(models.Model):
for line in order.order_line.filtered(lambda line: not line.is_delivery and not line.display_type):
total_cost += self._product_price_to_company_currency(line.product_qty, line.product_id, order.company_id)
total_weight = order._get_estimated_weight()
total_weight = order._get_estimated_weight() + default_package_type.base_weight
# If max weight == 0 => division by 0. If this happens, we want to have
# more in the max weight than in the total weight, so that it only
# creates ONE package with everything.
@@ -327,7 +327,7 @@ class DeliveryCarrier(models.Model):
if picking.is_return_picking:
commodities = self._get_commodities_from_stock_move_lines(picking.move_line_ids)
weight = picking._get_estimated_weight()
weight = picking._get_estimated_weight() + default_package_type.base_weight
packages.append(DeliveryPackage(commodities, weight, default_package_type, currency=picking.company_id.currency_id, picking=picking))
return packages
+3 -2
View File
@@ -11,10 +11,11 @@ from odoo.exceptions import UserError
class StockQuantPackage(models.Model):
_inherit = "stock.quant.package"
@api.depends('quant_ids')
@api.depends('quant_ids', 'package_type_id')
def _compute_weight(self):
for package in self:
weight = 0.0
# set initial weight to package type base weight
weight = package.package_type_id.base_weight or 0.0
if self.env.context.get('picking_id'):
# TODO: potential bottleneck: N packages = N queries, use groupby ?
current_picking_move_line_ids = self.env['stock.move.line'].search([
@@ -9,25 +9,9 @@ class ChooseDeliveryPackage(models.TransientModel):
_name = 'choose.delivery.package'
_description = 'Delivery Package Selection Wizard'
@api.model
def default_get(self, fields_list):
defaults = super().default_get(fields_list)
if 'shipping_weight' in fields_list:
picking = self.env['stock.picking'].browse(defaults.get('picking_id'))
move_line_ids = picking.move_line_ids.filtered(lambda m:
float_compare(m.qty_done, 0.0, precision_rounding=m.product_uom_id.rounding) > 0
and not m.result_package_id
)
total_weight = 0.0
for ml in move_line_ids:
qty = ml.product_uom_id._compute_quantity(ml.qty_done, ml.product_id.uom_id)
total_weight += qty * ml.product_id.weight
defaults['shipping_weight'] = total_weight
return defaults
picking_id = fields.Many2one('stock.picking', 'Picking')
delivery_package_type_id = fields.Many2one('stock.package.type', 'Delivery Package Type', check_company=True)
shipping_weight = fields.Float('Shipping Weight')
shipping_weight = fields.Float('Shipping Weight', compute='_compute_shipping_weight', store=True, readonly=False)
weight_uom_name = fields.Char(string='Weight unit of measure label', compute='_compute_weight_uom_name')
company_id = fields.Many2one(related='picking_id.company_id')
@@ -37,6 +21,20 @@ class ChooseDeliveryPackage(models.TransientModel):
for package in self:
package.weight_uom_name = weight_uom_id.name
@api.depends('delivery_package_type_id')
def _compute_shipping_weight(self):
for rec in self:
move_line_ids = rec.picking_id.move_line_ids.filtered(lambda m:
float_compare(m.qty_done, 0.0, precision_rounding=m.product_uom_id.rounding) > 0
and not m.result_package_id
)
# Add package weights to shipping weight, package base weight is defined in package.type
total_weight = rec.delivery_package_type_id.base_weight or 0.0
for ml in move_line_ids:
qty = ml.product_uom_id._compute_quantity(ml.qty_done, ml.product_id.uom_id)
total_weight += qty * ml.product_id.weight
rec.shipping_weight = total_weight
@api.onchange('delivery_package_type_id', 'shipping_weight')
def _onchange_package_type_weight(self):
if self.delivery_package_type_id.max_weight and self.shipping_weight > self.delivery_package_type_id.max_weight:
+2 -2
View File
@@ -27,7 +27,7 @@ class ProductTemplate(models.Model):
compute='_compute_bom_count', compute_sudo=False)
used_in_bom_count = fields.Integer('# of BoM Where is Used',
compute='_compute_used_in_bom_count', compute_sudo=False)
mrp_product_qty = fields.Float('Manufactured',
mrp_product_qty = fields.Float('Manufactured', digits='Product Unit of Measure',
compute='_compute_mrp_product_qty', compute_sudo=False)
produce_delay = fields.Float(
'Manufacturing Lead Time', default=0.0,
@@ -97,7 +97,7 @@ class ProductProduct(models.Model):
compute='_compute_bom_count', compute_sudo=False)
used_in_bom_count = fields.Integer('# BoM Where Used',
compute='_compute_used_in_bom_count', compute_sudo=False)
mrp_product_qty = fields.Float('Manufactured',
mrp_product_qty = fields.Float('Manufactured', digits='Product Unit of Measure',
compute='_compute_mrp_product_qty', compute_sudo=False)
is_kits = fields.Boolean(compute="_compute_is_kits", compute_sudo=False)
@@ -17,9 +17,13 @@ def _prepare_data(env, data):
raise UserError(_('Product model not defined, Please contact your administrator.'))
total = 0
qty_by_product_in = data.get('quantity_by_product')
# search for products all at once, ordered by name desc since popitem() used in xml to print the labels
# is LIFO, which results in ordering by product name in the report
products = Product.search([('id', 'in', [int(p) for p in qty_by_product_in.keys()])], order='name desc')
quantity_by_product = defaultdict(list)
for p, q in data.get('quantity_by_product').items():
product = Product.browse(int(p))
for product in products:
q = qty_by_product_in[str(product.id)]
quantity_by_product[product].append((product.barcode, q))
total += q
if data.get('custom_barcodes'):
@@ -47,6 +47,8 @@
<search string="Vendor">
<field name="partner_id"/>
<field name="product_tmpl_id"/>
<filter string="Active Products" name="active_products" domain="['|', ('product_tmpl_id.active', '=', True),('product_id.active', '=', True)]"/>
<separator />
<filter string="Active" name="active" domain="['|', ('date_end', '=', False), ('date_end', '&gt;=', (context_today() - datetime.timedelta(days=1)).strftime('%Y-%m-%d'))]"/>
<filter string="Archived" name="archived" domain="[('date_end', '&lt;', (context_today() - datetime.timedelta(days=1)).strftime('%Y-%m-%d'))]"/>
<group expand="0" string="Group By">
@@ -122,7 +124,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.supplierinfo</field>
<field name="view_mode">tree,form,kanban</field>
<field name="context">{'visible_product_tmpl_id':False}</field>
<field name="context">{'visible_product_tmpl_id': False, 'search_default_active_products': True}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No vendor pricelist found
+3 -2
View File
@@ -15,7 +15,7 @@ class ProductTemplate(models.Model):
'account.account', string="Price Difference Account", company_dependent=True,
help="This account is used in automated inventory valuation to "\
"record the price difference between a purchase order and its related vendor bill when validating this vendor bill.")
purchased_product_qty = fields.Float(compute='_compute_purchased_product_qty', string='Purchased')
purchased_product_qty = fields.Float(compute='_compute_purchased_product_qty', string='Purchased', digits='Product Unit of Measure')
purchase_method = fields.Selection([
('purchase', 'On ordered quantities'),
('receive', 'On received quantities'),
@@ -52,7 +52,8 @@ class ProductProduct(models.Model):
_name = 'product.product'
_inherit = 'product.product'
purchased_product_qty = fields.Float(compute='_compute_purchased_product_qty', string='Purchased')
purchased_product_qty = fields.Float(compute='_compute_purchased_product_qty', string='Purchased',
digits='Product Unit of Measure')
def _compute_purchased_product_qty(self):
date_from = fields.Datetime.to_string(fields.Date.context_today(self) - relativedelta(years=1))
+4 -6
View File
@@ -12,7 +12,7 @@ from odoo import api, fields, models, _
from odoo.osv import expression
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, format_amount, format_date, formatLang, get_lang, groupby
from odoo.tools.float_utils import float_compare, float_is_zero, float_round
from odoo.exceptions import AccessError, UserError, ValidationError
from odoo.exceptions import UserError, ValidationError
class PurchaseOrder(models.Model):
@@ -492,7 +492,7 @@ class PurchaseOrder(models.Model):
return {
'partner_id': partner.id,
'sequence': max(line.product_id.seller_ids.mapped('sequence')) + 1 if line.product_id.seller_ids else 1,
'min_qty': 0.0,
'min_qty': 1.0,
'price': price,
'currency_id': currency.id,
'delay': 0,
@@ -528,10 +528,8 @@ class PurchaseOrder(models.Model):
vals = {
'seller_ids': [(0, 0, supplierinfo)],
}
try:
line.product_id.write(vals)
except AccessError: # no write access rights -> just ignore
break
# supplier info should be added regardless of the user access rights
line.product_id.sudo().write(vals)
def action_create_invoice(self):
"""Create the invoice associated to the PO.
@@ -327,71 +327,3 @@ class TestPurchaseToInvoice(AccountTestInvoicingCommon):
aml = self.env['account.move.line'].search([('purchase_line_id', '=', purchase_order.order_line.id)])
self.assertRecordValues(aml, [{'analytic_account_id': analytic_account_manual.id}])
def test_multicompany_partner_bank(self):
""" Test that in a multiple company environment, the bank account of the invoice
is the one corresponding to the active company. """
company_a = self.env.user.company_id
company_b = self.env['res.company'].create({
'name': 'Company B',
})
self.env.ref('l10n_generic_coa.configurable_chart_template')._load(company_b)
partner = self.env['res.partner'].create({
'name': 'AAAAA',
})
partner_bank_a = self.env['res.partner.bank'].create({
'acc_number': "BE01 23456789 10",
'partner_id': partner.id,
'acc_type': 'bank'
})
partner_bank_b = self.env['res.partner.bank'].create({
'acc_number': "BE10 98765432 10",
'partner_id': partner.id,
'acc_type': 'bank'
})
partner.bank_ids = [partner_bank_a.id, partner_bank_b.id]
partner_bank_a.company_id = company_a
partner_bank_b.company_id = company_b
PurchaseOrder = self.env['purchase.order'].with_context(tracking_disable=True)
po_a = PurchaseOrder.with_company(company_a).create({
'partner_id': partner.id,
'company_id': company_a.id,
'currency_id': company_a.currency_id.id,
'date_order': '2019-01-01',
})
po_b = PurchaseOrder.with_company(company_b).create({
'partner_id': partner.id,
'company_id': company_b.id,
'currency_id': company_b.currency_id.id,
'date_order': '2019-01-01',
})
vals_pol = {
'name': self.product_deliver.name,
'product_id': self.product_deliver.id,
'product_qty': 10.0,
'product_uom': self.product_deliver.uom_id.id,
'price_unit': self.product_deliver.list_price,
'order_id': po_a.id,
'taxes_id': False,
}
PurchaseOrderLine = self.env['purchase.order.line'].with_context(tracking_disable=True)
PurchaseOrderLine.create(vals_pol)
vals_pol['order_id'] = po_b.id
PurchaseOrderLine.create(vals_pol)
po_a.button_confirm()
po_b.button_confirm()
po_a.order_line.qty_received = po_b.order_line.qty_received = 10
po_a.with_company(company_a).action_create_invoice()
po_b.with_company(company_b).action_create_invoice()
self.assertEqual(po_a.invoice_ids.company_id, company_a)
self.assertEqual(po_a.invoice_ids.partner_bank_id, partner_bank_a)
self.assertEqual(po_b.invoice_ids.company_id, company_b)
self.assertEqual(po_b.invoice_ids.partner_bank_id, partner_bank_b)
+1 -1
View File
@@ -18,7 +18,7 @@ class PurchaseOrder(models.Model):
return self._get_picking_type(self.env.context.get('company_id') or self.env.company.id)
incoterm_id = fields.Many2one('account.incoterms', 'Incoterm', states={'done': [('readonly', True)]}, help="International Commercial Terms are a series of predefined commercial terms used in international transactions.")
incoterm_location = fields.Char(string='Incoterm Location', states={'done': [('readonly', True)]})
incoming_picking_count = fields.Integer("Incoming Shipment count", compute='_compute_incoming_picking_count')
picking_ids = fields.Many2many('stock.picking', compute='_compute_picking_ids', string='Receptions', copy=False, store=True)
@@ -16,7 +16,8 @@
<xpath expr="//div[@t-elif='o.date_order']" position="after">
<div t-if="o.incoterm_id" class="col-3 bm-2">
<strong>Incoterm:</strong>
<p t-field="o.incoterm_id.code" class="m-0"/>
<p t-if="o.incoterm_location" t-out="'%s %s' % (o.incoterm_id.code, o.incoterm_location)" class="m-0"/>
<p t-else="" t-field="o.incoterm_id.code" class="m-0"/>
</div>
</xpath>
</template>
@@ -37,7 +38,8 @@
<div id="informations" class="row mt16 mb16">
<div t-if="o.incoterm_id" class="col-3 bm-2">
<strong>Incoterm:</strong>
<p t-field="o.incoterm_id.code" class="m-0"/>
<p t-if="o.incoterm_location" t-out="'%s %s' % (o.incoterm_id.code, o.incoterm_location)" class="m-0"/>
<p t-else="" t-field="o.incoterm_id.code" class="m-0"/>
</div>
</div>
</xpath>
@@ -370,19 +370,14 @@ class TestPurchaseOrder(ValuationReconciliationTestCommon):
self.assertEqual(po.order_line.mapped('qty_received'), [4.0], 'Purchase: no conversion error on receipt in different uom"')
def test_message_qty_already_received(self):
_product = self.env['product.product'].create({
'name': 'TempProduct',
'type': 'consu',
'company_id': self.env.user.company_id.id,
})
self.env.user.write({'company_id': self.company_data['company'].id})
_purchase_order = self.env['purchase.order'].create({
'company_id': self.env.user.company_id.id,
'partner_id': self.partner_a.id,
'order_line': [
(0, 0, {
'name': _product.name,
'product_id': _product.id,
'name': self.product_id_2.name,
'product_id': self.product_id_2.id,
'product_qty': 25.0,
'price_unit': 250.0,
})],
@@ -61,6 +61,7 @@
<xpath expr="//page[@name='purchase_delivery_invoice']/group/group" position="inside">
<field name="default_location_dest_id_usage" invisible="1"/>
<field name="incoterm_id"/>
<field name="incoterm_location" />
</xpath>
<xpath expr="//div[@name='reminder']" position="after">
<field name="picking_type_id" domain="[('code','=','incoming'), '|', ('warehouse_id', '=', False), ('warehouse_id.company_id', '=', company_id)]" options="{'no_create': True}" groups="stock.group_stock_multi_locations"/>
+1 -1
View File
@@ -8,7 +8,7 @@ from odoo.tools.float_utils import float_round
class ProductProduct(models.Model):
_inherit = 'product.product'
sales_count = fields.Float(compute='_compute_sales_count', string='Sold')
sales_count = fields.Float(compute='_compute_sales_count', string='Sold', digits='Product Unit of Measure')
def _compute_sales_count(self):
r = {}
+1 -1
View File
@@ -32,7 +32,7 @@ class ProductTemplate(models.Model):
help="Expenses and vendor bills can be re-invoiced to a customer."
"With this option, a validated expense can be re-invoice to a customer at its cost or sales price.")
visible_expense_policy = fields.Boolean("Re-Invoice Policy visible", compute='_compute_visible_expense_policy')
sales_count = fields.Float(compute='_compute_sales_count', string='Sold')
sales_count = fields.Float(compute='_compute_sales_count', string='Sold', digits='Product Unit of Measure')
visible_qty_configurator = fields.Boolean("Quantity visible in configurator", compute='_compute_visible_qty_configurator')
invoice_policy = fields.Selection(
[('order', 'Ordered quantities'),
+1
View File
@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
from . import wizards
+1
View File
@@ -20,6 +20,7 @@ by external providers and will automatically generate purchase orders directed t
'views/product_views.xml',
'views/sale_order_views.xml',
'views/purchase_order_views.xml',
'wizards/sale_order_cancel_views.xml',
],
'auto_install': True,
'license': 'LGPL-3',
+1
View File
@@ -0,0 +1 @@
from . import sale_order_cancel
@@ -0,0 +1,17 @@
from odoo import api, fields, models
class SaleOrderCancel(models.TransientModel):
_inherit = "sale.order.cancel"
display_purchase_orders_alert = fields.Boolean(
string="Purchase Order Alert",
compute='_compute_display_purchase_orders_alert'
)
@api.depends('order_id')
def _compute_display_purchase_orders_alert(self):
for wizard in self:
wizard.display_purchase_orders_alert = bool(
wizard.order_id.purchase_order_count
)
@@ -0,0 +1,18 @@
<odoo>
<record id="sale_order_cancel_view_form" model="ir.ui.view">
<field name="name">sale.order.cancel.form.inherit</field>
<field name="model">sale.order.cancel</field>
<field name="inherit_id" ref="sale.sale_order_cancel_view_form"/>
<field name="arch" type="xml">
<field name="display_invoice_alert" position="after">
<field name="display_purchase_orders_alert" invisible="True" />
</field>
<span id="display_invoice_alert" position="after">
<span id="display_purchase_orders_alert"
attrs="{'invisible': [('display_purchase_orders_alert', '=', False)]}">
There are active purchase orders linked to this sale order that are not cancelled automatically! <br/>
</span>
</span>
</field>
</record>
</odoo>
+1
View File
@@ -16,6 +16,7 @@ class SaleOrder(models.Model):
incoterm = fields.Many2one(
'account.incoterms', 'Incoterm',
help="International Commercial Terms are a series of predefined commercial terms used in international transactions.")
incoterm_location = fields.Char(string='Incoterm Location')
picking_policy = fields.Selection([
('direct', 'As soon as possible'),
('one', 'When all products are ready')],
@@ -4,7 +4,8 @@
<xpath expr="//div[@name='expiration_date']" position="after">
<div class="col-auto col-3 mw-100 mb-2" t-if="doc.incoterm" groups="sale_stock.group_display_incoterm">
<strong>Incoterm:</strong>
<p class="m-0" t-field="doc.incoterm.code"/>
<p t-if="doc.incoterm_location" t-out="'%s %s' % (doc.incoterm.code, doc.incoterm_location)" class="m-0"/>
<p t-else="" t-field="doc.incoterm.code" class="m-0"/>
</div>
</xpath>
</template>
@@ -22,6 +22,7 @@
<xpath expr="//label[@for='commitment_date']" position="before">
<field name="warehouse_id" options="{'no_create': True}" groups="stock.group_stock_multi_warehouses" force_save="1"/>
<field name="incoterm" options="{'no_open': True, 'no_create': True}" groups="sale_stock.group_display_incoterm"/>
<field name="incoterm_location" groups="sale_stock.group_display_incoterm"/>
<field name="picking_policy" required="True"/>
</xpath>
<xpath expr="//span[@name='expected_date_span']" position="attributes">
@@ -19,6 +19,7 @@ class PackageType(models.Model):
height = fields.Integer('Height', help="Packaging Height")
width = fields.Integer('Width', help="Packaging Width")
packaging_length = fields.Integer('Length', help="Packaging Length")
base_weight = fields.Float(string='Weight', help='Weight of the package type')
max_weight = fields.Float('Max Weight', help='Maximum weight shippable in this packaging')
barcode = fields.Char('Barcode', copy=False)
weight_uom_name = fields.Char(string='Weight unit of measure label', compute='_compute_weight_uom_name', default=_get_default_weight_uom)
+4 -4
View File
@@ -318,13 +318,13 @@ class Picking(models.Model):
location_id = fields.Many2one(
'stock.location', "Source Location",
default=lambda self: self.env['stock.picking.type'].browse(self._context.get('default_picking_type_id')).default_location_src_id,
check_company=True, readonly=True, required=True,
states={'draft': [('readonly', False)]})
check_company=True, required=True,
states={'done': [('readonly', True)]})
location_dest_id = fields.Many2one(
'stock.location', "Destination Location",
default=lambda self: self.env['stock.picking.type'].browse(self._context.get('default_picking_type_id')).default_location_dest_id,
check_company=True, readonly=True, required=True,
states={'draft': [('readonly', False)]})
check_company=True, required=True,
states={'done': [('readonly', True)]})
move_ids = fields.One2many('stock.move', 'picking_id', string="Stock Moves", copy=True)
move_ids_without_package = fields.One2many(
'stock.move', 'picking_id', string="Stock moves not in package", compute='_compute_move_without_package',
+13 -1
View File
@@ -104,7 +104,8 @@ class StockQuant(models.Model):
'Counted Quantity', digits='Product Unit of Measure',
help="The product's counted quantity.")
inventory_quantity_auto_apply = fields.Float(
'Inventoried Quantity', compute='_compute_inventory_quantity_auto_apply',
'Inventoried Quantity', digits='Product Unit of Measure',
compute='_compute_inventory_quantity_auto_apply',
inverse='_set_inventory_quantity', groups='stock.group_stock_manager'
)
inventory_diff_quantity = fields.Float(
@@ -303,6 +304,13 @@ class StockQuant(models.Model):
group['inventory_quantity_auto_apply'] = group['quantity']
return result
@api.model
def get_import_templates(self):
return [{
'label': _('Import Template for Inventory Adjustments'),
'template': '/stock/static/xlsx/stock_quant.xlsx'
}]
def write(self, vals):
""" Override to handle the "inventory mode" and create the inventory move. """
allowed_fields = self._get_inventory_fields_write()
@@ -877,6 +885,10 @@ class StockQuant(models.Model):
name = _('Product Quantity Confirmed')
else:
name = _('Product Quantity Updated')
if self.inventory_date:
name += _(' [Scheduled on %s]', self.inventory_date)
return {
'name': self.env.context.get('inventory_name') or name,
'product_id': self.product_id.id,
Binary file not shown.
+3 -3
View File
@@ -220,7 +220,7 @@
name="%(action_product_replenish)d"
context="{'default_product_id': id}"
groups="stock.group_stock_user"
attrs="{'invisible': [('type', '!=', 'product')]}"/>
attrs="{'invisible': [('type', 'not in', ['consu', 'product'])]}"/>
</header>
<div name="button_box" position="inside">
<button string="Putaway Rules" type="object"
@@ -249,7 +249,7 @@
name="%(action_product_replenish)d"
context="{'default_product_id': id}"
groups="stock.group_stock_user"
attrs="{'invisible': [('type', '!=', 'product')]}"/>
attrs="{'invisible': [('type', 'not in', ['consu', 'product'])]}"/>
</header>
<div name="button_box" position="inside">
<field name="show_on_hand_qty_status_button" invisible="1"/>
@@ -355,7 +355,7 @@
name="%(action_product_replenish)d"
context="{'default_product_tmpl_id': id}"
groups="stock.group_stock_user"
attrs="{'invisible': [('type', '!=', 'product')]}"/>
attrs="{'invisible': [('type', 'not in', ['consu', 'product'])]}"/>
</header>
<div name="button_box" position="inside">
<field name="show_on_hand_qty_status_button" invisible="1"/>
@@ -22,6 +22,11 @@
<field name="height" placeholder="Height"/>
<span><field name="length_uom_name" help="Size: Length &#215; Width &#215; Height"/></span>
</div>
<label for="base_weight"/>
<div class="o_row" name="base_weight">
<field name="base_weight"/>
<span><field name="weight_uom_name"/></span>
</div>
<label for="max_weight"/>
<div class="o_row" name="max_weight">
<field name="max_weight"/>
+9 -1
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
from odoo import api, fields, models, _
from odoo.tools.float_utils import float_is_zero
from odoo.tools.misc import groupby
@@ -71,6 +71,14 @@ class StockQuant(models.Model):
else:
super(StockQuant, inventories)._apply_inventory()
def _get_inventory_move_values(self, qty, location_id, location_dest_id, out=False):
res_move = super()._get_inventory_move_values(qty, location_id, location_dest_id, out)
if not self.env.context.get('inventory_name'):
force_period_date = self.env.context.get('force_period_date', False)
if force_period_date:
res_move['name'] += _(' [Accounted on %s]', force_period_date)
return res_move
@api.model
def _get_inventory_fields_write(self):
""" Returns a list of fields user can edit when editing a quant in `inventory_mode`."""
@@ -24,9 +24,4 @@
<field name="company_id" eval="False"/>
</record>
<!-- Update existing picking types to include autobatch settings for incoming/outgoing -->
<function model="stock.picking.type" name="write">
<value model="stock.picking.type" eval="obj().search([('code', 'in', ['incoming', 'outgoing'])]).ids"/>
<value eval="{'auto_batch': True, 'batch_group_by_partner': True}"/>
</function>
</data></odoo>
@@ -11,7 +11,7 @@
</header>
</xpath>
<xpath expr="//field[@name='picking_id']" position="after">
<field name="batch_id" optional="hide"/>
<field name="batch_id" optional="show"/>
</xpath>
</field>
</record>