Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 29 additions & 0 deletions connector_extension/models/binding/binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,27 @@ def import_data(self, backend_record, domain=None, delayed=True):
@api.model
def export_data(self, backend_record, domain=None, delayed=True):
"""Prepare the batch export records to Channel"""
# Cursor-rebind workaround for OCA/queue queue_job (16.0+).
# `Job.in_temporary_env()` (added by OCA/queue#910 / commit f2bfda90)
# only rebinds `self.recordset` to the new cursor opened when
# `allow_commit=True`; it does NOT rebind args. Without this manual
# rebind, `backend_record.work_on()` builds a `WorkContext` whose
# `env` is the OUTER cursor (with `_prevent_commit` patched on
# `cr.commit`), so `binder.bind_export()` at `binder.py:315` still
# raises RuntimeError("Commit is forbidden in queue jobs") despite
# `allow_commit=True` being set. Pattern (cursor-only swap, preserves
# uid/su/context captured at `_job_prepare_context_before_enqueue`)
# matches what queue_job uses internally for `self.recordset`, and
# what @guewen (queue_job maintainer) himself suggested in
# OCA/queue#889 ("such export_record and such are implementation
# specific and need to be fixed in many places"). The OCA wiki page
# https://github.com/OCA/queue/wiki/Upgrade-warning:-commits-inside-jobs
# does NOT document this args-rebinding limitation.
# Same fix applied below in export_batch, export_record,
# export_delete_record. Imports do not need it because bind_import
# does not commit.
# Refs: OCA/queue#889, OCA/queue#910, OCA/connector#522.
backend_record = backend_record.with_env(backend_record.env(cr=self.env.cr))
if delayed:
model = self.with_delay()
return model.export_batch(
Expand All @@ -61,6 +82,8 @@ def import_batch(self, backend_record, domain=None, delayed=True, use_data=True)
@api.model
def export_batch(self, backend_record, domain=None, delayed=True):
"""Prepare the batch export of records modified on Odoo"""
# Cursor-rebind workaround for queue_job; see export_data for rationale.
backend_record = backend_record.with_env(backend_record.env(cr=self.env.cr))
if not domain:
domain = []
with backend_record.work_on(self._name) as work:
Expand Down Expand Up @@ -102,13 +125,19 @@ def import_record(self, backend_record, external_id, sync_date, external_data=No
@api.model
def export_record(self, backend_record, relation):
"""Export Odoo record"""
# Cursor-rebind workaround for queue_job; see export_data for rationale.
backend_record = backend_record.with_env(backend_record.env(cr=self.env.cr))
relation = relation.with_env(relation.env(cr=self.env.cr))
with backend_record.work_on(self._name) as work:
exporter = work.component(usage="record.direct.exporter")
return exporter.run(relation)

@api.model
def export_delete_record(self, backend_record, relation):
"""Export Odoo record"""
# Cursor-rebind workaround for queue_job; see export_data for rationale.
backend_record = backend_record.with_env(backend_record.env(cr=self.env.cr))
relation = relation.with_env(relation.env(cr=self.env.cr))
with backend_record.work_on(self._name) as work:
deleter = work.component(usage="record.direct.export.deleter")
return deleter.run(relation)
Expand Down
6 changes: 5 additions & 1 deletion connector_sapb1/README.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

================
Connector SAP B1
================
Expand All @@ -13,7 +17,7 @@ Connector SAP B1
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-nuobit%2Fodoo--addons-lightgray.png?logo=github
Expand Down
2 changes: 1 addition & 1 deletion connector_sapb1/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{
"name": "Connector SAP B1",
"version": "16.0.1.0.0",
"version": "16.0.1.0.1",
"author": "NuoBiT Solutions SL",
"license": "AGPL-3",
"category": "Connector",
Expand Down
56 changes: 56 additions & 0 deletions connector_sapb1/data/queue_job_function_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,60 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)-->
<field name="channel_id" ref="connector_sapb1.channel_sapb1" />
<field name="retry_pattern" eval="{1: 10, 5: 20, 10: 30, 15: 120}" />
</record>
<!--
Allow commit on export_record for sapb1 binding models.
bind_export does cr.commit() to persist the binding immediately after
the SAP HTTP call succeeds (avoids duplicate addresses on retry). Since
queue_job 16.0.2.13.2 (OCA/queue#892), _prevent_commit raises RuntimeError
unless allow_commit=True — which runs perform() with a separate DB cursor,
so the commit does not release the queue_job row-lock.
See: https://github.com/OCA/queue/wiki/Upgrade-warning:-commits-inside-jobs
-->
<record
id="sapb1_binding_method_export_record_job_function"
model="queue.job.function"
>
<field name="model_id" ref="connector_sapb1.model_sapb1_binding" />
<field name="method">export_record</field>
<field name="channel_id" ref="connector_sapb1.channel_sapb1" />
<field name="retry_pattern" eval="{1: 10, 5: 20, 10: 30, 15: 120}" />
<field name="allow_commit" eval="True" />
</record>
<record
id="sapb1_res_partner_export_record_job_function"
model="queue.job.function"
>
<field name="model_id" ref="connector_sapb1.model_sapb1_res_partner" />
<field name="method">export_record</field>
<field name="channel_id" ref="connector_sapb1.channel_sapb1" />
<field name="retry_pattern" eval="{1: 10, 5: 20, 10: 30, 15: 120}" />
<field name="allow_commit" eval="True" />
</record>
<record id="sapb1_sale_order_export_record_job_function" model="queue.job.function">
<field name="model_id" ref="connector_sapb1.model_sapb1_sale_order" />
<field name="method">export_record</field>
<field name="channel_id" ref="connector_sapb1.channel_sapb1" />
<field name="retry_pattern" eval="{1: 10, 5: 20, 10: 30, 15: 120}" />
<field name="allow_commit" eval="True" />
</record>
<record
id="sapb1_sale_order_line_export_record_job_function"
model="queue.job.function"
>
<field name="model_id" ref="connector_sapb1.model_sapb1_sale_order_line" />
<field name="method">export_record</field>
<field name="channel_id" ref="connector_sapb1.channel_sapb1" />
<field name="retry_pattern" eval="{1: 10, 5: 20, 10: 30, 15: 120}" />
<field name="allow_commit" eval="True" />
</record>
<record
id="sapb1_product_product_export_record_job_function"
model="queue.job.function"
>
<field name="model_id" ref="connector_sapb1.model_sapb1_product_product" />
<field name="method">export_record</field>
<field name="channel_id" ref="connector_sapb1.channel_sapb1" />
<field name="retry_pattern" eval="{1: 10, 5: 20, 10: 30, 15: 120}" />
<field name="allow_commit" eval="True" />
</record>
</odoo>
59 changes: 59 additions & 0 deletions connector_sapb1/migrations/16.0.1.0.1/pre-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""Pre-migration: claim auto-created queue.job.function records.

Existing installs may have queue.job.function records for export_record on
sapb1 binding models that were auto-created and have no ir_model_data entry
(thus no xml_id). When the new XML definition loads with noupdate="1",
Odoo would try to CREATE records with our new xml_ids, which fails due to
the (model_id, method) unique constraint.

Solution: insert the ir_model_data entries BEFORE the XML loads, so each
xml_id is already linked to the existing record. Also set allow_commit=True
directly (since noupdate="1" prevents the XML from updating fields).

See: https://github.com/OCA/queue/wiki/Upgrade-warning:-commits-inside-jobs
"""

JOB_FUNCTIONS = [
("sapb1_binding_method_export_record_job_function", "sapb1.binding"),
("sapb1_res_partner_export_record_job_function", "sapb1.res.partner"),
("sapb1_sale_order_export_record_job_function", "sapb1.sale.order"),
("sapb1_sale_order_line_export_record_job_function", "sapb1.sale.order.line"),
("sapb1_product_product_export_record_job_function", "sapb1.product.product"),
]


def migrate(cr, version):
if not version:
return
for xml_id, model_name in JOB_FUNCTIONS:
cr.execute(
"""
SELECT qjf.id
FROM queue_job_function qjf
JOIN ir_model im ON im.id = qjf.model_id
WHERE qjf.method = 'export_record' AND im.model = %s
""",
(model_name,),
)
row = cr.fetchone()
if not row:
continue
qjf_id = row[0]
cr.execute(
"""
INSERT INTO ir_model_data
(module, name, model, res_id, noupdate)
VALUES
('connector_sapb1', %s, 'queue.job.function', %s, TRUE)
ON CONFLICT (module, name) DO NOTHING
""",
(xml_id, qjf_id),
)
cr.execute(
"""
UPDATE queue_job_function
SET allow_commit = TRUE
WHERE id = %s
""",
(qjf_id,),
)
32 changes: 19 additions & 13 deletions connector_sapb1/static/description/index.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Connector SAP B1</title>
<title>README.rst</title>
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.

See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
Expand Down Expand Up @@ -275,7 +275,7 @@
margin-left: 2em ;
margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
Expand All @@ -301,7 +301,7 @@
span.pre {
white-space: pre }

span.problematic {
span.problematic, pre.problematic {
color: red }

span.section-subtitle {
Expand Down Expand Up @@ -360,16 +360,21 @@
</style>
</head>
<body>
<div class="document" id="connector-sap-b1">
<h1 class="title">Connector SAP B1</h1>
<div class="document">


<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="connector-sap-b1">
<h1>Connector SAP B1</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:c799d46c1b505b1bb1f2e4dd97c5b9b99529754db92831bf17b9c36576475511
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/nuobit/odoo-addons/tree/16.0/connector_sapb1"><img alt="nuobit/odoo-addons" src="https://img.shields.io/badge/github-nuobit%2Fodoo--addons-lightgray.png?logo=github" /></a></p>
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/nuobit/odoo-addons/tree/16.0/connector_sapb1"><img alt="nuobit/odoo-addons" src="https://img.shields.io/badge/github-nuobit%2Fodoo--addons-lightgray.png?logo=github" /></a></p>
<p>SAP Business One connector</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
Expand All @@ -384,23 +389,23 @@ <h1 class="title">Connector SAP B1</h1>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<h2><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h2>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/nuobit/odoo-addons/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/nuobit/odoo-addons/issues/new?body=module:%20connector_sapb1%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
<h2><a class="toc-backref" href="#toc-entry-2">Credits</a></h2>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
<h3><a class="toc-backref" href="#toc-entry-3">Authors</a></h3>
<ul class="simple">
<li>NuoBiT Solutions SL</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<h3><a class="toc-backref" href="#toc-entry-4">Contributors</a></h3>
<ul class="simple">
<li><a class="reference external" href="https://www.nuobit.com">NuoBiT</a>:<ul>
<li>Kilian Niubo &lt;<a class="reference external" href="mailto:kniubo&#64;nuobit.com">kniubo&#64;nuobit.com</a>&gt;</li>
Expand All @@ -410,11 +415,12 @@ <h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
<h3><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h3>
<p>This module is part of the <a class="reference external" href="https://github.com/nuobit/odoo-addons/tree/16.0/connector_sapb1">nuobit/odoo-addons</a> project on GitHub.</p>
<p>You are welcome to contribute.</p>
</div>
</div>
</div>
</div>
</body>
</html>
Loading