-
-
-
- hr.action.reason.tree
- hr.action.reason
- tree
-
-
-
-
-
-
-
-
- Attendance Reasons
- ir.actions.act_window
- hr.action.reason
- form
- tree,form
-
-
-
-
+
diff --git a/addons/hr/hr_wizard.xml b/addons/hr/hr_wizard.xml
index 71dcb201381..8b3c3e1c619 100644
--- a/addons/hr/hr_wizard.xml
+++ b/addons/hr/hr_wizard.xml
@@ -2,15 +2,12 @@
-
-
-
-
+
diff --git a/addons/hr/report/__init__.py b/addons/hr/report/__init__.py
index b3d4f8263fe..0a96f7363f4 100644
--- a/addons/hr/report/__init__.py
+++ b/addons/hr/report/__init__.py
@@ -29,7 +29,6 @@
##############################################################################
import bymonth
-import attendance_errors
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr/wizard/__init__.py b/addons/hr/wizard/__init__.py
index dab91d43608..e898f4c6561 100644
--- a/addons/hr/wizard/__init__.py
+++ b/addons/hr/wizard/__init__.py
@@ -28,11 +28,11 @@
#
##############################################################################
-from print_byweek import wiz_byweek
-from print_bymonth import wiz_bymonth
-import print_attendance_error
+#from print_byweek import wiz_byweek
+#from print_bymonth import wiz_bymonth
+
+
-import sign_in_out
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_attendance/__init__.py b/addons/hr_attendance/__init__.py
new file mode 100644
index 00000000000..917959631a7
--- /dev/null
+++ b/addons/hr_attendance/__init__.py
@@ -0,0 +1,35 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#
+# $Id$
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+import hr_attendance
+import wizard
+import report
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_attendance/__terp__.py b/addons/hr_attendance/__terp__.py
new file mode 100644
index 00000000000..0dd9eff1013
--- /dev/null
+++ b/addons/hr_attendance/__terp__.py
@@ -0,0 +1,16 @@
+{
+ "name" : "Attendances Of Employees",
+ "version" : "1.0",
+ "author" : "Tiny",
+ "category" : "Generic Modules/Human Resources",
+ "description": "This module aims to manage employee's attendances.",
+ "depends" : ["base","hr",],
+ "demo_xml" : ["hr_attendance_demo.xml"],
+ "update_xml" : [
+ "hr_attendance_view.xml",
+ "hr_attendance_wizard.xml",
+ "hr_attendance_report.xml"
+ ],
+ "active": False,
+ "installable": True,
+}
diff --git a/addons/hr_attendance/hr_attendance.py b/addons/hr_attendance/hr_attendance.py
new file mode 100644
index 00000000000..7550ec18847
--- /dev/null
+++ b/addons/hr_attendance/hr_attendance.py
@@ -0,0 +1,158 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#
+# $Id$
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+from mx import DateTime
+import time
+
+from osv import fields, osv
+from tools.translate import _
+
+class hr_action_reason(osv.osv):
+ _name = "hr.action.reason"
+ _description = "Action reason"
+ _columns = {
+ 'name' : fields.char('Reason', size=64, required=True),
+ 'action_type' : fields.selection([('sign_in', 'Sign in'), ('sign_out', 'Sign out')], "Action's type"),
+ }
+ _defaults = {
+ 'action_type' : lambda *a: 'sign_in',
+ }
+hr_action_reason()
+
+def _employee_get(obj,cr,uid,context={}):
+ ids = obj.pool.get('hr.employee').search(cr, uid, [('user_id','=', uid)])
+ if ids:
+ return ids[0]
+ return False
+
+class hr_attendance(osv.osv):
+ _name = "hr.attendance"
+ _description = "Attendance"
+ _columns = {
+ 'name' : fields.datetime('Date', required=True),
+ 'action' : fields.selection([('sign_in', 'Sign In'), ('sign_out', 'Sign Out'),('action','Action')], 'Action', required=True),
+ 'action_desc' : fields.many2one("hr.action.reason", "Action reason", domain="[('action_type', '=', action)]"),
+ 'employee_id' : fields.many2one('hr.employee', 'Employee', required=True, select=True),
+ }
+ _defaults = {
+ 'name' : lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'employee_id' : _employee_get,
+ }
+
+ def _altern_si_so(self, cr, uid, ids):
+ for id in ids:
+ sql = '''
+ select action, name
+ from hr_attendance as att
+ where employee_id = (select employee_id from hr_attendance where id=%s)
+ and action in ('sign_in','sign_out')
+ and name <= (select name from hr_attendance where id=%s)
+ order by name desc
+ limit 2
+ ''' % (id, id)
+ cr.execute(sql)
+ atts = cr.fetchall()
+ if not ((len(atts)==1 and atts[0][0] == 'sign_in') or (atts[0][0] != atts[1][0] and atts[0][1] != atts[1][1])):
+ return False
+ return True
+
+ _constraints = [(_altern_si_so, 'Error: Sign in (resp. Sign out) must follow Sign out (resp. Sign in)', ['action'])]
+ _order = 'name desc'
+hr_attendance()
+
+class hr_employee(osv.osv):
+ _inherit = "hr.employee"
+ _description = "Employee"
+
+ def _state(self, cr, uid, ids, name, args, context={}):
+ result = {}
+ for id in ids:
+ result[id] = 'absent'
+ cr.execute('SELECT hr_attendance.action, hr_attendance.employee_id \
+ FROM ( \
+ SELECT MAX(name) AS name, employee_id \
+ FROM hr_attendance \
+ WHERE action in (\'sign_in\', \'sign_out\') \
+ GROUP BY employee_id \
+ ) AS foo \
+ LEFT JOIN hr_attendance \
+ ON (hr_attendance.employee_id = foo.employee_id \
+ AND hr_attendance.name = foo.name) \
+ WHERE hr_attendance.employee_id \
+ in (' + ','.join([str(x) for x in ids]) + ')')
+ for res in cr.fetchall():
+ result[res[1]] = res[0] == 'sign_in' and 'present' or 'absent'
+ return result
+
+ _columns = {
+ 'state': fields.function(_state, method=True, type='selection', selection=[('absent', 'Absent'), ('present', 'Present')], string='Attendance'),
+ }
+
+ def sign_change(self, cr, uid, ids, context={}, dt=False):
+ for emp in self.browse(cr, uid, ids):
+ if not self._action_check(cr, uid, emp.id, dt, context):
+ raise osv.except_osv(_('Warning'), _('You tried to sign with a date anterior to another event !\nTry to contact the administrator to correct attendances.'))
+ res = {'action':'action', 'employee_id':emp.id}
+ if dt:
+ res['name'] = dt
+ att_id = self.pool.get('hr.attendance').create(cr, uid, res, context=context)
+ return True
+
+ def sign_out(self, cr, uid, ids, context={}, dt=False, *args):
+ id = False
+ for emp in self.browse(cr, uid, ids):
+ if not self._action_check(cr, uid, emp.id, dt, context):
+ raise osv.except_osv(_('Warning'), _('You tried to sign out with a date anterior to another event !\nTry to contact the administrator to correct attendances.'))
+ res = {'action':'sign_out', 'employee_id':emp.id}
+ if dt:
+ res['name'] = dt
+ att_id = self.pool.get('hr.attendance').create(cr, uid, res, context=context)
+ id = att_id
+ return id
+
+ def _action_check(self, cr, uid, emp_id, dt=False,context={}):
+ cr.execute('select max(name) from hr_attendance where employee_id=%d', (emp_id,))
+ res = cr.fetchone()
+ return not (res and (res[0]>=(dt or time.strftime('%Y-%m-%d %H:%M:%S'))))
+
+ def sign_in(self, cr, uid, ids, context={}, dt=False, *args):
+ id = False
+ for emp in self.browse(cr, uid, ids):
+ if not self._action_check(cr, uid, emp.id, dt, context):
+ raise osv.except_osv(_('Warning'), _('You tried to sign in with a date anterior to another event !\nTry to contact the administrator to correct attendances.'))
+ res = {'action':'sign_in', 'employee_id':emp.id}
+ if dt:
+ res['name'] = dt
+ id = self.pool.get('hr.attendance').create(cr, uid, res, context=context)
+ return id
+
+hr_employee()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_attendance/hr_attendance_demo.xml b/addons/hr_attendance/hr_attendance_demo.xml
new file mode 100644
index 00000000000..640d6b5257a
--- /dev/null
+++ b/addons/hr_attendance/hr_attendance_demo.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+ sign_in
+
+
+
+
+ sign_out
+
+
+
+
+ sign_in
+
+
+
+
+ sign_out
+
+
+
+
+ sign_in
+
+
+
+
+ sign_out
+
+
+
+
+ sign_in
+
+
+
+
+ sign_out
+
+
+
+
+ sign_in
+
+
+
+
+ sign_out
+
+
+
+
+ sign_in
+
+
+
+
+ sign_out
+
+
+
+
+ sign_in
+
+
+
+
+ sign_out
+
+
+
+
+ sign_in
+
+
+
+
+ sign_out
+
+
+
+
+ sign_in
+
+
+
+
+ sign_out
+
+
+
+
+ sign_in
+
+
+
+
+ sign_out
+
+
+
+
diff --git a/addons/hr/hr_report.xml b/addons/hr_attendance/hr_attendance_report.xml
similarity index 100%
rename from addons/hr/hr_report.xml
rename to addons/hr_attendance/hr_attendance_report.xml
diff --git a/addons/hr_attendance/hr_attendance_view.xml b/addons/hr_attendance/hr_attendance_view.xml
new file mode 100644
index 00000000000..fe2b1e6f0dc
--- /dev/null
+++ b/addons/hr_attendance/hr_attendance_view.xml
@@ -0,0 +1,102 @@
+
+
+
+
+
+ hr.attendance.form
+ hr.attendance
+ form
+
+
+
+
+
+ hr.action.reason.tree
+ hr.action.reason
+ tree
+
+
+
+
+
+
+
+
+ Attendance Reasons
+ ir.actions.act_window
+ hr.action.reason
+ form
+ tree,form
+
+
+
+
+
+ hr.employee.form1
+ hr.employee
+ form
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/hr_attendance/hr_attendance_wizard.xml b/addons/hr_attendance/hr_attendance_wizard.xml
new file mode 100644
index 00000000000..707e63a4460
--- /dev/null
+++ b/addons/hr_attendance/hr_attendance_wizard.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/hr_attendance/report/__init__.py b/addons/hr_attendance/report/__init__.py
new file mode 100644
index 00000000000..c9f1ff7008a
--- /dev/null
+++ b/addons/hr_attendance/report/__init__.py
@@ -0,0 +1,32 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#
+# $Id$
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+import attendance_errors
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr/report/attendance_errors.py b/addons/hr_attendance/report/attendance_errors.py
similarity index 97%
rename from addons/hr/report/attendance_errors.py
rename to addons/hr_attendance/report/attendance_errors.py
index 231fe98b8e5..286fad59f67 100644
--- a/addons/hr/report/attendance_errors.py
+++ b/addons/hr_attendance/report/attendance_errors.py
@@ -81,7 +81,7 @@ class attendance_print(report_sxw.rml_parse):
return (self._sign(total),total2 and self._sign(total2))
-report_sxw.report_sxw('report.hr.timesheet.attendance.error', 'hr.employee', 'addons/hr/report/attendance_errors.rml',parser=attendance_print)
+report_sxw.report_sxw('report.hr.timesheet.attendance.error', 'hr.employee', 'addons/hr_attendance/report/attendance_errors.rml',parser=attendance_print)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr/report/attendance_errors.rml b/addons/hr_attendance/report/attendance_errors.rml
similarity index 75%
rename from addons/hr/report/attendance_errors.rml
rename to addons/hr_attendance/report/attendance_errors.rml
index a2d9ebe3625..aacdde99e06 100644
--- a/addons/hr/report/attendance_errors.rml
+++ b/addons/hr_attendance/report/attendance_errors.rml
@@ -10,7 +10,7 @@
-
+
@@ -33,7 +33,7 @@
-
+
@@ -42,7 +42,7 @@
-
+
@@ -52,7 +52,6 @@
-
@@ -71,6 +70,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -80,10 +91,10 @@
-
+
-
+
- (*) A positive delay means that the employee worked less than recorded.
- (*) A negative delay means that the employee worked more than encoded.
+ (*) A positive delay means that the employee worked less than recorded.
+ (*) A negative delay means that the employee worked more than encoded.
diff --git a/addons/hr_attendance/wizard/__init__.py b/addons/hr_attendance/wizard/__init__.py
new file mode 100644
index 00000000000..447b2047f2c
--- /dev/null
+++ b/addons/hr_attendance/wizard/__init__.py
@@ -0,0 +1,33 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#
+# $Id$
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+import sign_in_out
+import print_attendance_error
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr/wizard/print_attendance_error.py b/addons/hr_attendance/wizard/print_attendance_error.py
similarity index 100%
rename from addons/hr/wizard/print_attendance_error.py
rename to addons/hr_attendance/wizard/print_attendance_error.py
diff --git a/addons/hr_attendance/wizard/sign_in_out.py b/addons/hr_attendance/wizard/sign_in_out.py
new file mode 100644
index 00000000000..a3e82b9d669
--- /dev/null
+++ b/addons/hr_attendance/wizard/sign_in_out.py
@@ -0,0 +1,194 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#
+# $Id$
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+import wizard
+import netsvc
+import time
+from tools.translate import _
+
+si_so_form ='''
+
- [[ '%.2f' % (sum_revenue(objects) or 0.0) ]]
+ [[ '%.2f' % (sum_balance(objects,data['form']['date1'],data['form']['date2']) or 0.0) ]]
-
+
-
-
+
\ No newline at end of file
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_demo.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_demo.xml
index 4b707196d37..c687b171640 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_demo.xml
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_demo.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
index ab654cad9b7..00b01f46ed2 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
@@ -279,7 +279,7 @@
hr.attendance.formhr.attendanceform
-
+
@@ -290,7 +290,7 @@
hr.attendance.treehr.attendancetree
-
+
diff --git a/addons/l10n_be/account_pcmn_belgium.xml b/addons/l10n_be/account_pcmn_belgium.xml
index 2104baf6670..d7252313333 100644
--- a/addons/l10n_be/account_pcmn_belgium.xml
+++ b/addons/l10n_be/account_pcmn_belgium.xml
@@ -6615,7 +6615,7 @@
- Template of the belgian Chart of Accounts
+ Belgian PCMN
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index 121ebbe6e1d..170cefd6fbc 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -49,26 +49,28 @@ class mrp_workcenter(osv.osv):
_name = 'mrp.workcenter'
_description = 'Workcenter'
_columns = {
- 'name': fields.char('Name', size=64, required=True),
+ 'name': fields.char('Workcenter Name', size=64, required=True),
'active': fields.boolean('Active'),
'type': fields.selection([('machine','Machine'),('hr','Human Resource'),('tool','Tool')], 'Type', required=True),
- 'code': fields.char('Code', size=8),
- 'timesheet_id': fields.many2one('hr.timesheet.group', 'Timesheet'),
- 'note': fields.text('Description'),
+ 'code': fields.char('Code', size=16),
+ 'timesheet_id': fields.many2one('hr.timesheet.group', 'Working Time', help="The normal working time of the workcenter."),
+ 'note': fields.text('Description', help="Description of the workcenter. Explain here what's a cycle according to this workcenter."),
- 'capacity_per_cycle': fields.float('Capacity per Cycle'),
+ 'capacity_per_cycle': fields.float('Capacity per Cycle', help="Number of operation this workcenter can do in parallel. If this workcenter represent a team of 5 workers, the capacity per cycle is 5."),
- 'time_cycle': fields.float('Time for 1 cycle (hour)'),
- 'time_start': fields.float('Time before prod.'),
- 'time_stop': fields.float('Time after prod.'),
- 'time_efficiency': fields.float('Time Efficiency'),
+ 'time_cycle': fields.float('Time for 1 cycle (hour)', help="Time in hours for doing one cycle."),
+ 'time_start': fields.float('Time before prod.', help="Time in hours for the setup."),
+ 'time_stop': fields.float('Time after prod.', help="Time in hours for the cleaning."),
+ 'time_efficiency': fields.float('Time Efficiency', help="Factor that multiplies all times expressed in the workcenter."),
'costs_hour': fields.float('Cost per hour'),
- 'costs_hour_account_id': fields.many2one('account.analytic.account', 'Hour Account', domain=[('type','=','expense')]),
+ 'costs_hour_account_id': fields.many2one('account.analytic.account', 'Hour Account', domain=[('type','<>','view')],
+ help="Complete this only if you want automatic analytic accounting entries on production orders."),
'costs_cycle': fields.float('Cost per cycle'),
- 'costs_cycle_account_id': fields.many2one('account.analytic.account', 'Cycle Account', domain=[('type','=','expense')]),
+ 'costs_cycle_account_id': fields.many2one('account.analytic.account', 'Cycle Account', domain=[('type','<>','view')],
+ help="Complete this only if you want automatic analytic accounting entries on production orders."),
'costs_journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal'),
- 'costs_general_account_id': fields.many2one('account.account', 'General Account'),
+ 'costs_general_account_id': fields.many2one('account.account', 'General Account', domain=[('type','<>','view')]),
}
_defaults = {
'active': lambda *a: 1,
@@ -93,7 +95,7 @@ class mrp_property(osv.osv):
_description = 'Property'
_columns = {
'name': fields.char('Name', size=64, required=True),
- 'composition': fields.selection([('min','min'),('max','max'),('plus','plus')], 'Properties composition', required=True),
+ 'composition': fields.selection([('min','min'),('max','max'),('plus','plus')], 'Properties composition', required=True, help="Not used in computations, for information purpose only."),
'group_id': fields.many2one('mrp.property.group', 'Property Group', required=True),
'description': fields.text('Description'),
}
@@ -113,7 +115,11 @@ class mrp_routing(osv.osv):
'note': fields.text('Description'),
'workcenter_lines': fields.one2many('mrp.routing.workcenter', 'routing_id', 'Workcenters'),
- 'location_id': fields.many2one('stock.location', 'Production Location'),
+ 'location_id': fields.many2one('stock.location', 'Production Location',
+ help="Keep empty if you produce at the location where the finnished products are needed." \
+ "Put a location if you produce at a fixed location. This can be a partner location " \
+ "if you subcontract the manufacturing operations."
+ ),
}
_defaults = {
'active': lambda *a: 1,
@@ -127,8 +133,8 @@ class mrp_routing_workcenter(osv.osv):
'workcenter_id': fields.many2one('mrp.workcenter', 'Workcenter', required=True),
'name': fields.char('Name', size=64, required=True),
'sequence': fields.integer('Sequence'),
- 'cycle_nbr': fields.float('Number of cycle', required=True),
- 'hour_nbr': fields.float('Number of hours', required=True),
+ 'cycle_nbr': fields.float('Number of Cycle', required=True),
+ 'hour_nbr': fields.float('Number of Hours', required=True),
'routing_id': fields.many2one('mrp.routing', 'Parent Routing', select=True),
'note': fields.text('Description')
}
@@ -145,11 +151,11 @@ class mrp_bom(osv.osv):
'name': fields.char('Name', size=64, required=True),
'code': fields.char('Code', size=16),
'active': fields.boolean('Active'),
- 'type': fields.selection([('normal','Normal BoM'),('phantom','Sets / Phantom')], 'BoM Type', required=True, help="Use a phantom bill of material in lines that have a sub-bom and that have to be automatically computed in one line, without habing two production orders."),
- 'date_start': fields.date('Valid from'),
- 'date_stop': fields.date('Valid until'),
+ 'type': fields.selection([('normal','Normal BoM'),('phantom','Sets / Phantom')], 'BoM Type', required=True, help="Use a phantom bill of material in lines that have a sub-bom and that have to be automatically computed in one line, without having two production orders."),
+ 'date_start': fields.date('Valid From', help="Validity of this BoM or component. Keep empty if it's always valid."),
+ 'date_stop': fields.date('Valid Until', help="Validity of this BoM or component. Keep empty if it's always valid."),
'sequence': fields.integer('Sequence'),
- 'position': fields.char('Internal Ref.', size=64),
+ 'position': fields.char('Internal Ref.', size=64, help="Reference to a position in an external plan."),
'product_id': fields.many2one('product.product', 'Product', required=True),
'product_uos_qty': fields.float('Product UOS Qty'),
'product_uos': fields.many2one('product.uom', 'Product UOS'),
@@ -304,6 +310,33 @@ class mrp_production(osv.osv):
_name = 'mrp.production'
_description = 'Production'
_date_name = 'date_planned'
+
+ def _get_sale_order(self,cr,uid,ids,field_name=False):
+ move_obj=self.pool.get('stock.move')
+ def get_parent_move(move_id):
+ move = move_obj.browse(cr,uid,move_id)
+ if move.move_dest_id:
+ return get_parent_move(move.move_dest_id.id)
+ return move_id
+ productions=self.read(cr,uid,ids,['id','move_prod_id'])
+ res={}
+ for production in productions:
+ if production.get('move_prod_id',False):
+ parent_move_line=get_parent_move(production['move_prod_id'][0])
+ if parent_move_line:
+ move = move_obj.browse(cr,uid,parent_move_line)
+ if field_name=='name':
+ res[production['id']]=move.sale_line_id and move.sale_line_id.order_id.name or False
+ if field_name=='client_order_ref':
+ res[production['id']]=move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False
+ return res
+
+ def _sale_name_calc(self, cr, uid, ids, prop, unknow_none, unknow_dict):
+ return self._get_sale_order(cr,uid,ids,field_name='name')
+
+ def _sale_ref_calc(self, cr, uid, ids, prop, unknow_none, unknow_dict):
+ return self._get_sale_order(cr,uid,ids,field_name='client_order_ref')
+
_columns = {
'name': fields.char('Reference', size=64, required=True),
'origin': fields.char('Origin', size=64),
@@ -332,7 +365,9 @@ class mrp_production(osv.osv):
'product_lines': fields.one2many('mrp.production.product.line', 'production_id', 'Scheduled goods'),
'workcenter_lines': fields.one2many('mrp.production.workcenter.line', 'production_id', 'Workcenters Utilisation'),
- 'state': fields.selection([('draft','Draft'),('picking_except', 'Packing Exception'),('confirmed','Waiting Goods'),('ready','Ready to Produce'),('in_production','In Production'),('cancel','Canceled'),('done','Done')],'Status', readonly=True)
+ 'state': fields.selection([('draft','Draft'),('picking_except', 'Packing Exception'),('confirmed','Waiting Goods'),('ready','Ready to Produce'),('in_production','In Production'),('cancel','Canceled'),('done','Done')],'Status', readonly=True),
+ 'sale_name': fields.function(_sale_name_calc, method=True, type='char', string='Sale Name'),
+ 'sale_ref': fields.function(_sale_ref_calc, method=True, type='char', string='Sale Ref'),
}
_defaults = {
'priority': lambda *a: '1',
@@ -611,11 +646,9 @@ mrp_production()
class stock_move(osv.osv):
_name = 'stock.move'
_inherit = 'stock.move'
-
_columns = {
- 'production_id': fields.many2one('mrp.production', 'Production', select=True),
- }
-
+ 'production_id': fields.many2one('mrp.production', 'Production', select=True),
+ }
stock_move()
class mrp_production_workcenter_line(osv.osv):
diff --git a/addons/mrp/mrp_report.xml b/addons/mrp/mrp_report.xml
index f6eca4722e8..eb97477f687 100644
--- a/addons/mrp/mrp_report.xml
+++ b/addons/mrp/mrp_report.xml
@@ -4,5 +4,14 @@
+
+
diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml
index 55986cd260c..50cfd1881c6 100644
--- a/addons/mrp/mrp_view.xml
+++ b/addons/mrp/mrp_view.xml
@@ -406,7 +406,6 @@
-
@@ -440,7 +439,7 @@
-
+
@@ -448,6 +447,8 @@
+
+
@@ -677,7 +678,7 @@
form
-
+
Draft procurements
@@ -706,7 +707,7 @@
tree,form[('state','=','exception')]
-
+
Exceptions procurements to fix
@@ -735,7 +736,7 @@
formform,tree
-
+
diff --git a/addons/mrp/report/__init__.py b/addons/mrp/report/__init__.py
index f55a94f166e..32bb00568ff 100644
--- a/addons/mrp/report/__init__.py
+++ b/addons/mrp/report/__init__.py
@@ -28,6 +28,7 @@
###############################################################################
import price
import workcenter_load
+import order
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/mrp/report/order.py b/addons/mrp/report/order.py
new file mode 100644
index 00000000000..1d801b3aa2e
--- /dev/null
+++ b/addons/mrp/report/order.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+import time
+from report import report_sxw
+from osv import osv
+import pooler
+
+class order(report_sxw.rml_parse):
+ def __init__(self, cr, uid, name, context):
+ super(order, self).__init__(cr, uid, name, context)
+ self.localcontext.update({
+ 'time': time,
+ })
+
+
+report_sxw.report_sxw('report.mrp.production.order','mrp.production','addons/mrp/report/order.rml',parser=order)
diff --git a/addons/mrp/report/order.rml b/addons/mrp/report/order.rml
new file mode 100644
index 00000000000..cc1b0bf34b3
--- /dev/null
+++ b/addons/mrp/report/order.rml
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [[ repeatIn(objects,'o') ]]
+
+
+
+
+
+
+ Production Order N° : [[ o.name ]]
+
+
+
+ Printing date : [[ time.strftime('%d/%m/%Y') ]]
+ Partner Order reference : [[ o.sale_ref or ' ' ]]
+ SO number : [[ o.sale_name or '' ]]
+
+
+
+
+
+
+
+
+
+ Process Nodes
+ process.node
+ form
+ tree,form
+
+
+
+
@@ -152,9 +282,13 @@
-
-
-
+
+
+
+
+
+
+
diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py
index e5d52cbb632..3d597f45a8c 100644
--- a/addons/product/pricelist.py
+++ b/addons/product/pricelist.py
@@ -56,10 +56,10 @@ class price_type(osv.osv):
_name = "product.price.type"
_description = "Price type"
_columns = {
- "name" : fields.char("Price Name", size=32, required=True, translate=True) ,
+ "name" : fields.char("Price Name", size=32, required=True, translate=True, help="Name of this kind of price."),
"active" : fields.boolean("Active"),
- "field" : fields.selection(_price_field_get, "Product Field", required=True),
- "currency_id" : fields.many2one('res.currency', "Currency", required=True),
+ "field" : fields.selection(_price_field_get, "Product Field", required=True, help="Associated field in the product form."),
+ "currency_id" : fields.many2one('res.currency', "Currency", required=True, help="The currency the field is expressed in."),
}
_defaults = {
"active": lambda *args: True,
@@ -76,7 +76,7 @@ class product_pricelist_type(osv.osv):
_description = "Pricelist Type"
_columns = {
'name': fields.char('Name',size=64, required=True),
- 'key': fields.char('Key', size=64, required=True),
+ 'key': fields.char('Key', size=64, required=True, help="Used in the code to select specific prices based on the context. Keep unchanged."),
}
product_pricelist_type()
@@ -88,7 +88,7 @@ class product_pricelist(osv.osv):
_name = "product.pricelist"
_description = "Pricelist"
_columns = {
- 'name': fields.char('Name',size=64, required=True, translate=True),
+ 'name': fields.char('Pricelist Name',size=64, required=True, translate=True),
'active': fields.boolean('Active'),
'type': fields.selection(_pricelist_type_get, 'Pricelist Type', required=True),
'version_id': fields.one2many('product.pricelist.version', 'pricelist_id', 'Pricelist Versions'),
@@ -247,8 +247,8 @@ class product_pricelist_version(osv.osv):
'active': fields.boolean('Active'),
'items_id': fields.one2many('product.pricelist.item',
'price_version_id', 'Price List Items', required=True),
- 'date_start': fields.date('Start Date'),
- 'date_end': fields.date('End Date'),
+ 'date_start': fields.date('Start Date', help="Starting date for validity of this pricelist version."),
+ 'date_end': fields.date('End Date', help="Ending date for validity of this pricelist version."),
}
_defaults = {
'active': lambda *a: 1,
@@ -320,22 +320,26 @@ class product_pricelist_item(osv.osv):
'price_discount': lambda *a: 0,
}
_columns = {
- 'name': fields.char('Name', size=64),
+ 'name': fields.char('Rule Name', size=64, help="Explicit rule name for this pricelist line."),
'price_version_id': fields.many2one('product.pricelist.version', 'Price List Version', required=True, select=True),
- 'product_tmpl_id': fields.many2one('product.template', 'Product Template', ondelete='cascade'),
- 'product_id': fields.many2one('product.product', 'Product', ondelete='cascade'),
- 'categ_id': fields.many2one('product.category', 'Product Category', ondelete='cascade'),
+ 'product_tmpl_id': fields.many2one('product.template', 'Product Template', ondelete='cascade', help="Set a template if this rule only apply to a template of product. Keep empty for all products"),
+ 'product_id': fields.many2one('product.product', 'Product', ondelete='cascade', help="Set a product if this rule only apply to one product. Keep empty for all products"),
+ 'categ_id': fields.many2one('product.category', 'Product Category', ondelete='cascade', help="Set a category of product if this rule only apply to products of a category and his childs. Keep empty for all products"),
- 'min_quantity': fields.integer('Min. Quantity', required=True),
+ 'min_quantity': fields.integer('Min. Quantity', required=True, help="The rule only apply if the partner buys/sells more than this quantity."),
'sequence': fields.integer('Sequence', required=True),
- 'base': fields.selection(_price_field_get, 'Based on', required=True, size=-1),
+ 'base': fields.selection(_price_field_get, 'Based on', required=True, size=-1, help="The mode of computation of the price for this rule."),
'base_pricelist_id': fields.many2one('product.pricelist', 'If Other Pricelist'),
'price_surcharge': fields.float('Price Surcharge',
digits=(16, int(config['price_accuracy']))),
'price_discount': fields.float('Price Discount', digits=(16,4)),
'price_round': fields.float('Price Rounding',
- digits=(16, int(config['price_accuracy']))),
+ digits=(16, int(config['price_accuracy'])),
+ help="Sets the price so that it is a multiple of this value.\n" \
+ "Rounding is applied after the discount and before the surcharge.\n" \
+ "To have prices that ends by 9.99, set rounding 10, surcharge -0.01" \
+ ),
'price_min_margin': fields.float('Price Min. Margin',
digits=(16, int(config['price_accuracy']))),
'price_max_margin': fields.float('Price Max. Margin',
diff --git a/addons/product/product.py b/addons/product/product.py
index 5c7f7d13bff..671433bd0fe 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -87,7 +87,8 @@ class product_uom(osv.osv):
_columns = {
'name': fields.char('Name', size=64, required=True),
- 'category_id': fields.many2one('product.uom.categ', 'UOM Category', required=True, ondelete='cascade'),
+ 'category_id': fields.many2one('product.uom.categ', 'UoM Category', required=True, ondelete='cascade',
+ help="Unit of Measure of the same category can be converted between each others."),
'factor': fields.float('Rate', digits=(12, 6), required=True,
help='The coefficient for the formula:\n' \
'1 (base unit) = coef (this unit)'),
@@ -96,7 +97,8 @@ class product_uom(osv.osv):
help='The coefficient for the formula:\n' \
'coef (base unit) = 1 (this unit)'),
'factor_inv_data': fields.float('Factor', digits=(12, 6)),
- 'rounding': fields.float('Rounding Precision', digits=(16, 3), required=True),
+ 'rounding': fields.float('Rounding Precision', digits=(16, 3), required=True,
+ help="The computed quantity will be a multiple of this value. Use 1.0 for products that can not be splitted."),
'active': fields.boolean('Active'),
}
@@ -228,7 +230,6 @@ product_category()
class product_template(osv.osv):
_name = "product.template"
_description = "Product Template"
-
def _calc_seller_delay(self, cr, uid, ids, name, arg, context={}):
result = {}
for product in self.browse(cr, uid, ids, context):
@@ -251,25 +252,25 @@ class product_template(osv.osv):
'procure_method': fields.selection([('make_to_stock','Make to Stock'),('make_to_order','Make to Order')], 'Procure Method', required=True, help="'Make to Stock': When needed, take from the stock or wait until refurnishing. 'Make to Order': When needed, purchase or produce for the procurement request."),
'rental': fields.boolean('Rentable product'),
'categ_id': fields.many2one('product.category','Category', required=True, change_default=True),
- 'list_price': fields.float('Sale Price', digits=(16, int(config['price_accuracy']))),
- 'standard_price': fields.float('Cost Price', required=True, digits=(16, int(config['price_accuracy']))),
+ 'list_price': fields.float('Sale Price', digits=(16, int(config['price_accuracy'])), help="Base price for computing the customer price. Sometimes called the catalog price."),
+ 'standard_price': fields.float('Cost Price', required=True, digits=(16, int(config['price_accuracy'])), help="The cost of the product for accounting stock valorisation. It can serves as a base price for supplier price."),
'volume': fields.float('Volume', help="The weight in Kg."),
'weight': fields.float('Gross weight'),
'weight_net': fields.float('Net weight'),
- 'cost_method': fields.selection([('standard','Standard Price'), ('average','Average Price')], 'Costing Method', required=True),
+ 'cost_method': fields.selection([('standard','Standard Price'), ('average','Average Price')], 'Costing Method', required=True,
+ help="Standard Price: the cost price is fixed and recomputed periodically (usually at the end of the year), Average Price: the cost price is recomputed at each reception of products."),
'warranty': fields.float('Warranty (months)'),
'sale_ok': fields.boolean('Can be sold', help="Determine if the product can be visible in the list of product within a selection from a sale order line."),
'purchase_ok': fields.boolean('Can be Purchased', help="Determine if the product is visible in the list of products within a selection from a purchase order line."),
- 'uom_id': fields.many2one('product.uom', 'Default UoM', required=True, help="This is the default Unit of Measure used for all stock operation."),
- 'uom_po_id': fields.many2one('product.uom', 'Purchase UoM', required=True),
+ 'uom_id': fields.many2one('product.uom', 'Default UoM', required=True, help="Default Unit of Measure used for all stock operation."),
+ 'uom_po_id': fields.many2one('product.uom', 'Purchase UoM', required=True, help="Default Unit of Measure used for purchase orders. It must in the same category than the default unit of measure."),
'state': fields.selection([('',''),('draft', 'In Development'),('sellable','In Production'),('end','End of Lifecycle'),('obsolete','Obsolete')], 'Status', help="Tells the user if he can use the product or not."),
'uos_id' : fields.many2one('product.uom', 'Unit of Sale',
- help='Keep empty to use the default UOM'),
+ help='Used by companies that manages two unit of measure: invoicing and stock management. For example, in food industries, you will manage a stock of ham but invoice in Kg. Keep empty to use the default UOM.'),
'uos_coeff': fields.float('UOM -> UOS Coeff', digits=(16,4),
help='Coefficient to convert UOM to UOS\n'
' uom = uos * coeff'),
'mes_type': fields.selection((('fixed', 'Fixed'), ('variable', 'Variable')), 'Measure Type', required=True),
- 'tracking': fields.boolean('Track Lots', help="Force to use a Production Lot number during stock operations for traceability."),
'seller_delay': fields.function(_calc_seller_delay, method=True, type='integer', string='Supplier Lead Time', help="This is the average delay in days between the purchase order confirmation and the reception of goods for this product and for the default supplier. It is used by the scheduler to order requests based on reordering delays."),
'seller_ids': fields.one2many('product.supplierinfo', 'product_id', 'Partners'),
'loc_rack': fields.char('Rack', size=16),
@@ -414,7 +415,7 @@ class product_product(osv.osv):
'variants': fields.char('Variants', size=64),
'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True),
'ean13': fields.char('EAN13', size=13),
- 'packaging' : fields.one2many('product.packaging', 'product_id', 'Palettization', help="Gives the different ways to package the same product. This has no impact on the packing order and is mainly used if you use the EDI module."),
+ 'packaging' : fields.one2many('product.packaging', 'product_id', 'Logistical Units', help="Gives the different ways to package the same product. This has no impact on the packing order and is mainly used if you use the EDI module."),
'price_extra': fields.float('Variant Price Extra', digits=(16, int(config['price_accuracy']))),
'price_margin': fields.float('Variant Price Margin', digits=(16, int(config['price_accuracy']))),
}
@@ -424,7 +425,6 @@ class product_product(osv.osv):
uom_obj=self.pool.get('product.uom')
uom=uom_obj.browse(cursor,user,[uom_id])[0]
uom_po=uom_obj.browse(cursor,user,[uom_po_id])[0]
- print uom.category_id.id , uom_po.category_id.id
if uom.category_id.id != uom_po.category_id.id:
return {'value': {'uom_po_id': uom_id}}
return False
@@ -529,28 +529,28 @@ product_product()
class product_packaging(osv.osv):
_name = "product.packaging"
- _description = "Conditionnement"
+ _description = "Packaging"
_rec_name = 'ean'
_columns = {
'name' : fields.char('Description', size=64),
- 'qty' : fields.float('Quantity by UL',
- help="The total number of products you can put by UL."),
- 'ul' : fields.many2one('product.ul', 'Type of UL', required=True),
- 'ul_qty' : fields.integer('UL by layer'),
- 'rows' : fields.integer('Number of layer', required=True,
- help='The number of layer on palette'),
+ 'qty' : fields.float('Quantity by Package',
+ help="The total number of products you can put by palet or box."),
+ 'ul' : fields.many2one('product.ul', 'Type of Package', required=True),
+ 'ul_qty' : fields.integer('Package by layer'),
+ 'rows' : fields.integer('Number of Layer', required=True,
+ help='The number of layer on a palet or box'),
'product_id' : fields.many2one('product.product', 'Product', select=1, ondelete='cascade', required=True),
'ean' : fields.char('EAN', size=14,
- help="The EAN code of the transport unit."),
+ help="The EAN code of the package unit."),
'code' : fields.char('Code', size=14,
help="The code of the transport unit."),
- 'weight': fields.float('Palette Weight',
- help='The weight of the empty palette'),
- 'weight_ul': fields.float('UL Weight',
+ 'weight': fields.float('Total Package Weight',
+ help='The weight of a full of products palet or box.'),
+ 'weight_ul': fields.float('Empty Package Weight',
help='The weight of the empty UL'),
- 'height': fields.float('Height', help='The height of the palette'),
- 'width': fields.float('Width', help='The width of the palette'),
- 'length': fields.float('Length', help='The length of the palette'),
+ 'height': fields.float('Height', help='The height of the package'),
+ 'width': fields.float('Width', help='The width of the package'),
+ 'length': fields.float('Length', help='The length of the package'),
}
def _get_1st_ul(self, cr, uid, context={}):
@@ -578,13 +578,13 @@ class product_supplierinfo(osv.osv):
_name = "product.supplierinfo"
_description = "Information about a product supplier"
_columns = {
- 'name' : fields.many2one('res.partner', 'Partner', required=True, ondelete='cascade'),
- 'product_name': fields.char('Partner product name', size=128),
- 'product_code': fields.char('Partner product reference', size=64),
+ 'name' : fields.many2one('res.partner', 'Partner', required=True, ondelete='cascade', help="Supplier of this product"),
+ 'product_name': fields.char('Partner Product Name', size=128, help="Name of the product for this partner, will be used when printing a request for quotation. Keep empty to use the internal one."),
+ 'product_code': fields.char('Partner Product Code', size=64, help="Code of the product for this partner, will be used when printing a request for quotation. Keep empty to use the internal one."),
'sequence' : fields.integer('Priority'),
- 'qty' : fields.float('Minimal quantity', required=True),
+ 'qty' : fields.float('Minimal Quantity', required=True, help="The minimal quantity to purchase for this supplier, expressed in the default unit of measure."),
'product_id' : fields.many2one('product.template', 'Product', required=True, ondelete='cascade', select=True),
- 'delay' : fields.integer('Delivery delay', required=True),
+ 'delay' : fields.integer('Delivery Delay', required=True, help="Delay in days between the confirmation of the purchase order and the reception of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning."),
'pricelist_ids': fields.one2many('pricelist.partnerinfo', 'suppinfo_id', 'Supplier Pricelist'),
}
_defaults = {
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml
index ef9d24fc05a..ad359628958 100644
--- a/addons/product/product_view.xml
+++ b/addons/product/product_view.xml
@@ -68,10 +68,9 @@
-
+
-
diff --git a/addons/product/report/product_pricelist.py b/addons/product/report/product_pricelist.py
index 17c7823c1bd..d35019d9b30 100644
--- a/addons/product/report/product_pricelist.py
+++ b/addons/product/report/product_pricelist.py
@@ -151,6 +151,6 @@ class product_pricelist(report_sxw.rml_parse):
newnode=False
return super(product_pricelist,self).repeatIn(lst, name, nodes_parent=False)
#end
-report_sxw.report_sxw('report.product.pricelist','product.product','addons/product_pricelist_print/report/product_pricelist.rml',parser=product_pricelist)
+report_sxw.report_sxw('report.product.pricelist','product.product','addons/product/report/product_pricelist.rml',parser=product_pricelist)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/profile_accounting/profile_accounting.py b/addons/profile_accounting/profile_accounting.py
index 74f8023bdc9..744a66dd796 100644
--- a/addons/profile_accounting/profile_accounting.py
+++ b/addons/profile_accounting/profile_accounting.py
@@ -59,7 +59,7 @@ class profile_accounting_config_install_modules_wizard(osv.osv_memory):
ids += mod_obj.search(cr, uid, [('name', '=', r)])
mod_obj.action_install(cr, uid, ids, context=context)
cr.commit()
- db, pool = pooler.restart_pool(cr.dbname, update_module=True)
+ db, pool = pooler.restart_pool(cr.dbname,force_demo=True, update_module=True)
return {
'view_type': 'form',
"view_mode": 'form',
diff --git a/addons/profile_accounting/profile_accounting.xml b/addons/profile_accounting/profile_accounting.xml
index 62350fa0d78..d98b6d1f0d1 100644
--- a/addons/profile_accounting/profile_accounting.xml
+++ b/addons/profile_accounting/profile_accounting.xml
@@ -38,7 +38,7 @@
Accounting Profile : Install Extra modules
- Install more modules. A few modules are proposed according to the service profile you selected. You will be able to install them based on our requirements.
+ Install more modules. A few modules are proposed according to the Account Profile you selected. You will be able to install them based on our requirements.open
diff --git a/addons/profile_association/profile_association.py b/addons/profile_association/profile_association.py
index 5a5a541ebbe..3ca64f5adbb 100644
--- a/addons/profile_association/profile_association.py
+++ b/addons/profile_association/profile_association.py
@@ -58,7 +58,7 @@ class profile_association_config_install_modules_wizard(osv.osv_memory):
ids = mod_obj.search(cr, uid, [('name', '=', r)])
mod_obj.action_install(cr, uid, ids, context=context)
cr.commit()
- db, pool = pooler.restart_pool(cr.dbname, update_module=True)
+ db, pool = pooler.restart_pool(cr.dbname,force_demo=True, update_module=True)
return {
'view_type': 'form',
"view_mode": 'form',
diff --git a/addons/profile_association/profile_association.xml b/addons/profile_association/profile_association.xml
index 03b8f441803..a1a8467fe51 100644
--- a/addons/profile_association/profile_association.xml
+++ b/addons/profile_association/profile_association.xml
@@ -37,7 +37,7 @@
Association Profile : Install Extra modules
- Install more modules. A few modules are proposed according to the service profile you selected. You will be able to install them based on our requirements.
+ Install more modules. A few modules are proposed according to the association profile you selected. You will be able to install them based on our requirements.open
diff --git a/addons/profile_manufacturing/__terp__.py b/addons/profile_manufacturing/__terp__.py
index 40479ffc38f..92ea4224877 100644
--- a/addons/profile_manufacturing/__terp__.py
+++ b/addons/profile_manufacturing/__terp__.py
@@ -31,7 +31,7 @@
"version":"1.0",
"author":"Tiny",
"category":"Profile",
- "depends":["mrp", "crm", "sale", "delivery","board_manufacturing"],
+ "depends":["mrp", "sale", "delivery","board_manufacturing"],
"demo_xml":[],
"update_xml":[
"security/ir.model.access.csv",
diff --git a/addons/profile_manufacturing/profile_manufacturing.py b/addons/profile_manufacturing/profile_manufacturing.py
index 36bc2aa18c8..5ab575acde6 100644
--- a/addons/profile_manufacturing/profile_manufacturing.py
+++ b/addons/profile_manufacturing/profile_manufacturing.py
@@ -67,7 +67,9 @@ class profile_manufacturing_config_install_modules_wizard(osv.osv_memory):
help="This module allows you to manage a point of sale system. "\
"It offers a basic form for pos operations. You must also check "\
"our frontend point of sale for a perfect ergonomy with touchscreen "\
- "materials and payment processing hardware.")
+ "materials and payment processing hardware."),
+ 'portal': fields.boolean('Portal',
+ help="This module allows you to manage a Portal system.")
}
def action_cancel(self,cr,uid,ids,conect=None):
return {
@@ -86,7 +88,7 @@ class profile_manufacturing_config_install_modules_wizard(osv.osv_memory):
ids = mod_obj.search(cr, uid, [('name', '=', r)])
mod_obj.action_install(cr, uid, ids, context=context)
cr.commit()
- db, pool = pooler.restart_pool(cr.dbname, update_module=True)
+ db, pool = pooler.restart_pool(cr.dbname,force_demo=True, update_module=True)
return {
'view_type': 'form',
"view_mode": 'form',
diff --git a/addons/profile_manufacturing/profile_manufacturing.xml b/addons/profile_manufacturing/profile_manufacturing.xml
index 1abe782d8b0..2d41b6d577a 100644
--- a/addons/profile_manufacturing/profile_manufacturing.xml
+++ b/addons/profile_manufacturing/profile_manufacturing.xml
@@ -17,6 +17,8 @@
+
+
@@ -39,7 +41,7 @@
Manufacturing Profile : Install Extra modules
- Install more modules. A few modules are proposed according to the service profile you selected. You will be able to install them based on our requirements.
+ Install more modules. A few modules are proposed according to the manufacturing profile you selected. You will be able to install them based on our requirements.open
diff --git a/addons/profile_service/profile_service.py b/addons/profile_service/profile_service.py
index 71371f59846..4dd4d83c24a 100644
--- a/addons/profile_service/profile_service.py
+++ b/addons/profile_service/profile_service.py
@@ -43,6 +43,8 @@ class profile_service_config_install_modules_wizard(osv.osv_memory):
'project_gtd':fields.boolean('Getting Things Done', help="GTD is a methodology to efficiently organise yourself and your tasks. This module fully integrates GTD principle with OpenERP's project management."),
'scrum':fields.boolean('Scrum Methodology', help="Scrum is an 'agile development methodology', mainly used in IT projects. It helps you to manage teams, long term roadmaps, sprints, and so on."),
'base_contact':fields.boolean('Contacts Management', help="Allows you to manage partners (enterprises), addresses of partners and contacts of these partners (employee/people). Install this if you plan to manage your relationships with partners and contacts."),
+ 'portal': fields.boolean('Portal',
+ help="This module allows you to manage a Portal system.")
}
def action_cancel(self,cr,uid,ids,conect=None):
return {
@@ -61,7 +63,7 @@ class profile_service_config_install_modules_wizard(osv.osv_memory):
ids = mod_obj.search(cr, uid, [('name', '=', r)])
mod_obj.action_install(cr,uid,ids,context=context)
cr.commit()
- db, pool = pooler.restart_pool(cr.dbname, update_module=True)
+ db, pool = pooler.restart_pool(cr.dbname,force_demo=True, update_module=True)
return {
'view_type': 'form',
"view_mode": 'form',
diff --git a/addons/profile_service/profile_service.xml b/addons/profile_service/profile_service.xml
index ba4039d678c..50e90f4c1d1 100644
--- a/addons/profile_service/profile_service.xml
+++ b/addons/profile_service/profile_service.xml
@@ -21,7 +21,8 @@
-
+
+
diff --git a/addons/project/project.py b/addons/project/project.py
index 5f7ba9c0930..b9878b2888c 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -151,21 +151,26 @@ class project(osv.osv):
# toggle activity of projects, their sub projects and their tasks
def set_template(self, cr, uid, ids, context={}):
res = self.setActive(cr, uid, ids, value=False, context=context)
- return res
-
+ return res
+
def reset_project(self, cr, uid, ids, context={}):
res = self.setActive(cr, uid, ids,value=True, context=context)
return res
-
+
+ def copy(self, cr, uid, id, default={},context={}):
+ default = default or {}
+ default['tasks'] = []
+ default['child_id'] = []
+ return super(project, self).copy(cr, uid, id, default, context)
+
def duplicate_template(self, cr, uid, ids,context={}):
- for proj in self.browse(cr, uid, ids):
- parent_id=context.get('parent_id',False)
- new_id=self.pool.get('project.project').copy(cr, uid, proj.id,default={'name':proj.name+'(copy)','state':'template','parent_id':parent_id})
+ for proj in self.browse(cr, uid, ids):
+ parent_id=context.get('parent_id',False)
+ new_id=self.pool.get('project.project').copy(cr, uid, proj.id,default={'name':proj.name+_(' (copy)'),'state':'open','parent_id':parent_id})
cr.execute('select id from project_task where project_id=%d', (proj.id,))
res = cr.fetchall()
- tasks_ids = [x[0] for x in res]
- for tasks_id in tasks_ids:
- self.pool.get('project.task').copy(cr, uid, tasks_id,default={'project_id':new_id,'active':False}, context=context)
+ for (tasks_id,) in res:
+ self.pool.get('project.task').copy(cr, uid, tasks_id,default={'project_id':new_id,'active':True}, context=context)
cr.execute('select id from project_project where parent_id=%d', (proj.id,))
res = cr.fetchall()
project_ids = [x[0] for x in res]
diff --git a/addons/project/project_demo.xml b/addons/project/project_demo.xml
index 903da6cdf0b..e95faefc384 100644
--- a/addons/project/project_demo.xml
+++ b/addons/project/project_demo.xml
@@ -7,13 +7,11 @@
-->
- 584.01Tiny ERP Integration
- 216.0110
@@ -22,7 +20,6 @@
- 264.020Specific Developements
@@ -30,7 +27,6 @@
- 104.030Install, data import, configuration
@@ -40,6 +36,7 @@
38.0
+ 38.0BoM, After sales returns, interventions. Tracability.
@@ -47,18 +44,21 @@
16.0
+ 16.0Data importation + Doc16.0
+ 16.0Modifications asked by the customer.16.0
+ 16.00
@@ -67,6 +67,7 @@
158.0
+ 8.0Internal testing + Software Install
@@ -75,6 +76,7 @@
1716.0
+ 16.02
@@ -83,6 +85,7 @@
2016.0
+ 16.0Parameters
@@ -90,6 +93,7 @@
2032.0
+ 32.0Start of the doc redaction + MRP
@@ -97,6 +101,7 @@
2524.0
+ 24.0MRP Tests
@@ -104,6 +109,7 @@
2924.0
+ 24.0MRP; functionnal layer
@@ -113,6 +119,7 @@
3024.0
+ 24.0Products Adaptation
@@ -120,6 +127,7 @@
3024.0
+ 24.0Install + Super User Training
@@ -127,6 +135,7 @@
3032.0
+ 32.0Customer docs
@@ -134,6 +143,7 @@
3024.0
+ 24.0Development of the presentation layer
@@ -141,6 +151,7 @@
4032.0
+ 32.0Free Time
@@ -148,6 +159,7 @@
4050.0
+ 50.0Specific tests
@@ -155,6 +167,7 @@
4024.0
+ 24.0Sale module
@@ -162,6 +175,7 @@
4032.0
+ 32.0In house trainings
@@ -170,6 +184,7 @@
5024.0
+ 24.0Validation + latest modifications.
@@ -177,6 +192,7 @@
5024.0
+ 24.0Adaptations buy module
@@ -184,6 +200,7 @@
6016.0
+ 16.0Presentation of the software.
@@ -191,6 +208,7 @@
6024.0
+ 24.0Adaptations Stock module
@@ -198,6 +216,7 @@
7024.0
+ 24.0Latest in house tests
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index fad26416d78..bfb85802320 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -21,20 +21,20 @@
-
-
-
+
+
+
-
+
-
-
+
+
@@ -90,16 +90,6 @@
-
- New Project
- project.project
- form
- form,tree,calendar
-
-
-
-
-
Unclosed projectsproject.project
@@ -117,7 +107,7 @@
[('parent_id','=',False),('state','=','open')]
-
+
Open projects
@@ -128,7 +118,7 @@
-
+ Template projectsproject.projectform
@@ -137,6 +127,14 @@
+
+ New Project
+ project.project
+ form
+ form,tree,calendar
+
+
+
project.task.work.form
@@ -318,18 +316,18 @@
-
- project.task.graph
- project.task
- graph
-
-
-
-
-
-
-
-
+
+ project.task.graph
+ project.task
+ graph
+
+
+
+
+
+
+
+ All Tasks
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 9def605ecb0..26fdf26c953 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -154,14 +154,19 @@ class purchase_order(osv.osv):
_columns = {
'name': fields.char('Order Reference', size=64, required=True, select=True),
- 'origin': fields.char('Origin', size=64),
+ 'origin': fields.char('Origin', size=64,
+ help="Reference of the document that generated this purchase order request."
+ ),
'partner_ref': fields.char('Partner Ref.', size=64),
'date_order':fields.date('Date Ordered', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}),
- 'date_approve':fields.date('Date Approved'),
+ 'date_approve':fields.date('Date Approved', readonly=1),
'partner_id':fields.many2one('res.partner', 'Supplier', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, change_default=True),
'partner_address_id':fields.many2one('res.partner.address', 'Address', required=True, states={'posted':[('readonly',True)]}),
- 'dest_address_id':fields.many2one('res.partner.address', 'Destination Address', states={'posted':[('readonly',True)]}),
+ 'dest_address_id':fields.many2one('res.partner.address', 'Destination Address', states={'posted':[('readonly',True)]},
+ help="Put an address if you want to deliver directly from the supplier to the customer." \
+ "In this case, it will remove the warehouse link and set the customer location."
+ ),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', states={'posted':[('readonly',True)]}),
'location_id': fields.many2one('stock.location', 'Destination', required=True),
@@ -177,8 +182,13 @@ class purchase_order(osv.osv):
'shipped_rate': fields.function(_shipped_rate, method=True, string='Received', type='float'),
'invoiced':fields.boolean('Invoiced & Paid', readonly=True, select=True),
'invoiced_rate': fields.function(_invoiced_rate, method=True, string='Invoiced', type='float'),
- 'invoice_method': fields.selection([('manual','Manual'),('order','From order'),('picking','From picking')], 'Invoicing Control', required=True),
- 'minimum_planned_date':fields.function(_minimum_planned_date, fnct_inv=_set_minimum_planned_date, method=True,store=True, string='Planned Date', type='date', help="This is computed as the minimum scheduled date of all purchase order lines' products."),
+ 'invoice_method': fields.selection([('manual','Manual'),('order','From Order'),('picking','From Picking')], 'Invoicing Control', required=True,
+ help="From Order: a draft invoice will be pre-generated based on the purchase order. The accountant " \
+ "will just have to validate this invoice for control.\n" \
+ "From Picking: a draft invoice will be pre-genearted based on validated receptions.\n" \
+ "Manual: no invoice will be pre-generated. The accountant will have to encode manually."
+ ),
+ 'minimum_planned_date':fields.function(_minimum_planned_date, fnct_inv=_set_minimum_planned_date, method=True,store=True, string='Planned Date', type='datetime', help="This is computed as the minimum scheduled date of all purchase order lines' products."),
'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'),
'amount_tax': fields.function(_amount_tax, method=True, string='Taxes'),
'amount_total': fields.function(_amount_total, method=True, string='Total'),
@@ -411,7 +421,7 @@ class purchase_order_line(osv.osv):
if not pricelist:
raise osv.except_osv(_('No Pricelist !'), _('You have to select a pricelist in the purchase form !\nPlease set one before choosing a product.'))
if not product:
- return {'value': {'price_unit': 0.0, 'name':'','notes':''}, 'domain':{'product_uom':[]}}
+ return {'value': {'price_unit': 0.0, 'name':'','notes':'', 'product_uom' : False}, 'domain':{'product_uom':[]}}
lang=False
if partner_id:
lang=self.pool.get('res.partner').read(cr, uid, [partner_id])[0]['lang']
diff --git a/addons/purchase/report/request_quotation.rml b/addons/purchase/report/request_quotation.rml
index 6b39f7084b3..99cd2a14a6e 100644
--- a/addons/purchase/report/request_quotation.rml
+++ b/addons/purchase/report/request_quotation.rml
@@ -90,7 +90,7 @@
[[ (order.partner_address_id and order.partner_address_id.title) or '' ]] [[ order.partner_address_id.name ]] [[ (order.partner_address_id and order.partner_address_id.street) or '']] [[ order.partner_address_id.street2 ]][[ (order.partner_address_id and order.partner_address_id.zip) or '' ]] [[ (order.partner_address_id and order.partner_address_id.city) or '' ]]
- [[ order.partner_address_id.state_id.code ]] [[ (order.partner_address_id and order.partner_address_id.country_id and order.partner_address_id.country_id.code) or '' ]]
+ [[ (order.partner_address_id and order.partner_address_id.state_id and order.partner_address_id.state_id.code) or '' ]] [[ (order.partner_address_id and order.partner_address_id.country_id and order.partner_address_id.country_id.code) or '' ]]
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 4a52e8d4608..45783dd5978 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -214,7 +214,7 @@ class sale_order(osv.osv):
'partner_shipping_id':fields.many2one('res.partner.address', 'Shipping Address', readonly=True, required=True, states={'draft':[('readonly',False)]}),
'incoterm': fields.selection(_incoterm_get, 'Incoterm',size=3),
- 'picking_policy': fields.selection([('direct','Partial Delivery'),('one','Complete Delivery')], 'Packing Policy', required=True ),
+ 'picking_policy': fields.selection([('direct','Partial Delivery'),('one','Complete Delivery')], 'Packing Policy', required=True),
'order_policy': fields.selection([
('prepaid','Payment before delivery'),
('manual','Shipping & Manual Invoice'),
@@ -241,7 +241,7 @@ class sale_order(osv.osv):
'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'),
'amount_tax': fields.function(_amount_tax, method=True, string='Taxes'),
'amount_total': fields.function(_amount_total, method=True, string='Total'),
- 'invoice_quantity': fields.selection([('order','Ordered Quantities'),('procurement','Shipped Quantities')], 'Invoice on', help="The sale order will automatically create the invoice proposition (draft invoice). Ordered and delivered quantities may not be the same. You have to choose if you invoice based on ordered or shipped quantities. If the product is a service, shipped quantities means hours spent on the associated tasks."),
+ 'invoice_quantity': fields.selection([('order','Ordered Quantities'),('procurement','Shipped Quantities')], 'Invoice on', help="The sale order will automatically create the invoice proposition (draft invoice). Ordered and delivered quantities may not be the same. You have to choose if you invoice based on ordered or shipped quantities. If the product is a service, shipped quantities means hours spent on the associated tasks.",required=True),
'payment_term' : fields.many2one('account.payment.term', 'Payment Term'),
}
_defaults = {
@@ -301,7 +301,7 @@ class sale_order(osv.osv):
def _inv_get(self, cr, uid, order, context={}):
return {}
- def _make_invoice(self, cr, uid, order, lines, context={}):
+ def _make_invoice(self, cr, uid, order, lines,context={}):
a = order.partner_id.property_account_receivable.id
if order.payment_term:
pay_term = order.payment_term.id
@@ -479,7 +479,7 @@ class sale_order(osv.osv):
for line in order.order_line:
proc_id=False
date_planned = DateTime.now() + DateTime.RelativeDateTime(days=line.delay or 0.0)
- date_planned = (date_planned - DateTime.RelativeDateTime(days=company.security_lead)).strftime('%Y-%m-%d')
+ date_planned = (date_planned - DateTime.RelativeDateTime(days=company.security_lead)).strftime('%Y-%m-%d %H:%M:%S')
if line.state == 'done':
continue
if line.product_id and line.product_id.product_tmpl_id.type in ('product', 'consu'):
@@ -770,10 +770,10 @@ class sale_order_line(osv.osv):
def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
lang=False, update_tax=True, date_order=False, packaging=False):
+ warning={}
product_uom_obj = self.pool.get('product.uom')
partner_obj = self.pool.get('res.partner')
product_obj = self.pool.get('product.product')
-
if partner_id:
lang = partner_obj.browse(cr, uid, partner_id).lang
context = {'lang': lang, 'partner_id': partner_id}
@@ -781,7 +781,7 @@ class sale_order_line(osv.osv):
if not product:
return {'value': {'th_weight' : 0, 'product_packaging': False,
'product_uos_qty': qty}, 'domain': {'product_uom': [],
- 'product_uos': []}}
+ 'product_uos': []}}
if not date_order:
date_order = time.strftime('%Y-%m-%d')
@@ -792,9 +792,19 @@ class sale_order_line(osv.osv):
default_uom = product_obj.uom_id and product_obj.uom_id.id
pack = self.pool.get('product.packaging').browse(cr, uid, packaging, context)
q = product_uom_obj._compute_qty(cr, uid, uom, pack.qty, default_uom)
- qty = qty - qty % q + q
+# qty = qty - qty % q + q
+ if not (qty % q) == 0 :
+ ean = pack.ean
+ qty_pack = pack.qty
+ type_ul = pack.ul
+ warn_msg = "You selected a quantity of %d Units.\nBut it's not compatible with the selected packaging.\nHere is a proposition of quantities according to the packaging: " % (qty)
+ warn_msg = warn_msg + "\n\nEAN: " + str(ean) + " Quantiny: " + str(qty_pack) + " Type of ul: " + str(type_ul.name)
+ warning={
+ 'title':'Packing Information !',
+ 'message': warn_msg
+ }
result['product_uom_qty'] = qty
-
+
if uom:
uom2 = product_uom_obj.browse(cr, uid, uom)
if product_obj.uom_id.category_id.id <> uom2.category_id.id:
@@ -864,7 +874,7 @@ class sale_order_line(osv.osv):
# Round the quantity up
# get unit price
- warning={}
+
if not pricelist:
warning={
'title':'No Pricelist !',
@@ -884,11 +894,9 @@ class sale_order_line(osv.osv):
'message':
"Couldn't find a pricelist line matching this product and quantity.\n"
"You have to change either the product, the quantity or the pricelist."
- }
+ }
else:
- result.update({'price_unit': price})
-
-
+ result.update({'price_unit': price})
return {'value': result, 'domain': domain,'warning':warning}
def product_uom_change(self, cursor, user, ids, pricelist, product, qty=0,
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index 13523bb86ed..68cf27bddf5 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -101,7 +101,6 @@
-
@@ -232,6 +231,7 @@
formtree,form,calendar,graph[('user_id','=',uid)]
+
diff --git a/addons/sale/security/ir.model.access.csv b/addons/sale/security/ir.model.access.csv
index 04064fa910d..31c68c7c885 100644
--- a/addons/sale/security/ir.model.access.csv
+++ b/addons/sale/security/ir.model.access.csv
@@ -1,5 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sale_shop,sale.shop,model_sale_shop,group_sale_user,1,0,0,0
-access_sale_order,sale.order,model_sale_order,group_sale_user,1,1,1,1
-access_sale_order_line,sale.order.line,model_sale_order_line,group_sale_user,1,1,1,1
+access_sale_order,sale.order,model_sale_order,group_sale_user,1,1,1,0
+access_sale_order_line,sale.order.line,model_sale_order_line,group_sale_user,1,1,1,0
access_sale_shop_admin,sale.shop,model_sale_shop,base.group_system,1,1,1,1
diff --git a/addons/sale/stock.py b/addons/sale/stock.py
index 002caba90d5..9dafbc6ff1d 100644
--- a/addons/sale/stock.py
+++ b/addons/sale/stock.py
@@ -114,3 +114,4 @@ stock_picking()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/sale/stock_view.xml b/addons/sale/stock_view.xml
index f6cc1f1c03f..db273c38b60 100644
--- a/addons/sale/stock_view.xml
+++ b/addons/sale/stock_view.xml
@@ -15,4 +15,3 @@
-
diff --git a/addons/sale/wizard/make_invoice_advance.py b/addons/sale/wizard/make_invoice_advance.py
index 792a3d41da2..da1bfb04b65 100644
--- a/addons/sale/wizard/make_invoice_advance.py
+++ b/addons/sale/wizard/make_invoice_advance.py
@@ -94,7 +94,7 @@ def _createInvoices(self, cr, uid, data, context={}):
'invoice_line': [(6,0,create_ids)],
'currency_id' :sale.pricelist_id.currency_id.id,
'comment': '',
- 'payment_term':sale.partner_id.property_payment_term.id,
+ 'payment_term':sale.payment_term.id,
}
inv_obj = pool_obj.get('account.invoice')
inv_id = inv_obj.create(cr, uid, inv)
diff --git a/addons/sale_journal/picking_journal_view.xml b/addons/sale_journal/picking_journal_view.xml
index 4bc9493e6bd..87ef5eedea3 100644
--- a/addons/sale_journal/picking_journal_view.xml
+++ b/addons/sale_journal/picking_journal_view.xml
@@ -56,8 +56,8 @@
tree,form
-
-
+
+
Packings by journal
@@ -67,8 +67,8 @@
[]
-
-
+
+
My open packing journals
@@ -98,8 +98,8 @@
tree
-
-
+
+
diff --git a/addons/sale_journal/picking_journal_view_report.xml b/addons/sale_journal/picking_journal_view_report.xml
index 7f956736fc0..d177673726e 100644
--- a/addons/sale_journal/picking_journal_view_report.xml
+++ b/addons/sale_journal/picking_journal_view_report.xml
@@ -57,7 +57,7 @@
[('name','=',time.strftime('%Y-%m-01'))]
-
+
diff --git a/addons/sale_journal/sale_journal_view.xml b/addons/sale_journal/sale_journal_view.xml
index be96302c583..7647a7b2bfb 100644
--- a/addons/sale_journal/sale_journal_view.xml
+++ b/addons/sale_journal/sale_journal_view.xml
@@ -1,283 +1,295 @@
-
- sale_journal.invoice.type.form
- sale_journal.invoice.type
- form
-
-
@@ -851,6 +868,11 @@
+
+
+ calendar
+
+
@@ -874,6 +896,11 @@
+
+
+ calendar
+
+
@@ -897,6 +924,11 @@
+
+
+ calendar
+
+
#
@@ -958,7 +990,7 @@
-
+
@@ -973,11 +1005,12 @@
-
+
-
+
-
+
+
@@ -1016,7 +1049,11 @@
-
+
+
+ calendar
+
+
@@ -1040,6 +1077,11 @@
+
+
+ calendar
+
+
@@ -1047,7 +1089,7 @@
stock.pickingir.actions.act_windowform
- form,tree
+ form,tree,calendar{'contact_display': 'partner'}[('type','=','in')]
@@ -1063,6 +1105,11 @@
+
+
+ calendar
+
+
@@ -1159,7 +1206,7 @@
-
+
@@ -1209,7 +1256,7 @@
stock.pickingir.actions.act_windowform
- tree,form
+ tree,form,calendar{'contact_display': 'partner'}
@@ -1248,20 +1295,31 @@
formtree,form
-
+
-
-
+
+ tree_but_openstock.locationProducts
-
+
+
+
+
+ tree_but_open
+ stock.location
+ Open Products
+
+
+
+
+
+
-
diff --git a/addons/stock/stock_wizard.xml b/addons/stock/stock_wizard.xml
index fa46831cf2c..1e04921ea3c 100644
--- a/addons/stock/stock_wizard.xml
+++ b/addons/stock/stock_wizard.xml
@@ -34,5 +34,15 @@
multi="True"
id="wizard_merge_inventory"/>
+
+
+
+
diff --git a/addons/stock/wizard/__init__.py b/addons/stock/wizard/__init__.py
index b18ad592fb3..4689425cee5 100644
--- a/addons/stock/wizard/__init__.py
+++ b/addons/stock/wizard/__init__.py
@@ -37,8 +37,9 @@ import wizard_split_lot_line
import wizard_track_line
import wizard_ups
import wizard_invoice_onshipping
-import inventory_merge
+import wizard_location_product
+import wizard_inventory
import inventory_merge_zero
-
+import inventory_merge
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/stock/wizard/wizard_inventory.py b/addons/stock/wizard/wizard_inventory.py
new file mode 100644
index 00000000000..f70b82b863d
--- /dev/null
+++ b/addons/stock/wizard/wizard_inventory.py
@@ -0,0 +1,113 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+import time
+import wizard
+import ir
+import pooler
+from osv.osv import except_osv
+from osv import fields,osv
+import netsvc
+
+inventory_form = """
+
+
+
+
+
+
+
+
+"""
+
+inventory_fields = {
+ 'location_id' : {
+ 'string':'Location',
+ 'type':'many2one',
+ 'relation':'stock.location',
+ 'required':True
+ },
+ 'recursive' : {'string':'Include all childs for the location', 'type':'boolean'}
+}
+
+
+
+def _fill_inventory(self, cr, uid, data, context):
+ pool = pooler.get_pool(cr.dbname)
+ inventory_line_obj = pooler.get_pool(cr.dbname).get('stock.inventory.line')
+ location_obj = pooler.get_pool(cr.dbname).get('stock.location')
+ res={}
+ res_location={}
+ if data['form']['recursive'] :
+ location_ids = location_obj.search(cr, uid, [('location_id', 'child_of', [data['form']['location_id']])])
+ for location in location_ids :
+ res=location_obj._product_get(cr, uid, location)
+ res_location[location]=res
+ else:
+ res=location_obj._product_get(cr, uid, data['form']['location_id'])
+ res_location[data['form']['location_id']]=res
+
+ product_ids=[]
+ for location in res_location.keys():
+ res=res_location[location]
+ for product_id in res.keys():
+ #product_ids.append(product_id)
+ prod = pool.get('product.product').browse(cr, uid, [product_id])[0]
+ uom = prod.uom_id.id
+ amount=pool.get('stock.location')._product_get(cr, uid, location, [product_id], {'uom': uom})[product_id]
+
+ if(amount):
+ line_ids=inventory_line_obj.search(cr,uid,[('inventory_id','=',data['id']),('location_id','=',location),('product_id','=',product_id),('product_uom','=',uom),('product_qty','=',amount)])
+ if not len(line_ids):
+ inventory_line={'inventory_id':data['id'],'location_id':location,'product_id':product_id,'product_uom':uom,'product_qty':amount}
+ inventory_line_obj.create(cr, uid, inventory_line)
+ product_ids.append(product_id)
+
+ if(len(product_ids)==0):
+ raise wizard.except_wizard('Message ! ','No product in this location.')
+ return {}
+
+
+
+class fill_inventory(wizard.interface):
+ states = {
+ 'init' : {
+ 'actions' : [],
+ 'result' : {'type' : 'form',
+ 'arch' : inventory_form,
+ 'fields' : inventory_fields,
+ 'state' : [('end', 'Cancel'),('fill_inventory', 'Fill Inventory') ]}
+ },
+ 'fill_inventory' : {
+ 'actions' : [],
+ 'result' : {'type' : 'action', 'action': _fill_inventory, 'state' : 'end'}
+ },
+ }
+fill_inventory("stock.fill_inventory")
+
+
+
diff --git a/addons/stock/wizard/wizard_location_product.py b/addons/stock/wizard/wizard_location_product.py
new file mode 100755
index 00000000000..0083c0e9863
--- /dev/null
+++ b/addons/stock/wizard/wizard_location_product.py
@@ -0,0 +1,78 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#
+# $Id$
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+import wizard
+import pooler
+import time
+
+def _action_open_window(self, cr, uid, data, context):
+ return {
+ 'view_type': 'form',
+ "view_mode": 'tree,form',
+ 'res_model': 'product.product',
+ 'type': 'ir.actions.act_window',
+ 'context':{'location': data['ids'][0],'from_date':data['form']['from_date'],'to_date':data['form']['to_date']},
+ 'domain':[('type','<>','service')]
+ }
+
+
+class product_by_location(wizard.interface):
+
+ form1 = '''
+
+
+
+
+
'''
+
+ form1_fields = {
+ 'from_date': {
+ 'string': 'From',
+ 'type': 'date',
+ },
+ 'to_date': {
+ 'string': 'To',
+ 'type': 'date',
+ },
+ }
+
+ states = {
+ 'init': {
+ 'actions': [],
+ 'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [ ('open', 'Open Products'),('end', 'Cancel')]}
+ },
+ 'open': {
+ 'actions': [],
+ 'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
+ }
+ }
+
+product_by_location('stock.location.products')
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/stock_location/stock.py b/addons/stock_location/stock.py
index 926b1d95e10..8c3626f9de8 100644
--- a/addons/stock_location/stock.py
+++ b/addons/stock_location/stock.py
@@ -73,5 +73,5 @@ class stock_location(osv.osv):
for path in product.path_ids:
if path.location_from_id.id == location.id:
return path.location_dest_id, path.auto, path.delay
- return super(stock_location, self).chained_location_get(cr, uid, location, partner, product, contex)
+ return super(stock_location, self).chained_location_get(cr, uid, location, partner, product, context)
stock_location()
diff --git a/addons/warning/__init__.py b/addons/warning/__init__.py
new file mode 100644
index 00000000000..b26647e7ffb
--- /dev/null
+++ b/addons/warning/__init__.py
@@ -0,0 +1,34 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#
+# $Id$
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+import warning
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/warning/__terp__.py b/addons/warning/__terp__.py
new file mode 100644
index 00000000000..db4a1616ac9
--- /dev/null
+++ b/addons/warning/__terp__.py
@@ -0,0 +1,44 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2004-2008 Tiny SPRL (http://tiny.be) All Rights Reserved.
+#
+# $Id$
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+###############################################################################
+{
+ "name":"Module for Warnings form onchange Event",
+ "version":"1.0",
+ "author":"Tiny",
+ "category":"Tools",
+ "depends":["base","sale"],
+ "demo_xml":[],
+ "update_xml":[
+ "warning_view.xml"],
+ "description": "Module for Warnings form onchange Event.",
+ "active":False,
+ "installable":True,
+}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/warning/warning.py b/addons/warning/warning.py
new file mode 100644
index 00000000000..be2c3f74ca1
--- /dev/null
+++ b/addons/warning/warning.py
@@ -0,0 +1,199 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#
+# $Id$
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+import time
+from osv import fields,osv
+
+class res_partner(osv.osv):
+ _inherit = 'res.partner'
+ _columns = {
+ 'sale_warn' : fields.boolean('Sale Order'),
+ 'sale_warn_msg' : fields.char('Message for Sale Order', size=64),
+ 'purchase_warn' : fields.boolean('Purchase Order'),
+ 'purchase_warn_msg' : fields.char('Message for Purchase Order', size=64),
+ 'picking_warn' : fields.boolean('Stock Picking'),
+ 'picking_warn_msg' : fields.char('Message for Stock Picking', size=64),
+ 'invoice_warn' : fields.boolean('Invoice'),
+ 'invoice_warn_msg' : fields.char('Message for Invoice', size=64),
+ }
+res_partner()
+
+
+class sale_order(osv.osv):
+ _inherit = 'sale.order'
+ def onchange_partner_id(self, cr, uid, ids, part):
+ if not part:
+ return {'value':{'partner_invoice_id': False, 'partner_shipping_id':False, 'partner_order_id':False, 'payment_term' : False}}
+ warning = {}
+ title=False
+ message=False
+ partner = self.pool.get('res.partner').browse(cr, uid, part)
+ if partner.sale_warn:
+ title= "Message",
+ message=partner.sale_warn_msg
+
+ result = super(sale_order, self).onchange_partner_id(cr, uid, ids, part)['value']
+ if result.get('warning',False):
+ warning['title']=title and title+' & '+result['warning']['title'] or result['warning']['title']
+ warning['message']=message and message +' '+result['warning']['message'] or result['warning']['message']
+ return {'value': result, 'warning':warning}
+sale_order()
+
+
+class purchase_order(osv.osv):
+ _inherit = 'purchase.order'
+ def onchange_partner_id(self, cr, uid, ids, part):
+ if not part:
+ return {'value':{'partner_address_id': False}}
+ warning = {}
+ partner = self.pool.get('res.partner').browse(cr, uid, part)
+ if partner.purchase_warn:
+ warning={
+ 'title': "Message",
+ 'message': partner.purchase_warn_msg
+ }
+ result = super(purchase_order, self).onchange_partner_id(cr, uid, ids, part)['value']
+ return {'value': result, 'warning':warning}
+
+purchase_order()
+
+
+class account_invoice(osv.osv):
+ _inherit = 'account.invoice'
+ def onchange_partner_id(self, cr, uid, ids, type, partner_id,
+ date_invoice=False, payment_term=False, partner_bank_id=False):
+ if not partner_id:
+ return {'value': {
+ 'address_contact_id': False ,
+ 'address_invoice_id': False,
+ 'account_id': False,
+ 'payment_term': False,
+ }
+ }
+ warning = {}
+ partner = self.pool.get('res.partner').browse(cr, uid, partner_id)
+ if partner.invoice_warn:
+ warning={
+ 'title': "Message",
+ 'message': partner.invoice_warn_msg
+ }
+ result = super(account_invoice, self).onchange_partner_id(cr, uid, ids, type, partner_id,
+ date_invoice=False, payment_term=False, partner_bank_id=False)['value']
+ return {'value': result, 'warning':warning}
+
+account_invoice()
+
+class stock_picking(osv.osv):
+ _inherit = 'stock.picking'
+
+ def onchange_partner_in(self, cr, uid, context, partner_id=None):
+ if not partner_id:
+ return {}
+ partner = self.pool.get('res.partner.address').browse(cr, uid, [partner_id])[0].partner_id
+ warning = {}
+ if partner.picking_warn:
+ warning={
+ 'title': "Message",
+ 'message': partner.picking_warn_msg
+ }
+ result = super(stock_picking, self).onchange_partner_in(cr, uid, context, partner_id)
+ return {'value': result, 'warning':warning}
+
+stock_picking()
+
+class product_product(osv.osv):
+ _inherit = 'product.product'
+ _columns = {
+ 'sale_line_warn' : fields.boolean('Sale Order Line'),
+ 'sale_line_warn_msg' : fields.char('Message for Sale Order Line', size=64),
+ 'purchase_line_warn' : fields.boolean('Purchase Order Line'),
+ 'purchase_line_warn_msg' : fields.char('Message for Purchase Order Line', size=64),
+ }
+product_product()
+
+class sale_order_line(osv.osv):
+ _inherit = 'sale.order.line'
+ def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
+ uom=False, qty_uos=0, uos=False, name='', partner_id=False,
+ lang=False, update_tax=True, date_order=False, packaging=False):
+ warning = {}
+ if not product:
+ return {'value': {'th_weight' : 0, 'product_packaging': False,
+ 'product_uos_qty': qty}, 'domain': {'product_uom': [],
+ 'product_uos': []}}
+ product_obj = self.pool.get('product.product')
+ product_info = product_obj.browse(cr, uid, product)
+ title=False
+ message=False
+ if product_info.sale_line_warn:
+ title= "Message",
+ message= product_info.sale_line_warn_msg
+ result = super(sale_order_line, self).product_id_change( cr, uid, ids, pricelist, product, qty,
+ uom, qty_uos, uos, name, partner_id,
+ lang, update_tax, date_order, packaging)
+ if title and message:
+ warning['title']=title[0]
+ warning['message']=message
+ if result.get('warning',False):
+ warning['title']= title and title[0]+' & '+result['warning']['title'] or result['warning']['title']
+ warning['message']=message and message +'\n\n'+result['warning']['message'] or result['warning']['message']
+ return {'value': result['value'], 'warning':warning}
+
+sale_order_line()
+
+class purchase_order_line(osv.osv):
+ _inherit = 'purchase.order.line'
+ def product_id_change(self,cr, uid, ids, pricelist, product, qty, uom,
+ partner_id, date_order=False):
+ warning = {}
+ if not product:
+ return {'value': {'price_unit': 0.0, 'name':'','notes':'', 'product_uom' : False}, 'domain':{'product_uom':[]}}
+ product_obj = self.pool.get('product.product')
+ product_info = product_obj.browse(cr, uid, product)
+ title=False
+ message=False
+ if product_info.purchase_line_warn:
+ title = "Message"
+ message = product_info.purchase_line_warn_msg
+
+ result = super(purchase_order_line, self).product_id_change(cr, uid, ids, pricelist, product, qty, uom,
+ partner_id, date_order)
+ if title and message:
+ warning['title']=title[0]
+ warning['message']=message
+ if result.get('warning',False):
+ warning['title']= title and title[0]+' & '+result['warning']['title'] or result['warning']['title']
+ warning['message']=message and message +'\n\n'+result['warning']['message'] or result['warning']['message']
+ return {'value': result['value'], 'warning':warning}
+
+purchase_order_line()
+
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/warning/warning_view.xml b/addons/warning/warning_view.xml
new file mode 100644
index 00000000000..769ddc8d5d2
--- /dev/null
+++ b/addons/warning/warning_view.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+ res.partner.warning.form.inherit
+ res.partner
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ product.warning.form.inherit
+ product.product
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+