Browse Source

Feb 20 : [ADD] Initial Commit 'website_return_management'

pull/254/merge
RisvanaCybro 1 year ago
parent
commit
a6ae78c86f
  1. 44
      website_return_management/README.rst
  2. 24
      website_return_management/__init__.py
  3. 55
      website_return_management/__manifest__.py
  4. 23
      website_return_management/controllers/__init__.py
  5. 136
      website_return_management/controllers/portal.py
  6. 88
      website_return_management/controllers/website_return_management.py
  7. 13
      website_return_management/data/ir_sequence.xml
  8. 5
      website_return_management/doc/RELEASE_NOTES.md
  9. 25
      website_return_management/models/__init__.py
  10. 63
      website_return_management/models/res_partner.py
  11. 65
      website_return_management/models/sale_order.py
  12. 264
      website_return_management/models/sale_return.py
  13. 72
      website_return_management/models/stock_picking.py
  14. 77
      website_return_management/report/website_return_management_reports.xml
  15. 2
      website_return_management/security/ir.model.access.csv
  16. BIN
      website_return_management/static/description/assets/icons/check.png
  17. BIN
      website_return_management/static/description/assets/icons/chevron.png
  18. BIN
      website_return_management/static/description/assets/icons/cogs.png
  19. BIN
      website_return_management/static/description/assets/icons/consultation.png
  20. BIN
      website_return_management/static/description/assets/icons/ecom-black.png
  21. BIN
      website_return_management/static/description/assets/icons/education-black.png
  22. BIN
      website_return_management/static/description/assets/icons/hotel-black.png
  23. BIN
      website_return_management/static/description/assets/icons/icon.png
  24. BIN
      website_return_management/static/description/assets/icons/license.png
  25. BIN
      website_return_management/static/description/assets/icons/lifebuoy.png
  26. BIN
      website_return_management/static/description/assets/icons/logo.png
  27. BIN
      website_return_management/static/description/assets/icons/manufacturing-black.png
  28. BIN
      website_return_management/static/description/assets/icons/pos-black.png
  29. BIN
      website_return_management/static/description/assets/icons/puzzle.png
  30. BIN
      website_return_management/static/description/assets/icons/restaurant-black.png
  31. BIN
      website_return_management/static/description/assets/icons/service-black.png
  32. BIN
      website_return_management/static/description/assets/icons/trading-black.png
  33. BIN
      website_return_management/static/description/assets/icons/training.png
  34. BIN
      website_return_management/static/description/assets/icons/update.png
  35. BIN
      website_return_management/static/description/assets/icons/user.png
  36. BIN
      website_return_management/static/description/assets/icons/wrench.png
  37. BIN
      website_return_management/static/description/assets/modules/budget_image.png
  38. BIN
      website_return_management/static/description/assets/modules/credit_image.png
  39. BIN
      website_return_management/static/description/assets/modules/employee_image.png
  40. BIN
      website_return_management/static/description/assets/modules/export_image.png
  41. BIN
      website_return_management/static/description/assets/modules/gantt_image.png
  42. BIN
      website_return_management/static/description/assets/modules/quotation_image.png
  43. BIN
      website_return_management/static/description/assets/screenshots/hero.gif
  44. BIN
      website_return_management/static/description/assets/screenshots/scrshot_1.png
  45. BIN
      website_return_management/static/description/assets/screenshots/scrshot_10.png
  46. BIN
      website_return_management/static/description/assets/screenshots/scrshot_11.png
  47. BIN
      website_return_management/static/description/assets/screenshots/scrshot_12.png
  48. BIN
      website_return_management/static/description/assets/screenshots/scrshot_13.png
  49. BIN
      website_return_management/static/description/assets/screenshots/scrshot_14.png
  50. BIN
      website_return_management/static/description/assets/screenshots/scrshot_2.png
  51. BIN
      website_return_management/static/description/assets/screenshots/scrshot_3.png
  52. BIN
      website_return_management/static/description/assets/screenshots/scrshot_4.png
  53. BIN
      website_return_management/static/description/assets/screenshots/scrshot_5.png
  54. BIN
      website_return_management/static/description/assets/screenshots/scrshot_6.png
  55. BIN
      website_return_management/static/description/assets/screenshots/scrshot_7.png
  56. BIN
      website_return_management/static/description/assets/screenshots/scrshot_8.png
  57. BIN
      website_return_management/static/description/assets/screenshots/scrshot_9.png
  58. BIN
      website_return_management/static/description/banner.jpg
  59. BIN
      website_return_management/static/description/icon.png
  60. 832
      website_return_management/static/description/index.html
  61. 88
      website_return_management/static/src/js/sale_return.js
  62. 377
      website_return_management/views/portal_templates.xml
  63. 19
      website_return_management/views/res_partner_views.xml
  64. 21
      website_return_management/views/sale_order_views.xml
  65. 118
      website_return_management/views/sale_return_views.xml
  66. 16
      website_return_management/views/stock_picking_views.xml
  67. 36
      website_return_management/views/website_thankyou_templates.xml
  68. 22
      website_return_management/wizard/__init__.py
  69. 40
      website_return_management/wizard/stock_return_picking.py

44
website_return_management/README.rst

@ -0,0 +1,44 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
Website Return Order Management
===============================
* Website Return Order Management module for Odoo 15
Installation
============
- https://www.odoo.com/documentation/17.0/administration/install.html
- Install our custom addon
Company
-------
* 'Cybrosys Techno Solutions <https://cybrosys.com/>`__
Credits
-------
* Developer:
(v14) Shijin @ Cybrosys
(v15) Sabeel @ Cybrosys
(v16) Rosmy @ Cybrosys
Contacts
--------
* Mail Contact : odoo@cybrosys.com
Bug Tracker
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
Maintainer
==========
.. image:: https://cybrosys.com/images/logo.png
:target: https://cybrosys.com
This module is maintained by Cybrosys Technologies.
For support and more information, please visit https://www.cybrosys.com
Further information
===================
HTML Description: `<static/description/index.html>`__

24
website_return_management/__init__.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from . import controllers
from . import models
from . import wizard

55
website_return_management/__manifest__.py

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
{
'name': 'Website Return Order Management',
'version': '15.0.1.0.0',
'category': 'Website',
'summary': 'Sale Order Return Management from Website',
'description': """Website Return Order Management, Website Return,
Order Return, RMA, Website RMA""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': ['website_sale', 'stock', 'sale_management'],
'data': [
'security/ir.model.access.csv',
'data/ir_sequence.xml',
'views/website_thankyou_templates.xml',
'views/portal_templates.xml',
'views/sale_return_views.xml',
'views/sale_order_views.xml',
'views/res_partner_views.xml',
'views/stock_picking_views.xml',
'report/website_return_management_reports.xml'
],
'assets': {
'web.assets_frontend': [
'website_return_management/static/src/js/sale_return.js'
]
},
'images': ['static/description/banner.jpg'],
'license': 'AGPL-3',
'installable': True,
'auto_install': False,
'application': False,
}

23
website_return_management/controllers/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from . import portal
from . import website_return_management

136
website_return_management/controllers/portal.py

@ -0,0 +1,136 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
import base64
from collections import OrderedDict
from odoo import http
from odoo.http import request
from odoo.exceptions import AccessError, MissingError
from odoo.tools import image_process
from odoo.tools.translate import _
from odoo.addons.portal.controllers.portal import CustomerPortal
class ReturnCustomerPortal(CustomerPortal):
"""Class to show return orders on portal pages"""
def _prepare_home_portal_values(self, counters):
"""Fetch total count of sale_return records"""
values = super()._prepare_home_portal_values(counters)
if 'return_count' in counters:
values['return_count'] = request.env['sale.return'].search_count([
('state', 'in', ['draft', 'confirm', 'done', 'cancel'])])
return values
@http.route(['/my/return_orders',
'/my/return_orders/page/<int:page>'],
type='http', auth="user", website=True)
def portal_my_sale_return(self, page=1, date_begin=None, date_end=None,
sortby=None, filterby=None):
"""Return History in my accounts"""
values = self._prepare_portal_layout_values()
sale_return = request.env['sale.return']
domain = []
searchbar_sortings = {
'date': {'label': _('Newest'), 'order': 'create_date desc'},
'name': {'label': _('Name'), 'order': 'name'},
'sale': {'label': _('Sale Order'), 'order': 'sale_order'},
}
# default sort by value
if not sortby:
sortby = 'date'
order = searchbar_sortings[sortby]['order']
if date_begin and date_end:
domain += [('create_date', '>', date_begin),
('create_date', '<=', date_end)]
searchbar_filters = {
'all': {'label': _('All'), 'domain': [
('state', 'in', ['draft', 'confirm', 'done', 'cancel'])]},
'confirm': {'label': _('Confirmed'), 'domain': [
('state', '=', 'confirm')]},
'cancel': {'label': _('Cancelled'), 'domain': [
('state', '=', 'cancel')]},
'done': {'label': _('Done'), 'domain': [('state', '=', 'done')]},
}
# default filter by value
if not filterby:
filterby = 'all'
domain += searchbar_filters[filterby]['domain']
# pager
pager = request.website.pager(
url="/my/return_orders",
url_args={'date_begin': date_begin, 'date_end': date_end,
'sortby': sortby},
total=sale_return.search_count(domain),
page=page,
step=self._items_per_page
)
# content according to pager and archive selected
orders = sale_return.search(domain, order=order,
limit=self._items_per_page,
offset=pager['offset'])
request.session['my_return_history'] = orders.ids[:100]
values.update({
'date': date_begin,
'orders': orders.sudo(),
'page_name': 'Sale_Return',
'default_url': '/my/return_orders',
'pager': pager,
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
'searchbar_sortings': searchbar_sortings,
'sortby': sortby,
})
return request.render("website_return_management.portal_my_returns",
values)
@http.route(['/my/return_orders/<int:order_id>'], type='http',
auth="public", website=True)
def portal_my_return_detail(self, order_id=None, access_token=None,
report_type=None, download=False, **kw):
"""Passing datas for detailed display in my account"""
try:
order_sudo = self._document_check_access('sale.return', order_id,
access_token)
except (AccessError, MissingError):
return request.redirect('/my')
if report_type in ('html', 'pdf', 'text'):
return self._show_report(model=order_sudo, report_type=report_type,
report_ref='website_return_management.'
'report_sale_returns',
download=download)
values = self._sale_return_get_page_view_values(order_sudo,
access_token, **kw)
return (request.render
("website_return_management.portal_sale_return_page", values))
def _sale_return_get_page_view_values(self, order, access_token, **kwargs):
def resize_to_48(b64source):
"""Converting product images"""
if not b64source:
b64source = request.env['ir.binary']._placeholder()
else:
b64source = base64.b64decode(b64source)
return base64.b64encode(image_process(b64source, size=(48, 48)))
values = {
'orders': order,
'resize_to_48': resize_to_48,
}
return self._get_page_view_values(order, access_token, values,
'my_return_history', False, **kwargs)

88
website_return_management/controllers/website_return_management.py

@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from datetime import datetime
from odoo import http, _
from odoo.http import request
from odoo.addons.website.controllers import main
class CustomerRegistration(main.Home):
"""Class to manage and create website return orders"""
@http.route('/sale_return', type='json', methods=['POST'],
auth="public", website=True,
csrf=False)
def sale_return(self, **kwargs):
"""Controller to create return order"""
product_id = request.env['product.product'].sudo().search([
('id', '=', int(kwargs['product']))])
order = request.env['sale.order'].sudo().search([
('id', '=', int(kwargs['order_id']))])
values = {
'partner_id': order.partner_id.id,
'sale_order_id': order.id,
'product_id': product_id.id,
'quantity': kwargs['qty'],
'reason': kwargs['reason'],
'user_id': request.env.uid,
'create_date': datetime.now(),
}
stock_picks = request.env['stock.picking'].search([
('origin', '=', order.name)])
moves = (stock_picks.mapped('move_ids_without_package').filtered
(lambda p: p.product_id == product_id))
if moves:
moves = moves.sorted('product_uom_qty', reverse=True)
values.update({'state': 'draft'})
ret_order = request.env['sale.return'].create(values)
ret_order.return_confirm()
moves[0].picking_id.return_order_id = ret_order.id
moves[0].picking_id.return_order_picking = False
return True
@http.route('/order_quantity', auth='public', type='json',
website=True)
def return_quantity(self, **kwargs):
"""Check the existing records for total returned quantity"""
current_order = (request.env['sale.order'].sudo().browse
(int(kwargs['current_order'])))
for rec in current_order.order_line.filtered(
lambda ids: ids.product_id.id == int(
kwargs['product_id'])):
return_order = request.env['sale.return'].sudo().search([
('sale_order_id', '=', current_order.id),
('product_id', '=', int(kwargs['product_id'])),
('state', 'in', ('confirm', 'done'))])
if return_order:
remaining_qty = rec.qty_delivered - sum(
return_order.mapped('quantity'))
if remaining_qty == 0:
rec.return_qty = True
return remaining_qty
else:
return rec.qty_delivered
@http.route('/my/request-thank-you', website=True, page=True,
auth='public', csrf=False)
def maintenance_request_thanks(self):
"""Thank you page"""
return (request.render
('website_return_management.customers_request_thank_page'))

13
website_return_management/data/ir_sequence.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<!-- Sequence Number For Sale Return-->
<record id="seq_sale_return" model="ir.sequence">
<field name="name">Sale Return</field>
<field name="code">sale.return</field>
<field name="prefix">RET</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
</data>
</odoo>

5
website_return_management/doc/RELEASE_NOTES.md

@ -0,0 +1,5 @@
## Module <website_return_management>
#### 16.02.2024
#### Version 15.0.1.0.0
- Initial Commit for Website Return Order Management

25
website_return_management/models/__init__.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from . import sale_order
from . import res_partner
from . import sale_return
from . import stock_picking

63
website_return_management/models/res_partner.py

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from odoo import fields, models
class ResPartner(models.Model):
"""Inheriting res_partner to show sale_return count"""
_inherit = 'res.partner'
return_order_count = fields.Integer(compute="_compute_returns",
string='Return Orders',
help="Fetch return order count")
def _compute_returns(self):
"""Function to calculate the return count"""
all_partners = self.with_context(active_test=False).search([
('id', 'child_of', self.ids)])
all_partners.read(['parent_id'])
sale_return_groups = self.env['sale.return'].sudo().read_group(
domain=[('partner_id', '=', all_partners.ids)],
fields=['partner_id'], groupby=['partner_id'])
partners = self.browse()
for group in sale_return_groups:
partner = self.browse(group['partner_id'][0])
while partner:
if partner in self:
partner.return_order_count += group['partner_id_count']
partners |= partner
partner = partner.parent_id
(self - partners).return_order_count = 0
def action_open_returns(self):
"""This function returns an action that displays the sale return
orders from partner."""
action = (self.env['ir.actions.act_window']._for_xml_id
('website_return_management.sale_return_action'))
domain = []
if self.is_company:
domain.append(('partner_id.commercial_partner_id.id', '=', self.id))
else:
domain.append(('partner_id.id', '=', self.id))
action['domain'] = domain
action['context'] = {'search_default_customer': 1}
return action

65
website_return_management/models/sale_order.py

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from odoo import fields, models
class SaleOrder(models.Model):
"""Inheriting sale_order to add internal link and counts of sale_return"""
_inherit = 'sale.order'
return_order_count = fields.Integer(compute="_compute_returns",
string='Return Orders',
help="Fetch return order count")
def _compute_returns(self):
"""method to compute return count"""
sale_return_groups = self.env['sale.return'].sudo().read_group(
domain=[('sale_order_id', '=', self.ids)],
fields=['sale_order_id'], groupby=['sale_order_id'])
orders = self.browse()
for group in sale_return_groups:
sale_order = self.browse(group['sale_order_id'][0])
while sale_order:
if sale_order in self:
sale_order.return_order_count += (
group)['sale_order_id_count']
orders |= sale_order
sale_order = False
(self - orders).return_order_count = 0
def action_open_returns(self):
"""This function returns an action that displays the sale return
orders from sale order"""
action = (self.env['ir.actions.act_window']._for_xml_id
('website_return_management.sale_return_action'))
domain = [('sale_order_id', '=', self.id)]
action['domain'] = domain
action['context'] = {'search_default_order': 1}
return action
class SaleOrderLine(models.Model):
"""Inherit sale order line to add a new field"""
_inherit = 'sale.order.line'
return_qty = fields.Boolean(string="Return Qty",
help="Hide the product from returning")

264
website_return_management/models/sale_return.py

@ -0,0 +1,264 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from odoo import api, fields, models
class SaleReturn(models.Model):
_name = 'sale.return'
_inherit = ['portal.mixin']
_rec_name = "name"
_order = "name"
_description = "Sale Return"
@api.model
def _get_default_name(self):
"""Default value for name field"""
return self.env['ir.sequence'].get('sale.return')
active = fields.Boolean('Active', default=True,
help="Show Active Record")
name = fields.Char(string="Name", default=_get_default_name,
help="Name Field")
product_id = fields.Many2one('product.product',
string="Product Variant", required=True,
help="defines the product variant that need"
"to be returned")
product_tmpl_id = fields.Many2one('product.template',
related="product_id.product_tmpl_id",
store=True,
string="Product",
help="Product template relation")
sale_order_id = fields.Many2one('sale.order',
string="Sale Order",
required=True, help="Sale order relation")
partner_id = fields.Many2one('res.partner', string="Customer",
help="Res partner relation")
user_id = fields.Many2one('res.users', string="Responsible",
default=lambda self: self.env.user,
help="Res user relation")
create_date = fields.Datetime(string="Create Date", help="Create Date")
quantity = fields.Float(string="Quantity", default=0,
help="Number of quantity")
received_qty = fields.Float(string="Received Quantity",
help="Number of received quantity")
reason = fields.Text("Reason", help="Reason to add")
stock_picking_ids = fields.One2many('stock.picking',
'return_order_pick_id',
domain="["
"('return_order_id','=',False)]",
string="Return Picking",
help="Shows the return picking of the "
"corresponding return order")
picking_count = fields.Integer(compute="_compute_delivery",
string='Picking Order', copy=False,
default=0,
store=True,
help="Picking count")
delivery_count = fields.Integer(compute="_compute_delivery",
string='Delivery Order', copy=False,
default=0,
store=True,
help="Delivery Count")
state = fields.Selection([('draft', 'Draft'),
('confirm', 'Confirm'), ('done', 'Done'),
('cancel', 'Canceled')],
string='Status', readonly=True, default='draft',
help="State")
source_pick_ids = fields.One2many('stock.picking',
'return_order_id',
string="Source Delivery",
domain="[('return_order_pick_id',"
"'=',False)]",
help="Shows the delivery orders of the "
"corresponding return order")
note = fields.Text("Note", help="Note field")
to_refund = fields.Boolean(string='Update SO/PO Quantity',
help='Trigger a decrease of the'
' delivered/received quantity in'
' the associated Sale '
'Order/Purchase Order')
def return_confirm(self):
"""Confirm the sale return"""
if not self.source_pick_ids:
stock_picks = self.env['stock.picking'].search([
('origin', '=', self.sale_order_id.name)])
moves = (stock_picks.mapped('move_ids_without_package').filtered
(lambda p: p.product_id == self.product_id))
else:
moves = (self.source_pick_ids.mapped
('move_ids_without_package').filtered
(lambda p: p.product_id == self.product_id))
if moves:
moves = moves.sorted('product_uom_qty', reverse=True)
return_pick_wizard = (self.env['stock.return.picking'].create
({'picking_id': moves[0].picking_id.id}))
return_pick_wizard._onchange_picking_id()
return_pick_wizard.product_return_moves.unlink()
lines = {'product_id': self.product_id.id,
"quantity": self.quantity,
'wizard_id': return_pick_wizard.id,
'move_id': moves[0].id, 'to_refund': self.to_refund}
self.env['stock.return.picking.line'].create(lines)
return_pick = return_pick_wizard._create_returns()
if return_pick:
return_pick = self.env['stock.picking'].browse(return_pick[0])
return_pick.update({'note': self.reason})
return_pick.write({'return_order_id': False,
'return_order_pick_id': self.id,
'return_order_picking': True})
self.write({'state': 'confirm'})
def return_cancel(self):
"""Cancel the return"""
self.write({'state': 'cancel'})
if self.source_pick_ids:
for rec in (self.source_pick_ids.filtered(lambda s:
s.state not in
['done', 'cancel'])):
rec.action_cancel()
def _get_report_base_filename(self):
"""Fetch report name"""
self.ensure_one()
return 'Sale Return - %s' % (self.name)
def _compute_access_url(self):
"""URL accessing"""
super(SaleReturn, self)._compute_access_url()
for order in self:
order.access_url = '/my/return_orders/%s' % order.id
@api.depends('stock_picking_ids', 'state')
def _compute_delivery(self):
"""Function to compute picking and delivery counts"""
for rec in self:
rec.delivery_count = 0
rec.picking_count = 0
if rec.source_pick_ids:
rec.delivery_count = len(rec.source_pick_ids)
else:
rec.delivery_count = self.env['stock.picking'].search_count(
[('return_order_id', 'in', self.ids),
('return_order_picking', '=', False)])
if rec.stock_picking_ids:
rec.picking_count = len(rec.stock_picking_ids)
else:
rec.picking_count = self.env['stock.picking'].search_count(
[('return_order_pick_id', 'in', self.ids),
('return_order_picking', '=', True)])
def action_view_picking(self):
"""Function to view the stock picking transfers"""
action = (self.env["ir.actions.actions"]._for_xml_id
("stock.action_picking_tree_all"))
pickings = self.mapped('stock_picking_ids')
if not self.stock_picking_ids:
pickings = self.env['stock.picking'].search(
[('return_order_pick_id', '=', self.id),
('return_order_picking', '=', True)])
if len(pickings) > 1:
action['domain'] = [('id', 'in', pickings.ids)]
elif pickings:
form_view = [(self.env.ref('stock.view_picking_form').id, 'form')]
if 'views' in action:
action['views'] = form_view + [(state, view) for state, view in
action['views']
if view != 'form']
else:
action['views'] = form_view
action['res_id'] = pickings.id
# Prepare the context.
picking_id = (pickings.filtered
(lambda x: x.picking_type_id.code == 'outgoing'))
if picking_id:
picking_id = picking_id[0]
else:
picking_id = pickings[0]
action['context'] = dict(self._context,
default_partner_id=self.partner_id.id,
default_picking_type_id=
picking_id.picking_type_id.id)
return action
def action_view_delivery(self):
"""Function to view the delivery transfers"""
action = (self.env["ir.actions.actions"]._for_xml_id
("stock.action_picking_tree_all"))
pickings = self.mapped('stock_picking_ids')
if not self.stock_picking_ids:
pickings = self.env['stock.picking'].search(
[('return_order_id', '=', self.id),
('return_order_picking', '=', False)])
if len(pickings) > 1:
action['domain'] = [('id', 'in', pickings.ids)]
elif pickings:
form_view = [(self.env.ref('stock.view_picking_form').id, 'form')]
if 'views' in action:
action['views'] = form_view + [(state, view) for state, view in
action['views']
if view != 'form']
else:
action['views'] = form_view
action['res_id'] = pickings.id
# Prepare the context.
picking_id = (pickings.filtered(lambda x:
x.picking_type_id.code == 'outgoing'))
if picking_id:
picking_id = picking_id[0]
else:
picking_id = pickings[0]
action['context'] = dict(self._context,
default_partner_id=self.partner_id.id,
default_picking_type_id=
picking_id.picking_type_id.id)
return action
@api.onchange('sale_order', 'source_pick')
def onchange_sale_order(self):
"""All the fields are updated according to the sale order"""
delivery = None
if self.sale_order_id:
self.partner_id = self.sale_order_id.partner_id
delivery = self.env['stock.picking'].search([
('origin', '=', self.sale_order_id.name)])
if self.source_pick_ids:
delivery = self.source_pick_ids
if delivery:
product_ids = (
delivery.move_ids_without_package.mapped('product_id').ids)
delivery = delivery.ids
else:
product_ids = self.sale_order_id.order_line.mapped('product_id').ids
return {'domain': {'source_pick': [('id', 'in', delivery)],
'product_id': [('id', 'in', product_ids)]}}
@api.onchange('product_id')
def onchange_product_id(self):
"""Return Stock Valuation"""
if self.product_id and self.source_pick_ids:
moves = (self.source_pick_ids.mapped('move_ids_without_package').
filtered(lambda p: p.product_id == self.product_id))
if moves:
self.received_qty = sum(moves.mapped('quantity_done'))

72
website_return_management/models/stock_picking.py

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from odoo import fields, models
class StockPicking(models.Model):
"""Inheriting stock_picking to add new fields regarding return orders"""
_inherit = 'stock.picking'
return_order_id = fields.Many2one('sale.return',
string='Return Order',
help="Shows the return order of current"
"transfer")
return_order_pick_id = fields.Many2one('sale.return',
string='Return Order Pick',
help="Shows the return order picking"
"of current return order")
return_order_picking = fields.Boolean(string='Return Order Picking',
help="Helps to identify delivery"
" and return picking, if true"
"the transfer is return picking"
"else delivery")
def button_validate(self):
"""Supering Validate Button function"""
res = super(StockPicking, self).button_validate()
for rec in self:
if rec.return_order_pick_id:
if any(line.state != 'done' for line in
rec.return_order_pick_id.stock_picking_ids):
return res
else:
for line in (rec.return_order_pick_id.sale_order_id.
order_line.filtered(
lambda ids: ids.product_id.id == rec.
return_order_pick_id.product_id.id)):
return_order = self.env[
'sale.return'].sudo().search(
[('sale_order_id', '=',
rec.return_order_pick_id.sale_order_id.id),
('product_id', '=',
rec.return_order_pick_id.product_id.id),
('state', '=', 'done')])
if (return_order and (
sum(return_order.mapped('quantity')) +
rec.return_order_pick_id.quantity) ==
line.qty_delivered):
line.return_qty = True
elif (rec.return_order_pick_id.quantity ==
line.qty_delivered):
line.return_qty = True
rec.return_order_pick_id.state = 'done'
return res

77
website_return_management/report/website_return_management_reports.xml

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- PDF report action-->
<record id="report_sale_returns" model="ir.actions.report">
<field name="name">Sale Return</field>
<field name="model">sale.return</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">website_return_management.report_salereturn</field>
<field name="report_file">website_return_management.report_salereturn</field>
<field name="print_report_name">'Sale Retun - %s' % object.name</field>
<field name="binding_model_id" ref="model_sale_return"/>
<field name="binding_type">report</field>
</record>
<!-- Calling template-->
<template id="report_salereturn">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="website_return_management.report_sale_return" t-lang="doc.partner_id.lang"/>
</t>
</t>
</template>
<!-- PDF report template-->
<template id="report_sale_return">
<t t-call="web.external_layout">
<t t-set="doc" t-value="doc.with_context(lang=doc.partner_id.lang)"/>
<div class="page">
<div class="oe_structure"/>
<h2 class="mt16">
<span>Return Order # </span>
<span t-field="doc.name"/>
</h2>
<div class="row mt32 mb32" id="informations">
<div t-if="doc.partner_id" class="col-auto col-3 mw-100 mb-2">
<strong>Customer:</strong>
<p class="m-0" t-field="doc.partner_id"/>
</div>
<div t-if="doc.sale_order_id" class="col-auto col-3 mw-100 mb-2">
<strong>Sale Order:</strong>
<p class="m-0" t-field="doc.sale_order_id"/>
</div>
<div t-if="doc.create_date" class="col-auto col-3 mw-100 mb-2">
<strong>Creation Date:</strong>
<p class="m-0" t-field="doc.create_date" t-options='{"widget": "date"}'/>
</div>
<div t-if="doc.user_id"
class="col-auto col-3 mw-100 mb-2" name="expiration_date">
<strong>Responsible:</strong>
<p class="m-0" t-field="doc.user_id"/>
</div>
</div>
<table class="table table-sm o_main_table">
<thead style="display: table-row-group">
<tr>
<th name="th_description" class="text-left">Product</th>
<th name="th_quantity" class="text-right">Quantity</th>
</tr>
</thead>
<tbody class="sale_tbody">
<tr t-att-class="'bg-200 font-weight-bold'">
<td name="td_product"><span t-field="doc.product_id"/></td>
<td name="td_quantity" class="text-right">
<span t-field="doc.quantity"/>
<span t-field="doc.product_id.uom_id"/>
</td>
</tr>
</tbody>
</table>
<div t-if="doc.partner_id" class="col-auto col-3 mw-100 mb-2">
<strong>Reason:</strong>
<p class="m-0" t-field="doc.reason"/>
</div>
</div>
</t>
</template>
</data>
</odoo>

2
website_return_management/security/ir.model.access.csv

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sale_return,access.sale.return,model_sale_return,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sale_return access.sale.return model_sale_return 1 1 1 1

BIN
website_return_management/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
website_return_management/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
website_return_management/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
website_return_management/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
website_return_management/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
website_return_management/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
website_return_management/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
website_return_management/static/description/assets/icons/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
website_return_management/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
website_return_management/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
website_return_management/static/description/assets/icons/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
website_return_management/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
website_return_management/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
website_return_management/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
website_return_management/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
website_return_management/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
website_return_management/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
website_return_management/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
website_return_management/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
website_return_management/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
website_return_management/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
website_return_management/static/description/assets/modules/budget_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
website_return_management/static/description/assets/modules/credit_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
website_return_management/static/description/assets/modules/employee_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
website_return_management/static/description/assets/modules/export_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
website_return_management/static/description/assets/modules/gantt_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
website_return_management/static/description/assets/modules/quotation_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
website_return_management/static/description/assets/screenshots/hero.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
website_return_management/static/description/assets/screenshots/scrshot_9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
website_return_management/static/description/banner.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
website_return_management/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

832
website_return_management/static/description/index.html

@ -0,0 +1,832 @@
<div class="container"
style="padding: 1rem !important; margin-bottom: 1rem !important;">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12 d-flex justify-content-between"
style="border-bottom: 1px solid #d5d5d5;">
<div class="my-3">
<img src="./assets/icons/logo.png"
style="width: auto !important; height: 40px !important;">
</div>
<div class="my-3 d-flex align-items-center">
<div
style="background-color: #7C7BAD !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;">
<i class="fa fa-check mr-1"></i>Community
</div>
<div
style="background-color: #875A7B !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
</div>
</div>
</div>
</div>
<div class="container" style="padding: 0rem 1.5rem 4rem !important">
<div class="row" style="height: 950px !important;">
<div class="col-sm-12 col-md-12 col-lg-12"
style="padding: 4.1rem 1rem !important; background-color: #FFFFFF !important; height: 600px !important;">
<div class="d-flex justify-content-center mb-2">
<h1
style="font-family: 'Montserrat', sans-serif !important; font-weight: 800 !important; color: #282F33 !important; font-size: 4rem !important; text-align: center !important;">
Website Return Order Management</h1>
</div>
<p
style="font-family: 'Montserrat', sans-serif !important; font-weight: 300 !important; color: #282F33 !important; font-size: 1.4rem !important; text-align: center !important;">
Manage Sale Order return from Website
</p>
<img src="./assets/screenshots/hero.gif" class="img-responsive"
width="100%" height="700px"/>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12 px-3 text-center">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-size: 1.4rem; font-weight: 700 !important;">
Explore this module</h2>
<div class="mt-3">
<a href="#overview" class="mr-5"
style="font-family: 'Montserrat', sans-serif !important; font-size: 1rem; font-weight: 700; color: #714B67 !important;">Overview
<i class="fa fa-chevron-right ml-1"
style="color: #714B67 !important;"></i></a>
<a href="#features" class="mr-5"
style="font-family: 'Montserrat', sans-serif !important; font-size: 1rem; font-weight: 700; color: #714B67 !important;">Key
Features <i class="fa fa-chevron-right ml-1"
style="color: #714B67 !important;"></i></a>
<a href="#screenshots" class="mr-5"
style="font-family: 'Montserrat', sans-serif !important; font-size: 1rem; font-weight: 700; color: #714B67 !important;">Screenshots
<i class="fa fa-chevron-right ml-1"
style="color: #714B67 !important;"></i></a>
</div>
<hr class="my-5" style="border-color: d5d5d5 !important;"/>
</div>
</div>
<div class="row " id="overview">
<div class="col-sm-12 col-md-12 col-lg-12 px-4">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-size: 2rem; font-weight: 700 !important; color: #21272B !important;">
Overview</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 30px !important; margin-left: 0 !important; margin-bottom: 2rem !important;"/>
<p class="mt-4"
style="font-size: 1.1rem !important; color: #282F33 !important; font-weight: 400 !important; line-height: 1.85 !important">
This module enables the creation and management of sales order returns on the website.
Authorized individuals have the capability to oversee return orders.
Additionally, portal users can view their return orders through the account portal view
</p>
</div>
</div>
<div class="row" id="features" style="margin-top: 3rem;">
<div class="col-sm-12 col-md-12 col-lg-12 px-4">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-size: 2rem; font-weight: 700 !important; color: #21272B !important;">
Features</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 30px !important; margin-left: 0 !important; margin-bottom: 2rem !important;"/>
<div class="row">
<div class="col-sm-12 col-md-6">
<div class="d-flex my-5"
style="padding-bottom: 1.3rem !important; border-bottom: 2px solid #f0f0f0;">
<img src="assets/icons/check.png" width="24px"
height="24px" class="mr-2">
<h3 style="font-size: 1.2rem !important;">Create Return
Orders From Website</h3>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 12px;">Customers can create return order from Portal/My Account and cangenerate return
order in backend by clicking the "Return" button to return item from the current order</span>
</div>
<div class="d-flex my-5"
style="padding-bottom: 1.3rem !important; border-bottom: 2px solid #f0f0f0;">
<img src="assets/icons/check.png" width="24px"
height="24px" class="mr-2">
<h3 style="font-size: 1.2rem !important;">Portal Return
Order View</h3>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 14px;">Customers can view the list of their return orders from My Account.</span>
</div>
<div class="d-flex my-5"
style="padding-bottom: 1.3rem !important; border-bottom: 2px solid #f0f0f0;">
<img src="assets/icons/check.png" width="24px"
height="24px" class="mr-2">
<h3 style="font-size: 1.2rem !important;">Link Return
With Sale Order</h3>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 14px;">Easily switch the return orders from sale order by clicking the
return smart button in the sale order.</span>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="d-flex my-5"
style="padding-bottom: 1.3rem !important; border-bottom: 2px solid #f0f0f0;">
<img src="assets/icons/check.png" width="24px"
height="24px" class="mr-2">
<h3 style="font-size: 1.2rem !important;">Link Return
Order With Partner
</h3>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 14px;">We can see the list of return related to a partner from the
partner form view and easily switch to return order by clicking Return Count smart
button.</span>
</div>
<div class="d-flex my-5"
style="padding-bottom: 1.3rem !important; border-bottom: 2px solid #f0f0f0;">
<img src="assets/icons/check.png" width="24px"
height="24px" class="mr-2">
<h3 style="font-size: 1.2rem !important;">Return Order
print</h3>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 14px;">Allows to take PDF print of the return order.</span>
</div>
</div>
</div>
</div>
</div>
<div class="row " id="screenshots">
<div class="col-sm-12 col-md-12 col-lg-12 px-4">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-size: 2rem; font-weight: 700 !important; color: #21272B !important;">
Screenshots</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 30px !important; margin-left: 0 !important; margin-bottom: 2rem !important;"/>
<div class="mt-5">
<div class="d-flex mb-2"
style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px"
height="20px" class="mr-2"
style="margin-top: 4px !important;">
<h3>Return Button on
Order Page on Portal</h3>
</div>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Goto Portal/ My Account -> Sale order , from the sale order
click Return button.
</p>
<img src="assets/screenshots/scrshot_1.png"
class="img-responsive img-thumbnail border">
</div>
<div class="mt-5">
<div class="d-flex mb-2"
style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px"
height="20px" class="mr-2"
style="margin-top: 4px !important;">
<h3>Return Product Screen</h3>
</div>
<p>
From the product screen you can select the product ,
quantity and return reason, after
that you can submit the return using Submit button.
</p>
<img src="assets/screenshots/scrshot_2.png"
class="img-responsive img-thumbnail border">
</div>
<div class="mt-5">
<div class="d-flex mb-2"
style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px"
height="20px" class="mr-2"
style="margin-top: 4px !important;">
<h3>Return Orders in
Portal for View</h3>
</div>
<p>
Customer can see list of RMA orders in Portal / My Account.
</p>
<img src="assets/screenshots/scrshot_3.png"
class="img-responsive img-thumbnail border">
</div>
<div class="mt-5">
<div class="d-flex mb-2"
style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px"
height="20px" class="mr-2"
style="margin-top: 4px !important;">
<h3>Return Orders tree
view in Portal.</h3>
</div>
<p>
The customer can see the basic details and status of the
return order.
</p>
<img src="assets/screenshots/scrshot_4.png"
class="img-responsive img-thumbnail border">
</div>
<div class="mt-5">
<div class="d-flex mb-2"
style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px"
height="20px" class="mr-2"
style="margin-top: 4px !important;">
<h3>Return Orders
detailed view in Portal.</h3>
</div>
<p>
The customer can see the detailed information of the return
order in portal.
</p>
<img src="assets/screenshots/scrshot_5.png"
class="img-responsive img-thumbnail border">
</div>
<div class="mt-5">
<div class="d-flex mb-2"
style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px"
height="20px" class="mr-2"
style="margin-top: 4px !important;">
<h3>RMA Return Orders -
Backend</h3>
</div>
<p>
Return order tree view, Goto Sales -> Return Orders
</p>
<img src="assets/screenshots/scrshot_6.png"
class="img-responsive img-thumbnail border">
</div>
<div class="mt-5">
<div class="d-flex mb-2"
style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px"
height="20px" class="mr-2"
style="margin-top: 4px !important;">
<h3>Return Orders form
view in backend.</h3>
</div>
<p>
Backend form view of return order.
</p>
<img src="assets/screenshots/scrshot_7.png"
class="img-responsive img-thumbnail border">
</div>
<div class="mt-5">
<div class="d-flex mb-2"
style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px"
height="20px" class="mr-2"
style="margin-top: 4px !important;">
<h3>Delivery Order Tab
and Smart button</h3>
</div>
<p>
Shows all the delivery order's related with Sales order.
</p>
<img src="assets/screenshots/scrshot_8.png"
class="img-responsive img-thumbnail border">
</div>
<div class="mt-5">
<div class="d-flex mb-2"
style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px"
height="20px" class="mr-2"
style="margin-top: 4px !important;">
<h3>Return Process on DO
picking.</h3>
</div>
<p>
Return picking creation from return order using confirm
button.
</p>
<img src="assets/screenshots/scrshot_7.png"
class="img-responsive img-thumbnail border">
</div>
</div>
</div>
<div class="mt-5">
<div class="d-flex mb-2" style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px" height="20px"
class="mr-2"
style="margin-top: 4px !important;">
<h3>Delivery Order Return
Button.</h3>
</div>
<p>
Return picking creation from return button in delivery (Odoo
Standard process).
</p>
<img src="assets/screenshots/scrshot_9.png"
class="img-responsive img-thumbnail border">
</div>
</div>
</div>
<div class="mt-5">
<div class="d-flex mb-2" style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px" height="20px"
class="mr-2"
style="margin-top: 4px !important;">
<h3>Delivery Order Return
Wizard(Odoo Standard).</h3>
</div>
<p>
Odoo default wizard for product return.
</p>
<img src="assets/screenshots/scrshot_10.png"
class="img-responsive img-thumbnail border">
</div>
</div>
</div>
<div class="mt-5">
<div class="d-flex mb-2" style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px" height="20px"
class="mr-2"
style="margin-top: 4px !important;">
<h3>Return Picking Order
Tab and Smart button)</h3>
</div>
<p>
Shows all the return picking order's related with Return Order.
</p>
<img src="assets/screenshots/scrshot_11.png"
class="img-responsive img-thumbnail border">
</div>
</div>
</div>
<div class="mt-5">
<div class="d-flex mb-2" style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px" height="20px"
class="mr-2"
style="margin-top: 4px !important;">
<h3>Smart Button on
Customer Form</h3>
</div>
<p>
On customer form smart button showing all return order related to that
customer.
</p>
<img src="assets/screenshots/scrshot_12.png"
class="img-responsive img-thumbnail border">
</div>
</div>
</div>
<div class="mt-5">
<div class="d-flex mb-2" style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px" height="20px"
class="mr-2"
style="margin-top: 4px !important;">
<h3>Smart Button on Sale
Order Form</h3>
</div>
<p>
On Sale Order form smart button showing all return order related to that
sale order.
</p>
<img src="assets/screenshots/scrshot_13.png"
class="img-responsive img-thumbnail border">
</div>
</div>
</div>
<div class="mt-5">
<div class="d-flex mb-2" style="padding-bottom: 0.5rem !important;">
<img src="assets/icons/chevron.png" width="20px" height="20px"
class="mr-2"
style="margin-top: 4px !important;">
<h3>Return Orders -
Report Sample</h3>
</div>
<p>
Print RMA PDF Report - Print Return Report.
</p>
<img src="assets/screenshots/scrshot_14.png"
class="img-responsive img-thumbnail border">
</div>
</div>
</div>
<!-- SUGGESTED PRODUCTS -->
<div class="row mt-3">
<div class="col-lg-12 d-flex flex-column justify-content-center"
style="padding: 2.5rem 1rem !important;">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-size: 2rem; font-weight: 700 !important; color: #21272B !important;">
Suggested Products</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 30px !important; margin-left: 0 !important; margin-bottom: 2rem !important;"/>
<div id="demo1" class="row carousel slide mt-4 data-ride=" carousel="">
<!-- The slideshow -->
<div class="carousel-inner">
<div class="carousel-item active" style="min-height:0px">
<div class="carousel-item active" style="min-height:0px">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/export_stockinfo_xls/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/export_image.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/custom_gantt_view/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/gantt_image.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/sales_credit_limit/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/credit_image.png">
</div>
</a>
</div>
</div>
<div class="carousel-item" style="min-height:0px">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/base_account_budget/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/budget_image.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/product_to_quotation/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/quotation_image.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/employee_documents_expiry/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/employee_image.png">
</div>
</a>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#demo1" data-slide="prev"
style="left:-25px;width: 35px;color: #000;"> <span
class="carousel-control-prev-icon"><i
class="fa fa-chevron-left"
style="font-size:24px"></i></span> </a> <a
class="carousel-control-next" href="#demo1" data-slide="next"
style="right:-25px;width: 35px;color: #000;">
<span class="carousel-control-next-icon"><i
class="fa fa-chevron-right"
style="font-size:24px"></i></span>
</a>
</div>
</div>
</div>
<!-- END OF SUGGESTED PRODUCTS -->
<!-- OUR SERVICES -->
<section class="container" style="margin-top: 6rem !important;">
<div class="row">
<div class="col-lg-12">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-size: 2rem; font-weight: 700 !important; color: #21272B !important;">
Our Services</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 30px !important; margin-left: 0 !important; margin-bottom: 2rem !important;"/>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/cogs.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Customization</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/wrench.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/lifebuoy.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Support</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/user.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Hire
Odoo
Developer</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/puzzle.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Integration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/update.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Migration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/consultation.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Consultancy</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/training.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/license.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Licensing Consultancy</h6>
</div>
</div>
</section>
<!-- END OF END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<section class="container" style="margin-top: 6rem !important;">
<div class="row">
<div class="col-lg-12">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-size: 2rem; font-weight: 700 !important; color: #21272B !important;">
Our Industries</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 30px !important; margin-left: 0 !important; margin-bottom: 2rem !important;"/>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/trading-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Trading
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easily procure
and
sell your products</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/pos-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
POS
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easy
configuration
and convivial experience</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/education-black.png"
class="img-responsive mb-3" height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Education
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
A platform for
educational management</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/manufacturing-black.png"
class="img-responsive mb-3" height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Manufacturing
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Plan, track and
schedule your operations</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/ecom-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
E-commerce &amp; Website
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Mobile
friendly,
awe-inspiring product pages</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/service-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Service Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Keep track of
services and invoice</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/restaurant-black.png"
class="img-responsive mb-3" height="48px"
width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Restaurant
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Run your bar or
restaurant methodically</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/hotel-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Hotel Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
An
all-inclusive
hotel management application</p>
</div>
</div>
</div>
</section>
<!-- END OF END OF OUR INDUSTRIES -->
<!-- FOOTER -->
<!-- Footer Section -->
<section class="container" style="margin: 5rem auto 2rem;">
<div class="row" style="max-width:1540px;">
<div class="col-lg-12">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-size: 2rem; font-weight: 700 !important; color: #21272B !important;">
Need Help?</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 30px !important; margin-left: 0 !important; margin-bottom: 2rem !important;"/>
</div>
</div>
<!-- Contact Cards -->
<div class="row d-flex justify-content-center align-items-center"
style="max-width:1540px; margin: 0 auto 2rem auto;">
<div class="col-lg-12"
style="padding: 0rem 3rem 2rem; border-radius: 10px; margin-right: 3rem; ">
<div class="row mt-4">
<div class="col-lg-6">
<a href="mailto:odoo@cybrosys.com" target="_blank"
class="btn btn-block mb-2 deep_hover"
style="text-decoration: none; background-color: #4d4d4d; color: #FFF; border-radius: 4px;"><i
class="fa fa-envelope mr-2"></i>odoo@cybrosys.com</a>
</div>
<div class="col-lg-6">
<a href="https://api.whatsapp.com/send?phone=918606827707"
target="_blank"
class="btn btn-block mb-2 deep_hover"
style="text-decoration: none; background-color: #25D366; color: #FFF; border-radius: 4px;"><i
class="fa fa-whatsapp mr-2"></i>+91 86068 27707</a>
</div>
</div>
</div>
</div>
<!-- End of Contact Cards -->
</section>
<!-- Footer -->
<section class="oe_container" style="padding: 2rem 3rem 1rem;">
<div class="row"
style="max-width:1540px; margin: 0 auto; margin-right: 3rem; ">
<!-- Logo -->
<div class="col-lg-12 d-flex justify-content-center align-items-center"
style="margin-top: 3rem;">
<img src="https://www.cybrosys.com/images/logo.png" width="200px"
height="auto"/>
</div>
<!-- End of Logo -->
<div class="col-lg-12">
<hr
style="margin-top: 3rem;background: linear-gradient(90deg, rgba(2,0,36,0) 0%, rgba(229,229,229,1) 33%, rgba(229,229,229,1) 58%, rgba(0,212,255,0) 100%); height: 2px; border-style: none;">
<!-- End of Footer Section -->
</div>
</div>
</section>
<!-- END OF FOOTER -->
</div>

88
website_return_management/static/src/js/sale_return.js

@ -0,0 +1,88 @@
odoo.define('website_return_management.return', function(require) {
"use strict";
var publicWidget = require('web.public.widget');
var ajax = require('web.ajax');
var rpc = require('web.rpc');
var core = require('web.core');
var QWeb = core.qweb;
/**
new component to publicWidget
*/
publicWidget.registry.returnOrderModal = publicWidget.Widget.extend({
selector: 'div[id="sale_return_modal"]',
events: {
'click #hidden_box_btn': '_onShowButtonClick',
'change #product': '_onShowFormSubmit',
'click #submit': '_onClickFormSubmit',
'change #qty': '_onChangeQuantity',
},
_onShowButtonClick: function() {
/**
on-click function to show the modal
*/
$('#hidden_box').modal('show');
},
_onShowFormSubmit: function() {
/**
on-click function to show the submit button
*/
var x = $('#submit');
x.addClass('d-none');
if ($("#product").val() == 'none') {
if (!x.hasClass('d-none')) {
x.addClass('d-none');
}
} else {
if (x.hasClass('d-none')) {
x.removeClass('d-none');
}
}
},
_onChangeQuantity: function() {
/**
on-change function to check the quantity
*/
if (!$("#warning_message").hasClass('d-none')) {
$('#warning_message').addClass('d-none');
$('#submit').prop('disabled', false);
}
else if (!$("#product_null_warning").hasClass('d-none')){
$('#product_null_warning').addClass('d-none');
$('#submit').prop('disabled', false);
}
},
_onClickFormSubmit: function(ev) {
/**
on-click function to show the submit button
*/
ev.preventDefault();
var current_order = $('#order_id').val()
var return_qty = $('#qty').val()
var product = $('#product').val()
var reason = $('#return_reason').val()
ajax.jsonRpc('/order_quantity', 'call', {
'current_order': current_order, 'return_qty': return_qty,
'product_id': product})
.then(function(data) {
if (data < return_qty) {
$('#warning_message').removeClass('d-none');
}
else if (return_qty <= 0){
$('#product_null_warning').removeClass('d-none');
$('#submit').prop('disabled', true);
}
else {
// Submit the form if the condition is met
ajax.jsonRpc('/sale_return', 'call', {
'order_id': current_order, 'qty': return_qty,
'product': product, 'reason': reason}).then(function(result) {
window.location.href = '/my/request-thank-you';
})
}
});
},
})
})

377
website_return_management/views/portal_templates.xml

@ -0,0 +1,377 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Portal template -->
<template id="sale_order_portal_content_return"
name="Sales Order Portal Content"
inherit_id="sale.sale_order_portal_content">
<xpath expr="//div[@id='introduction']/h2" position="replace">
<div id="sale_return_modal">
<form>
<span id="hidden_box" class="modal fade">
<div class="modal-dialog modal-content"
style="border:solid 1px #604e5b; min-height:px;max-width:500px;max-height: 685px;">
<div class="modal-body" id="pop_html">
<a href="#"
class="o_popup_btn_close o_not_editable pull-right"
data-dismiss="modal" style="font-size:20px">x
</a>
<br/>
<h2 style="text-align:center; font-size 24px; font-weight:bold"
class="o_default_snippet_text">Sale Return
</h2>
<form>
<div class="form-group row form-field o_website_form_custom o_website_form_required_custom">
<div class="col-6 d-block font-weight-bold">
Customer Name
</div>
<div class="col-6 d-block font-weight-bold">
Sale Order
</div>
</div>
<div class="row form-group">
<div class="col-6 align-middle">
<input type="text" readonly="1"
t-att-value="sale_order.partner_id.name"
name="partner"
class="form-control o_website_form_custom"
style="color: #606060;box-shadow: none;padding-left: 0;font-size: 18px;border: 1px solid #aaa;box-sizing: border-box; text-align: center;"/>
</div>
<div class="col-6 align-middle">
<input type="text"
style="color: #606060;box-shadow: none;padding-left: 0;font-size: 18px;border: 1px solid #aaa;box-sizing: border-box;text-align: center;"
t-att-value="sale_order.name"
name="order" readonly="1"
class="form-control o_website_form_custom"/>
<input type="text"
style="color: #606060;box-shadow: none;padding-left: 0;font-size: 18px;border: 1px solid #aaa;box-sizing: border-box;text-align: center;"
t-att-value="sale_order.id"
name="order_id"
id="order_id"
class="form-control o_website_form_custom d-none"/>
</div>
</div>
<div class="row">
<br/>
</div>
<div class="form-group row ">
<div class="col-6 d-block font-weight-bold">
Select Product
</div>
<div class="col-6 d-block font-weight-bold">
Quantity
</div>
</div>
<div class="form-group row">
<div class="col-6 align-middle">
<select class="form-control product"
id="product" name="product"
default="None"
style="color: #606060;box-shadow: none;padding-left: 0;font-size: 18px;border: 1px solid #aaa;box-sizing: border-box;text-align: center;">
<option value="none">None</option>
<t t-foreach="sale_order.order_line.filtered(lambda line: not line.return_qty).mapped('product_id')"
t-as="product">
<option t-att-value='product.id'>
<t t-esc="product.name"/>
</option>
</t>
</select>
</div>
<div class="col-6 align-middle">
<input type="text"
style="color: #606060;box-shadow: none;padding-left: 0;font-size: 18px;border: 1px solid #aaa;box-sizing: border-box; text-align: center;"
value="0"
name="qty"
id="qty"
class="form-control"/>
</div>
</div>
<div class="form-group row">
<div class="col-12 d-block font-weight-bold">
Reason
</div>
<div class="col-12">
<textarea rows="10" cols="45"
id="return_reason"
name="reason"
placeholder="Explain your Reason"/>
</div>
</div>
<div class="form-group row">
<div class="col-12">
<div id="warning_message" class="alert alert-danger d-none" role="alert"
style="width: 300px; height: 70px;">
Return quantity exceeds the delivered quantity.
</div>
<div id="product_null_warning" class="alert alert-danger d-none" role="alert"
style="width: 300px; height: 70px;">
Add a quantity to return.
</div>
<button id='submit'
class="btn btn-secondary flex-grow-1 mb-1 d-none">
Submit
</button>
<span id="o_website_form_result"/>
</div>
</div>
</form>
</div>
</div>
</span>
<div class="row">
<div class="col-6">
<h2 class="my-0">
<t t-esc="sale_order.type_name"/>
<em t-esc="sale_order.name"/>
</h2>
</div>
<div class="col-6">
<span class="btn-group flex-grow-1 mb-1 float-left"
style="padding-left: 18rem !important;">
<t t-if="sale_order.state in ['sale','done'] and sum(sale_order.order_line.mapped('qty_delivered')) > 0">
<a class="btn btn-secondary btn-block"
style="color: #FFFFFF;"
id="hidden_box_btn"><i
class="fa fa-truck"/> Return
</a>
</t>
</span>
</div>
</div>
</form>
</div>
</xpath>
</template>
<!-- Returns order breadcrumbs-->
<template id="portal_my_home_menu_sale_return"
name="Portal layout : Return Order menu entry"
inherit_id="portal.portal_breadcrumbs" priority="10">
<xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside">
<li t-if="page_name == 'Sale_Return' or sale_return"
t-attf-class="breadcrumb-item #{'active ' if not orders else ''}">
<a t-if="orders"
t-attf-href="/my/return_orders?{{ keep_query() }}">Return
orders
</a>
<t t-else="">Return Order</t>
</li>
</xpath>
</template>
<!-- Returns orders -->
<template id="portal_my_home_sale_return" name="Show Return Order"
customize_show="True"
inherit_id="portal.portal_my_home" priority="25">
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
<t t-call="portal.portal_docs_entry">
<t t-set="title">Return Orders</t>
<t t-set="url" t-value="'/my/return_orders'"/>
<t t-set="placeholder_count" t-value="'return_count'"/>
</t>
</xpath>
</template>
<!-- User returns in portal -->
<template id="portal_my_returns" name="Portal: My Sale Return">
<t t-call="portal.portal_layout">
<t t-set="breadcrumbs_searchbar" t-value="True"/>
<t t-call="portal.portal_searchbar">
<t t-set="title">Sale Returns</t>
</t>
<t t-if="not orders">
<p>There are currently no return order for your account.</p>
</t>
<t t-if="orders" t-call="portal.portal_table">
<thead>
<tr class="active">
<th>Sale Return #</th>
<th class="text-right">Create Date</th>
<th class="text-right">Order</th>
<th class="text-right">State</th>
</tr>
</thead>
<tbody>
<t t-foreach="orders" t-as="order">
<tr>
<td>
<a t-att-href="order.get_portal_url()">
<t t-esc="order.name"/>
</a>
</td>
<td class="text-right">
<span t-field="order.create_date"/>
</td>
<td class="text-right">
<span t-field="order.sale_order_id"/>
</td>
<td class="text-right">
<t t-if="order.state == 'draft'">
<span class="badge badge-warning"><i
class="fa fa-fw fa-file-text"/>Draft
</span>
</t>
<t t-if="order.state == 'done'">
<span class="badge badge-success "><i
class="fa fa-fw fa-file-text"/>Done
</span>
</t>
<t t-if="order.state == 'confirm'">
<span class="badge badge-info">
<i
class="fa fa-fw fa-file-text"/>
Confirmed
</span>
</t>
<t t-if="order.state == 'cancel'">
<span class="badge badge-dark">
<i class="fa fa-fw fa-remove"/>
Cancelled
</span>
</t>
</td>
</tr>
</t>
</tbody>
</t>
</t>
</template>
<!-- Adding sale return options in portal-->
<template id="portal_sale_return_page" name="Portal: My Sale Return">
<t t-call="portal.portal_layout">
<t t-set="sale_return" t-value="orders"/>
<div id="optional_placeholder"/>
<div class="container">
<div class="row mt16 o_portal_purchase_sidebar">
<!-- Sidebar -->
<t t-call="portal.portal_record_sidebar">
<t t-set="classes"
t-value="'col-lg-auto d-print-none'"/>
<t t-set="title">
<h2 class="mb-0">
<b t-field="sale_return.name"
data-id="return_name"/>
</h2>
</t>
<t t-set="entries">
<ul class="list-group list-group-flush flex-wrap flex-row flex-lg-column">
<li class="list-group-item flex-grow-1">
<div class="o_download_pdf btn-toolbar flex-sm-nowrap">
<div class="btn-group flex-grow-1 mr-1 mb-1">
<a class="btn btn-secondary btn-block o_download_btn"
t-att-href="sale_return.get_portal_url(report_type='pdf', download=True)"
title="Download">
<i class="fa fa-download"/>
Download
</a>
</div>
<div class="btn-group flex-grow-1 mb-1">
<a class="btn btn-secondary btn-block o_print_btn o_portal_invoice_print"
t-att-href="sale_return.get_portal_url(report_type='pdf')"
id="print_invoice_report"
title="Print" target="_blank">
<i class="fa fa-print"/>
Print
</a>
</div>
</div>
</li>
<li t-if="sale_return.user_id"
class="list-group-item flex-grow-1">
<div class="small mb-1">
<strong class="text-muted">
Representative
</strong>
</div>
<div class="row flex-nowrap">
<div class="col flex-grow-0 pr-2">
<img class="rounded-circle mr4 float-left o_portal_contact_img"
t-if="sale_return.user_id.image_1024"
t-att-src="image_data_uri(sale_return.user_id.image_1024)"
alt="Contact"/>
<img class="rounded-circle mr4 float-left o_portal_contact_img"
t-if="not sale_return.user_id.image_1024"
src="/web/static/src/img/placeholder.png"
alt="Contact"/>
</div>
<div class="col pl-0"
style="min-width: 150px">
<span t-field="sale_return.user_id"
t-options='{"widget": "contact", "fields": ["name", "phone"], "no_marker": True}'/>
<a href="#discussion" class="small">
<i class="fa fa-comment"/>
Send
message
</a>
</div>
</div>
</li>
</ul>
</t>
</t>
<div class=" col-lg col-12 justify-content-end w-100">
<div class="card pb-5">
<div class="card-header bg-white pb-1">
<div class="row">
<div class="col-lg-12">
<h2 class="font-weight-normal">
<t t-if="orders.state in ['draft']">
Draft Return
</t>
<t t-else="1">
Sale Return
</t>
<span class="font-italic"
t-esc="orders.name"/>
</h2>
</div>
</div>
</div>
<div class="card-body">
<div class="mb-4">
<strong>Creation Date:</strong>
<span t-field="orders.create_date"
t-options='{"widget": "date"}'/>
<br/>
<div t-att-class="'d-inline' if orders.sale_order_id else 'd-none'">
<strong>Sale Order:</strong>
<span class="ml-1"
t-field="orders.sale_order_id"/>
</div>
</div>
<h3 class="font-weight-normal">Returns</h3>
<table class="table table-sm">
<thead class="bg-100">
<tr>
<th>Products</th>
<th class="text-right">Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<img t-att-src="image_data_uri(orders.product_id.image_1024)"
alt="Product"
class="d-none d-lg-inline"
width="48" height="48"/>
<span t-esc="orders.name"/>
</td>
<td class="text-right">
<span t-esc="orders.quantity"/>
</td>
</tr>
</tbody>
</table>
<div class="row"/>
<div class="row">
<div class="col-lg-12">
<h5 class="font-weight-normal">Reason
</h5>
<p t-esc="orders.reason"/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="oe_structure mb32"/>
</t>
</template>
</odoo>

19
website_return_management/views/res_partner_views.xml

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Inherit res_partner-->
<record id="view_partner_form" model="ir.ui.view">
<field name="name">res.partner.view.form.inherit.sale.return</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field eval="1" name="priority"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='button_box']" position="inside">
<button name="action_open_returns" type="object"
class="oe_stat_button" icon="fa-truck"
attrs="{'invisible': [('return_order_count','=', 0)]}">
<field name="return_order_count" widget="statinfo"/>
</button>
</xpath>
</field>
</record>
</odoo>

21
website_return_management/views/sale_order_views.xml

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Sale order inherit to add a new button -->
<record id="view_order_form" model="ir.ui.view">
<field name="name">sale.order.view.form.inherit.sales.return</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='button_box']" position="inside">
<button name="action_open_returns" type="object"
class="oe_stat_button" icon="fa-truck"
attrs="{'invisible': [('return_order_count','=', 0)]}">
<field name="return_order_count" widget="statinfo"/>
</button>
</xpath>
<xpath expr="//notebook/page[@name='order_lines']/field/tree/field[@name='qty_delivered']" position="after">
<field name="return_qty" attrs="{'column_invisible': [('parent.state', 'not in', ('sale', 'done'))]}"/>
</xpath>
</field>
</record>
</odoo>

118
website_return_management/views/sale_return_views.xml

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Sale return form view-->
<record id="sale_return_view_form" model="ir.ui.view">
<field name="name">Sale Return</field>
<field name="model">sale.return</field>
<field name="priority">100</field>
<field name="arch" type="xml">
<form>
<header>
<button name="return_confirm" string="Confirm" class="oe_highlight"
type="object" states="draft"/>
<button name="return_cancel" string="Cancel" type="object" states="draft,confirm"/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,done"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="action_view_picking" type="object" class="oe_stat_button"
icon="fa-pencil-square-o" attrs="{'invisible': [('picking_count', '=', 0)]}">
<field name="picking_count" widget="statinfo" string="Return Picking"/>
</button>
<button name="action_view_delivery" type="object" class="oe_stat_button"
icon="fa-pencil-square-o" attrs="{'invisible': [('delivery_count', '=', 0)]}">
<field name="delivery_count" widget="statinfo" string="Delivery order"/>
</button>
</div>
<div class="oe_title">
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="sale_order_id"/>
<field name="partner_id"/>
<field name="create_date"/>
<field name="user_id"/>
</group>
<group>
<field name="product_id"/>
<field name="received_qty" readonly="1" force_save="1"/>
<field name="quantity"/>
<field name="to_refund"/>
<field name="stock_picking_ids" invisible="1"/>
</group>
</group>
<notebook>
<page string="Reason" name="reason">
<field name="reason"/>
</page>
<page string="Delivery Order" name="delivery_order">
<field name="source_pick_ids"/>
</page>
<page string="Return Picking" name="return_picking">
<field name="stock_picking_ids"/>
</page>
<page string="Other" name="other_info">
<separator colspan="4" string="Other Datails"/>
<field name="note" colspan="4" nolabel="1"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!-- Sale return tree view -->
<record model="ir.ui.view" id="sale_return_tree_view">
<field name="name">Sale Return</field>
<field name="model">sale.return</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="sale_order_id"/>
<field name="partner_id"/>
<field name="create_date"/>
<field name="user_id"/>
<field name="state"/>
<field name="product_id" optional="hide"/>
</tree>
</field>
</record>
<!-- Sale return search-->
<record id="sale_return_view_search" model="ir.ui.view">
<field name="name">sale.return.search</field>
<field name="model">sale.return</field>
<field name="arch" type="xml">
<search>
<field name="sale_order_id" string="Sale order"/>
<field name="partner_id" string="Customer"/>
<field name="product_id" string="Product"/>
<filter string="Done" name="done" domain="[('state', '=', 'done')]" help="Done order"/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<separator/>
<group expand="0" string="Group By">
<filter string="Status" name="status" domain="[]" context="{'group_by':'state'}"/>
<filter string="Sale Order" name="order" context="{'group_by':'sale_order_id'}"/>
<filter string="Customer" name="customer" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Product" name="product" domain="[]" context="{'group_by':'product_id'}"/>
</group>
</search>
</field>
</record>
<!-- Sale return action-->
<record id="sale_return_action" model="ir.actions.act_window">
<field name="name">Sale Return</field>
<field name="res_model">sale.return</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">Create The First Return
</p>
</field>
</record>
<!-- Sale return menu-->
<menuitem id="sale_return_menu"
parent="sale.sale_menu_root"
name="Return Orders"
action="website_return_management.sale_return_action"/>
</odoo>

16
website_return_management/views/stock_picking_views.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Inheriting model stock_picking form view to add new fields-->
<record id="view_picking_form" model="ir.ui.view">
<field name="name">stock.picking.view.form.inherit.website.return</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<field name="origin" position="after">
<field name="return_order_id" attrs="{'invisible': [('return_order_id','=', False)]}"/>
<field name="return_order_pick_id" attrs="{'invisible': [('return_order_pick_id','=', False)]}"/>
<field name="return_order_picking" invisible="1"/>
</field>
</field>
</record>
</odoo>

36
website_return_management/views/website_thankyou_templates.xml

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Acknowledgement template-->
<template id="customers_request_thank_page" name="Customer Request Thank">
<t t-call="website.layout">
<div class="oe_structure">
<div class="contain">
<div id="wrap">
<div class="oe_structure"
id="oe_structure_website_form_contact_us_thanks_1"/>
<div class="container pt-3">
<h1>Thanks!</h1>
<div class="row">
<div class="col-lg-8">
<div class="alert alert-success"
role="status">
Your order for return has been sent
successfully.
<button type="button" class="close"
data-dismiss="alert">&amp;times;
</button>
</div>
<p>
We will get back to you shortly.
</p>
</div>
</div>
</div>
<div class="oe_structure"
id="oe_structure_website_form_contact_us_thanks_2"/>
</div>
</div>
</div>
</t>
</template>
</odoo>

22
website_return_management/wizard/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from . import stock_return_picking

40
website_return_management/wizard/stock_return_picking.py

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from odoo import models
class StockReturnPicking(models.TransientModel):
"""Transient model to create return order"""
_inherit = 'stock.return.picking'
def _create_returns(self):
"""Supering create_returns function"""
new_picking, pick_type_id = (
super(StockReturnPicking, self)._create_returns())
picking = self.env['stock.picking'].browse(new_picking)
if self.picking_id.return_order_id:
picking.write({'return_order_picking': False,
'return_order_id': False,
'return_order_pick_id':
self.picking_id.return_order_id.id})
self.picking_id.return_order_id.write({'state': 'confirm'})
return new_picking, pick_type_id
Loading…
Cancel
Save