",
+ "Material Product"
+ ]
+
+ for line in strings_to_find:
+ line_found = False
+ for html_line in html_content:
+ if line in html_line:
+ line_found = True
+ self.assertTrue(line_found, f"{line} should be in file.")
diff --git a/bemade_fsm/wizard/__init__.py b/bemade_fsm/wizard/__init__.py
index 5cc0245..d7ab68a 100644
--- a/bemade_fsm/wizard/__init__.py
+++ b/bemade_fsm/wizard/__init__.py
@@ -1 +1,2 @@
from . import new_task_from_template
+from . import res_config_settings
diff --git a/bemade_fsm/wizard/res_config_settings.py b/bemade_fsm/wizard/res_config_settings.py
new file mode 100644
index 0000000..69541e6
--- /dev/null
+++ b/bemade_fsm/wizard/res_config_settings.py
@@ -0,0 +1,23 @@
+from odoo import models, fields, api
+
+
+class ResConfigSettings(models.TransientModel):
+ _inherit = "res.config.settings"
+
+ module_bemade_fsm_separate_time_on_work_orders = fields.Boolean("Separate Time from Materials on Work Order")
+ module_bemade_fsm_create_default_fsm_visit = fields.Boolean("Create Default Visit for FSM Sales Orders")
+
+ def set_values(self):
+ super().set_values()
+ self.env.company.split_time_from_materials_on_service_work_orders = \
+ self.module_bemade_fsm_separate_time_on_work_orders
+ self.env.company.create_default_fsm_visit = self.module_bemade_fsm_create_default_fsm_visit
+
+ def get_values(self):
+ res = super().get_values()
+ res.update({
+ 'module_bemade_fsm_separate_time_on_work_orders':
+ self.env.company.split_time_from_materials_on_service_work_orders,
+ 'module_bemade_fsm_create_default_fsm_visit': self.env.company.create_default_fsm_visit
+ })
+ return res
diff --git a/bemade_fsm/wizard/res_config_settings.xml b/bemade_fsm/wizard/res_config_settings.xml
new file mode 100644
index 0000000..2779b1a
--- /dev/null
+++ b/bemade_fsm/wizard/res_config_settings.xml
@@ -0,0 +1,22 @@
+
+
+
+ res.config.settings.view.form.inherit.bemade.fsm
+ res.config.settings
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bemade_geo_routing/__manifest__.py b/bemade_geo_routing/__manifest__.py
index 6ed5473..5d080f1 100644
--- a/bemade_geo_routing/__manifest__.py
+++ b/bemade_geo_routing/__manifest__.py
@@ -18,7 +18,7 @@
#
{
'name': 'Bemade Geo Distance',
- 'version': '15.0.1.0.0',
+ 'version': '17.0.1.0.0',
'summary': 'Utility module for calculating the distance driving between addresses.',
'description': """Module for calculating the driving distance between addresses using the Google Route API.
**IMPORTANT NOTE:** You must have an active Google Route API key configured in the Geo Localization
diff --git a/bemade_mailcow_integration/__manifest__.py b/bemade_mailcow_integration/__manifest__.py
index 466e33c..53b8e24 100644
--- a/bemade_mailcow_integration/__manifest__.py
+++ b/bemade_mailcow_integration/__manifest__.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
{
'name': 'Mailcow Integration',
- 'version': '1.0.0',
+ 'version': '17.0.1.0.1',
'category': 'Administration',
'summary': 'Module for integrating Mailcow email server with Odoo.',
'description': """
diff --git a/bemade_mailcow_integration/migrations/15.0.1.0.1/pre-migrate.py b/bemade_mailcow_integration/migrations/15.0.1.0.1/pre-migrate.py
new file mode 100644
index 0000000..451c1c0
--- /dev/null
+++ b/bemade_mailcow_integration/migrations/15.0.1.0.1/pre-migrate.py
@@ -0,0 +1,13 @@
+from odoo import api, SUPERUSER_ID
+
+
+def migrate(cr, version):
+ env = api.Environment(cr, SUPERUSER_ID, {})
+ settings = env['ir.config_parameter']
+ create_param = settings.get_param('mailcow.create_mailbox')
+ sync_param = settings.get_param('mailcow.sync_alias')
+ base_url = settings.get_param('mailcow.base_url')
+ api_key = settings.get_param('mailcow.api_key')
+
+ if (create_param or sync_param) and (not base_url or not api_key):
+ (create_param | sync_param).write({'value': False})
diff --git a/bemade_mailcow_integration/models/mail_alias.py b/bemade_mailcow_integration/models/mail_alias.py
index df38063..8f31bb7 100644
--- a/bemade_mailcow_integration/models/mail_alias.py
+++ b/bemade_mailcow_integration/models/mail_alias.py
@@ -6,6 +6,7 @@ class MailAlias(models.Model):
mailcow_id = fields.One2many('mail.mailcow.alias', 'alias_id')
+
@api.model_create_multi
def create(self, vals_list):
alias_list = super().create(vals_list)
diff --git a/bemade_mailcow_integration/models/mailcow_mailbox.py b/bemade_mailcow_integration/models/mailcow_mailbox.py
index f6699e6..f5d4d30 100644
--- a/bemade_mailcow_integration/models/mailcow_mailbox.py
+++ b/bemade_mailcow_integration/models/mailcow_mailbox.py
@@ -53,7 +53,7 @@ class MailcowMailbox(models.Model):
Overridden create method to add a new mailbox entry on the Mailcow server for each user created in Odoo.
"""
- res_list = []
+ res = self.env['mail.mailcow.mailbox']
for vals in vals_list:
password = secrets.token_hex(16)
@@ -81,10 +81,8 @@ class MailcowMailbox(models.Model):
self.api_request(endpoint, method='POST', data=data)
_logger.info(f"Mailbox {vals['local_part']}@{vals['domain']} has been created on Mailcow server")
- res = super().create(vals)
- res_list.append(res)
-
- return res_list
+ res |= super().create(vals)
+ return res
def write(self, vals):
"""
@@ -141,8 +139,8 @@ class MailcowMailbox(models.Model):
self.api_request(endpoint, method='POST', data=data)
_logger.info(f'Mailbox for user {user.login} has been created on Mailcow server')
- pw_bundle = seld.env['password.bundle'].search([('name', '=', user.name)])
- self.env['password.key'].create_mailbox_for_user(res)
+ pw_bundle = self.env['password.bundle'].search([('name', '=', user.name)])
+ self.env['password.key'].create_mailbox_for_user(user)
return self.create({
'address': user.login,
diff --git a/bemade_mailcow_integration/models/res_config_settings.py b/bemade_mailcow_integration/models/res_config_settings.py
index e0b47e5..bd5db68 100644
--- a/bemade_mailcow_integration/models/res_config_settings.py
+++ b/bemade_mailcow_integration/models/res_config_settings.py
@@ -1,4 +1,6 @@
-from odoo import fields, models
+from odoo import fields, models, api, _
+from odoo.exceptions import ValidationError
+
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
@@ -23,3 +25,8 @@ class ResConfigSettings(models.TransientModel):
string='Create Mailboxes in Mailcow',
help='Auto create Mailboxes in Mailcow on creation in Odoo',
config_parameter='mailcow.create_mailbox')
+
+ @api.constrains('mailcow_sync_alias', 'mailcow_auto_create')
+ def require_api_key_and_base_url_to_sync(self):
+ if not self.mailcow_api_key and self.mailcow_base_url:
+ raise ValidationError(_("You must set a base URL and API key to enable synchronization."))
diff --git a/bemade_margin_vendor_pricelist/__manifest__.py b/bemade_margin_vendor_pricelist/__manifest__.py
index d38621a..45dfc06 100644
--- a/bemade_margin_vendor_pricelist/__manifest__.py
+++ b/bemade_margin_vendor_pricelist/__manifest__.py
@@ -18,7 +18,7 @@
#
{
'name': 'Sales Margin on Vendor Price',
- 'version': '17.0.0.0.1',
+ 'version': '17.0.0.0.2',
'summary': 'Enables calculation of sales margins based on vendor pricelists.',
'description': """Adds a new method for calculating """,
'author': 'Bemade Inc.',
diff --git a/bemade_margin_vendor_pricelist/models/sale_order_line.py b/bemade_margin_vendor_pricelist/models/sale_order_line.py
index b8b3b2b..dd7bf31 100644
--- a/bemade_margin_vendor_pricelist/models/sale_order_line.py
+++ b/bemade_margin_vendor_pricelist/models/sale_order_line.py
@@ -100,7 +100,7 @@ class SaleOrderLine(models.Model):
if is_order and self.qty_to_deliver == 0:
return 0
elif is_order and self.qty_to_deliver > 0:
- reserved = sum([m.reserved_availability for m in self.move_ids])
+ reserved = sum([q.reserved_quantity for q in self.move_ids.mapped('move_line_ids').mapped('quant_id')])
missing = self.qty_to_deliver - reserved
if float_compare(missing, 0.0,
precision_rounding=self.product_uom.rounding) == 1:
diff --git a/bemade_margin_vendor_pricelist/views/sale_order.xml b/bemade_margin_vendor_pricelist/views/sale_order.xml
index 8c7eb40..5dad852 100644
--- a/bemade_margin_vendor_pricelist/views/sale_order.xml
+++ b/bemade_margin_vendor_pricelist/views/sale_order.xml
@@ -7,12 +7,14 @@
+
+
@@ -24,6 +26,7 @@
+
@@ -34,12 +37,15 @@
sale.order
+
+
+
diff --git a/bemade_multiple_billing_contacts/__manifest__.py b/bemade_multiple_billing_contacts/__manifest__.py
index 9ed2d59..e4af7fc 100644
--- a/bemade_multiple_billing_contacts/__manifest__.py
+++ b/bemade_multiple_billing_contacts/__manifest__.py
@@ -29,14 +29,14 @@
'author': 'Bemade Inc.',
'website': 'https://www.bemade.org',
'license': 'OPL-1',
- 'depends': [
- 'sale',
- 'account',
- 'bemade_partner_root_ancestor',
- ],
+ 'depends': ['sale',
+ 'account',
+ 'bemade_partner_root_ancestor',
+ ],
'data': [
'views/account_move_views.xml',
- 'views/res_partner_views.xml'
+ 'views/res_partner_views.xml',
+ 'views/sale_order_views.xml',
],
'demo': [],
'installable': True,
diff --git a/bemade_multiple_billing_contacts/models/account_move.py b/bemade_multiple_billing_contacts/models/account_move.py
index 11d2aa0..0e8fe1f 100644
--- a/bemade_multiple_billing_contacts/models/account_move.py
+++ b/bemade_multiple_billing_contacts/models/account_move.py
@@ -29,6 +29,6 @@ class AccountMove(models.Model):
initial_subscribers = self.message_partner_ids.ids
final_subscribers = initial_subscribers + self.billing_contacts.ids
posted = super()._post()
- self.message_unsubscribe([s.id for s in self.message_partner_ids if s not in initial_subscribers])
+ self.message_unsubscribe([s.id for s in self.message_partner_ids if s.id not in initial_subscribers])
self.message_subscribe(final_subscribers)
return posted
diff --git a/bemade_multiple_billing_contacts/tests/test_billing_contacts.py b/bemade_multiple_billing_contacts/tests/test_billing_contacts.py
index 1329090..82c15ce 100644
--- a/bemade_multiple_billing_contacts/tests/test_billing_contacts.py
+++ b/bemade_multiple_billing_contacts/tests/test_billing_contacts.py
@@ -63,7 +63,8 @@ class TestBillingContacts(TransactionCase):
'price_unit': cls.product.list_price,
'order_id': cls.sale_order.id,
'tax_id': False,
- 'qty_delivered_manual': 2,
+ 'qty_delivered': 2,
+ 'qty_delivered_method': 'manual',
})
def test_billing_contacts_structure(self):
diff --git a/bemade_multiple_billing_contacts/views/sale_order_views.xml b/bemade_multiple_billing_contacts/views/sale_order_views.xml
new file mode 100644
index 0000000..35fe9f3
--- /dev/null
+++ b/bemade_multiple_billing_contacts/views/sale_order_views.xml
@@ -0,0 +1,20 @@
+
+
+
+ view_sale_order_form_inherit
+ sale.order
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bemade_open_project_details/__init__.py b/bemade_open_project_details/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bemade_open_project_details/__manifest__.py b/bemade_open_project_details/__manifest__.py
new file mode 100644
index 0000000..a8396a0
--- /dev/null
+++ b/bemade_open_project_details/__manifest__.py
@@ -0,0 +1,39 @@
+#
+# Bemade Inc.
+#
+# Copyright (C) June 2023 Bemade Inc. ().
+# Author: mdurepos (Contact : it@bemade.org)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+{
+ 'name': 'Open Project Details',
+ 'version': '17.0.0.0.1',
+ 'summary': 'Open Project Details',
+ 'description': """
+ This module adds the ability to view project details from the project form view.
+ """,
+ 'category': 'Project',
+ 'author': 'Bemade Inc.',
+ 'website': 'https://www.bemade.org',
+ 'license': 'OPL-1',
+ 'depends': [
+ 'project',
+ ],
+ 'data': [
+ # 'views/project_project_views.xml'
+ ],
+ 'demo': [],
+ 'installable': True,
+ 'auto_install': False,
+}
diff --git a/bemade_open_project_details/views/project_project_views.xml b/bemade_open_project_details/views/project_project_views.xml
new file mode 100644
index 0000000..8458b5b
--- /dev/null
+++ b/bemade_open_project_details/views/project_project_views.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+ project.view.project.kanban.inherit
+ project.project
+
+
+
+
+ base.group_user
+
+
+ Open
+
+
+
+
+
diff --git a/bemade_packing_wizard/__manifest__.py b/bemade_packing_wizard/__manifest__.py
index b0b1cb9..bd4ba9e 100644
--- a/bemade_packing_wizard/__manifest__.py
+++ b/bemade_packing_wizard/__manifest__.py
@@ -10,7 +10,7 @@
You need to activate the auto create package feature on the delivery carrier to use this feature.
""",
'depends': [
- 'delivery'
+ 'stock_delivery'
],
'data': [
'views/stock_package_views.xml',
diff --git a/bemade_packing_wizard/views/stock_package_views.xml b/bemade_packing_wizard/views/stock_package_views.xml
index 31e680a..4847d56 100644
--- a/bemade_packing_wizard/views/stock_package_views.xml
+++ b/bemade_packing_wizard/views/stock_package_views.xml
@@ -6,18 +6,12 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/bemade_packing_wizard/wizard/choose_delivery_package_views.xml b/bemade_packing_wizard/wizard/choose_delivery_package_views.xml
index da22a15..1b85781 100644
--- a/bemade_packing_wizard/wizard/choose_delivery_package_views.xml
+++ b/bemade_packing_wizard/wizard/choose_delivery_package_views.xml
@@ -3,20 +3,14 @@
choose.delivery.package.form2choose.delivery.package
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
diff --git a/bemade_quotation_alternative/__init__.py b/bemade_quotation_alternative/__init__.py
index 8604020..3c4e748 100644
--- a/bemade_quotation_alternative/__init__.py
+++ b/bemade_quotation_alternative/__init__.py
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
from . import wizard
-from . import models
\ No newline at end of file
+from . import models
diff --git a/bemade_quotation_alternative/__manifest__.py b/bemade_quotation_alternative/__manifest__.py
index 1e2db88..78e7504 100644
--- a/bemade_quotation_alternative/__manifest__.py
+++ b/bemade_quotation_alternative/__manifest__.py
@@ -17,7 +17,7 @@
# Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml
# for the full list
'category': 'Uncategorized',
- 'version': '0.1',
+ 'version': '17.0.1.0.0',
# any module necessary for this one to work correctly
'depends': [
@@ -26,9 +26,9 @@
# always loaded
'data': [
- # 'security/ir.model.access.csv',
+ 'security/ir.model.access.csv',
'views/sale_order_views.xml',
- 'wizard/sale_order_alternative_views.xml',
+ 'wizard/sale_order_duplication_wizard_view.xml',
],
# only loaded in demonstration mode
'demo': [
diff --git a/bemade_quotation_alternative/controllers/__init__.py b/bemade_quotation_alternative/controllers/__init__.py
deleted file mode 100644
index 457bae2..0000000
--- a/bemade_quotation_alternative/controllers/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from . import controllers
\ No newline at end of file
diff --git a/bemade_quotation_alternative/controllers/controllers.py b/bemade_quotation_alternative/controllers/controllers.py
deleted file mode 100644
index ab78d96..0000000
--- a/bemade_quotation_alternative/controllers/controllers.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-# from odoo import http
-
-
-# class .repos/bemade-addons/bemadeQuotationAlternative(http.Controller):
-# @http.route('/.repos/bemade-addons/bemade_quotation_alternative/.repos/bemade-addons/bemade_quotation_alternative', auth='public')
-# def index(self, **kw):
-# return "Hello, world"
-
-# @http.route('/.repos/bemade-addons/bemade_quotation_alternative/.repos/bemade-addons/bemade_quotation_alternative/objects', auth='public')
-# def list(self, **kw):
-# return http.request.render('.repos/bemade-addons/bemade_quotation_alternative.listing', {
-# 'root': '/.repos/bemade-addons/bemade_quotation_alternative/.repos/bemade-addons/bemade_quotation_alternative',
-# 'objects': http.request.env['.repos/bemade-addons/bemade_quotation_alternative..repos/bemade-addons/bemade_quotation_alternative'].search([]),
-# })
-
-# @http.route('/.repos/bemade-addons/bemade_quotation_alternative/.repos/bemade-addons/bemade_quotation_alternative/objects/', auth='public')
-# def object(self, obj, **kw):
-# return http.request.render('.repos/bemade-addons/bemade_quotation_alternative.object', {
-# 'object': obj
-# })
diff --git a/bemade_quotation_alternative/demo/demo.xml b/bemade_quotation_alternative/demo/demo.xml
deleted file mode 100644
index e9046ff..0000000
--- a/bemade_quotation_alternative/demo/demo.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/bemade_quotation_alternative/models/__init__.py b/bemade_quotation_alternative/models/__init__.py
index 3e8b8f8..6064afe 100644
--- a/bemade_quotation_alternative/models/__init__.py
+++ b/bemade_quotation_alternative/models/__init__.py
@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
-from . import sale_order
\ No newline at end of file
+from . import sale_order
diff --git a/bemade_quotation_alternative/models/models.py b/bemade_quotation_alternative/models/models.py
deleted file mode 100644
index 3e82283..0000000
--- a/bemade_quotation_alternative/models/models.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# from odoo import models, fields, api
-
-
-# class .repos/bemade-addons/bemade_quotation_alternative(models.Model):
-# _name = '.repos/bemade-addons/bemade_quotation_alternative..repos/bemade-addons/bemade_quotation_alternative'
-# _description = '.repos/bemade-addons/bemade_quotation_alternative..repos/bemade-addons/bemade_quotation_alternative'
-
-# name = fields.Char()
-# value = fields.Integer()
-# value2 = fields.Float(compute="_value_pc", store=True)
-# description = fields.Text()
-#
-# @api.depends('value')
-# def _value_pc(self):
-# for record in self:
-# record.value2 = float(record.value) / 100
diff --git a/bemade_quotation_alternative/models/sale_order.py b/bemade_quotation_alternative/models/sale_order.py
index 50498d9..c5bb2dd 100644
--- a/bemade_quotation_alternative/models/sale_order.py
+++ b/bemade_quotation_alternative/models/sale_order.py
@@ -1,17 +1,13 @@
from odoo import fields, models, api
-class ModelName(models.Model):
+class SaleOrder(models.Model):
_inherit = 'sale.order'
- def action_create_alternative(self):
- return {
- 'name': 'Create Alternative',
- 'type': 'ir.actions.act_window',
- 'res_model': 'bemade.quotation.alternative',
- 'view_mode': 'form',
- 'target': 'new',
- 'context': {
- 'default_sale_order_id': self.id,
- }
- }
\ No newline at end of file
+ def action_duplicate_order(self):
+ self.ensure_one()
+ action = self.env.ref('bemade_quotation_alternative.sale_order_duplication_wizard_action').read()[0]
+ action['context'] = {
+ 'default_original_order_id': self.id,
+ }
+ return action
diff --git a/bemade_quotation_alternative/security/ir.model.access.csv b/bemade_quotation_alternative/security/ir.model.access.csv
index a531b67..29adc9a 100644
--- a/bemade_quotation_alternative/security/ir.model.access.csv
+++ b/bemade_quotation_alternative/security/ir.model.access.csv
@@ -1,2 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_.repos/bemade-addons/bemade_quotation_alternative_.repos/bemade-addons/bemade_quotation_alternative,.repos/bemade-addons/bemade_quotation_alternative..repos/bemade-addons/bemade_quotation_alternative,model_.repos/bemade-addons/bemade_quotation_alternative_.repos/bemade-addons/bemade_quotation_alternative,base.group_user,1,1,1,1
\ No newline at end of file
+bemade_quotation_alternative.access_sale_order_duplication_wizard,access_sale_order_duplication_wizard,bemade_quotation_alternative.model_sale_order_duplication_wizard,base.group_user,1,1,1,1
+bemade_quotation_alternative.access_sale_order_line_duplication_wizard,access_sale_order_line_duplication_wizard,bemade_quotation_alternative.model_sale_order_line_duplication_wizard,base.group_user,1,1,1,1
diff --git a/bemade_quotation_alternative/views/sale_order_views.xml b/bemade_quotation_alternative/views/sale_order_views.xml
index c28516e..72df092 100644
--- a/bemade_quotation_alternative/views/sale_order_views.xml
+++ b/bemade_quotation_alternative/views/sale_order_views.xml
@@ -1,58 +1,62 @@
+
-
-
-
-
- bemade_quotation_alternative form
- sale.order
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
-
-
-
+
-
-
+
-
-
+
-
-
\ No newline at end of file
+
+
diff --git a/bemade_quotation_alternative/views/templates.xml b/bemade_quotation_alternative/views/templates.xml
deleted file mode 100644
index cea6b39..0000000
--- a/bemade_quotation_alternative/views/templates.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/bemade_quotation_alternative/wizard/__init__.py b/bemade_quotation_alternative/wizard/__init__.py
index ca94d45..c8bd2b8 100644
--- a/bemade_quotation_alternative/wizard/__init__.py
+++ b/bemade_quotation_alternative/wizard/__init__.py
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
-from . import sale_order_alternative
\ No newline at end of file
+from . import sale_order_duplication_wizard
+from . import sale_oder_line_duplication_wizard
diff --git a/bemade_quotation_alternative/wizard/sale_oder_line_duplication_wizard.py b/bemade_quotation_alternative/wizard/sale_oder_line_duplication_wizard.py
new file mode 100644
index 0000000..c21a696
--- /dev/null
+++ b/bemade_quotation_alternative/wizard/sale_oder_line_duplication_wizard.py
@@ -0,0 +1,9 @@
+from odoo import models, fields
+
+class SaleOrderLineDuplicationWizard(models.TransientModel):
+ _name = 'sale.order.line.duplication.wizard'
+ _description = 'Wizard for selecting sale order lines to duplicate'
+
+ wizard_id = fields.Many2one('sale.order.duplication.wizard', required=True, ondelete='cascade', string="Wizard")
+ sale_order_line_id = fields.Many2one('sale.order.line', string="Sale Order Line", required=True)
+ to_duplicate = fields.Boolean(string="Duplicate?", default=True)
diff --git a/bemade_quotation_alternative/wizard/sale_order_alternative.py b/bemade_quotation_alternative/wizard/sale_order_alternative.py
deleted file mode 100644
index 9b2b92b..0000000
--- a/bemade_quotation_alternative/wizard/sale_order_alternative.py
+++ /dev/null
@@ -1,59 +0,0 @@
-from odoo import fields, models, api
-import string
-
-
-class AlternativeQuotation(models.TransientModel):
- _name = 'sale.order.alternative'
- _description = 'Quotation Alternative'
-
- name = fields.Char()
- original_sale_order_id = fields.Many2one('sale.order')
-
- clone_all_lines = fields.Boolean('Clone all lines', default=True)
- origin = fields.Text('Why this alternative ?')
- internal_note = fields.Text('Internal Note')
-
- def action_create_alternative(self):
- name = self.original_sale_order_id.name
-
- if name and name[-1] not in string.ascii_letters:
- self.original_sale_order_id.name = name + "A"
- name = self.name + "B"
- else:
- # Assuming 'all_names' is a list of all names
- # Add a domain to filter names starting with 'name' (less the last letter)
- all_names = [record.name for record in self.env['sale.order'].search([('name', 'like', name[:-1] + '%')])]
- if name in all_names:
- # Get the index of the current name in the list
- index = all_names.index(name)
- # If this is not the last name in the list, get the next one
- if index < len(all_names) - 1:
- name = all_names[index + 1]
- else:
- # If this is the last name, just add 'B' to it
- name = name + "B"
-
- new_quot = quot.original_sale_order_id.copy({
- 'name': quot.name,
- 'origin': quot.original_sale_order_id.name,
- 'alternative_sale_order_id': quot.original_sale_order_id.id,
- 'alternative': True,
- 'alternative_origine': quot.origine,
- 'alternative_internal_note': quot.internal_note,
-
-# # Lines and line based computes
-# order_line = fields.One2many(
-# comodel_name='sale.order.alternative.line',
-# inverse_name='order_id',
-# string="Order Lines",
-# copy=True, auto_join=True)
-#
-# class AlternativeQuotation(models.TransientModel):
-# _name = 'sale.order.alternative.line'
-# # _inherit = 'sale.order.line'
-# _description = 'Quotation Alternative Line'
-#
-# order_id = fields.Many2one(
-# comodel_name='sale.order.alternative',
-# string="Alternative Quotation Reference",
-# required=True, ondelete='cascade', index=True, copy=False)
diff --git a/bemade_quotation_alternative/wizard/sale_order_alternative_views.xml b/bemade_quotation_alternative/wizard/sale_order_alternative_views.xml
deleted file mode 100644
index 1c0f07a..0000000
--- a/bemade_quotation_alternative/wizard/sale_order_alternative_views.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
- bemade_quotation_alternative.sale_order_alternative.form
- sale.order.alternative
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/bemade_quotation_alternative/wizard/sale_order_duplication_wizard.py b/bemade_quotation_alternative/wizard/sale_order_duplication_wizard.py
new file mode 100644
index 0000000..a4e070b
--- /dev/null
+++ b/bemade_quotation_alternative/wizard/sale_order_duplication_wizard.py
@@ -0,0 +1,78 @@
+from odoo import models, fields, api
+
+class SaleOrderDuplicationWizard(models.TransientModel):
+ _name = 'sale.order.duplication.wizard'
+ _description = 'Wizard for duplicating a sale order'
+
+ original_order_id = fields.Many2one('sale.order', string='Original Order', required=True)
+ new_quot = fields.Char(string='New Quotation Name', compute='_compute_new_quot', store=True)
+
+ duplicate_all_lines = fields.Boolean(string='Duplicate All Lines?', default=True)
+ lines_to_duplicate = fields.One2many(
+ 'sale.order.line.duplication.wizard', 'wizard_id',
+ string="Lines to Duplicate",
+ context={'default_original_order_id': original_order_id},
+ )
+
+ purpose = fields.Text(string='Purpose')
+ note = fields.Html(string='Note')
+
+ @api.model
+ def default_get(self, fields_list):
+ res = super(SaleOrderDuplicationWizard, self).default_get(fields_list)
+ if 'default_original_order_id' in self.env.context:
+ original_order_id = self.env.context['default_original_order_id']
+ original_order = self.env['sale.order'].browse(original_order_id)
+ lines_vals = []
+ for line in original_order.order_line:
+ lines_vals.append((0, 0, {'sale_order_line_id': line.id}))
+ res.update({
+ 'lines_to_duplicate': lines_vals,
+ 'purpose': original_order.purpose if 'purpose' in fields_list else '',
+ 'note': original_order.note if 'note' in fields_list else '',
+ })
+ return res
+
+ def action_duplicate_order(self):
+ self.ensure_one()
+ # Duplication de la commande de vente
+ new_order = self.original_order_id.copy({
+ 'purpose': self.purpose,
+ 'note': self.note,
+ # Assurez-vous que 'new_quot' est défini correctement dans votre modèle
+ 'name': self.new_quot,
+ })
+ if not self.duplicate_all_lines:
+ new_order.order_line.unlink()
+ for line_wiz in self.lines_to_duplicate.filtered('to_duplicate'):
+ line_wiz.sale_order_line_id.copy({'order_id': new_order.id})
+
+ # Préparation et envoi des messages de notification dans le chatter
+ user_name = self.env.user.name
+ now = fields.Datetime.now()
+
+ # Message pour la commande originale
+ original_msg_body = f"A new quotation #{new_order.name} created by {user_name} duplicating this Quotation."
+ self.original_order_id.message_post(body=original_msg_body)
+
+ # Message pour la nouvelle commande dupliquée
+ new_msg_body = f"This quotation has been created by {user_name} duplicating the original Quotation #{self.original_order_id.name}."
+ new_order.message_post(body=new_msg_body)
+
+ return {
+ 'type': 'ir.actions.act_window',
+ 'name': 'Duplicated Order',
+ 'res_model': 'sale.order',
+ 'res_id': new_order.id,
+ 'view_mode': 'form',
+ 'target': 'current',
+ }
+
+ @api.depends('original_order_id')
+ def _compute_new_quot(self):
+
+ for rec in self:
+ original_order_name = rec.original_order_id.name.split('-')[
+ 0] if '-' in rec.original_order_id.name else rec.original_order_id.name
+ other_quotes = self.env['sale.order'].search([('name', 'like', original_order_name + '%')])
+ rec.new_quot = original_order_name + '-REV' + str(len(other_quotes))
diff --git a/bemade_quotation_alternative/wizard/sale_order_duplication_wizard_view.xml b/bemade_quotation_alternative/wizard/sale_order_duplication_wizard_view.xml
new file mode 100644
index 0000000..096cae0
--- /dev/null
+++ b/bemade_quotation_alternative/wizard/sale_order_duplication_wizard_view.xml
@@ -0,0 +1,39 @@
+
+
+
+
+ sale.order.duplication.wizard.form
+ sale.order.duplication.wizard
+
+
+
+
+ Duplicate Sale Order
+ ir.actions.act_window
+ sale.order.duplication.wizard
+ form
+ new
+
+
+
diff --git a/bemade_search_supplier_code/__manifest__.py b/bemade_search_supplier_code/__manifest__.py
index 7e43849..eb245be 100644
--- a/bemade_search_supplier_code/__manifest__.py
+++ b/bemade_search_supplier_code/__manifest__.py
@@ -1,5 +1,6 @@
{
- 'version': '17.0.0.1',
+ 'name': 'Bemade Search Supplier Code',
+ 'version': '17.0.1.0.1',
'summary': 'Search for products by supplier code',
'sequence': 10,
'description': """
diff --git a/bemade_so_followers_to_picking/__manifest__.py b/bemade_so_followers_to_picking/__manifest__.py
index 12f3c62..7827752 100644
--- a/bemade_so_followers_to_picking/__manifest__.py
+++ b/bemade_so_followers_to_picking/__manifest__.py
@@ -11,7 +11,8 @@
'website': 'https://www.bemade.org',
"depends": [
'sale',
- 'purchase'
+ 'purchase',
+ 'stock',
],
"data": [
],
diff --git a/bemade_sports_clinic/views/res_partner_views.xml b/bemade_sports_clinic/views/res_partner_views.xml
index 5c810f2..e2c77af 100644
--- a/bemade_sports_clinic/views/res_partner_views.xml
+++ b/bemade_sports_clinic/views/res_partner_views.xml
@@ -1,4 +1,4 @@
-
+
res.partner.view.form.sports.teams
@@ -7,14 +7,9 @@
-
-
+
+
-
-
+
-
\ No newline at end of file
+
diff --git a/bemade_sports_clinic/views/sports_team_views.xml b/bemade_sports_clinic/views/sports_team_views.xml
index 50ccca2..b52058b 100644
--- a/bemade_sports_clinic/views/sports_team_views.xml
+++ b/bemade_sports_clinic/views/sports_team_views.xml
@@ -1,4 +1,4 @@
-
+
teams.view.search
@@ -9,21 +9,16 @@
-
-
-
-
-
+
+
+
+
sports.team.view.kanbansports.team
-
+
@@ -35,7 +30,9 @@
-
+
+
+
@@ -44,16 +41,21 @@
- Head coach:
+
+ Head coach:
+
+
- Head therapist:
+
+ Head therapist:
+
+
- Healthy:
+
+ Healthy:
@@ -67,8 +69,7 @@
-
-
+
sports.team.view.list
@@ -81,19 +82,22 @@
-
-
+
sports.team.view.formsports.team
-
+
sports.team.staff.view.form
@@ -150,7 +140,6 @@
-
-
+
diff --git a/bemade_total_show_currency/__manifest__.py b/bemade_total_show_currency/__manifest__.py
new file mode 100644
index 0000000..c422023
--- /dev/null
+++ b/bemade_total_show_currency/__manifest__.py
@@ -0,0 +1,41 @@
+#
+# Bemade Inc.
+#
+# Copyright (C) June 2023 Bemade Inc. ().
+# Author: mdurepos (Contact : it@bemade.org)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+{
+ 'name': 'Show Currency in total',
+ 'version': '17.0.0.0.1',
+ 'summary': 'Show Currency in total',
+ 'description': """
+ This module adds the ability to view currency in total in all pdf.
+ """,
+ 'category': 'Account',
+ 'author': 'Bemade Inc.',
+ 'website': 'https://www.bemade.org',
+ 'license': 'OPL-1',
+ 'depends': [
+ 'sale',
+ 'purchase',
+ 'account'
+ ],
+ 'data': [
+ 'views/total_template.xml'
+ ],
+ 'demo': [],
+ 'installable': True,
+ 'auto_install': False,
+}
diff --git a/bemade_total_show_currency/views/total_template.xml b/bemade_total_show_currency/views/total_template.xml
new file mode 100644
index 0000000..77a2bf2
--- /dev/null
+++ b/bemade_total_show_currency/views/total_template.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+ ()
+
+
+
+
+
\ No newline at end of file
diff --git a/bemade_utils/__init__.py b/bemade_utils/__init__.py
new file mode 100644
index 0000000..9ac735b
--- /dev/null
+++ b/bemade_utils/__init__.py
@@ -0,0 +1 @@
+from odoo.addons.bemade_utils.tools import patch_test
diff --git a/bemade_utils/__manifest__.py b/bemade_utils/__manifest__.py
new file mode 100644
index 0000000..669c94a
--- /dev/null
+++ b/bemade_utils/__manifest__.py
@@ -0,0 +1,33 @@
+#
+# Bemade Inc.
+#
+# Copyright (C) 2023-June Bemade Inc. ().
+# Author: Marc Durepos (Contact : marc@bemade.org)
+#
+# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
+# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
+# or modified copies of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+{
+ 'name': 'Bemade App Utilities',
+ 'version': '17.0.1.0.0',
+ 'summary': 'Utilities commonly used in Bemade modules.',
+ 'description': 'Adds utilities such as an annotation for patching tests when modifying Odoo behaviour.',
+ 'category': 'Technical',
+ 'author': 'Bemade Inc.',
+ 'website': 'http://www.bemade.org',
+ 'license': 'OPL-1',
+ 'depends': [],
+ 'data': [],
+ 'assets': {},
+ 'installable': True,
+ 'auto_install': False
+}
diff --git a/bemade_utils/tests/__init__.py b/bemade_utils/tests/__init__.py
new file mode 100644
index 0000000..27cd6d5
--- /dev/null
+++ b/bemade_utils/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_patching_test
diff --git a/bemade_utils/tests/test_patching_test.py b/bemade_utils/tests/test_patching_test.py
new file mode 100644
index 0000000..9cd5bb4
--- /dev/null
+++ b/bemade_utils/tests/test_patching_test.py
@@ -0,0 +1,16 @@
+from odoo.tests import TransactionCase
+from addons.bemade_utils import patch_test
+
+
+class TestA(TransactionCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+
+ def test_method_a(self):
+ self.assertFalse(True)
+
+
+@patch_test(TestA.test_method_a)
+def test_redefining_test(self):
+ self.assertTrue(True)
diff --git a/bemade_utils/tools/__init__.py b/bemade_utils/tools/__init__.py
new file mode 100644
index 0000000..f467f1c
--- /dev/null
+++ b/bemade_utils/tools/__init__.py
@@ -0,0 +1,2 @@
+from .test import patch_test
+
diff --git a/bemade_utils/tools/test.py b/bemade_utils/tools/test.py
new file mode 100644
index 0000000..3f4aa18
--- /dev/null
+++ b/bemade_utils/tools/test.py
@@ -0,0 +1,28 @@
+import importlib
+from functools import wraps
+
+
+def patch_test(original_method):
+ """
+ A decorator that patches an Odoo test method with a new one.
+ The original_method is a direct reference to the method to be patched.
+ """
+ def decorator(new_method):
+ @wraps(new_method)
+ def wrapper(*args, **kwargs):
+ return new_method(*args, **kwargs)
+
+ # Extract module and class names
+ module_name = original_method.__module__
+ class_name = original_method.__qualname__.split('.')[0]
+
+ # Import the module
+ module = importlib.import_module(module_name)
+ # Get the class
+ cls = getattr(module, class_name)
+
+ # Replace the original method with the new one
+ setattr(cls, original_method.__name__, wrapper)
+
+ return wrapper
+ return decorator