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.
Files changed (57) hide show
  1. odoo/addons/shopfloor_mobile/README.rst +215 -0
  2. odoo/addons/shopfloor_mobile/__init__.py +0 -0
  3. odoo/addons/shopfloor_mobile/__manifest__.py +17 -0
  4. odoo/addons/shopfloor_mobile/i18n/es_AR.po +39 -0
  5. odoo/addons/shopfloor_mobile/i18n/pt_BR.po +14 -0
  6. odoo/addons/shopfloor_mobile/i18n/shopfloor_mobile.pot +13 -0
  7. odoo/addons/shopfloor_mobile/readme/CONTRIBUTORS.rst +12 -0
  8. odoo/addons/shopfloor_mobile/readme/CREDITS.rst +5 -0
  9. odoo/addons/shopfloor_mobile/readme/DESCRIPTION.rst +31 -0
  10. odoo/addons/shopfloor_mobile/readme/HISTORY.rst +4 -0
  11. odoo/addons/shopfloor_mobile/readme/ROADMAP.rst +29 -0
  12. odoo/addons/shopfloor_mobile/readme/USAGE.rst +34 -0
  13. odoo/addons/shopfloor_mobile/static/description/icon.png +0 -0
  14. odoo/addons/shopfloor_mobile/static/description/index.html +555 -0
  15. odoo/addons/shopfloor_mobile/static/wms/.gitignore +21 -0
  16. odoo/addons/shopfloor_mobile/static/wms/src/components/batch_picking_detail.js +69 -0
  17. odoo/addons/shopfloor_mobile/static/wms/src/components/batch_picking_line_detail.js +141 -0
  18. odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_location.js +66 -0
  19. odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_lot.js +91 -0
  20. odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_operation.js +50 -0
  21. odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_package.js +73 -0
  22. odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_picking.js +40 -0
  23. odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_product.js +70 -0
  24. odoo/addons/shopfloor_mobile/static/wms/src/components/detail/detail_transfer.js +128 -0
  25. odoo/addons/shopfloor_mobile/static/wms/src/components/forms/form_edit_stock_picking.js +39 -0
  26. odoo/addons/shopfloor_mobile/static/wms/src/components/manual_select_color.js +24 -0
  27. odoo/addons/shopfloor_mobile/static/wms/src/components/misc.js +201 -0
  28. odoo/addons/shopfloor_mobile/static/wms/src/components/packaging-qty-picker.js +329 -0
  29. odoo/addons/shopfloor_mobile/static/wms/src/components/scenario_picking_detail/mixins.js +130 -0
  30. odoo/addons/shopfloor_mobile/static/wms/src/components/scenario_picking_detail/picking_select.js +135 -0
  31. odoo/addons/shopfloor_mobile/static/wms/src/components/scenario_picking_detail/picking_summary.js +212 -0
  32. odoo/addons/shopfloor_mobile/static/wms/src/css/main.css +73 -0
  33. odoo/addons/shopfloor_mobile/static/wms/src/css/normalize.css +351 -0
  34. odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.checkout.js +257 -0
  35. odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.cluster_picking.js +188 -0
  36. odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.delivery.js +79 -0
  37. odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.location_content_transfer.js +179 -0
  38. odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.scan_anything.js +124 -0
  39. odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.single_pack_transfer.js +83 -0
  40. odoo/addons/shopfloor_mobile/static/wms/src/demo/demo.zone_picking.js +277 -0
  41. odoo/addons/shopfloor_mobile/static/wms/src/i18n/add_translations_to_registry.js +4 -0
  42. odoo/addons/shopfloor_mobile/static/wms/src/i18n/en.json +31 -0
  43. odoo/addons/shopfloor_mobile/static/wms/src/i18n/fr.json +27 -0
  44. odoo/addons/shopfloor_mobile/static/wms/src/scenario/checkout.js +390 -0
  45. odoo/addons/shopfloor_mobile/static/wms/src/scenario/checkout_states.js +380 -0
  46. odoo/addons/shopfloor_mobile/static/wms/src/scenario/cluster_picking.js +481 -0
  47. odoo/addons/shopfloor_mobile/static/wms/src/scenario/delivery.js +353 -0
  48. odoo/addons/shopfloor_mobile/static/wms/src/scenario/location_content_transfer.js +388 -0
  49. odoo/addons/shopfloor_mobile/static/wms/src/scenario/single_pack_transfer.js +132 -0
  50. odoo/addons/shopfloor_mobile/static/wms/src/scenario/zone_picking.js +838 -0
  51. odoo/addons/shopfloor_mobile/static/wms/src/screen.js +36 -0
  52. odoo/addons/shopfloor_mobile/static/wms/src/wms_utils.js +318 -0
  53. odoo/addons/shopfloor_mobile/templates/assets.xml +180 -0
  54. odoo_addon_shopfloor_mobile-16.0.1.0.0.6.dist-info/METADATA +235 -0
  55. odoo_addon_shopfloor_mobile-16.0.1.0.0.6.dist-info/RECORD +57 -0
  56. odoo_addon_shopfloor_mobile-16.0.1.0.0.6.dist-info/WHEEL +5 -0
  57. 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
+ });