-
-
- |
- []
-
- |
-
-
- |
-
-
+
+
+
-
-
-
-
-
-
-
+ |
+
|
No Stock
On Hand , Available
- Public Price : , Cost :
+
+ Public Price : ,
+ Cost :
+
|
@@ -255,7 +249,7 @@
-
+
Products
ir.actions.act_window
diff --git a/addons/project/project.py b/addons/project/project.py
index 05bed8a9b9a..a5cd8928dfc 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -471,6 +471,7 @@ class task(osv.osv):
'company_id': fields.many2one('res.company', 'Company'),
'id': fields.integer('ID', readonly=True),
'color': fields.integer('Color Index'),
+ 'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
}
_defaults = {
@@ -484,7 +485,7 @@ class task(osv.osv):
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.task', context=c)
}
- _order = "sequence,priority, date_start, name, id"
+ _order = "priority, sequence, date_start, name, id"
def set_priority(self, cr, uid, ids, priority):
"""Set task priority
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index 94724993a9d..18ff634f796 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -175,7 +175,7 @@
{'search_default_Current':1}
A project contains a set of tasks or issues that will be performed by your resources assigned to it. A project can be hierarchically structured, as a child of a Parent Project. This allows you to design large project structures with different phases spread over the project duration cycle. Each user can set his default project in his own preferences to automatically filter the tasks or issues he usually works on. If you choose to invoice the time spent on a project task, you can find project tasks to be invoiced in the billing section.
-
+
Templates of Projects
@@ -323,12 +323,14 @@
-
+
+
+
-
-
+
http://pad.openerp.com/
+
@@ -338,40 +340,31 @@
-
+
|
-
-
+
+
+
+ -
+
+
-
-
-
-
-
@@ -467,8 +460,8 @@
-
-
+
+
tree,form,calendar,gantt,graph,kanban
-
{"search_default_user_id":uid, "search_default_current": 1}
+
{"search_default_user_id":uid, "search_default_draft": 1, "search_default_open":1 }
A task represents a work that has to be done. Each user works in his own list of tasks where he can record his task work in hours. He can work and close the task itself or delegate it to another user. If you delegate a task to another user, you get a new task in pending state, which will be reopened when you have to review the work achieved. If you install the project_timesheet module, task work can be invoiced based on the project configuration. With the project_mrp module, sales orders can create tasks automatically when they are confirmed.
diff --git a/addons/project/static/src/img/kanban-pad-openerp.png b/addons/project/static/src/img/kanban-pad-openerp.png
new file mode 100644
index 00000000000..ad64c5aea0e
Binary files /dev/null and b/addons/project/static/src/img/kanban-pad-openerp.png differ
diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py
index e94349e028f..5575eee71d8 100644
--- a/addons/project_issue/project_issue.py
+++ b/addons/project_issue/project_issue.py
@@ -226,7 +226,8 @@ class project_issue(crm.crm_case, osv.osv):
multi='compute_day', type="float", store=True),
'inactivity_days': fields.function(_compute_day, string='Days since last action', \
multi='compute_day', type="integer", help="Difference in days between last action and current date"),
- 'color': fields.integer('Color Index'),
+ 'color': fields.integer('Color Index'),
+ 'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1),
diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml
index 00e6a00c163..c6d852cfde0 100644
--- a/addons/project_issue/project_issue_view.xml
+++ b/addons/project_issue/project_issue_view.xml
@@ -261,15 +261,19 @@
-
+
-
+
Project Issue Kanban
project.issue
kanban
-
+
+
+
+
+
@@ -283,7 +287,7 @@
-
+
|
@@ -315,11 +319,11 @@
-
+
diff --git a/addons/project_long_term/__openerp__.py b/addons/project_long_term/__openerp__.py
index ef57f53e5f1..31522d63ea2 100644
--- a/addons/project_long_term/__openerp__.py
+++ b/addons/project_long_term/__openerp__.py
@@ -49,13 +49,11 @@ Features
'test/test_schedule_phases_case2.yml',
'test/project_schedule_consecutive_day.yml',
'test/project_schedule_without_wroking_hour.yml',
- 'test/schedule_phase_tasks.yml',
'test/phase_constraint.yml',
'test/test_schedule_tasks_case1.yml',
],
"update_xml": [
"security/ir.model.access.csv",
- "wizard/project_schedule_tasks_view.xml",
"project_long_term_view.xml",
"project_long_term_workflow.xml",
"wizard/project_compute_phases_view.xml",
diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py
index 7cd6697b67a..8588b90f5a2 100644
--- a/addons/project_long_term/project_long_term.py
+++ b/addons/project_long_term/project_long_term.py
@@ -22,7 +22,7 @@
from datetime import datetime
from tools.translate import _
from osv import fields, osv
-from resource.faces import task as Task
+from resource.faces import task as Task
from operator import itemgetter
class project_phase(osv.osv):
@@ -74,40 +74,43 @@ class project_phase(osv.osv):
return False
return True
- def _check_constraint_start(self, cr, uid, ids, context=None):
- phase = self.read(cr, uid, ids[0], ['date_start', 'constraint_date_start'], context=context)
- if phase['date_start'] and phase['constraint_date_start'] and phase['date_start'] < phase['constraint_date_start']:
- return False
- return True
-
- def _check_constraint_end(self, cr, uid, ids, context=None):
- phase = self.read(cr, uid, ids[0], ['date_end', 'constraint_date_end'], context=context)
- if phase['date_end'] and phase['constraint_date_end'] and phase['date_end'] > phase['constraint_date_end']:
- return False
- return True
-
def _get_default_uom_id(self, cr, uid):
model_data_obj = self.pool.get('ir.model.data')
model_data_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour')
return model_data_obj.read(cr, uid, [model_data_id], ['res_id'])[0]['res_id']
- def _compute(self, cr, uid, ids, field_name, arg, context=None):
+ def _compute_progress(self, cr, uid, ids, field_name, arg, context=None):
res = {}
if not ids:
return res
for phase in self.browse(cr, uid, ids, context=context):
- tot = 0.0
+ if phase.state=='done':
+ res[phase.id] = 100.0
+ continue
+ elif phase.state=="cancelled":
+ res[phase.id] = 0.0
+ continue
+ elif not phase.task_ids:
+ res[phase.id] = 0.0
+ continue
+
+ tot = done = 0.0
for task in phase.task_ids:
- tot += task.planned_hours
- res[phase.id] = tot
+ tot += task.total_hours
+ done += min(task.effective_hours, task.total_hours)
+
+ if not tot:
+ res[phase.id] = 0.0
+ else:
+ res[phase.id] = round(100.0 * done / tot, 2)
return res
_columns = {
'name': fields.char("Name", size=64, required=True),
- 'date_start': fields.date('Start Date', help="It's computed by the scheduler according the project date or the end date of the previous phase.", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
- 'date_end': fields.date('End Date', help=" It's computed by the scheduler according to the start date and the duration.", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
- 'constraint_date_start': fields.date('Minimum Start Date', help='force the phase to start after this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
- 'constraint_date_end': fields.date('Deadline', help='force the phase to finish before this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
+ 'date_start': fields.datetime('Start Date', help="It's computed by the scheduler according the project date or the end date of the previous phase.", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
+ 'date_end': fields.datetime('End Date', help=" It's computed by the scheduler according to the start date and the duration.", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
+ 'constraint_date_start': fields.datetime('Minimum Start Date', help='force the phase to start after this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
+ 'constraint_date_end': fields.datetime('Deadline', help='force the phase to finish before this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'project_id': fields.many2one('project.project', 'Project', required=True),
'next_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'prv_phase_id', 'next_phase_id', 'Next Phases', states={'cancelled':[('readonly',True)]}),
'previous_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'next_phase_id', 'prv_phase_id', 'Previous Phases', states={'cancelled':[('readonly',True)]}),
@@ -115,74 +118,27 @@ class project_phase(osv.osv):
'duration': fields.float('Duration', required=True, help="By default in days", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'product_uom': fields.many2one('product.uom', 'Duration UoM', required=True, help="UoM (Unit of Measure) is the unit of measurement for Duration", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'task_ids': fields.one2many('project.task', 'phase_id', "Project Tasks", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
- 'resource_ids': fields.one2many('project.resource.allocation', 'phase_id', "Project Resources",states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
- 'responsible_id': fields.many2one('res.users', 'Responsible', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
+ 'user_force_ids': fields.many2many('res.users', string='Force Assigned Users'),
+ 'user_ids': fields.one2many('project.user.allocation', 'phase_id', "Assigned Users",states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]},
+ help="The ressources on the project can be computed automatically by the scheduler"),
'state': fields.selection([('draft', 'New'), ('open', 'In Progress'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True,
help='If the phase is created the state \'Draft\'.\n If the phase is started, the state becomes \'In Progress\'.\n If review is needed the phase is in \'Pending\' state.\
\n If the phase is over, the states is set to \'Done\'.'),
- 'total_hours': fields.function(_compute, string='Total Hours'),
+ 'progress': fields.function(_compute_progress, string='Progress', help="Computed based on related tasks"),
}
_defaults = {
- 'responsible_id': lambda obj,cr,uid,context: uid,
'state': 'draft',
'sequence': 10,
'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Day'))], context=c)[0]
}
- _order = "project_id, date_start, sequence, name"
+ _order = "project_id, date_start, sequence"
_constraints = [
(_check_recursion,'Loops in phases not allowed',['next_phase_ids', 'previous_phase_ids']),
(_check_dates, 'Phase start-date must be lower than phase end-date.', ['date_start', 'date_end']),
]
def onchange_project(self, cr, uid, ids, project, context=None):
- result = {}
- result['date_start'] = False
- project_obj = self.pool.get('project.project')
- if project:
- project_id = project_obj.browse(cr, uid, project, context=context)
- result['date_start'] = project_id.date_start
- return {'value': result}
-
-
- def _check_date_start(self, cr, uid, phase, date_end, context=None):
- """
- Check And Compute date_end of phase if change in date_start < older time.
- """
- uom_obj = self.pool.get('product.uom')
- resource_obj = self.pool.get('resource.resource')
- cal_obj = self.pool.get('resource.calendar')
- calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
- resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)])
- if resource_id:
- res = resource_obj.read(cr, uid, resource_id, ['calendar_id'], context=context)[0]
- cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False
- if cal_id:
- calendar_id = cal_id
- default_uom_id = self._get_default_uom_id(cr, uid)
- avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
- work_times = cal_obj.interval_min_get(cr, uid, calendar_id, date_end, avg_hours or 0.0, resource_id and resource_id[0] or False)
- dt_start = work_times[0][0].strftime('%Y-%m-%d')
- self.write(cr, uid, [phase.id], {'date_start': dt_start, 'date_end': date_end.strftime('%Y-%m-%d')}, context=context)
-
- def _check_date_end(self, cr, uid, phase, date_start, context=None):
- """
- Check And Compute date_end of phase if change in date_end > older time.
- """
- uom_obj = self.pool.get('product.uom')
- resource_obj = self.pool.get('resource.resource')
- cal_obj = self.pool.get('resource.calendar')
- calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
- resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)], context=context)
- if resource_id:
- res = resource_obj.read(cr, uid, resource_id, ['calendar_id'], context=context)[0]
- cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False
- if cal_id:
- calendar_id = cal_id
- default_uom_id = self._get_default_uom_id(cr, uid)
- avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
- work_times = cal_obj.interval_get(cr, uid, calendar_id, date_start, avg_hours or 0.0, resource_id and resource_id[0] or False)
- dt_end = work_times[-1][1].strftime('%Y-%m-%d')
- self.write(cr, uid, [phase.id], {'date_start': date_start.strftime('%Y-%m-%d'), 'date_end': dt_end}, context=context)
+ return {}
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
@@ -211,208 +167,57 @@ class project_phase(osv.osv):
self.write(cr, uid, ids, {'state': 'done'})
return True
- def generate_phase(self, cr, uid, ids, f, parent=False, context=None):
- if context is None:
- context = {}
- phase_ids = []
- data_pool = self.pool.get('ir.model.data')
- uom_pool = self.pool.get('product.uom')
- task_pool = self.pool.get('project.task')
- data_model, day_uom_id = data_pool.get_object_reference(cr, uid, 'product', 'uom_day')
- for phase in self.browse(cr, uid, ids, context=context):
- avg_days = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration, day_uom_id)
- duration = str(avg_days) + 'd'
- # Create a new project for each phase
- str_resource = ('%s & '*len(phase.resource_ids))[:-2]
- str_vals = str_resource % tuple(map(lambda x: 'Resource_%s'%x.resource_id.id, phase.resource_ids))
+ def generate_phase(self, cr, uid, phases, context=None):
+ context = context or {}
+ result = ""
- # Phases Defination for the Project
- s = '''
+ task_pool = self.pool.get('project.task')
+ for phase in phases:
+ if phase.state in ('done','cancelled'):
+ continue
+ duration_uom = {
+ 'days': 'd', 'day': 'd', 'd':'d',
+ 'months': 'm', 'month':'month', 'm':'m',
+ 'weeks': 'w', 'week': 'w', 'w':'w',
+ 'hours': 'H', 'hour': 'H', 'h':'H',
+ }.get(phase.product_uom.name.lower(), "h")
+ duration = str(phase.duration) + duration_uom
+ result += '''
def Phase_%s():
- title = \"%s\"
- effort = \'%s\'
- resource = %s
-'''%(phase.id, phase.name, duration, str_vals or False)
-
- # Recalculate date_start and date_end
- # according to constraints on date start and date end on phase
- start_date = ''
- end_date = ''
+ effort = \"%s\"''' % (phase.id, duration)
+ start = []
if phase.constraint_date_start:
- start_date = datetime.strptime(phase.constraint_date_start, '%Y-%m-%d')
- s += '''
- start = \"%s\"
-'''%(datetime.strftime(start_date, "%Y-%m-%d"))
- else:
- if parent:
- start = 'up.Phase_%s.end' % (parent.id)
- s += '''
- start = %s
-'''%(start)
- else:
- start = phase.project_id.date_start or phase.date_start
- s += '''
- start = \"%s\"
-'''%(start)
-
- if phase.constraint_date_end :
- end_date= datetime.strptime(phase.constraint_date_end, '%Y-%m-%d')
- s += '''
- end = \"%s\"
-'''%(datetime.strftime(end_date, "%Y-%m-%d"))
+ start.append('datetime.datetime.strptime("'+str(phase.constraint_date_start)+'", "%Y-%m-%d %H:%M:%S")')
+ for previous_phase in phase.previous_phase_ids:
+ start.append("up.Phase_%s.end" % (previous_phase.id,))
+ if start:
+ result += '''
+ start = max(%s)
+''' % (','.join(start))
+ if phase.user_force_ids:
+ result += '''
+ resource = %s
+''' % '|'.join(map(lambda x: 'User_'+str(x.id), phase.user_force_ids))
- #start = datetime.strftime((datetime.strptime(start, "%Y-%m-%d")), "%Y-%m-%d")
+ result += task_pool._generate_task(cr, uid, phase.task_ids, ident=8, context=context)
+ result += "\n"
- phase_ids.append(phase.id)
- parent = False
- task_ids = []
- todo_task_ids = task_pool.search(cr, uid, [('id', 'in', map(lambda x : x.id, phase.task_ids)),
- ('state', 'in', ['draft', 'open', 'pending'])
- ], order='sequence')
- if todo_task_ids :
- for task in task_pool.browse(cr, uid, todo_task_ids, context=context):
- s += task_pool.generate_task(cr, uid, task.id, parent=parent, flag=False, context=context)
- if not parent:
- parent = task
- task_ids.append(task.id)
-
- f += s + '\n'
- # Recursive call till all the next phases scheduled
- for next_phase in phase.next_phase_ids:
- if next_phase.state in ['draft', 'open', 'pending']:
- rf, rphase_ids = self.generate_phase(cr, uid, [next_phase.id], f = '', parent=phase, context=context)
- f += rf +'\n'
- phase_ids += rphase_ids
- else:
- continue
- return f, phase_ids
-
- def schedule_tasks(self, cr, uid, ids, context=None):
- """
- Schedule tasks base on faces lib
- """
- if context is None:
- context = {}
- if type(ids) in (long, int,):
- ids = [ids]
- task_pool = self.pool.get('project.task')
- resource_pool = self.pool.get('resource.resource')
- for phase in self.browse(cr, uid, ids, context=context):
- project = phase.project_id
- calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
- start_date = project.date_start
- #Creating resources using the member of the Project
- u_ids = [i.id for i in project.members]
- resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
- start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
- func_str = ''
- start = start_date
- minimum_time_unit = 1
- # default values
- working_hours_per_day = 24
- working_days_per_week = 7
- working_days_per_month = 30
- working_days_per_year = 365
-
- vacation = []
- if calendar_id:
- working_hours_per_day = 8 #TODO: it should be come from calendars
- working_days_per_week = 5
- working_days_per_month = 20
- working_days_per_year = 200
- vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
-
- working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
-
- cls_str = ''
- # Creating Resources for the Project
- for key, vals in resource_objs.items():
- cls_str +='''
- class Resource_%s(Resource):
- title = \"%s\"
- vacation = %s
- efficiency = %s
-'''%(key, vals.get('name',False), vals.get('vacation', False), vals.get('efficiency', False))
-
- # Create a new project for each phase
- func_str += '''
-def Phase_%d():
- from resource.faces import Resource
- title = \"%s\"
- start = \'%s\'
- minimum_time_unit = %s
- working_hours_per_day = %s
- working_days_per_week = %s
- working_days_per_month = %s
- working_days_per_year = %s
- vacation = %s
- working_days = %s
-'''%(phase.id, phase.name, start, minimum_time_unit, working_hours_per_day, working_days_per_week, working_days_per_month, working_days_per_year, vacation, working_days )
-
- parent = False
- task_ids = []
- todo_task_ids = task_pool.search(cr, uid, [('id', 'in', map(lambda x : x.id, phase.task_ids)),
- ('state', 'in', ['draft', 'open', 'pending'])
- ], order='sequence')
- for task in task_pool.browse(cr, uid, todo_task_ids, context=context):
- func_str += task_pool.generate_task(cr, uid, task.id, parent=parent, flag=True, context=context)
- if not parent:
- parent = task
- task_ids.append(task.id)
- func_str += cls_str
- phase_id = phase.id
- #check known constraints before running Face algorithm in order to have the error translated
- if not phase.project_id.date_start:
- raise osv.except_osv(_('Error !'),_('Task Scheduling is not possible.\nProject should have the Start date for scheduling.'))
- # Allocating Memory for the required Project and Pahses and Resources
- exec(func_str)
- Phase = eval('Phase_%d' % phase.id)
- phase = None
- try:
- phase = Task.BalancedProject(Phase)
- except Exception, e:
- raise osv.except_osv(_('Error !'),e)
-
- for task_id in task_ids:
- task = eval("phase.Task_%d" % task_id)
- start_date = task.start.to_datetime()
- end_date = task.end.to_datetime()
-
- task_pool.write(cr, uid, [task_id], {
- 'date_start': start_date.strftime('%Y-%m-%d %H:%M:%S'),
- 'date_end': end_date.strftime('%Y-%m-%d %H:%M:%S')
- }, context=context)
- return True
+ return result
project_phase()
-class project_resource_allocation(osv.osv):
- _name = 'project.resource.allocation'
- _description = 'Project Resource Allocation'
- _rec_name = 'resource_id'
-
- def get_name(self, cr, uid, ids, field_name, arg, context=None):
- res = {}
- for allocation in self.browse(cr, uid, ids, context=context):
- name = allocation.phase_id.name
- name += ' (%s%%)' %(allocation.useability)
- res[allocation.id] = name
- return res
+class project_user_allocation(osv.osv):
+ _name = 'project.user.allocation'
+ _description = 'Phase User Allocation'
+ _rec_name = 'user_id'
_columns = {
- 'name': fields.function(get_name, type='char', size=256),
- 'resource_id': fields.many2one('resource.resource', 'Resource', required=True),
+ 'user_id': fields.many2one('res.users', 'User', required=True),
'phase_id': fields.many2one('project.phase', 'Project Phase', ondelete='cascade', required=True),
'project_id': fields.related('phase_id', 'project_id', type='many2one', relation="project.project", string='Project', store=True),
- 'user_id': fields.related('resource_id', 'user_id', type='many2one', relation="res.users", string='User'),
- 'date_start': fields.date('Start Date', help="Starting Date"),
- 'date_end': fields.date('End Date', help="Ending Date"),
- 'useability': fields.float('Availability', help="Availability of this resource for this project phase in percentage (=50%)"),
+ 'date_start': fields.datetime('Start Date', help="Starting Date"),
+ 'date_end': fields.datetime('End Date', help="Ending Date"),
}
- _defaults = {
- 'useability': 100,
- }
-
-project_resource_allocation()
+project_user_allocation()
class project(osv.osv):
_inherit = "project.project"
@@ -420,161 +225,102 @@ class project(osv.osv):
'phase_ids': fields.one2many('project.phase', 'project_id', "Project Phases"),
'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)]} ),
}
- def generate_members(self, cr, uid, ids, context=None):
- """
- Return a list of Resource Class objects for the resources allocated to the phase.
- """
- res = {}
- resource_pool = self.pool.get('resource.resource')
- for project in self.browse(cr, uid, ids, context=context):
- user_ids = map(lambda x:x.id, project.members)
- calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
- resource_objs = resource_pool.generate_resources(cr, uid, user_ids, calendar_id, context=context)
- res[project.id] = resource_objs
- return res
-
- def schedule_phases(self, cr, uid, ids, context=None):
- """
- Schedule phase base on faces lib
- """
- if context is None:
- context = {}
+ def _schedule_header(self, cr, uid, ids, context=None):
+ context = context or {}
if type(ids) in (long, int,):
ids = [ids]
- phase_pool = self.pool.get('project.phase')
- task_pool = self.pool.get('project.task')
+ projects = self.browse(cr, uid, ids, context=context)
+
+ for project in projects:
+ if not project.members:
+ raise osv.except_osv(_('Warning !'),_("You must assign members on the project '%s' !") % (project.name,))
+
resource_pool = self.pool.get('resource.resource')
- data_pool = self.pool.get('ir.model.data')
- resource_allocation_pool = self.pool.get('project.resource.allocation')
- data_model, day_uom_id = data_pool.get_object_reference(cr, uid, 'product', 'uom_day')
-
- #Checking the Valid Phase resource allocation from project member
- for project in self.browse(cr, uid, ids, context=context):
- flag = False
- res_missing = []
- members_ids = []
- if project.members:
- members_ids = [user.id for user in project.members]
- for phase in project.phase_ids:
- if phase.resource_ids:
- res_ids = [ re.id for re in phase.resource_ids]
- for res in resource_allocation_pool.browse(cr, uid, res_ids, context=context):
- if res.resource_id.user_id.id not in members_ids:
- res_missing += [res.resource_id.name]
- flag = True
- if flag:
- raise osv.except_osv(_('Warning !'),_("Resource(s) %s is(are) not member(s) of the project '%s' .") % (",".join(res_missing), project.name))
+ result = "from resource.faces import *\n"
+ result += "import datetime\n"
for project in self.browse(cr, uid, ids, context=context):
- root_phase_ids = phase_pool.search(cr, uid, [('project_id', '=', project.id),
- ('state', 'in', ['draft', 'open', 'pending']),
- ('previous_phase_ids', '=', False)
- ])
- calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
- start_date = project.date_start
- #if start_date:
- # start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
- #Creating resources using the member of the Project
u_ids = [i.id for i in project.members]
+ for task in project.tasks:
+ if task.state in ('done','cancelled'):
+ continue
+ if task.user_id and (task.user_id.id not in u_ids):
+ u_ids.append(task.user_id.id)
+ calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
- func_str = ''
- start = start_date
- minimum_time_unit = 1
- # default values
- working_hours_per_day = 24
- working_days_per_week = 7
- working_days_per_month = 30
- working_days_per_year = 365
-
- vacation = []
- if calendar_id:
- working_hours_per_day = 8 #TODO: it should be come from calendars
- working_days_per_week = 5
- working_days_per_month = 20
- working_days_per_year = 200
- vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
-
- working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
-
- cls_str = ''
- # Creating Resources for the Project
for key, vals in resource_objs.items():
- cls_str +='''
- class Resource_%s(Resource):
- title = \"%s\"
- vacation = %s
- efficiency = %s
-'''%(key, vals.get('name',False), vals.get('vacation', False), vals.get('efficiency', False))
-
- # Create a new project for each phase
- func_str += '''
-def Project_%d():
- from resource.faces import Resource
- title = \"%s\"
+ result +='''
+class User_%s(Resource):
+ efficiency = %s
+''' % (key, vals.get('efficiency', False))
+
+ result += '''
+def Project():
+ '''
+ return result
+
+ def _schedule_project(self, cr, uid, project, context=None):
+ resource_pool = self.pool.get('resource.resource')
+ calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
+ working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
+ # TODO: check if we need working_..., default values are ok.
+ result = """
+ def Project_%d():
start = \'%s\'
- minimum_time_unit = %s
- working_hours_per_day = %s
- working_days_per_week = %s
- working_days_per_month = %s
- working_days_per_year = %s
+ working_days = %s
+ resource = %s
+""" % (
+ project.id,
+ project.date_start, working_days,
+ '|'.join(['User_'+str(x.id) for x in project.members])
+ )
+ vacation = calendar_id and tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context)) or False
+ if vacation:
+ result+= """
vacation = %s
- working_days = %s
-'''%(project.id, project.name, start, minimum_time_unit, working_hours_per_day, working_days_per_week, working_days_per_month, working_days_per_year, vacation, working_days )
-
- func_str += cls_str
- phase_ids = []
- for root_phase in phase_pool.browse(cr, uid, root_phase_ids, context=context):
- phases, child_phase_ids = phase_pool.generate_phase(cr, uid, [root_phase.id], '', context=context)
- func_str += phases
- phase_ids += child_phase_ids
-
- project_id = project.id
- if not project.date_start:
- raise osv.except_osv(_('Error !'),_('Task Scheduling is not possible.\nProject should have the Start date for scheduling.'))
- # Allocating Memory for the required Project and Phases and Resources
- exec(func_str)
- Project = eval('Project_%d' % project.id)
- project = None
- try:
- project = Task.BalancedProject(Project)
- except Exception, e:
- raise osv.except_osv(_('Error !'), e)
-
- for phase_id in phase_ids:
- act_phase = phase_pool.browse(cr, uid, phase_id, context=context)
- resources = act_phase.resource_ids
- phase = eval("project.Phase_%d" % phase_id)
- start_date = phase.start.to_datetime()
- end_date = phase.end.to_datetime()
-
- if resources:
- for res in resources:
- vals = {}
- vals.update({'date_start' : start_date })
- vals.update({'date_end' : end_date})
- resource_allocation_pool.write(cr, uid, res.id, vals, context=context)
- if act_phase.task_ids:
- for task in act_phase.task_ids:
- vals = {}
- #Getting values of the Tasks
- temp = eval("phase.Task_%s"%task.id)
- if temp.booked_resource:
- res_name = temp.booked_resource[0].title
- res_id = resource_pool.search(cr, uid,[('name','=',res_name)], context = context)
- if res_id:
- res = resource_pool.browse(cr, uid, res_id[0], context = context)
- vals.update({'user_id' : res.user_id.id})
-
- vals.update({'date_start' : temp.start.strftime('%Y-%m-%d %H:%M:%S')})
- vals.update({'date_end' : temp.end.strftime('%Y-%m-%d %H:%M:%S')})
- task_pool.write(cr, uid, task.id, vals, context=context)
+""" % ( vacation, )
+ return result
- phase_pool.write(cr, uid, [phase_id], {
- 'date_start': start_date.strftime('%Y-%m-%d'),
- 'date_end': end_date.strftime('%Y-%m-%d')
- }, context=context)
- return True
+ def schedule_phases(self, cr, uid, ids, context=None):
+ context = context or {}
+ if type(ids) in (long, int,):
+ ids = [ids]
+ projects = self.browse(cr, uid, ids, context=context)
+ result = self._schedule_header(cr, uid, ids, context=context)
+ for project in projects:
+ result += self._schedule_project(cr, uid, project, context=context)
+ result += self.pool.get('project.phase').generate_phase(cr, uid, project.phase_ids, context=context)
+
+ local_dict = {}
+ exec result in local_dict
+ projects_gantt = Task.BalancedProject(local_dict['Project'])
+
+ for project in projects:
+ project_gantt = getattr(projects_gantt, 'Project_%d' % (project.id,))
+ for phase in project.phase_ids:
+ if phase.state in ('done','cancelled'):
+ continue
+ # Maybe it's better to update than unlink/create if it already exists ?
+ p = getattr(project_gantt, 'Phase_%d' % (phase.id,))
+
+ self.pool.get('project.user.allocation').unlink(cr, uid,
+ [x.id for x in phase.user_ids],
+ context=context
+ )
+
+ for r in p.booked_resource:
+ self.pool.get('project.user.allocation').create(cr, uid, {
+ 'user_id': int(r.name[5:]),
+ 'phase_id': phase.id,
+ 'date_start': p.start.strftime('%Y-%m-%d %H:%M:%S'),
+ 'date_end': p.end.strftime('%Y-%m-%d %H:%M:%S')
+ }, context=context)
+ self.pool.get('project.phase').write(cr, uid, [phase.id], {
+ 'date_start': p.start.strftime('%Y-%m-%d %H:%M:%S'),
+ 'date_end': p.end.strftime('%Y-%m-%d %H:%M:%S')
+ }, context=context)
+ return True
#TODO: DO Resource allocation and compute availability
def compute_allocation(self, rc, uid, ids, start_date, end_date, context=None):
@@ -584,186 +330,67 @@ def Project_%d():
return allocation
def schedule_tasks(self, cr, uid, ids, context=None):
- """
- Schedule task base on faces lib
- """
- if context is None:
- context = {}
+ context = context or {}
if type(ids) in (long, int,):
ids = [ids]
- task_pool = self.pool.get('project.task')
- resource_pool = self.pool.get('resource.resource')
- data_pool = self.pool.get('ir.model.data')
- data_model, day_uom_id = data_pool.get_object_reference(cr, uid, 'product', 'uom_day')
+ projects = self.browse(cr, uid, ids, context=context)
+ result = self._schedule_header(cr, uid, ids, context=context)
+ for project in projects:
+ result += self._schedule_project(cr, uid, project, context=context)
+ result += self.pool.get('project.task')._generate_task(cr, uid, project.tasks, ident=4, context=context)
- for project in self.browse(cr, uid, ids, context=context):
- calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
- start_date = project.date_start
-
- #Checking the Valid Phase resource allocation from project member
- flag = False
- res_missing = []
- members_ids = []
- if project.members:
- members_ids = [user.id for user in project.members]
- for phase in project.phase_ids:
- if phase.resource_ids:
- res_ids = [ re.id for re in phase.resource_ids]
- for res in self.pool.get('project.resource.allocation').browse(cr, uid, res_ids, context=context):
- if res.resource_id.user_id.id not in members_ids:
- res_missing += [res.resource_id.name]
- flag = True
- if flag:
- raise osv.except_osv(_('Warning !'),_("Resource(s) %s is(are) not member(s) of the project '%s' .") % (",".join(res_missing), project.name))
- #Creating resources using the member of the Project
- u_ids = [i.id for i in project.members]
- resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
- try:
- start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
- except:
- raise osv.except_osv(_('Error !'),_('Task Scheduling is not possible.\nProject should have the Start date for scheduling.'))
- func_str = ''
- start = start_date
- minimum_time_unit = 1
- # default values
- working_hours_per_day = 24
- working_days_per_week = 7
- working_days_per_month = 30
- working_days_per_year = 365
-
- vacation = []
- if calendar_id:
- working_hours_per_day = 8 #TODO: it should be come from calendars
- working_days_per_week = 5
- working_days_per_month = 20
- working_days_per_year = 200
- vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
+ local_dict = {}
+ exec result in local_dict
+ projects_gantt = Task.BalancedProject(local_dict['Project'])
- working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
-
- cls_str = ''
- # Creating Resources for the Project
- for key, vals in resource_objs.items():
- cls_str +='''
- class Resource_%s(Resource):
- title = \"%s\"
- vacation = %s
- efficiency = %s
-'''%(key, vals.get('name',False), vals.get('vacation', False), vals.get('efficiency', False))
-
- # Create a new project for each phase
- func_str += '''
-def Project_%d():
- from resource.faces import Resource
- title = \"%s\"
- start = \'%s\'
- minimum_time_unit = %s
- working_hours_per_day = %s
- working_days_per_week = %s
- working_days_per_month = %s
- working_days_per_year = %s
- vacation = %s
- working_days = %s
-'''%(project.id, project.name, start, minimum_time_unit, working_hours_per_day, working_days_per_week, working_days_per_month, working_days_per_year, vacation, working_days )
-
- parent = False
- task_ids = []
- todo_task_ids = task_pool.search(cr, uid, [('project_id', '=', project.id),
- ('state', 'in', ['draft', 'open', 'pending'])
- ], order='sequence')
- if todo_task_ids:
- for task in task_pool.browse(cr, uid, todo_task_ids, context=context):
- func_str += task_pool.generate_task(cr, uid, task.id, parent=parent, flag=True,context=context)
- if not parent:
- parent = task
- task_ids.append(task.id)
- func_str += cls_str
+ for project in projects:
+ project_gantt = getattr(projects_gantt, 'Project_%d' % (project.id,))
+ for task in project.tasks:
+ if task.state in ('done','cancelled'):
+ continue
- if not project.date_start:# or not project.members:
- raise osv.except_osv(_('Error !'),_('Task Scheduling is not possible.\nProject should have the Start date for scheduling.'))
- # Allocating Memory for the required Project and Phases and Resources
- exec(func_str)
- Project = eval('Project_%d' % project.id)
- project = None
- try:
- project = Task.BalancedProject(Project)
- except Exception, e:
- raise osv.except_osv(_('Error !'), e)
-
- for task_id in task_ids:
- task = eval("project.Task_%d" % task_id)
- start_date = task.start.to_datetime()
- end_date = task.end.to_datetime()
-
- task_pool.write(cr, uid, [task_id], {
- 'date_start': start_date.strftime('%Y-%m-%d %H:%M:%S'),
- 'date_end': end_date.strftime('%Y-%m-%d %H:%M:%S')
- }, context=context)
+ p = getattr(project_gantt, 'Task_%d' % (task.id,))
+
+ self.pool.get('project.task').write(cr, uid, [task.id], {
+ 'date_start': p.start.strftime('%Y-%m-%d %H:%M:%S'),
+ 'date_end': p.end.strftime('%Y-%m-%d %H:%M:%S')
+ }, context=context)
+ if (not task.user_id) and (p.booked_resource):
+ self.pool.get('project.task').write(cr, uid, [task.id], {
+ 'user_id': int(p.booked_resource[0].name[5:]),
+ }, context=context)
return True
-
project()
-class resource_resource(osv.osv):
- _inherit = "resource.resource"
- def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
- if context is None:
- context = {}
- if context.get('project_id',False):
- project_pool = self.pool.get('project.project')
- project_rec = project_pool.browse(cr, uid, context['project_id'], context=context)
- user_ids = [user_id.id for user_id in project_rec.members]
- args.append(('user_id','in',user_ids))
- return super(resource_resource, self).search(cr, uid, args, offset, limit, order, context, count)
-
-resource_resource()
-
class project_task(osv.osv):
_inherit = "project.task"
_columns = {
'phase_id': fields.many2one('project.phase', 'Project Phase'),
}
- _defaults = {
- 'user_id' : False
- }
+ def _generate_task(self, cr, uid, tasks, ident=4, context=None):
+ context = context or {}
+ result = ""
+ ident = ' '*ident
+ for task in tasks:
+ if task.state in ('done','cancelled'):
+ continue
+ result += '''
+%sdef Task_%s():
+%s todo = \"%.2fH\"
+%s effort = \"%.2fH\"''' % (ident,task.id, ident,task.remaining_hours, ident,task.total_hours)
+ start = []
+ for t2 in task.parent_ids:
+ start.append("up.Task_%s.end" % (t2.id,))
+ if start:
+ result += '''
+%s start = max(%s)
+''' % (ident,','.join(start))
- def generate_task(self, cr, uid, task_id, parent=False, flag=False, context=None):
- if context is None:
- context = {}
- task = self.browse(cr, uid, task_id, context=context)
- duration = str(task.planned_hours)+ 'H'
- str_resource = False
- parent = task.parent_ids
- if task.phase_id.resource_ids:
- str_resource = ('%s | '*len(task.phase_id.resource_ids))[:-2]
- str_resource = str_resource % tuple(map(lambda x: 'Resource_%s'%x.resource_id.id, task.phase_id.resource_ids))
- # Task Defination for the Phase of the Project
- if not flag:
- s = '''
- def Task_%s():
- title = \"%s\"
- effort = \'%s\'
- resource = %s
-'''%(task.id, task.name, duration, str_resource)
- if task.child_ids:
- seq = [[child.planned_hours, child.id] for child in task.child_ids]
- seq.sort(key=itemgetter(0))
- s +='''
- start = up.Task_%s.end
- '''%(seq[-1][1])
- else:
- s = '''
- def Task_%s():
- title = \"%s\"
- effort = \'%s\'
- resource = %s
-'''%(task.id, task.name, duration, str_resource)
- if task.child_ids:
- seq = [[child.planned_hours, child.id] for child in task.child_ids]
- seq.sort(key=itemgetter(0))
- s +='''
- start = up.Task_%s.end
-'''%(seq[-1][1])
- s += '\n'
- return s
+ if task.user_id:
+ result += '''
+%s resource = %s
+''' % (ident, 'User_'+str(task.user_id.id))
+
+ result += "\n"
+ return result
project_task()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_long_term/project_long_term_demo.xml b/addons/project_long_term/project_long_term_demo.xml
index 961b0c62c9b..252bcdd0e9d 100644
--- a/addons/project_long_term/project_long_term_demo.xml
+++ b/addons/project_long_term/project_long_term_demo.xml
@@ -1,55 +1,9 @@
-
-
-
-
- Analyst
-
-
-
-
-
- Project Manager
-
-
-
-
-
- Technical Leader
-
-
-
-
-
- Developer
-
-
-
-
-
- Designer
-
-
-
-
-
- Tester
-
-
-
-
-
- Project Finacial Manager
-
-
-
-
-
-
+
@@ -58,7 +12,6 @@ This Demo data file Human Resources, Phases and Resources,Tasks allocation and
30
-
@@ -68,7 +21,6 @@ This Demo data file Human Resources, Phases and Resources,Tasks allocation and
20
-
@@ -78,7 +30,6 @@ This Demo data file Human Resources, Phases and Resources,Tasks allocation and
20
-
@@ -88,7 +39,6 @@ This Demo data file Human Resources, Phases and Resources,Tasks allocation and
90
-
@@ -98,7 +48,6 @@ This Demo data file Human Resources, Phases and Resources,Tasks allocation and
30
-
@@ -108,56 +57,9 @@ This Demo data file Human Resources, Phases and Resources,Tasks allocation and
10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/project_long_term/project_long_term_view.xml b/addons/project_long_term/project_long_term_view.xml
index 49b306ebfd5..dfef83e4468 100644
--- a/addons/project_long_term/project_long_term_view.xml
+++ b/addons/project_long_term/project_long_term_view.xml
@@ -2,32 +2,32 @@
-
+
# ------------------------------------------------------
- # Project Resource Allocation
+ # Project User Allocation
# ------------------------------------------------------
-
- project.resource.allocation.gantt
- project.resource.allocation
+
+ project.user.allocation.gantt
+ project.user.allocation
gantt
-
+
-
- project.resource.allocation.calendar
- project.resource.allocation
+
+ project.user.allocation.calendar
+ project.user.allocation
calendar
-
+
@@ -35,53 +35,51 @@
-
- project.resource.allocation.form
- project.resource.allocation
+
+ project.user.allocation.form
+ project.user.allocation
form
-
-
- project.resource.allocation.list
- project.resource.allocation
+
+ project.user.allocation.list
+ project.user.allocation
tree
-
-
+
+
-
-
- project.resource.allocation.search
- project.resource.allocation
+
+ project.user.allocation.search
+ project.user.allocation
search
-
+
-
+
-
+
@@ -90,12 +88,12 @@
- Resources Allocation
- project.resource.allocation
+ Planning of Users
+ project.user.allocation
form
gantt,tree,form,calendar
{}
-
+
@@ -110,32 +108,27 @@
@@ -241,7 +205,6 @@
-
@@ -275,14 +238,11 @@
-
-
-
@@ -300,7 +260,7 @@
gantt,tree,form,calendar
{"search_default_current": 1}
- A project can be split into the different phases. For each phase, you can define your resources allocation, describe different tasks and link your phase to previous and next phases, add date constraints for the automated scheduling. Use the long term planning in order to planify your available human resources, convert your phases into a series of tasks when you start working on the project.
+ A project can be split into the different phases. For each phase, you can define your users allocation, describe different tasks and link your phase to previous and next phases, add date constraints for the automated scheduling. Use the long term planning in order to planify your available users, convert your phases into a series of tasks when you start working on the project.
@@ -317,7 +277,7 @@
# Project
# ------------------------------------------------------
-
+
Project Resource Calendar View
project.project
form
@@ -402,17 +362,6 @@
view_type="form"
/>
-
-
# ------------------------------------------------------
# Menu Items
# ------------------------------------------------------
@@ -428,16 +377,16 @@
+ parent="base.menu_project_long_term" sequence="2"/>
-
+ name="Users" parent="project.menu_definitions" sequence="3"/>
-
-
-
+
+
+
diff --git a/addons/project_long_term/security/ir.model.access.csv b/addons/project_long_term/security/ir.model.access.csv
index 6d4961f2cfe..4382d27834e 100644
--- a/addons/project_long_term/security/ir.model.access.csv
+++ b/addons/project_long_term/security/ir.model.access.csv
@@ -1,9 +1,9 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_project_phase","project.phase","model_project_phase","project.group_project_user",1,1,1,0
-"access_project_resource_allocation","project.resource.allocation","model_project_resource_allocation","project.group_project_user",1,0,0,0
+"access_project_user_allocation","project.user.allocation","model_project_user_allocation","project.group_project_user",1,0,0,0
"access_project_phase_manager","project.phase manager","model_project_phase","project.group_project_manager",1,1,1,1
-"access_project_resource_allocation_manager","project.resource.allocation manager","model_project_resource_allocation","project.group_project_manager",1,1,1,1
-"access_resource_resource_user","resource.resource user","resource.model_resource_resource","project.group_project_user",1,0,0,0
-"access_resource_calendar_leaves_user","resource.calendar.leaves user","resource.model_resource_calendar_leaves","project.group_project_user",1,1,1,1
-"access_resource_resource_manager","resource.resource manager","resource.model_resource_resource","project.group_project_manager",1,1,1,1
-"access_project_resource_allocation_manager","project.resource.allocation.manager","model_project_resource_allocation","project.group_project_manager",1,1,1,1
+"access_project_user_allocation_manager","project.user.allocation manager","model_project_user_allocation","project.group_project_manager",1,1,1,1
+"access_resource_resource_user","user.user user","resource.model_resource_resource","project.group_project_user",1,0,0,0
+"access_resource_calendar_leaves_user","user.calendar.leaves user","resource.model_resource_calendar_leaves","project.group_project_user",1,1,1,1
+"access_resource_resource_manager","user.user manager","resource.model_resource_resource","project.group_project_manager",1,1,1,1
+"access_project_user_allocation_manager","project.user.allocation.manager","model_project_user_allocation","project.group_project_manager",1,1,1,1
diff --git a/addons/project_long_term/test/phase_constraint.yml b/addons/project_long_term/test/phase_constraint.yml
index ad1a3db095e..f4fa09e6e38 100644
--- a/addons/project_long_term/test/phase_constraint.yml
+++ b/addons/project_long_term/test/phase_constraint.yml
@@ -5,6 +5,8 @@
name: "Develop Yaml Project Module"
date_start: !eval time.strftime('%Y-%m-%d')
resource_calendar_id: resource.timesheet_group1
+ members:
+ - base.user_admin
-
And I create three human ressources to work on this project, an analyst.
-
@@ -43,7 +45,6 @@
name: "Analysis"
product_uom: product.uom_day
project_id: project_project_developyamlproject0
- responsible_id: project.res_users_analyst
state: draft
-
diff --git a/addons/project_long_term/test/project_schedule_consecutive_day.yml b/addons/project_long_term/test/project_schedule_consecutive_day.yml
index 10cfc7b6b9c..cffe06a9ff9 100644
--- a/addons/project_long_term/test/project_schedule_consecutive_day.yml
+++ b/addons/project_long_term/test/project_schedule_consecutive_day.yml
@@ -4,6 +4,8 @@
!record {model: project.project, id: project_project_developyamlproject_2}:
name: "Develop Yaml Project Module"
date_start: !eval time.strftime('%Y-%m-%d')
+ members:
+ - base.user_admin
-
I have set Working Time from Monday to Friday from 9am to 17pm.
@@ -107,7 +109,6 @@
!record {model: project.compute.phases, id: project_compute_phases_0}:
project_id: project_project_developyamlproject_2
target_project: one
-
-
Schedule project phases using Compute Phase Scheduling
-
@@ -120,7 +121,7 @@
!python {model: project.project}: |
proj=self.browse(cr, uid, [ref("project_project_developyamlproject_2")])[0]
for phase in proj.phase_ids:
- if (not phase.responsible_id) or (not phase.date_start) or (not phase.date_end):
- raise AssertionError("Phases not scheduled")
-
+ if (not phase.date_start) or (not phase.date_end):
+ raise AssertionError("Phases not scheduled")
+
diff --git a/addons/project_long_term/test/project_schedule_without_wroking_hour.yml b/addons/project_long_term/test/project_schedule_without_wroking_hour.yml
index 61a8539585a..4fe7687425b 100644
--- a/addons/project_long_term/test/project_schedule_without_wroking_hour.yml
+++ b/addons/project_long_term/test/project_schedule_without_wroking_hour.yml
@@ -15,7 +15,6 @@
product_uom: product.uom_day
name: "Analysis Flow for Yaml"
project_id: project_project_developyamlproject_2
- responsible_id: project.res_users_analyst
state: draft
-
@@ -71,7 +70,7 @@
!python {model: project.project}: |
proj=self.browse(cr, uid, [ref("project_project_developyamlproject_2")])[0]
for phase in proj.phase_ids:
- if (not phase.responsible_id) or (not phase.date_start) or (not phase.date_end):
+ if (not phase.date_start) or (not phase.date_end):
raise AssertionError("Phases not scheduled")
diff --git a/addons/project_long_term/test/schedule_phase_tasks.yml b/addons/project_long_term/test/schedule_phase_tasks.yml
deleted file mode 100644
index be22f778cee..00000000000
--- a/addons/project_long_term/test/schedule_phase_tasks.yml
+++ /dev/null
@@ -1,90 +0,0 @@
--
- Create project 'Develop an outlook-openerp synchronization plugin'
--
- !record {model: project.project, id: project_project_project4}:
- name: Develop an outlook-openerp synchronization plugin
- members:
- - project.res_users_project_manager
- - project.res_users_technical_leader
- - project.res_users_developer
- - project.res_users_designer
- - project.res_users_tester
- - project.res_users_analyst
- - project.res_users_finacial_manager
--
- Create phase 'Develop GUI' in Outlook
--
- !record {model: project.phase, id: project_phase_phase0}:
- date_start: !eval time.strftime("%Y-%m-%d")
- duration: 200.0
- name: Develop GUI in Outlook
- product_uom: product.uom_day
- project_id: project_project_project4
- state: draft
- resource_ids:
- - resource_id: project_long_term.resource_analyst
- - resource_id: project_long_term.resource_developer
- - resource_id: project_long_term.resource_designer
- - resource_id: project_long_term.resource_tester
- - resource_id: project_long_term.resource_project_manager
-
--
- Create the phase task 'Develop GUI for Server Configuration'
--
- !record {model: project.task, id: project_task_t0}:
- name: Develop GUI for Server Configuration
- planned_hours: 20.0
- remaining_hours: 20.0
- state: draft
- phase_id: project_phase_phase0
- project_id: project_project_project4
-
-
--
- Create the phase task 'Develop GUI for Modules Configuration'
--
- !record {model: project.task, id: project_task_t1}:
- name: Develop GUI for Modules Configuration
- planned_hours: 25.0
- remaining_hours: 25.0
- state: draft
- phase_id: project_phase_phase0
- project_id: project_project_project4
-
--
- Create the phase task 'Develop GUI for OpenERP Synchronisation'
--
- !record {model: project.task, id: project_task_t2}:
- name: Develop GUI for OpenERP Synchronisation
- planned_hours: 30.0
- remaining_hours: 30.0
- state: draft
- phase_id: project_phase_phase0
- project_id: project_project_project4
-
--
- Create the phase task 'Design required GUI/Menus'
--
- !record {model: project.task, id: project_task_3}:
- name: Design required GUI/Menus
- planned_hours: 25.0
- remaining_hours: 25.0
- state: draft
- phase_id: project_phase_phase0
- project_id: project_project_project4
-
--
- Schedule phase tasks
--
- !python {model: project.phase}: |
- res = self.schedule_tasks(cr, uid, [ref("project_phase_phase0")])
-
--
- Check if tasks scheduled, check that either of task's start_date, end_date and user_id is not null
--
- !python {model: project.phase}: |
- phase = self.browse(cr, uid, [ref("project_phase_phase0")])[0]
- for task in phase.task_ids:
- if (not task.date_start) or (not task.date_end):
- raise AssertionError("Phase Tasks not scheduled: %d uid=%r start=%r end=%r" % \
- (task.id, task.user_id, task.date_start, task.date_end))
diff --git a/addons/project_long_term/test/schedule_project_phases.yml b/addons/project_long_term/test/schedule_project_phases.yml
index 4bc6549bf35..550787fe867 100644
--- a/addons/project_long_term/test/schedule_project_phases.yml
+++ b/addons/project_long_term/test/schedule_project_phases.yml
@@ -31,28 +31,6 @@
name: Establishing Project Feasibility
product_uom: product.uom_day
project_id: project_project_worldbanksproject0
-
--
- Resource1
--
- !record {model: project.resource.allocation, id: res_phase1}:
- resource_id: project_long_term.resource_project_manager
- phase_id: project_phase_definingclientsbasicideaofproject0
-
--
- Resource2
--
- !record {model: project.resource.allocation, id: res_phase2}:
- resource_id: project_long_term.resource_analyst
- phase_id: project_phase_definingclientsbasicideaofproject0
-
--
- Resource3
--
- !record {model: project.resource.allocation, id: res_phase3}:
- resource_id: project_long_term.resource_technical_leader
- phase_id: project_phase_definingclientsbasicideaofproject0
-
-
Create the phase task 'Develop GUI for Server Configuration'
-
@@ -84,20 +62,6 @@
product_uom: product.uom_hour
project_id: project_project_worldbanksproject0
--
- Resource4
--
- !record {model: project.resource.allocation, id: res_phase4}:
- resource_id: project_long_term.resource_developer
- phase_id: project_phase_preparationofengineeringdesigns0
-
--
- Resource5
--
- !record {model: project.resource.allocation, id: res_phase5}:
- resource_id: project_long_term.resource_designer
- phase_id: project_phase_preparationofengineeringdesigns0
-
-
Create the phase task 'Develop GUI for Client Configuration'
-
@@ -210,7 +174,7 @@
!python {model: project.project}: |
prj=self.browse(cr, uid, [ref("project_project_worldbanksproject0")])[0]
for phase in prj.phase_ids:
- if (not phase.responsible_id) or (not phase.date_start) or (not phase.date_end):
- raise AssertionError("Tasks not scheduled")
+ if (not phase.date_start) or (not phase.date_end):
+ raise AssertionError("Tasks not scheduled")
diff --git a/addons/project_long_term/test/schedule_project_tasks.yml b/addons/project_long_term/test/schedule_project_tasks.yml
index 825b7c404d9..17db7ef8038 100644
--- a/addons/project_long_term/test/schedule_project_tasks.yml
+++ b/addons/project_long_term/test/schedule_project_tasks.yml
@@ -11,26 +11,17 @@
- project.res_users_tester
- project.res_users_analyst
- project.res_users_finacial_manager
-
+
-
Create phase 'Develop GUI' in thunderbird
-
!record {model: project.phase, id: project_phase_phase1}:
- date_start: !eval time.strftime('%Y-%m-%d')
+ date_start: !eval time.strftime('%Y-%m-%d %H:%M:%S')
duration: 200.0
name: Develop GUI in thunderbird
product_uom: product.uom_day
project_id: project_project_project1
state: draft
- resource_ids:
- - resource_id: project_long_term.resource_analyst
- useability: 80.0
- - resource_id: project_long_term.resource_developer
- useability: 30.0
- - resource_id: project_long_term.resource_designer
- useability: 30.0
-
-
-
Create the phase task 'Develop GUI for Server Configuration'
-
@@ -76,8 +67,7 @@
phase_id: project_phase_phase1
project_id: project_project_project1
user_id: project.res_users_designer
-
-
+
-
Schedule tasks
-
@@ -88,7 +78,9 @@
Check if tasks scheduled, check that either of task's start_date, end_date and user_id is not null
-
!python {model: project.project}: |
- prj = self.browse(cr, uid, [ref("project_project_project1")])[0]
- for task in prj.tasks:
- if (not task.user_id) or (not task.date_start) or (not task.date_end):
- raise AssertionError("Project Tasks not scheduled")
+ prj = self.browse(cr, uid, [ref("project_project_project1")])[0]
+ for task in prj.tasks:
+ if task.state in ('done','cancelled'):
+ continue
+ if (not task.user_id) or (not task.date_start) or (not task.date_end):
+ raise AssertionError("Project tasks not scheduled!")
diff --git a/addons/project_long_term/test/test_schedule_phases_case1.yml b/addons/project_long_term/test/test_schedule_phases_case1.yml
index ba091a29916..ef8d0410439 100644
--- a/addons/project_long_term/test/test_schedule_phases_case1.yml
+++ b/addons/project_long_term/test/test_schedule_phases_case1.yml
@@ -63,10 +63,12 @@
import datetime
from dateutil.relativedelta import *
start = (datetime.date.today()).strftime('%Y-%m-%d')
- end = (datetime.date.today() + relativedelta(days=2)).strftime('%Y-%m-%d')
+ end = (datetime.date.today() + relativedelta(days=1)).strftime('%Y-%m-%d 17:00:00')
first_phase = self.browse(cr, uid, ref('project_phase_firstphase0_case1'))
- assert (first_phase.date_start == start and first_phase.date_end == end),'Dates are wrong!'
+ assert (first_phase.date_start[:10] == start),'Start dates are wrong: %s != %s !' % (first_phase.date_start, start)
+ assert (first_phase.date_end >= end),'End dates are wrong: %s <%s!' % (first_phase.date_end, end)
+
second_phase = self.browse(cr, uid, ref('project_phase_secondphase0_case2'))
start = first_phase.date_end
end = (datetime.date.today() + relativedelta(days=5)).strftime('%Y-%m-%d')
- assert (second_phase.date_start == start and second_phase.date_end == end),'Dates are wrong!'
+ assert (second_phase.date_start >= start and second_phase.date_end >= end),'Dates are wrong on second phase!'
diff --git a/addons/project_long_term/test/test_schedule_phases_case2.yml b/addons/project_long_term/test/test_schedule_phases_case2.yml
index 67a7332cf5b..35173a897a3 100644
--- a/addons/project_long_term/test/test_schedule_phases_case2.yml
+++ b/addons/project_long_term/test/test_schedule_phases_case2.yml
@@ -147,7 +147,7 @@
I create a phase 'Initial Phase' for project 'Development and Testing'.
-
!record {model: project.phase, id: project_phase_phase0}:
- date_start: '2011-01-03'
+ date_start: '2011-01-03 08:00:00'
duration: 0.0
name: Initial Phase
product_uom: product.uom_day
diff --git a/addons/project_long_term/test/test_schedule_tasks_case1.yml b/addons/project_long_term/test/test_schedule_tasks_case1.yml
index d40b61d6b3a..3bb0ea87c43 100644
--- a/addons/project_long_term/test/test_schedule_tasks_case1.yml
+++ b/addons/project_long_term/test/test_schedule_tasks_case1.yml
@@ -38,7 +38,7 @@
- res_users_user0
- res_users_user1
phase_ids:
- - date_start: '2011-01-06'
+ - date_start: '2011-01-06 08:00:00'
duration: 2.0
name: Phase A
product_uom: product.uom_day
@@ -184,16 +184,11 @@
Now I create one phase for the project.
-
!record {model: project.phase, id: project_phase_phasea0}:
- date_start: '2011-01-06'
+ date_start: '2011-01-06 08:00:00'
duration: 2.0
name: Phase A
product_uom: product.uom_day
project_id: project_project_projecta0
- resource_ids:
- - project_id: project_project_projecta0
- resource_id: resource_resource_user0
- - project_id: project_project_projecta0
- resource_id: resource_resource_user1
state: draft
task_ids:
- delay_hours: 0.0
diff --git a/addons/project_long_term/wizard/__init__.py b/addons/project_long_term/wizard/__init__.py
index c1e6d838111..4536f4a3cbb 100644
--- a/addons/project_long_term/wizard/__init__.py
+++ b/addons/project_long_term/wizard/__init__.py
@@ -21,6 +21,5 @@
import project_compute_phases
import project_compute_tasks
-import project_schedule_tasks
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_long_term/wizard/project_compute_phases.py b/addons/project_long_term/wizard/project_compute_phases.py
index 7e84f0681cc..57a1b3b6ed3 100644
--- a/addons/project_long_term/wizard/project_compute_phases.py
+++ b/addons/project_long_term/wizard/project_compute_phases.py
@@ -25,21 +25,19 @@ class project_compute_phases(osv.osv_memory):
_name = 'project.compute.phases'
_description = 'Project Compute Phases'
_columns = {
- 'target_project': fields.selection([('all', 'Compute All Projects'),
- ('one', 'Compute a Single Project'),
- ], 'Schedule', required = True),
-
+ 'target_project': fields.selection([
+ ('all', 'Compute All My Projects'),
+ ('one', 'Compute a Single Project'),
+ ], 'Schedule', required=True),
'project_id': fields.many2one('project.project', 'Project')
}
-
_defaults = {
- 'target_project': 'all'
+ 'target_project': 'one'
}
def check_selection(self, cr, uid, ids, context=None):
return self.compute_date(cr, uid, ids, context=context)
-
def compute_date(self, cr, uid, ids, context=None):
"""
Compute the phases for scheduling.
@@ -47,12 +45,12 @@ class project_compute_phases(osv.osv_memory):
project_pool = self.pool.get('project.project')
data = self.read(cr, uid, ids, [], context=context)[0]
if not data['project_id'] and data['target_project'] == 'one':
- raise osv.except_osv(_('Error!'), _('Please Specify Project to be schedule'))
+ raise osv.except_osv(_('Error!'), _('Please specify a project to schedule.'))
- if data['project_id']: # If project mentioned find its phases
+ if data['target_project'] == 'one':
project_ids = [data['project_id'][0]]
- else: # Else take all the draft,open,pending states phases
- project_ids = project_pool.search(cr, uid, [], context=context)
+ else:
+ project_ids = project_pool.search(cr, uid, [('user_id','=',uid)], context=context)
project_pool.schedule_phases(cr, uid, project_ids, context=context)
return self._open_phases_list(cr, uid, data, context=context)
@@ -70,8 +68,7 @@ class project_compute_phases(osv.osv_memory):
result = act_obj.read(cr, uid, [id], context=context)[0]
result['target'] = 'current'
project_id = data.get('project_id') and data.get('project_id')[0] or False
- result['context'] = {"search_default_project_id":project_id, "default_project_id":project_id, "search_default_responsible_id":uid, "search_default_current": 1}
+ result['context'] = {"search_default_project_id":project_id, "default_project_id":project_id, "search_default_current": 1}
return result
project_compute_phases()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_long_term/wizard/project_compute_phases_view.xml b/addons/project_long_term/wizard/project_compute_phases_view.xml
index 69b7d94eabd..b6afc26276b 100644
--- a/addons/project_long_term/wizard/project_compute_phases_view.xml
+++ b/addons/project_long_term/wizard/project_compute_phases_view.xml
@@ -2,42 +2,42 @@
-
- Compute Scheduling of Phases
+
+ Schedule Phases
project.compute.phases
form
-
+
+
-
+
-
- Compute Phase Scheduling
- ir.actions.act_window
- project.compute.phases
- form
- form
-
- new
- To schedule phases of all or a specified project. It then open a gantt view.
-
-
+
+ Schedule Phases
+ ir.actions.act_window
+ project.compute.phases
+ form
+ form
+
+ new
+ To schedule phases of all or a specified project. It then open a gantt view.
+
+
-
+
diff --git a/addons/project_long_term/wizard/project_compute_tasks.py b/addons/project_long_term/wizard/project_compute_tasks.py
index a74cd07ddc6..24240f90a54 100644
--- a/addons/project_long_term/wizard/project_compute_tasks.py
+++ b/addons/project_long_term/wizard/project_compute_tasks.py
@@ -30,7 +30,7 @@ class project_compute_tasks(osv.osv_memory):
def compute_date(self, cr, uid, ids, context=None):
"""
- Schedule the tasks according to resource available and priority.
+ Schedule the tasks according to users and priority.
"""
project_pool = self.pool.get('project.project')
task_pool = self.pool.get('project.task')
diff --git a/addons/project_long_term/wizard/project_compute_tasks_view.xml b/addons/project_long_term/wizard/project_compute_tasks_view.xml
index e679110acdc..bf27e7e7286 100644
--- a/addons/project_long_term/wizard/project_compute_tasks_view.xml
+++ b/addons/project_long_term/wizard/project_compute_tasks_view.xml
@@ -2,39 +2,38 @@
-
- Compute Task Scheduling
+
+ Schedule Tasks
project.compute.tasks
form
-
-
+
-
- Compute Task Scheduling
- ir.actions.act_window
- project.compute.tasks
- form
- form
-
- new
-
+
+ Schedule Tasks
+ ir.actions.act_window
+ project.compute.tasks
+ form
+ form
+
+ new
+
-
+
diff --git a/addons/project_long_term/wizard/project_schedule_tasks.py b/addons/project_long_term/wizard/project_schedule_tasks.py
deleted file mode 100644
index d446ef20183..00000000000
--- a/addons/project_long_term/wizard/project_schedule_tasks.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-##############################################################################
-
-from osv import fields, osv
-
-class project_schedule_task(osv.osv_memory):
- _name = "project.schedule.tasks"
- _description = 'project.schedule.tasks'
- _columns = {
- 'msg': fields.char('Message', size=64)
- }
- _defaults = {
- 'msg': 'Task Scheduling Completed Successfully'
- }
-
- def default_get(self, cr, uid, fields_list, context=None):
- res = super(project_schedule_task, self).default_get(cr, uid, fields_list, context)
- self.compute_date(cr, uid, context=context)
- return res
-
- def compute_date(self, cr, uid, context=None):
- """
- Schedule the tasks according to resource available and priority.
- """
- phase_pool = self.pool.get('project.phase')
- if context is None:
- context = {}
- if not 'active_id' in context:
- return {'type': 'ir.actions.act_window_close'}
- return phase_pool.schedule_tasks(cr, uid, [context['active_id']], context=context)
-project_schedule_task()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_long_term/wizard/project_schedule_tasks_view.xml b/addons/project_long_term/wizard/project_schedule_tasks_view.xml
deleted file mode 100644
index f8e2f2d828b..00000000000
--- a/addons/project_long_term/wizard/project_schedule_tasks_view.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
- Schedule Tasks
- project.schedule.tasks
- form
-
-
-
-
-
-
-
-
-
-
-
-
-
- Schedule Tasks
- ir.actions.act_window
- project.schedule.tasks
- form
- form
-
- {'record_id': active_id}
- new
-
-
-
-
diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml
index 71bb002a284..69c283fd8de 100644
--- a/addons/purchase/purchase_view.xml
+++ b/addons/purchase/purchase_view.xml
@@ -246,7 +246,7 @@
-
+
@@ -282,7 +282,7 @@
-
+
diff --git a/addons/purchase_requisition/purchase_requisition_view.xml b/addons/purchase_requisition/purchase_requisition_view.xml
index 06ee94c3941..fdddb4b7fee 100644
--- a/addons/purchase_requisition/purchase_requisition_view.xml
+++ b/addons/purchase_requisition/purchase_requisition_view.xml
@@ -21,7 +21,7 @@
purchase.order
-
+
@@ -34,7 +34,7 @@
purchase.order
-
+
diff --git a/addons/resource/resource.py b/addons/resource/resource.py
index 932e9cd4855..f90a402946b 100644
--- a/addons/resource/resource.py
+++ b/addons/resource/resource.py
@@ -265,28 +265,20 @@ class resource_resource(osv.osv):
resource_objs = {}
user_pool = self.pool.get('res.users')
for user in user_pool.browse(cr, uid, user_ids, context=context):
+ resource_objs[user.id] = {
+ 'name' : user.name,
+ 'vacation': [],
+ 'efficiency': 1.0,
+ }
+
resource_ids = self.search(cr, uid, [('user_id', '=', user.id)], context=context)
- #assert len(resource_ids) < 1, "User should not has more than one resources"
- leaves = []
- resource_eff = 1.0
if resource_ids:
for resource in self.browse(cr, uid, resource_ids, context=context):
- resource_eff = resource.time_efficiency
+ resource_objs[user.id]['efficiency'] = resource.time_efficiency
resource_cal = resource.calendar_id.id
if resource_cal:
leaves = self.compute_vacation(cr, uid, calendar_id, resource.id, resource_cal, context=context)
- temp = {
- 'name' : resource.name,
- 'vacation': tuple(leaves),
- 'efficiency': resource_eff,
- }
- resource_objs[resource.id] = temp
-# resource_objs.append(classobj(str(user.name), (Resource,),{
-# '__doc__': user.name,
-# '__name__': user.name,
-# 'vacation': tuple(leaves),
-# 'efficiency': resource_eff,
-# }))
+ resource_objs[user.id]['vacation'] += list(leaves)
return resource_objs
def compute_vacation(self, cr, uid, calendar_id, resource_id=False, resource_calendar=False, context=None):
@@ -323,8 +315,8 @@ class resource_resource(osv.osv):
"""
if not calendar_id:
# Calendar is not specified: working days: 24/7
- return [('fri', '1:0-12:0','12:0-24:0'), ('thu', '1:0-12:0','12:0-24:0'), ('wed', '1:0-12:0','12:0-24:0'),
- ('mon', '1:0-12:0','12:0-24:0'), ('tue', '1:0-12:0','12:0-24:0'), ('sat', '1:0-12:0','12:0-24:0'), ('sun', '1:0-12:0','12:0-24:0')]
+ return [('fri', '8:0-12:0','13:0-17:0'), ('thu', '8:0-12:0','13:0-17:0'), ('wed', '8:0-12:0','13:0-17:0'),
+ ('mon', '8:0-12:0','13:0-17:0'), ('tue', '8:0-12:0','13:0-17:0')]
resource_attendance_pool = self.pool.get('resource.calendar.attendance')
time_range = "8:00-8:00"
non_working = ""
diff --git a/addons/sale_journal/sale_journal.py b/addons/sale_journal/sale_journal.py
index 136e7d68198..5a2004842cd 100644
--- a/addons/sale_journal/sale_journal.py
+++ b/addons/sale_journal/sale_journal.py
@@ -47,10 +47,10 @@ class res_partner(osv.osv):
'sale_journal.invoice.type',
type = 'many2one',
relation = 'sale_journal.invoice.type',
- string = "Invoicing Method",
+ string = "Invoicing Type",
view_load = True,
group_name = "Accounting Properties",
- help = "The type of journal used for sales and picking."),
+ help = "This invoicing type will be used, by default, for invoicing the current partner."),
}
res_partner()
diff --git a/addons/share/__openerp__.py b/addons/share/__openerp__.py
index f6a0c93285d..954f915c885 100644
--- a/addons/share/__openerp__.py
+++ b/addons/share/__openerp__.py
@@ -3,6 +3,7 @@
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL ().
+# Copyright (C) 2010-2011 OpenERP SA ().
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -22,7 +23,7 @@
{
"name" : "Web Share",
- "version" : "1.5",
+ "version" : "2.0",
"depends" : ["base", "mail"],
"author" : "OpenERP SA",
"category": 'Hidden',
@@ -53,6 +54,8 @@ synchronization with other companies, etc.
'installable': True,
'web': True,
'certificate' : '001301246528927038493',
+ 'js': ['static/src/js/share.js'],
+ 'css': ['static/src/css/share.css'],
'images': ['images/share_wizard.jpeg','images/sharing_wizard_step1.jpeg', 'images/sharing_wizard_step2.jpeg'],
}
diff --git a/addons/share/i18n/fi.po b/addons/share/i18n/fi.po
index 03ffccab983..25e6a026d54 100644
--- a/addons/share/i18n/fi.po
+++ b/addons/share/i18n/fi.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2011-01-11 11:16+0000\n"
-"PO-Revision-Date: 2011-06-13 06:18+0000\n"
-"Last-Translator: FULL NAME \n"
+"PO-Revision-Date: 2011-10-25 12:21+0000\n"
+"Last-Translator: Jussi Mikkola \n"
"Language-Team: Finnish \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-19 05:41+0000\n"
-"X-Generator: Launchpad (build 14157)\n"
+"X-Launchpad-Export-Date: 2011-10-26 05:13+0000\n"
+"X-Generator: Launchpad (build 14189)\n"
#. module: share
#: code:addons/share/web/editors.py:15
@@ -149,7 +149,7 @@ msgstr "Jako velho: vaihe 2"
#. module: share
#: view:share.wizard:0
msgid "Share wizard: step 0"
-msgstr "JJako velho: vaihe 0"
+msgstr ""
#. module: share
#: view:share.wizard:0
@@ -183,7 +183,7 @@ msgstr "Valmis"
#: field:share.wizard,user_ids:0
#: field:share.wizard.user,user_id:0
msgid "Users"
-msgstr ""
+msgstr "Käyttäjät"
#. module: share
#: code:addons/share/wizard/share_wizard.py:103
diff --git a/addons/share/static/src/css/share.css b/addons/share/static/src/css/share.css
new file mode 100644
index 00000000000..3b47a065b1e
--- /dev/null
+++ b/addons/share/static/src/css/share.css
@@ -0,0 +1,13 @@
+
+.openerp li.oe-share {
+ background: url(../img/share.png) no-repeat;
+ padding-left: 20px;
+}
+
+.openerp a.oe-share {
+ background: url(../img/share.png) no-repeat;
+ display: block;
+ float: left;
+ width: 20px;
+ height: 20px;
+}
diff --git a/addons/share/static/src/js/share.js b/addons/share/static/src/js/share.js
new file mode 100644
index 00000000000..6d02a39cf1f
--- /dev/null
+++ b/addons/share/static/src/js/share.js
@@ -0,0 +1,83 @@
+
+openerp.share = function(instance) {
+var QWeb = instance.web.qweb;
+QWeb.add_template('/share/static/src/xml/share.xml');
+
+function launch_wizard(self, view) {
+ var action = view.widget_parent.action;
+ var Share = new instance.web.DataSet(self, 'share.wizard', view.dataset.get_context());
+ var domain = view.dataset.domain;
+
+ if (view.fields_view.type == 'form') {
+ domain = new instance.web.CompoundDomain(domain, [['id', '=', view.datarecord.id]]);
+ }
+
+ Share.create({
+ name: action.name,
+ domain: domain,
+ action_id: action.id,
+ }, function(result) {
+ var share_id = result.result;
+ var step1 = Share.call('go_step_1', [[share_id],], function(result) {
+ var action = result;
+ self.do_action(action);
+ });
+ });
+}
+
+var _has_share = null;
+function if_has_share(yes, no) {
+ if (!_has_share) {
+ _has_share = $.Deferred(function() {
+ var self = this;
+ var session = instance.webclient.session;
+ session.on_session_invalid.add_last(function() { _has_share = null; });
+ var func = new instance.web.Model(session, "share.wizard").get_func("has_share");
+ func(session.uid).pipe(function(res) {
+ if(res) {
+ self.resolve();
+ } else {
+ self.reject();
+ }
+ });
+ });
+ }
+ _has_share.done(yes).fail(no);
+}
+
+
+instance.web.Sidebar = instance.web.Sidebar.extend({
+ add_default_sections: function() {
+ this._super();
+ var self = this;
+ if_has_share(function() {
+ self.add_items('other', [{
+ label: 'Share',
+ callback: self.on_sidebar_click_share,
+ classname: 'oe-share',
+ }]);
+ });
+ },
+ on_sidebar_click_share: function(item) {
+ var view = this.widget_parent
+ launch_wizard(this, view);
+ },
+});
+
+instance.web.ViewManagerAction.include({
+ start: function() {
+ var self = this;
+ if_has_share(function() {
+ self.$element.find('a.oe-share').click(self.on_click_share);
+ }, function() {
+ self.$element.find('a.oe-share').remove();
+ });
+ return this._super.apply(this, arguments);
+ },
+ on_click_share: function(e) {
+ e.preventDefault();
+ launch_wizard(this, this.views[this.active_view].controller);
+ },
+});
+
+};
diff --git a/addons/share/static/src/xml/share.xml b/addons/share/static/src/xml/share.xml
new file mode 100644
index 00000000000..9a1363846a0
--- /dev/null
+++ b/addons/share/static/src/xml/share.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/share/web/__init__.py b/addons/share/web/__init__.py
deleted file mode 100644
index f95bb222c10..00000000000
--- a/addons/share/web/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-import controllers
-import editors
\ No newline at end of file
diff --git a/addons/share/web/controllers.py b/addons/share/web/controllers.py
deleted file mode 100644
index e682c8d9709..00000000000
--- a/addons/share/web/controllers.py
+++ /dev/null
@@ -1,49 +0,0 @@
-import urlparse
-import cherrypy
-
-from openobject import rpc
-from openobject.tools import expose, ast
-
-import openerp.controllers
-
-
-
-class ShareWizardController(openerp.controllers.SecuredController):
- _cp_path = "/share"
-
- @expose()
- def index(self, domain, context, view_id, search_domain='[]', action_id=None):
- context = ast.literal_eval(context)
-
- if not action_id:
- # This should not be needed anymore, but just in case users are
- # running the module with an older version of the web client...
-
- # to remove soon-ish
- action_id = rpc.RPCProxy('ir.actions.act_window').search(
- [('view_id','=',int(view_id))], context=context)
- if not action_id: return ""
-
- action_id = action_id[0]
-
- domain = ast.literal_eval(domain)
- domain.extend(ast.literal_eval(search_domain))
-
- scheme, netloc, _, _, _ = urlparse.urlsplit(cherrypy.request.base)
- share_root_url = urlparse.urlunsplit((
- scheme, netloc, '/openerp/login',
- 'db=%(dbname)s&user=%(login)s&password=%(password)s', ''))
-
- context.update(
- #active_ids=share_wiz_id,
- #active_id=share_wiz_id[0],
- _terp_view_name='Share Wizard',
- share_root_url=share_root_url)
- Share = rpc.RPCProxy('share.wizard')
- sharing_view_id = Share.create({
- 'domain': str(domain),
- 'action_id': action_id and int(action_id)
- }, context)
- return openerp.controllers.actions.execute(
- Share.go_step_1([sharing_view_id], context),
- ids=[sharing_view_id], context=context)
diff --git a/addons/share/web/editors.py b/addons/share/web/editors.py
deleted file mode 100644
index 677de4a8317..00000000000
--- a/addons/share/web/editors.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# -*- coding: utf-8 -*-
-import openobject.templating
-
-class FormEditor(openobject.templating.TemplateEditor):
- templates = ['/openerp/controllers/templates/form.mako']
- MAIN_FORM_BODY = u'id="main_form_body"'
-
- def insert_share_button(self, output):
- # Insert the share button on the form title H1 line, at the very end,
- # but only if the user is a member of the sharing group
- share_opener_insertion = output.index('% endif', output.index(
- '/view_diagram/process',
- output.index(self.MAIN_FORM_BODY))) + len('% endif')
- return output[:share_opener_insertion] + '''
- <%
- if 'has_share' not in cp.session:
- cp.session['has_share'] = rpc.RPCProxy('share.wizard').has_share()
- %>
- % if cp.session['has_share'] and buttons.toolbar and not is_dashboard:
-
-
-
-
- \n
- % endif
-''' + output[share_opener_insertion:]
-
- def edit(self, template, template_text):
- return self.insert_share_button(
- super(FormEditor, self).edit(template, template_text))
-
-
-class SidebarEditor(openobject.templating.TemplateEditor):
- templates = ['/openerp/widgets/templates/sidebar.mako']
- ADD_SHARE_SECTION = u'id="sidebar"'
-
- def insert_share_link(self, output):
- # Insert the link on the line, right after the link to open the
- # attachment form, but only if the user is a member of the sharing group
- share_opener_insertion = output.index(
- '\n',
- output.index(self.ADD_SHARE_SECTION)) + 1
- return output[:share_opener_insertion] + '''
- <%
- if 'has_share' not in cp.session:
- cp.session['has_share'] = rpc.RPCProxy('share.wizard').has_share()
- %>
- % if cp.session['has_share']:
-
-
-
- \n
- % endif
-''' + output[share_opener_insertion:]
-
- def edit(self, template, template_text):
- return self.insert_share_link(
- super(SidebarEditor, self).edit(template, template_text))
diff --git a/addons/share/wizard/share_wizard.py b/addons/share/wizard/share_wizard.py
index b66ccc2dd47..1cd8104100c 100644
--- a/addons/share/wizard/share_wizard.py
+++ b/addons/share/wizard/share_wizard.py
@@ -119,24 +119,38 @@ class share_wizard(osv.osv_memory):
values['name'] = action.name
return super(share_wizard,self).create(cr, uid, values, context=context)
+ def share_url_template(self, cr, uid, _ids, context=None):
+ # NOTE: take _ids in parameter to allow usage through browse_record objects
+ base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='', context=context)
+ if base_url:
+ base_url += '/?db=%(dbname)s&login=%(login)s'
+ return base_url
+
+ def _share_root_url(self, cr, uid, ids, _fieldname, _args, context=None):
+ result = dict.fromkeys(ids, '')
+ data = dict(dbname=cr.dbname, login='')
+ for this in self.browse(cr, uid, ids, context=context):
+ result[this.id] = this.share_url_template() % data
+ return result
+
_columns = {
'action_id': fields.many2one('ir.actions.act_window', 'Action to share', required=True,
help="The action that opens the screen containing the data you wish to share."),
'domain': fields.char('Domain', size=256, help="Optional domain for further data filtering"),
- 'user_type': fields.selection(_user_type_selection,'Users to share with',
+ 'user_type': fields.selection(lambda s, *a, **k: s._user_type_selection(*a, **k),'Users to share with', required=True,
help="Select the type of user(s) you would like to share data with."),
'new_users': fields.text("Emails"),
'access_mode': fields.selection([('readonly','Can view'),('readwrite','Can edit')],'Access Mode', required=True,
help="Access rights to be granted on the shared documents."),
'result_line_ids': fields.one2many('share.wizard.result.line', 'share_wizard_id', 'Summary', readonly=True),
- 'share_root_url': fields.char('Share Access URL', size=512, readonly=True, tooltip='Main access page for users that are granted shared access'),
+ 'share_root_url': fields.function(_share_root_url, string='Share Access URL', type='char', size=512, readonly=True,
+ help='Main access page for users that are granted shared access'),
'name': fields.char('Share Title', size=64, required=True, help="Title for the share (displayed to users as menu and shortcut name)"),
'message': fields.text("Personal Message", help="An optional personal message, to be included in the e-mail notification."),
}
_defaults = {
- 'user_type' : 'new',
+ 'user_type' : 'emails',
'domain': lambda self, cr, uid, context, *a: context.get('domain', '[]'),
- 'share_root_url': lambda self, cr, uid, context, *a: context.get('share_root_url') or _('Please specify "share_root_url" in context'),
'action_id': lambda self, cr, uid, context, *a: context.get('action_id'),
'access_mode': 'readonly',
}
@@ -537,12 +551,11 @@ class share_wizard(osv.osv_memory):
try:
domain = safe_eval(wizard_data.domain)
if domain:
- domain_expr = expression.expression(domain)
for rel_field, model in fields_relations:
related_domain = []
if not rel_field: continue
for element in domain:
- if domain_expr._is_leaf(element):
+ if expression.is_leaf(element):
left, operator, right = element
left = '%s.%s'%(rel_field, left)
element = left, operator, right
@@ -555,19 +568,6 @@ class share_wizard(osv.osv_memory):
raise osv.except_osv(_('Sharing access could not be created'),
_('Sorry, the current screen and filter you are trying to share are not supported at the moment.\nYou may want to try a simpler filter.'))
- def _finish_result_lines(self, cr, uid, wizard_data, share_group_id, context=None):
- """Perform finalization of the share, and populate the summary"""
- share_root_url = wizard_data.share_root_url
- format_url = '%(dbname)s' in share_root_url
- for result in wizard_data.result_line_ids:
- # share_root_url may contain placeholders for dbname, login and password
- share_url = (share_root_url % \
- {'login': quote_plus(result.user_id.login),
- 'password': '', # kept empty for security reasons
- 'dbname': quote_plus(cr.dbname)}) \
- if format_url else share_root_url
- result.write({'share_url': share_url}, context=context)
-
def _check_preconditions(self, cr, uid, wizard_data, context=None):
self._assert(wizard_data.action_id and wizard_data.access_mode,
_('Action and Access Mode are required to create a shared access'),
@@ -662,15 +662,6 @@ class share_wizard(osv.osv_memory):
# C.
self._create_indirect_sharing_rules(cr, current_user, wizard_data, group_id, obj1, context=context)
- # so far, so good -> check summary results and return them
- self._finish_result_lines(cr, uid, wizard_data, group_id, context=context)
-
- # update share URL to make it generic
- generic_share_url = wizard_data.share_root_url % {'dbname': cr.dbname,
- 'login': '',
- 'password': ''}
- wizard_data.write({'share_root_url': generic_share_url}, context=context)
-
# refresh wizard_data
wizard_data = self.browse(cr, uid, ids[0], context=context)
@@ -742,11 +733,20 @@ share_wizard()
class share_result_line(osv.osv_memory):
_name = 'share.wizard.result.line'
_rec_name = 'user_id'
+
+
+ def _share_url(self, cr, uid, ids, _fieldname, _args, context=None):
+ result = dict.fromkeys(ids, '')
+ for this in self.browse(cr, uid, ids, context=context):
+ data = dict(dbname=cr.dbname, login=this.login)
+ result[this.id] = this.share_wizard_id.share_url_template() % data
+ return result
+
_columns = {
'user_id': fields.many2one('res.users', required=True, readonly=True),
'login': fields.related('user_id', 'login', string='Login', type='char', size=64, required=True, readonly=True),
'password': fields.char('Password', size=64, readonly=True),
- 'share_url': fields.char('Share URL', size=512, required=True),
+ 'share_url': fields.function(_share_url, string='Share URL', type='char', size=512),
'share_wizard_id': fields.many2one('share.wizard', 'Share Wizard', required=True),
'newly_created': fields.boolean('Newly created', readonly=True),
}
diff --git a/addons/share/wizard/share_wizard_view.xml b/addons/share/wizard/share_wizard_view.xml
index 5087b85d7bd..128b32b07da 100644
--- a/addons/share/wizard/share_wizard_view.xml
+++ b/addons/share/wizard/share_wizard_view.xml
@@ -29,6 +29,10 @@
form
+
+
+
+
@@ -78,7 +82,6 @@
- 'action_id' (id of action)
- 'domain' (string expression for full domain to apply as sent to server,
with dynamic data like 'uid' replaced by actual value (i.e. after eval)!)
- - 'share_root_url' : URL for direct access to share page (may include %(login)s and %(password)s placeholders)
-->
Share Wizard
@@ -94,7 +97,6 @@
- 'action_id' (id of action)
- 'domain' (string expression for full domain to apply as sent to server,
with dynamic data like 'uid' replaced by actual value (i.e. after eval)!)
- - 'share_root_url' : URL for direct access to share page (may include %(login)s and %(password)s placeholders)
-->
Share Wizard
diff --git a/addons/stock/product_view.xml b/addons/stock/product_view.xml
index 39d155b57d4..4205efd3efa 100644
--- a/addons/stock/product_view.xml
+++ b/addons/stock/product_view.xml
@@ -127,39 +127,33 @@
kanban
+
+
+
+
-
-
- |
- []
-
- |
-
-
- |
-
-
+
+
+
-
-
-
-
-
-
-
+ |
+
|
No Stock
On Hand , Available
- Public Price : , Cost :
+
+ Public Price : ,
+ Cost :
+
|
@@ -170,7 +164,7 @@
diff --git a/addons/stock_location/i18n/es_CL.po b/addons/stock_location/i18n/es_CL.po
new file mode 100644
index 00000000000..b6b2b458f1a
--- /dev/null
+++ b/addons/stock_location/i18n/es_CL.po
@@ -0,0 +1,594 @@
+# Spanish (Chile) translation for openobject-addons
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2011-01-11 11:16+0000\n"
+"PO-Revision-Date: 2011-10-24 19:30+0000\n"
+"Last-Translator: Francisco Reyes Acuña \n"
+"Language-Team: Spanish (Chile) \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-10-25 04:53+0000\n"
+"X-Generator: Launchpad (build 14185)\n"
+
+#. module: stock_location
+#: selection:product.pulled.flow,picking_type:0
+#: selection:stock.location.path,picking_type:0
+msgid "Sending Goods"
+msgstr "Envío de mercancías"
+
+#. module: stock_location
+#: view:product.product:0
+msgid "Pulled Paths"
+msgstr "Rutas arrastradas"
+
+#. module: stock_location
+#: selection:product.pulled.flow,type_proc:0
+msgid "Move"
+msgstr "Movimiento"
+
+#. module: stock_location
+#: model:ir.model,name:stock_location.model_stock_location_path
+msgid "Pushed Flows"
+msgstr "Flujos empujados"
+
+#. module: stock_location
+#: selection:stock.location.path,auto:0
+msgid "Automatic No Step Added"
+msgstr "Movimiento automático, paso no añadido"
+
+#. module: stock_location
+#: view:product.product:0
+msgid "Parameters"
+msgstr "Parámetros"
+
+#. module: stock_location
+#: field:stock.location.path,location_from_id:0
+msgid "Source Location"
+msgstr "Ubicación de origen"
+
+#. module: stock_location
+#: help:product.pulled.flow,cancel_cascade:0
+msgid "Allow you to cancel moves related to the product pull flow"
+msgstr ""
+"Le permite cancelar movimientos relacionados con el flujo de arrastre de "
+"producto."
+
+#. module: stock_location
+#: model:ir.model,name:stock_location.model_product_pulled_flow
+#: field:product.product,flow_pull_ids:0
+msgid "Pulled Flows"
+msgstr "Flujos arrastrados"
+
+#. module: stock_location
+#: constraint:stock.move:0
+msgid "You must assign a production lot for this product"
+msgstr "Debe asignar un lote de producción para este producto"
+
+#. module: stock_location
+#: help:product.pulled.flow,location_src_id:0
+msgid "Location used by Destination Location to supply"
+msgstr "Ubicación usada como destino al abastecer."
+
+#. module: stock_location
+#: selection:product.pulled.flow,picking_type:0
+#: selection:stock.location.path,picking_type:0
+msgid "Internal"
+msgstr "Interno"
+
+#. module: stock_location
+#: code:addons/stock_location/procurement_pull.py:98
+#, python-format
+msgid ""
+"Pulled procurement coming from original location %s, pull rule %s, via "
+"original Procurement %s (#%d)"
+msgstr ""
+"Abastecimiento arrastrado proveniente de la ubicación original %s, regla de "
+"arrastre %s, vía abastecimiento original %s (#%d)"
+
+#. module: stock_location
+#: model:ir.model,name:stock_location.model_stock_location
+msgid "Location"
+msgstr "Ubicación"
+
+#. module: stock_location
+#: field:product.pulled.flow,invoice_state:0
+#: field:stock.location.path,invoice_state:0
+msgid "Invoice Status"
+msgstr "Estado de facturación"
+
+#. module: stock_location
+#: help:product.pulled.flow,name:0
+msgid "This field will fill the packing Origin and the name of its moves"
+msgstr ""
+"Este campo rellenará el origen de la guiá de despacho y el nombre de sus "
+"movimientos."
+
+#. module: stock_location
+#: help:stock.location.path,auto:0
+msgid ""
+"This is used to define paths the product has to follow within the location "
+"tree.\n"
+"The 'Automatic Move' value will create a stock move after the current one "
+"that will be validated automatically. With 'Manual Operation', the stock "
+"move has to be validated by a worker. With 'Automatic No Step Added', the "
+"location is replaced in the original move."
+msgstr ""
+"Se utiliza para definir rutas que el producto debe seguir dentro del árbol "
+"de ubicaciones.\n"
+"La opción 'Movimiento automático' creará un movimiento de stock después del "
+"actual que se validará automáticamente. Con 'Operación manual', el "
+"movimiento de stock debe ser validado por un trabajador. Con 'Automático "
+"paso no añadido', la ubicación se reemplaza en el movimiento original."
+
+#. module: stock_location
+#: model:ir.module.module,shortdesc:stock_location.module_meta_information
+msgid "Warehouse Locations Paths"
+msgstr "Rutas en las ubicaciones de almacén"
+
+#. module: stock_location
+#: view:product.product:0
+msgid "Conditions"
+msgstr "Condiciones"
+
+#. module: stock_location
+#: model:stock.location,name:stock_location.location_pack_zone
+msgid "Pack Zone"
+msgstr "Zona de empaquetado"
+
+#. module: stock_location
+#: model:stock.location,name:stock_location.location_gate_b
+msgid "Gate B"
+msgstr "Puerta B"
+
+#. module: stock_location
+#: model:stock.location,name:stock_location.location_gate_a
+msgid "Gate A"
+msgstr "Puerta A"
+
+#. module: stock_location
+#: selection:product.pulled.flow,type_proc:0
+msgid "Buy"
+msgstr "Comprar"
+
+#. module: stock_location
+#: view:product.product:0
+msgid "Pushed flows"
+msgstr "Flujos empujados"
+
+#. module: stock_location
+#: model:stock.location,name:stock_location.location_dispatch_zone
+msgid "Dispatch Zone"
+msgstr "Zona de despacho"
+
+#. module: stock_location
+#: model:ir.model,name:stock_location.model_stock_move
+msgid "Stock Move"
+msgstr "Movimiento de stock"
+
+#. module: stock_location
+#: view:product.product:0
+msgid "Pulled flows"
+msgstr "Flujos arrastrados"
+
+#. module: stock_location
+#: field:product.pulled.flow,company_id:0
+#: field:stock.location.path,company_id:0
+msgid "Company"
+msgstr "Empresa"
+
+#. module: stock_location
+#: view:product.product:0
+msgid "Logistics Flows"
+msgstr "Flujos de logística"
+
+#. module: stock_location
+#: help:stock.move,cancel_cascade:0
+msgid "If checked, when this move is cancelled, cancel the linked move too"
+msgstr ""
+"Si está marcado, cuando este movimiento se cancela, también cancela el "
+"movimiento relacionado."
+
+#. module: stock_location
+#: selection:product.pulled.flow,type_proc:0
+msgid "Produce"
+msgstr "Producir"
+
+#. module: stock_location
+#: selection:product.pulled.flow,procure_method:0
+msgid "Make to Order"
+msgstr "Obtener bajo pedido"
+
+#. module: stock_location
+#: selection:product.pulled.flow,procure_method:0
+msgid "Make to Stock"
+msgstr "Obtener para stock"
+
+#. module: stock_location
+#: field:product.pulled.flow,partner_address_id:0
+msgid "Partner Address"
+msgstr "Dirección de empresa"
+
+#. module: stock_location
+#: selection:product.pulled.flow,invoice_state:0
+#: selection:stock.location.path,invoice_state:0
+msgid "To Be Invoiced"
+msgstr "Para facturar"
+
+#. module: stock_location
+#: help:stock.location.path,delay:0
+msgid "Number of days to do this transition"
+msgstr "Número de días para realizar esta transición"
+
+#. module: stock_location
+#: model:ir.module.module,description:stock_location.module_meta_information
+msgid ""
+"\n"
+"This module supplements the Warehouse application by adding support for per-"
+"product\n"
+"location paths, effectively implementing Push and Pull inventory flows.\n"
+"\n"
+"Typically this could be used to:\n"
+"* Manage product manufacturing chains\n"
+"* Manage default locations per product\n"
+"* Define routes within your warehouse according to business needs, such as:\n"
+" - Quality Control\n"
+" - After Sales Services\n"
+" - Supplier Returns\n"
+"* Help rental management, by generating automated return moves for rented "
+"products\n"
+"\n"
+"Once this module is installed, an additional tab appear on the product form, "
+"where you can add\n"
+"Push and Pull flow specifications. The demo data of CPU1 product for that "
+"push/pull :\n"
+"\n"
+"Push flows\n"
+"----------\n"
+"Push flows are useful when the arrival of certain products in a given "
+"location should always\n"
+"be followed by a corresponding move to another location, optionally after a "
+"certain delay.\n"
+"The original Warehouse application already supports such Push flow "
+"specifications on the\n"
+"Locations themselves, but these cannot be refined per-product.\n"
+"\n"
+"A push flow specification indicates which location is chained with which "
+"location, and with\n"
+"what parameters. As soon as a given quantity of products is moved in the "
+"source location,\n"
+"a chained move is automatically foreseen according to the parameters set on "
+"the flow specification\n"
+"(destination location, delay, type of move, journal, etc.) The new move can "
+"be automatically\n"
+"processed, or require a manual confirmation, depending on the parameters.\n"
+"\n"
+"Pull flows\n"
+"----------\n"
+"Pull flows are a bit different from Pull flows, in the sense that they are "
+"not related to\n"
+"the processing of product moves, but rather to the processing of procurement "
+"orders.\n"
+"What is being pulled is a need, not directly products.\n"
+"A classical example of Push flow is when you have an Outlet company, with a "
+"parent Company\n"
+"that is responsible for the supplies of the Outlet.\n"
+"\n"
+" [ Customer ] <- A - [ Outlet ] <- B - [ Holding ] <~ C ~ [ Supplier ]\n"
+"\n"
+"When a new procurement order (A, coming from the confirmation of a Sale "
+"Order for example) arrives\n"
+"in the Outlet, it is converted into another procurement (B, via a Push flow "
+"of type 'move')\n"
+"requested from the Holding. When procurement order B is processed by the "
+"Holding company, and\n"
+"if the product is out of stock, it can be converted into a Purchase Order "
+"(C) from the Supplier\n"
+"(Push flow of type Purchase). The result is that the procurement order, the "
+"need, is pushed\n"
+"all the way between the Customer and Supplier.\n"
+"\n"
+"Technically, Pull flows allow to process procurement orders differently, not "
+"only depending on\n"
+"the product being considered, but also depending on which location holds the "
+"\"need\" for that\n"
+"product (i.e. the destination location of that procurement order).\n"
+"\n"
+"Use-Case\n"
+"--------\n"
+"\n"
+"You can use the demo data as follow:\n"
+" CPU1: Sell some CPU1 from Shop 1 and run the scheduler\n"
+" - Warehouse: delivery order, Shop 1: reception\n"
+" CPU3:\n"
+" - When receiving the product, it goes to Quality Control location then "
+"stored to shelf 2.\n"
+" - When delivering the customer: Pick List -> Packing -> Delivery Order "
+"from Gate A\n"
+" "
+msgstr ""
+"\n"
+"Este módulo complementa la aplicación Almacén, añadiendo soporte para cada "
+"producto,\n"
+"ruta de ubicación, aplicación efectiva de flujos de inventario de Entrada y "
+"Salida.\n"
+"\n"
+"Normalmente, esto se podría utilizar para:\n"
+"* Gestión de las cadenas de fabricación de productos\n"
+"* Gestionar ubicaciones predeterminadas por producto\n"
+"* Definir las rutas dentro de su almacén de acuerdo a las necesidades "
+"empresariales, tales como:\n"
+" - Control de Calidad\n"
+" - Después de Servicios de Ventas\n"
+" - Proveedor Devoluciones\n"
+"* Gestión de Ayuda a la rentabilidad, mediante la generación de movimientos "
+"automáticos para productos alquilados\n"
+"\n"
+"Una vez que este módulo está instalado, aparecerá una ficha adicional en la "
+"pestaña del producto, donde se puede añadir\n"
+"las especificaciones del flujo de Entrada y de Salida. Los datos de "
+"demostración del producto CPU1 para esos flujos de entrada/salida:\n"
+"\n"
+"Flujos de Entrada\n"
+"----------\n"
+"Los flujos de entrada son útiles cuando la llegada de determinados productos "
+"a un lugar determinado siempre\n"
+"va seguida de un movimiento que corresponde a otra ubicación, opcionalmente "
+"después de un cierto retraso.\n"
+"La aplicación Almacén original ya soporta tales especificaciones del flujo "
+"de entrada en sus Ubicaciones, pero estas no pueden ser refinadas por "
+"producto.\n"
+"\n"
+"Una especificación de flujo de entrada indica qué ubicación está encadenada "
+"con qué ubicación, y con\n"
+"qué parámetros. Tan pronto como una cantidad determinada de productos se "
+"mueve de la ubicación de origen,\n"
+"un movimiento encadenado de forma automática configurado de acuerdo con los "
+"parámetros establecidos en la especificación del flujo\n"
+"(lugar de destino, demora, tipo de movimiento, diarios, etc) se dispara. El "
+"nuevo movimiento puede ser automáticamente\n"
+"procesado, o requerir una confirmación manual, dependiendo de los "
+"parámetros.\n"
+"\n"
+"Flujos de Salida\n"
+"----------\n"
+"Los flujos de salida son un poco diferentes de los flujos de entrada, en el "
+"sentido de que no están relacionados con\n"
+"la tramitación de movimientos de productos, sino más bien con el tratamiento "
+"de los pedidos de venta.\n"
+"Lo que se saca es una necesidad, no directamente los productos.\n"
+"Un ejemplo clásico de flujo de salida es cuando usted tiene una empresa de "
+"Outlet, con una empresa padre\n"
+"que es la responsable de los suministros del Outlet.\n"
+"\n"
+" [cliente] <- A - [Outlet] <- B - [Suministrador] <~ C ~ [Proveedor]\n"
+"\n"
+"Cuando una nueva orden de compra (A, procedente de la confirmación de una "
+"orden de venta por ejemplo) llega al Outlet, se convierte en otra compra (B, "
+"a través de un flujo de entrada del tipo 'mover')\n"
+"solicitada desde el socio. Cuando el orden de compa para B es procesado por "
+"la empresa socia, y\n"
+"si el producto está agotado, puede convertirse en una Orden de Compra (C) "
+"del Proveedor\n"
+"(flujo de Entrada de tipo Compra). El resultado es que el orden de "
+"adquisición, la necesidad, se traslada automáticamente del Cliente al "
+"Proveedor.\n"
+"\n"
+"Técnicamente, los flujos de Salida permiten procesar los pedidos de "
+"adquisición de otra manera, no sólo en función del producto considerado, "
+"sino también en función de qué ubicación tiene la \"necesidad\" de qué\n"
+"producto (es decir, la ubicación de destino de esa orden de compra).\n"
+"\n"
+"Caso de Uso\n"
+"---------------\n"
+"\n"
+"Puede utilizar los datos de demostración de la siguiente manera:\n"
+" CPU1: Venta de algunas CPU1 en la tienda 1 y ejecutar el planificador\n"
+" - Almacén: órden de entrega, Tienda 1: Recepción\n"
+" CPU3:\n"
+" - Al recibir el producto, va al Control de Calidad y se almacena en la "
+"plataforma 2.\n"
+" - Cuando se entrega al cliente: Lista de Selección -> Embalaje -> Orden "
+"de Entrega desde la puerta A\n"
+" "
+
+#. module: stock_location
+#: field:product.pulled.flow,type_proc:0
+msgid "Type of Procurement"
+msgstr "Tipo de abastecimiento"
+
+#. module: stock_location
+#: help:product.pulled.flow,company_id:0
+msgid "Is used to know to which company belong packings and moves"
+msgstr ""
+"Se usa para saber a que compañía pertenece las guias de despacho y "
+"movimientos."
+
+#. module: stock_location
+#: field:product.pulled.flow,name:0
+msgid "Name"
+msgstr "Nombre"
+
+#. module: stock_location
+#: help:product.product,path_ids:0
+msgid ""
+"These rules set the right path of the product in the whole location tree."
+msgstr ""
+"Estas reglas fijan la ruta correcta del producto en todo el árbol de "
+"ubicaciones."
+
+#. module: stock_location
+#: selection:stock.location.path,auto:0
+msgid "Manual Operation"
+msgstr "Operación manual"
+
+#. module: stock_location
+#: model:ir.model,name:stock_location.model_product_product
+#: field:product.pulled.flow,product_id:0
+msgid "Product"
+msgstr "Producto"
+
+#. module: stock_location
+#: field:product.pulled.flow,procure_method:0
+msgid "Procure Method"
+msgstr "Método abastecimiento"
+
+#. module: stock_location
+#: field:product.pulled.flow,picking_type:0
+#: field:stock.location.path,picking_type:0
+msgid "Shipping Type"
+msgstr "Tipo de envío"
+
+#. module: stock_location
+#: help:product.pulled.flow,procure_method:0
+msgid ""
+"'Make to Stock': When needed, take from the stock or wait until re-"
+"supplying. 'Make to Order': When needed, purchase or produce for the "
+"procurement request."
+msgstr ""
+"'Obtener para stock': Cuando sea necesario, coger del stock o esperar hasta "
+"que sea reabastecido. 'Obtener bajo pedido': Cuando sea necesario, comprar o "
+"producir para la petición de abastecimiento."
+
+#. module: stock_location
+#: help:product.pulled.flow,location_id:0
+msgid "Is the destination location that needs supplying"
+msgstr "Es la ubicación destino que necesita suministro."
+
+#. module: stock_location
+#: field:stock.location.path,product_id:0
+msgid "Products"
+msgstr "Productos"
+
+#. module: stock_location
+#: code:addons/stock_location/procurement_pull.py:118
+#, python-format
+msgid "Pulled from another location via procurement %d"
+msgstr "Arrastrado desde otra ubicación vía abastecimiento %d"
+
+#. module: stock_location
+#: model:stock.location,name:stock_location.stock_location_qualitytest0
+msgid "Quality Control"
+msgstr "Control de calidad"
+
+#. module: stock_location
+#: selection:product.pulled.flow,invoice_state:0
+#: selection:stock.location.path,invoice_state:0
+msgid "Not Applicable"
+msgstr "No Aplicable"
+
+#. module: stock_location
+#: field:stock.location.path,delay:0
+msgid "Delay (days)"
+msgstr "Retraso (días)"
+
+#. module: stock_location
+#: code:addons/stock_location/procurement_pull.py:67
+#, python-format
+msgid ""
+"Picking for pulled procurement coming from original location %s, pull rule "
+"%s, via original Procurement %s (#%d)"
+msgstr ""
+"Guía de despacho para abastecimiento arrastrado proveniente de la ubicación "
+"original %s, regla de arrastre %s, vía abastecimiento original %s (#%d)"
+
+#. module: stock_location
+#: field:product.product,path_ids:0
+msgid "Pushed Flow"
+msgstr "Flujo empujado"
+
+#. module: stock_location
+#: code:addons/stock_location/procurement_pull.py:89
+#, python-format
+msgid ""
+"Move for pulled procurement coming from original location %s, pull rule %s, "
+"via original Procurement %s (#%d)"
+msgstr ""
+"Movimiento para abastecimiento arrastrado proveniente de la ubicación "
+"original %s, regla de arrastre %s, vía abastecimiento original %s (#%d)"
+
+#. module: stock_location
+#: constraint:stock.move:0
+msgid "You try to assign a lot which is not from the same product"
+msgstr "Está intentando asignar un lote que no es del mismo producto"
+
+#. module: stock_location
+#: model:ir.model,name:stock_location.model_procurement_order
+msgid "Procurement"
+msgstr "Abastecimiento"
+
+#. module: stock_location
+#: field:stock.location.path,location_dest_id:0
+msgid "Destination Location"
+msgstr "Ubicación de destino"
+
+#. module: stock_location
+#: field:stock.location.path,auto:0
+#: selection:stock.location.path,auto:0
+msgid "Automatic Move"
+msgstr "Movimiento automático"
+
+#. module: stock_location
+#: selection:product.pulled.flow,picking_type:0
+#: selection:stock.location.path,picking_type:0
+msgid "Getting Goods"
+msgstr "Recepción mercancías"
+
+#. module: stock_location
+#: view:product.product:0
+msgid "Action Type"
+msgstr "Tipo de acción"
+
+#. module: stock_location
+#: constraint:product.product:0
+msgid "Error: Invalid ean code"
+msgstr "Error: Código EAN no válido"
+
+#. module: stock_location
+#: help:product.pulled.flow,picking_type:0
+#: help:stock.location.path,picking_type:0
+msgid ""
+"Depending on the company, choose whatever you want to receive or send "
+"products"
+msgstr "Según la compañía, seleccionar si desea recibir o enviar productos."
+
+#. module: stock_location
+#: model:stock.location,name:stock_location.location_order
+msgid "Order Processing"
+msgstr "Procesando pedido"
+
+#. module: stock_location
+#: field:stock.location.path,name:0
+msgid "Operation"
+msgstr "Operación"
+
+#. module: stock_location
+#: view:product.product:0
+#: field:product.product,path_ids:0
+#: view:stock.location.path:0
+msgid "Location Paths"
+msgstr "Rutas de ubicaciones"
+
+#. module: stock_location
+#: field:product.pulled.flow,journal_id:0
+#: field:stock.location.path,journal_id:0
+msgid "Journal"
+msgstr "Diario"
+
+#. module: stock_location
+#: field:product.pulled.flow,cancel_cascade:0
+#: field:stock.move,cancel_cascade:0
+msgid "Cancel Cascade"
+msgstr "Cancelar cascada"
+
+#. module: stock_location
+#: selection:product.pulled.flow,invoice_state:0
+#: selection:stock.location.path,invoice_state:0
+msgid "Invoiced"
+msgstr "Facturado"
diff --git a/addons/stock_no_autopicking/i18n/es_CL.po b/addons/stock_no_autopicking/i18n/es_CL.po
new file mode 100644
index 00000000000..98a3c002c30
--- /dev/null
+++ b/addons/stock_no_autopicking/i18n/es_CL.po
@@ -0,0 +1,83 @@
+# Spanish (Chile) translation for openobject-addons
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2011-01-03 16:58+0000\n"
+"PO-Revision-Date: 2011-10-24 19:35+0000\n"
+"Last-Translator: Francisco Reyes Acuña \n"
+"Language-Team: Spanish (Chile) \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-10-25 04:53+0000\n"
+"X-Generator: Launchpad (build 14185)\n"
+
+#. module: stock_no_autopicking
+#: model:ir.model,name:stock_no_autopicking.model_product_product
+msgid "Product"
+msgstr "Producto"
+
+#. module: stock_no_autopicking
+#: model:ir.module.module,description:stock_no_autopicking.module_meta_information
+msgid ""
+"\n"
+" This module allows an intermediate picking process to provide raw "
+"materials\n"
+" to production orders.\n"
+"\n"
+" One example of usage of this module is to manage production made by "
+"your\n"
+" suppliers (sub-contracting). To achieve this, set the assembled product\n"
+" which is sub-contracted to \"No Auto-Picking\" and put the location of "
+"the\n"
+" supplier in the routing of the assembly operation.\n"
+" "
+msgstr ""
+"\n"
+" Este módulo permite un proceso de recogida intermedio para proveer "
+"materias\n"
+" primas a las órdenes de fabricación.\n"
+"\n"
+" Un ejemplo de uso de este módulo es gestionar la producción realizada "
+"por sus\n"
+" proveedores (subcontratación). Para conseguir esto, establezca los "
+"productos ensamblados\n"
+" que serán subcontratados a \"No Auto-Recogida\" y establezca la "
+"ubicación del nuevo\n"
+" proveedor en el proceso de la operación de ensamblado.\n"
+" "
+
+#. module: stock_no_autopicking
+#: model:ir.model,name:stock_no_autopicking.model_mrp_production
+msgid "Manufacturing Order"
+msgstr "Orden de fabricación"
+
+#. module: stock_no_autopicking
+#: field:product.product,auto_pick:0
+msgid "Auto Picking"
+msgstr "Auto empaquetado"
+
+#. module: stock_no_autopicking
+#: help:product.product,auto_pick:0
+msgid "Auto picking for raw materials of production orders."
+msgstr "Auto empaquetado para materiales a granel en órdenes de producción."
+
+#. module: stock_no_autopicking
+#: constraint:product.product:0
+msgid "Error: Invalid ean code"
+msgstr "Error: Código EAN no válido"
+
+#. module: stock_no_autopicking
+#: model:ir.module.module,shortdesc:stock_no_autopicking.module_meta_information
+msgid "Stock No Auto-Picking"
+msgstr "Stock no auto empaquetado"
+
+#. module: stock_no_autopicking
+#: constraint:mrp.production:0
+msgid "Order quantity cannot be negative or zero !"
+msgstr "¡La cantidad ordenada no puede ser negativa o cero!"
diff --git a/addons/stock_planning/i18n/es_CL.po b/addons/stock_planning/i18n/es_CL.po
new file mode 100644
index 00000000000..9e876116a3a
--- /dev/null
+++ b/addons/stock_planning/i18n/es_CL.po
@@ -0,0 +1,1861 @@
+# Spanish (Chile) translation for openobject-addons
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2011-01-11 11:16+0000\n"
+"PO-Revision-Date: 2011-10-24 20:18+0000\n"
+"Last-Translator: Francisco Reyes Acuña \n"
+"Language-Team: Spanish (Chile) \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-10-25 04:53+0000\n"
+"X-Generator: Launchpad (build 14185)\n"
+
+#. module: stock_planning
+#: code:addons/stock_planning/wizard/stock_planning_createlines.py:73
+#, python-format
+msgid ""
+"No forecasts for selected period or no products in selected category !"
+msgstr ""
+"¡No hay previsiones para el periodo seleccionado o no hay productos en la "
+"categoría seleccionada!"
+
+#. module: stock_planning
+#: help:stock.planning,stock_only:0
+msgid ""
+"Check to calculate stock location of selected warehouse only. If not "
+"selected calculation is made for input, stock and output location of "
+"warehouse."
+msgstr ""
+"Marque esta opción para calcular el stock sólo de la ubicación stock del "
+"almacén seleccionado. Si no se marca, el cálculo se realiza para las "
+"ubicaciones de entrada, stock y salida del almacén."
+
+#. module: stock_planning
+#: field:stock.planning,maximum_op:0
+msgid "Maximum Rule"
+msgstr "Regla máximo"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period1_per_company:0
+msgid "This Copmany Period1"
+msgstr "Esta compañía período1"
+
+#. module: stock_planning
+#: view:stock.planning:0
+#: view:stock.sale.forecast:0
+msgid "Group By..."
+msgstr "Agrupar por..."
+
+#. module: stock_planning
+#: help:stock.sale.forecast,product_amt:0
+msgid ""
+"Forecast value which will be converted to Product Quantity according to "
+"prices."
+msgstr ""
+"Valor de la previsión que será convertido en cantidad de producto en función "
+"de precios."
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:621
+#: code:addons/stock_planning/stock_planning.py:663
+#, python-format
+msgid "Incoming Left must be greater than 0 !"
+msgstr "¡Entradas restantes debe ser mayor que 0!"
+
+#. module: stock_planning
+#: help:stock.planning,outgoing_before:0
+msgid ""
+"Planned Out in periods before calculated. Between start date of current "
+"period and one day before start of calculated period."
+msgstr ""
+"Salidas planificadas en periodos anteriores al calculado. Entre la fecha de "
+"inicio del periodo actual y un día antes del comienzo del periodo calculado."
+
+#. module: stock_planning
+#: code:addons/stock_planning/wizard/stock_planning_forecast.py:60
+#, python-format
+msgid "No products in selected category !"
+msgstr "¡No hay productos en la categoría seleccionada!"
+
+#. module: stock_planning
+#: help:stock.sale.forecast.createlines,warehouse_id:0
+msgid ""
+"Warehouse which forecasts will concern. If during stock planning you will "
+"need sales forecast for all warehouses choose any warehouse now."
+msgstr ""
+"Almacén al que conciernen las previsiones. Si durante la planificación de "
+"stock necesita previsiones de ventas para todos los almacenes escoja ahora "
+"un almacén cualquiera."
+
+#. module: stock_planning
+#: field:stock.planning,outgoing_left:0
+msgid "Expected Out"
+msgstr "Salidas previstas"
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid " "
+msgstr " "
+
+#. module: stock_planning
+#: field:stock.planning,incoming_left:0
+msgid "Incoming Left"
+msgstr "Entradas restantes"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Requisition history"
+msgstr "Historial demandas"
+
+#. module: stock_planning
+#: view:stock.sale.forecast.createlines:0
+msgid "Create Forecasts Lines"
+msgstr "Crear líneas de previsiones"
+
+#. module: stock_planning
+#: help:stock.planning,outgoing:0
+msgid "Quantity of all confirmed outgoing moves in calculated Period."
+msgstr "Cantidades de todas las salidas confirmadas en el periodo calculado."
+
+#. module: stock_planning
+#: view:stock.period.createlines:0
+msgid "Create Daily Periods"
+msgstr "Crear periodos diarios"
+
+#. module: stock_planning
+#: view:stock.planning:0
+#: field:stock.planning,company_id:0
+#: field:stock.planning.createlines,company_id:0
+#: view:stock.sale.forecast:0
+#: field:stock.sale.forecast,company_id:0
+#: field:stock.sale.forecast.createlines,company_id:0
+msgid "Company"
+msgstr "Compañía"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:640
+#: code:addons/stock_planning/stock_planning.py:682
+#, python-format
+msgid ""
+"\n"
+" Initial Stock: "
+msgstr ""
+"\n"
+" Stock inicial: "
+
+#. module: stock_planning
+#: help:stock.planning,warehouse_forecast:0
+msgid ""
+"All sales forecasts for selected Warehouse of selected Product during "
+"selected Period."
+msgstr ""
+"Todas las previsiones de ventas para el almacén seleccionado del producto "
+"seleccionado durante el periodo seleccionado."
+
+#. module: stock_planning
+#: model:ir.ui.menu,name:stock_planning.menu_stock_period_creatlines
+msgid "Create Stock and Sales Periods"
+msgstr "Crear periodos de stock y ventas"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Minimum Stock Rule Indicators"
+msgstr "Indicadores de reglas de stock mínimo"
+
+#. module: stock_planning
+#: help:stock.sale.forecast.createlines,period_id:0
+msgid "Period which forecasts will concern."
+msgstr "Periodo al que conciernen las previsiones."
+
+#. module: stock_planning
+#: field:stock.planning,stock_only:0
+msgid "Stock Location Only"
+msgstr "Sólo ubicaciones de stock"
+
+#. module: stock_planning
+#: help:stock.planning,already_out:0
+msgid ""
+"Quantity which is already dispatched out of this warehouse in current period."
+msgstr ""
+"Cantidades que ya se enviaron fuera de este almacén en el período actual."
+
+#. module: stock_planning
+#: help:stock.planning,procure_to_stock:0
+msgid ""
+"Chect to make procurement to stock location of selected warehouse. If not "
+"selected procurement will be made into input location of warehouse."
+msgstr ""
+"Marque esta opción para realizar los abastecimientos en la ubicación stock "
+"del almacén seleccionado. Si no se marca, el abastecimiento se realizará en "
+"la ubicación de entrada del almacén."
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Current Period Situation"
+msgstr "Situación del periodo actual"
+
+#. module: stock_planning
+#: view:stock.period.createlines:0
+msgid "Create Monthly Periods"
+msgstr "Crear períodos mensuales"
+
+#. module: stock_planning
+#: help:stock.planning,supply_warehouse_id:0
+msgid ""
+"Warehouse used as source in supply pick move created by 'Supply from Another "
+"Warhouse'."
+msgstr ""
+"Almacén usado como origen en el movimiento de suministro creado por "
+"'Suministrar desde otro almacén'."
+
+#. module: stock_planning
+#: model:ir.model,name:stock_planning.model_stock_period_createlines
+msgid "stock.period.createlines"
+msgstr "stock.periodo.crearlíneas"
+
+#. module: stock_planning
+#: field:stock.planning,outgoing_before:0
+msgid "Planned Out Before"
+msgstr "Salidas planificadas antes"
+
+#. module: stock_planning
+#: field:stock.planning.createlines,forecasted_products:0
+msgid "All Products with Forecast"
+msgstr "Todos los productos con previsión"
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid "Periods :"
+msgstr "Periodos :"
+
+#. module: stock_planning
+#: help:stock.planning,already_in:0
+msgid ""
+"Quantity which is already picked up to this warehouse in current period."
+msgstr ""
+"Cantidades que ya han sido recogidas en este almacén en el periodo actual."
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:644
+#: code:addons/stock_planning/stock_planning.py:686
+#, python-format
+msgid " Confirmed In Before: "
+msgstr " Entradas confirmadas antes: "
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid "Stock and Sales Forecast"
+msgstr "Previsiones de stock y ventas"
+
+#. module: stock_planning
+#: model:ir.model,name:stock_planning.model_stock_sale_forecast
+msgid "stock.sale.forecast"
+msgstr "stock.ventas.prevision"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_dept_id:0
+msgid "This Department"
+msgstr "Este departamento"
+
+#. module: stock_planning
+#: field:stock.planning,to_procure:0
+msgid "Planned In"
+msgstr "Entradas planificadas"
+
+#. module: stock_planning
+#: field:stock.planning,stock_simulation:0
+msgid "Stock Simulation"
+msgstr "Simulación de stock"
+
+#. module: stock_planning
+#: model:ir.model,name:stock_planning.model_stock_planning_createlines
+msgid "stock.planning.createlines"
+msgstr "stock.planificación.crearlíneas"
+
+#. module: stock_planning
+#: help:stock.planning,incoming_before:0
+msgid ""
+"Confirmed incoming in periods before calculated (Including Already In). "
+"Between start date of current period and one day before start of calculated "
+"period."
+msgstr ""
+"Entradas confirmadas en periodos anteriores al calculado (incluyendo las "
+"entradas realizadas). Entre la fecha de inicio del periodo actual y un día "
+"antes del comienzo del periodo calculado."
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid "Search Sales Forecast"
+msgstr "Buscar previsiones de ventas"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period5_per_user:0
+msgid "This User Period5"
+msgstr "El periodo de este usuario5"
+
+#. module: stock_planning
+#: help:stock.planning,history:0
+msgid "History of procurement or internal supply of this planning line."
+msgstr ""
+"Historial de abastecimiento o suministro interno de esta línea de "
+"planificación."
+
+#. module: stock_planning
+#: help:stock.planning,company_forecast:0
+msgid ""
+"All sales forecasts for whole company (for all Warehouses) of selected "
+"Product during selected Period."
+msgstr ""
+"Todas las previsiones para la compañía entera (para todos los almacenes) del "
+"producto seleccionado durante el periodo seleccionado."
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period1_per_user:0
+msgid "This User Period1"
+msgstr "El periodo de este usuario1"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period3_per_user:0
+msgid "This User Period3"
+msgstr "El periodo de este usuario3"
+
+#. module: stock_planning
+#: model:ir.ui.menu,name:stock_planning.menu_stock_planning_main
+#: view:stock.planning:0
+msgid "Stock Planning"
+msgstr "Planificación de stock"
+
+#. module: stock_planning
+#: field:stock.planning,minimum_op:0
+msgid "Minimum Rule"
+msgstr "Regla de mínimos"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Procure Incoming Left"
+msgstr "Entradas abastecimiento restante"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:646
+#: code:addons/stock_planning/stock_planning.py:688
+#, python-format
+msgid " Incoming Left: "
+msgstr " Entradas restante: "
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:719
+#, python-format
+msgid "%s Pick List %s (%s, %s) %s %s \n"
+msgstr "%s Lista de selección %s (%s, %s) %s %s \n"
+
+#. module: stock_planning
+#: view:stock.planning.createlines:0
+#: view:stock.sale.forecast.createlines:0
+msgid "Create"
+msgstr "Crear"
+
+#. module: stock_planning
+#: model:ir.actions.act_window,name:stock_planning.action_view_stock_planning_form
+#: model:ir.module.module,shortdesc:stock_planning.module_meta_information
+#: model:ir.ui.menu,name:stock_planning.menu_stock_planning
+#: view:stock.planning:0
+msgid "Master Procurement Schedule"
+msgstr "Plan maestro de abastecimiento"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:636
+#: code:addons/stock_planning/stock_planning.py:678
+#, python-format
+msgid " Creation Date: "
+msgstr " Fecha de creación: "
+
+#. module: stock_planning
+#: field:stock.planning,period_id:0
+#: field:stock.planning.createlines,period_id:0
+#: field:stock.sale.forecast,period_id:0
+#: field:stock.sale.forecast.createlines,period_id:0
+msgid "Period"
+msgstr "Período"
+
+#. module: stock_planning
+#: view:stock.period:0
+#: field:stock.period,state:0
+#: field:stock.planning,state:0
+#: field:stock.sale.forecast,state:0
+msgid "State"
+msgstr "Estado"
+
+#. module: stock_planning
+#: help:stock.sale.forecast.createlines,product_categ_id:0
+msgid "Product Category of products which created forecasts will concern."
+msgstr "Categoría de los productos cuyas previsiones se crearán."
+
+#. module: stock_planning
+#: model:ir.model,name:stock_planning.model_stock_period
+msgid "stock period"
+msgstr "periodo stock"
+
+#. module: stock_planning
+#: model:ir.model,name:stock_planning.model_stock_sale_forecast_createlines
+msgid "stock.sale.forecast.createlines"
+msgstr "stock.venta.previsión.crearlíneas"
+
+#. module: stock_planning
+#: field:stock.planning,warehouse_id:0
+#: field:stock.planning.createlines,warehouse_id:0
+#: field:stock.sale.forecast,warehouse_id:0
+#: field:stock.sale.forecast.createlines,warehouse_id:0
+msgid "Warehouse"
+msgstr "Almacén"
+
+#. module: stock_planning
+#: help:stock.planning,stock_simulation:0
+msgid ""
+"Stock simulation at the end of selected Period.\n"
+" For current period it is: \n"
+"Initial Stock - Already Out + Already In - Expected Out + Incoming Left.\n"
+"For periods ahead it is: \n"
+"Initial Stock - Planned Out Before + Incoming Before - Planned Out + Planned "
+"In."
+msgstr ""
+"Simulación de stock al final del período seleccionado.\n"
+" Para el periodo actual es: \n"
+"Stock inicial – salidas + entradas – salidas previstas + entradas "
+"esperadas.\n"
+" Para los siguientes periodos es: \n"
+"Stock inicial – salidas previstas anteriores + entradas anteriores – salidas "
+"previstas + entradas previstas."
+
+#. module: stock_planning
+#: help:stock.sale.forecast,analyze_company:0
+msgid "Check this box to see the sales for whole company."
+msgstr "Seleccione esta casilla para ver las ventas de todda la compañía."
+
+#. module: stock_planning
+#: field:stock.sale.forecast,name:0
+msgid "Name"
+msgstr "Nombre"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Search Stock Planning"
+msgstr "Buscar planificación de stock"
+
+#. module: stock_planning
+#: field:stock.planning,incoming_before:0
+msgid "Incoming Before"
+msgstr "Entradas antes"
+
+#. module: stock_planning
+#: field:stock.planning.createlines,product_categ_id:0
+#: field:stock.sale.forecast.createlines,product_categ_id:0
+msgid "Product Category"
+msgstr "Categoría del producto"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:621
+#: code:addons/stock_planning/stock_planning.py:663
+#: code:addons/stock_planning/stock_planning.py:665
+#: code:addons/stock_planning/stock_planning.py:667
+#: code:addons/stock_planning/wizard/stock_planning_createlines.py:73
+#: code:addons/stock_planning/wizard/stock_planning_forecast.py:60
+#, python-format
+msgid "Error !"
+msgstr "¡ Error !"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:626
+#, python-format
+msgid "Manual planning for %s"
+msgstr "Manual para la planificación de %s"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_user_id:0
+msgid "This User"
+msgstr "Este usuario"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:643
+#: code:addons/stock_planning/stock_planning.py:685
+#, python-format
+msgid ""
+"\n"
+" Confirmed Out: "
+msgstr ""
+"\n"
+" Salidas confirmadas: "
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Forecasts"
+msgstr "Previsiones"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Supply from Another Warehouse"
+msgstr "Abastecer desde otro almacén"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Calculate Planning"
+msgstr "Calcular planificación"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:636
+#, python-format
+msgid ""
+" Procurement created in MPS by user: %s Creation Date: %s "
+" \n"
+" For period: %s \n"
+" according to state: \n"
+" Warehouse Forecast: %s \n"
+" Initial Stock: %s \n"
+" Planned Out: %s Planned In: %s \n"
+" Already Out: %s Already In: %s \n"
+" Confirmed Out: %s Confirmed In: %s "
+" \n"
+" Planned Out Before: %s Confirmed In Before: %s "
+" \n"
+" Expected Out: %s Incoming Left: %s "
+" \n"
+" Stock Simulation: %s Minimum stock: %s"
+msgstr ""
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:140
+#, python-format
+msgid "Invalid action !"
+msgstr "¡Acción no válida!"
+
+#. module: stock_planning
+#: help:stock.planning,stock_start:0
+msgid "Stock quantity one day before current period."
+msgstr "Cantidad stock un día antes del periodo actual."
+
+#. module: stock_planning
+#: view:stock.period.createlines:0
+msgid "Create Weekly Periods"
+msgstr "Crear periodos semanales"
+
+#. module: stock_planning
+#: help:stock.planning,maximum_op:0
+msgid "Maximum quantity set in Minimum Stock Rules for this Warhouse"
+msgstr ""
+"Cantidad máxima establecida en las reglas de stock mínimo para este almacén."
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:665
+#, python-format
+msgid "You must specify a Source Warehouse !"
+msgstr "¡Debe especificar un almacén de origen!"
+
+#. module: stock_planning
+#: view:stock.planning.createlines:0
+msgid "Creates planning lines for selected period and warehouse."
+msgstr ""
+"Crea líneas de planificación para el periodo y almacén seleccionados."
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period4_per_user:0
+msgid "This User Period4"
+msgstr "Este periodo de usuario4"
+
+#. module: stock_planning
+#: view:stock.planning.createlines:0
+#: view:stock.sale.forecast.createlines:0
+msgid "Note: Doesn't duplicate existing lines created by you."
+msgstr "Nota: No duplica las líneas creadas por usted."
+
+#. module: stock_planning
+#: view:stock.period:0
+msgid "Stock and Sales Period"
+msgstr "Periodo de stock y ventas"
+
+#. module: stock_planning
+#: field:stock.planning,company_forecast:0
+msgid "Company Forecast"
+msgstr "Previsión de la compañía"
+
+#. module: stock_planning
+#: help:stock.planning,product_uom:0
+#: help:stock.sale.forecast,product_uom:0
+msgid ""
+"Unit of Measure used to show the quanities of stock calculation.You can use "
+"units form default category or from second category (UoS category)."
+msgstr ""
+"Unidad de medida utilizada para mostrar las cantidades calculadas de stock. "
+"Puede utilizar las unidades de la categoría por defecto o las de la segunda "
+"categoría (categoría UdV)."
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid "Per User :"
+msgstr "Por usuario :"
+
+#. module: stock_planning
+#: model:ir.ui.menu,name:stock_planning.menu_stock_sale_forecast
+#: model:ir.ui.menu,name:stock_planning.menu_stock_sale_forecast_all
+#: view:stock.sale.forecast:0
+msgid "Sales Forecasts"
+msgstr "Previsiones de ventas"
+
+#. module: stock_planning
+#: field:stock.period,name:0
+#: field:stock.period.createlines,name:0
+msgid "Period Name"
+msgstr "Nombre del período"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,user_id:0
+msgid "Created/Validated by"
+msgstr "Creado/Validado por"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Internal Supply"
+msgstr "Suministro interno"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period4_per_company:0
+msgid "This Company Period4"
+msgstr "El periodo de esta compañía4"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period5_per_company:0
+msgid "This Company Period5"
+msgstr "El periodo de esta compañía5"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period2_per_company:0
+msgid "This Company Period2"
+msgstr "El periodo de esta compañía2"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period3_per_company:0
+msgid "This Company Period3"
+msgstr "El periodo de esta compañía3"
+
+#. module: stock_planning
+#: field:stock.period,date_start:0
+#: field:stock.period.createlines,date_start:0
+msgid "Start Date"
+msgstr "Fecha de inicio"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:642
+#: code:addons/stock_planning/stock_planning.py:684
+#, python-format
+msgid ""
+"\n"
+" Already Out: "
+msgstr ""
+"\n"
+" Salidas realizadas: "
+
+#. module: stock_planning
+#: field:stock.planning,confirmed_forecasts_only:0
+msgid "Validated Forecasts"
+msgstr "Previsiones validadas"
+
+#. module: stock_planning
+#: help:stock.planning.createlines,product_categ_id:0
+msgid ""
+"Planning will be created for products from Product Category selected by this "
+"field. This field is ignored when you check \"All Forecasted Product\" box."
+msgstr ""
+"Se creará la planificación para los productos de la categoría de productos "
+"seleccionada con este campo. Este campo se ignora cuando se marca la opción "
+"\"Todas las previsiones de productos”."
+
+#. module: stock_planning
+#: field:stock.planning,planned_outgoing:0
+msgid "Planned Out"
+msgstr "Salidas planificadas"
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid "Per Department :"
+msgstr "Por departamento:"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Forecast"
+msgstr "Previsión"
+
+#. module: stock_planning
+#: selection:stock.period,state:0
+#: selection:stock.planning,state:0
+#: selection:stock.sale.forecast,state:0
+msgid "Draft"
+msgstr "Borrador"
+
+#. module: stock_planning
+#: view:stock.period:0
+msgid "Closed"
+msgstr "Cerrada"
+
+#. module: stock_planning
+#: view:stock.planning:0
+#: view:stock.sale.forecast:0
+msgid "Warehouse "
+msgstr "Almacén "
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:646
+#: code:addons/stock_planning/stock_planning.py:688
+#, python-format
+msgid ""
+"\n"
+" Expected Out: "
+msgstr ""
+"\n"
+" Salidas previstas: "
+
+#. module: stock_planning
+#: view:stock.period.createlines:0
+msgid "Create periods for Stock and Sales Planning"
+msgstr "Crear periodos para planificación de stock y ventas"
+
+#. module: stock_planning
+#: help:stock.planning,planned_outgoing:0
+msgid ""
+"Enter planned outgoing quantity from selected Warehouse during the selected "
+"Period of selected Product. To plan this value look at Confirmed Out or "
+"Sales Forecasts. This value should be equal or greater than Confirmed Out."
+msgstr ""
+"Introduzca la cantidad saliente planificada para el almacén seleccionado "
+"durante el periodo seleccionado y para el producto seleccionado. Para "
+"planificar este valor puede fijarse en las salidas confirmadas o las "
+"previsiones de ventas. Este valor debería ser igual o superior a las salidas "
+"confirmadas."
+
+#. module: stock_planning
+#: model:ir.module.module,description:stock_planning.module_meta_information
+msgid ""
+"\n"
+"This module is based on original OpenERP SA module stock_planning version "
+"1.0 of the same name Master Procurement Schedule.\n"
+"\n"
+"Purpose of MPS is to allow create a manual procurement (requisition) apart "
+"of MRP scheduler (which works automatically on minimum stock rules).\n"
+"\n"
+"Terms used in the module:\n"
+"- Stock and Sales Period - is the time (between Start Date and End Date) for "
+"which you plan Stock and Sales Forecast and make Procurement Planning. \n"
+"- Stock and Sales Forecast - is the quantity of products you plan to sell in "
+"the Period.\n"
+"- Stock Planning - is the quantity of products you plan to purchase or "
+"produce for the Period.\n"
+"\n"
+"Because we have another module sale_forecast which uses terms \"Sales "
+"Forecast\" and \"Planning\" as amount values we will use terms \"Stock and "
+"Sales Forecast\" and \"Stock Planning\" to emphasize that we use quantity "
+"values. \n"
+"\n"
+"Activity with this module is divided to three steps:\n"
+"- Creating Periods. Mandatory step.\n"
+"- Creating Sale Forecasts and entering quantities to them. Optional step but "
+"useful for further planning.\n"
+"- Creating Planning lines, entering quantities to them and making "
+"Procurement. Making procurement is the final step for the Period.\n"
+"\n"
+"Periods\n"
+"=======\n"
+"You have two menu items for Periods in \"Sales Management - Configuration\". "
+"There are:\n"
+"- \"Create Sales Periods\" - Which automates creating daily, weekly or "
+"monthly periods.\n"
+"- \"Stock and sales Periods\" - Which allows to create any type of periods, "
+"change the dates and change the State of period.\n"
+"\n"
+"Creating periods is the first step you have to do to use modules features. "
+"You can create custom periods using \"New\" button in \"Stock and Sales "
+"Periods\" form or view but it is recommended to use automating tool.\n"
+"\n"
+"Remarks:\n"
+"- These periods (officially Stock and Sales Periods) are separated of "
+"Financial or other periods in the system.\n"
+"- Periods are not assigned to companies (when you use multicompany feature "
+"at all). Module suppose that you use the same periods across companies. If "
+"you wish to use different periods for different companies define them as you "
+"wish (they can overlap). Later on in this text will be indications how to "
+"use such periods.\n"
+"- When periods are created automatically their start and finish dates are "
+"with start hour 00:00:00 and end hour 23:59:00. Fe. when you create daily "
+"periods they will have start date 31.01.2010 00:00:00 and end date "
+"31.01.2010 23:59:00. It works only in automatic creation of periods. When "
+"you create periods manually you have to take care about hours because you "
+"can have incorrect values form sales or stock. \n"
+"- If you use overlapping periods for the same product, warehouse and company "
+"results can be unpredictable.\n"
+"- If current date doesn't belong to any period or you have holes between "
+"periods results can be unpredictable.\n"
+"\n"
+"Sales Forecasts\n"
+"===============\n"
+"You have few menus for Sales forecast in \"Sales Management - Sales "
+"Forecasts\".\n"
+"- \"Create Sales Forecasts for Sales Periods\" - which automates creating "
+"forecasts lines according to some parameters.\n"
+"- \"Sales Forecasts\" - few menus for working with forecasts lists and "
+"forms.\n"
+"\n"
+"Menu \"Create Sales Forecasts for Sales Periods\" creates Forecasts for "
+"products from selected Category, for selected Period and for selected "
+"Warehouse. It is an option \"Copy Last Forecast\" to copy forecast and other "
+"settings of period before this one to created one.\n"
+"\n"
+"Remarks:\n"
+"- This tool doesn't create lines, if relevant lines (for the same Product, "
+"Period, Warehouse and validated or created by you) already exists. If you "
+"wish to create another forecast, if relevant lines exists you have to do it "
+"manually using menus described bellow.\n"
+"- When created lines are validated by someone else you can use this tool to "
+"create another lines for the same Period, Product and Warehouse. \n"
+"- When you choose \"Copy Last Forecast\" created line takes quantity and "
+"some settings from your (validated by you or created by you if not validated "
+"yet) forecast which is for last period before period of created forecast. If "
+"there are few your forecasts for period before this one (it is possible) "
+"system takes one of them (no rule which of them).\n"
+"\n"
+"\n"
+"Menus \"Sales Forecasts\"\n"
+"On \"Sales Forecast\" form mainly you have to enter a forecast quantity in "
+"\"Product Quantity\". Further calculation can work for draft forecasts. But "
+"validation can save your data against any accidental changes. You can click "
+"\"Validate\" button but it is not mandatory.\n"
+"\n"
+"Instead of forecast quantity you can enter amount of forecast sales in field "
+"\"Product Amount\". System will count quantity from amount according to Sale "
+"price of the Product.\n"
+"\n"
+"All values on the form are expressed in unit of measure selected on form. "
+"You can select one of unit of measure from default category or from second "
+"category. When you change unit of measure the quanities will be recalculated "
+"according to new UoM: editable values (blue fields) immediately, non edited "
+"fields after clicking of \"Calculate Planning\" button.\n"
+"\n"
+"To find proper value for Sale Forecast you can use \"Sales History\" table "
+"for this product. You have to enter parameters to the top and left of this "
+"table and system will count sale quantities according to these parameters. "
+"So you can select fe. your department (at the top) then (to the left): last "
+"period, period before last and period year ago.\n"
+"\n"
+"Remarks:\n"
+"\n"
+"\n"
+"Procurement Planning\n"
+"====================\n"
+"Menu for Planning you can find in \"Warehouse - Stock Planning\".\n"
+"- \"Create Stock Planning Lines\" - allows you to automate creating planning "
+"lines according to some parameters.\n"
+"- \"Master Procurement Scheduler\" - is the most important menu of the "
+"module which allows to create procurement.\n"
+"\n"
+"As Sales forecast is phase of planning sales. The Procurement Planning "
+"(Planning) is the phase of scheduling Purchasing or Producing. You can "
+"create Procurement Planning quickly using tool from menu \"Create Stock "
+"Planning Lines\", then you can review created planning and make procurement "
+"using menu \"Master Procurement Schedule\".\n"
+"\n"
+"Menu \"Create Stock Planning Lines\" allows you to create quickly Planning "
+"lines for products from selected Category, for selected Period, and for "
+"selected Warehouse. When you check option \"All Products with Forecast\" "
+"system creates lines for all products having forecast for selected Period "
+"and Warehouse. Selected Category will be ignored in this case.\n"
+"\n"
+"Under menu \"Master Procurement Scheduler\" you can generally change the "
+"values \"Planned Out\" and \"Planned In\" to observe the field \"Stock "
+"Simulation\" and decide if this value would be accurate for end of the "
+"Period. \n"
+"\"Planned Out\" can be based on \"Warehouse Forecast\" which is the sum of "
+"all forecasts for Period and Warehouse. But your planning can be based on "
+"any other information you have. It is not necessary to have any forecast. \n"
+"\"Planned In\" quantity is used to calculate field \"Incoming Left\" which "
+"is the quantity to be procured to make stock as indicated in \"Stock "
+"Simulation\" at the end of Period. You can compare \"Stock Simulation\" "
+"quantity to minimum stock rules visible on the form. But you can plan "
+"different quantity than in Minimum Stock Rules. Calculation is made for "
+"whole Warehouse by default. But if you want to see values for Stock location "
+"of calculated warehouse you can use check box \"Stock Location Only\".\n"
+"\n"
+"If after few tries you decide that you found correct quantities for "
+"\"Planned Out\" and \"Planned In\" and you are satisfied with end of period "
+"stock calculated in \"Stock Simulation\" you can click \"Procure Incoming "
+"Left\" button to procure quantity of field \"Incoming Left\" into the "
+"Warehouse. System creates appropriate Procurement Order. You can decide if "
+"procurement will be made to Stock or Input location of calculated Warehouse. "
+"\n"
+"\n"
+"If you don't want to Produce or Buy the product but just pick calculated "
+"quantity from another warehouse you can click \"Supply from Another "
+"Warehouse\" (instead of \"Procure Incoming Left\"). System creates pick list "
+"with move from selected source Warehouse to calculated Warehouse (as "
+"destination). You can also decide if this pick should be done from Stock or "
+"Output location of source warehouse. Destination location (Stock or Input) "
+"of destination warehouse will be used as set for \"Procure Incoming Left\". "
+"\n"
+"\n"
+"To see proper quantities in fields \"Confirmed In\", \"Confirmed Out\", "
+"\"Confirmed In Before\", \"Planned Out Before\" and \"Stock Simulation\" you "
+"have to click button \"Calculate Planning\".\n"
+"\n"
+"All values on the form are expressed in unit of measure selected on form. "
+"You can select one of unit of measure from default category or from second "
+"category. When you change unit of measure the quanities will be recalculated "
+"according to new UoM: editable values (blue fields) immediately, non edited "
+"fields after clicking of \"Calculate Planning\" button.\n"
+"\n"
+"How Stock Simulation field is calculated:\n"
+"Generally Stock Simulation shows the stock for end of the calculated period "
+"according to some planned or confirmed stock moves. Calculation always "
+"starts with quantity of real stock of beginning of current period. Then "
+"calculation adds or subtracts quantities of calculated period or periods "
+"before calculated.\n"
+"When you are in the same period (current period is the same as calculated) "
+"Stock Simulation is calculated as follows:\n"
+"Stock Simulation = \n"
+"\tStock of beginning of current Period\n"
+"\t- Planned Out \n"
+"\t+ Planned In\n"
+"\n"
+"When you calculate period next to current:\n"
+"Stock Simulation = \n"
+"\tStock of beginning of current Period\n"
+"\t- Planned Out of current Period \n"
+"\t+ Confirmed In of current Period (incl. Already In)\n"
+"\t- Planned Out of calculated Period \n"
+"\t+ Planned In of calculated Period .\n"
+"\n"
+"As you see calculated Period is taken the same way like in case above. But "
+"calculation of current Period are made a little bit different. First you "
+"should note that system takes for current Period only Confirmed In moves. It "
+"means that you have to make planning and procurement for current Period "
+"before this calculation (for Period next to current). \n"
+"\n"
+"When you calculate Period ahead:\n"
+"Stock Simulation = \n"
+"\tStock of beginning of current Period \n"
+"\t- Sum of Planned Out of Periods before calculated \n"
+"\t+ Sum of Confirmed In of Periods before calculated (incl. Already In) \n"
+"\t- Planned Out of calculated Period \n"
+"\t+ Planned In of calculated Period.\n"
+"\n"
+"Periods before calculated means periods starting from current till period "
+"before calculated.\n"
+"\n"
+"Remarks:\n"
+"- Remember to make planning for all periods before calculated because "
+"omitting these quantities and procurements can cause wrong suggestions for "
+"procurements few periods ahead.\n"
+"- If you made planning few periods ahead and you find that real Confirmed "
+"Out is bigger than Planned Out in some periods before you can repeat "
+"Planning and make another procurement. You should do it in the same planning "
+"line. If you create another planning line the suggestions can be wrong.\n"
+"- When you wish to work with different periods for some part of products "
+"define two kinds of periods (fe. Weekly and Monthly) and use them for "
+"different products. Example: If you use always Weekly periods for Products "
+"A, and Monthly periods for Products B your all calculations will work "
+"correctly. You can also use different kind of periods for the same products "
+"from different warehouse or companies. But you cannot use overlapping "
+"periods for the same product, warehouse and company because results can be "
+"unpredictable. The same apply to Forecasts lines.\n"
+msgstr ""
+"\n"
+"Este módulo se basa en la versión original de OpenERP stock_planning SA "
+"módulo 1.0 del mismo nombre Programador de Compras Maestras.\n"
+"\n"
+"El propósito de la MPS es permitir crear un manual de contratación "
+"(solicitud), aparte del programador MRP (que funciona automáticamente, "
+"basándose en reglas de existencias mínimas).\n"
+"\n"
+"Los términos utilizados en el módulo:\n"
+"- Stock y Período de ventas - es el tiempo (entre Fecha de inicio y Fecha de "
+"finalización) para el que planifica el Stock y la Previsión de Ventas y hace "
+"la Planificación de las Compras.\n"
+"- Stock y pronóstico de ventas - es la cantidad de productos que planea "
+"vender en el Período.\n"
+"- Planificación de Stock - es la cantidad de productos que planea comprar o "
+"producir para el Período.\n"
+"\n"
+"Porque tenemos otra módulo sale_forecast que utiliza los términos "
+"\"Pronóstico de Ventas\" y \"Planificación\" como valores de cantidad, "
+"utilizaremos términos \"Stock y Pronóstico de Ventas\" y \"Planificación del "
+"Stock\" para hacer hincapié en que usamos los valores de cantidad.\n"
+"\n"
+"La actividad con este módulo se divide en tres pasos:\n"
+"- Creación de Períodos. Paso obligatorio.\n"
+"- Creación de Pronósticos de Venta e introducción de sus cantidades. Un paso "
+"opcional pero útil para una mayor planificación.\n"
+"- Creación de líneas de Planificación, introducción de sus cantidades y "
+"hacer Adquisiciones. Hacer compras es el paso final para el Período.\n"
+"\n"
+"Períodos\n"
+"=========\n"
+"Tiene dos opciones de menú para Períodos en \"Gestión de Ventas - "
+"Configuración\". Son las siguientes:\n"
+"- \"Crear los Períodos de Ventas\" - Que automatiza la creación de periodos "
+"diarios, semanales o mensuales.\n"
+"- \"Stock y Períodos de ventas\" - Que permite crear cualquier tipo de "
+"períodos, el cambio de las fechas y el cambio del Estado del período.\n"
+"\n"
+"Creación de periodos es el primer paso que tiene que hacer para utilizar las "
+"funciones de los módulos. Puede crear períodos personalizados mediante el "
+"botón \"Nuevo\" en el formulario o vista de \"Stock y Períodos de Ventas\", "
+"pero se recomienda utilizar la herramienta automática.\n"
+"\n"
+"Observaciones:\n"
+"- Estos períodos (Stock oficial y Períodos de Ventas) están separan de "
+"Finanzas o de otros períodos en el sistema.\n"
+"- Los Períodos no se asignan a las compañías (en ningún caso cuando se "
+"utiliza la función multicompañía). El módulo supone que utiliza los mismos "
+"períodos a través de las compañías. Si desea utilizar períodos diferentes "
+"para diferentes compañías defínalos a su gusto (pueden solaparse). Más "
+"adelante en este texto se indica cómo utilizar esos períodos.\n"
+"- Cuando los períodos son creados automáticamente sus fechas de inicio y "
+"final se inician con la hora 00:00:00 y 23:59:00 como hora final. Pe.cuando "
+"crea períodos diarios tendrán fecha de inicio 01.31.2010 00:00:00 y fecha de "
+"finalización 01.31.2010 23:59:00. Funciona sólo en la creación automática de "
+"los períodos. Cuando crea períodos manualmente hay que tener cuidado con las "
+"horas, ya que puede tener valores incorrectos en ventas y stock.\n"
+"- Si utiliza períodos solapados para el mismo producto, almacén y compañía, "
+"los resultados pueden ser impredecibles.\n"
+"- Si la fecha actual no pertenece a ningún período o si tiene agujeros entre "
+"los períodos los resultados pueden ser impredecibles.\n"
+"\n"
+"Previsión de ventas\n"
+"====================\n"
+"Tiene menús pocas ventas previsto en \"Gestión de Ventas - Pronósticos de "
+"Ventas\".\n"
+"- \"Creación de Pronósticos de Ventas para los Períodos de Ventas\" - que "
+"automatiza la creación de líneas de previsiones de acuerdo con algunos "
+"parámetros.\n"
+"- \"Las Previsiones de Ventas\" - algunos menús para trabajar con listas de "
+"las previsiones y las formas.\n"
+"\n"
+"Menú \"Crear Pronósticos de Ventas para Períodos de Ventas\" crea "
+"Pronósticos para los productos de la Categoría seleccionada, para el Período "
+"y Almacén seleccionado. Es una opción \"Copia del Último Pronóstico\" para "
+"copiar previsiones y otros ajustes del período anterior a éste para crear "
+"uno.\n"
+"\n"
+"Observaciones:\n"
+"- Esta herramienta no crea líneas, si las líneas oportunas (para el mismo "
+"Producto, Período y Almacén, y validado o creado por usted) ya existen. Si "
+"desea crear otro pronóstico, si las líneas pertinentes existen tiene que "
+"hacerlo manualmente usando los menús que se describen a continuación.\n"
+"- Cuando las líneas se crean son validadas por otra persona que puede "
+"utilizar esta herramienta para crear otras líneas para el mismo Período, "
+"Producto y Almacén.\n"
+"- Cuando se elige \"Copiar Último Pronóstico\" la línea creada tiene la "
+"cantidad y algunos ajustes de su (validado o creadas por usted, si no se ha "
+"validado aún) pronostico que para el último período anterior al período de "
+"la previsión creada. Si hay pocos pronósticos para el período anterior a "
+"éste (es posible) el sistema toma una de ellos (no existe regla sobre "
+"cual).\n"
+"\n"
+"\n"
+"Menús \"Previsión de Ventas\"\n"
+"En el formulario \"Pronóstico de Ventas\" principalmente tiene que "
+"introducir una cantidad prevista en la \"Cantidad de Producto\". Además del "
+"cálculo puede funcionar para las previsiones borrador. Sin embargo, la "
+"validación puede guardar sus datos contra cualquier cambio accidental. Puede "
+"hacer clic en botón \"Validar\", pero no es obligatorio.\n"
+"\n"
+"En lugar de la cantidad prevista se puede introducir la cantidad de "
+"previsión de ventas en el campo \"Cantidad de Producto\". El sistema contará "
+"la cantidad en función del Precio de Venta del Producto.\n"
+"\n"
+"Todos los valores del formulario se expresan en la unidad de medida "
+"seleccionada en el formulario. Usted puede seleccionar uno de la unidad de "
+"medida de la categoría por defecto o de segunda categoría. Cuando se cambia "
+"la unidad de medida las cantiades se volverán a calcular de acuerdo con la "
+"nueva UoM: los valores editables (campos azules) inmediatamente, los campos "
+"no editables después de hacer clic en el botón \"Calcular Planificación\".\n"
+"\n"
+"Para encontrar el valor adecuado para Pronóstico de Venta se puede utilizar "
+"la tabla \"Historial de ventas\" para este producto. Tienes que introducir "
+"los parámetros en la parte superior izquierda de esta tabla y el sistema "
+"contará las vantidades venta de acuerdo con estos parámetros. Así que usted "
+"puede seleccionar, pe. de su departamento (en la parte superior) y luego (a "
+"la izquierda): el último período, el período anterior al último y el período "
+"de hace un año.\n"
+"\n"
+"Observaciones:\n"
+"\n"
+"\n"
+"Planificación de las compras\n"
+"====================\n"
+"Menú para la Planificación de lo que puedes encontrar en \"Almacén - "
+"Planificación del Stock\".\n"
+"- \"Crear archivo de Planificación Lines\" - le permite automatizar la "
+"creación de líneas de planificación de acuerdo con algunos parámetros.\n"
+"- \"Programador Maestro de Adquisiciones\" - es el menú más importante del "
+"módulo que permite la creación de la contratación.\n"
+"\n"
+"Con arreglo a las previsiones de ventas, es la fase de planificación de "
+"ventas. La Planificación de compras (planificación) es la fase de "
+"programación de compras o de producción. Usted puede crear la planificación "
+"de las compras rápidamente con la herramienta del menú \"Crear Líneas de "
+"Planificación de Stock\", entonces puede revisar la planificación creada y "
+"hacer compras usando el menú \"Lista Maestra de Adquisiciones\".\n"
+"\n"
+"Menú \"Crear Líneas de Planificación de Stock\" le permite crear rápidamente "
+"las Líneas de Planificación de productos de la categoría seleccionada, en "
+"determinados períodos, y para el almacén seleccionado. Al marcar la opción "
+"\"Todos los productos con Pronóstico\" el sistema crea las líneas para todos "
+"los productos que tiene previsto para el Período seleccionado y Almacén. La "
+"Categoría seleccionada se tendrá en cuenta en este caso.\n"
+"\n"
+"Debajo del menú \"Programador Maestro de Adquisiciones\" por lo general, "
+"puede cambiar los valores \"Salidas planificadas\" y \"Entradas "
+"planificadas\" para observar el campo \"Simulación de Stock\" y decidir si "
+"este valor es exacto para el final del período.\n"
+"\"Planeado\" puede basarse en la \"Pronóstico de Almacén\", que es la suma "
+"de todas las previsiones para el período y Almacén. Pero la planificación se "
+"puede basar en cualquier otra información que usted tenga. No es necesario "
+"tener ningún pronóstico.\n"
+"\"Entradas planificadas\" la cantidad se utiliza para calcular el campo "
+"\"Entradas Restantes\" que es la cantidad que falta por adquirir para "
+"alcanzar el stock, como se indica en la \"Simulación de Stock\" al final del "
+"período. Usted puede comparar la \"Simulación de Stock\" con las normas de "
+"cantidad mínima de existencias visibles en el formulario. Pero puede planear "
+"una cantidad diferente al de las Reglas Mínimas de Stock. El cálculo está "
+"hecho para todo el almacén por defecto. Pero si usted quiere ver los valores "
+"de la ubicación del stock del almacén calculado, puede utilizar la casilla "
+"\"Sólo Ubicación del Stock\".\n"
+"\n"
+"Si después de varios intentos decide que las cantidades son correctas para "
+"lo \"Salidas planificadas\" y lo \"Entradas planificadas\" y que está "
+"satisfecho con el final de existencias del período calculado en la "
+"\"Simulación del Stock\" puede hacer clic en \"Adquirir Entradas Restantes\" "
+"para obtener la cantidad del campo \"Entradas Restantes\" en el Almacén. El "
+"sistema crea la correspondiente Orden de Compras. Usted puede decidir si la "
+"contratación se hará para el stock o para la ubicación de entrada del "
+"Almacén calculado.\n"
+"\n"
+"Si no quieres Producir o Comprar el producto, pero sólo debes elegir la "
+"cantidad calculada, desde otro almacén puede hacer clic en \"Suministro "
+"desde Otro Almacén\" (en lugar de \"Adquirir Entradas Restantes\"). El "
+"sistema crea la lista de selección desde el Almacén origen seleccionado "
+"hasta el Almacén calculado (como destino). También puede decidir si esta "
+"selección debe hacerse de almacén o la ubicación de salida del almacén de "
+"origen. La ubicación de destino (almacén o entrada) del almacén de destino, "
+"se utilizará como establecido para \"Adquirir Entradas Restantes\".\n"
+"\n"
+"Para ver las cantidades adecuadas en los campos \"Entrada Confirmada\", "
+"\"Salida Confirmada\", \"Entrada Confirmada Antes\", \"Salidas planificadas "
+"antes\" y \"Simulación de Stock\" tiene que hacer clic en el botón "
+"\"Calcular Planificación\".\n"
+"\n"
+"Todos los valores en el formulario se expresan en la unidad de medida "
+"seleccionada en el formulario. Usted puede seleccionar uno de la unidad de "
+"medida de la categoría por defecto o de una segunda categoría. Cuando se "
+"cambia la unidad de medida las cantidades se volverán a calcular de acuerdo "
+"con UoM: los valores editables inmediatamente (campos azules), los campos no "
+"editables después de hacer clic en el botón \"Calcular Planificación\".\n"
+"\n"
+"Cómo se calcula el campo Simulación del Stock:\n"
+"Generalmente la Simulación del Stock muestra el stock al final período "
+"calculado de acuerdo con algunos movimientos de stock previsto o confirmado. "
+"El cálculo se inicia siempre con la cantidad de stock real del inicio del "
+"período actual. Luego se calcula la suma o resta de las cantidades del "
+"período o períodos antes calculados.\n"
+"Cuando está en el mismo período (período actual es el mismo que el "
+"calculado) la Simulación del Stock se calcula como sigue:\n"
+"Simulación de Stock = \n"
+"\t Stock inicial del período actual\n"
+"\t - Salidas planificadas \n"
+"\t + Entradas planificadas\n"
+"\n"
+"Cuando se calcula el período siguiente al actual:\n"
+"Simulación del Stock = \n"
+"\t Stock inicial del período actual \n"
+"\t - Planificación de Salidas del Período actual\n"
+"\t + Entradas Confirmadas en el Período actual (incl. las Entradas ya "
+"existentes)\n"
+"\t - Salidas planificadas del Período calculado \n"
+"\t + Entradas planificadas en el Período calculado.\n"
+"\n"
+"Como puede ver el período calculado se toma de la misma forma que en el caso "
+"anterior. Sin embargo, el cálculo del período actual se hace de manera un "
+"poco diferente. En primer lugar debe tener en cuenta que el sistema tiene "
+"para el Período actual sólo Confirmados los movimientos de entrada. Esto "
+"significa que tiene que hacer la planificación y la compra para Período "
+"actual antes de este cálculo (para el Próximo período al actual).\n"
+"\n"
+"Cuando se calcula el período siguiente:\n"
+"Colección de simulación = \n"
+"\t Stock inicial del Período actual \n"
+"\t - Suma de Planificación de salida de los períodos antes calculados \n"
+"\t + Suma de Confirmados En períodos anteriores calculados (incl. las "
+"entradas ya existentes) \n"
+"\t - Salidas Planificadas del Período calculado \n"
+"\t + Entradas Planificadas del Período calculado.\n"
+"\n"
+"Los períodos anteriores calculados, significa que los períodos comienzados "
+"en el actual hasta el período antes calculado.\n"
+"\n"
+"Observaciones:\n"
+"- Recuerde hacer la planificación para todos los períodos antes calculados "
+"debido a omitir estas cantidades y las adquisiciones pueden causar "
+"sugerencias erróneas para las compras de algunos períodos posteriores.\n"
+"- Si ha realizado la planificación de unos pocos períodos posteriores y "
+"encuentra que las Salidas Confirmadas reales son mayores de lo previsto en "
+"algunos períodos antes de que pueda repetirse la Planificación y realizar "
+"otra adquisición. Debe hacerlo en la misma línea de la planificación. Si se "
+"crea otra línea de planificación de sugerencias puede estar equivocada.\n"
+"- Cuando desea trabajar con diferentes períodos para una parte de los "
+"productos, defina dos tipos de períodos (pe. semanal y mensual) y los "
+"utilícelos para diferentes productos. Ejemplo: si utiliza siempre los "
+"períodos semanales para los productos A, y los períodos mensuales de los "
+"productos B todos sus cálculos funcionarán correctamente. También puede "
+"utilizar diferentes tipos de períodos para los mismos productos de "
+"diferentes almacenes de diferentes compañías. Pero no se pueden utilizar "
+"períodos solapados para el mismo producto de un almacén, y compañía porque "
+"los resultados pueden ser impredecibles. Lo mismo se aplica a las líneas de "
+"Previsiones.\n"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:140
+#, python-format
+msgid "Cannot delete Validated Sale Forecasts !"
+msgstr "¡ No se pueden borrar previsiones de ventas validadas !"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:641
+#: code:addons/stock_planning/stock_planning.py:683
+#, python-format
+msgid ""
+"\n"
+" Planned Out: "
+msgstr ""
+"\n"
+" Salidas planificadas: "
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:667
+#, python-format
+msgid ""
+"You must specify a Source Warehouse different than calculated (destination) "
+"Warehouse !"
+msgstr ""
+"¡Debe especificar un almacén de origen diferente del almacén calculado (de "
+"destino)!"
+
+#. module: stock_planning
+#: model:ir.actions.act_window,name:stock_planning.action_stock_sale_forecast_createlines_form
+#: model:ir.ui.menu,name:stock_planning.menu_stock_sale_forecast_createlines
+msgid "Create Sales Forecasts"
+msgstr "Crear previsiones de ventas"
+
+#. module: stock_planning
+#: view:stock.sale.forecast.createlines:0
+msgid "Creates forecast lines for selected warehouse and period."
+msgstr "Crear líneas de previsión para el almacén y periodo seleccionados."
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:656
+#, python-format
+msgid "%s Requisition (%s, %s) %s %s \n"
+msgstr "%s Solicitud (%s, %s) %s %s \n"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:655
+#, python-format
+msgid "Requisition ("
+msgstr "Solicitud ("
+
+#. module: stock_planning
+#: help:stock.planning,outgoing_left:0
+msgid ""
+"Quantity expected to go out in selected period. As a difference between "
+"Planned Out and Confirmed Out. For current period Already Out is also "
+"calculated"
+msgstr ""
+"Cantidad prevista para salir en el período seleccionado. Diferencia entre "
+"las salidas previstas y las salidas confirmadas. Para el periodo actual "
+"también se calculan las salidas realizadas."
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period4_id:0
+msgid "Period4"
+msgstr "Periodo4"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:642
+#: code:addons/stock_planning/stock_planning.py:684
+#, python-format
+msgid " Already In: "
+msgstr " Entradas realizadas: "
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period2_id:0
+msgid "Period2"
+msgstr "Periodo2"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period3_id:0
+msgid "Period3"
+msgstr "Periodo3"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period1_id:0
+msgid "Period1"
+msgstr "Periodo1"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:647
+#: code:addons/stock_planning/stock_planning.py:689
+#, python-format
+msgid " Minimum stock: "
+msgstr " Stock mínimo: "
+
+#. module: stock_planning
+#: field:stock.planning,active_uom:0
+#: field:stock.sale.forecast,active_uom:0
+msgid "Active UoM"
+msgstr "UdM activa"
+
+#. module: stock_planning
+#: model:ir.actions.act_window,name:stock_planning.action_stock_planning_createlines_form
+#: model:ir.ui.menu,name:stock_planning.menu_stock_planning_createlines
+#: view:stock.planning.createlines:0
+msgid "Create Stock Planning Lines"
+msgstr "Crear líneas de planificación de stock"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "General Info"
+msgstr "Información General"
+
+#. module: stock_planning
+#: model:ir.actions.act_window,name:stock_planning.action_view_stock_sale_forecast_form
+msgid "Sales Forecast"
+msgstr "Previsión de ventas"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Planning and Situation for Calculated Period"
+msgstr "Planificación y situación para el periodo calculado"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period1_per_warehouse:0
+msgid "This Warehouse Period1"
+msgstr "Peridodo de este almacen1"
+
+#. module: stock_planning
+#: field:stock.planning,warehouse_forecast:0
+msgid "Warehouse Forecast"
+msgstr "Previsión almacen"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:643
+#: code:addons/stock_planning/stock_planning.py:685
+#, python-format
+msgid " Confirmed In: "
+msgstr " Entradas confirmadas: "
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid "Sales history"
+msgstr "Histórico de ventas"
+
+#. module: stock_planning
+#: field:stock.planning,supply_warehouse_id:0
+msgid "Source Warehouse"
+msgstr "Almacén origen"
+
+#. module: stock_planning
+#: help:stock.sale.forecast,product_qty:0
+msgid "Forecasted quantity."
+msgstr "Cantidad prevista."
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Stock"
+msgstr "Stock"
+
+#. module: stock_planning
+#: field:stock.planning,stock_supply_location:0
+msgid "Stock Supply Location"
+msgstr "Ubicación suministro de stock"
+
+#. module: stock_planning
+#: help:stock.period.createlines,date_stop:0
+msgid "Ending date for planning period."
+msgstr "Fecha de fin para el periodo planificado."
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period2_per_user:0
+msgid "This User Period2"
+msgstr "El periodo de este usuario2"
+
+#. module: stock_planning
+#: help:stock.planning.createlines,forecasted_products:0
+msgid ""
+"Check this box to create planning for all products having any forecast for "
+"selected Warehouse and Period. Product Category field will be ignored."
+msgstr ""
+"Marque esta opción para crear la planificación de todos los productos que "
+"tengan cualquier previsión en el almacén y periodo seleccionado. El campo "
+"categoría de producto será ignorado."
+
+#. module: stock_planning
+#: field:stock.planning,already_in:0
+msgid "Already In"
+msgstr "Entradas realizadas"
+
+#. module: stock_planning
+#: field:stock.planning,product_uom_categ:0
+#: field:stock.planning,product_uos_categ:0
+#: field:stock.sale.forecast,product_uom_categ:0
+msgid "Product UoM Category"
+msgstr "Categoría UdM producto"
+
+#. module: stock_planning
+#: field:stock.planning,incoming:0
+msgid "Confirmed In"
+msgstr "Entradas confirmadas"
+
+#. module: stock_planning
+#: field:stock.planning,line_time:0
+msgid "Past/Future"
+msgstr "Pasado/Futuro"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,product_uos_categ:0
+msgid "Product UoS Category"
+msgstr "Categoría UdV producto"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,product_qty:0
+msgid "Product Quantity"
+msgstr "Cantidad de producto"
+
+#. module: stock_planning
+#: field:stock.sale.forecast.createlines,copy_forecast:0
+msgid "Copy Last Forecast"
+msgstr "Copiar última previsión"
+
+#. module: stock_planning
+#: help:stock.sale.forecast,product_id:0
+msgid "Shows which product this forecast concerns."
+msgstr "Muestra a qué producto concierne esta previsión"
+
+#. module: stock_planning
+#: selection:stock.planning,state:0
+msgid "Done"
+msgstr "Listo"
+
+#. module: stock_planning
+#: field:stock.period.createlines,period_ids:0
+msgid "Periods"
+msgstr "Periodos"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:638
+#: code:addons/stock_planning/stock_planning.py:680
+#, python-format
+msgid " according to state:"
+msgstr " según el estado:"
+
+#. module: stock_planning
+#: view:stock.period.createlines:0
+msgid "Cancel"
+msgstr "Cancelar"
+
+#. module: stock_planning
+#: view:stock.period:0
+#: selection:stock.period,state:0
+#: view:stock.planning.createlines:0
+#: view:stock.sale.forecast.createlines:0
+msgid "Close"
+msgstr "Cerrar"
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+#: selection:stock.sale.forecast,state:0
+msgid "Validated"
+msgstr "Validado"
+
+#. module: stock_planning
+#: view:stock.period:0
+#: selection:stock.period,state:0
+msgid "Open"
+msgstr "Abrir"
+
+#. module: stock_planning
+#: help:stock.sale.forecast.createlines,copy_forecast:0
+msgid "Copy quantities from last Stock and Sale Forecast."
+msgstr "Copiar cantidades desde el stock pasado y previsión de ventas"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period1_per_dept:0
+msgid "This Dept Period1"
+msgstr "El periodo de este depto.1"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period3_per_dept:0
+msgid "This Dept Period3"
+msgstr "El periodo de este depto.3"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period2_per_dept:0
+msgid "This Dept Period2"
+msgstr "El periodo de este depto.2"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period5_per_dept:0
+msgid "This Dept Period5"
+msgstr "El periodo de este depto.5"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period4_per_dept:0
+msgid "This Dept Period4"
+msgstr "El periodo de este depto.4"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period2_per_warehouse:0
+msgid "This Warehouse Period2"
+msgstr "El periodo de este almacén2"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period3_per_warehouse:0
+msgid "This Warehouse Period3"
+msgstr "El periodo de este almacén3"
+
+#. module: stock_planning
+#: field:stock.planning,outgoing:0
+msgid "Confirmed Out"
+msgstr "Salidas confirmadas"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,create_uid:0
+msgid "Responsible"
+msgstr "Responsable"
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid "Default UOM"
+msgstr "UdM por defecto"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period4_per_warehouse:0
+msgid "This Warehouse Period4"
+msgstr "El periodo de este almacén4"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period5_per_warehouse:0
+msgid "This Warehouse Period5"
+msgstr "El periodo de este almacén5"
+
+#. module: stock_planning
+#: view:stock.period:0
+msgid "Current"
+msgstr "Actual"
+
+#. module: stock_planning
+#: model:ir.model,name:stock_planning.model_stock_planning
+msgid "stock.planning"
+msgstr "stock.planificación"
+
+#. module: stock_planning
+#: help:stock.sale.forecast,warehouse_id:0
+msgid ""
+"Shows which warehouse this forecast concerns. If during stock planning you "
+"will need sales forecast for all warehouses choose any warehouse now."
+msgstr ""
+"Muestra a qué almacén concierne esta previsión. Si durante la planificación "
+"de stock necesita previsiones de ventas para todos los almacenes escoja "
+"ahora un almacén cualquiera."
+
+#. module: stock_planning
+#: help:stock.planning.createlines,warehouse_id:0
+msgid "Warehouse which planning will concern."
+msgstr "Almacén que se referirá la planificación"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:647
+#: code:addons/stock_planning/stock_planning.py:689
+#, python-format
+msgid ""
+"\n"
+" Stock Simulation: "
+msgstr ""
+"\n"
+" Simulación de stock: "
+
+#. module: stock_planning
+#: help:stock.planning,to_procure:0
+msgid ""
+"Enter quantity which (by your plan) should come in. Change this value and "
+"observe Stock simulation. This value should be equal or greater than "
+"Confirmed In."
+msgstr ""
+"Introducir la cantidad que (por su plan) debe entrar. Cambie este valor y "
+"observe la simulación de stock. Este valor debería ser igual o superior a "
+"las entradas confirmadas."
+
+#. module: stock_planning
+#: help:stock.planning.createlines,period_id:0
+msgid "Period which planning will concern."
+msgstr "Periodo al cual concierne la planificación"
+
+#. module: stock_planning
+#: field:stock.planning,already_out:0
+msgid "Already Out"
+msgstr "Salidas realizadas"
+
+#. module: stock_planning
+#: help:stock.planning,product_id:0
+msgid "Product which this planning is created for."
+msgstr "Producto para el que ha sido creada esta planificación."
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid "Per Warehouse :"
+msgstr "Por almacén :"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:639
+#: code:addons/stock_planning/stock_planning.py:681
+#, python-format
+msgid ""
+"\n"
+" Warehouse Forecast: "
+msgstr ""
+"\n"
+" Previsión almacén: "
+
+#. module: stock_planning
+#: field:stock.planning,history:0
+msgid "Procurement History"
+msgstr "Histórico abastecimientos"
+
+#. module: stock_planning
+#: help:stock.period.createlines,date_start:0
+msgid "Starting date for planning period."
+msgstr "Fecha inicial para el periodo planificado."
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:641
+#: code:addons/stock_planning/stock_planning.py:683
+#, python-format
+msgid " Planned In: "
+msgstr " Entradas planificadas: "
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyze_company:0
+msgid "Per Company"
+msgstr "Por compañía"
+
+#. module: stock_planning
+#: help:stock.planning,incoming_left:0
+msgid ""
+"Quantity left to Planned incoming quantity. This is calculated difference "
+"between Planned In and Confirmed In. For current period Already In is also "
+"calculated. This value is used to create procurement for lacking quantity."
+msgstr ""
+"Cantidad restante de la cantidad entrante planificada. Se calcula mediante "
+"la diferencia entre las entradas planificadas y las entradas confirmadas. "
+"Para el periodo actual las entradas realizadas también se calculan. Este "
+"valor se usa para crear abastecimientos para la cantidad faltante."
+
+#. module: stock_planning
+#: help:stock.planning,incoming:0
+msgid "Quantity of all confirmed incoming moves in calculated Period."
+msgstr ""
+"Cantidades de todas las entradas confirmadas en el periodo calculado."
+
+#. module: stock_planning
+#: field:stock.period,date_stop:0
+#: field:stock.period.createlines,date_stop:0
+msgid "End Date"
+msgstr "Fecha de término"
+
+#. module: stock_planning
+#: help:stock.planning,stock_supply_location:0
+msgid ""
+"Check to supply from Stock location of Supply Warehouse. If not checked "
+"supply will be made from Output location of Supply Warehouse. Used in "
+"'Supply from Another Warhouse' with Supply Warehouse."
+msgstr ""
+"Marque esta opción para suministrar desde la ubicación stock del almacén de "
+"suministro. Si no se marca, el suministro se realizará desde la ubicación de "
+"salida del almacén de suministro. Utilizado en 'Suministrar desde otro "
+"almacén' con un almacén de suministro."
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "No Requisition"
+msgstr "No solicitar"
+
+#. module: stock_planning
+#: help:stock.planning,minimum_op:0
+msgid "Minimum quantity set in Minimum Stock Rules for this Warhouse"
+msgstr ""
+"Cantidad mínima establecida en las reglas de stock mínimo para este almacén."
+
+#. module: stock_planning
+#: help:stock.sale.forecast,period_id:0
+msgid "Shows which period this forecast concerns."
+msgstr "Muestra a que periodo concierne esta previsión."
+
+#. module: stock_planning
+#: field:stock.planning,product_uom:0
+msgid "UoM"
+msgstr "UdM"
+
+#. module: stock_planning
+#: view:stock.planning:0
+msgid "Calculated Period Simulation"
+msgstr "Simulación calculada del periodo"
+
+#. module: stock_planning
+#: view:stock.planning:0
+#: field:stock.planning,product_id:0
+#: view:stock.sale.forecast:0
+#: field:stock.sale.forecast,product_id:0
+msgid "Product"
+msgstr "Producto"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:638
+#: code:addons/stock_planning/stock_planning.py:680
+#, python-format
+msgid ""
+"\n"
+"For period: "
+msgstr ""
+"\n"
+"Por periodo: "
+
+#. module: stock_planning
+#: field:stock.sale.forecast,product_uom:0
+msgid "Product UoM"
+msgstr "UdM del producto"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:627
+#: code:addons/stock_planning/stock_planning.py:673
+#: code:addons/stock_planning/stock_planning.py:697
+#, python-format
+msgid "MPS(%s) %s"
+msgstr "Copy text \t MPS(%s) %s"
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:627
+#: code:addons/stock_planning/stock_planning.py:671
+#: code:addons/stock_planning/stock_planning.py:693
+#, python-format
+msgid "MPS("
+msgstr "MPS("
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:680
+#, python-format
+msgid ""
+"Pick created from MPS by user: %s Creation Date: %s "
+" \n"
+"For period: %s according to state: \n"
+" Warehouse Forecast: %s \n"
+" Initial Stock: %s \n"
+" Planned Out: %s Planned In: %s \n"
+" Already Out: %s Already In: %s \n"
+" Confirmed Out: %s Confirmed In: %s \n"
+" Planned Out Before: %s Confirmed In Before: %s "
+" \n"
+" Expected Out: %s Incoming Left: %s \n"
+" Stock Simulation: %s Minimum stock: %s "
+msgstr ""
+
+#. module: stock_planning
+#: field:stock.planning,procure_to_stock:0
+msgid "Procure To Stock Location"
+msgstr "Abastecimiento a ubicación stock"
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid "Approve"
+msgstr "Aprobar"
+
+#. module: stock_planning
+#: help:stock.planning,period_id:0
+msgid ""
+"Period for this planning. Requisition will be created for beginning of the "
+"period."
+msgstr ""
+"Periodo para esta planificación. Se creará una solicitud al principio del "
+"periodo."
+
+#. module: stock_planning
+#: view:stock.sale.forecast:0
+msgid "Calculate Sales History"
+msgstr "Calcular historial de ventas"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,product_amt:0
+msgid "Product Amount"
+msgstr "Cantidad de producto"
+
+#. module: stock_planning
+#: help:stock.planning,confirmed_forecasts_only:0
+msgid ""
+"Check to take validated forecasts only. If not checked system takes "
+"validated and draft forecasts."
+msgstr ""
+"Marcar para usar sólo las previsiones validadas. Si no se marca el sistema "
+"usa las previsiones validadas y borrador."
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_period5_id:0
+msgid "Period5"
+msgstr "Periodo5"
+
+#. module: stock_planning
+#: model:ir.actions.act_window,name:stock_planning.action_stock_period_createlines_form
+msgid "Stock and Sales Planning Periods"
+msgstr "Periodos de planificación de stock y ventas"
+
+#. module: stock_planning
+#: field:stock.sale.forecast,analyzed_warehouse_id:0
+msgid "This Warehouse"
+msgstr "Este almacén"
+
+#. module: stock_planning
+#: model:ir.actions.act_window,name:stock_planning.action_stock_period_form
+#: model:ir.ui.menu,name:stock_planning.menu_stock_period
+#: model:ir.ui.menu,name:stock_planning.menu_stock_period_main
+#: view:stock.period:0
+#: view:stock.period.createlines:0
+msgid "Stock and Sales Periods"
+msgstr "Periodos de stock y ventas"
+
+#. module: stock_planning
+#: help:stock.sale.forecast,user_id:0
+msgid "Shows who created this forecast, or who validated."
+msgstr "Muestra quién creó esta previsión, o quién la validó."
+
+#. module: stock_planning
+#: code:addons/stock_planning/stock_planning.py:644
+#: code:addons/stock_planning/stock_planning.py:686
+#, python-format
+msgid ""
+"\n"
+" Planned Out Before: "
+msgstr ""
+"\n"
+" Salidas planificadas antes: "
+
+#. module: stock_planning
+#: field:stock.planning,stock_start:0
+msgid "Initial Stock"
+msgstr "Stock inicial"