[IMP] stock: Convert yml file to python and xml
This commit is contained in:
@@ -11,14 +11,13 @@
|
||||
'category': 'Warehouse',
|
||||
'sequence': 13,
|
||||
'demo': [
|
||||
'data/stock_demo_pre.yml',
|
||||
'data/stock_demo_pre.xml',
|
||||
'data/procurement_demo.xml',
|
||||
'data/stock_demo.xml',
|
||||
'data/stock_orderpoint_demo.xml',
|
||||
'data/stock_orderpoint_demo.yml',
|
||||
'data/stock_demo.yml',
|
||||
'data/stock_demo2.xml',
|
||||
'data/stock_location_demo_cpu1.xml',
|
||||
'data/stock_location_demo_cpu3.yml',
|
||||
'data/stock_location_demo_cpu3.xml',
|
||||
'data/stock_quant_demo.xml',
|
||||
],
|
||||
'data': [
|
||||
@@ -66,20 +65,12 @@
|
||||
|
||||
'data/default_barcode_patterns.xml',
|
||||
'data/stock_data.xml',
|
||||
'data/stock_data.yml',
|
||||
'data/stock_incoterms_data.xml',
|
||||
'data/stock_sequence_data.xml',
|
||||
],
|
||||
'qweb': [
|
||||
'static/src/xml/stock_traceability_report_backend.xml',
|
||||
],
|
||||
'test': [
|
||||
'test/stock_users.yml',
|
||||
'test/packing.yml',
|
||||
'test/packingneg.yml',
|
||||
'test/procrule.yml',
|
||||
'test/wiseoperator.yml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': True,
|
||||
'auto_install': False,
|
||||
|
||||
@@ -143,5 +143,109 @@
|
||||
<field name="number_increment">1</field>
|
||||
</record>
|
||||
|
||||
<record id="base.main_partner" model="res.partner">
|
||||
<field name="property_stock_customer" model="stock.warehouse"
|
||||
eval="obj().env.ref('stock.warehouse0').lot_stock_id.id"/>
|
||||
</record>
|
||||
|
||||
<!-- create xml ids for demo data that are widely used in tests or in other codes, for more convenience -->
|
||||
<function model="ir.model.data" name="create">
|
||||
<value model="stock.warehouse" eval="{
|
||||
'name': 'stock_location_stock',
|
||||
'module':'stock',
|
||||
'model': 'stock.location',
|
||||
'res_id': obj().env.ref('stock.warehouse0').lot_stock_id.id,
|
||||
}"/>
|
||||
</function>
|
||||
<function model="ir.model.data" name="create">
|
||||
<value model="stock.warehouse" eval="{
|
||||
'name': 'stock_location_company',
|
||||
'module':'stock',
|
||||
'model': 'stock.location',
|
||||
'res_id': obj().env.ref('stock.warehouse0').wh_input_stock_loc_id.id,
|
||||
}"/>
|
||||
</function>
|
||||
<function model="ir.model.data" name="create">
|
||||
<value model="stock.warehouse" eval="{
|
||||
'name': 'stock_location_output',
|
||||
'module':'stock',
|
||||
'model': 'stock.location',
|
||||
'res_id': obj().env.ref('stock.warehouse0').wh_output_stock_loc_id.id,
|
||||
}"/>
|
||||
</function>
|
||||
<function model="ir.model.data" name="create">
|
||||
<value model="stock.warehouse" eval="{
|
||||
'name': 'location_pack_zone',
|
||||
'module':'stock',
|
||||
'model': 'stock.location',
|
||||
'res_id': obj().env.ref('stock.warehouse0').wh_pack_stock_loc_id.id,
|
||||
}"/>
|
||||
</function>
|
||||
<function model="ir.model.data" name="create">
|
||||
<value model="stock.warehouse" eval="{
|
||||
'name': 'picking_type_internal',
|
||||
'module':'stock',
|
||||
'model': 'stock.picking.type',
|
||||
'res_id': obj().env.ref('stock.warehouse0').int_type_id.id,
|
||||
}"/>
|
||||
</function>
|
||||
<function model="ir.model.data" name="create">
|
||||
<value model="stock.warehouse" eval="{
|
||||
'name': 'picking_type_in',
|
||||
'module':'stock',
|
||||
'model': 'stock.picking.type',
|
||||
'res_id': obj().env.ref('stock.warehouse0').in_type_id.id,
|
||||
}"/>
|
||||
</function>
|
||||
<function model="ir.model.data" name="create">
|
||||
<value model="stock.warehouse" eval="{
|
||||
'name': 'picking_type_out',
|
||||
'module':'stock',
|
||||
'model': 'stock.picking.type',
|
||||
'res_id': obj().env.ref('stock.warehouse0').out_type_id.id,
|
||||
}"/>
|
||||
</function>
|
||||
|
||||
<!-- avoid the xml id and the associated resource being dropped by the orm by manually making a hit on it -->
|
||||
<function model="ir.model.data" name="_update_dummy">
|
||||
<value>stock.location</value>
|
||||
<value>stock</value>
|
||||
<value>stock_location_stock</value>
|
||||
</function>
|
||||
<function model="ir.model.data" name="_update_dummy">
|
||||
<value>stock.location</value>
|
||||
<value>stock</value>
|
||||
<value>stock_location_company</value>
|
||||
</function>
|
||||
<function model="ir.model.data" name="_update_dummy">
|
||||
<value>stock.location</value>
|
||||
<value>stock</value>
|
||||
<value>stock_location_output</value>
|
||||
</function>
|
||||
<function model="ir.model.data" name="_update_dummy">
|
||||
<value>stock.location</value>
|
||||
<value>stock</value>
|
||||
<value>location_pack_zone</value>
|
||||
</function>
|
||||
<function model="ir.model.data" name="_update_dummy">
|
||||
<value>stock.picking.type</value>
|
||||
<value>stock</value>
|
||||
<value>picking_type_internal</value>
|
||||
</function>
|
||||
<function model="ir.model.data" name="_update_dummy">
|
||||
<value>stock.picking.type</value>
|
||||
<value>stock</value>
|
||||
<value>picking_type_in</value>
|
||||
</function>
|
||||
<function model="ir.model.data" name="_update_dummy">
|
||||
<value>stock.picking.type</value>
|
||||
<value>stock</value>
|
||||
<value>picking_type_out</value>
|
||||
</function>
|
||||
|
||||
<!-- create the transit location for each company existing -->
|
||||
<function model="res.company" name="create_transit_location">
|
||||
<value model="res.company" eval="obj().search([('internal_transit_location_id', '=', False)]).ids"/>
|
||||
</function>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
-
|
||||
!python {model: res.partner, id: base.main_partner}: |
|
||||
main_warehouse = self.env['stock.warehouse'].browse(ref('warehouse0'))
|
||||
self.write({'property_stock_customer':main_warehouse.lot_stock_id.id})
|
||||
|
||||
-
|
||||
!python {model: ir.model.data, id: False}: |
|
||||
main_warehouse = self.env['stock.warehouse'].browse(ref('warehouse0'))
|
||||
|
||||
#create xml ids for demo data that are widely used in tests or in other codes, for more convenience
|
||||
xml_references = [
|
||||
{'name': 'stock_location_stock', 'module': 'stock', 'model': 'stock.location', 'res_id': main_warehouse.lot_stock_id.id},
|
||||
{'name': 'stock_location_company', 'module': 'stock', 'model': 'stock.location', 'res_id': main_warehouse.wh_input_stock_loc_id.id},
|
||||
{'name':'stock_location_output','module':'stock', 'model':'stock.location','res_id':main_warehouse.wh_output_stock_loc_id.id},
|
||||
{'name':'location_pack_zone','module':'stock', 'model':'stock.location','res_id':main_warehouse.wh_pack_stock_loc_id.id},
|
||||
{'name':'picking_type_internal','module':'stock', 'model':'stock.picking.type','res_id':main_warehouse.int_type_id.id},
|
||||
{'name':'picking_type_in','module':'stock', 'model':'stock.picking.type','res_id':main_warehouse.in_type_id.id},
|
||||
{'name':'picking_type_out','module':'stock', 'model':'stock.picking.type','res_id':main_warehouse.out_type_id.id},
|
||||
]
|
||||
for xml_record in xml_references:
|
||||
xml_ids = self.search([('module', '=', xml_record['module']), ('model', '=', xml_record['model']), ('name', '=', xml_record['name'])]).ids
|
||||
if not xml_ids:
|
||||
self.create(xml_record)
|
||||
#avoid the xml id and the associated resource being dropped by the orm by manually making a hit on it
|
||||
self._update_dummy(xml_record['model'], xml_record['module'], xml_record['name'])
|
||||
|
||||
-
|
||||
!python {model: res.company, id: False}: |
|
||||
#create the transit location for each company existing
|
||||
companies = self.search([('internal_transit_location_id', '=', False)])
|
||||
for company in companies:
|
||||
company.create_transit_location()
|
||||
|
||||
@@ -1,354 +0,0 @@
|
||||
-
|
||||
!python {model: ir.model.data, id: False}: |
|
||||
chicago_warehouse = self.env['stock.warehouse'].browse(ref('stock_warehouse_shop0'))
|
||||
|
||||
#create xml ids for demo data that are widely used in tests or in other codes, for more convenience
|
||||
xml_references = [
|
||||
{'name':'chi_picking_type_in','module':'stock', 'model':'stock.picking.type','res_id': chicago_warehouse.in_type_id.id},
|
||||
{'name':'chi_picking_type_out','module':'stock', 'model':'stock.picking.type','res_id': chicago_warehouse.out_type_id.id},
|
||||
{'name':'stock_location_shop0','module':'stock', 'model':'stock.location','res_id': chicago_warehouse.lot_stock_id.id},
|
||||
]
|
||||
for xml_record in xml_references:
|
||||
xml_ids = self.search([('module', '=', xml_record['module']), ('model', '=', xml_record['model']), ('name', '=', xml_record['name'])]).ids
|
||||
if not xml_ids:
|
||||
self.create(xml_record)
|
||||
#avoid the xml id and the associated resource being dropped by the orm by manually making a hit on it
|
||||
self._update_dummy(xml_record['model'], xml_record['module'], xml_record['name'])
|
||||
-
|
||||
!record {model: stock.location, id: location_refrigerator_small}:
|
||||
name: Small Refrigerator
|
||||
usage: internal
|
||||
location_id: stock_location_14
|
||||
-
|
||||
!record {model: product.product, id: product_icecream}:
|
||||
default_code: 001
|
||||
name: Ice Cream
|
||||
type: product
|
||||
categ_id: product.product_category_1
|
||||
lst_price: 100.0
|
||||
standard_price: 70.0
|
||||
weight: 1.0
|
||||
uom_id: product.product_uom_kgm
|
||||
property_stock_inventory: location_inventory
|
||||
description: Ice cream can be mass-produced and thus is widely available in developed parts of the world. Ice cream can be purchased in large cartons (vats and squrounds) from supermarkets and grocery stores, in smaller quantities from ice cream shops, convenience stores, and milk bars, and in individual servings from small carts or vans at public events.
|
||||
-
|
||||
!record {model: stock.production.lot, id: lot_icecream_0}:
|
||||
name: '0000000000017'
|
||||
product_id: product_icecream
|
||||
-
|
||||
!record {model: stock.production.lot, id: lot_icecream_1}:
|
||||
name: '0000000000024'
|
||||
product_id: product_icecream
|
||||
-
|
||||
!record {model: stock.inventory, id: stock_inventory_icecream}:
|
||||
name: Inventory for icecream
|
||||
filter: 'product'
|
||||
product_id: product_icecream
|
||||
-
|
||||
!record {model: stock.inventory.line, id: stock_inventory_line_icecream_lot0}:
|
||||
product_id: product_icecream
|
||||
product_uom_id: product.product_uom_kgm
|
||||
inventory_id: stock_inventory_icecream
|
||||
product_qty: 50.0
|
||||
prod_lot_id: lot_icecream_0
|
||||
location_id: stock_location_14
|
||||
-
|
||||
!record {model: stock.inventory.line, id: stock_inventory_line_icecream_lot1}:
|
||||
product_id: product_icecream
|
||||
product_uom_id: product.product_uom_kgm
|
||||
inventory_id: stock_inventory_icecream
|
||||
product_qty: 40.0
|
||||
prod_lot_id: lot_icecream_1
|
||||
location_id: stock_location_14
|
||||
-
|
||||
Create STOCK_MOVE for OUT
|
||||
-
|
||||
!record {model: stock.picking, id: outgoing_shipment_main_warehouse}:
|
||||
picking_type_id: stock.picking_type_out
|
||||
origin: 'outgoing shipment main_warehouse'
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_stock
|
||||
location_dest_id: stock.stock_location_customers
|
||||
move_lines:
|
||||
- product_id: product.product_product_27
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 15.0
|
||||
picking_type_id: stock.picking_type_out
|
||||
location_id: stock.stock_location_stock
|
||||
location_dest_id: stock.stock_location_customers
|
||||
-
|
||||
!record {model: stock.picking, id: outgoing_shipment_main_warehouse1}:
|
||||
picking_type_id: stock.picking_type_out
|
||||
origin: 'outgoing shipment'
|
||||
partner_id: base.res_partner_1
|
||||
date: !eval "'%s-%s-15' %((datetime.now()-timedelta(days=60)).year, (datetime.now()-timedelta(days=60)).month)"
|
||||
location_id: stock.stock_location_stock
|
||||
location_dest_id: stock.stock_location_customers
|
||||
move_lines:
|
||||
- product_id: product.product_product_6
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 180.0
|
||||
picking_type_id: stock.picking_type_out
|
||||
location_id: stock.stock_location_stock
|
||||
location_dest_id: stock.stock_location_customers
|
||||
move_line_ids:
|
||||
- product_id: product.product_product_6
|
||||
qty_done: 100
|
||||
product_uom_id: product.product_uom_unit
|
||||
location_id: stock.stock_location_stock
|
||||
location_dest_id: stock.stock_location_customers
|
||||
-
|
||||
!record {model: stock.picking, id: outgoing_shipment_main_warehouse2}:
|
||||
picking_type_id: stock.picking_type_out
|
||||
origin: 'outgoing shipment your_company warehouse'
|
||||
partner_id: base.res_partner_1
|
||||
date: !eval "'%s-%s-15' % ((datetime.now()-timedelta(days=30)).month,(datetime.now()-timedelta(days=30)).month)"
|
||||
location_id: stock.stock_location_stock
|
||||
location_dest_id: stock.stock_location_customers
|
||||
move_lines:
|
||||
- product_id: product.product_delivery_02
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 45.0
|
||||
picking_type_id: stock.picking_type_out
|
||||
location_id: stock.stock_location_stock
|
||||
location_dest_id: stock.stock_location_customers
|
||||
-
|
||||
!record {model: stock.picking, id: outgoing_shipment_main_warehouse3}:
|
||||
picking_type_id: stock.picking_type_out
|
||||
origin: 'your company warehouse'
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_stock
|
||||
location_dest_id: stock.stock_location_customers
|
||||
move_lines:
|
||||
- product_id: product.product_product_5
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 75.0
|
||||
picking_type_id: stock.picking_type_out
|
||||
location_id: stock.stock_location_stock
|
||||
location_dest_id: stock.stock_location_customers
|
||||
-
|
||||
Create STOCK_PICKING for IN
|
||||
-
|
||||
!record {model: stock.picking, id: incomming_shipment}:
|
||||
picking_type_id: stock.picking_type_in
|
||||
location_id: stock_location_suppliers
|
||||
location_dest_id: stock_location_stock
|
||||
-
|
||||
!record {model: stock.move, id: incomming_shipment_icecream}:
|
||||
product_id: product_icecream
|
||||
product_uom: product.product_uom_kgm
|
||||
product_uom_qty: 50.0
|
||||
picking_type_id: stock.picking_type_in
|
||||
location_id: stock_location_suppliers
|
||||
location_dest_id: stock_location_stock
|
||||
picking_id: incomming_shipment
|
||||
-
|
||||
!record {model: stock.picking, id: incomming_shipment1}:
|
||||
picking_type_id: stock.picking_type_in
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_stock
|
||||
move_lines:
|
||||
- product_id: product.product_delivery_01
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 35.0
|
||||
picking_type_id: stock.picking_type_in
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_stock
|
||||
-
|
||||
!record {model: stock.picking, id: incomming_shipment2}:
|
||||
picking_type_id: stock.picking_type_in
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_stock
|
||||
move_lines:
|
||||
- product_id: product.product_product_22
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 125.0
|
||||
picking_type_id: stock.picking_type_in
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_stock
|
||||
-
|
||||
!record {model: stock.picking, id: incomming_shipment3}:
|
||||
picking_type_id: stock.picking_type_in
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_stock
|
||||
move_lines:
|
||||
- product_id: product.product_product_10
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 120.0
|
||||
picking_type_id: stock.picking_type_in
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_stock
|
||||
-
|
||||
!record {model: stock.picking, id: incomming_shipment4}:
|
||||
picking_type_id: stock.picking_type_in
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_stock
|
||||
move_lines:
|
||||
- product_id: product.product_delivery_02
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 50.0
|
||||
picking_type_id: stock.picking_type_in
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_stock
|
||||
-
|
||||
Create STOCK_PICKING_IN for Chicago Warehouse
|
||||
-
|
||||
!record {model: stock.picking, id: incomming_chicago_warehouse}:
|
||||
picking_type_id: chi_picking_type_in
|
||||
origin: 'incoming_chicago_warehouse'
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_shop0
|
||||
move_lines:
|
||||
- product_id: product.product_product_9
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 25.0
|
||||
picking_type_id: chi_picking_type_in
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_shop0
|
||||
|
||||
-
|
||||
!record {model: stock.picking, id: incomming_chicago_warehouse1}:
|
||||
picking_type_id: chi_picking_type_in
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_shop0
|
||||
move_lines:
|
||||
- product_id: product.product_delivery_01
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 180.0
|
||||
picking_type_id: chi_picking_type_in
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_shop0
|
||||
state: done
|
||||
move_line_ids:
|
||||
- product_id: product.product_delivery_01
|
||||
qty_done: 100
|
||||
product_uom_id: product.product_uom_unit
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_shop0
|
||||
-
|
||||
!record {model: stock.picking, id: incomming_chicago_warehouse2}:
|
||||
picking_type_id: chi_picking_type_in
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_shop0
|
||||
move_lines:
|
||||
- product_id: product.product_delivery_01
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 45.0
|
||||
picking_type_id: chi_picking_type_in
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_shop0
|
||||
-
|
||||
!record {model: stock.picking, id: incomming_chicago_warehouse3}:
|
||||
picking_type_id: chi_picking_type_in
|
||||
origin: 'chicago_warehouse'
|
||||
partner_id: base.res_partner_1
|
||||
date: !eval "'%s-%s-2' % ((datetime.now()-timedelta(days=30)).month,(datetime.now()-timedelta(days=30)).month)"
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_shop0
|
||||
move_lines:
|
||||
- product_id: product.product_product_22
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 75.0
|
||||
picking_type_id: chi_picking_type_in
|
||||
location_id: stock.stock_location_suppliers
|
||||
location_dest_id: stock.stock_location_shop0
|
||||
-
|
||||
Create STOCK_PICKING_OUT for Chicago Warehouse
|
||||
-
|
||||
!record {model: stock.picking, id: outgoing_chicago_warehouse}:
|
||||
picking_type_id: chi_picking_type_out
|
||||
origin: 'outgoing_chicago_warehouse'
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_shop0
|
||||
location_dest_id: stock.stock_location_customers
|
||||
move_lines:
|
||||
- product_id: product.product_product_27
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 15.0
|
||||
picking_type_id: chi_picking_type_out
|
||||
location_id: stock.stock_location_shop0
|
||||
location_dest_id: stock.stock_location_customers
|
||||
-
|
||||
!record {model: stock.picking, id: outgoing_chicago_warehouse1}:
|
||||
picking_type_id: chi_picking_type_out
|
||||
origin: 'outgoing_shipment_chicago_warehouse'
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_shop0
|
||||
location_dest_id: stock.stock_location_customers
|
||||
move_lines:
|
||||
- product_id: product.product_product_6
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 180.0
|
||||
picking_type_id: chi_picking_type_out
|
||||
location_id: stock.stock_location_shop0
|
||||
location_dest_id: stock.stock_location_customers
|
||||
move_line_ids:
|
||||
- product_id: product.product_product_6
|
||||
qty_done: 100
|
||||
product_uom_id: product.product_uom_unit
|
||||
location_id: stock.stock_location_shop0
|
||||
location_dest_id: stock.stock_location_customers
|
||||
-
|
||||
!record {model: stock.picking, id: outgoing_chicago_warehouse2}:
|
||||
picking_type_id: chi_picking_type_out
|
||||
origin: 'chicago_warehouse'
|
||||
partner_id: base.res_partner_1
|
||||
location_id: stock.stock_location_shop0
|
||||
location_dest_id: stock.stock_location_customers
|
||||
move_lines:
|
||||
- product_id: product.product_delivery_02
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 45.0
|
||||
picking_type_id: chi_picking_type_out
|
||||
location_id: stock.stock_location_shop0
|
||||
location_dest_id: stock.stock_location_customers
|
||||
-
|
||||
!record {model: stock.picking, id: outgoing_chicago_warehouse3}:
|
||||
picking_type_id: chi_picking_type_out
|
||||
origin: 'outgoing chicago warehouse'
|
||||
location_id: stock.stock_location_shop0
|
||||
location_dest_id: stock.stock_location_customers
|
||||
partner_id: base.res_partner_1
|
||||
move_lines:
|
||||
- product_id: product.product_product_5
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 75.0
|
||||
picking_type_id: chi_picking_type_out
|
||||
location_id: stock.stock_location_shop0
|
||||
location_dest_id: stock.stock_location_customers
|
||||
-
|
||||
!python {model: stock.picking, id: False}: |
|
||||
self.browse([
|
||||
ref('outgoing_shipment_main_warehouse'),
|
||||
ref('outgoing_shipment_main_warehouse1'),
|
||||
ref('incomming_shipment2'),
|
||||
ref('incomming_shipment1'),
|
||||
ref('incomming_shipment3'),
|
||||
ref('outgoing_chicago_warehouse3'),
|
||||
ref('outgoing_chicago_warehouse2'),
|
||||
ref('outgoing_chicago_warehouse1'),
|
||||
ref('incomming_chicago_warehouse1'),
|
||||
ref('incomming_chicago_warehouse2'),
|
||||
ref('incomming_chicago_warehouse3')
|
||||
]).action_confirm()
|
||||
record = self.browse(ref('outgoing_shipment_main_warehouse1'))
|
||||
record_chi_in = self.browse(ref('incomming_chicago_warehouse1'))
|
||||
record_chi_out = self.browse(ref('outgoing_chicago_warehouse1'))
|
||||
if record.state != 'done' and record_chi_in.state != 'done' and record_chi_out.state != 'done':
|
||||
self.browse([
|
||||
ref('outgoing_shipment_main_warehouse'),
|
||||
ref('outgoing_chicago_warehouse3'),
|
||||
ref('outgoing_shipment_main_warehouse2')
|
||||
]).force_assign()
|
||||
self.browse([
|
||||
ref('outgoing_shipment_main_warehouse1'),
|
||||
ref('incomming_chicago_warehouse1'),
|
||||
ref('outgoing_chicago_warehouse1')
|
||||
]).do_transfer()
|
||||
@@ -0,0 +1,449 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- create xml ids for demo data that are widely used in tests or in other codes, for more convenience -->
|
||||
<function model="ir.model.data" name="create">
|
||||
<value model="stock.warehouse" eval="{
|
||||
'name': 'chi_picking_type_in',
|
||||
'module':'stock',
|
||||
'model': 'stock.picking.type',
|
||||
'res_id': obj().env.ref('stock.stock_warehouse_shop0').in_type_id.id,
|
||||
}"/>
|
||||
</function>
|
||||
<function model="ir.model.data" name="create">
|
||||
<value model="stock.warehouse" eval="{
|
||||
'name': 'chi_picking_type_out',
|
||||
'module':'stock',
|
||||
'model': 'stock.picking.type',
|
||||
'res_id': obj().env.ref('stock.stock_warehouse_shop0').out_type_id.id,
|
||||
}"/>
|
||||
</function>
|
||||
<function model="ir.model.data" name="create">
|
||||
<value model="stock.warehouse" eval="{
|
||||
'name': 'stock_location_shop0',
|
||||
'module':'stock',
|
||||
'model': 'stock.picking.type',
|
||||
'res_id': obj().env.ref('stock.stock_warehouse_shop0').lot_stock_id.id,
|
||||
}"/>
|
||||
</function>
|
||||
<!-- avoid the xml id and the associated resource being dropped by the orm by manually making a hit on it -->
|
||||
<function model="ir.model.data" name="_update_dummy">
|
||||
<value>stock.picking.type</value>
|
||||
<value>stock</value>
|
||||
<value>chi_picking_type_in</value>
|
||||
</function>
|
||||
<function model="ir.model.data" name="_update_dummy">
|
||||
<value>stock.picking.type</value>
|
||||
<value>stock</value>
|
||||
<value>chi_picking_type_out</value>
|
||||
</function>
|
||||
<function model="ir.model.data" name="_update_dummy">
|
||||
<value>stock.picking.type</value>
|
||||
<value>stock</value>
|
||||
<value>stock_location_shop0</value>
|
||||
</function>
|
||||
|
||||
<record id="location_refrigerator_small" model="stock.location">
|
||||
<field name="name">Small Refrigerator</field>
|
||||
<field name="usage">internal</field>
|
||||
<field name="location_id" ref="stock.stock_location_14"/>
|
||||
</record>
|
||||
|
||||
<record id="product_icecream" model="product.product">
|
||||
<field name="default_code">001</field>
|
||||
<field name="name">Ice Cream</field>
|
||||
<field name="type">product</field>
|
||||
<field name="categ_id" ref="product.product_category_1"/>
|
||||
<field name="lst_price">100.0</field>
|
||||
<field name="standard_price">70.0</field>
|
||||
<field name="weight">1.0</field>
|
||||
<field name="uom_id" ref="product.product_uom_kgm"/>
|
||||
<field name="uom_po_id" ref="product.product_uom_kgm"/>
|
||||
<field name="property_stock_inventory" ref="stock.location_inventory"/>
|
||||
<field name="description">
|
||||
Ice cream can be mass-produced and thus is widely available in developed parts
|
||||
of the world. Ice cream can be purchased in large cartons (vats and squrounds)
|
||||
from supermarkets and grocery stores, in smaller quantities from ice cream shops,
|
||||
convenience stores, and milk bars, and in individual servings from small carts or
|
||||
vans at public events.
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="lot_icecream_0" model="stock.production.lot">
|
||||
<field name="name">0000000000017</field>
|
||||
<field name="product_id" ref="stock.product_icecream"/>
|
||||
</record>
|
||||
|
||||
<record id="lot_icecream_1" model="stock.production.lot">
|
||||
<field name="name">0000000000024</field>
|
||||
<field name="product_id" ref="stock.product_icecream"/>
|
||||
</record>
|
||||
|
||||
<record id="stock_inventory_icecream" model="stock.inventory">
|
||||
<field name="name">Inventory for icecream</field>
|
||||
<field name="filter">product</field>
|
||||
<field name="product_id" ref="stock.product_icecream"/>
|
||||
</record>
|
||||
|
||||
<record id="stock_inventory_line_icecream_lot0" model="stock.inventory.line">
|
||||
<field name="product_id" ref="stock.product_icecream"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_kgm"/>
|
||||
<field name="inventory_id" ref="stock.stock_inventory_icecream"/>
|
||||
<field name="product_qty">50.0</field>
|
||||
<field name="prod_lot_id" ref="stock.lot_icecream_0"/>
|
||||
<field name="location_id" ref="stock.stock_location_14"/>
|
||||
</record>
|
||||
|
||||
<record id="stock_inventory_line_icecream_lot1" model="stock.inventory.line">
|
||||
<field name="product_id" ref="stock.product_icecream"/>
|
||||
<field name="product_uom_id" ref="product.product_uom_kgm"/>
|
||||
<field name="inventory_id" ref="stock.stock_inventory_icecream"/>
|
||||
<field name="product_qty">40.0</field>
|
||||
<field name="prod_lot_id" ref="stock.lot_icecream_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_14"/>
|
||||
</record>
|
||||
|
||||
<!-- Create STOCK_MOVE for OUT -->
|
||||
<record id="outgoing_shipment_main_warehouse" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.picking_type_out"/>
|
||||
<field name="origin">outgoing shipment main_warehouse</field>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_stock"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_customers"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_product_27').name,
|
||||
'product_id': ref('product.product_product_27'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 15.0,
|
||||
'picking_type_id': ref('stock.picking_type_out'),
|
||||
'location_id': ref('stock.stock_location_stock'),
|
||||
'location_dest_id': ref('stock.stock_location_customers'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="outgoing_shipment_main_warehouse1" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.picking_type_out"/>
|
||||
<field name="origin">outgoing shipment</field>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="date" eval="'%s-%s-15' %((datetime.now()-timedelta(days=60)).year, (datetime.now()-timedelta(days=60)).month)"/>
|
||||
<field name="location_id" ref="stock.stock_location_stock"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_customers"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_product_6').name,
|
||||
'product_id': ref('product.product_product_6'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 180.0,
|
||||
'picking_type_id': ref('stock.picking_type_out'),
|
||||
'location_id': ref('stock.stock_location_stock'),
|
||||
'location_dest_id': ref('stock.stock_location_customers'),
|
||||
'move_line_ids': [(0, 0, {
|
||||
'product_id': ref('product.product_product_6'),
|
||||
'qty_done': 100,
|
||||
'product_uom_id': ref('product.product_uom_unit'),
|
||||
'location_id': ref('stock.stock_location_stock'),
|
||||
'location_dest_id': ref('stock.stock_location_customers'),
|
||||
})],
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="outgoing_shipment_main_warehouse2" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.picking_type_out"/>
|
||||
<field name="origin">outgoing shipment your_company warehouse</field>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="date" eval="'%s-%s-15' % ((datetime.now()-timedelta(days=30)).month,(datetime.now()-timedelta(days=30)).month)"/>
|
||||
<field name="location_id" ref="stock.stock_location_stock"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_customers"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_delivery_02').name,
|
||||
'product_id': ref('product.product_delivery_02'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 45.0,
|
||||
'picking_type_id': ref('stock.picking_type_out'),
|
||||
'location_id': ref('stock.stock_location_stock'),
|
||||
'location_dest_id': ref('stock.stock_location_customers'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="outgoing_shipment_main_warehouse3" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.picking_type_out"/>
|
||||
<field name="origin">your company warehouse</field>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_stock"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_customers"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_product_5').name,
|
||||
'product_id': ref('product.product_product_5'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 75.0,
|
||||
'picking_type_id': ref('stock.picking_type_out'),
|
||||
'location_id': ref('stock.stock_location_stock'),
|
||||
'location_dest_id': ref('stock.stock_location_customers'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<!-- Create STOCK_PICKING for IN -->
|
||||
<record id="incomming_shipment" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.picking_type_in"/>
|
||||
<field name="location_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_stock"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('stock.product_icecream').name,
|
||||
'product_id': ref('stock.product_icecream'),
|
||||
'product_uom': ref('product.product_uom_kgm'),
|
||||
'product_uom_qty': 50.0,
|
||||
'picking_type_id': ref('stock.picking_type_in'),
|
||||
'location_id': ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock.stock_location_stock'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="incomming_shipment1" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.picking_type_in"/>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_stock"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_delivery_01').name,
|
||||
'product_id': ref('product.product_delivery_01'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 35.0,
|
||||
'picking_type_id': ref('stock.picking_type_in'),
|
||||
'location_id': ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock.stock_location_stock'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="incomming_shipment2" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.picking_type_in"/>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_stock"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_product_22').name,
|
||||
'product_id': ref('product.product_product_22'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 125.0,
|
||||
'picking_type_id': ref('stock.picking_type_in'),
|
||||
'location_id': ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock.stock_location_stock'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="incomming_shipment3" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.picking_type_in"/>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_stock"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_product_10').name,
|
||||
'product_id': ref('product.product_product_10'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 120.0,
|
||||
'picking_type_id': ref('stock.picking_type_in'),
|
||||
'location_id': ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock.stock_location_stock'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="incomming_shipment4" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.picking_type_in"/>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_stock"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_delivery_02').name,
|
||||
'product_id': ref('product.product_delivery_02'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 50.0,
|
||||
'picking_type_id': ref('stock.picking_type_in'),
|
||||
'location_id': ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock.stock_location_stock'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<!-- Create STOCK_PICKING_IN for Chicago Warehouse -->
|
||||
<record id="incomming_chicago_warehouse" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.chi_picking_type_in"/>
|
||||
<field name="origin">incoming_chicago_warehouse</field>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_shop0"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_product_9').name,
|
||||
'product_id': ref('product.product_product_9'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 25.0,
|
||||
'picking_type_id': ref('stock.chi_picking_type_in'),
|
||||
'location_id': ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock.stock_location_shop0'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="incomming_chicago_warehouse1" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.chi_picking_type_in"/>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_shop0"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_delivery_01').name,
|
||||
'product_id': ref('product.product_delivery_01'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 180.0,
|
||||
'picking_type_id': ref('stock.chi_picking_type_in'),
|
||||
'location_id': ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock.stock_location_shop0'),
|
||||
'move_line_ids': [(0, 0, {
|
||||
'product_id': ref('product.product_delivery_01'),
|
||||
'qty_done': 100,
|
||||
'product_uom_id': ref('product.product_uom_unit'),
|
||||
'location_id': ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock.stock_location_shop0'),
|
||||
})],
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="incomming_chicago_warehouse2" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.chi_picking_type_in"/>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_shop0"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_delivery_01').name,
|
||||
'product_id': ref('product.product_delivery_01'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 45.0,
|
||||
'picking_type_id': ref('stock.chi_picking_type_in'),
|
||||
'location_id': ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock.stock_location_shop0'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="incomming_chicago_warehouse3" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.chi_picking_type_in"/>
|
||||
<field name="origin">chicago_warehouse</field>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="date" eval="'%s-%s-2' % ((datetime.now()-timedelta(days=30)).month,(datetime.now()-timedelta(days=30)).month)"/>
|
||||
<field name="location_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_shop0"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_product_22').name,
|
||||
'product_id': ref('product.product_product_22'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 75.0,
|
||||
'picking_type_id': ref('stock.chi_picking_type_in'),
|
||||
'location_id': ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock.stock_location_shop0'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<!-- Create STOCK_PICKING_OUT for Chicago Warehouse -->
|
||||
<record id="outgoing_chicago_warehouse" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.chi_picking_type_out"/>
|
||||
<field name="origin">outgoing_chicago_warehouse</field>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="date" eval="'%s-%s-2' % ((datetime.now()-timedelta(days=30)).month,(datetime.now()-timedelta(days=30)).month)"/>
|
||||
<field name="location_id" ref="stock.stock_location_shop0"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_customers"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_product_27').name,
|
||||
'product_id': ref('product.product_product_27'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 15.0,
|
||||
'picking_type_id': ref('stock.chi_picking_type_out'),
|
||||
'location_id': ref('stock.stock_location_shop0'),
|
||||
'location_dest_id': ref('stock.stock_location_customers'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="outgoing_chicago_warehouse1" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.chi_picking_type_out"/>
|
||||
<field name="origin">outgoing_shipment_chicago_warehouse</field>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="date" eval="'%s-%s-2' % ((datetime.now()-timedelta(days=30)).month,(datetime.now()-timedelta(days=30)).month)"/>
|
||||
<field name="location_id" ref="stock.stock_location_shop0"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_customers"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_product_6').name,
|
||||
'product_id': ref('product.product_product_6'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 180.0,
|
||||
'picking_type_id': ref('stock.chi_picking_type_out'),
|
||||
'location_id': ref('stock.stock_location_shop0'),
|
||||
'location_dest_id': ref('stock.stock_location_customers'),
|
||||
'move_line_ids': [(0, 0, {
|
||||
'product_id': ref('product.product_product_6'),
|
||||
'qty_done': 100,
|
||||
'product_uom_id': ref('product.product_uom_unit'),
|
||||
'location_id': ref('stock.stock_location_shop0'),
|
||||
'location_dest_id': ref('stock.stock_location_customers'),
|
||||
})],
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="outgoing_chicago_warehouse2" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.chi_picking_type_out"/>
|
||||
<field name="origin">chicago_warehouse</field>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="date" eval="'%s-%s-2' % ((datetime.now()-timedelta(days=30)).month,(datetime.now()-timedelta(days=30)).month)"/>
|
||||
<field name="location_id" ref="stock.stock_location_shop0"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_customers"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_delivery_02').name,
|
||||
'product_id': ref('product.product_delivery_02'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 45.0,
|
||||
'picking_type_id': ref('stock.chi_picking_type_out'),
|
||||
'location_id': ref('stock.stock_location_shop0'),
|
||||
'location_dest_id': ref('stock.stock_location_customers'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<record id="outgoing_chicago_warehouse3" model="stock.picking">
|
||||
<field name="picking_type_id" ref="stock.chi_picking_type_out"/>
|
||||
<field name="origin">outgoing chicago warehouse</field>
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="location_id" ref="stock.stock_location_shop0"/>
|
||||
<field name="location_dest_id" ref="stock.stock_location_customers"/>
|
||||
<field name="move_lines" model="stock.move" eval="[(0, 0, {
|
||||
'name': obj().env.ref('product.product_product_5').name,
|
||||
'product_id': ref('product.product_product_5'),
|
||||
'product_uom': ref('product.product_uom_unit'),
|
||||
'product_uom_qty': 75.0,
|
||||
'picking_type_id': ref('stock.chi_picking_type_out'),
|
||||
'location_id': ref('stock.stock_location_shop0'),
|
||||
'location_dest_id': ref('stock.stock_location_customers'),
|
||||
})]"/>
|
||||
</record>
|
||||
|
||||
<function model="stock.picking" name="action_confirm">
|
||||
<value model="stock.picking" eval="[
|
||||
obj().env.ref('stock.outgoing_shipment_main_warehouse').id,
|
||||
obj().env.ref('stock.outgoing_shipment_main_warehouse1').id,
|
||||
obj().env.ref('stock.incomming_shipment2').id,
|
||||
obj().env.ref('stock.incomming_shipment1').id,
|
||||
obj().env.ref('stock.incomming_shipment3').id,
|
||||
obj().env.ref('stock.outgoing_chicago_warehouse3').id,
|
||||
obj().env.ref('stock.outgoing_chicago_warehouse2').id,
|
||||
obj().env.ref('stock.outgoing_chicago_warehouse1').id,
|
||||
obj().env.ref('stock.incomming_chicago_warehouse1').id,
|
||||
obj().env.ref('stock.incomming_chicago_warehouse2').id,
|
||||
obj().env.ref('stock.incomming_chicago_warehouse3').id]"/>
|
||||
</function>
|
||||
|
||||
<function model="stock.picking" name="force_assign">
|
||||
<value model="stock.picking" eval="[
|
||||
obj().env.ref('stock.outgoing_shipment_main_warehouse').id,
|
||||
obj().env.ref('stock.outgoing_chicago_warehouse3').id,
|
||||
obj().env.ref('stock.outgoing_shipment_main_warehouse2').id]"/>
|
||||
</function>
|
||||
|
||||
<function model="stock.picking" name="do_transfer">
|
||||
<value model="stock.picking" eval="[
|
||||
obj().env.ref('stock.outgoing_shipment_main_warehouse1').id,
|
||||
obj().env.ref('stock.incomming_chicago_warehouse1').id,
|
||||
obj().env.ref('stock.outgoing_chicago_warehouse1').id]"/>
|
||||
</function>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="stock_location_14" model="stock.location">
|
||||
<field name="name">Shelf 2</field>
|
||||
<field name="posx">0</field>
|
||||
<field name="location_id" model="stock.location"
|
||||
eval="obj().env.ref('stock.warehouse0').lot_stock_id.id"/>
|
||||
</record>
|
||||
<record id="stock_location_components" model="stock.location">
|
||||
<field name="name">Shelf 1</field>
|
||||
<field name="posx">0</field>
|
||||
<field name="location_id" model="stock.location"
|
||||
eval="obj().env.ref('stock.warehouse0').lot_stock_id.id"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -1,17 +0,0 @@
|
||||
-
|
||||
!record {model: stock.location, id: stock_location_14}:
|
||||
name: Shelf 2
|
||||
posx: 0
|
||||
|
||||
-
|
||||
!record {model: stock.location, id: stock_location_components}:
|
||||
name: Shelf 1
|
||||
posx: 0
|
||||
|
||||
-
|
||||
!python {model: ir.model.data, id: False}: |
|
||||
main_warehouse = self.env['stock.warehouse'].browse(ref('warehouse0'))
|
||||
self.env['stock.location'].browse([
|
||||
ref('stock_location_14'),
|
||||
ref('stock_location_components')
|
||||
]).write({'location_id':main_warehouse.lot_stock_id.id})
|
||||
@@ -0,0 +1,27 @@
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="location_order" model="stock.location">
|
||||
<field name="name">Order Processing</field>
|
||||
<field name="usage">internal</field>
|
||||
<field name="location_id" ref="stock.stock_location_company"/>
|
||||
</record>
|
||||
|
||||
<record id="location_dispatch_zone" model="stock.location">
|
||||
<field name="name">Dispatch Zone</field>
|
||||
<field name="usage">internal</field>
|
||||
<field name="location_id" ref="stock.location_order"/>
|
||||
</record>
|
||||
|
||||
<record id="location_gate_a" model="stock.location">
|
||||
<field name="name">Gate A</field>
|
||||
<field name="usage">internal</field>
|
||||
<field name="location_id" ref="stock.location_dispatch_zone"/>
|
||||
</record>
|
||||
|
||||
<record id="location_gate_b" model="stock.location">
|
||||
<field name="name">Gate B</field>
|
||||
<field name="usage">internal</field>
|
||||
<field name="location_id" ref="stock.location_dispatch_zone"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -1,20 +0,0 @@
|
||||
-
|
||||
!record {model: stock.location, id: location_order}:
|
||||
name: Order Processing
|
||||
usage: internal
|
||||
location_id: stock.stock_location_company
|
||||
-
|
||||
!record {model: stock.location, id: location_dispatch_zone}:
|
||||
name: Dispatch Zone
|
||||
usage: internal
|
||||
location_id: location_order
|
||||
-
|
||||
!record {model: stock.location, id: location_gate_a}:
|
||||
name: Gate A
|
||||
usage: internal
|
||||
location_id: location_dispatch_zone
|
||||
-
|
||||
!record {model: stock.location, id: location_gate_b}:
|
||||
name: Gate B
|
||||
usage: internal
|
||||
location_id: location_dispatch_zone
|
||||
@@ -9,7 +9,8 @@
|
||||
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
|
||||
<field name="product_id" ref="product.product_delivery_02"/>
|
||||
<!-- <field name="location_id" ref="stock.stock_location_stock"/> -->
|
||||
<field name="location_id" model="stock.location"
|
||||
eval="obj().env.ref('stock.warehouse0').lot_stock_id.id"/>
|
||||
</record>
|
||||
<record id="stock_warehouse_orderpoint_2" model="stock.warehouse.orderpoint">
|
||||
<field name="product_max_qty">12.0</field>
|
||||
@@ -17,7 +18,8 @@
|
||||
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
|
||||
<field name="product_id" ref="product.product_product_20"/>
|
||||
<!-- <field name="location_id" ref="stock.stock_location_stock"/> -->
|
||||
<field name="location_id" model="stock.location"
|
||||
eval="obj().env.ref('stock.warehouse0').lot_stock_id.id"/>
|
||||
</record>
|
||||
<record id="stock_warehouse_orderpoint_5" model="stock.warehouse.orderpoint">
|
||||
<field name="product_max_qty">5.0</field>
|
||||
@@ -25,7 +27,9 @@
|
||||
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
|
||||
<field name="product_id" ref="product.product_delivery_01"/>
|
||||
<!-- <field name="location_id" ref="stock.stock_location_stock"/> -->
|
||||
<field name="location_id" model="stock.location"
|
||||
eval="obj().env.ref('stock.warehouse0').lot_stock_id.id"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -1,6 +0,0 @@
|
||||
-
|
||||
!python {model: stock.location, id: False}: |
|
||||
main_warehouse = self.env['stock.warehouse'].browse(ref('warehouse0'))
|
||||
main_stock = main_warehouse.lot_stock_id.id
|
||||
stowar_ops = self.env['stock.warehouse.orderpoint'].search([])
|
||||
stowar_ops.write({'location_id':main_stock})
|
||||
@@ -1,173 +0,0 @@
|
||||
-
|
||||
Create a new stockable product
|
||||
-
|
||||
!record {model: product.product, id: product1, view: False}:
|
||||
name: Nice product
|
||||
type: product
|
||||
categ_id: product.product_category_1
|
||||
list_price: 100.0
|
||||
standard_price: 70.0
|
||||
seller_ids:
|
||||
- delay: 1
|
||||
name: base.res_partner_2
|
||||
min_qty: 2.0
|
||||
uom_id: product.product_uom_unit
|
||||
uom_po_id: product.product_uom_unit
|
||||
-
|
||||
Create an incoming picking for this product of 300 PCE from suppliers to stock
|
||||
-
|
||||
!record {model: stock.picking, id: pick1}:
|
||||
name: Incoming picking
|
||||
partner_id: base.res_partner_2
|
||||
picking_type_id: picking_type_in
|
||||
move_lines:
|
||||
- product_id: product1
|
||||
product_uom_qty: 300.00
|
||||
location_id: stock_location_suppliers
|
||||
location_dest_id: stock_location_stock
|
||||
-
|
||||
Confirm and assign picking
|
||||
-
|
||||
!python {model: stock.picking, id: pick1}: |
|
||||
self.action_confirm()
|
||||
self.action_assign()
|
||||
-
|
||||
Put 120 pieces on Pallet 1 (package), 120 pieces on Pallet 2 with lot A and 60 pieces on Pallet 3
|
||||
-
|
||||
!python {model: stock.picking, id: pick1}: |
|
||||
#Change quantity of first to 120 and create 2 others quant operations
|
||||
stock_pack = self.env['stock.move.line']
|
||||
stock_quant_pack = self.env['stock.quant.package']
|
||||
#create lot A
|
||||
lot_a = self.env['stock.production.lot'].create({'name': 'Lot A', 'product_id': ref('product1')})
|
||||
#create package
|
||||
package1 = stock_quant_pack.create({'name': 'Pallet 1'})
|
||||
package2 = stock_quant_pack.create({'name': 'Pallet 2'})
|
||||
package3 = stock_quant_pack.create({'name': 'Pallet 3'})
|
||||
#Create package for each line and assign it as result_package_id
|
||||
#create pack operation
|
||||
self.move_line_ids[0].write({'result_package_id': package1.id, 'qty_done': 120})
|
||||
new_pack1 = stock_pack.create({
|
||||
'product_id': ref('product1'),
|
||||
'product_uom_id': ref('product.product_uom_unit'),
|
||||
'picking_id': ref('pick1'),
|
||||
'lot_id': lot_a.id,
|
||||
'qty_done': 120,
|
||||
'result_package_id': package2.id,
|
||||
'location_id': ref('stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock_location_stock')
|
||||
})
|
||||
new_pack2 = stock_pack.create({
|
||||
'product_id': ref('product1'),
|
||||
'product_uom_id': ref('product.product_uom_unit'),
|
||||
'picking_id': ref('pick1'),
|
||||
'result_package_id': package3.id,
|
||||
'qty_done': 60,
|
||||
'location_id': ref('stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock_location_stock')
|
||||
})
|
||||
-
|
||||
Transfer the receipt
|
||||
-
|
||||
!python {model: stock.picking, id: pick1}: |
|
||||
self.action_done()
|
||||
-
|
||||
Check the system created 5 quants one with 120 pieces on pallet 1, one with 120 pieces on pallet 2 with lot A and 60 pieces on pallet 3 in stock
|
||||
and 1 with -180 pieces and another with -120 piece lot A in supplier
|
||||
-
|
||||
!python {model: stock.quant, id: False}: |
|
||||
quants = self.search([('product_id','=',ref('product1'))])
|
||||
assert len(quants.ids) == 5, "The number of quants created is not correct"
|
||||
for quant in quants:
|
||||
if quant.package_id.name == 'Pallet 1':
|
||||
assert quant.quantity == 120, "Should have 120 pieces on pallet 1"
|
||||
elif quant.package_id.name == 'Pallet 2':
|
||||
assert quant.quantity == 120, "Should have 120 pieces on pallet 2"
|
||||
elif quant.package_id.name == 'Pallet 3':
|
||||
assert quant.quantity == 60, "Should have 60 pieces on pallet 3"
|
||||
-
|
||||
Check there is no backorder or extra moves created
|
||||
-
|
||||
!python {model: stock.picking, id: pick1}: |
|
||||
backorder = self.search([('backorder_id', '=', ref('pick1'))])
|
||||
assert not backorder, ""
|
||||
#Check extra moves created
|
||||
assert len(self.move_lines) == 1, ""
|
||||
-
|
||||
Make a delivery order of 300 pieces to the customer
|
||||
-
|
||||
!record {model: stock.picking, id: delivery_order1}:
|
||||
name: outgoing picking
|
||||
partner_id: base.res_partner_4
|
||||
picking_type_id: stock.picking_type_out
|
||||
move_lines:
|
||||
- product_id: product1
|
||||
product_uom_qty: 300.00
|
||||
location_id: stock_location_stock
|
||||
location_dest_id: stock_location_customers
|
||||
-
|
||||
Assign and confirm
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order1}: |
|
||||
self.action_confirm()
|
||||
self.action_assign()
|
||||
-
|
||||
Instead of doing the 300 pieces, you decide to take pallet 1 (do not mention product in operation here) and 20 pieces from lot A and 10 pieces from pallet 3
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order1}: |
|
||||
for rec in self.move_line_ids:
|
||||
if rec.package_id.name == 'Pallet 1':
|
||||
rec.qty_done = 120
|
||||
rec.result_package_id = False
|
||||
if rec.package_id.name == 'Pallet 2':
|
||||
rec.qty_done = 20
|
||||
rec.result_package_id = False
|
||||
if rec.package_id.name == 'Pallet 3':
|
||||
rec.qty_done = 10
|
||||
rec.result_package_id = False
|
||||
-
|
||||
Process this picking
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order1 }: |
|
||||
self.action_done()
|
||||
-
|
||||
Check the quants that you have 100 pieces of pallet 2 and 50 pieces of pallet 3 in stock
|
||||
-
|
||||
!python {model: stock.quant, id: False}: |
|
||||
records = self.search([('product_id','=',ref('product1'))])
|
||||
for rec in records:
|
||||
if rec.package_id.name == 'Pallet 2' and rec.location_id.id == ref('stock_location_stock'):
|
||||
assert rec.quantity == 100, "Should have 100 pieces in stock on pallet 2, got " + str(rec.quantity)
|
||||
elif rec.package_id.name == 'Pallet 3' and rec.location_id.id == ref('stock_location_stock'):
|
||||
assert rec.quantity == 50, "Should have 50 pieces in stock on pallet 3"
|
||||
else:
|
||||
assert rec.location_id.id != ref('stock_location_stock'), "Unrecognized quant in stock"
|
||||
-
|
||||
Check a backorder was created and on that backorder, prepare partial and process backorder
|
||||
-
|
||||
!python {model: stock.picking, id: False}: |
|
||||
backorders = self.search([('backorder_id', '=', ref('delivery_order1'))])
|
||||
assert backorders, "Backorder should have been created"
|
||||
backorders.action_assign()
|
||||
picking = backorders[0]
|
||||
assert len(picking.move_line_ids) == 2, "Wrong number of pack operation"
|
||||
for pack_op in picking.move_line_ids:
|
||||
assert pack_op.package_id.name in ('Pallet 2', 'Pallet 3'), "Wrong pallet info in pack operation (%s found)" % (pack_op.package_id.name)
|
||||
if pack_op.package_id.name == 'Pallet 2':
|
||||
assert pack_op.product_qty == 100
|
||||
pack_op.qty_done = 100
|
||||
elif pack_op.package_id.name == 'Pallet 3':
|
||||
assert pack_op.product_qty == 50
|
||||
pack_op.qty_done = 50
|
||||
backorders.action_done()
|
||||
-
|
||||
Check there are still 0 pieces in stock
|
||||
-
|
||||
!python {model: stock.quant, id: False}: |
|
||||
records = self.search([('product_id','=',ref('product1')), ('location_id', '=', ref('stock_location_stock'))])
|
||||
total_qty = 0
|
||||
for rec in records:
|
||||
total_qty += rec.quantity
|
||||
product = self.env["product.product"].browse(ref('product1'))
|
||||
assert total_qty == 0, "Total quantity in stock should be 0 as the backorder took everything out of stock"
|
||||
assert product.qty_available == 0, "Quantity available should be 0 too"
|
||||
@@ -1,163 +0,0 @@
|
||||
-
|
||||
Create a new "negative" stockable product
|
||||
-
|
||||
!record {model: product.product, id: product_neg, view: False}:
|
||||
name: Negative product
|
||||
type: product
|
||||
categ_id: product.product_category_1
|
||||
list_price: 100.0
|
||||
standard_price: 70.0
|
||||
seller_ids:
|
||||
- delay: 1
|
||||
name: base.res_partner_2
|
||||
min_qty: 2.0
|
||||
uom_id: product.product_uom_unit
|
||||
uom_po_id: product.product_uom_unit
|
||||
-
|
||||
Create an incoming picking for this product of 300 PCE from suppliers to stock
|
||||
-
|
||||
!record {model: stock.picking, id: pick_neg}:
|
||||
name: Incoming picking (negative product)
|
||||
partner_id: base.res_partner_2
|
||||
picking_type_id: picking_type_in
|
||||
move_lines:
|
||||
- product_id: product_neg
|
||||
product_uom_qty: 300.00
|
||||
location_id: stock_location_suppliers
|
||||
location_dest_id: stock_location_stock
|
||||
-
|
||||
Confirm and assign picking
|
||||
-
|
||||
!python {model: stock.picking, id: pick_neg}: |
|
||||
self.action_confirm()
|
||||
self.action_assign()
|
||||
-
|
||||
Put 120 pieces on Palneg 1 (package), 120 pieces on Palneg 2 with lot A and 60 pieces on Palneg 3
|
||||
-
|
||||
!python {model: stock.picking, id: pick_neg}: |
|
||||
#Change quantity of first to 120 and create 2 others quant operations
|
||||
stock_pack = self.env['stock.move.line']
|
||||
stock_quant_pack = self.env['stock.quant.package']
|
||||
#create lot A
|
||||
lot_a = self.env['stock.production.lot'].create({'name': 'Lot neg', 'product_id': ref('product_neg')})
|
||||
#create package
|
||||
package1 = stock_quant_pack.create({'name': 'Palneg 1'})
|
||||
package2 = stock_quant_pack.create({'name': 'Palneg 2'})
|
||||
package3 = stock_quant_pack.create({'name': 'Palneg 3'})
|
||||
#Create package for each line and assign it as result_package_id
|
||||
#create pack operation
|
||||
self.move_line_ids[0].write({'result_package_id': package1.id, 'qty_done': 120})
|
||||
new_pack1 = stock_pack.create({
|
||||
'product_id': ref('product_neg'),
|
||||
'product_uom_id': ref('product.product_uom_unit'),
|
||||
'picking_id': ref('pick_neg'),
|
||||
'lot_id': lot_a.id,
|
||||
'qty_done': 120,
|
||||
'result_package_id': package2.id,
|
||||
'location_id': ref('stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock_location_stock')
|
||||
})
|
||||
new_pack2 = stock_pack.create({
|
||||
'product_id': ref('product_neg'),
|
||||
'product_uom_id': ref('product.product_uom_unit'),
|
||||
'picking_id': ref('pick_neg'),
|
||||
'result_package_id': package3.id,
|
||||
'qty_done': 60,
|
||||
'location_id': ref('stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock_location_stock')
|
||||
})
|
||||
-
|
||||
Transfer the receipt
|
||||
-
|
||||
!python {model: stock.picking, id: pick_neg}: |
|
||||
self.do_transfer()
|
||||
-
|
||||
Make a delivery order of 300 pieces to the customer
|
||||
-
|
||||
!record {model: stock.picking, id: delivery_order_neg}:
|
||||
name: outgoing picking (negative product)
|
||||
partner_id: base.res_partner_4
|
||||
picking_type_id: stock.picking_type_out
|
||||
move_lines:
|
||||
- product_id: product_neg
|
||||
product_uom_qty: 300.00
|
||||
location_id: stock_location_stock
|
||||
location_dest_id: stock_location_customers
|
||||
-
|
||||
Assign and confirm
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order_neg}: |
|
||||
self.action_confirm()
|
||||
self.action_assign()
|
||||
-
|
||||
Instead of doing the 300 pieces, you decide to take pallet 1 (do not mention product in operation here) and 140 pieces from lot A/pallet 2 and 10 pieces from pallet 3
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order_neg}: |
|
||||
for rec in self.move_line_ids:
|
||||
if rec.package_id.name == 'Palneg 1':
|
||||
rec.qty_done = rec.product_qty
|
||||
rec.result_package_id = False
|
||||
elif rec.package_id.name == 'Palneg 2' and rec.lot_id.name == 'Lot neg' :
|
||||
rec.write({
|
||||
'qty_done': 140,
|
||||
'result_package_id': False,
|
||||
})
|
||||
elif rec.package_id.name == 'Palneg 3':
|
||||
rec.qty_done = 10
|
||||
rec.result_package_id = False
|
||||
-
|
||||
Process this picking
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order_neg}: |
|
||||
self.do_transfer()
|
||||
-
|
||||
Check the quants that you have -20 pieces pallet 2 in stock, and a total quantity of 50 in stock from pallet 3 (should be 20+30, as it has been split by reservation)
|
||||
-
|
||||
!python {model: stock.quant, id: False}: |
|
||||
records = self.search([('product_id','=',ref('product_neg'))])
|
||||
pallet_3_stock_qty = 0
|
||||
for rec in records:
|
||||
if rec.package_id.name == 'Palneg 2' and rec.location_id.id == ref('stock_location_stock'):
|
||||
assert rec.quantity == -20, "Should have -20 pieces in stock on pallet 2. Got " + str(rec.quantity)
|
||||
assert rec.lot_id.name == 'Lot neg', "It should have kept its Lot"
|
||||
elif rec.package_id.name == 'Palneg 3' and rec.location_id.id == ref('stock_location_stock'):
|
||||
pallet_3_stock_qty += rec.quantity
|
||||
else:
|
||||
assert rec.location_id.id != ref('stock_location_stock'), "Unrecognized quant in stock"
|
||||
assert pallet_3_stock_qty == 50, "Should have 50 pieces in stock on pallet 3"
|
||||
-
|
||||
Create a picking for reconciling the negative quant
|
||||
-
|
||||
!record {model: stock.picking, id: delivery_reconcile}:
|
||||
name: reconciling_delivery
|
||||
partner_id: base.res_partner_4
|
||||
picking_type_id: stock.picking_type_in
|
||||
move_lines:
|
||||
- product_id: product_neg
|
||||
product_uom_qty: 20.0
|
||||
location_id: stock_location_suppliers
|
||||
location_dest_id: stock_location_stock
|
||||
-
|
||||
Receive 20 products with lot neg in stock with a new incoming shipment that should be on pallet 2
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_reconcile}: |
|
||||
self.action_confirm()
|
||||
pack_obj = self.env["stock.quant.package"]
|
||||
lot = self.env["stock.production.lot"].search([('product_id', '=', ref('product_neg')), ('name','=','Lot neg')], limit=1)
|
||||
pack = pack_obj.search([('name', '=', 'Palneg 2')], limit=1)
|
||||
self.move_line_ids[0].write({'lot_id': lot.id, 'qty_done': 20.0, 'result_package_id': pack.id})
|
||||
self.do_transfer()
|
||||
-
|
||||
Check the negative quant was reconciled
|
||||
-
|
||||
!python {model: stock.quant, id: False}: |
|
||||
neg_quants = self.search([('product_id','=', ref('product_neg')), ('quantity', '<', 0), ('location_id.id', '!=',
|
||||
ref('stock_location_suppliers'))])
|
||||
assert len(neg_quants) == 0, "Negative quants should have been reconciled"
|
||||
pick = self.env['stock.picking'].browse(ref('delivery_reconcile'))
|
||||
customer_quant = self.search([
|
||||
('product_id', '=', ref('product_neg')),
|
||||
('location_id', '=', ref('stock_location_customers')),
|
||||
('lot_id.name','=', 'Lot neg'),
|
||||
('quantity','=', 20)
|
||||
])
|
||||
@@ -1,54 +0,0 @@
|
||||
-
|
||||
Create a product route containing a procurement rule that will
|
||||
generate a move from Stock for every procurement created in Output
|
||||
-
|
||||
!record {model: stock.location.route, id: product_route}:
|
||||
name: Stock -> output route
|
||||
product_selectable: True
|
||||
pull_ids:
|
||||
- name: Stock -> output rule
|
||||
action: move
|
||||
picking_type_id: stock.picking_type_internal
|
||||
location_src_id: stock.stock_location_stock
|
||||
location_id: stock.stock_location_output
|
||||
-
|
||||
Set this route on `product.product_product_3`
|
||||
-
|
||||
!python {model: product.product, id: product.product_product_3}: |
|
||||
self.write({'route_ids': [(4, ref('stock.product_route'))]})
|
||||
-
|
||||
Create Delivery Order of 10 `product.product_product_3`
|
||||
from Output -> Customer
|
||||
-
|
||||
!record {model: stock.picking, id: pick_output}:
|
||||
name: Delivery order for procurement
|
||||
partner_id: base.res_partner_2
|
||||
picking_type_id: stock.picking_type_out
|
||||
location_id: stock.stock_location_output
|
||||
location_dest_id: stock.stock_location_customers
|
||||
move_lines:
|
||||
- product_id: product.product_product_3
|
||||
product_uom_qty: 10.00
|
||||
procure_method: make_to_order
|
||||
-
|
||||
Confirm delivery order.
|
||||
-
|
||||
!python {model: stock.picking, id: pick_output}: |
|
||||
self.action_confirm()
|
||||
-
|
||||
I run the scheduler.
|
||||
-
|
||||
!python {model: procurement.group, id: False}: |
|
||||
self.run_scheduler()
|
||||
-
|
||||
Check that a picking was created from stock to output.
|
||||
-
|
||||
!python {model: stock.move, id: False}: |
|
||||
picking = self.env["stock.picking"].browse(ref("pick_output"))
|
||||
moves = self.search([
|
||||
('product_id', '=', ref('product.product_product_3')),
|
||||
('location_id', '=', ref('stock.stock_location_stock')),
|
||||
('location_dest_id', '=', ref('stock.stock_location_output')),
|
||||
('move_dest_ids', 'in', [picking.move_lines[0].id])
|
||||
])
|
||||
assert len(moves.ids) == 1, "It should have created a picking from Stock to Output with the original picking as destination"
|
||||
@@ -1,28 +0,0 @@
|
||||
-
|
||||
Create a user as 'Stock Manager'
|
||||
-
|
||||
!record {model: res.users, id: res_users_stock_manager, view: False}:
|
||||
company_id: base.main_company
|
||||
name: Stock Manager
|
||||
login: sam
|
||||
email: stockmanager@yourcompany.com
|
||||
-
|
||||
I added groups for Stock Manager.
|
||||
-
|
||||
!record {model: res.users, id: res_users_stock_manager}:
|
||||
groups_id:
|
||||
- stock.group_stock_manager
|
||||
-
|
||||
Create a user as 'Stock User'
|
||||
-
|
||||
!record {model: res.users, id: res_users_stock_user, view: False}:
|
||||
company_id: base.main_company
|
||||
name: Stock User
|
||||
login: sau
|
||||
email: stockuser@yourcompany.com
|
||||
-
|
||||
I added groups for Stock User.
|
||||
-
|
||||
!record {model: res.users, id: res_users_stock_user}:
|
||||
groups_id:
|
||||
- stock.group_stock_user
|
||||
@@ -1,159 +0,0 @@
|
||||
-
|
||||
Create a new stockable product
|
||||
-
|
||||
!record {model: product.product, id: product_wise}:
|
||||
name: Wise Unit
|
||||
type: product
|
||||
categ_id: product.product_category_1
|
||||
uom_id: product.product_uom_unit
|
||||
uom_po_id: product.product_uom_unit
|
||||
-
|
||||
Create an incoming picking for this product of 10 PCE from suppliers to stock
|
||||
-
|
||||
!record {model: stock.picking, id: pick1_wise}:
|
||||
name: Incoming picking (wise unit)
|
||||
partner_id: base.res_partner_2
|
||||
picking_type_id: picking_type_in
|
||||
move_lines:
|
||||
- product_id: product_wise
|
||||
product_uom_qty: 10.00
|
||||
location_id: stock_location_suppliers
|
||||
location_dest_id: stock_location_stock
|
||||
-
|
||||
Confirm and assign picking and prepare partial
|
||||
-
|
||||
!python {model: stock.picking, id: pick1_wise}: |
|
||||
self.action_confirm()
|
||||
self.action_assign()
|
||||
-
|
||||
Put 4 pieces in shelf1 and 6 pieces in shelf2
|
||||
-
|
||||
!python {model: stock.picking, id: pick1_wise}: |
|
||||
stock_pack = self.env['stock.move.line']
|
||||
stock_quant_pack = self.env['stock.quant.package']
|
||||
package1 = stock_quant_pack.create({'name': 'Pack 1'})
|
||||
self.move_line_ids[0].write({
|
||||
'result_package_id': package1.id,
|
||||
'qty_done': 4,
|
||||
'location_dest_id': ref('stock_location_components')
|
||||
})
|
||||
new_pack1 = stock_pack.create({
|
||||
'product_id': ref('product_wise'),
|
||||
'product_uom_id': ref('product.product_uom_unit'),
|
||||
'picking_id': ref('pick1_wise'),
|
||||
'qty_done': 6.0,
|
||||
'location_id': ref('stock_location_suppliers'),
|
||||
'location_dest_id': ref('stock_location_14')
|
||||
})
|
||||
-
|
||||
Transfer the receipt
|
||||
-
|
||||
!python {model: stock.picking, id: pick1_wise}: |
|
||||
self.do_transfer()
|
||||
-
|
||||
Check the system created 3 quants
|
||||
-
|
||||
!python {model: stock.quant, id: False}: |
|
||||
records = self.search([('product_id','=',ref('product_wise'))])
|
||||
assert len(records.ids) == 3, "The number of quants created is not correct"
|
||||
-
|
||||
Make a delivery order of 5 pieces to the customer
|
||||
-
|
||||
!record {model: stock.picking, id: delivery_order_wise1}:
|
||||
name: outgoing picking 1 (wise unit)
|
||||
partner_id: base.res_partner_4
|
||||
picking_type_id: stock.picking_type_out
|
||||
move_lines:
|
||||
- product_id: product_wise
|
||||
product_uom_qty: 5.0
|
||||
location_id: stock_location_stock
|
||||
location_dest_id: stock_location_customers
|
||||
-
|
||||
Assign and confirm
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order_wise1}: |
|
||||
self.action_confirm()
|
||||
self.action_assign()
|
||||
assert self.state == 'assigned'
|
||||
-
|
||||
Make a delivery order of 5 pieces to the customer
|
||||
-
|
||||
!record {model: stock.picking, id: delivery_order_wise2}:
|
||||
name: outgoing picking 2 (wise unit)
|
||||
partner_id: base.res_partner_4
|
||||
picking_type_id: stock.picking_type_out
|
||||
move_lines:
|
||||
- product_id: product_wise
|
||||
product_uom_qty: 5.0
|
||||
location_id: stock_location_stock
|
||||
location_dest_id: stock_location_customers
|
||||
-
|
||||
Assign and confirm
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order_wise2}: |
|
||||
self.action_confirm()
|
||||
self.action_assign()
|
||||
assert self.state == 'assigned'
|
||||
-
|
||||
The operator is a wise guy and decides to do the opposite of what Odoo proposes. He uses the products reserved on picking 1 on picking 2 and vice versa
|
||||
-
|
||||
!python {model: stock.picking, id: False}: |
|
||||
picking1 = self.browse(ref('delivery_order_wise1'))
|
||||
picking2 = self.browse(ref('delivery_order_wise2'))
|
||||
move1 = picking1.move_lines[0]
|
||||
move2 = picking2.move_lines[0]
|
||||
pack_ids1 = picking1.move_line_ids
|
||||
pack_ids2 = picking2.move_line_ids
|
||||
|
||||
assert pack_ids1.location_id.id == ref('stock_location_14')
|
||||
assert set(pack_ids2.mapped('location_id.id')) == set([ref('stock_location_components'), ref('stock_location_14')])
|
||||
|
||||
# put the move lines from picking2 into picking1
|
||||
for pack_id2 in pack_ids2:
|
||||
new_pack_id1 = pack_id2.copy(default={'picking_id': picking1.id, 'move_id': move1.id})
|
||||
new_pack_id1.qty_done = new_pack_id1.product_qty
|
||||
new_pack_id1.with_context(bypass_reservation_update=True).product_uom_qty = 0
|
||||
|
||||
new_move_lines = picking1.move_line_ids.filtered(lambda p: p.qty_done)
|
||||
assert sum(new_move_lines.mapped('product_qty')) == 0
|
||||
assert sum(new_move_lines.mapped('qty_done')) == 5
|
||||
assert set(new_move_lines.mapped('location_id.id')) == set([ref('stock_location_components'), ref('stock_location_14')])
|
||||
|
||||
# put the move line from picking1 into picking2
|
||||
new_pack_id2 = pack_ids1.copy(default={'picking_id': picking2.id, 'move_id': move2.id})
|
||||
new_pack_id2.qty_done = new_pack_id2.product_qty
|
||||
new_pack_id2.with_context(bypass_reservation_update=True).product_uom_qty = 0
|
||||
|
||||
new_move_lines = picking2.move_line_ids.filtered(lambda p: p.qty_done)
|
||||
assert len(new_move_lines) == 1
|
||||
assert sum(new_move_lines.mapped('product_qty')) == 0
|
||||
assert sum(new_move_lines.mapped('qty_done')) == 5
|
||||
assert new_move_lines.location_id.id == ref('stock_location_14')
|
||||
-
|
||||
Process this picking
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order_wise1}: |
|
||||
self.do_transfer()
|
||||
-
|
||||
Check there was no negative quant created by this picking
|
||||
-
|
||||
!python {model: stock.quant, id: False}: |
|
||||
records = self.search([('product_id','=',ref('product_wise')), ('quantity', '<', 0.0), ('location_id.id', '=',
|
||||
ref('stock_location_stock'))])
|
||||
assert len(records.ids) == 0, 'This should not have created a negative quant'
|
||||
-
|
||||
Check the other delivery order has changed its state back to ready
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order_wise2}: |
|
||||
assert self.state == 'assigned', "Delivery order 2 should be back in ready state"
|
||||
-
|
||||
Process the second picking
|
||||
-
|
||||
!python {model: stock.picking, id: delivery_order_wise2}: |
|
||||
self.action_done()
|
||||
-
|
||||
Check all quants are in Customers and there are no negative quants anymore
|
||||
-
|
||||
!python {model: stock.quant, id: False}: |
|
||||
records = self.search([('product_id','=',ref('product_wise')), ('location_id', '!=', ref('stock_location_suppliers'))])
|
||||
assert all([x.location_id.id==ref('stock_location_customers') and x.quantity > 0.0 for x in records]), "Negative quant or wrong location detected"
|
||||
@@ -9,3 +9,7 @@ from . import test_quant
|
||||
from . import test_inventory
|
||||
from . import test_move
|
||||
from . import test_move2
|
||||
from . import test_packing
|
||||
from . import test_packing_neg
|
||||
from . import test_proc_rule
|
||||
from . import test_wise_operator
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestPacking(TransactionCase):
|
||||
|
||||
def test_packing(self):
|
||||
|
||||
# Create a new stockable product
|
||||
|
||||
product1 = self.env['product.product'].create({
|
||||
'name': 'Nice product',
|
||||
'type': 'product',
|
||||
'categ_id': self.ref('product.product_category_1'),
|
||||
'list_price': 100.0,
|
||||
'standard_price': 70.0,
|
||||
'seller_ids': [(0, 0, {
|
||||
'delay': 1,
|
||||
'name': self.ref('base.res_partner_2'),
|
||||
'min_qty': 2.0,
|
||||
})],
|
||||
'uom_id': self.ref('product.product_uom_unit'),
|
||||
'uom_po_id': self.ref('product.product_uom_unit'),
|
||||
})
|
||||
|
||||
# Create an incoming picking for this product of 300 PCE from suppliers to stock
|
||||
default_get_vals = self.env['stock.picking'].default_get(list(self.env['stock.picking'].fields_get()))
|
||||
default_get_vals.update({
|
||||
'name': 'Incoming picking',
|
||||
'partner_id': self.ref('base.res_partner_2'),
|
||||
'picking_type_id': self.ref('stock.picking_type_in'),
|
||||
'move_lines': [(0, 0, {
|
||||
'product_id': product1.id,
|
||||
'product_uom_qty': 300.00,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.ref('stock.stock_location_stock'),
|
||||
})],
|
||||
})
|
||||
pick1 = self.env['stock.picking'].new(default_get_vals)
|
||||
pick1.onchange_picking_type()
|
||||
pick1.move_lines.onchange_product_id()
|
||||
vals = pick1._convert_to_write(pick1._cache)
|
||||
pick1 = self.env['stock.picking'].create(vals)
|
||||
|
||||
# Confirm and assign picking
|
||||
pick1.action_confirm()
|
||||
pick1.action_assign()
|
||||
|
||||
# Put 120 pieces on Pallet 1 (package), 120 pieces on Pallet 2 with lot A and 60 pieces on Pallet 3
|
||||
lot_a = self.env['stock.production.lot'].create({
|
||||
'name': 'Lot A',
|
||||
'product_id': product1.id,
|
||||
})
|
||||
|
||||
# create package
|
||||
package1 = self.env['stock.quant.package'].create({'name': 'Pallet 1'})
|
||||
package2 = self.env['stock.quant.package'].create({'name': 'Pallet 2'})
|
||||
package3 = self.env['stock.quant.package'].create({'name': 'Pallet 3'})
|
||||
|
||||
# Create package for each line and assign it as result_package_id
|
||||
# create pack operation
|
||||
pick1.move_line_ids[0].write({'result_package_id': package1.id, 'qty_done': 120})
|
||||
new_pack1 = self.env['stock.move.line'].create({
|
||||
'product_id': product1.id,
|
||||
'product_uom_id': self.ref('product.product_uom_unit'),
|
||||
'picking_id': pick1.id,
|
||||
'lot_id': lot_a.id,
|
||||
'qty_done': 120.0,
|
||||
'result_package_id': package2.id,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.ref('stock.stock_location_stock')
|
||||
})
|
||||
new_pack2 = self.env['stock.move.line'].create({
|
||||
'product_id': product1.id,
|
||||
'product_uom_id': self.ref('product.product_uom_unit'),
|
||||
'picking_id': pick1.id,
|
||||
'result_package_id': package3.id,
|
||||
'qty_done': 60.0,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.ref('stock.stock_location_stock')
|
||||
})
|
||||
|
||||
# Transfer the receipt
|
||||
pick1.action_done()
|
||||
|
||||
# Check the system created 5 quants one with 120 pieces on pallet 1,
|
||||
# one with 120 pieces on pallet 2 with lot A and 60 pieces on pallet 3 in stock
|
||||
# and 1 with -180 pieces and another with -120 piece lot A in supplier
|
||||
quants = self.env['stock.quant'].search([('product_id', '=', product1.id)])
|
||||
self.assertTrue(len(quants.ids) == 5, "The number of quants created is not correct")
|
||||
for quant in quants:
|
||||
if quant.package_id.name == 'Pallet 1':
|
||||
self.assertTrue(quant.quantity == 120, "Should have 120 pieces on pallet 1")
|
||||
elif quant.package_id.name == 'Pallet 2':
|
||||
self.assertTrue(quant.quantity == 120, "Should have 120 pieces on pallet 2")
|
||||
elif quant.package_id.name == 'Pallet 3':
|
||||
self.assertTrue(quant.quantity == 60, "Should have 60 pieces on pallet 3")
|
||||
|
||||
# Check there is no backorder or extra moves created
|
||||
backorder = self.env['stock.picking'].search([('backorder_id', '=', pick1.id)])
|
||||
self.assertTrue(not backorder)
|
||||
|
||||
# Check extra moves created
|
||||
self.assertTrue(len(pick1.move_lines) == 1)
|
||||
|
||||
# Make a delivery order of 300 pieces to the customer
|
||||
default_get_vals = self.env['stock.picking'].default_get(list(self.env['stock.picking'].fields_get()))
|
||||
default_get_vals.update({
|
||||
'name': 'outgoing picking',
|
||||
'partner_id': self.ref('base.res_partner_4'),
|
||||
'picking_type_id': self.ref('stock.picking_type_out'),
|
||||
'move_lines': [(0, 0, {
|
||||
'product_id': product1.id,
|
||||
'product_uom_qty': 300.00,
|
||||
'location_id': self.ref('stock.stock_location_stock'),
|
||||
'location_dest_id': self.ref('stock.stock_location_customers'),
|
||||
})],
|
||||
})
|
||||
delivery_order1 = self.env['stock.picking'].new(default_get_vals)
|
||||
delivery_order1.onchange_picking_type()
|
||||
delivery_order1.move_lines.onchange_product_id()
|
||||
vals = delivery_order1._convert_to_write(delivery_order1._cache)
|
||||
delivery_order1 = self.env['stock.picking'].create(vals)
|
||||
|
||||
# Assign and confirm
|
||||
delivery_order1.action_confirm()
|
||||
delivery_order1.action_assign()
|
||||
|
||||
# Instead of doing the 300 pieces, you decide to take pallet 1 (do not
|
||||
# mention product in operation here) and 20 pieces from lot A and 10 pieces from pallet 3
|
||||
for rec in delivery_order1.move_line_ids:
|
||||
if rec.package_id.name == 'Pallet 1':
|
||||
rec.qty_done = 120
|
||||
rec.result_package_id = False
|
||||
if rec.package_id.name == 'Pallet 2':
|
||||
rec.qty_done = 20
|
||||
rec.result_package_id = False
|
||||
if rec.package_id.name == 'Pallet 3':
|
||||
rec.qty_done = 10
|
||||
rec.result_package_id = False
|
||||
|
||||
# Process this picking
|
||||
delivery_order1.action_done()
|
||||
|
||||
# Check the quants that you have 100 pieces of pallet 2 and 50 pieces of pallet 3 in stock
|
||||
records = self.env['stock.quant'].search([('product_id', '=', product1.id)])
|
||||
for rec in records:
|
||||
if rec.package_id.name == 'Pallet 2' and rec.location_id.id == self.ref('stock.stock_location_stock'):
|
||||
self.assertTrue(rec.quantity == 100, "Should have 100 pieces in stock on pallet 2, got " + str(rec.quantity))
|
||||
elif rec.package_id.name == 'Pallet 3' and rec.location_id.id == self.ref('stock.stock_location_stock'):
|
||||
self.assertTrue(rec.quantity == 50, "Should have 50 pieces in stock on pallet 3")
|
||||
else:
|
||||
self.assertTrue(rec.location_id.id != self.ref('stock.stock_location_stock'), "Unrecognized quant in stock")
|
||||
|
||||
# Check a backorder was created and on that backorder, prepare partial and process backorder
|
||||
backorders = self.env['stock.picking'].search([('backorder_id', '=', delivery_order1.id)])
|
||||
self.assertTrue(backorders, "Backorder should have been created")
|
||||
backorders.action_assign()
|
||||
picking = backorders[0]
|
||||
self.assertTrue(len(picking.move_line_ids) == 2, "Wrong number of pack operation")
|
||||
for pack_op in picking.move_line_ids:
|
||||
self.assertTrue(pack_op.package_id.name in ('Pallet 2', 'Pallet 3'), "Wrong pallet info in pack operation (%s found)" % (pack_op.package_id.name))
|
||||
if pack_op.package_id.name == 'Pallet 2':
|
||||
self.assertTrue(pack_op.product_qty == 100)
|
||||
pack_op.qty_done = 100
|
||||
elif pack_op.package_id.name == 'Pallet 3':
|
||||
self.assertTrue(pack_op.product_qty == 50)
|
||||
pack_op.qty_done = 50
|
||||
backorders.action_done()
|
||||
|
||||
# Check there are still 0 pieces in stock
|
||||
records = self.env['stock.quant'].search([('product_id', '=', product1.id), ('location_id', '=', self.ref('stock.stock_location_stock'))])
|
||||
total_qty = 0
|
||||
for rec in records:
|
||||
total_qty += rec.quantity
|
||||
self.assertTrue(total_qty == 0, "Total quantity in stock should be 0 as the backorder took everything out of stock")
|
||||
self.assertTrue(product1.qty_available == 0, "Quantity available should be 0 too")
|
||||
@@ -0,0 +1,171 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestPackingNeg(TransactionCase):
|
||||
|
||||
def test_packing_neg(self):
|
||||
|
||||
# Create a new "negative" stockable product
|
||||
product_neg = self.env['product.product'].create({
|
||||
'name': 'Negative product',
|
||||
'type': 'product',
|
||||
'categ_id': self.ref('product.product_category_1'),
|
||||
'list_price': 100.0,
|
||||
'standard_price': 70.0,
|
||||
'seller_ids': [(0, 0, {
|
||||
'delay': 1,
|
||||
'name': self.ref('base.res_partner_2'),
|
||||
'min_qty': 2.0,})],
|
||||
'uom_id': self.ref('product.product_uom_unit'),
|
||||
'uom_po_id': self.ref('product.product_uom_unit'),
|
||||
})
|
||||
|
||||
# Create an incoming picking for this product of 300 PCE from suppliers to stock
|
||||
default_get_vals = self.env['stock.picking'].default_get(list(self.env['stock.picking'].fields_get()))
|
||||
default_get_vals.update({
|
||||
'name': 'Incoming picking (negative product)',
|
||||
'partner_id': self.ref('base.res_partner_2'),
|
||||
'picking_type_id': self.ref('stock.picking_type_in'),
|
||||
'move_lines': [(0, 0, {
|
||||
'product_id': product_neg.id,
|
||||
'product_uom_qty': 300.00,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.ref('stock.stock_location_stock'),
|
||||
})],
|
||||
})
|
||||
pick_neg = self.env['stock.picking'].new(default_get_vals)
|
||||
pick_neg.onchange_picking_type()
|
||||
pick_neg.move_lines.onchange_product_id()
|
||||
vals = pick_neg._convert_to_write(pick_neg._cache)
|
||||
pick_neg = self.env['stock.picking'].create(vals)
|
||||
|
||||
# Confirm and assign picking
|
||||
pick_neg.action_confirm()
|
||||
pick_neg.action_assign()
|
||||
|
||||
# Put 120 pieces on Palneg 1 (package), 120 pieces on Palneg 2 with lot A and 60 pieces on Palneg 3
|
||||
# create lot A
|
||||
lot_a = self.env['stock.production.lot'].create({'name': 'Lot neg', 'product_id': product_neg.id})
|
||||
# create package
|
||||
package1 = self.env['stock.quant.package'].create({'name': 'Palneg 1'})
|
||||
package2 = self.env['stock.quant.package'].create({'name': 'Palneg 2'})
|
||||
package3 = self.env['stock.quant.package'].create({'name': 'Palneg 3'})
|
||||
# Create package for each line and assign it as result_package_id
|
||||
# create pack operation
|
||||
pick_neg.move_line_ids[0].write({'result_package_id': package1.id, 'qty_done': 120})
|
||||
new_pack1 = self.env['stock.move.line'].create({
|
||||
'product_id': product_neg.id,
|
||||
'product_uom_id': self.ref('product.product_uom_unit'),
|
||||
'picking_id': pick_neg.id,
|
||||
'lot_id': lot_a.id,
|
||||
'qty_done': 120,
|
||||
'result_package_id': package2.id,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.ref('stock.stock_location_stock')
|
||||
})
|
||||
new_pack2 = self.env['stock.move.line'].create({
|
||||
'product_id': product_neg.id,
|
||||
'product_uom_id': self.ref('product.product_uom_unit'),
|
||||
'picking_id': pick_neg.id,
|
||||
'result_package_id': package3.id,
|
||||
'qty_done': 60,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.ref('stock.stock_location_stock')
|
||||
})
|
||||
|
||||
# Transfer the receipt
|
||||
pick_neg.do_transfer()
|
||||
|
||||
# Make a delivery order of 300 pieces to the customer
|
||||
default_get_vals = self.env['stock.picking'].default_get(list(self.env['stock.picking'].fields_get()))
|
||||
default_get_vals.update({
|
||||
'name': 'outgoing picking (negative product)',
|
||||
'partner_id': self.ref('base.res_partner_4'),
|
||||
'picking_type_id': self.ref('stock.picking_type_out'),
|
||||
'move_lines': [(0, 0, {
|
||||
'product_id': product_neg.id,
|
||||
'product_uom_qty': 300.00,
|
||||
'location_id': self.ref('stock.stock_location_stock'),
|
||||
'location_dest_id': self.ref('stock.stock_location_customers'),
|
||||
})],
|
||||
})
|
||||
delivery_order_neg = self.env['stock.picking'].new(default_get_vals)
|
||||
delivery_order_neg.onchange_picking_type()
|
||||
delivery_order_neg.move_lines.onchange_product_id()
|
||||
vals = delivery_order_neg._convert_to_write(delivery_order_neg._cache)
|
||||
delivery_order_neg = self.env['stock.picking'].create(vals)
|
||||
|
||||
# Assign and confirm
|
||||
delivery_order_neg.action_confirm()
|
||||
delivery_order_neg.action_assign()
|
||||
|
||||
# Instead of doing the 300 pieces, you decide to take pallet 1 (do not mention
|
||||
# product in operation here) and 140 pieces from lot A/pallet 2 and 10 pieces from pallet 3
|
||||
|
||||
for rec in delivery_order_neg.move_line_ids:
|
||||
if rec.package_id.name == 'Palneg 1':
|
||||
rec.qty_done = rec.product_qty
|
||||
rec.result_package_id = False
|
||||
elif rec.package_id.name == 'Palneg 2' and rec.lot_id.name == 'Lot neg':
|
||||
rec.write({
|
||||
'qty_done': 140,
|
||||
'result_package_id': False,
|
||||
})
|
||||
elif rec.package_id.name == 'Palneg 3':
|
||||
rec.qty_done = 10
|
||||
rec.result_package_id = False
|
||||
|
||||
# Process this picking
|
||||
delivery_order_neg.do_transfer()
|
||||
|
||||
# Check the quants that you have -20 pieces pallet 2 in stock, and a total quantity
|
||||
# of 50 in stock from pallet 3 (should be 20+30, as it has been split by reservation)
|
||||
records = self.env['stock.quant'].search([('product_id', '=', product_neg.id)])
|
||||
pallet_3_stock_qty = 0
|
||||
for rec in records:
|
||||
if rec.package_id.name == 'Palneg 2' and rec.location_id.id == self.ref('stock.stock_location_stock'):
|
||||
self.assertTrue(rec.quantity == -20, "Should have -20 pieces in stock on pallet 2. Got " + str(rec.quantity))
|
||||
self.assertTrue(rec.lot_id.name == 'Lot neg', "It should have kept its Lot")
|
||||
elif rec.package_id.name == 'Palneg 3' and rec.location_id.id == self.ref('stock.stock_location_stock'):
|
||||
pallet_3_stock_qty += rec.quantity
|
||||
else:
|
||||
self.assertTrue(rec.location_id.id != self.ref('stock.stock_location_stock'), "Unrecognized quant in stock")
|
||||
self.assertEqual(pallet_3_stock_qty, 50, "Should have 50 pieces in stock on pallet 3")
|
||||
|
||||
# Create a picking for reconciling the negative quant
|
||||
default_get_vals = self.env['stock.picking'].default_get(list(self.env['stock.picking'].fields_get()))
|
||||
default_get_vals.update({
|
||||
'name': 'reconciling_delivery',
|
||||
'partner_id': self.ref('base.res_partner_4'),
|
||||
'picking_type_id': self.ref('stock.picking_type_in'),
|
||||
'move_lines': [(0, 0, {
|
||||
'product_id': product_neg.id,
|
||||
'product_uom_qty': 20.0,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.ref('stock.stock_location_stock'),
|
||||
})],
|
||||
})
|
||||
delivery_reconcile = self.env['stock.picking'].new(default_get_vals)
|
||||
delivery_reconcile.onchange_picking_type()
|
||||
delivery_reconcile.move_lines.onchange_product_id()
|
||||
vals = delivery_reconcile._convert_to_write(delivery_reconcile._cache)
|
||||
delivery_reconcile = self.env['stock.picking'].create(vals)
|
||||
|
||||
# Receive 20 products with lot neg in stock with a new incoming shipment that should be on pallet 2
|
||||
delivery_reconcile.action_confirm()
|
||||
lot = self.env["stock.production.lot"].search([
|
||||
('product_id', '=', product_neg.id),
|
||||
('name', '=', 'Lot neg')], limit=1)
|
||||
pack = self.env["stock.quant.package"].search([('name', '=', 'Palneg 2')], limit=1)
|
||||
delivery_reconcile.move_line_ids[0].write({'lot_id': lot.id, 'qty_done': 20.0, 'result_package_id': pack.id})
|
||||
delivery_reconcile.do_transfer()
|
||||
|
||||
# Check the negative quant was reconciled
|
||||
neg_quants = self.env['stock.quant'].search([
|
||||
('product_id', '=', product_neg.id),
|
||||
('quantity', '<', 0),
|
||||
('location_id.id', '!=', self.ref('stock.stock_location_suppliers'))])
|
||||
self.assertTrue(len(neg_quants) == 0, "Negative quants should have been reconciled")
|
||||
@@ -0,0 +1,69 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
class TestProcRule(TransactionCase):
|
||||
|
||||
def test_proc_rule(self):
|
||||
# Create a product route containing a procurement rule that will
|
||||
# generate a move from Stock for every procurement created in Output
|
||||
product_route = self.env['stock.location.route'].create({
|
||||
'name': 'Stock -> output route',
|
||||
'product_selectable': True,
|
||||
'pull_ids': [(0, 0, {
|
||||
'name': 'Stock -> output rule',
|
||||
'action': 'move',
|
||||
'picking_type_id': self.ref('stock.picking_type_internal'),
|
||||
'location_src_id': self.ref('stock.stock_location_stock'),
|
||||
'location_id': self.ref('stock.stock_location_output'),
|
||||
})],
|
||||
})
|
||||
|
||||
# Set this route on `product.product_product_3`
|
||||
self.env.ref('product.product_product_3').write({
|
||||
'route_ids': [(4, product_route.id)]})
|
||||
|
||||
# Create Delivery Order of 10 `product.product_product_3` from Output -> Customer
|
||||
default_get_vals = self.env['stock.picking'].default_get(list(self.env['stock.picking'].fields_get()))
|
||||
default_get_vals.update({
|
||||
'name': 'Delivery order for procurement',
|
||||
'partner_id': self.ref('base.res_partner_2'),
|
||||
'picking_type_id': self.ref('stock.picking_type_out'),
|
||||
'move_lines': [(0, 0, {
|
||||
'product_id': self.ref('product.product_product_3'),
|
||||
'product_uom_qty': 10.00,
|
||||
'procure_method': 'make_to_order',
|
||||
})],
|
||||
})
|
||||
pick_output = self.env['stock.picking'].new(default_get_vals)
|
||||
pick_output.onchange_picking_type()
|
||||
pick_output.move_lines.onchange_product_id()
|
||||
pick_output.update({
|
||||
'location_id': self.ref('stock.stock_location_output'),
|
||||
'location_dest_id': self.ref('stock.stock_location_customers'),
|
||||
})
|
||||
vals = pick_output._convert_to_write(pick_output._cache)
|
||||
pick_output = self.env['stock.picking'].create(vals)
|
||||
|
||||
# Confirm delivery order.
|
||||
pick_output.action_confirm()
|
||||
|
||||
# I run the scheduler.
|
||||
# Note: If purchase if already installed, the method _run_buy will be called due
|
||||
# to the purchase demo data. As we update the stock module to run this test, the
|
||||
# method won't be an attribute of stock.procurement at this moment. For that reason
|
||||
# we mute the logger when running the scheduler.
|
||||
with mute_logger('odoo.addons.stock.models.procurement'):
|
||||
self.env['procurement.group'].run_scheduler()
|
||||
|
||||
# Check that a picking was created from stock to output.
|
||||
moves = self.env['stock.move'].search([
|
||||
('product_id', '=', self.ref('product.product_product_3')),
|
||||
('location_id', '=', self.ref('stock.stock_location_stock')),
|
||||
('location_dest_id', '=', self.ref('stock.stock_location_output')),
|
||||
('move_dest_ids', 'in', [pick_output.move_lines[0].id])
|
||||
])
|
||||
self.assertEqual(len(moves.ids), 1, "It should have created a picking from Stock to Output with the original picking as destination")
|
||||
@@ -0,0 +1,171 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestWiseOperator(TransactionCase):
|
||||
|
||||
def test_wise_operator(self):
|
||||
|
||||
# Create a new stockable product
|
||||
product_wise = self.env['product.product'].create({
|
||||
'name': 'Wise Unit',
|
||||
'type': 'product',
|
||||
'categ_id': self.ref('product.product_category_1'),
|
||||
'uom_id': self.ref('product.product_uom_unit'),
|
||||
'uom_po_id': self.ref('product.product_uom_unit'),
|
||||
})
|
||||
|
||||
picking_default_vals = self.env['stock.picking'].default_get(list(self.env['stock.picking'].fields_get()))
|
||||
|
||||
# Create an incoming picking for this product of 10 PCE from suppliers to stock
|
||||
vals = dict(picking_default_vals, **{
|
||||
'name': 'Incoming picking (wise unit)',
|
||||
'partner_id': self.ref('base.res_partner_2'),
|
||||
'picking_type_id': self.ref('stock.picking_type_in'),
|
||||
'move_lines': [(0, 0, {
|
||||
'product_id': product_wise.id,
|
||||
'product_uom_qty': 10.00,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.ref('stock.stock_location_stock'),
|
||||
})],
|
||||
})
|
||||
pick1_wise = self.env['stock.picking'].new(vals)
|
||||
pick1_wise.onchange_picking_type()
|
||||
pick1_wise.move_lines.onchange_product_id()
|
||||
vals = pick1_wise._convert_to_write(pick1_wise._cache)
|
||||
pick1_wise = self.env['stock.picking'].create(vals)
|
||||
|
||||
# Confirm and assign picking and prepare partial
|
||||
pick1_wise.action_confirm()
|
||||
pick1_wise.action_assign()
|
||||
|
||||
# Put 4 pieces in shelf1 and 6 pieces in shelf2
|
||||
package1 = self.env['stock.quant.package'].create({'name': 'Pack 1'})
|
||||
pick1_wise.move_line_ids[0].write({
|
||||
'result_package_id': package1.id,
|
||||
'qty_done': 4,
|
||||
'location_dest_id': self.ref('stock.stock_location_components')
|
||||
})
|
||||
new_pack1 = self.env['stock.move.line'].create({
|
||||
'product_id': product_wise.id,
|
||||
'product_uom_id': self.ref('product.product_uom_unit'),
|
||||
'picking_id': pick1_wise.id,
|
||||
'qty_done': 6.0,
|
||||
'location_id': self.ref('stock.stock_location_suppliers'),
|
||||
'location_dest_id': self.ref('stock.stock_location_14')
|
||||
})
|
||||
|
||||
# Transfer the receipt
|
||||
pick1_wise.do_transfer()
|
||||
|
||||
# Check the system created 3 quants
|
||||
records = self.env['stock.quant'].search([('product_id', '=', product_wise.id)])
|
||||
self.assertEqual(len(records.ids), 3, "The number of quants created is not correct")
|
||||
|
||||
# Make a delivery order of 5 pieces to the customer
|
||||
vals = dict(picking_default_vals, **{
|
||||
'name': 'outgoing picking 1 (wise unit)',
|
||||
'partner_id': self.ref('base.res_partner_4'),
|
||||
'picking_type_id': self.ref('stock.picking_type_out'),
|
||||
'move_lines': [(0, 0, {
|
||||
'product_id': product_wise.id,
|
||||
'product_uom_qty': 5.0,
|
||||
'location_id': self.ref('stock.stock_location_stock'),
|
||||
'location_dest_id': self.ref('stock.stock_location_customers'),
|
||||
})],
|
||||
})
|
||||
delivery_order_wise1 = self.env['stock.picking'].new(vals)
|
||||
delivery_order_wise1.onchange_picking_type()
|
||||
delivery_order_wise1.move_lines.onchange_product_id()
|
||||
vals = delivery_order_wise1._convert_to_write(delivery_order_wise1._cache)
|
||||
delivery_order_wise1 = self.env['stock.picking'].create(vals)
|
||||
|
||||
# Assign and confirm
|
||||
delivery_order_wise1.action_confirm()
|
||||
delivery_order_wise1.action_assign()
|
||||
self.assertEqual(delivery_order_wise1.state, 'assigned')
|
||||
|
||||
# Make a delivery order of 5 pieces to the customer
|
||||
vals = dict(picking_default_vals, **{
|
||||
'name': 'outgoing picking 2 (wise unit)',
|
||||
'partner_id': self.ref('base.res_partner_4'),
|
||||
'picking_type_id': self.ref('stock.picking_type_out'),
|
||||
'move_lines': [(0, 0, {
|
||||
'product_id': product_wise.id,
|
||||
'product_uom_qty': 5.0,
|
||||
'location_id': self.ref('stock.stock_location_stock'),
|
||||
'location_dest_id': self.ref('stock.stock_location_customers'),
|
||||
})],
|
||||
})
|
||||
delivery_order_wise2 = self.env['stock.picking'].new(vals)
|
||||
delivery_order_wise2.onchange_picking_type()
|
||||
delivery_order_wise2.move_lines.onchange_product_id()
|
||||
vals = delivery_order_wise2._convert_to_write(delivery_order_wise2._cache)
|
||||
delivery_order_wise2 = self.env['stock.picking'].create(vals)
|
||||
|
||||
# Assign and confirm
|
||||
delivery_order_wise2.action_confirm()
|
||||
delivery_order_wise2.action_assign()
|
||||
self.assertEqual(delivery_order_wise2.state, 'assigned')
|
||||
|
||||
# The operator is a wise guy and decides to do the opposite of what Odoo proposes.
|
||||
# He uses the products reserved on picking 1 on picking 2 and vice versa
|
||||
move1 = delivery_order_wise1.move_lines[0]
|
||||
move2 = delivery_order_wise2.move_lines[0]
|
||||
pack_ids1 = delivery_order_wise1.move_line_ids
|
||||
pack_ids2 = delivery_order_wise2.move_line_ids
|
||||
|
||||
self.assertEqual(pack_ids1.location_id.id, self.ref('stock.stock_location_14'))
|
||||
self.assertEqual(set(pack_ids2.mapped('location_id.id')), set([
|
||||
self.ref('stock.stock_location_components'),
|
||||
self.ref('stock.stock_location_14')]))
|
||||
|
||||
# put the move lines from delivery_order_wise2 into delivery_order_wise1
|
||||
for pack_id2 in pack_ids2:
|
||||
new_pack_id1 = pack_id2.copy(default={'picking_id': delivery_order_wise1.id, 'move_id': move1.id})
|
||||
new_pack_id1.qty_done = new_pack_id1.product_qty
|
||||
new_pack_id1.with_context(bypass_reservation_update=True).product_uom_qty = 0
|
||||
|
||||
new_move_lines = delivery_order_wise1.move_line_ids.filtered(lambda p: p.qty_done)
|
||||
self.assertEqual(sum(new_move_lines.mapped('product_qty')), 0)
|
||||
self.assertEqual(sum(new_move_lines.mapped('qty_done')), 5)
|
||||
self.assertEqual(set(new_move_lines.mapped('location_id.id')), set([
|
||||
self.ref('stock.stock_location_components'),
|
||||
self.ref('stock.stock_location_14')]))
|
||||
|
||||
# put the move line from delivery_order_wise1 into delivery_order_wise2
|
||||
new_pack_id2 = pack_ids1.copy(default={'picking_id': delivery_order_wise2.id, 'move_id': move2.id})
|
||||
new_pack_id2.qty_done = new_pack_id2.product_qty
|
||||
new_pack_id2.with_context(bypass_reservation_update=True).product_uom_qty = 0
|
||||
|
||||
new_move_lines = delivery_order_wise2.move_line_ids.filtered(lambda p: p.qty_done)
|
||||
self.assertEqual(len(new_move_lines), 1)
|
||||
self.assertEqual(sum(new_move_lines.mapped('product_qty')), 0)
|
||||
self.assertEqual(sum(new_move_lines.mapped('qty_done')), 5)
|
||||
self.assertEqual(new_move_lines.location_id.id, self.ref('stock.stock_location_14'))
|
||||
|
||||
# Process this picking
|
||||
delivery_order_wise1.do_transfer()
|
||||
|
||||
# Check there was no negative quant created by this picking
|
||||
|
||||
records = self.env['stock.quant'].search([
|
||||
('product_id', '=', product_wise.id),
|
||||
('quantity', '<', 0.0),
|
||||
('location_id.id', '=', self.ref('stock.stock_location_stock'))])
|
||||
self.assertEqual(len(records.ids), 0, 'This should not have created a negative quant')
|
||||
|
||||
# Check the other delivery order has changed its state back to ready
|
||||
self.assertEqual(delivery_order_wise2.state, 'assigned', "Delivery order 2 should be back in ready state")
|
||||
|
||||
# Process the second picking
|
||||
delivery_order_wise2.action_done()
|
||||
|
||||
# Check all quants are in Customers and there are no negative quants anymore
|
||||
records = self.env['stock.quant'].search([
|
||||
('product_id', '=', product_wise.id),
|
||||
('location_id', '!=', self.ref('stock.stock_location_suppliers'))])
|
||||
self.assertTrue(all([x.location_id.id == self.ref('stock.stock_location_customers') and x.quantity > 0.0 for x in records]),
|
||||
"Negative quant or wrong location detected")
|
||||
Reference in New Issue
Block a user