[IMP] Stock Picking Type

bzr revid: fp@openerp.com-20130728124201-jcazoieogux7ehu6
This commit is contained in:
Fabien Pinckaers 2013-07-28 14:42:01 +02:00
parent 90aa53ad15
commit a08801f603
7 changed files with 3257 additions and 18 deletions

View File

@ -101,6 +101,8 @@ Dashboard / Reports for Warehouse Management will include:
'static/src/css/stock.css',
],
'js': [
'static/lib/sparkline/jquery.sparkline.js',
'static/src/js/stock_picking_type.js',
'static/src/js/widgets.js',
'static/src/js/main.js',
],

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,24 @@
openerp.stock = function(openerp) {
openerp.stock.SparklineBarWidget = openerp.web_kanban.AbstractField.extend({
className: "oe_sparkline_bar",
start: function() {
var self = this;
var title = this.$node.html();
setTimeout(function () {
var value = _.pluck(self.field.value, 'value');
var tooltips = _.pluck(self.field.value, 'tooltip');
self.$el.sparkline(value, {
type: 'bar',
barWidth: 5,
tooltipFormat: '{{offset:offset}} {{value}}',
tooltipValueLookups: {
'offset': tooltips
},
});
self.$el.tipsy({'delayIn': 0, 'html': true, 'title': function(){return title}, 'gravity': 'n'});
}, 0);
},
});
openerp.web_kanban.fields_registry.add("stock_sparkline_bar", "openerp.stock.SparklineBarWidget");
};

View File

@ -19,8 +19,9 @@
#
##############################################################################
from datetime import datetime
from dateutil.relativedelta import relativedelta
from datetime import date, datetime
from dateutil import relativedelta
import time
from operator import itemgetter
from itertools import groupby
@ -1970,10 +1971,7 @@ class stock_package(osv.osv):
"""
_name = "stock.quant.package"
_description = "Physical Packages"
_parent_name = "parent_id"
_parent_store = True
_parent_order = 'name'
_order = 'parent_left'
_order = 'name'
def name_get(self, cr, uid, ids, context=None):
res = self._complete_name(cr, uid, ids, 'complete_name', None, context=context)
@ -2271,22 +2269,120 @@ class stock_picking_code(osv.osv):
_name = "stock.picking.code"
_description = "Will group picking types for kanban view"
_columns = {
'name': fields.char("Name", size=30),
}
'name': fields.char("Picking Type", translate=True),
}
class stock_picking_type(osv.osv):
_name = "stock.picking.type"
_description = "The picking type determines the picking view"
def __get_bar_values(self, cr, uid, obj, domain, read_fields, value_field, groupby_field, context=None):
""" Generic method to generate data for bar chart values using SparklineBarWidget.
This method performs obj.read_group(cr, uid, domain, read_fields, groupby_field).
:param obj: the target model (i.e. crm_lead)
:param domain: the domain applied to the read_group
:param list read_fields: the list of fields to read in the read_group
:param str value_field: the field used to compute the value of the bar slice
:param str groupby_field: the fields used to group
:return list section_result: a list of dicts: [
{ 'value': (int) bar_column_value,
'tootip': (str) bar_column_tooltip,
}
]
"""
month_begin = date.today().replace(day=1)
section_result = [{
'value': 0,
'tooltip': (month_begin + relativedelta.relativedelta(months=-i)).strftime('%B'),
} for i in range(10, -1, -1)]
group_obj = obj.read_group(cr, uid, domain, read_fields, groupby_field, context=context)
for group in group_obj:
group_begin_date = datetime.strptime(group['__domain'][0][2], tools.DEFAULT_SERVER_DATE_FORMAT)
month_delta = relativedelta.relativedelta(month_begin, group_begin_date)
section_result[10 - (month_delta.months + 1)] = {'value': group.get(value_field, 0), 'tooltip': group_begin_date.strftime('%B')}
return section_result
def _get_picking_data(self, cr, uid, ids, field_name, arg, context=None):
obj = self.pool.get('stock.picking')
res = dict.fromkeys(ids, False)
month_begin = date.today().replace(day=1)
groupby_begin = (month_begin + relativedelta.relativedelta(months=-4)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
groupby_end = (month_begin + relativedelta.relativedelta(months=3)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
for id in ids:
created_domain = [
('picking_type_id', '=', id),
('state', 'not in', ['draft', 'cancel']),
('date', '>=', groupby_begin),
('date', '<', groupby_end),
]
res[id] = self.__get_bar_values(cr, uid, obj, created_domain, ['date'], '__count', 'date', context=context)
print '_get_picking_data', res
return res
def _get_picking_count(self, cr, uid, ids, field_names, arg, context=None):
obj = self.pool.get('stock.picking')
domains = {
'count_picking': [],
'count_picking_late': [('min_date','<', time.strftime('%Y-%m-%d %H:%M:%S'))],
'count_picking_backorders': [('backorder_id','<>', False)],
}
result = {}
for field in field_names:
data = obj.read_group(cr, uid, domains[field] +
[('state', 'not in',('done','cancel','draft')), ('picking_type_id', 'in', ids)],
['picking_type_id'], ['picking_type_id'], context=context)
count = dict(map(lambda x: (x['picking_type_id'], x['__count']), data))
for tid in ids:
result.setdefault(tid, {})[field] = count.get(tid, 0)
print '_get_picking_count', result
return result
def _get_picking_history(self, cr, uid, ids, field_names, arg, context=None):
obj = self.pool.get('stock.picking')
result = {}
for id in ids:
result[id] = {
'latest_picking_late': [],
'latest_picking_backorders': []
}
for type_id in ids:
pick_ids = obj.search(cr, uid, [('state', '=','done'), ('picking_type_id','=',type_id)], limit=12, order="date desc", context=context)
for pick in obj.browse(cr, uid, pick_ids, context=context):
result[type_id]['latest_picking_late'] = cmp(pick.date[:10], time.strftime('%Y-%m-%d'))
result[type_id]['latest_picking_backorders'] = bool(pick.backorder_id)
print '_get_picking_history', result
return result
_columns = {
'name': fields.char('name', size=30),
'name': fields.char('name', translate=True),
'pack': fields.boolean('Pack', 'This picking type needs packing interface'),
'color': fields.integer('Color Index'),
'delivery': fields.boolean('Print delivery'),
'sequence_id': fields.many2one('ir.sequence', 'Sequence', required = True),
'default_location_src_id': fields.many2one('stock.location', 'Default Source Location'),
'default_location_dest_id': fields.many2one('stock.location', 'Default Destination Location'),
'code_id': fields.many2one('stock.picking.code', 'Picking type code', required = True),
}
# Statistics for the kanban view
'weekly_picking': fields.function(_get_picking_data,
type='string',
string='Scheduled pickings per week'),
'count_picking': fields.function(_get_picking_count,
type='integer', multi='_get_picking_count'),
'count_picking_late': fields.function(_get_picking_count,
type='integer', multi='_get_picking_count'),
'count_picking_backorders': fields.function(_get_picking_count,
type='integer', multi='_get_picking_count'),
'latest_picking_late': fields.function(_get_picking_history,
type='string', multi='_get_picking_history'),
'latest_picking_backorders': fields.function(_get_picking_history,
type='string', multi='_get_picking_history'),
}

View File

@ -115,11 +115,11 @@
</record>
<record id="picking_code_internal" model="stock.picking.code">
<field name="name">Internals</field>
<field name="name">Internal</field>
</record>
<record id="picking_type_in" model="stock.picking.type">
<field name="name">in</field>
<field name="name">Receptions</field>
<field name="sequence_id" ref="seq_picking_type_in"/>
<field name="default_location_src_id" ref="stock_location_suppliers"/>
<field name="default_location_dest_id" ref="stock_location_stock"/>
@ -127,7 +127,7 @@
</record>
<record id="picking_type_out" model="stock.picking.type">
<field name="name">out</field>
<field name="name">Delivery Orders</field>
<field name="sequence_id" ref="seq_picking_type_out"/>
<field name="default_location_src_id" ref="stock_location_stock"/>
<field name="default_location_dest_id" ref="stock_location_customers"/>
@ -135,7 +135,7 @@
</record>
<record id="picking_type_internal" model="stock.picking.type">
<field name="name">internal</field>
<field name="name">Internal Transfers</field>
<field name="sequence_id" ref="seq_picking_type_internal"/>
<field name="code_id" ref="picking_code_internal"/>
</record>

View File

@ -1172,11 +1172,83 @@
</form>
</field>
</record>
<record id="stock_picking_type_kanban" model="ir.ui.view">
<field name="name">stock.picking.type.kanban</field>
<field name="model">stock.picking.type</field>
<field name="arch" type="xml">
<kanban version="7.0" class="oe_background_grey">
<field name="name"/>
<field name="color"/>
<field name="count_picking"/>
<field name="count_picking_late"/>
<field name="count_picking_backorders"/>
<field name="latest_picking_late"/>
<field name="latest_picking_backorders"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_stock_picking_type">
<div class="oe_dropdown_toggle oe_dropdown_kanban" groups="stock.group_stock_manager">
<span class="oe_e">í</span>
<ul class="oe_dropdown_menu">
<li t-if="widget.view.is_action_enabled('edit')"><a type="edit">Settings</a></li>
<li t-if="widget.view.is_action_enabled('delete')"><a type="delete">Delete</a></li>
<li t-if="widget.view.is_action_enabled('edit')"><ul class="oe_kanban_colorpicker" data-field="color"/></li>
</ul>
</div>
<div class="oe_kanban_content">
<h4 class="oe_center"><field name="name"/></h4>
<div class="oe_right">
<a name="%(action_stock_stock_ui)d" type="action">
<img src="/stock/static/src/img/scan.png" alt="Click to launch the barcode interface"/>
</a>
</div>
<div class="oe_items_list">
<div>
<a name="%(action_picking_tree)d" type="action">
<field name="count_picking"/>
<t t-esc="record.name.raw_value"/>
</a>
<a name="%(action_picking_tree)d" type="action" class="oe_sparkline_bar_link">
<field name="weekly_picking" widget="stock_sparkline_bar"/>
</a>
</div>
<div>
<a name="%(action_picking_tree)d" type="action">
<field name="count_picking_late"/>
Late <t t-esc="record.name.raw_value"/>
</a>
<a name="%(action_picking_tree)d" type="action" class="oe_sparkline_bar_link">
<field name="latest_picking_late" widget="sparkline_bar"/>
</a>
</div>
<div>
<a name="%(action_picking_tree)d" type="action">
<field name="count_picking_backorders"/>
Partial <t t-esc="record.name.raw_value"/>
</a>
<a name="%(action_picking_tree)d" type="action" class="oe_sparkline_bar_link">
<field name="latest_picking_backorders" widget="sparkline_bar"/>
</a>
</div>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="action_picking_type_form" model="ir.actions.act_window">
<field name="name">Picking Types</field>
<field name="res_model">stock.picking.type</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,list,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new picking type.
@ -1185,15 +1257,13 @@
operation a specific type which will alter its views accordingly.
On the picking type you could e.g. specify if packing is needed by default,
if it should show the customer.
<br/>
Examples are in, out, internal, packing, quality control, ...
</p>
</field>
</record>
<menuitem
action="action_picking_type_form"
id="menu_action_picking_type_form"
parent="menu_warehouse_config" sequence="1"/>
parent="menu_stock_warehouse_mgmt" sequence="1"/>
<!-- Order Point -->
<record id="view_warehouse_orderpoint_tree" model="ir.ui.view">