diff --git a/addons/account/account_wizard.xml b/addons/account/account_wizard.xml
index cdd14780256..93dba0e5249 100644
--- a/addons/account/account_wizard.xml
+++ b/addons/account/account_wizard.xml
@@ -78,8 +78,8 @@
-
diff --git a/addons/account/wizard/account_aged_trial_balance_view.xml b/addons/account/wizard/account_aged_trial_balance_view.xml
index 258de38b714..7984f69e86e 100644
--- a/addons/account/wizard/account_aged_trial_balance_view.xml
+++ b/addons/account/wizard/account_aged_trial_balance_view.xml
@@ -2,11 +2,6 @@
-
-
Aged Partner Balance
account.aged.trial.balance
diff --git a/addons/delivery/delivery.py b/addons/delivery/delivery.py
index 7e7d31975e5..35b3ed481e9 100644
--- a/addons/delivery/delivery.py
+++ b/addons/delivery/delivery.py
@@ -28,6 +28,17 @@ class delivery_carrier(osv.osv):
_name = "delivery.carrier"
_description = "Carrier and delivery grids"
+ def name_get(self, cr, uid, ids, context={}):
+ if not len(ids):
+ return []
+ order_id = context.get('order_id',False)
+ if not order_id:
+ res = super(delivery_carrier, self).name_get(cr, uid, ids, context=context)
+ else:
+ order = self.pool.get('sale.order').browse(cr, uid, [order_id])[0]
+ currency = order.pricelist_id.currency_id.name or ''
+ res = [(r['id'], r['name']+' ('+(str(r['price']))+' '+currency+')') for r in self.read(cr, uid, ids, ['name', 'price'], context)]
+ return res
def get_price(self, cr, uid, ids, field_name, arg=None, context={}):
res={}
sale_obj=self.pool.get('sale.order')
@@ -94,9 +105,7 @@ class delivery_grid(osv.osv):
}
_order = 'sequence'
-
def get_price(self, cr, uid, id, order, dt, context):
-
total = 0
weight = 0
volume = 0
@@ -112,7 +121,6 @@ class delivery_grid(osv.osv):
def get_price_from_picking(self, cr, uid, id, total, weight, volume, context={}):
grid = self.browse(cr, uid, id, context)
-
price = 0.0
ok = False
diff --git a/addons/delivery/delivery_view.xml b/addons/delivery/delivery_view.xml
index 16f4a61ed1e..f14d45c79de 100644
--- a/addons/delivery/delivery_view.xml
+++ b/addons/delivery/delivery_view.xml
@@ -289,5 +289,16 @@
+
+ sale.order.multicompany
+ sale.order
+
+
+
+
+
+
+
+
diff --git a/addons/delivery/wizard/delivery_sale_order.py b/addons/delivery/wizard/delivery_sale_order.py
index efc82ae4141..5f066b23bb0 100644
--- a/addons/delivery/wizard/delivery_sale_order.py
+++ b/addons/delivery/wizard/delivery_sale_order.py
@@ -50,7 +50,11 @@ class make_delivery(osv.osv_memory):
res = super(make_delivery, self).default_get(cr, uid, fields, context=context)
order_obj = self.pool.get('sale.order')
for order in order_obj.browse(cr, uid, context.get('active_ids', [])):
- res.update({'carrier_id': order.partner_id.property_delivery_carrier.id})
+ carrier = order.carrier_id.id
+ if not carrier:
+ carrier = order.partner_id.property_delivery_carrier.id
+ res.update({'carrier_id': carrier})
+
return res
def view_init(self, cr , uid , fields, context=None):
diff --git a/addons/delivery/wizard/delivery_sale_order_view.xml b/addons/delivery/wizard/delivery_sale_order_view.xml
index c2609bc3923..6ac0883493f 100644
--- a/addons/delivery/wizard/delivery_sale_order_view.xml
+++ b/addons/delivery/wizard/delivery_sale_order_view.xml
@@ -11,26 +11,28 @@
+
+
+ Delivery Costs
+ ir.actions.act_window
+ delivery.sale.order
+ form
+ form
+
+ new
+
-
-
-
diff --git a/addons/hr_recruitment/wizard/hr_recruitment_phonecall.py b/addons/hr_recruitment/wizard/hr_recruitment_phonecall.py
new file mode 100644
index 00000000000..27c0a2c49bd
--- /dev/null
+++ b/addons/hr_recruitment/wizard/hr_recruitment_phonecall.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved
+# $Id$
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+import time
+
+from osv import osv, fields
+from tools.translate import _
+
+class job2phonecall(osv.osv_memory):
+ _name = 'hr.recruitment.job2phonecall'
+ _description = 'Schedule Phone Call'
+ _columns = {
+ 'user_id': fields.many2one('res.users', 'Assign To'),
+ 'deadline': fields.datetime('Planned Date'),
+ 'note': fields.text('Goals'),
+ 'category_id': fields.many2one('crm.case.categ', 'Category', required=True),
+ }
+
+ def _date_user(self, cr, uid, context=None):
+ case_obj = self.pool.get('hr.applicant')
+ case = case_obj.browse(cr, uid, context['active_id'])
+ return case.user_id and case.user_id.id or False
+
+ def _date_category(self, cr, uid, context=None):
+ categ_id = self.pool.get('crm.case.categ').search(cr, uid, [('name','=','Outbound')])
+ return categ_id and categ_id[0] or case.categ_id and case.categ_id.id or False
+
+ def _get_note(self, cr, uid, context=None):
+ case_obj = self.pool.get('hr.applicant')
+ case = case_obj.browse(cr, uid, context['active_id'])
+ return case.description or ''
+
+ _defaults = {
+ 'user_id': _date_user,
+ 'category_id': _date_category,
+ 'note': _get_note
+ }
+
+ def make_phonecall(self, cr, uid, ids, context=None):
+ mod_obj = self.pool.get('ir.model.data')
+ job_case_obj = self.pool.get('hr.applicant')
+ data_obj = self.pool.get('ir.model.data')
+ phonecall_case_obj = self.pool.get('crm.phonecall')
+
+ form = self.read(cr, uid, ids, [], context=context)[0]
+# form = data['form']
+ result = mod_obj._get_id(cr, uid, 'crm', 'view_crm_case_phonecalls_filter')
+ res = mod_obj.read(cr, uid, result, ['res_id'])
+ # Select the view
+
+ id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_phone_tree_view')
+ id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_phone_form_view')
+ if id2:
+ id2 = data_obj.browse(cr, uid, id2, context=context).res_id
+ if id3:
+ id3 = data_obj.browse(cr, uid, id3, context=context).res_id
+
+ for job in job_case_obj.browse(cr, uid, context['active_ids']):
+ #TODO : Take other info from job
+ new_phonecall_id = phonecall_case_obj.create(cr, uid, {
+ 'name' : job.name,
+ 'user_id' : form['user_id'],
+ 'categ_id' : form['category_id'],
+ 'description' : form['note'],
+ 'date' : form['deadline'],
+# 'section_id' : form['section_id'],
+ 'description':job.description,
+ 'partner_id':job.partner_id.id,
+ 'partner_address_id':job.partner_address_id.id,
+ 'partner_phone':job.partner_phone,
+ 'partner_mobile':job.partner_mobile,
+ 'description':job.description,
+ 'date':job.date,
+ }, context=context)
+ new_phonecall = phonecall_case_obj.browse(cr, uid, new_phonecall_id)
+ vals = {}
+# if not job.case_id:
+# vals.update({'phonecall_id' : new_phonecall.id})
+ job_case_obj.write(cr, uid, [job.id], vals)
+ job_case_obj.case_cancel(cr, uid, [job.id])
+ phonecall_case_obj.case_open(cr, uid, [new_phonecall_id])
+
+ value = {
+ 'name': _('Phone Call'),
+ 'view_type': 'form',
+ 'view_mode': 'tree,form',
+ 'res_model': 'crm.phonecall',
+ 'res_id' : new_phonecall_id,
+ 'views': [(id3,'form'),(id2,'tree'),(False,'calendar'),(False,'graph')],
+ 'type': 'ir.actions.act_window',
+ 'search_view_id': res['res_id']
+ }
+ return value
+
+job2phonecall()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:>>>>>>> MERGE-SOURCE
diff --git a/addons/hr_recruitment/wizard/hr_recruitment_wizard.py b/addons/hr_recruitment/wizard/hr_recruitment_wizard.py
deleted file mode 100644
index bd6fa8ba134..00000000000
--- a/addons/hr_recruitment/wizard/hr_recruitment_wizard.py
+++ /dev/null
@@ -1,273 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved
-# $Id$
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-#
-##############################################################################
-
-from mx.DateTime import now
-
-import wizard
-import netsvc
-import ir
-import pooler
-import time
-
-from tools.translate import _
-
-class job2phonecall(wizard.interface):
- case_form = """
- """
-
- case_fields = {
- 'user_id' : {'string' : 'Assign To', 'type' : 'many2one', 'relation' : 'res.users'},
- 'deadline' : {'string' : 'Planned Date', 'type' : 'datetime'},
- 'note' : {'string' : 'Goals', 'type' : 'text'},
- 'category_id' : {'string' : 'Category', 'type' : 'many2one', 'relation' : 'crm.case.categ', 'required' : True},
- 'section_id' : {'string' : 'Section', 'type' : 'many2one', 'relation' : 'hr.case.section'},
-
- }
- def _default_values(self, cr, uid, data, context):
-
- case_obj = pooler.get_pool(cr.dbname).get('hr.applicant')
- categ_id=pooler.get_pool(cr.dbname).get('crm.case.categ').search(cr, uid, [('name','=','Outbound')])
- case = case_obj.browse(cr, uid, data['id'])
- return {
- 'user_id' : case.user_id and case.user_id.id,
- 'category_id' : categ_id and categ_id[0] or case.categ_id and case.categ_id.id,
- 'section_id' : case.section_id and case.section_id.id or False,
- 'note' : case.description
- }
-
- def _doIt(self, cr, uid, data, context):
- form = data['form']
- pool = pooler.get_pool(cr.dbname)
- mod_obj = pool.get('ir.model.data')
- result = mod_obj._get_id(cr, uid, 'hr', 'view_hr_case_phonecalls_filter')
- res = mod_obj.read(cr, uid, result, ['res_id'])
- phonecall_case_obj = pool.get('hr.phonecall')
- job_case_obj = pool.get('hr.applicant')
- # Select the view
-
- data_obj = pool.get('ir.model.data')
- id2 = data_obj._get_id(cr, uid, 'hr', 'hr_case_phone_tree_view')
- id3 = data_obj._get_id(cr, uid, 'hr', 'hr_case_phone_form_view')
- if id2:
- id2 = data_obj.browse(cr, uid, id2, context=context).res_id
- if id3:
- id3 = data_obj.browse(cr, uid, id3, context=context).res_id
-
- for job in job_case_obj.browse(cr, uid, data['ids']):
- #TODO : Take other info from job
- new_phonecall_id = phonecall_case_obj.create(cr, uid, {
- 'name' : job.name,
- 'user_id' : form['user_id'],
- 'categ_id' : form['category_id'],
- 'description' : form['note'],
- 'date' : form['deadline'],
- 'section_id' : form['section_id'],
- 'description':job.description,
- 'partner_id':job.partner_id.id,
- 'partner_address_id':job.partner_address_id.id,
- 'partner_phone':job.partner_phone,
- 'partner_mobile':job.partner_mobile,
- 'description':job.description,
- 'date':job.date,
- }, context=context)
- new_phonecall = phonecall_case_obj.browse(cr, uid, new_phonecall_id)
- vals = {}
- if not job.case_id:
- vals.update({'phonecall_id' : new_phonecall.id})
- job_case_obj.write(cr, uid, [job.id], vals)
- job_case_obj.case_cancel(cr, uid, [job.id])
- phonecall_case_obj.case_open(cr, uid, [new_phonecall_id])
- value = {
- 'name': _('Phone Call'),
- 'view_type': 'form',
- 'view_mode': 'tree,form',
- 'res_model': 'hr.phonecall',
- 'res_id' : new_phonecall_id,
- 'views': [(id3,'form'),(id2,'tree'),(False,'calendar'),(False,'graph')],
- 'type': 'ir.actions.act_window',
- 'search_view_id': res['res_id']
- }
- return value
-
- states = {
- 'init': {
- 'actions': [_default_values],
- 'result': {'type': 'form', 'arch': case_form, 'fields': case_fields,
- 'state' : [('end', 'Cancel','gtk-cancel'),('order', 'Schedule Phone Call','gtk-go-forward')]}
- },
- 'order': {
- 'actions': [],
- 'result': {'type': 'action', 'action': _doIt, 'state': 'end'}
- }
- }
-
-job2phonecall('hr.applicant.reschedule_phone_call')
-
-class job2meeting(wizard.interface):
-
- def _makeMeeting(self, cr, uid, data, context):
- pool = pooler.get_pool(cr.dbname)
- job_case_obj = pool.get('hr.applicant')
- meeting_case_obj = pool.get('hr.meeting')
- for job in job_case_obj.browse(cr, uid, data['ids']):
- new_meeting_id = meeting_case_obj.create(cr, uid, {
- 'name': job.name,
- 'date': job.date,
- 'duration': job.duration,
- })
- new_meeting = meeting_case_obj.browse(cr, uid, new_meeting_id)
- vals = {}
- job_case_obj.write(cr, uid, [job.id], vals)
- job_case_obj.case_cancel(cr, uid, [job.id])
- meeting_case_obj.case_open(cr, uid, [new_meeting_id])
-
- data_obj = pool.get('ir.model.data')
- result = data_obj._get_id(cr, uid, 'hr', 'view_hr_case_meetings_filter')
- id = data_obj.read(cr, uid, result, ['res_id'])
- id1 = data_obj._get_id(cr, uid, 'hr', 'hr_case_calendar_view_meet')
- id2 = data_obj._get_id(cr, uid, 'hr', 'hr_case_form_view_meet')
- id3 = data_obj._get_id(cr, uid, 'hr', 'hr_case_tree_view_meet')
- if id1:
- id1 = data_obj.browse(cr, uid, id1, context=context).res_id
- if id2:
- id2 = data_obj.browse(cr, uid, id2, context=context).res_id
- if id3:
- id3 = data_obj.browse(cr, uid, id3, context=context).res_id
- return {
- 'name': _('Meetings'),
- 'view_type': 'form',
- 'view_mode': 'calendar,form,tree',
- 'res_model': 'hr.meeting',
- 'view_id': False,
- 'views': [(id1,'calendar'),(id2,'form'),(id3,'tree'),(False,'graph')],
- 'type': 'ir.actions.act_window',
- 'search_view_id': id['res_id']
- }
-
- states = {
- 'init': {
- 'actions': [],
- 'result': {'type': 'action', 'action': _makeMeeting, 'state': 'order'}
- },
- 'order': {
- 'actions': [],
- 'result': {'type': 'state', 'state': 'end'}
- }
- }
-
-job2meeting('hr.applicant.meeting_set')
-
-
-class partner_create(wizard.interface):
-
- case_form = """
- """
-
- case_fields = {
- 'close': {'type':'boolean', 'string':'Close job request'}
- }
-
- def _selectPartner(self, cr, uid, data, context):
- pool = pooler.get_pool(cr.dbname)
- case_obj = pool.get('hr.applicant')
- for case in case_obj.browse(cr, uid, data['ids']):
- if case.partner_id:
- raise wizard.except_wizard(_('Warning !'),
- _('A partner is already defined on this job request.'))
- return {}
-
- def _makeOrder(self, cr, uid, data, context):
- pool = pooler.get_pool(cr.dbname)
- mod_obj = pool.get('ir.model.data')
- result = mod_obj._get_id(cr, uid, 'base', 'view_res_partner_filter')
- res = mod_obj.read(cr, uid, result, ['res_id'])
- case_obj = pool.get('hr.applicant')
- partner_obj = pool.get('res.partner')
- contact_obj = pool.get('res.partner.address')
- for case in case_obj.browse(cr, uid, data['ids']):
- partner_id = partner_obj.search(cr, uid, [('name', '=', case.partner_name or case.name)])
- if partner_id:
- raise wizard.except_wizard(_('Warning !'),_('A partner is already existing with the same name.'))
- else:
- partner_id = partner_obj.create(cr, uid, {
- 'name': case.partner_name or case.name,
- 'user_id': case.user_id.id,
- 'comment': case.description,
- })
- contact_id = contact_obj.create(cr, uid, {
- 'partner_id': partner_id,
- 'name': case.partner_name2,
- 'phone': case.partner_phone,
- 'mobile': case.partner_mobile,
- 'email': case.email_from
- })
-
-
- case_obj.write(cr, uid, data['ids'], {
- 'partner_id': partner_id,
- 'partner_address_id': contact_id
- })
- if data['form']['close']:
- case_obj.case_close(cr, uid, data['ids'])
-
- value = {
- 'domain': "[]",
- 'view_type': 'form',
- 'view_mode': 'form,tree',
- 'res_model': 'res.partner',
- 'res_id': int(partner_id),
- 'view_id': False,
- 'type': 'ir.actions.act_window',
- 'search_view_id': res['res_id']
- }
- return value
-
- states = {
- 'init': {
- 'actions': [_selectPartner],
- 'result': {'type': 'form', 'arch': case_form, 'fields': case_fields,
- 'state' : [('end', 'Cancel', 'gtk-cancel'),('confirm', 'Create Partner', 'gtk-go-forward')]}
- },
- 'confirm': {
- 'actions': [],
- 'result': {'type': 'action', 'action': _makeOrder, 'state': 'end'}
- }
- }
-
-partner_create('hr.applicant.partner_create')
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
index 04d9451a4bf..1a8b110d690 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
@@ -192,10 +192,10 @@
-
+
-
-
+
+
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index 0c5a1252d59..7433520234e 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -188,7 +188,7 @@
-
+
diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py
index d1ab1f2b577..20e0d30d8fb 100644
--- a/addons/stock/__openerp__.py
+++ b/addons/stock/__openerp__.py
@@ -62,6 +62,7 @@ Thanks to the double entry management, the inventory controlling is powerful and
"product_data.xml",
"product_view.xml",
"partner_view.xml",
+ "report/report_stock_move_view.xml",
"report/report_stock_view.xml",
"report/report_stock_picking_view.xml",
"security/stock_security.xml",
diff --git a/addons/stock/report/__init__.py b/addons/stock/report/__init__.py
index 6e0bc044d3e..6b7f36a69fc 100644
--- a/addons/stock/report/__init__.py
+++ b/addons/stock/report/__init__.py
@@ -28,6 +28,7 @@ import lot_overview
import lot_overview_all
import report_stock
import report_stock_picking
+import report_stock_move
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/stock/report/report_stock_move.py b/addons/stock/report/report_stock_move.py
new file mode 100755
index 00000000000..b5388b336e6
--- /dev/null
+++ b/addons/stock/report/report_stock_move.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+import tools
+from osv import fields,osv
+
+
+class report_stock_move(osv.osv):
+ _name = "report.stock.move"
+ _description = "Stock Statistics"
+ _auto = False
+ _columns = {
+ 'date': fields.date('Date', readonly=True),
+ 'year': fields.char('Year', size=4, readonly=True),
+ 'day': fields.char('Day', size=128, readonly=True),
+ 'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
+ ('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
+ ('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
+ 'product_id':fields.many2one('product.product', 'Product', readonly=True),
+ 'location_id':fields.many2one('stock.location', 'Location', readonly=True),
+ 'product_qty':fields.integer('Qty',readonly=True),
+ 'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting'), ('confirmed', 'Confirmed'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, select=True,
+ help='When the stock move is created it is in the \'Draft\' state.\n After that it is set to \'Confirmed\' state.\n If stock is available state is set to \'Avaiable\'.\n When the picking it done the state is \'Done\'.\
+ \nThe state is \'Waiting\' if the move is waiting for another one.'),
+
+ }
+
+ def init(self, cr):
+ tools.drop_view_if_exists(cr, 'report_stock_move')
+ cr.execute("""
+ create or replace view report_stock_move as (
+ select min(m.id) as id,
+ m.date as date,
+ to_char(date_trunc('day',m.date), 'YYYY') as year,
+ to_char(date_trunc('day',m.date), 'MM') as month,
+ to_char(date_trunc('day',m.date), 'YYYY-MM-DD') as day,
+ m.location_id as location_id,
+ m.product_id as product_id,
+ m.state as state,
+ sum(m.product_qty) as product_qty
+ from stock_move as m group by m.product_id, m.location_id, m.id, m.date, m.state
+ )
+ """)
+report_stock_move()
diff --git a/addons/stock/report/report_stock_move_view.xml b/addons/stock/report/report_stock_move_view.xml
new file mode 100755
index 00000000000..79657da0fc7
--- /dev/null
+++ b/addons/stock/report/report_stock_move_view.xml
@@ -0,0 +1,106 @@
+
+
+
+
+ report.stock.move.tree
+ report.stock.move
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ report.stock.move.graph
+ report.stock.move
+ graph
+
+
+
+
+
+
+
+
+
+ report.stock.move.search
+ report.stock.move
+ search
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Stock Moves
+ report.stock.move
+ form
+ tree,graph
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file