-
![]()
+
diff --git a/addons/portal/portal.py b/addons/portal/portal.py
index de39944e69f..4a96df1a65f 100644
--- a/addons/portal/portal.py
+++ b/addons/portal/portal.py
@@ -98,6 +98,7 @@ class portal(osv.osv):
def do_create_menu(self, cr, uid, ids, context=None):
""" create a parent menu for the given portals """
menu_obj = self.pool.get('ir.ui.menu')
+ ir_data = self.pool.get('ir.model.data')
menu_root = self._res_xml_id(cr, uid, 'portal', 'portal_menu')
for p in self.browse(cr, uid, ids, context):
@@ -110,7 +111,13 @@ class portal(osv.osv):
menu_id = menu_obj.create(cr, uid, menu_values, context)
# set the parent_menu_id to item_id
self.write(cr, uid, [p.id], {'parent_menu_id': menu_id}, context)
-
+ menu_values.pop('parent_id')
+ menu_values.pop('groups_id')
+ menu_values.update({'model': 'ir.ui.menu',
+ 'module': 'portal',
+ 'res_id': menu_id,
+ 'noupdate': 'True'})
+ data_id = ir_data.create(cr, uid, menu_values, context)
return True
def _assign_menu(self, cr, uid, ids, context=None):
diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py
index 55b843ec68b..164314c4573 100644
--- a/addons/procurement/procurement.py
+++ b/addons/procurement/procurement.py
@@ -567,4 +567,12 @@ class stock_warehouse_orderpoint(osv.osv):
return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context=context)
stock_warehouse_orderpoint()
+
+class product_product(osv.osv):
+ _inherit="product.product"
+ _columns = {
+ 'orderpoint_ids': fields.one2many('stock.warehouse.orderpoint', 'product_id', 'Minimum Stock Rule')
+ }
+product_product()
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/procurement/procurement_view.xml b/addons/procurement/procurement_view.xml
index 400412298cc..518a8900072 100644
--- a/addons/procurement/procurement_view.xml
+++ b/addons/procurement/procurement_view.xml
@@ -275,5 +275,30 @@
+
+
+ product.normal.form.orderpoint.inherit
+ product.product
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/product/__openerp__.py b/addons/product/__openerp__.py
index 81ec3a0ae64..846aa5881f2 100644
--- a/addons/product/__openerp__.py
+++ b/addons/product/__openerp__.py
@@ -61,7 +61,11 @@ Print product labels with barcode.
'partner_view.xml',
'process/product_process.xml'
],
- 'test':['test/product_report.yml','test/product_test.yml'],
+ 'test': [
+ 'product_pricelist_demo.yml',
+ 'test/product_uom.yml',
+ 'test/product_pricelist.yml',
+ ],
'installable': True,
'active': False,
'certificate': '0068861431437',
diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py
index db953c8a319..ea29292f445 100644
--- a/addons/product/pricelist.py
+++ b/addons/product/pricelist.py
@@ -271,7 +271,7 @@ class product_pricelist(osv.osv):
if price is not False:
price_limit = price
price = price * (1.0+(res['price_discount'] or 0.0))
- price = rounding(price, res['price_round'])
+ price = rounding(price, res['price_round']) #TOFIX: rounding with tools.float_rouding
price += (res['price_surcharge'] or 0.0)
if res['price_min_margin']:
price = max(price, price_limit+res['price_min_margin'])
diff --git a/addons/product/product.py b/addons/product/product.py
index 874680cb17d..a443ebe6033 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -218,6 +218,8 @@ class product_category(osv.osv):
'child_id': fields.one2many('product.category', 'parent_id', string='Child Categories'),
'sequence': fields.integer('Sequence', select=True, help="Gives the sequence order when displaying a list of product categories."),
'type': fields.selection([('view','View'), ('normal','Normal')], 'Category Type'),
+ 'parent_left': fields.integer('Left Parent', select=1),
+ 'parent_right': fields.integer('Right Parent', select=1),
}
@@ -225,7 +227,11 @@ class product_category(osv.osv):
'type' : lambda *a : 'normal',
}
- _order = "sequence, name"
+ _parent_name = "parent_id"
+ _parent_store = True
+ _parent_order = 'sequence, name'
+ _order = 'parent_left'
+
def _check_recursion(self, cr, uid, ids, context=None):
level = 100
while len(ids):
@@ -406,10 +412,11 @@ class product_product(osv.osv):
context = {}
quantity = context.get('quantity') or 1.0
pricelist = context.get('pricelist', False)
+ partner = context.get('partner', False)
if pricelist:
for id in ids:
try:
- price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist], id, quantity, context=context)[pricelist]
+ price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist], id, quantity, partner=partner, context=context)[pricelist]
except:
price = 0.0
res[id] = price
diff --git a/addons/product/product_demo.xml b/addons/product/product_demo.xml
index 2ed53ce0acf..a331d5c8b6b 100644
--- a/addons/product/product_demo.xml
+++ b/addons/product/product_demo.xml
@@ -321,6 +321,7 @@
product
+
TOW1
37.5
diff --git a/addons/product/product_pricelist_demo.yml b/addons/product/product_pricelist_demo.yml
new file mode 100644
index 00000000000..d5228422a83
--- /dev/null
+++ b/addons/product/product_pricelist_demo.yml
@@ -0,0 +1,62 @@
+-
+ !record {model: product.product, id: product_product_pc2}:
+ uom_id: product_uom_unit
+ categ_id: product_category_pc
+-
+ !record {model: product.pricelist, id: customer_pricelist}:
+ name: Customer Pricelist
+ type: sale
+ version_id:
+ - name: v1.0
+ date_start: 2012-01-01
+ items_id:
+ - name: Default pricelist
+ base: -1
+ base_pricelist_id: list0
+ - name: 10% Discount on PC2
+ sequence: 1
+ product_id: product_product_pc2
+ base: !eval (ref('product.list_price'))
+ price_discount: -0.10
+ - name: 1 surchange on PC3
+ sequence: 1
+ product_id: product_product_pc3
+ base: !eval (ref('product.list_price'))
+ price_surcharge: 1
+ - name: 5% Discount on all IT components
+ sequence: 1
+ min_quantity: 2
+ base: !eval (ref('product.list_price'))
+ categ_id: product_category_10
+ price_discount: -0.05
+ - name: v2.0 (Special Discount on all products during last 5 days in current year)
+ date_start: 2011-12-27
+ date_end: 2011-12-31
+ items_id:
+ - name: 30% Discount on all products
+ price_discount: -0.30
+ sequence: 1
+ base: !eval (ref('product.list_price'))
+-
+ !record {model: product.pricelist, id: supplier_pricelist}:
+ name: Supplier Pricelist
+ type: sale
+ version_id:
+ - name: v1.0
+ items_id:
+ - name: 20% Discount given by my supplier
+ sequence: 1
+ price_min_margin: 2
+ price_max_margin: -5
+ product_id: product_product_pc2
+ base: -2
+-
+ !record {model: pricelist.partnerinfo, id: supplier_pricelist0_product_pc2}:
+ suppinfo_id: supplierinfo6
+ min_quantity: 3
+ price: 405
+-
+ !record {model: pricelist.partnerinfo, id: supplier_pricelist1_product_pc2}:
+ suppinfo_id: supplierinfo6
+ min_quantity: 1
+ price: 455
diff --git a/addons/product/test/product_pricelist.yml b/addons/product/test/product_pricelist.yml
new file mode 100644
index 00000000000..2dbc4be1120
--- /dev/null
+++ b/addons/product/test/product_pricelist.yml
@@ -0,0 +1,75 @@
+-
+ In order to check the calculation of price of the products according to pricelist,
+-
+ I check sale price of PC2.
+-
+ !python {model: product.product}: |
+ context.update({'pricelist': ref("customer_pricelist"), 'quantity':1})
+ product = self.browse(cr, uid, ref("product_product_pc2"), context=context)
+ assert product.price == product.lst_price-product.lst_price*(0.10), "Sell price is not correspond."
+-
+ I check sale price of PC3.
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref("product_product_pc3"), context=context)
+ assert product.price == product.lst_price + 1, "Sell price is not correspond."
+-
+ I check sale price of IT componet.
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref("product_product_mb1"), context=context)
+ assert product.price == product.lst_price, "Sell price is not correspond."
+
+-
+ I check sale price of IT componet if more than 3 PCE.
+-
+ !python {model: product.product}: |
+ context.update({'quantity':5})
+ product = self.browse(cr, uid, ref("product_product_mb1"), context=context)
+ assert product.price == product.lst_price-product.lst_price*(0.05), "Sell price is not correspond."
+-
+ I check sale price of PC4.
+-
+ !python {model: product.product}: |
+ context.update({'quantity':1})
+ product = self.browse(cr, uid, ref("product_product_pc4"), context=context)
+ assert product.price == product.lst_price, "Sell price is not correspond."
+
+-
+ I check sale price of PC4 on end of year.
+-
+ !python {model: product.product}: |
+ context.update({'quantity':1, 'date': '2011-12-31'})
+ product = self.browse(cr, uid, ref("product_product_pc4"), context=context)
+ assert product.price == product.lst_price-product.lst_price*(0.30), "Sell price is not correspond."
+
+-
+ I check cost price of PC2.
+-
+ !python {model: product.product}: |
+ context.update({'quantity':1, 'date': False, 'partner': ref('base.res_partner_4'), 'pricelist': ref("supplier_pricelist")})
+ product = self.browse(cr, uid, ref("product_product_pc2"), context=context)
+ assert product.price == 450, "cost price is not correspond."
+-
+ I check cost price of PC2 if more than 3 PCE.
+-
+ !python {model: product.product}: |
+ context.update({'quantity':3})
+ product = self.browse(cr, uid, ref("product_product_pc2"), context=context)
+ assert product.price == 400, "cost price is not correspond."
+
+-
+ I print the sale prices report.
+-
+ !python {model: product.product}: |
+ ctx = {'model': 'product.product', 'date': '2011-12-30', 'active_ids': [ref('product.product_product_pc1'), ref('product.product_product_pc2'), ref('product.product_product_pc3'), ref('product.product_product_pc4')]}
+ data_dict = {
+ 'qty1': 1,
+ 'qty2': 5,
+ 'qty3': 10,
+ 'qty4': 15,
+ 'qty5': 30,
+ 'price_list':ref('customer_pricelist'),
+ }
+ from tools import test_reports
+ test_reports.try_report_action(cr, uid, 'action_product_price_list',wiz_data=data_dict, context=ctx, our_module='product')
diff --git a/addons/product/test/product_report.yml b/addons/product/test/product_report.yml
deleted file mode 100644
index 397c2c9d0b6..00000000000
--- a/addons/product/test/product_report.yml
+++ /dev/null
@@ -1,16 +0,0 @@
--
- Print the Products Pricelists Report through the wizard
--
- !python {model: product.product}: |
- ctx={}
- ctx.update({'model': 'product.product','active_ids': [ref('product.product_product_pc1'), ref('product.product_product_pc3')]})
- data_dict = {'qty1': 1,
- 'qty2': 5,
- 'qty3': 10,
- 'qty4': 0,
- 'qty5': 0,
- 'price_list':ref('product.list0')}
- from tools import test_reports
- test_reports.try_report_action(cr, uid, 'action_product_price_list',wiz_data=data_dict, context=ctx, our_module='product')
-
-
diff --git a/addons/product/test/product_test.yml b/addons/product/test/product_test.yml
deleted file mode 100644
index ae75a552c79..00000000000
--- a/addons/product/test/product_test.yml
+++ /dev/null
@@ -1,33 +0,0 @@
--
- In order to test product,I start by creating a 20KG UOM for 'Sugar'
--
- !record {model: product.uom, id: product_20k_uom_sugar}:
- name: 20KG
- uom_type: bigger
- category_id: product.product_uom_categ_kgm
- factor_inv: 20
--
- I create a 10KG UOM for 'Sugar'
--
- !record {model: product.uom, id: product_10k_uom_sugar}:
- name: 10KG
- uom_type: bigger
- category_id: product.product_uom_categ_kgm
- factor_inv: 10
--
- I create a new product 'Sugar' in 20KG UOM.
--
- !record {model: product.product, id: product_sugar_id1}:
- categ_id: 'product.product_category_rawmaterial0'
- name: Sugar 20KG
- procure_method: make_to_order
- standard_price: 400.0
- uom_id: product.product_20k_uom_sugar
- uom_po_id: product.product_20k_uom_sugar
--
- I test onchanged on UOM, Create Duplicate Product and Delete original Product.
--
- !python {model: product.product}: |
- self.onchange_uom(cr ,uid, [ref("product_sugar_id1")], ref("product.product_20k_uom_sugar"), ref("product.product_10k_uom_sugar"))
- self.copy(cr, uid, ref("product_sugar_id1"))
- self.unlink(cr, uid, [ref("product_sugar_id1")])
diff --git a/addons/product/test/product_uom.yml b/addons/product/test/product_uom.yml
new file mode 100644
index 00000000000..04928d43d87
--- /dev/null
+++ b/addons/product/test/product_uom.yml
@@ -0,0 +1,15 @@
+-
+ In order to test conversation of UOM,
+-
+ I convert Grams into TON with price.
+-
+ !python {model: product.uom}: |
+ from_uom_id = ref("product_uom_gram")
+ to_uom_id = ref("product_uom_ton")
+ price = 2
+ qty = 1020000
+ price = self._compute_price(cr, uid, from_uom_id, price, to_uom_id)
+ qty = self._compute_qty(cr, uid, from_uom_id, qty, to_uom_id)
+ assert qty == 1.02, "Qty is not correspond."
+ assert price == 2000000.0, "Price is not correspond."
+
diff --git a/addons/project/security/ir.model.access.csv b/addons/project/security/ir.model.access.csv
index e919f09cee1..3dc9cdbab46 100644
--- a/addons/project/security/ir.model.access.csv
+++ b/addons/project/security/ir.model.access.csv
@@ -17,3 +17,4 @@ access_account_analytic_line_project,account.analytic.line project,analytic.mode
access_project_task_history,project.task.history project,project.model_project_task_history,project.group_project_user,1,1,1,0
access_project_task_history_cumulative,project.task.history project,project.model_project_task_history_cumulative,project.group_project_manager,1,0,0,0
access_resource_calendar,project.resource_calendar manager,resource.model_resource_calendar,project.group_project_manager,1,0,0,0
+access_mail_message_project_user,project.mail.message.user,mail.model_mail_message,project.group_project_user,1,1,1,0
diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py
index 948352940a0..318e305b8ea 100644
--- a/addons/sale/__openerp__.py
+++ b/addons/sale/__openerp__.py
@@ -76,10 +76,10 @@ Dashboard for Sales Manager that includes:
'company_view.xml',
'sale_workflow.xml',
'sale_sequence.xml',
+ 'sale_report.xml',
'sale_data.xml',
'sale_view.xml',
'report/sale_report_view.xml',
- 'sale_report.xml',
'stock_view.xml',
'process/sale_process.xml',
'board_sale_view.xml',
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index 478c8276a90..f5b797c9f66 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -102,12 +102,16 @@
+
diff --git a/addons/stock/stock_demo.yml b/addons/stock/stock_demo.yml
new file mode 100644
index 00000000000..99cde47b843
--- /dev/null
+++ b/addons/stock/stock_demo.yml
@@ -0,0 +1,102 @@
+-
+ !record {model: stock.location, id: location_refrigerator}:
+ name: Refrigerator
+ usage: internal
+-
+ !record {model: stock.location, id: location_delivery_counter}:
+ name: Delivery Counter
+ usage: internal
+-
+ !record {model: stock.location, id: location_refrigerator_small}:
+ name: Small Refrigerator
+ usage: internal
+ location_id: location_refrigerator
+-
+ !record {model: stock.location, id: location_opening}:
+ name: opening
+ usage: inventory
+-
+ !record {model: stock.location, id: location_convenience_shop}:
+ name: Convenient Store
+ chained_auto_packing: auto
+ chained_location_type: fixed
+ usage: supplier
+ chained_location_id: location_refrigerator
+ location_id: stock_location_suppliers
+-
+ !record {model: stock.warehouse, id: warehouse_icecream}:
+ name: Ice Cream Shop
+ lot_input_id: location_refrigerator
+ lot_stock_id: location_refrigerator
+ lot_output_id: location_delivery_counter
+-
+ !record {model: product.product, id: product_icecream}:
+ default_code: 001
+ name: Ice Cream
+ type: product
+ categ_id: product.cat1
+ supply_method: buy
+ list_price: 100.0
+ standard_price: 70.0
+ uom_id: product.product_uom_kgm
+ uom_po_id: product.product_uom_kgm
+ procure_method: make_to_stock
+ property_stock_inventory: location_opening
+ property_stock_account_input: location_refrigerator
+ property_stock_account_output: location_delivery_counter
+ 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: Lot0 for Ice cream
+ product_id: product_icecream
+-
+ !record {model: stock.production.lot, id: lot_icecream_1}:
+ name: Lot1 for Ice cream
+ product_id: product_icecream
+-
+ !record {model: stock.inventory, id: stock_inventory_icecream}:
+ name: Inventory for icecream
+-
+ !record {model: stock.inventory.line, id: stock_inventory_line_icecream_lot0}:
+ product_id: product_icecream
+ product_uom: product.product_uom_kgm
+ inventory_id: stock_inventory_icecream
+ product_qty: 50.0
+ prod_lot_id: lot_icecream_0
+ location_id: location_refrigerator
+-
+ !record {model: stock.inventory.line, id: stock_inventory_line_icecream_lot1}:
+ product_id: product_icecream
+ product_uom: product.product_uom_kgm
+ inventory_id: stock_inventory_icecream
+ product_qty: 40.0
+ prod_lot_id: lot_icecream_1
+ location_id: location_refrigerator
+
+-
+ !record {model: stock.picking, id: outgoing_shipment}:
+ type: out
+ location_dest_id: location_delivery_counter
+-
+ !record {model: stock.move, id: outgoing_shipment_icecream}:
+ picking_id: outgoing_shipment
+ product_id: product_icecream
+ product_uom: product.product_uom_kgm
+ product_qty: 130.0
+ location_id: location_refrigerator
+ location_dest_id: location_delivery_counter
+-
+ !record {model: stock.picking, id: incomming_shipment}:
+ type: in
+ invoice_state: 2binvoiced
+ address_id: base.res_partner_address_9
+ location_dest_id: location_refrigerator
+-
+ !record {model: stock.move, id: incomming_shipment_icecream}:
+ picking_id: incomming_shipment
+ product_id: product_icecream
+ product_uom: product.product_uom_kgm
+ product_qty: 50.0
+ location_id: location_convenience_shop
+ location_dest_id: location_refrigerator
diff --git a/addons/stock/stock_demo_picking.yml b/addons/stock/stock_demo_picking.yml
deleted file mode 100644
index 6301ab7a0cb..00000000000
--- a/addons/stock/stock_demo_picking.yml
+++ /dev/null
@@ -1,25 +0,0 @@
--
- !record {model: stock.picking, id: stock_picking_1}:
- type: out
- company_id: base.main_company
- address_id: res_partner_address_fabien0
--
- !record {model: stock.move, id: stock_move_1}:
- product_id: product.product_product_cpu1
- product_uom: product.product_uom_unit
- product_uos_qty: 5.0
- product_qty: 5.0
- location_dest_id: stock.stock_location_customers
- location_id: stock.stock_location_stock
- name: CPU1, Processor AMD Athlon XP 1800
- picking_id: stock_picking_1
--
- !record {model: stock.move, id: stock_move_2}:
- product_id: product.product_product_cpu3
- product_uom: product.product_uom_unit
- product_uos_qty: 5.0
- product_qty: 5.0
- location_dest_id: stock.stock_location_customers
- location_id: stock.stock_location_stock
- name: CPU3, Processor AMD Athlon XP 1800
- picking_id: stock_picking_1
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index cbcc1eee4c6..2ba44fb6e97 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -171,7 +171,7 @@
-
+
@@ -709,7 +709,7 @@
-
+
@@ -902,7 +902,7 @@
-
+
@@ -1058,7 +1058,7 @@
form
tree,form,calendar
[('type','=','out')]
- {'default_type': 'out', 'contact_display': 'partner_address', 'search_default_available': 1}
+ {'default_type': 'out', 'contact_display': 'partner_address', 'search_default_confirmed': 1, 'search_default_available': 1}
This is the list of all delivery orders that have to be prepared, according to your different sales orders and your logistics rules.
@@ -1123,7 +1123,7 @@
-
+
diff --git a/addons/stock/test/opening_stock.yml b/addons/stock/test/opening_stock.yml
new file mode 100644
index 00000000000..0cb6c0b78ad
--- /dev/null
+++ b/addons/stock/test/opening_stock.yml
@@ -0,0 +1,131 @@
+-
+ I update the price of the Ice-cream.
+-
+ !python {model: stock.change.standard.price}: |
+ context.update({'active_model':'product.product', 'active_id': ref('product_icecream'), 'active_ids':[ref('product_icecream')]})
+-
+ !record {model: stock.change.standard.price, id: change_price}:
+ new_price: 120
+-
+ !python {model: stock.change.standard.price}: |
+ self.change_price(cr, uid, [ref('change_price')], context=context)
+-
+ I check price of Ice-cream after update price.
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref('product_icecream'), context=context)
+ assert product.standard_price == 120, "Price is not updated."
+-
+ I update the current stock of the Ice-cream with 10 kgm in Small Refrigerator in lot0.
+-
+ !record {model: stock.change.product.qty, id: change_qty}:
+ location_id: location_refrigerator_small
+ new_quantity: 10
+ product_id: product_icecream
+ prodlot_id: lot_icecream_1
+-
+ !python {model: stock.change.product.qty}: |
+ self.change_product_qty(cr, uid, [ref('change_qty')], context=context)
+-
+ I check available stock of Ice-cream after update stock.
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref('product_icecream'), context=context)
+ assert product.qty_available == 10, "Stock is not updated."
+-
+ I merge inventory.
+-
+ !python {model: stock.inventory.merge }: |
+ context.update({'active_model': 'stock.inventory', 'active_id': ref('stock_inventory_icecream'), 'active_ids': [ref('stock_inventory_icecream')]})
+-
+ !record {model: stock.inventory.merge, id: merge_inventory}:
+-
+ !python {model: stock.inventory.merge }: |
+ self.do_merge(cr, uid, [ref('merge_inventory')], context=context)
+-
+ I cancel inventory.
+-
+ !python {model: stock.inventory}: |
+ self.action_cancel_inventory(cr, uid, [ref('stock_inventory_icecream')])
+-
+ I reset to draft inventory.
+-
+ !python {model: stock.inventory}: |
+ self.action_cancel_draft(cr, uid, [ref('stock_inventory_icecream')])
+-
+ I confirm physical inventory of Ice-cream which are came in different lots.
+-
+ !python {model: stock.inventory}: |
+ self.action_confirm(cr, uid, [ref('stock_inventory_icecream')], context=context)
+-
+ I check move details after confirmed physical inventory.
+-
+ !python {model: stock.inventory}: |
+ inventory = self.browse(cr, uid, ref('stock_inventory_icecream'), context=context)
+ assert len(inventory.move_ids) == len(inventory.inventory_line_id), "moves are not correspond."
+ for move_line in inventory.move_ids:
+ for line in inventory.inventory_line_id:
+ if move_line.product_id.id == line.product_id.id and move_line.prodlot_id.id == line.prod_lot_id.id:
+ location_id = line.product_id.product_tmpl_id.property_stock_inventory.id
+ assert move_line.product_qty == line.product_qty, "Qty is not correspond."
+ assert move_line.product_uom.id == line.product_uom.id, "UOM is not correspond."
+ assert move_line.date == inventory.date, "Date is not correspond."
+ assert move_line.location_id.id == location_id, "Source location is not correspond."
+ assert move_line.location_dest_id.id == line.location_id.id, "Destination location is not correspond."
+ assert move_line.state == 'confirmed', "Move is not confirmed."
+-
+ I split inventory line.
+-
+ !python {model: stock.inventory.line.split}: |
+ context.update({'active_model': 'stock.inventory.line', 'active_id': ref('stock_inventory_line_icecream_lot0'), 'active_ids': [ref('stock_inventory_line_icecream_lot0')]})
+-
+ !record {model: stock.inventory.line.split, id: split_inventory_lot0}:
+ use_exist: True
+ line_exist_ids:
+ - quantity: 6
+ prodlot_id: lot_icecream_0
+ - quantity: 4
+ prodlot_id: lot_icecream_0
+-
+ !python {model: stock.inventory.line.split }: |
+ self.split_lot(cr, uid, [ref('split_inventory_lot0')], context=context)
+-
+ I fill inventory line.
+-
+ !python {model: stock.fill.inventory}: |
+ context.update({'active_model': 'stock.inventory', 'active_id': ref('stock_inventory_icecream'), 'active_ids': [ref('stock_inventory_icecream')]})
+-
+ !record {model: stock.fill.inventory, id: fill_inventory}:
+ location_id: location_refrigerator
+ recursive: True
+-
+ !python {model: stock.fill.inventory }: |
+ self.fill_inventory(cr, uid, [ref('fill_inventory')], context=context)
+
+-
+ Now I check vitual stock of Ice-cream after confirmed physical inventory.
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref('product_icecream'), context=context)
+ assert product.virtual_available == 100, "Vitual stock is not updated."
+-
+ I close physical inventory of Ice-cream.
+-
+ !python {model: stock.inventory}: |
+ self.action_done(cr, uid, [ref('stock_inventory_icecream')], context=context)
+-
+ I check closed move and real stock of Ice-cream after closed physical inventory.
+-
+ !python {model: stock.inventory}: |
+ inventory = self.browse(cr, uid, ref('stock_inventory_icecream'), context=context)
+ assert inventory.state == 'done', "inventory is not closed."
+ for move_line in inventory.move_ids:
+ assert move_line.state == 'done', "Move is not closed."
+ product = self.pool.get('product.product').browse(cr, uid, ref('product_icecream'), context=context)
+ product.qty_available == 100, "Real stock is not updated."
+-
+ I check stock in lot.
+-
+ !python {model: stock.production.lot}: |
+ lot = self.browse(cr, uid, ref('lot_icecream_0'), context=context)
+ assert lot.stock_available == 50, "Stock in lot is not correspond."
diff --git a/addons/stock/test/shipment.yml b/addons/stock/test/shipment.yml
new file mode 100644
index 00000000000..dad6edd78a5
--- /dev/null
+++ b/addons/stock/test/shipment.yml
@@ -0,0 +1,263 @@
+-
+ I confirm outgoing shipment of 130 kgm Ice-cream.
+-
+ !workflow {model: stock.picking, action: button_confirm, ref: outgoing_shipment}
+-
+ I check shipment details after confirmed.
+-
+ !python {model: stock.picking}: |
+ shipment = self.browse(cr, uid, ref("outgoing_shipment"))
+ assert shipment.state == "confirmed", "Shipment should be confirmed."
+ for move_line in shipment.move_lines:
+ assert move_line.state == "confirmed", "Move should be confirmed."
+
+-
+ Now I check vitual stock of Ice-cream after confirmed outgoing shipment.
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref('product_icecream'), context=context)
+ product.virtual_available == -30, "Vitual stock is not updated."
+
+-
+ I confirm incomming shipment of 50 kgm Ice-cream.
+-
+ !workflow {model: stock.picking, action: button_confirm, ref: incomming_shipment}
+-
+ I receive 40kgm Ice-cream so I make backorder of incomming shipment for 40 kgm.
+-
+ !python {model: stock.partial.picking}: |
+ context.update({'active_model': 'stock.picking', 'active_id': ref('incomming_shipment'), 'active_ids': [ref('incomming_shipment')]})
+-
+ !record {model: stock.partial.picking, id: partial_incomming}:
+ move_ids:
+ - quantity: 40
+ product_id: product_icecream
+ product_uom: product.product_uom_kgm
+ move_id: incomming_shipment_icecream
+ location_id: location_convenience_shop
+ location_dest_id: location_refrigerator
+-
+ !python {model: stock.partial.picking }: |
+ self.do_partial(cr, uid, [ref('partial_incomming')], context=context)
+-
+ I check backorder shipment after received partial shipment.
+-
+ !python {model: stock.picking}: |
+ shipment = self.browse(cr, uid, ref("incomming_shipment"))
+ backorder = shipment.backorder_id
+ assert backorder, "Backorder should be created after partial shipment."
+ assert backorder.state == 'done', "Backorder should be close after received."
+ for move_line in backorder.move_lines:
+ assert move_line.product_qty == 40, "Qty in backorder is not correspond."
+ assert move_line.state == 'done', "Move line of backorder should be closed."
+-
+ I receive another 10kgm Ice-cream.
+-
+ !record {model: stock.partial.picking, id: partial_incomming}:
+ move_ids:
+ - quantity: 10
+ product_id: product_icecream
+ product_uom: product.product_uom_kgm
+ move_id: incomming_shipment_icecream
+ location_id: location_convenience_shop
+ location_dest_id: location_refrigerator
+-
+ !python {model: stock.partial.picking }: |
+ self.do_partial(cr, uid, [ref('partial_incomming')], context=context)
+
+-
+ I check incomming shipment after received.
+-
+ !python {model: stock.picking}: |
+ shipment = self.browse(cr, uid, ref("incomming_shipment"))
+ assert shipment.state == 'done', "shipment should be close after received."
+ for move_line in shipment.move_lines:
+ assert move_line.product_qty == 10, "Qty is not correspond."
+ assert move_line.state == 'done', "Move line should be closed."
+
+-
+ I return last incomming shipment for 10 kgm Ice-cream.
+-
+ !record {model: stock.return.picking, id: return_incomming}:
+ invoice_state: none
+-
+ !python {model: stock.return.picking }: |
+ self.create_returns(cr, uid, [ref('return_incomming')], context=context)
+-
+ I cancel incomming shipment after return it.
+-
+ !python {model: stock.picking}: |
+ self.action_cancel(cr, uid, [ref("incomming_shipment")], context=context)
+-
+ I make invoice of backorder of incomming shipment.
+-
+ !python {model: stock.invoice.onshipping}: |
+ shipment = self.pool.get('stock.picking').browse(cr, uid, ref("incomming_shipment"))
+ context.update({'active_model': 'stock.picking', 'active_id': shipment.backorder_id.id, 'active_ids': [shipment.backorder_id.id]})
+-
+ !record {model: stock.invoice.onshipping, id: invoice_incomming}:
+ group: False
+-
+ !python {model: stock.invoice.onshipping }: |
+ self.create_invoice(cr, uid, [ref('invoice_incomming')], context=context)
+-
+ I check invoice state of backorder of incomming shipment.
+-
+ !python {model: stock.picking}: |
+ shipment = self.browse(cr, uid, ref("incomming_shipment"))
+ assert shipment.backorder_id.invoice_state == 'invoiced', 'Invoice state is not upadted.'
+-
+ I check availabile stock after received incomming shipping.
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref('product_icecream'), context=context)
+ assert product.qty_available == 140, "Stock is not correspond."
+ assert product.virtual_available == 10, "Vitual stock is not correspond."
+
+-
+ I split incomming shipment into lots. each lot contain 10 kgm Ice-cream.
+-
+ !python {model: stock.picking}: |
+ shipment = self.browse(cr, uid, ref("incomming_shipment"))
+ move_ids = [x.id for x in shipment.backorder_id.move_lines]
+ context.update({'active_model': 'stock.move', 'active_id': move_ids[0], 'active_ids': move_ids})
+-
+ !record {model: stock.move.split, id: split_lot_incomming}:
+ line_ids:
+ - name: incoming_lot0
+ quantity: 10
+ - name: incoming_lot1
+ quantity: 10
+ - name: incoming_lot2
+ quantity: 10
+ - name: incoming_lot3
+ quantity: 10
+
+-
+ !python {model: stock.move.split }: |
+ self.split_lot(cr, uid, [ref('split_lot_incomming')], context=context)
+-
+ I check move lines after spliting
+-
+ !python {model: stock.move}: |
+ lot = self.pool.get('stock.move.split').browse(cr, uid, ref('split_lot_incomming'), context=context)
+ lot_ids = self.pool.get('stock.production.lot').search(cr, uid, [('name','in',[x.name for x in lot.line_ids])])
+ assert len(lot_ids) == 4, 'lots of incomming shipment are not correspond.'
+ move_ids = self.search(cr, uid, [('location_dest_id','=',ref('location_refrigerator')),('prodlot_id','in',lot_ids)])
+ assert len(move_ids) == 4, 'move lines are not correspond per prodcution lot after splited.'
+ for move in self.browse(cr, uid, move_ids, context=context):
+ assert move.prodlot_id.name in ['incoming_lot0', 'incoming_lot1', 'incoming_lot2', 'incoming_lot3'], "lot is not correspond."
+ assert move.product_qty == 10, "qty is not correspond per production lot."
+ context.update({'active_model':'stock.move', 'active_id':move_ids[0],'active_ids': move_ids})
+-
+ I consume 1 kgm ice-cream from each incoming lots into internal production.
+-
+ !record {model: stock.move.consume, id: consume_lot_incomming}:
+ product_qty: 1
+ location_id: location_refrigerator
+-
+ !python {model: stock.move.consume}: |
+ self.do_move_consume(cr, uid, [ref('consume_lot_incomming')], context=context)
+-
+ I scrap 10 gm ice-cream from each incoming lots into scrap location.
+-
+ !record {model: stock.move.scrap, id: scrap_lot_incomming}:
+ product_qty: 0.010
+-
+ !python {model: stock.move.scrap}: |
+ self.move_scrap(cr, uid, [ref('scrap_lot_incomming')], context=context)
+-
+ I check stock in scrap location and refrigerator location.
+-
+ !python {model: stock.location}: |
+ ctx = {'product_id': ref('product_icecream')}
+ refrigerator_location = self.browse(cr, uid, ref('location_refrigerator'), context=ctx)
+ assert refrigerator_location.stock_real == 131.96, 'stock is not correspond in refrigerator location.'
+ scrapped_location = self.browse(cr, uid, ref('stock_location_scrapped'), context=ctx)
+ assert scrapped_location.stock_real == 0.010*4, 'scraped stock is not correspond in scrap location.'
+ production_location = self.browse(cr, uid, ref('location_production'), context=ctx)
+ assert production_location.stock_real == 1*4, 'consume stock is not correspond in production location.' #TOFIX: consume stock is not updated in default production location of product.
+
+-
+ I check availabile stock after consumed and scraped.
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref('product_icecream'), context=context)
+ assert product.qty_available == 131.96, "Stock is not correspond."
+ assert round(product.virtual_available, 2) == 1.96, "Vitual stock is not correspond."
+-
+ I trace all incoming lots.
+-
+ !python {model: stock.production.lot }: |
+ lot = self.pool.get('stock.move.split').browse(cr, uid, ref('split_lot_incomming'), context=context)
+ lot_ids = self.search(cr, uid, [('name', 'in', [x.name for x in lot.line_ids])])
+ self.action_traceability(cr, uid, lot_ids, context=context)
+-
+ I check outgoing shipment after stock availablity in refrigerator.
+-
+ !python {model: stock.picking}: |
+ shipment = self.browse(cr, uid, ref("outgoing_shipment"), context=context)
+ self.pool.get('stock.move').action_assign(cr, uid, [x.id for x in shipment.move_lines]) #TOFIX: assignment of move lines should be call before testing assigment otherwise picking never gone in assign state
+ #TOFIX: shipment should be assigned if stock available
+ #assert shipment.state == "assigned", "Shipment should be assigned."
+ #for move_line in shipment.move_lines:
+ # assert move_line.state == "assigned", "Move should be assigned."
+ self.force_assign(cr, uid, [shipment.id])
+-
+ I deliver 5kgm Ice-cream to customer so I make partial deliver
+-
+ !python {model: stock.partial.move}: |
+ context.update({'active_model': 'stock.move', 'active_id': ref('outgoing_shipment_icecream'), 'active_ids': [ref('outgoing_shipment_icecream')]})
+-
+ !record {model: stock.partial.move, id: partial_outgoing_icecream}:
+ move_ids:
+ - quantity: 5
+ product_id: product_icecream
+ product_uom: product.product_uom_kgm
+ move_id: outgoing_shipment_icecream
+ location_id: location_refrigerator
+ location_dest_id: location_delivery_counter
+-
+ !python {model: stock.partial.move }: |
+ self.do_partial(cr, uid, [ref('partial_outgoing_icecream')], context=context)
+
+-
+ I packing outgoing shipment into box per 10kgm with unique tracking lot.
+-
+ !python {model: stock.move}: |
+ stock_split = self.pool.get('stock.split.into')
+ move = self.browse(cr, uid, ref('outgoing_shipment_icecream'), context=context)
+ context.update({'active_model': 'stock.move', 'active_id': move.id, 'active_ids': [move.id]})
+ total_qty = move.product_qty
+ split_qty = 10
+ while(total_qty>0):
+ split_id = stock_split.create(cr, uid, {'quantity': split_qty}, context=context)
+ stock_split.split(cr, uid, [split_id], context=context)
+ total_qty -= split_qty
+-
+ I deliver outgoing shipment.
+-
+ !python {model: stock.partial.picking}: |
+ context.update({'active_model': 'stock.picking', 'active_id': ref('outgoing_shipment'), 'active_ids': [ref('outgoing_shipment')]})
+-
+ !record {model: stock.partial.picking, id: partial_outgoing}:
+ picking_id: outgoing_shipment
+-
+ !python {model: stock.partial.picking }: |
+ self.do_partial(cr, uid, [ref('partial_outgoing')], context=context)
+
+-
+ I check outgoing shipment after deliver.
+-
+ !python {model: stock.picking}: |
+ shipment = self.browse(cr, uid, ref("outgoing_shipment"), context=context)
+ assert shipment.state == "done", "Shipment should be closed."
+ for move_line in shipment.move_lines:
+ assert move_line.state == "done", "Move should be closed."
+-
+ I check availabile stock after deliver.
+-
+ !python {model: product.product}: |
+ product = self.browse(cr, uid, ref('product_icecream'), context=context)
+ assert round(product.qty_available, 2) == 1.96, "Stock is not correspond."
+ assert round(product.virtual_available, 2) == 1.96, "Vitual stock is not correspond."
diff --git a/addons/stock/test/stock_demo_backorder.yml b/addons/stock/test/stock_demo_backorder.yml
deleted file mode 100644
index 986a59c7349..00000000000
--- a/addons/stock/test/stock_demo_backorder.yml
+++ /dev/null
@@ -1,65 +0,0 @@
--
- In order to test partial delivery and back orders, I will use a delivery order with 5 CPU1 and 5 CPU3
--
- I confirm and force the availability of all products on the picking OUT001
--
- !python {model: stock.picking}: |
- self.draft_force_assign(cr, uid, [ref('stock.stock_picking_1')], {})
- self.force_assign(cr, uid, [ref('stock.stock_picking_1')], {})
--
- After having confirmed the picking and its two lines, I add a new move line in draft state with 7 FAN2
--
- !record {model: stock.move, id: stock_move_3}:
- product_id: product.product_product_fan2
- product_uom: product.product_uom_unit
- product_uos_qty: 7.0
- product_qty: 7.0
- location_dest_id: stock.stock_location_customers
- location_id: stock.stock_location_stock
- name: CPU3, Processor AMD Athlon XP 1800
- picking_id: stock_picking_1
-- |
- I click on 'Process Now' to process the delivery order and I change quantities to:
- 7 CPU1, 0 CPU3, 3 FAN2 and a new product of 4 PC1
--
- !python {model: stock.picking}: |
- result = self.action_process(cr, uid, [ref('stock.stock_picking_1')], {})['res_id']
- pick = self.pool.get('stock.partial.picking').browse(cr, uid, result, {})
- lobj = self.pool.get('stock.partial.picking.line')
- for line in pick.move_ids:
- if line.product_id.id == ref('product.product_product_cpu3'):
- lobj.write(cr, uid, [line.id], {
- 'quantity': 0.0
- }, {})
- elif line.product_id.id == ref('product.product_product_cpu1'):
- lobj.write(cr, uid, [line.id], {
- 'quantity': 7.0
- }, {})
- elif line.product_id.id == ref('product.product_product_fan2'):
- lobj.write(cr, uid, [line.id], {
- 'quantity': 3.0
- }, {})
- lobj.create(cr, uid, {
- 'product_id': ref('product.product_product_pc1'),
- 'quantity': 2.0,
- 'product_uom': ref('product.product_uom_unit'),
- 'location_id': ref('stock.stock_location_stock'),
- 'location_dest_id': ref('stock.stock_location_customers'),
- 'wizard_id': result
- }, {})
- self.pool.get('stock.partial.picking').do_partial(cr, uid, [result], {})
--
- I test that the back order contains 5 CPU3, 4 FAN2 and nothing else
--
- !python {model: stock.picking}: |
- pick = self.browse(cr, uid, ref('stock.stock_picking_1'), {})
- for line in pick.move_lines:
- if line.product_id.id == ref('product.product_product_cpu3'):
- assert line.product_qty == 5.0, "Wrong quantity %.2f for CPU3 back order" % (line.product_qty,)
- elif line.product_id.id == ref('product.product_product_fan2'):
- assert line.product_qty == 4.0, "Wrong quantity %.2f for FAN2 back order" % (line.product_qty,)
- elif line.product_id.id == ref('product.product_product_pc1'):
- assert line.product_qty == 0.0, "Wrong quantity for PC1 back order"
- else:
- assert line.product_qty == 0.0, "Wrong quantity for %s back order" % (line.product_id.code,)
-
diff --git a/addons/stock/test/stock_report.yml b/addons/stock/test/stock_report.yml
index 41acade696a..5c5932446eb 100644
--- a/addons/stock/test/stock_report.yml
+++ b/addons/stock/test/stock_report.yml
@@ -1,40 +1,41 @@
-
- In order to test the PDF reports defined on a stock, we will print a Stock Overviewall(children) report
+ I print a stock overview report of location.
-
!python {model: stock.location}: |
import netsvc, tools, os
- (data, format) = netsvc.LocalService('report.lot.stock.overview_all').create(cr, uid, [ref('stock.stock_location_stock')], {}, {})
- if tools.config['test_report_directory']:
- file(os.path.join(tools.config['test_report_directory'], 'stock-overviewall'+format), 'wb+').write(data)
--
- In order to test the PDF reports defined on stock inventory, we will print a Stock Inventory Move report
--
- !python {model: stock.inventory}: |
- import netsvc, tools, os
- (data, format) = netsvc.LocalService('report.stock.inventory.move').create(cr, uid, [ref('stock.stock_inventory_0')], {}, {})
- if tools.config['test_report_directory']:
- file(os.path.join(tools.config['test_report_directory'], 'stock-stock_inventory_move.'+format), 'wb+').write(data)
--
- In order to test the PDF reports defined on a stock, we will print a Stock Overview report
--
- !python {model: stock.location}: |
- import netsvc, tools, os
- (data, format) = netsvc.LocalService('report.lot.stock.overview').create(cr, uid, [ref('stock.stock_location_14')], {}, {})
+ (data, format) = netsvc.LocalService('report.lot.stock.overview').create(cr, uid, [ref('location_refrigerator')], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'stock-overview'+format), 'wb+').write(data)
-
- In order to test the PDF reports defined on a stock, we will print a Stock Picking List report
+ I print a Stock Overview report of location with child location.
+-
+ !python {model: stock.location}: |
+ import netsvc, tools, os
+ (data, format) = netsvc.LocalService('report.lot.stock.overview_all').create(cr, uid, [ref('location_refrigerator')], {}, {})
+ if tools.config['test_report_directory']:
+ file(os.path.join(tools.config['test_report_directory'], 'stock-overviewall'+format), 'wb+').write(data)
+-
+ I print a Stock Inventory report.
+-
+ !python {model: stock.inventory}: |
+ import netsvc, tools, os
+ (data, format) = netsvc.LocalService('report.stock.inventory.move').create(cr, uid, [ref('stock_inventory_icecream')], {}, {})
+ if tools.config['test_report_directory']:
+ file(os.path.join(tools.config['test_report_directory'], 'stock-stock_inventory_move.'+format), 'wb+').write(data)
+-
+ I print a outgoing shipment report.
-
!python {model: stock.picking}: |
import netsvc, tools, os
- (data, format) = netsvc.LocalService('report.stock.picking.list').create(cr, uid, [ref('stock.stock_picking_0')], {}, {})
+ (data, format) = netsvc.LocalService('report.stock.picking.list').create(cr, uid, [ref('outgoing_shipment')], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'stock-picking_list'+format), 'wb+').write(data)
-
- In order to test the PDF reports defined on a Stock, we will print Product Stock Report
+ I print stock Report.
-
!python {model: product.product}: |
import netsvc, tools, os
- (data, format) = netsvc.LocalService('report.stock.product.history').create(cr, uid, [ref('product.product_product_pc1')], {}, {})
+ (data, format) = netsvc.LocalService('report.stock.product.history').create(cr, uid, [ref('product_icecream')], {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'stock-product_stock_report.'+format), 'wb+').write(data)
+
diff --git a/addons/stock/test/stock_test.yml b/addons/stock/test/stock_test.yml
deleted file mode 100644
index 6e41849ea51..00000000000
--- a/addons/stock/test/stock_test.yml
+++ /dev/null
@@ -1,424 +0,0 @@
-
--
- In order to test the stock module, I will create product,
- create physical inventory ,fill inventory lines from location,split inventory line into production lot
--
- I create Stock Production Lot for product PC3
--
- !record {model: stock.production.lot, id: stock_production_lot0}:
- product_id: product.product_product_pc3
- date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
- name: 0000001
--
- I trace the Stock Production Lot for product PC3.
--
- !python {model: stock.production.lot }: |
- self.action_traceability(cr,uid,[ref('stock_production_lot0')], {'lang': 'en_US', 'tz': False, 'active_model': 'ir.ui.menu', 'field': '', 'type': ''})
-
--
- I create change product quantity for product PC3.
--
- !record {model: stock.change.product.qty, id: stock_change_product_qty0}:
- product_id: product.product_product_pc3
- new_quantity: 100
- location_id: stock.stock_location_stock
- prodlot_id: stock.stock_production_lot0
-
--
- I apply the new quantity on product PC3.
--
- !python {model: stock.change.product.qty }: |
- context = {"lang": 'en_US', "active_model":
- "product.product", "active_ids": [ref("product.product_product_pc3")], "tz": False, "active_id":ref('product.product_product_pc3')}
- self.default_get(cr, uid, ["prodlot_id", "location_id", "new_quantity", "product_id"], context)
- self.fields_view_get(cr, uid, ref("stock.view_change_product_quantity"),"form", context)
- self.change_product_qty(cr, uid, [ref("stock_change_product_qty0")], {"lang": 'en_US', "active_model":
- "stock.change.product.qty", "active_ids": ref("product.product_product_pc3"), "tz": False, "active_id":ref('product.product_product_pc3')})
-
--
- I check that the quantity on product PC3 is updated.
--
- !python {model: product.product }: |
- pro_obj = self.browse(cr, uid, ref("product.product_product_pc3"))
- assert (pro_obj.qty_available >= 100) , "The quantity of PC3 is not updated!"
-
--
- I Read quantity on product PC3.
--
- !python {model: stock.location }: |
- self.read(cr, uid, [ref("stock.stock_location_stock")],['stock_real_value','stock_virtual'], {'lang': 'en_GB', 'tz': False, 'active_model': 'product.product', 'bin_size': True, 'active_ids': [ref("product.product_product_pc3")], 'product_id':ref("product.product_product_pc3"), 'active_id': ref("product.product_product_pc3")})
-
--
- I Creating a chained stock.location record
--
- !record {model: stock.location, id: stock_location_loc0}:
- chained_auto_packing: auto
- chained_delay: 0.0
- chained_location_id: stock.stock_location_customers
- chained_location_type: fixed
- location_id: stock.stock_location_company
- name: chain location
- parent_left: 2
- parent_right: 3
- usage: internal
-
--
- I create Product By location chart for stock.location.product Object.
--
- !record {model: stock.location.product, id: stock_location_product0}:
- from_date: '2011-07-01 00:00:00'
- to_date: '2011-07-31 23:59:00'
-
--
- I open product chart.
--
- !python {model: stock.location.product }: |
- self.action_open_window(cr, uid, [ref("stock_location_product0")], {'lang': 'en_US', 'full': 1, 'tz': False, 'active_model': 'stock.location', 'search_default_in_location': 1, 'active_ids': [ref("stock.stock_location_stock")], 'active_id': ref("stock.stock_location_stock")})
-
--
- I open product form from stock.location object .
--
- !python {model: product.product }: |
- self.fields_view_get(cr, uid, False, "tree", {'lang': 'en_US', 'full': 1, 'tz': False, 'active_model': 'stock.location', 'location': ref('stock.stock_location_stock'), 'search_default_in_location': 1, 'active_ids': [ref("stock.stock_location_stock")], 'active_id': ref("stock.stock_location_stock")})
-
--
- I create change product standard price for product PC3.
--
- !record {model: stock.change.standard.price, id: stock_change_standard_price0}:
- new_price: 1515
- stock_account_input: account.a_recv
- stock_account_output: account.a_pay
- stock_journal: account.expenses_journal
- enable_stock_in_out_acc: True
-
--
- I apply the new product standard price on product PC3.
--
- !python {model: stock.change.standard.price }: |
- context = {"lang": 'en_US', "active_model":
- "product.product", "active_ids": [ref("product.product_product_pc3")], "tz": False, "active_id":ref('product.product_product_pc3')}
- self.default_get(cr, uid, ["new_price"], context)
- self.change_price(cr, uid, [ref("stock_change_product_qty0")], context)
-
--
- I create Physical Inventory for the products.
--
- !record {model: stock.inventory, id: stock_inventory_physicalinventoy0}:
- company_id: base.main_company
- date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
- inventory_line_id:
- - company_id: base.main_company
- location_id: stock.stock_location_stock
- product_id: product.product_product_pc3
- product_qty: 10.0
- product_uom: product.product_uom_unit
- - company_id: base.main_company
- location_id: stock.stock_location_stock
- product_id: product.product_product_pc1
- product_qty: 10.0
- product_uom: product.product_uom_unit
- name: Physical inventory
- state: draft
-
--
- I create merge Inventory for the products.
--
- !record {model: stock.inventory, id: stock_inventory_mergeinventoy0}:
- company_id: base.main_company
- date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
- inventory_line_id:
- - company_id: base.main_company
- location_id: stock.stock_location_stock
- product_id: product.product_product_pc3
- product_qty: 20.0
- product_uom: product.product_uom_unit
- - company_id: base.main_company
- location_id: stock.stock_location_stock
- product_id: product.product_product_pc1
- product_qty: 20.0
- product_uom: product.product_uom_unit
- name: Physical inventory
- state: draft
-
--
- I merge inventory .
--
- !python {model: stock.inventory.merge}: |
- context = {"lang": 'en_US',
- "full": "1", "tz": False, "active_model": "stock.inventory", "active_ids":
- [ref("stock_inventory_physicalinventoy0"), ref("stock_inventory_mergeinventoy0")], "active_id": ref("stock_inventory_physicalinventoy0"), }
- self.fields_view_get(cr, uid, False, "form", context)
- self.do_merge(cr, uid, [ref("stock_inventory_mergeinventoy0")], context)
-
--
- I create stock.inventory.line record.
--
- !record {model: stock.inventory.line, id: stock_inventory_line}:
- product_id: product.product_product_pc1
- product_uom: product.product_uom_unit
- product_qty: 10
- inventory_id: stock_inventory_mergeinventoy0
- location_id: stock.stock_location_stock
-
--
- I Change a Product oF stock.inventory.line record.
--
- !python {model: stock.inventory.line}: |
- self.on_change_product_id(cr, uid, [ref("stock_inventory_line")], ref('stock.stock_location_stock'), ref('product.product_product_pc3'), False, False)
-
--
- I create stock.fill.inventory .
--
- !record {model: stock.fill.inventory, id: stock_fill_inventory_0}:
- location_id: stock.stock_location_stock
- recursive: False
- set_stock_zero: False
-
--
- I fill inventory for PC3.
--
- !python {model: stock.fill.inventory}: |
- context = {"lang": 'en_US',"full": "1", "tz": False, "active_model": "stock.inventory", "active_ids":
- [ref("stock_inventory_physicalinventoy0")], "active_id": ref("stock_inventory_physicalinventoy0")}
- self.view_init(cr, uid, ["set_stock_zero", "location_id", "recursive"], context)
- self.fill_inventory(cr, uid, [ref("stock_fill_inventory_0")], context)
-
--
- I split the PC3 inventory line to create 5 PC3 with production lot 00002-stock-test
--
- !record {model: stock.inventory.line.split, id: stock_inventory_line_0}:
- line_ids:
- - name: '00002-stock-test'
- quantity: 5
- product_id: product.product_product_pc1
- product_uom: product.product_uom_unit
- use_exist: False
- qty: 10
--
- I confirm the split operation
--
- !python {model: stock.inventory.line}: |
- line_ids = self.search(cr, uid, [('inventory_id','=',ref('stock_inventory_physicalinventoy0')),
- ('product_id','=',ref('product.product_product_pc1'))])
- assert line_ids, 'Inventory lines are missing'
- self.pool.get('stock.inventory.line.split').split_lot(cr, uid, [ref("stock_inventory_line_0")],
- {'active_model': 'stock.inventory.line',
- 'active_ids': [line_ids[0]]})
--
- I confirm the Inventory for PC3.
--
- !python {model: stock.inventory}: |
- self.action_confirm(cr,uid,[ref('stock_inventory_physicalinventoy0')])
- self.action_done(cr,uid,[ref('stock_inventory_physicalinventoy0')])
--
- I cancel the Inventory for PC3.
--
- !python {model: stock.inventory}: |
- self.action_cancel_inventary(cr,uid,[ref('stock_inventory_physicalinventoy0')])
-
--
- I change inventory state to draft for PC3.
--
- !python {model: stock.inventory}: |
- self.action_cancel_draft(cr,uid,[ref('stock_inventory_physicalinventoy0')])
-
--
- In Order to test the picking I create picking with move lines.
--
- !record {model: stock.picking, id: stock_picking_0}:
- name: test_picking
- address_id: base.res_partner_address_4
- company_id: base.main_company
- date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
- invoice_state: 2binvoiced
- move_lines:
- - company_id: base.main_company
- date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
- location_dest_id: stock.stock_location_loc0
- location_id: stock.stock_location_stock
- name: PC3
- product_id: product.product_product_pc3
- product_qty: 100.0
- product_uom: product.product_uom_unit
- date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
- product_uos_qty: 100.0
- move_type: direct
- type: out
-
--
- I split the picking with a first batch of 20 PCs
--
- !python {model: stock.picking }: |
- pick=self.browse(cr,uid,ref('stock_picking_0'))
- split_obj=self.pool.get('stock.split.into')
- partial_datas={}
- move=pick.move_lines[0]
- partial_datas= {
- 'quantity': 20,
- }
- split_id = self.pool.get('stock.split.into').create(cr, uid, partial_datas)
- split_obj.split(cr, uid, [split_id], {"lang": "en_US", "tz":
- False, "active_model": "stock.move", "active_ids": [move.id],
- "active_id": move.id, })
-
--
- I click on draft_force_assign on picking.
--
- !python {model: stock.picking}: |
- self.draft_force_assign(cr, uid, [ref("stock_picking_0")], {"lang": "en_US", "active_model":
- "ir.ui.menu", "tz": False, "search_default_confirmed": 1, "contact_display":
- "partner", "active_ids": [ref("stock.menu_action_picking_tree6")], "active_id":
- ref("stock.menu_action_picking_tree6"), })
-
--
- I click on action_assign on picking.
--
- !python {model: stock.picking}: |
- self.action_assign(cr, uid, [ref("stock_picking_0")], {"lang": "en_US", "active_model":
- "ir.ui.menu", "tz": False, "search_default_confirmed": 1, "contact_display":
- "partner", "active_ids": [ref("stock.menu_action_picking_tree6")], "active_id":
- ref("stock.menu_action_picking_tree6"), })
-
--
- I process the partial picking with 20 PCE
--
- !python {model: stock.picking }: |
- pick = self.browse(cr,uid,ref('stock_picking_0'))
- stock_partial_move = self.pool.get('stock.partial.move')
- partial_id = stock_partial_move.create(cr, uid, {},
- context={'active_model': 'stock.move',
- 'active_ids': [x.id for x in pick.move_lines]})
- stock_partial_move.do_partial(cr, uid, [partial_id])
--
- I Performing an osv_memory action split_lot on module stock.move.split
--
-
- !python {model: stock.picking }: |
- split_obj=self.pool.get('stock.move.split')
- split_move_lines=self.pool.get('stock.move.split.lines')
- pick=self.browse(cr,uid,ref('stock_picking_0'))
- partial_datas={}
- move=pick.move_lines[0]
- partial_datas= {
- 'product_id': move.product_id.id,
- 'qty': 80,
- 'product_uom': move.product_uom.id,
- 'use_exist': move.picking_id and move.picking_id.type=='out' and True or False
- }
- split_id = self.pool.get('stock.move.split').create(cr, uid, partial_datas, context={})
- split_move_data= {
- 'quantity': 10,
- 'name': 'lot',
- }
- split_move_id = split_move_lines.create(cr, uid, split_move_data, context={})
- split_obj.default_get(cr, uid, ["product_id", "product_uom", "line_exist_ids", "qty",
- "line_ids", "use_exist"], {'lang': 'en_US', 'default_location_dest_id': ref('stock.stock_location_stock'), 'tz': False, 'active_model': 'stock.move', 'search_default_receive': 1, 'product_receive': True, 'active_ids': [move.id], 'default_location_id': ref('stock.stock_location_locations'), 'active_id': move.id})
- split_obj.split_lot(cr, uid, [split_id], context={"lang": "en_US", "tz":
- False, "active_model": "stock.move", "scrap": True, "active_ids": [move.id],
- "active_id": move.id, })
-
--
- I Performed an osv_memory action move_scrap on module stock.move.scrap
--
- !python {model: stock.picking }: |
- location_obj = self.pool.get('stock.location')
- scrpaed_location_ids = location_obj.search(cr, uid, [('scrap_location','=',True)])
- pick=self.browse(cr,uid,ref('stock_picking_0'))
- scrap_obj=self.pool.get('stock.move.scrap')
- partial_datas={}
- move=pick.move_lines[0]
- partial_datas= {
- 'product_id': move.product_id.id,
- 'location_id': scrpaed_location_ids[0],
- 'product_qty': 1,
- 'product_uom': move.product_uom.id,
- }
- scrap_id = scrap_obj.create(cr, uid, partial_datas)
- context = {"lang": "en_US", "tz": False, "active_model": "stock.move",
- "scrap": True, "active_ids": [move.id], "active_id": move.id, }
- scrap_obj.default_get(cr, uid, ["location_id", "product_id", "product_uom", "product_qty"], context)
- scrap_obj.move_scrap(cr, uid, [scrap_id], context)
-
--
- I Performed an osv_memory do move consume on module stock.move.consume
--
- !python {model: stock.picking }: |
- location_obj = self.pool.get('stock.location')
- scrpaed_location_ids = location_obj.search(cr, uid, [('scrap_location','=',True)])
- pick=self.browse(cr,uid,ref('stock_picking_0'))
- consume_obj=self.pool.get('stock.move.consume')
- partial_datas={}
- move=pick.move_lines[0]
- partial_datas= {
- 'product_id': move.product_id.id,
- 'location_id': scrpaed_location_ids[0],
- 'product_qty': 1,
- 'product_uom': move.product_uom.id,
- }
- context = {"lang": "en_US", "tz": False, "active_model": "stock.move",
- "scrap": True, "active_ids": [move.id], "active_id": move.id, }
- consume_id = consume_obj.create(cr, uid, partial_datas)
- consume_obj.default_get(cr, uid, ["location_id", "product_id", "product_uom", "product_qty"], context)
- consume_obj.do_move_consume(cr, uid, [consume_id], context)
-
--
- I process the picking with the 80 remaining PCs
--
- !python {model: stock.picking}: |
- stock_partial_picking = self.pool.get('stock.partial.picking')
- partial_id = stock_partial_picking.create(cr, uid, {},
- context={'active_model': 'stock.picking',
- 'active_ids': [ref('stock_picking_0')]})
- stock_partial_picking.do_partial(cr, uid, [partial_id])
--
- I Performing an osv_memory action create_invoice on module stock.invoice.onshipping
--
- !python {model: stock.invoice.onshipping}: |
- invoice_line_id = self.create(cr, uid,{}, {"lang": 'en_US', "active_model":
- "stock.picking", "active_ids": [ref("stock_picking_0")], "tz": False, "active_id":ref("stock_picking_0")})
- self.open_invoice(cr, uid, [invoice_line_id], {"lang": "en_US",
- "search_default_available": 1, "inv_type": "in_invoice" , "tz": False, "active_model": "stock.picking",
- "contact_display": "partner_address", "active_ids": [ref("stock_picking_0")],
- "active_id": ref("stock_picking_0")})
- self._get_journal_id(cr, uid, {"lang": "en_US", "search_default_available": 1, "tz": False, "active_model": "stock.picking",
- "contact_display": "partner_address", "active_ids": [ref("stock_picking_0")],
- "active_id": ref("stock_picking_0"), })
-
--
- I create a record of stock.picking and unlink a record
--
- !python {model: stock.picking}: |
- copy_id = self.copy(cr, uid, (ref("stock_picking_0")))
- ctx = {"lang": "en_US", "active_model":
- "ir.ui.menu", "tz": False, "search_default_confirmed": 1, "contact_display":
- "partner", "active_ids": [ref("stock.menu_action_picking_tree6")], "active_id":
- ref("stock.menu_action_picking_tree6"), }
- self.draft_force_assign(cr, uid, [copy_id], ctx)
- self.unlink(cr, uid, [copy_id], ctx)
-
--
- I create a record of stock.picking and cancel a record
--
- !python {model: stock.picking}: |
- copy_id = self.copy(cr, uid, (ref("stock_picking_0")))
- self.draft_validate(cr, uid, [copy_id], {"lang": "en_US", "search_default_available":
- 1, "tz": False, "active_model": "ir.ui.menu", "contact_display": "partner_address",
- "active_ids": [ref("stock.menu_action_picking_tree4")], "active_id": ref("stock.menu_action_picking_tree4"),
- })
- self.allow_cancel(cr, uid, [copy_id], context= None)
-
--
- I process a copy of the picking and I return it
--
- !python {model: stock.picking}: |
- copy_id = self.copy(cr, uid, (ref("stock_picking_0")))
- self.draft_force_assign(cr, uid, [copy_id])
- self.force_assign(cr, uid, [copy_id])
- stock_partial_picking = self.pool.get('stock.partial.picking')
- context = {'active_model': 'stock.picking',
- 'active_ids': [copy_id],
- 'active_id': copy_id}
- partial_id = stock_partial_picking.create(cr, uid, {}, context=context)
- stock_partial_picking.do_partial(cr, uid, [partial_id], context)
- return_pick_id = self.pool.get('stock.return.picking').create(cr, uid,{}, context)
- self.pool.get('stock.return.picking').create_returns(cr, uid, [return_pick_id], context)
diff --git a/addons/stock/test/stock_test_wizard.yml b/addons/stock/test/stock_test_wizard.yml
deleted file mode 100644
index 6c4d5ae12c2..00000000000
--- a/addons/stock/test/stock_test_wizard.yml
+++ /dev/null
@@ -1,78 +0,0 @@
-
--
- I create stock.tracking record.
--
- !record {model: stock.tracking, id: stock_tracking_0}:
- move_ids:
- - product_id: product.product_product_pc1
- product_qty: 5.0
- product_uom: product.product_uom_unit
- location_id : stock.stock_location_suppliers
- location_dest_id: stock.stock_location_shop0
- name : '[PC1] Basic PC'
- date_expected : !eval time.strftime('%Y-%m-%d %H:%M:%S')
- name: 0000007
- active: True
- date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
-
--
- I trace the information of a product.
--
- !python {model: stock.tracking}: |
- self.name_get(cr, uid, [ref('stock_tracking_0')],{'lang': 'en_US', 'tz': False, 'active_model': 'ir.ui.menu', 'field': '', 'type': ''})
- self.action_traceability(cr,uid,[ref('stock_tracking_0')], {'lang': 'en_US', 'tz': False, 'active_model': 'ir.ui.menu', 'field': '', 'type': ''})
-
--
- I creat stock.move Record
--
- !record {model: stock.move, id: stock_move_test0}:
- location_dest_id: stock.stock_location_shop0
- product_id: product.product_product_pc1
- product_qty: 5.0
- product_uom: product.product_uom_unit
- date_expected : !eval time.strftime('%Y-%m-%d %H:%M:%S')
- location_id : stock.stock_location_suppliers
- name : '[PC1] Basic PC'
- company_id: base.main_company
- product_uos_qty : 5.0
- name: IN/00010
- state: assigned
-
--
- I Check onchange function of stock.move object
--
- !python {model: stock.move }: |
- self.onchange_lot_id(cr, uid, [ref("stock_move_test0")], ref("stock.stock_production_lot0"), 5, ref("stock.stock_location_suppliers"), ref("product.product_product_pc1"), ref("product.product_uom_unit"), None)
- self.onchange_quantity(cr, uid, [ref("stock_move_test0")], ref("product.product_product_pc1"), 10, ref("product.product_uom_unit"), ref("product.product_uom_unit"))
- self.onchange_uos_quantity(cr, uid, [ref("stock_move_test0")], ref("product.product_product_pc1"), 10, ref("product.product_uom_unit"), ref("product.product_uom_unit"))
- self.onchange_product_id(cr, uid, [ref("stock_move_test0")], ref("product.product_product_pc1"), ref("stock.stock_location_suppliers"), ref("stock.stock_location_shop0"), False)
-
--
- I Check _getSSCC and action_partial_move function of stock.move object
--
- !python {model: stock.move }: |
- context = {"lang": 'en_US', "default_location_dest_id": ref("stock.stock_location_shop0"), "active_model":
- "stock.move", "search_default_receive": 1, 'product_receive': True, "default_location_id": ref("stock.stock_location_suppliers"),"active_ids":[ref("stock_move_test0")], "tz": False, "active_id":ref("stock_move_test0")}
- self._getSSCC(cr, uid , context)
- self.action_partial_move(cr, uid , [ref("stock_move_test0")], context)
-
--
- I check write function
--
- !python {model: stock.move }: |
- vals = {"product_qty" : 2, "product_uos_qty": 2}
- self.write(cr, uid, [ref("stock_move_test0")], vals, {"lang": 'en_US', "default_location_dest_id": ref("stock.stock_location_shop0"), "active_model":
- "ir.ui.menu", "search_default_receive": 1, 'product_receive': True, "default_location_id": ref("stock.stock_location_suppliers"),"active_ids":[ref("stock_move_tree")], "tz": False, "active_id":ref("stock_move_tree")})
-
--
- I check default function
--
- !python {model: stock.move }: |
- self.name_get(cr, uid, [ref("stock_move_test0")], {"lang": 'en_US', "default_location_dest_id": ref("stock.stock_location_shop0"), "active_model":
- "stock.move", "search_default_receive": 1, 'product_receive': True, "default_location_id": ref("stock.stock_location_suppliers"),"active_ids":[ref("stock_move_test0")], "tz": False, "active_id":ref("stock_move_test0")})
- ctx = {"lang": 'en_US', "default_location_dest_id": ref("stock.stock_location_shop0"), "active_model":
- "ir.ui.menu", "search_default_receive": 1, 'product_receive': True, "default_location_id": ref("stock.stock_location_suppliers"),"active_ids":[ref("view_move_form_reception_picking")], "tz": False, "active_id":ref("view_move_form_reception_picking")}
- self._default_location_destination(cr, uid, ctx)
- self._default_location_source(cr, uid, ctx)
-
-
diff --git a/addons/stock/wizard/stock_fill_inventory.py b/addons/stock/wizard/stock_fill_inventory.py
index 5c5e8964e9a..cd6aa59dc66 100644
--- a/addons/stock/wizard/stock_fill_inventory.py
+++ b/addons/stock/wizard/stock_fill_inventory.py
@@ -81,7 +81,7 @@ class stock_fill_inventory(osv.osv_memory):
if fill_inventory.recursive:
location_ids = location_obj.search(cr, uid, [('location_id',
- 'child_of', [fill_inventory.location_id.id])], order="id",
+ 'child_of', [fill_inventory.location_id.id])], order="id",
context=context)
else:
location_ids = [fill_inventory.location_id.id]
diff --git a/addons/stock/wizard/stock_move.py b/addons/stock/wizard/stock_move.py
index a61784f7a6b..e7cd5a4e41c 100644
--- a/addons/stock/wizard/stock_move.py
+++ b/addons/stock/wizard/stock_move.py
@@ -34,6 +34,7 @@ class stock_move_consume(osv.osv_memory):
'location_id': fields.many2one('stock.location', 'Location', required=True)
}
+ #TOFIX: product_uom should not have differemt category of default UOM of product. Qty should be convert into UOM of original move line before going in consume and scrap
def default_get(self, cr, uid, fields, context=None):
""" Get default values
@param self: The object pointer.
diff --git a/addons/stock/wizard/stock_traceability.py b/addons/stock/wizard/stock_traceability.py
index 779843e8ccd..cc28c57b9bb 100644
--- a/addons/stock/wizard/stock_traceability.py
+++ b/addons/stock/wizard/stock_traceability.py
@@ -42,8 +42,8 @@ class action_traceability(osv.osv_memory):
lot_id = ids
if context is None:
context = {}
- type1 = context['type'] or 'move_history_ids2'
- field = context['field'] or 'tracking_id'
+ type1 = context.get('type', 'move_history_ids2')
+ field = context.get('field', 'tracking_id')
obj = self.pool.get('stock.move')
ids = obj.search(cr, uid, [(field, 'in',lot_id)])
cr.execute('select id from ir_ui_view where model=%s and field_parent=%s and type=%s', ('stock.move', type1, 'tree'))
diff --git a/addons/stock_invoice_directly/test/stock_invoice_directly.yml b/addons/stock_invoice_directly/test/stock_invoice_directly.yml
index 795da509d04..f07e2dbfa31 100644
--- a/addons/stock_invoice_directly/test/stock_invoice_directly.yml
+++ b/addons/stock_invoice_directly/test/stock_invoice_directly.yml
@@ -6,20 +6,15 @@
-
!record {model: stock.picking, id: stock_picking_out0}:
address_id: base.res_partner_address_3000
- company_id: base.main_company
invoice_state: 2binvoiced
move_lines:
- company_id: base.main_company
- date_expected: !eval time.strftime('%Y-%m-%d %H:%M:%S')
- date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
location_id: stock.stock_location_stock
product_id: product.product_product_pc1
product_qty: 3.0
product_uom: product.product_uom_unit
location_dest_id: stock.stock_location_customers
- name: '[PC1] Basic PC'
move_type: direct
- name: OUT/00006
type: out
-
I need to check the availability of the product so I make my picking order for processing later.
diff --git a/addons/wiki_sale_faq/wiki_sale_faq_view.xml b/addons/wiki_sale_faq/wiki_sale_faq_view.xml
index 82cfb6a43be..9fdaafd96b9 100644
--- a/addons/wiki_sale_faq/wiki_sale_faq_view.xml
+++ b/addons/wiki_sale_faq/wiki_sale_faq_view.xml
@@ -12,7 +12,7 @@
ir.actions.act_window
ir.attachment
form
-
+
Documents give you access to all files attached to any record. It is a repository of all documents such as emails, project-related attachments or any other documents. From this view, you can search through the content of the documents. OpenERP automatically assign meta data based on the record like the related partner and indexes the content of .DOC, .ODT, .TXT, .SXW and .PDF documents.