[IMP] Stock Picking Type
bzr revid: fp@openerp.com-20130728124201-jcazoieogux7ehu6
This commit is contained in:
parent
90aa53ad15
commit
a08801f603
|
@ -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 |
|
@ -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");
|
||||
|
||||
};
|
|
@ -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'),
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Reference in New Issue