summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorJigar Patel <jat@openerp.com>2019-05-10 07:27:16 +0000
committerDharmraj Jhala <dja@odoo.com>2019-10-16 06:09:02 +0000
commit316d5afdd3798ff75a3742e07b0640c84ab177fc (patch)
tree2254b9925b9d0714758fa3ec1322bc159f2b5fb7 /addons
parentf703271c0a79cc5bd989d83695a11f04d348f044 (diff)
[IMP] stock: add hierarchical view for stock location
Diffstat (limited to 'addons')
-rw-r--r--addons/stock/models/stock_location.py26
-rw-r--r--addons/stock/static/src/js/stock_location_hierarchy.js19
-rw-r--r--addons/stock/static/src/scss/stock_location_hierarchy.scss105
-rw-r--r--addons/stock/views/stock_location_views.xml49
-rw-r--r--addons/stock/views/stock_template.xml2
5 files changed, 201 insertions, 0 deletions
diff --git a/addons/stock/models/stock_location.py b/addons/stock/models/stock_location.py
index 6ce9ac1019b..120bc1d590b 100644
--- a/addons/stock/models/stock_location.py
+++ b/addons/stock/models/stock_location.py
@@ -163,6 +163,32 @@ class Location(models.Model):
self.ensure_one()
return self.usage in ('supplier', 'customer', 'inventory', 'production') or self.scrap_location
+ def _qweb_prepare_qcontext(self, view_id, domain):
+ values = super()._qweb_prepare_qcontext(view_id, domain)
+ result = self.search_read(domain, ['name', 'location_id', 'usage', 'barcode'])
+ roots = []
+
+ locations = {location['id']: dict(location, **{'childs': []}) for location in result}
+
+ for location in locations.values():
+ parent_location_id = location['location_id']
+ if parent_location_id and parent_location_id[0] in locations:
+ locations[parent_location_id[0]]['childs'].append(location)
+ else:
+ roots.append(location)
+
+ values['data'] = roots
+ return values
+
+ @api.model
+ def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
+ result = super().fields_view_get(view_id, view_type, toolbar, submenu)
+
+ view_location_qweb = self.env.ref('stock.view_location_qweb', raise_if_not_found=False)
+ if result['type'] == 'qweb' and view_location_qweb and result['view_id'] == view_location_qweb.id:
+ result['arch'] = '<qweb js_class="stock_location_hierarchy_qweb"/>'
+ return result
+
class Route(models.Model):
_name = 'stock.location.route'
diff --git a/addons/stock/static/src/js/stock_location_hierarchy.js b/addons/stock/static/src/js/stock_location_hierarchy.js
new file mode 100644
index 00000000000..29fb287de3f
--- /dev/null
+++ b/addons/stock/static/src/js/stock_location_hierarchy.js
@@ -0,0 +1,19 @@
+odoo.define('stock.stock_location_hierarchy_qweb', function (require) {
+"use strict";
+
+var QwebView = require('web.qweb');
+var registry = require('web.view_registry');
+
+
+var QWebView = QwebView.View.extend({
+ icon: 'fa-sitemap',
+ searchMenuTypes: ['filter', 'favorite'],
+});
+
+registry.add('stock_location_hierarchy_qweb', QWebView);
+
+return {
+ View: QWebView,
+};
+
+});
diff --git a/addons/stock/static/src/scss/stock_location_hierarchy.scss b/addons/stock/static/src/scss/stock_location_hierarchy.scss
new file mode 100644
index 00000000000..6ea799ff508
--- /dev/null
+++ b/addons/stock/static/src/scss/stock_location_hierarchy.scss
@@ -0,0 +1,105 @@
+$o-hierarchical-highlight-color: $o-brand-primary;
+$o-hierarchical-border-color: gray('500');
+$o-hierarchical-border-width: 1px;
+$o-hierarchical-border-radius: 4px;
+
+@mixin o-stock-hierarchy-level {
+ position: relative;
+ padding: 1em 0;
+ text-align: center;
+}
+
+.o_stock_location_hierarchy {
+ .o_hierarchy_container {
+ border: 1px solid gray('300');
+ background-color: lighten(gray('200'), 2%);
+ border-radius: .5rem;
+ white-space: nowrap;
+ overflow-x: auto;
+ @include o-stock-hierarchy-level();
+ ul.o_hierarchy_level {
+ @include o-stock-hierarchy-level();
+ &:before {
+ content: '';
+ @include o-position-absolute($top: 0, $left: 50%);
+ border-left: $o-hierarchical-border-width solid $o-hierarchical-border-color;
+ height: 1.2rem;
+ }
+ }
+ li.o_hierarchy_item {
+ display: inline-block;
+ vertical-align: top;
+ position: relative;
+ padding: 1rem .5rem 0 .5rem;
+ .o_hierarchy_box {
+ position: relative;
+ border: $o-hierarchical-border-width solid gray('white');
+ padding: .5rem .75rem;
+ display: inline-block;
+ border-radius: $o-hierarchical-border-radius;
+ transition: 0.2s;
+ background: gray('white');
+ box-shadow: 0 1px 3px rgba(gray('black'), 0.12), 0 1px 2px rgba(gray('black'), 0.14);
+ &.disabled {
+ background-color: #f1f1f1;
+ border-color: #f1f1f1;
+ }
+ .o_hierarchy_box_title, .o_hierarchy_box_subtitle {
+ max-width: 170px;
+ }
+ .o_hierarchy_action {
+ display: none;
+ @include o-position-absolute($left: 0, $right: 0, $bottom: -10px);
+ z-index: 1;
+ .o_hierarchy_add_child .fa {
+ background-color: gray('white');
+ border-radius: 8rem;
+ }
+ }
+ @include media-breakpoint-up(md) {
+ &:hover .o_hierarchy_action {
+ display: block;
+ }
+ &:hover, &:hover + ul li .o_hierarchy_box {
+ background: lighten($o-hierarchical-highlight-color, 65);
+ border: $o-hierarchical-border-width solid $o-hierarchical-highlight-color;
+ }
+ &:hover + ul li::after,
+ &:hover + ul li::before,
+ &:hover + ul::before,
+ &:hover + ul ul::before {
+ border-color: $o-hierarchical-highlight-color;
+ }
+ }
+ }
+ &::before, &::after {
+ content: '';
+ @include o-position-absolute($top: 0, $right: 50%);
+ border-top: $o-hierarchical-border-width solid $o-hierarchical-border-color;
+ width: 52%;
+ height: 1em;
+ }
+ &::after {
+ right: auto;
+ left: 50%;
+ border-left: $o-hierarchical-border-width solid $o-hierarchical-border-color;
+ }
+ &:only-child::after, &:only-child::before {
+ display: none;
+ }
+ &:only-child {
+ padding-top: 0;
+ }
+ &:first-child::before, &:last-child::after {
+ border: 0 none;
+ }
+ &:last-child::before {
+ border-right: $o-hierarchical-border-width solid $o-hierarchical-border-color;
+ border-radius: 0 $o-hierarchical-border-radius 0 0;
+ }
+ &:first-child::after {
+ border-radius: $o-hierarchical-border-radius 0 0 0;
+ }
+ }
+ }
+}
diff --git a/addons/stock/views/stock_location_views.xml b/addons/stock/views/stock_location_views.xml
index dc0b83af390..7d0ea34a729 100644
--- a/addons/stock/views/stock_location_views.xml
+++ b/addons/stock/views/stock_location_views.xml
@@ -53,6 +53,53 @@
</field>
</record>
+ <record id="view_location_qweb" model="ir.ui.view">
+ <field name="name">stock.location.qweb</field>
+ <field name="type">qweb</field>
+ <field name="model">stock.location</field>
+ <field name="arch" type="xml">
+ <div class="container-fluid o_stock_location_hierarchy">
+ <div class="row">
+ <t t-if="data">
+ <div class="col-12 py-3" t-foreach="data" t-as="location">
+ <ul class="o_hierarchy_container mb-0">
+ <t t-call="stock.stock_location_hierarchy"/>
+ </ul>
+ </div>
+ </t>
+ <t t-else="">
+ <div class="col py-4 text-center">
+ <h1>No data available.</h1>
+ </div>
+ </t>
+ </div>
+ </div>
+ </field>
+ </record>
+
+ <template id="stock_location_hierarchy" name="Stock Location Hierarchy">
+ <li class="o_hierarchy_item">
+ <div t-attf-class="o_hierarchy_box #{location['usage'] == 'view' and 'disabled' or ''}">
+ <a href="#" type="action" t-att-data-res-id="location['id']" class="o_hierarchy_box_title text-truncate" t-att-title="location['name']">
+ <t t-esc="location['name']"/>
+ </a>
+ <small class="o_hierarchy_box_subtitle text-truncate text-muted d-block" t-att-title="location['barcode']">
+ <t t-esc="location['barcode']"/>
+ </small>
+ <div class="o_hierarchy_action">
+ <a href="#" type="action" data-views='[[false, "form"]]' t-attf-data-context='{"default_location_id": #{location["id"]}}' class="o_hierarchy_add_child" title="Add a new child record">
+ <i class="fa fa-plus-circle"/>
+ </a>
+ </div>
+ </div>
+ <ul class="o_hierarchy_level" t-if="len(location['childs'])">
+ <t t-foreach="location['childs']" t-as="location">
+ <t t-call="stock.stock_location_hierarchy"/>
+ </t>
+ </ul>
+ </li>
+ </template>
+
<record id="stock_location_view_form_editable" model="ir.ui.view">
<field name="name">stock.location.form.editable</field>
<field name="model">stock.location</field>
@@ -111,6 +158,8 @@
<field name="name">Locations</field>
<field name="res_model">stock.location</field>
<field name="type">ir.actions.act_window</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">tree,form,qweb</field>
<field name="view_id" ref="view_location_tree2"/>
<field name="search_view_id" ref="view_location_search"/>
<field name="context">{'search_default_in_location':1}</field>
diff --git a/addons/stock/views/stock_template.xml b/addons/stock/views/stock_template.xml
index 64561ddd527..54bad8cea54 100644
--- a/addons/stock/views/stock_template.xml
+++ b/addons/stock/views/stock_template.xml
@@ -11,7 +11,9 @@
<script type="text/javascript" src="/stock/static/src/js/inventory_validate_button_view.js"></script>
<script type="text/javascript" src="/stock/static/src/js/stock_traceability_report_backend.js"></script>
<script type="text/javascript" src="/stock/static/src/js/stock_traceability_report_widgets.js"></script>
+ <script type="text/javascript" src="/stock/static/src/js/stock_location_hierarchy.js"></script>
<link rel="stylesheet" type="text/scss" href="/stock/static/src/scss/stock_traceability_report.scss"/>
+ <link rel="stylesheet" type="text/scss" href="/stock/static/src/scss/stock_location_hierarchy.scss"/>
</xpath>
</template>