Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0][ADD] wms_connector #762

Closed
wants to merge 70 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
63bcbde
[ADD] wms_connector
kevinkhao Oct 9, 2023
d66c5de
wip
kevinkhao Oct 10, 2023
d85aeeb
wip
kevinkhao Oct 10, 2023
64ba460
wip
kevinkhao Oct 12, 2023
2408560
wip
kevinkhao Oct 12, 2023
49fa6b8
wip
kevinkhao Oct 12, 2023
3bbbb1c
wip
kevinkhao Oct 12, 2023
69d5d4d
wip
kevinkhao Oct 12, 2023
bde235a
wip
kevinkhao Oct 13, 2023
1295521
wip
kevinkhao Oct 13, 2023
34542c9
wip
kevinkhao Oct 16, 2023
8826d65
wip
kevinkhao Oct 17, 2023
6f2c662
wip
kevinkhao Oct 17, 2023
1741ca7
wip
kevinkhao Oct 17, 2023
884dd7e
wip
kevinkhao Oct 18, 2023
44494c6
wip
kevinkhao Oct 18, 2023
48a4654
wip
kevinkhao Oct 18, 2023
a9f1087
wip
kevinkhao Oct 18, 2023
123913e
wip
kevinkhao Oct 18, 2023
2694d0f
wip
kevinkhao Oct 20, 2023
71afb28
wip
kevinkhao Oct 23, 2023
2b5e80a
change cron and filter logic
kevinkhao Oct 24, 2023
0e04865
change export logic
kevinkhao Oct 24, 2023
e3745b8
cleanup
kevinkhao Oct 24, 2023
6e6052f
misc fixes, tests
kevinkhao Oct 24, 2023
9a97798
minor name fix
kevinkhao Oct 25, 2023
2be02f1
minor interface fix
kevinkhao Oct 25, 2023
2f85e81
wms_connector: improve export
sebastienbeau Oct 26, 2023
f196b4c
wms_connector: clean code, improve view
sebastienbeau Nov 1, 2023
233b3f5
wms_connector: fix export, review product sync
sebastienbeau Nov 1, 2023
8ba7bef
wms_connector: do not try to send record with error
sebastienbeau Nov 2, 2023
048e83e
wms_connector: ADD make filetype consistent between task and queue
FranzPoize Nov 20, 2023
05be645
wms_connector: ADD adds method_type and filepath to task mappings for…
FranzPoize Nov 20, 2023
0d90371
FIX method_type and filepath default values
FranzPoize Nov 21, 2023
179ea42
ADD storage backend value (mostly for test purpose right now)
FranzPoize Nov 21, 2023
6923c08
wms_connector: improve code
sebastienbeau Nov 23, 2023
0f2e0a9
wms_connector: ADD wms_connector_exported and is_wms_exportable fields
FranzPoize Nov 28, 2023
e1be055
wms_connector: ADD a smart button to the picking view form that links to
FranzPoize Nov 28, 2023
1ea74a0
wms_connector: clean view, and simplify code, add cancel check
sebastienbeau Nov 29, 2023
8756b21
Merge pull request #8 from akretion/14.0-wms_connector_3
sebastienbeau Nov 29, 2023
8946312
wms_connector: ADD inventory import support
FranzPoize Dec 6, 2023
fc60d25
wms_connector: compute default_warehouse_id for inventory in a simple…
FranzPoize Dec 7, 2023
d18a784
wms_conne: return attachment queue
sebastienbeau Dec 14, 2023
dfe2fb5
wms_connector: fix getting task, show error message on picking, raise…
sebastienbeau Dec 15, 2023
3c142fe
wms_connector: fix access right issue
sebastienbeau Dec 15, 2023
fdd62ed
wms_connector: fix cancelling sale order. Do not raise error if alrea…
sebastienbeau Dec 19, 2023
f8dc2e5
Merge remote-tracking branch 'origin/14.0-wms_connector_inventory_sup…
sebastienbeau Jan 22, 2024
3e5b64d
wms_connector: improve UI, clean code
sebastienbeau Jan 22, 2024
b895a7f
wms_connector: fix computing warehouse_id
sebastienbeau Jan 28, 2024
d41fc57
wms_connector: purge binding that have been never exported, and clean…
sebastienbeau Jan 30, 2024
a8e2251
wms_connector: reset wms_export_date and file when force cancel, so w…
sebastienbeau Feb 25, 2024
5c2cdee
wms_connector: do not unlink file sent
sebastienbeau Mar 20, 2024
83f1f86
wms_connector: fix checking allowed to cancel
sebastienbeau Mar 20, 2024
f9239b7
wms_connector: do not edit picking already synchronized. Add fr trans…
sebastienbeau Mar 24, 2024
83c7d9e
wms_connector: Allow sequence management by child specialization
FranzPoize May 8, 2024
24b3096
wms_connector: encapsulate MAPPINGS and FILTER VAlS in function for i…
FranzPoize May 8, 2024
b338229
wms_connector_picking_batch: Adds picking batch specialization for wm…
FranzPoize May 8, 2024
9da6bc7
wms_connector_picking_batch: Adds README.rst
FranzPoize May 8, 2024
d4ab4bc
wms_connector_picking_batch: good manifest
FranzPoize May 8, 2024
3cc52c9
wms_connector_picking_batch: working filters
FranzPoize May 8, 2024
d6dcd70
wms_connector: allows to specify record_per_file to -1 which puts all…
FranzPoize May 14, 2024
1b64cf4
wms_cconnector_picking_batch: fix wms_export_task_id access
FranzPoize May 14, 2024
3a98018
wms_connector: makes filter_domains easier to modify by inheriting mo…
FranzPoize May 14, 2024
863766f
wms_connector_picking_batch: modify filter_domains
FranzPoize May 14, 2024
a495733
wms_connector_picking_batch: fix stock_picking modal in stock_picking…
FranzPoize May 30, 2024
842915d
wms_connector: adds missing field to stock_picking_views
FranzPoize May 30, 2024
c2f6b77
wms_connector_picking_batch: adds field to stock_picking_batch
FranzPoize May 30, 2024
79d9f1a
wms_connector: remove incoming and outgoing constraints on exportable…
FranzPoize May 30, 2024
39d0e7f
wms_connector_picking_batch: Choose batch transfer in state draft
FranzPoize May 31, 2024
f710273
[FIX] make it possible to export errored wms_product_sync without cha…
FranzPoize Jun 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions wms_connector_picking_batch/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
23 changes: 23 additions & 0 deletions wms_connector_picking_batch/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2023 Akretion
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Wms Connector",
"summary": """
WMS Connector""",
"version": "14.0.1.0.0",
"license": "AGPL-3",
"author": "Akretion,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/wms",
"depends": ["stock", "sale", "attachment_synchronize"],
"data": [
"security/wms_product_sync.xml",
"views/wms_product_sync.xml",
"views/stock_picking.xml",
"views/stock_warehouse.xml",
"views/attachment_queue_view.xml",
],
"demo": [
"demo/storage_backend.xml",
],
}
1 change: 1 addition & 0 deletions wms_connector_picking_batch/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import stock_picking_batch
73 changes: 73 additions & 0 deletions wms_connector_picking_batch/models/stock_picking_batch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from odoo import _, api, fields, models
from odoo.exceptions import UserError


class StockPikcingBatch(models.Model):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor typo

_inherit = ["synchronize.exportable.mixin", "stock.picking.batch"]
_name = "stock.picking.batch"

is_wms_exportable = fields.Boolean(
compute="_compute_is_wms_exportable", readonly=True, store=True
)

wms_sync_cancel_supported = fields.Boolean(
compute="_compute_wms_sync_cancel_supported"
)

wms_import_attachment_id = fields.Many2one(
"attachment.queue", index=True, readonly=True
)
wms_export_date = fields.Datetime(tracking=True)

def _get_wms_export_task(self):
return self.picking_type_id.warehouse_id.sudo().wms_task_id

def _compute_wms_sync_cancel_supported(self):
self.wms_sync_cancel_supported = False

@api.depends(
"picking_type_id.warehouse_id.active_wms_sync",
"picking_type_id.code",
)
def _compute_is_wms_exportable(self):
for rec in self:
rec.is_wms_exportable = (
rec.picking_type_id.warehouse_id.active_wms_sync
and rec.picking_type_id.code in ("incoming", "outgoing")
)

def _is_user_allowed_to_cancel(self):
return self.env.user.has_group("stock.group_stock_manager")

def action_force_cancel_wms(self):
if not self._is_user_allowed_to_cancel():
raise UserError(_("You are not allowed to cancel this batch transfer"))
self.wms_export_date = None
self.wms_export_attachment_id = None
return self.with_context(skip_wms_cancel_check=True).action_cancel()

def action_cancel(self):
for record in self.filtered(lambda p: p.state != "cancel"):
if (
not self._context.get("skip_wms_cancel_check")
and record.wms_export_date
and not record.wms_sync_cancel_supported
):
raise UserError(
_(
"The batch transfer %s can not be deleted as it have been sent "
"to the WMS, ask your manager to force the cancellation"
)
% record.name
)
return super().action_cancel()

def _wms_check_if_editable(self):
if self._context.get("skip_check_protected_fields"):
return True
for picking_batch in self:
if picking_batch.wms_export_date:
raise UserError(
_("The batch transfer %s have been exported and can not be modified")
% picking_batch.name
)
107 changes: 107 additions & 0 deletions wms_connector_picking_batch/models/stock_warehouse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from odoo import fields, models

FILTER_VALS = {
"wms_export_batch_picking_in_filter_id": {
"name": "WMS: {} filter for picking batch in",
"model_id": "stock.picking.batch",
},
"wms_export_batch_picking_out_filter_id": {
"name": "WMS: {} filter for picking batch out",
"model_id": "stock.picking.batch",
},
}
FILTER_DOMAINS = {
"wms_export_product_filter_id": "[]",
"wms_export_picking_in_filter_id": '[("wms_export_date", "=", False),'
' ("picking_type_id", "=", {}), ("state", "=", "assigned")]',
"wms_export_picking_out_filter_id": '[("wms_export_date", "=", False),'
' ("picking_type_id", "=", {}), ("state", "=", "assigned")]',
}


MAPPINGS = {
"export_batch_pickings_in": {
"fieldname_task": "wms_export_task_id",
"fieldname_cron": "wms_export_batch_picking_in_cron_id",
"filetype": "export",
"method_type": "export",
"filepath": "IN/",
"name_fragment": "export batch pickings in",
"code": "wh = env['stock.warehouse'].browse({})\n"
"env['stock.picking.batch'].with_context(attachment_task=wh.{})._schedule_export(wh,"
"domain=wh._wms_domain_for('batch_pickings_in')),",
},
"export_batch_pickings_out": {
"fieldname_task": "wms_export_task_id",
"fieldname_cron": "wms_export_batch_picking_out_cron_id",
"filetype": "export",
"method_type": "export",
"filepath": "IN/",
"name_fragment": "export batch pickings out",
"code": "wh = env['stock.warehouse'].browse({})\n"
"env['stock.picking.batch'].with_context(attachment_task=wh.{})._schedule_export(wh,"
"domain=wh._wms_domain_for('batch_pickings_out')),",
},
}

class StockWarehouse(models.Model):
_inherit = "stock.warehouse"

wms_export_batch_picking_in_cron_id = fields.Many2one("ir.cron", readonly=True)
wms_export_batch_picking_out_cron_id = fields.Many2one("ir.cron", readonly=True)
wms_export_batch_picking_in_filter_id = fields.Many2one("ir.filters")
wms_export_batch_picking_out_filter_id = fields.Many2one("ir.filters")

def _wms_domain_for(self, model_domain):
domains = {
"batch_pickings_in": self.wms_export_batch_picking_in_filter_id._get_eval_domain(),
"batch_pickings_out": self.wms_export_batch_picking_out_filter_id._get_eval_domain(),
}
return domains[model_domain]

def _get_mappings(self):
mappings = super()._get_mappings()
mappings.update(MAPPINGS)
return mappings

def _get_filter_vals(self):
# TODO(franz) remove picking with batch id from the picking in and out filter
filter_vals = super()._get_filter_vals()
filter_vals.update(FILTER_VALS)
return filter_vals

def _activate_filters(self):
self.wms_export_batch_picking_in_filter_id.domain = FILTER_DOMAINS[
"wms_export_batch_picking_in_filter_id"
].format(self.in_type_id.id)
self.wms_export_batch_picking_out_filter_id.domain = FILTER_DOMAINS[
"wms_export_batch_picking_out_filter_id"
].format(self.out_type_id.id)

def button_open_wms_batch_pickings_in(self):
return {
"name": "WMS synchronized transfers",
"view_mode": "tree,form",
"views": [
(False, "tree"),
(False, "form"),
],
"res_model": "stock.picking.batch",
"type": "ir.actions.act_window",
"target": "current",
"domain": self._wms_domain_for("batch_pickings_in"),
}

def button_open_wms_batch_pickings_out(self):
return {
"name": "WMS synchronized transfers",
"view_mode": "tree,form",
"views": [
(False, "tree"),
(False, "form"),
],
"res_model": "stock.picking.batch",
"type": "ir.actions.act_window",
"target": "current",
"domain": self._wms_domain_for("batch_pickings_out"),
}
93 changes: 93 additions & 0 deletions wms_connector_picking_batch/views/stock_picking_batch.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2023 Akretion
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>

<record model="ir.ui.view" id="stock_picking_form_view">
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form" />
<field name="arch" type="xml">
<header position="inside">
<field name="is_wms_exportable" invisible="True" />
<button
name="button_trigger_export"
type="object"
string="Export to WMS"
attrs="{'invisible': [
'|',
'|',
('wms_export_date', '!=', False),
('is_wms_exportable', '=', False),
('state', 'in', ('cancel', 'done', 'draft')),
]}"
/>
<button
name="action_force_cancel_wms"
type="object"
string="Force Cancel"
groups="stock.group_stock_manager"
attrs="{'invisible': [
'|',
('wms_export_date', '=', False),
('state', '=', 'cancel'),
]}"
confirm="Before cancelling, ensure that your have cancelled the picking in the
external WMS"
/>
</header>
<field name="date_done" position="before">
<field
name="wms_export_date"
attrs="{'invisible': [('is_wms_exportable', '=', False)]}"
/>
</field>
<field name="group_id" position="after">
<field
name="wms_export_attachment_id"
attrs="{'invisible': [('wms_export_attachment_id', '=', False)]}"
/>
<field
name="wms_import_attachment_id"
attrs="{'invisible': [('wms_import_attachment_id', '=', False)]}"
/>
</field>
<header position="after">
<div
class="alert alert-danger"
role="alert"
attrs="{'invisible': [('wms_export_error', '=', False)]}"
>
<p>Synchronisation error</p>
<field name="wms_export_error" />
</div>
</header>
</field>
</record>

<record model="ir.ui.view" id="stock_picking_search">
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_internal_search" />
<field name="arch" type="xml">
<filter name="starred" position="after">
<separator />
<filter
string="To export"
name="not_wms_exported"
domain="[('wms_export_date', '=', False)]"
/>
</filter>
</field>
</record>

<record model="ir.ui.view" id="stock_picking_tree_view">
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.vpicktree" />
<field name="arch" type="xml">
<field name="date_deadline" position="after">
<field name="wms_export_date" string="Exported at" optional="True" />
</field>
</field>
</record>


</odoo>
28 changes: 28 additions & 0 deletions wms_connector_picking_batch/views/stock_warehouse.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2023 Akretion
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="stock_warehouse_form_view">
<field name="name">stock.warehouse.form (in wms_connector)</field>
<field name="model">stock.warehouse</field>
<field name="inherit_id" ref="stock.view_warehouse" />
<field name="arch" type="xml">
<div class="oe_button_box" position="inside">
<button
name="button_open_wms_batch_pickings_in"
string="WMS sync batch transfer in"
icon="fa-refresh"
class="oe_stat_button"
type="object"
/>
<button
name="button_open_wms_pickings_out"
string="WMS sync batch transfer pickings out"
icon="fa-refresh"
class="oe_stat_button"
type="object"
/>
</div>
</field>
</record>
</odoo>