odoo-addon-shopfloor-mobile 16.0.1.0.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odoo/addons/shopfloor_mobile/README.rst +215 -0
- odoo/addons/shopfloor_mobile/__init__.py +0 -0
- odoo/addons/shopfloor_mobile/__manifest__.py +17 -0
- odoo/addons/shopfloor_mobile/i18n/es_AR.po +39 -0
- odoo/addons/shopfloor_mobile/i18n/pt_BR.po +14 -0
- odoo/addons/shopfloor_mobile/i18n/shopfloor_mobile.pot +13 -0
- odoo/addons/shopfloor_mobile/readme/CONTRIBUTORS.rst +12 -0
- odoo/addons/shopfloor_mobile/readme/CREDITS.rst +5 -0
- odoo/addons/shopfloor_mobile/readme/DESCRIPTION.rst +31 -0
- odoo/addons/shopfloor_mobile/readme/HISTORY.rst +4 -0
- odoo/addons/shopfloor_mobile/readme/ROADMAP.rst +29 -0
- odoo/addons/shopfloor_mobile/readme/USAGE.rst +34 -0
- odoo/addons/shopfloor_mobile/static/description/icon.png +0 -0
- odoo/addons/shopfloor_mobile/static/description/index.html +555 -0
- odoo/addons/shopfloor_mobile/static/wms/.gitignore +21 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/batch_picking_detail.js +69 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/batch_picking_line_detail.js +141 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_location.js +66 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_lot.js +91 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_operation.js +50 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_package.js +73 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_picking.js +40 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_product.js +70 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_transfer.js +128 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/forms/form_edit_stock_picking.js +39 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/manual_select_color.js +24 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/misc.js +201 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/packaging-qty-picker.js +329 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/scenario_picking_detail/mixins.js +130 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/scenario_picking_detail/picking_select.js +135 -0
- odoo/addons/shopfloor_mobile/static/wms/src/components/scenario_picking_detail/picking_summary.js +212 -0
- odoo/addons/shopfloor_mobile/static/wms/src/css/main.css +73 -0
- odoo/addons/shopfloor_mobile/static/wms/src/css/normalize.css +351 -0
- odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.checkout.js +257 -0
- odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.cluster_picking.js +188 -0
- odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.delivery.js +79 -0
- odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.location_content_transfer.js +179 -0
- odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.scan_anything.js +124 -0
- odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.single_pack_transfer.js +83 -0
- odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.zone_picking.js +277 -0
- odoo/addons/shopfloor_mobile/static/wms/src/i18n/add_translations_to_registry.js +4 -0
- odoo/addons/shopfloor_mobile/static/wms/src/i18n/en.json +31 -0
- odoo/addons/shopfloor_mobile/static/wms/src/i18n/fr.json +27 -0
- odoo/addons/shopfloor_mobile/static/wms/src/scenario/checkout.js +390 -0
- odoo/addons/shopfloor_mobile/static/wms/src/scenario/checkout_states.js +380 -0
- odoo/addons/shopfloor_mobile/static/wms/src/scenario/cluster_picking.js +481 -0
- odoo/addons/shopfloor_mobile/static/wms/src/scenario/delivery.js +353 -0
- odoo/addons/shopfloor_mobile/static/wms/src/scenario/location_content_transfer.js +388 -0
- odoo/addons/shopfloor_mobile/static/wms/src/scenario/single_pack_transfer.js +132 -0
- odoo/addons/shopfloor_mobile/static/wms/src/scenario/zone_picking.js +838 -0
- odoo/addons/shopfloor_mobile/static/wms/src/screen.js +36 -0
- odoo/addons/shopfloor_mobile/static/wms/src/wms_utils.js +318 -0
- odoo/addons/shopfloor_mobile/templates/assets.xml +180 -0
- odoo_addon_shopfloor_mobile-16.0.1.0.0.6.dist-info/METADATA +235 -0
- odoo_addon_shopfloor_mobile-16.0.1.0.0.6.dist-info/RECORD +57 -0
- odoo_addon_shopfloor_mobile-16.0.1.0.0.6.dist-info/WHEEL +5 -0
- odoo_addon_shopfloor_mobile-16.0.1.0.0.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
|
|
3
|
+
* @author Simone Orsi <simahawk@gmail.com>
|
|
4
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// TODO: rename as we used this not only for batch picking
|
|
8
|
+
export var batch_picking_line = Vue.component("batch-picking-line-detail", {
|
|
9
|
+
props: {
|
|
10
|
+
line: Object,
|
|
11
|
+
articleScanned: {
|
|
12
|
+
type: Boolean,
|
|
13
|
+
default: false,
|
|
14
|
+
},
|
|
15
|
+
showQtyPicker: {
|
|
16
|
+
type: Boolean,
|
|
17
|
+
default: false,
|
|
18
|
+
},
|
|
19
|
+
defaultDestinationKey: {
|
|
20
|
+
type: String,
|
|
21
|
+
default: "package_dest",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
data() {
|
|
25
|
+
return {
|
|
26
|
+
dialog: false,
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
computed: {
|
|
30
|
+
destination() {
|
|
31
|
+
return _.result(this.line, this.$props.defaultDestinationKey);
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
template: `
|
|
35
|
+
<div v-if="!_.isEmpty(line)" :class="'detail batch-picking-line-detail ' + (line.postponed ? 'line-postponed' : '')">
|
|
36
|
+
|
|
37
|
+
<item-detail-card
|
|
38
|
+
:key="'batch-picking-line-detail-1'"
|
|
39
|
+
:record="line"
|
|
40
|
+
:options="{main: true, key_title: 'location_src.name', title_action_field: {action_val_path: 'location_src.barcode'}}"
|
|
41
|
+
:card_color="utils.colors.color_for(articleScanned ? 'screen_step_done': 'screen_step_todo')"
|
|
42
|
+
/>
|
|
43
|
+
<item-detail-card
|
|
44
|
+
:key="'batch-picking-line-detail-2'"
|
|
45
|
+
:record="line"
|
|
46
|
+
:options="utils.wms.move_line_product_detail_options(line, {fields_blacklist: ['quantity']})"
|
|
47
|
+
:card_color="utils.colors.color_for(articleScanned ? 'screen_step_done': 'screen_step_todo')"
|
|
48
|
+
/>
|
|
49
|
+
|
|
50
|
+
<item-detail-card
|
|
51
|
+
v-if="articleScanned && destination"
|
|
52
|
+
:key="'batch-picking-line-detail-3'"
|
|
53
|
+
:record="line"
|
|
54
|
+
:options="{main: true, key_title: defaultDestinationKey + '.name', title_action_field: {action_val_path: defaultDestinationKey + '.name'}}"
|
|
55
|
+
:card_color="utils.colors.color_for('screen_step_todo')"
|
|
56
|
+
/>
|
|
57
|
+
|
|
58
|
+
<v-card class="pa-2" :color="utils.colors.color_for('screen_step_todo')">
|
|
59
|
+
<packaging-qty-picker
|
|
60
|
+
:key="make_component_key(['packaging-qty-picker', line.id])"
|
|
61
|
+
v-bind="utils.wms.move_line_qty_picker_props(line, {qtyInit: showQtyPicker ? line.qty_done : line.quantity})"
|
|
62
|
+
:readonly="!showQtyPicker"
|
|
63
|
+
/>
|
|
64
|
+
</v-card>
|
|
65
|
+
|
|
66
|
+
<item-detail-card
|
|
67
|
+
v-if="articleScanned && !destination"
|
|
68
|
+
:key="'batch-picking-line-detail-4'"
|
|
69
|
+
:record="line"
|
|
70
|
+
:options="{main: true, title_action_field: {action_val_path: 'name'}}"
|
|
71
|
+
:card_color="utils.colors.color_for(destination ? 'screen_step_done': 'screen_step_todo')"
|
|
72
|
+
>
|
|
73
|
+
<template v-slot:title>
|
|
74
|
+
Destination not selected.
|
|
75
|
+
</template>
|
|
76
|
+
</item-detail-card>
|
|
77
|
+
|
|
78
|
+
</div>
|
|
79
|
+
`,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// TODO: use `misc.line-actions-popup` instead
|
|
83
|
+
export var batch_picking_line_actions = Vue.component("batch-picking-line-actions", {
|
|
84
|
+
props: ["line"],
|
|
85
|
+
data() {
|
|
86
|
+
return {
|
|
87
|
+
dialog: false,
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
methods: {
|
|
91
|
+
handle_action(action) {
|
|
92
|
+
this.$emit("action", action);
|
|
93
|
+
this.dialog = false;
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
template: `
|
|
97
|
+
<div class="batch-picking-line-actions">
|
|
98
|
+
<v-dialog v-model="dialog" fullscreen tile class="actions fullscreen text-center">
|
|
99
|
+
<template v-slot:activator="{ on }">
|
|
100
|
+
<div class="button-list button-vertical-list full">
|
|
101
|
+
<v-row class="actions bottom-actions">
|
|
102
|
+
<v-col class="text-center" cols="12">
|
|
103
|
+
<btn-action v-on="on">Action</btn-action>
|
|
104
|
+
</v-col>
|
|
105
|
+
</v-row>
|
|
106
|
+
</div>
|
|
107
|
+
</template>
|
|
108
|
+
<v-card>
|
|
109
|
+
<div class="button-list button-vertical-list full">
|
|
110
|
+
<v-row align="center">
|
|
111
|
+
<v-col class="text-center" cols="12">
|
|
112
|
+
<btn-action @click="handle_action('action_full_bin')">Go to destination - full bin(s)</btn-action>
|
|
113
|
+
</v-col>
|
|
114
|
+
</v-row>
|
|
115
|
+
<v-row align="center">
|
|
116
|
+
<v-col class="text-center" cols="12">
|
|
117
|
+
<btn-action @click="handle_action('action_skip_line')">Skip line</btn-action>
|
|
118
|
+
</v-col>
|
|
119
|
+
</v-row>
|
|
120
|
+
<v-row align="center">
|
|
121
|
+
<v-col class="text-center" cols="12">
|
|
122
|
+
<btn-action
|
|
123
|
+
@click="handle_action('action_stock_out')">Declare stock out</btn-action>
|
|
124
|
+
</v-col>
|
|
125
|
+
</v-row>
|
|
126
|
+
<v-row align="center">
|
|
127
|
+
<v-col class="text-center" cols="12">
|
|
128
|
+
<btn-action @click="handle_action('action_change_pack_or_lot')">Change lot or pack</btn-action>
|
|
129
|
+
</v-col>
|
|
130
|
+
</v-row>
|
|
131
|
+
<v-row align="center">
|
|
132
|
+
<v-col class="text-center" cols="12">
|
|
133
|
+
<v-btn x-large @click="dialog = false">Back</v-btn>
|
|
134
|
+
</v-col>
|
|
135
|
+
</v-row>
|
|
136
|
+
</div>
|
|
137
|
+
</v-card>
|
|
138
|
+
</v-dialog>
|
|
139
|
+
</div>
|
|
140
|
+
`,
|
|
141
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
|
|
3
|
+
* @author Simone Orsi <simahawk@gmail.com>
|
|
4
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {ItemDetailMixin} from "/shopfloor_mobile_base/static/wms/src/components/detail/detail_mixin.js";
|
|
8
|
+
|
|
9
|
+
Vue.component("detail-location", {
|
|
10
|
+
mixins: [ItemDetailMixin],
|
|
11
|
+
methods: {
|
|
12
|
+
product_list_options() {
|
|
13
|
+
return {
|
|
14
|
+
key_title: "display_name",
|
|
15
|
+
card_klass: "loud-labels",
|
|
16
|
+
list_item_options: {
|
|
17
|
+
fields: this.product_list_fields(),
|
|
18
|
+
list_item_klass_maker: this.utils.wms.move_line_color_klass,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
product_list_fields() {
|
|
23
|
+
return [
|
|
24
|
+
{
|
|
25
|
+
path: "product.display_name",
|
|
26
|
+
action_val_path: "product.barcode",
|
|
27
|
+
klass: "loud",
|
|
28
|
+
},
|
|
29
|
+
{path: "product.supplier_code", label: "Vendor code", klass: "loud"},
|
|
30
|
+
{
|
|
31
|
+
path: "package_src.name",
|
|
32
|
+
label: "Pack",
|
|
33
|
+
action_val_path: "package_src.name",
|
|
34
|
+
},
|
|
35
|
+
{path: "lot.name", label: "Lot", action_val_path: "lot.name"},
|
|
36
|
+
{path: "product.qty_reserved", label: "Qty reserved"},
|
|
37
|
+
{path: "product.qty_available", label: "Qty in stock"},
|
|
38
|
+
];
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
template: `
|
|
42
|
+
<div :class="$options._componentTag">
|
|
43
|
+
<item-detail-card
|
|
44
|
+
v-bind="$props"
|
|
45
|
+
:options="{main: true}"
|
|
46
|
+
:card_color="utils.colors.color_for('detail_main_card')">
|
|
47
|
+
|
|
48
|
+
<template v-slot:subtitle>
|
|
49
|
+
{{ record.complete_name }}
|
|
50
|
+
</template>
|
|
51
|
+
|
|
52
|
+
</item-detail-card>
|
|
53
|
+
|
|
54
|
+
<div class="products" v-if="record.reserved_move_lines.length">
|
|
55
|
+
<separator-title>Reserved products</separator-title>
|
|
56
|
+
|
|
57
|
+
<list
|
|
58
|
+
:records="record.reserved_move_lines"
|
|
59
|
+
:options="product_list_options()"
|
|
60
|
+
/>
|
|
61
|
+
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
</div>
|
|
65
|
+
`,
|
|
66
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
|
|
3
|
+
* @author Simone Orsi <simahawk@gmail.com>
|
|
4
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {ItemDetailMixin} from "/shopfloor_mobile_base/static/wms/src/components/detail/detail_mixin.js";
|
|
8
|
+
|
|
9
|
+
// TODO: this should be probably merged or combined w/ detail-product
|
|
10
|
+
Vue.component("detail-lot", {
|
|
11
|
+
mixins: [ItemDetailMixin],
|
|
12
|
+
methods: {
|
|
13
|
+
lot_detail_options() {
|
|
14
|
+
return {
|
|
15
|
+
main: true,
|
|
16
|
+
key_title: "name",
|
|
17
|
+
fields: this.lot_detail_fields(),
|
|
18
|
+
klass: "loud-labels",
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
lot_detail_fields() {
|
|
22
|
+
const self = this;
|
|
23
|
+
return [
|
|
24
|
+
{
|
|
25
|
+
path: "expire_date",
|
|
26
|
+
label: "Expiry date",
|
|
27
|
+
renderer: function (rec, field) {
|
|
28
|
+
return self.utils.display.render_field_date(rec, field);
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
path: "removal_date",
|
|
33
|
+
label: "Removal date",
|
|
34
|
+
renderer: function (rec, field) {
|
|
35
|
+
return self.utils.display.render_field_date(rec, field);
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
},
|
|
40
|
+
supplier_detail_fields() {
|
|
41
|
+
return [
|
|
42
|
+
{path: "name", klass: "loud"},
|
|
43
|
+
{path: "product_code", label: "Code"},
|
|
44
|
+
{path: "product_name", label: "Name"},
|
|
45
|
+
];
|
|
46
|
+
},
|
|
47
|
+
render_packaging(record, field) {
|
|
48
|
+
return [record.name, "(" + record.code + ")", "= " + record.qty].join(" ");
|
|
49
|
+
},
|
|
50
|
+
packaging_detail_fields() {
|
|
51
|
+
return [{path: "name", renderer: this.render_packaging}];
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
template: `
|
|
55
|
+
<div :class="$options._componentTag">
|
|
56
|
+
<item-detail-card
|
|
57
|
+
v-bind="$props"
|
|
58
|
+
:key="make_component_key(['product'])"
|
|
59
|
+
:options="{main: true, key_title: 'product.display_name'}"
|
|
60
|
+
:card_color="utils.colors.color_for('detail_main_card')"
|
|
61
|
+
/>
|
|
62
|
+
|
|
63
|
+
<!-- TODO: handle image here -->
|
|
64
|
+
|
|
65
|
+
<item-detail-card
|
|
66
|
+
v-bind="$props"
|
|
67
|
+
:key="make_component_key(['lot'])"
|
|
68
|
+
:options="lot_detail_options()"
|
|
69
|
+
:card_color="utils.colors.color_for('detail_main_card')"
|
|
70
|
+
/>
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
<div class="suppliers mb-4" v-if="record.product.suppliers.length">
|
|
74
|
+
<separator-title>Suppliers</separator-title>
|
|
75
|
+
<item-detail-card
|
|
76
|
+
v-for="supp in record.product.suppliers"
|
|
77
|
+
:key="'supp' + supp.id"
|
|
78
|
+
:record="supp"
|
|
79
|
+
:options="{no_title: true, fields: supplier_detail_fields()}" />
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div class="packaging pb-2" v-if="opts.full_detail && record.product.packaging">
|
|
83
|
+
<separator-title>Packaging</separator-title>
|
|
84
|
+
<list
|
|
85
|
+
:records="record.product.packaging"
|
|
86
|
+
:options="{key_title: 'display_name', list_item_fields: packaging_detail_fields()}"
|
|
87
|
+
/>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
`,
|
|
91
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
|
|
3
|
+
* @author Simone Orsi <simahawk@gmail.com>
|
|
4
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {ItemDetailMixin} from "/shopfloor_mobile_base/static/wms/src/components/detail/detail_mixin.js";
|
|
8
|
+
|
|
9
|
+
// TODO: this should probably trashed in favour of detail-transfer
|
|
10
|
+
// ATM is used only by single pack transfer to display package level info.
|
|
11
|
+
Vue.component("detail-operation", {
|
|
12
|
+
mixins: [ItemDetailMixin],
|
|
13
|
+
methods: {
|
|
14
|
+
detail_fields() {
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
path: "location_src.name",
|
|
18
|
+
label: "Source",
|
|
19
|
+
action_val_path: "location_src.barcode",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
path: "location_dest.name",
|
|
23
|
+
label: "Destination",
|
|
24
|
+
action_val_path: "location_dest.barcode",
|
|
25
|
+
},
|
|
26
|
+
{path: "product.display_name", action_val_path: "product.barcode"},
|
|
27
|
+
{path: "product.supplier_code", label: "Vendor code", klass: "loud"},
|
|
28
|
+
{path: "package_dest.name", action_val_path: "package_dest.barcode"},
|
|
29
|
+
{path: "lot.name", action_val_path: "lot.barcode"},
|
|
30
|
+
];
|
|
31
|
+
},
|
|
32
|
+
op_card_options() {
|
|
33
|
+
return {
|
|
34
|
+
loud: true,
|
|
35
|
+
no_title: true,
|
|
36
|
+
fields: this.detail_fields(),
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
template: `
|
|
41
|
+
<div :class="$options._componentTag">
|
|
42
|
+
<detail-picking
|
|
43
|
+
:key="record.picking.id"
|
|
44
|
+
:record="record.picking"
|
|
45
|
+
:options="{main: true}"
|
|
46
|
+
/>
|
|
47
|
+
<item-detail-card v-bind="$props" :options="op_card_options()" />
|
|
48
|
+
</div>
|
|
49
|
+
`,
|
|
50
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
|
|
3
|
+
* @author Simone Orsi <simahawk@gmail.com>
|
|
4
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {ItemDetailMixin} from "/shopfloor_mobile_base/static/wms/src/components/detail/detail_mixin.js";
|
|
8
|
+
|
|
9
|
+
Vue.component("detail-package", {
|
|
10
|
+
mixins: [ItemDetailMixin],
|
|
11
|
+
methods: {
|
|
12
|
+
detail_fields() {
|
|
13
|
+
return [
|
|
14
|
+
{path: "location.name", label: "Location"},
|
|
15
|
+
{path: "weight", label: "Weight (kg)"},
|
|
16
|
+
{path: "packaging.name", label: "Packaging"},
|
|
17
|
+
{path: "storage_type.name", label: "Storage type"},
|
|
18
|
+
{path: "package_type.name", label: "Package type"},
|
|
19
|
+
];
|
|
20
|
+
},
|
|
21
|
+
product_list_options() {
|
|
22
|
+
return {
|
|
23
|
+
card_klass: "loud-labels",
|
|
24
|
+
key_title: "",
|
|
25
|
+
list_item_options: {
|
|
26
|
+
fields: this.product_list_fields(),
|
|
27
|
+
list_item_klass_maker: this.utils.wms.move_line_color_klass,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
product_list_fields() {
|
|
32
|
+
return [
|
|
33
|
+
{
|
|
34
|
+
path: "product.display_name",
|
|
35
|
+
action_val_path: "product.barcode",
|
|
36
|
+
klass: "loud",
|
|
37
|
+
},
|
|
38
|
+
{path: "product.barcode", label: "Barcode"},
|
|
39
|
+
{path: "product.supplier_code", label: "Vendor code"},
|
|
40
|
+
{path: "lot.name", label: "Lot"},
|
|
41
|
+
{path: "quantity", label: "Reserved"},
|
|
42
|
+
{path: "product.qty_available", label: "In stock"},
|
|
43
|
+
];
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
template: `
|
|
47
|
+
<div :class="$options._componentTag">
|
|
48
|
+
<item-detail-card
|
|
49
|
+
v-bind="$props"
|
|
50
|
+
:options="{main: true, fields: detail_fields(), klass: 'loud-labels'}"
|
|
51
|
+
:card_color="utils.colors.color_for('detail_main_card')"
|
|
52
|
+
/>
|
|
53
|
+
|
|
54
|
+
<div class="products mb-4" v-if="(record.move_lines || []).length">
|
|
55
|
+
<separator-title>Products</separator-title>
|
|
56
|
+
<list
|
|
57
|
+
:records="record.move_lines"
|
|
58
|
+
:options="product_list_options()"
|
|
59
|
+
:key="make_component_key(['product-list'])"
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div class="pickings" v-if="(record.pickings || []).length">
|
|
64
|
+
<separator-title>Transfers</separator-title>
|
|
65
|
+
<detail-picking
|
|
66
|
+
v-for="picking in record.pickings"
|
|
67
|
+
:record="picking"
|
|
68
|
+
:key="make_component_key(['picking', picking.id])"
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
`,
|
|
73
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
|
|
3
|
+
* @author Simone Orsi <simahawk@gmail.com>
|
|
4
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export var PickingDetailMixin = {
|
|
8
|
+
props: {
|
|
9
|
+
record: Object,
|
|
10
|
+
options: Object,
|
|
11
|
+
},
|
|
12
|
+
computed: {
|
|
13
|
+
opts() {
|
|
14
|
+
const opts = _.defaults({}, this.$props.options, {
|
|
15
|
+
title_action_field: {path: "name", action_val_path: "name"},
|
|
16
|
+
});
|
|
17
|
+
return opts;
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
template: `
|
|
21
|
+
<item-detail-card :record="record" :options="opts" v-bind="$attrs">
|
|
22
|
+
<template v-slot:subtitle>
|
|
23
|
+
<span class="origin" v-if="record.origin">
|
|
24
|
+
<span>{{ record.origin }}</span>
|
|
25
|
+
</span>
|
|
26
|
+
<span v-if="record.origin && record.partner"> - </span>
|
|
27
|
+
<span class="partner" v-if="record.partner">
|
|
28
|
+
<span>{{ record.partner.name }}</span>
|
|
29
|
+
</span>
|
|
30
|
+
</template>
|
|
31
|
+
<template v-slot:after_details>
|
|
32
|
+
<slot name="actions"></slot>
|
|
33
|
+
</template>
|
|
34
|
+
</item-detail-card>
|
|
35
|
+
`,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
Vue.component("detail-picking", {
|
|
39
|
+
mixins: [PickingDetailMixin],
|
|
40
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
|
|
3
|
+
* @author Simone Orsi <simahawk@gmail.com>
|
|
4
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {ItemDetailMixin} from "/shopfloor_mobile_base/static/wms/src/components/detail/detail_mixin.js";
|
|
8
|
+
|
|
9
|
+
// TODO: refactor according to new data from backend and maybe merge w/ `detail-lot`
|
|
10
|
+
Vue.component("detail-product", {
|
|
11
|
+
mixins: [ItemDetailMixin],
|
|
12
|
+
methods: {
|
|
13
|
+
product_detail_fields() {
|
|
14
|
+
const fields = [{path: "package_dest.name"}, {path: "lot.name"}];
|
|
15
|
+
return this.opts.full_detail
|
|
16
|
+
? _.concat(fields, this.full_detail_fields())
|
|
17
|
+
: fields;
|
|
18
|
+
},
|
|
19
|
+
full_detail_fields() {
|
|
20
|
+
return [
|
|
21
|
+
// Image TODO
|
|
22
|
+
{path: "lot.name", label: "Lot"},
|
|
23
|
+
{path: "expiry_date", label: "Expiry date"},
|
|
24
|
+
{path: "default_code", label: "Internal ref"},
|
|
25
|
+
{path: "barcode", label: "Barcode"},
|
|
26
|
+
{path: "product.supplier_code", label: "Supplier ref"},
|
|
27
|
+
];
|
|
28
|
+
},
|
|
29
|
+
packaging_detail_fields() {
|
|
30
|
+
return [{path: "name", renderer: this.render_packaging}];
|
|
31
|
+
},
|
|
32
|
+
supplier_detail_fields() {
|
|
33
|
+
return [
|
|
34
|
+
{path: "name", klass: "loud"},
|
|
35
|
+
{path: "product_code", label: "Code"},
|
|
36
|
+
{path: "product_name", label: "Name"},
|
|
37
|
+
];
|
|
38
|
+
},
|
|
39
|
+
render_packaging(record, field) {
|
|
40
|
+
return [record.name, "(" + record.code + ")", "= " + record.qty].join(" ");
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
template: `
|
|
44
|
+
<div :class="$options._componentTag">
|
|
45
|
+
<item-detail-card
|
|
46
|
+
v-bind="$props"
|
|
47
|
+
:options="{main: true, fields: product_detail_fields(), key_title: 'display_name'}"
|
|
48
|
+
card_color="info lighten-3"
|
|
49
|
+
/>
|
|
50
|
+
|
|
51
|
+
<div class="suppliers mb-4" v-if="_.result(record, 'suppliers', []).length">
|
|
52
|
+
<separator-title>Suppliers</separator-title>
|
|
53
|
+
<item-detail-card
|
|
54
|
+
v-for="supp in record.suppliers"
|
|
55
|
+
:key="'supp' + supp.id"
|
|
56
|
+
:record="supp"
|
|
57
|
+
:options="{no_title: true, fields: supplier_detail_fields()}"
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div class="packaging mb-4" v-if="opts.full_detail && record.packaging">
|
|
62
|
+
<separator-title>Packaging</separator-title>
|
|
63
|
+
<list
|
|
64
|
+
:records="record.packaging"
|
|
65
|
+
:options="{key_title: 'display_name', list_item_fields: packaging_detail_fields()}"
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
`,
|
|
70
|
+
});
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
|
|
3
|
+
* @author Simone Orsi <simahawk@gmail.com>
|
|
4
|
+
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {ItemDetailMixin} from "/shopfloor_mobile_base/static/wms/src/components/detail/detail_mixin.js";
|
|
8
|
+
|
|
9
|
+
Vue.component("detail-transfer", {
|
|
10
|
+
mixins: [ItemDetailMixin],
|
|
11
|
+
methods: {
|
|
12
|
+
detail_fields() {
|
|
13
|
+
const self = this;
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
path: "scheduled_date",
|
|
17
|
+
label: "Scheduled on",
|
|
18
|
+
renderer: function (rec, field) {
|
|
19
|
+
return self.utils.display.render_field_date(rec, field);
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
path: "operation_type.name",
|
|
24
|
+
label: "Operation type",
|
|
25
|
+
},
|
|
26
|
+
{path: "carrier.name", label: "Carrier"},
|
|
27
|
+
{path: "priority", label: "Priority"},
|
|
28
|
+
{path: "note"},
|
|
29
|
+
];
|
|
30
|
+
},
|
|
31
|
+
picking_detail_options() {
|
|
32
|
+
return _.defaults({}, this.opts, {
|
|
33
|
+
main: true,
|
|
34
|
+
klass: "loud-labels",
|
|
35
|
+
title_action_field: null,
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
line_list_options() {
|
|
39
|
+
return {
|
|
40
|
+
card_klass: "loud-labels",
|
|
41
|
+
key_title: "",
|
|
42
|
+
list_item_options: {
|
|
43
|
+
fields: this.line_list_fields(),
|
|
44
|
+
list_item_klass_maker: this.utils.wms.move_line_color_klass,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
line_list_fields() {
|
|
49
|
+
const self = this;
|
|
50
|
+
return [
|
|
51
|
+
{
|
|
52
|
+
path: "product.display_name",
|
|
53
|
+
action_val_path: "product.barcode",
|
|
54
|
+
klass: "loud",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
path: "package_src.name",
|
|
58
|
+
label: "Pack",
|
|
59
|
+
action_val_path: "package_src.name",
|
|
60
|
+
},
|
|
61
|
+
{path: "lot.name", label: "Lot", action_val_path: "lot.name"},
|
|
62
|
+
{
|
|
63
|
+
path: "product.qty_reserved",
|
|
64
|
+
label: "Qty reserved",
|
|
65
|
+
render_component: "packaging-qty-picker-display",
|
|
66
|
+
render_props: function (record) {
|
|
67
|
+
return self.utils.wms.move_line_qty_picker_props(record, {
|
|
68
|
+
qtyInit: record.product.qty_reserved,
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
path: "product.qty_available",
|
|
74
|
+
label: "Qty in stock",
|
|
75
|
+
render_component: "packaging-qty-picker-display",
|
|
76
|
+
render_props: function (record) {
|
|
77
|
+
return self.utils.wms.move_line_qty_picker_props(record, {
|
|
78
|
+
qtyInit: record.product.qty_available,
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
},
|
|
84
|
+
grouped_lines() {
|
|
85
|
+
return this.utils.wms.group_lines_by_locations(this.record.move_lines);
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
template: `
|
|
89
|
+
<div :class="$options._componentTag">
|
|
90
|
+
|
|
91
|
+
<detail-picking
|
|
92
|
+
:key="record.id"
|
|
93
|
+
:record="record"
|
|
94
|
+
:options="picking_detail_options()"
|
|
95
|
+
:card_color="utils.colors.color_for('detail_main_card')"
|
|
96
|
+
>
|
|
97
|
+
<!-- TODO: this actions should come from a registry -->
|
|
98
|
+
<template v-slot:actions>
|
|
99
|
+
<speed-dial :fab_btn_attrs="{small: true}" :options="{fab_btn_icon: 'mdi-pencil'}" v-if="record.carrier">
|
|
100
|
+
<v-btn
|
|
101
|
+
fab
|
|
102
|
+
dark
|
|
103
|
+
small
|
|
104
|
+
color="green"
|
|
105
|
+
title="Edit carrier"
|
|
106
|
+
@click="$router.push({'name': 'edit_form', params: {form_name: 'form_edit_stock_picking', record_id: record.id}})"
|
|
107
|
+
>
|
|
108
|
+
<v-icon>mdi-truck-outline</v-icon>
|
|
109
|
+
</v-btn>
|
|
110
|
+
</speed-dial>
|
|
111
|
+
</template>
|
|
112
|
+
</detail-picking>
|
|
113
|
+
|
|
114
|
+
<div class="lines" v-if="(record.move_lines || []).length">
|
|
115
|
+
<div v-for="group in grouped_lines()">
|
|
116
|
+
<separator-title>
|
|
117
|
+
{{group.location_src.name}} -> {{ group.location_dest.name }}
|
|
118
|
+
</separator-title>
|
|
119
|
+
<list
|
|
120
|
+
:records="group.records"
|
|
121
|
+
:key="'group-' + group.key"
|
|
122
|
+
:options="line_list_options()"
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
`,
|
|
128
|
+
});
|