Browse Source

[ADD] Initial Commit

pull/200/head
Ajmal Cybro 3 years ago
parent
commit
e63c4e053a
  1. 26
      website_multi_product_return_management/__init__.py
  2. 50
      website_multi_product_return_management/__manifest__.py
  3. 25
      website_multi_product_return_management/controllers/__init__.py
  4. 70
      website_multi_product_return_management/controllers/main.py
  5. 139
      website_multi_product_return_management/controllers/portal.py
  6. 14
      website_multi_product_return_management/data/ir_sequence.xml
  7. 8
      website_multi_product_return_management/doc/RELEASE_NOTES.md
  8. 28
      website_multi_product_return_management/models/__init__.py
  9. 62
      website_multi_product_return_management/models/res_partner.py
  10. 54
      website_multi_product_return_management/models/sale_order.py
  11. 240
      website_multi_product_return_management/models/sale_return.py
  12. 60
      website_multi_product_return_management/models/stock_picking.py
  13. 78
      website_multi_product_return_management/report/report.xml
  14. 3
      website_multi_product_return_management/security/ir.model.access.csv
  15. BIN
      website_multi_product_return_management/static/description/assets/icons/chevron.png
  16. BIN
      website_multi_product_return_management/static/description/assets/icons/cogs.png
  17. BIN
      website_multi_product_return_management/static/description/assets/icons/consultation.png
  18. BIN
      website_multi_product_return_management/static/description/assets/icons/ecom-black.png
  19. BIN
      website_multi_product_return_management/static/description/assets/icons/education-black.png
  20. BIN
      website_multi_product_return_management/static/description/assets/icons/hotel-black.png
  21. BIN
      website_multi_product_return_management/static/description/assets/icons/license.png
  22. BIN
      website_multi_product_return_management/static/description/assets/icons/lifebuoy.png
  23. BIN
      website_multi_product_return_management/static/description/assets/icons/manufacturing-black.png
  24. BIN
      website_multi_product_return_management/static/description/assets/icons/pos-black.png
  25. BIN
      website_multi_product_return_management/static/description/assets/icons/puzzle.png
  26. BIN
      website_multi_product_return_management/static/description/assets/icons/restaurant-black.png
  27. BIN
      website_multi_product_return_management/static/description/assets/icons/service-black.png
  28. BIN
      website_multi_product_return_management/static/description/assets/icons/trading-black.png
  29. BIN
      website_multi_product_return_management/static/description/assets/icons/training.png
  30. BIN
      website_multi_product_return_management/static/description/assets/icons/update.png
  31. BIN
      website_multi_product_return_management/static/description/assets/icons/user.png
  32. BIN
      website_multi_product_return_management/static/description/assets/icons/wrench.png
  33. BIN
      website_multi_product_return_management/static/description/banner.png
  34. BIN
      website_multi_product_return_management/static/description/icon.png
  35. BIN
      website_multi_product_return_management/static/description/images/checked.png
  36. BIN
      website_multi_product_return_management/static/description/images/hero.png
  37. BIN
      website_multi_product_return_management/static/description/images/link.png
  38. BIN
      website_multi_product_return_management/static/description/images/list.png
  39. BIN
      website_multi_product_return_management/static/description/images/logo.png
  40. BIN
      website_multi_product_return_management/static/description/images/modules/approval_image.png
  41. BIN
      website_multi_product_return_management/static/description/images/modules/dynamic_image.png
  42. BIN
      website_multi_product_return_management/static/description/images/modules/mulitple-ref_image.png
  43. BIN
      website_multi_product_return_management/static/description/images/modules/pos_image.png
  44. BIN
      website_multi_product_return_management/static/description/images/modules/shopify_image.png
  45. BIN
      website_multi_product_return_management/static/description/images/my leave analysis.png
  46. BIN
      website_multi_product_return_management/static/description/images/partner.png
  47. BIN
      website_multi_product_return_management/static/description/images/printer.png
  48. BIN
      website_multi_product_return_management/static/description/images/return.png
  49. BIN
      website_multi_product_return_management/static/description/images/screenshot-1.png
  50. BIN
      website_multi_product_return_management/static/description/images/screenshot-10.png
  51. BIN
      website_multi_product_return_management/static/description/images/screenshot-11.png
  52. BIN
      website_multi_product_return_management/static/description/images/screenshot-12.png
  53. BIN
      website_multi_product_return_management/static/description/images/screenshot-13.png
  54. BIN
      website_multi_product_return_management/static/description/images/screenshot-14.png
  55. BIN
      website_multi_product_return_management/static/description/images/screenshot-15.png
  56. BIN
      website_multi_product_return_management/static/description/images/screenshot-2.png
  57. BIN
      website_multi_product_return_management/static/description/images/screenshot-3.png
  58. BIN
      website_multi_product_return_management/static/description/images/screenshot-4.png
  59. BIN
      website_multi_product_return_management/static/description/images/screenshot-5.png
  60. BIN
      website_multi_product_return_management/static/description/images/screenshot-6.png
  61. BIN
      website_multi_product_return_management/static/description/images/screenshot-7.png
  62. BIN
      website_multi_product_return_management/static/description/images/screenshot-8.png
  63. BIN
      website_multi_product_return_management/static/description/images/screenshot-9.png
  64. 804
      website_multi_product_return_management/static/description/index.html
  65. 61
      website_multi_product_return_management/static/src/js/sale_return.js
  66. 18
      website_multi_product_return_management/views/res_partner.xml
  67. 349
      website_multi_product_return_management/views/sale_order.xml
  68. 124
      website_multi_product_return_management/views/sale_return.xml
  69. 15
      website_multi_product_return_management/views/stock_picking.xml
  70. 32
      website_multi_product_return_management/views/website_thankyou_template.xml

26
website_multi_product_return_management/__init__.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Shijin V (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from . import controllers
from . import models

50
website_multi_product_return_management/__manifest__.py

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Shijin V (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
{
'name': 'Multi Product Return From Website',
'summary': 'Sale Order Multi product Return Management from Website',
'version': '14.0.1.0.0',
'description': """Website Multi product Return Order Management, Website Return, Order Return, RMA, Website RMA""",
'author': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'category': 'Website',
'depends': ['website_sale', 'stock', 'sale_management'],
'data': [
'security/ir.model.access.csv',
'data/ir_sequence.xml',
'views/website_thankyou_template.xml',
'views/sale_return.xml',
'views/sale_order.xml',
'views/res_partner.xml',
'views/stock_picking.xml',
'report/report.xml'
],
'images': ['static/description/banner.png'],
'license': 'AGPL-3',
'installable': True,
'application': False,
'auto_install': False,
}

25
website_multi_product_return_management/controllers/__init__.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Shijin V (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from . import main
from . import portal

70
website_multi_product_return_management/controllers/main.py

@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Shijin V (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from odoo.addons.web.controllers import main
from datetime import datetime
from odoo import http
from odoo.http import request
class CustomerRegistration(main.Home):
@http.route('/sale_return', type='json', csrf=False, auth="public", website=True)
def sale_return(self, **kwargs, ):
"""Controller to create return order"""
if kwargs.get('vals'):
lines = []
so_id = False
for line in kwargs.get('vals'):
so_id = request.env['sale.order'].sudo().search([('id', '=', int(line['order_id']))])
qty = int(line['quantity'])
d_qty = int(line['deli_qty'])
reason = line['reason']
if qty > 0:
lines.append((0, 0,{'product_id': line['product_id'],
'received_qty': qty,
'quantity': d_qty,
'reason':reason
}))
if so_id:
values = {
'partner_id': so_id.partner_id.id,
'sale_order': so_id.id,
'user_id': request.env.uid,
'create_date': datetime.now(),
'return_line_ids':lines
}
stock_picks = request.env['stock.picking'].sudo().search([('origin', '=', so_id.name)])
moves = stock_picks.mapped('move_ids_without_package').sudo().filtered(
lambda p: p.product_id.id == line['product_id'])
if moves:
moves = moves.sorted('product_uom_qty', reverse=True)
values.update({'state': 'draft'})
ret_order = request.env['sale.return'].sudo().create(values)
moves[0].picking_id.return_order = ret_order.id
moves[0].picking_id.return_order_picking = False
return True
return False
@http.route('/my/request-thank-you', website=True, page=True, auth='public', csrf=False)
def maintenance_request_thanks(self):
return request.render('website_multi_product_return_management.customers_request_thank_page')

139
website_multi_product_return_management/controllers/portal.py

@ -0,0 +1,139 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Shijin V (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
import base64
from collections import OrderedDict
from odoo.exceptions import AccessError, MissingError
from odoo import http
from odoo.http import request
from odoo.tools import image_process
from odoo.tools.translate import _
from odoo.addons.portal.controllers.portal import CustomerPortal
from odoo.addons.web.controllers.main import Binary
class ReturnCustomerPortal(CustomerPortal):
def _prepare_home_portal_values(self, counters):
values = super()._prepare_home_portal_values(counters)
partner = request.env.user.partner_id
if 'return_count' in counters:
if request.env.user.has_group('base.group_portal'):
values['return_count'] = request.env['sale.return'].search_count([
('state', 'in', ['draft', 'confirm', 'done', 'cancel']), ('partner_id', '=', partner.id)])
elif request.env.user.has_group('base.group_system'):
values['return_count'] = request.env['sale.return'].search_count([
('state', 'in', ['draft', 'confirm', 'done', 'cancel'])])
else:
domain = [('user_id', '=', request.env.user.id)]
values['return_count'] = request.env['sale.return'].search_count(
['|', ('partner_id', '=', partner.id), ('user_id', '=', request.env.user.id)])
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, **kw):
values = self._prepare_portal_layout_values()
sale_return = request.env['sale.return']
partner = request.env.user.partner_id
if request.env.user.has_group('base.group_portal'):
domain = [
('partner_id', '=', partner.id)
]
elif request.env.user.has_group('base.group_system'):
domain = []
else:
domain = ['|', ('partner_id', '=', partner.id), ('user_id', '=', request.env.user.id)]
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']
return_count = sale_return.sudo().search_count(domain)
# pager
pager = request.website.pager(
url="/my/return_orders",
url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby},
total=return_count,
page=page,
step=self._items_per_page
)
# content according to pager and archive selected
orders = sale_return.sudo().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_multi_product_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):
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_multi_product_return_management.report_sale_returns',
download=download)
values = self._sale_return_get_page_view_values(order_sudo, access_token, **kw)
return request.render("website_multi_product_return_management.portal_sale_return_page", values)
def _sale_return_get_page_view_values(self, order, access_token, **kwargs):
def resize_to_48(b64source):
if not b64source:
b64source = base64.b64encode(Binary.placeholder())
return 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)

14
website_multi_product_return_management/data/ir_sequence.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<record id="sale_return_ir_sequence" 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>

8
website_multi_product_return_management/doc/RELEASE_NOTES.md

@ -0,0 +1,8 @@
## Module <website_multi_product_return_management>
#### 11.01.2022
#### Version 14.0.1.0.0
##### Initial Commit for wwebsite_multi_product_return_management

28
website_multi_product_return_management/models/__init__.py

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Shijin V (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from . import sale_return
from . import sale_order
from . import res_partner
from . import stock_picking

62
website_multi_product_return_management/models/res_partner.py

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Shijin V (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
####################################################################################
from odoo import models, fields, api, _
class ResPartner(models.Model):
_inherit = 'res.partner'
return_order_count = fields.Integer(compute="_compute_returns", string='Return Orders')
def _compute_returns(self):
"""Function to calculate the return count"""
all_partners = self.with_context(active_test=False).sudo().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.sudo().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_multi_product_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

54
website_multi_product_return_management/models/sale_order.py

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Shijin V (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from odoo import models, fields, api, _
class SaleOrder(models.Model):
_inherit = 'sale.order'
return_order_count = fields.Integer(compute="_compute_retuns", string='Return Orders')
def _compute_retuns(self):
"""method to compute return count"""
sale_return_groups = self.env['sale.return'].sudo().read_group(
domain=[('sale_order', '=', self.ids)],
fields=['sale_order'], groupby=['sale_order'])
orders = self.sudo().browse()
for group in sale_return_groups:
sale_order = self.sudo().browse(group['sale_order'][0])
while sale_order:
if sale_order in self:
sale_order.return_order_count += group['sale_order_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_multi_product_return_management.sale_return_action')
domain = [('sale_order', '=', self.id)]
action['domain'] = domain
action['context'] = {'search_default_order': 1}
return action

240
website_multi_product_return_management/models/sale_return.py

@ -0,0 +1,240 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Shijin V (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from odoo import models, fields, api, _
class ReturnOrder(models.Model):
_name = 'sale.return'
_inherit = ['portal.mixin']
_rec_name = "name"
_order = "name"
_description = "Return Order"
@api.model
def _get_default_name(self):
return self.env['ir.sequence'].get('sale.return')
active = fields.Boolean('Active', default=True)
name = fields.Char(string="Name", default=_get_default_name)
sale_order = fields.Many2one('sale.order', string="Sale Order", required=True)
partner_id = fields.Many2one('res.partner', string="Customer")
user_id = fields.Many2one('res.users', string="Responsible", default=lambda self: self.env.user)
create_date = fields.Datetime(string="Create Date")
stock_picking = fields.One2many('stock.picking', 'return_order_pick', domain="[('return_order','=',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)
delivery_count = fields.Integer(compute="_compute_delivery", string='Delivery Order', copy=False, default=0,
store=True)
state = fields.Selection([('draft', 'Draft'), ('confirm', 'Confirm'), ('done', 'Done'), ('cancel', 'Canceled')],
string='Status', readonly=True, default='draft')
source_pick = fields.One2many('stock.picking', 'return_order', string="Source Delivery",
domain="[('return_order_pick','=',False)]",
help="Shows the delivery orders of the corresponding return order")
note = fields.Text("Note")
return_line_ids = fields.One2many('return.order.line', 'order_id', string="Return Lines")
def return_confirm(self):
"""Confirm the sale return"""
if not self.source_pick:
stock_picks = self.env['stock.picking'].sudo().search([('origin', '=', self.sale_order.name)])
moves = stock_picks.mapped('move_ids_without_package').sudo().filtered(
lambda p: p.product_id.id in self.return_line_ids.mapped('product_id').ids)
else:
moves = self.source_pick.mapped('move_ids_without_package').sudo().filtered(
lambda p: p.product_id.id in self.return_line_ids.mapped('product_id').ids)
if moves:
moves = moves.sorted('product_uom_qty', reverse=True)
pick = moves[0].picking_id
vals = {'picking_id': pick.id}
return_pick_wizard = self.env['stock.return.picking'].sudo().create(vals)
return_pick_wizard._onchange_picking_id()
return_pick_wizard.product_return_moves.unlink()
lines = []
reason = ''
for line in self.return_line_ids:
move = moves.filtered(lambda m:m.product_id == line.product_id)
lines.append(
{'product_id': line.product_id.id, "quantity": line.received_qty,
'move_id': move.id, 'to_refund': line.to_refund})
reason = reason + '\n' + line.reason
lines = self.env['stock.return.picking.line'].create(lines)
return_pick_wizard.write({
'product_return_moves': [(6, 0, lines.ids)]
})
return_pick = return_pick_wizard._create_returns()
if return_pick:
return_pick = self.env['stock.picking'].sudo().browse(return_pick[0])
return_pick.update({'note': reason})
return_pick.write({'return_order': False, 'return_order_pick': self.id, 'return_order_picking': True})
self.write({'state': 'confirm'})
def return_cancel(self):
"""Cancel the return"""
self.write({'state': 'cancel'})
if self.stock_picking:
for rec in self.stock_picking.sudo().filtered(lambda s: s.state not in ['done', 'cancel']):
rec.action_cancel()
def _get_report_base_filename(self):
self.ensure_one()
return 'Sale Return - %s' % (self.name)
def _compute_access_url(self):
super(ReturnOrder, self)._compute_access_url()
for order in self:
order.access_url = '/my/return_orders/%s' % order.id
@api.depends('stock_picking', '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:
rec.delivery_count = len(rec.source_pick)
else:
rec.delivery_count = self.env['stock.picking'].sudo().search_count(
[('return_order', 'in', self.ids), ('return_order_picking', '=', False)])
if rec.stock_picking:
rec.picking_count = len(rec.stock_picking)
else:
rec.picking_count = self.env['stock.picking'].sudo().search_count(
[('return_order_pick', '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')
if not self.stock_picking:
pickings = self.env['stock.picking'].sudo().search(
[('return_order_pick', '=', 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.sudo().filtered(lambda l: l.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('source_pick')
if not self.source_pick:
pickings = self.env['stock.picking'].sudo().search(
[('return_order', '=', 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 l: l.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:
self.partner_id = self.sale_order.partner_id
delivery = self.env['stock.picking'].sudo().search([('origin', '=', self.sale_order.name)])
if self.source_pick:
delivery = self.source_pick
if delivery:
product_ids = delivery.move_ids_without_package.mapped('product_id').ids
delivery = delivery.ids
else:
product_ids = self.sale_order.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):
if self.product_id and self.source_pick:
moves = self.source_pick.mapped('move_ids_without_package').sudo().filtered(
lambda p: p.product_id == self.product_id)
if moves:
self.received_qty = sum(moves.mapped('quantity_done'))
class ReturnOrderLine(models.Model):
_name = 'return.order.line'
_description = "return products Details"
order_id = fields.Many2one("sale.return", string="Order")
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")
quantity = fields.Float(string="Delivered Quantity", store=True)
received_qty = fields.Float(string="Received Quantity")
reason = fields.Text("Reason")
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')
@api.onchange('product_id')
def onchange_product_id(self):
""" setting up domain for products as per the products in the vendor price list"""
self.ensure_one()
if self._context.get('order_id'):
order_id = self.env['sale.order'].browse(self._context.get('order_id'))
products = order_id.order_line.mapped('product_id').ids
if self.product_id:
dqty = sum(
order_id.order_line.filtered(lambda p: p.product_id == self.product_id).mapped('qty_delivered'))
self.quantity = dqty
return {'domain': {'product_id': [('id', 'in', products)]}}

60
website_multi_product_return_management/models/stock_picking.py

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Shijin V (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from odoo import models, fields, api, _
class StockReturnPicking(models.TransientModel):
_inherit = 'stock.return.picking'
def _create_returns(self):
new_picking, pick_type_id = super(StockReturnPicking, self)._create_returns()
picking = self.env['stock.picking'].browse(new_picking)
if self.picking_id.return_order:
picking.write({'return_order_picking': False,
'return_order': False,
'return_order_pick': self.picking_id.return_order.id})
self.picking_id.return_order.write({'state': 'confirm'})
return new_picking, pick_type_id
class StockPicking(models.Model):
_inherit = 'stock.picking'
return_order = fields.Many2one('sale.return', string='Return order',
help="Shows the return order of current transfer")
return_order_pick = 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):
res = super(StockPicking, self).button_validate()
for rec in self:
if rec.return_order_pick:
if any(line.state != 'done' for line in rec.return_order_pick.stock_picking):
return res
else:
rec.return_order_pick.write({'state': 'done'})
return res

78
website_multi_product_return_management/report/report.xml

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<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_multi_product_return_management.report_salereturn</field>
<field name="report_file">website_multi_product_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>
<template id="report_salereturn">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="website_multi_product_return_management.report_sale_return" t-lang="doc.partner_id.lang"/>
</t>
</t>
</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" class="col-auto col-3 mw-100 mb-2">
<strong>Sale Order:</strong>
<p class="m-0" t-field="doc.sale_order"/>
</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">
<!-- In case we want to repeat the header, remove "display: table-row-group" -->
<thead style="display: table-row-group">
<tr>
<th name="th_description" class="text-left">Product</th>
<th name="th_quantity" class="text-left">Quantity</th>
<th name="th_quantity" class="text-left">Reason</th>
</tr>
</thead>
<tbody class="sale_tbody">
<tr t-foreach="doc.return_line_ids" t-as="line" t-att-class="'bg-200 font-weight-bold'">
<td name="td_product"><span t-field="line.product_id"/></td>
<td name="td_quantity" class="text-left">
<span t-esc="line.received_qty"/>
<span t-field="line.product_id.uom_id"/>
</td>
<td name="td_quantity" class="text-left">
<span t-field="line.reason"/>
</td>
</tr>
</tbody>
</table>
</div>
</t>
</template>
</data>
</odoo>

3
website_multi_product_return_management/security/ir.model.access.csv

@ -0,0 +1,3 @@
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
access_sale_return_line,access.sale.return.line,model_return_order_line,,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
3 access_sale_return_line access.sale.return.line model_return_order_line 1 1 1 1

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
website_multi_product_return_management/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
website_multi_product_return_management/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
website_multi_product_return_management/static/description/images/checked.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
website_multi_product_return_management/static/description/images/hero.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

BIN
website_multi_product_return_management/static/description/images/link.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
website_multi_product_return_management/static/description/images/list.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

BIN
website_multi_product_return_management/static/description/images/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
website_multi_product_return_management/static/description/images/modules/approval_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
website_multi_product_return_management/static/description/images/modules/dynamic_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
website_multi_product_return_management/static/description/images/modules/mulitple-ref_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
website_multi_product_return_management/static/description/images/modules/pos_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
website_multi_product_return_management/static/description/images/modules/shopify_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
website_multi_product_return_management/static/description/images/my leave analysis.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

BIN
website_multi_product_return_management/static/description/images/partner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
website_multi_product_return_management/static/description/images/printer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
website_multi_product_return_management/static/description/images/return.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-15.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

BIN
website_multi_product_return_management/static/description/images/screenshot-9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

804
website_multi_product_return_management/static/description/index.html

@ -0,0 +1,804 @@
<!-- Enterprise/Community Support Badge Section -->
<div class="container" style="padding: 1rem !important; margin-bottom: 1.5rem !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="./images/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 style="padding: 3.5rem 1.5rem !important; background-color: #ffffff !important;">
<div class="container">
<!-- HERO -->
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center"
style="text-align: center; padding: 1rem !important;">
<h1 class="text-center" style="color: #212121 !important; font-size: 3rem !important;"><span
style="font-weight: 700 !important;">Multi Product Return From Website</span></h1>
<p class="text-center"
style="color: #212529 !important; font-size: 1.5rem !important; letter-spacing: 1px !important;">
Manage Sale Order return from Website</p>
<img src="./images/hero.png" class="img-responsive">
</div>
</div>
<!-- END OF HERO -->
<!-- OVERVIEW -->
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center"
style="text-align: center; padding: 2.5rem 1rem !important;">
<h2 style="color: #212529 !important;">Overview</h2>
<hr
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
<p class="text-center" style="color: #212529 !important; font-size: 1.5rem !important;">
This module allows to create and manage sale order return from website. The logged user can create multiple product return from website. The
Authorize persons can manage the return orders. And allow the portal users can view their return
orders from the account portal view.
</p>
</div>
</div>
<!-- END OF OVERVIEW -->
<!-- KEY FEATURES -->
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center" style="padding: 2.5rem 1rem !important;">
<h2 class="text-center" style="color: #212529 !important;">Key Features</h2>
<hr
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
<div class="row align-items-center justify-content-between mb-5 pt-5 mb-lg-3 text-center">
<div class="col-sm-4 px-sm-4 pb-5">
<img src="./images/return.png">
<h5 class="my-2 text-bold">Create Return Orders From Website</h5>
<p class="text-gray-soft">Customers can create return order from Portal/My Account.Customer
can go to order and click "Return" button to return item which will generate return
order in backend</p>
</div>
<div class="col-sm-4 px-sm-4 pb-5">
<img src="./images/list.png">
<h5 class="my-2 text-bold">Portal Return Order View</h5>
<p class="text-gray-soft">Customers can view list of return orders from My Account.</p>
<br/><br/>
</div>
<div class="col-sm-4 px-sm-4 pb-5">
<img src="./images/link.png">
<h5 class="my-2 text-bold">Link Return With Sale Order</h5>
<p class="text-gray-soft">Easily switch the return orders from sale order by clicking the
return smart button in the sale order.</p>
<br/>
</div>
</div>
<div class="row align-items-center justify-content-center mb-5 pt-5 mb-lg-3 text-center">
<div class="col-sm-4 px-sm-4 pb-5">
<img src="./images/partner.png">
<h5 class="my-2 text-bold">Link Return Order With Partner </h5>
<p class="text-gray-soft">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.</p>
</div>
<div class="col-sm-4 px-sm-4 pb-5">
<img src="./images/printer.png">
<h5 class="my-2 text-bold">Return Order print</h5>
<p class="text-gray-soft">Allows to take PDF print of the return order.</p>
<br/><br/><br/>
</div>
</div>
</div>
</div>
<!-- END OF KEY FEATURES -->
<!-- SCREENSHOTS -->
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center" style="padding: 2.5rem 1rem !important;">
<h2 style="text-align: center; color: #212529 !important;">Screenshots</h2>
<hr
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
01</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Return Button on
Order Page on Portal
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
Goto Portal/ My Account -> Sale order , from the sale order click Return button.
</p>
</div>
</div>
<img src="./images/screenshot-1.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
02</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Return Product Screen
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
User can see the prefilled product in the return wizard , user can edit and update the quantity and return reason, after that you can submit the return using Submit button.
</p>
</div>
</div>
<img src="./images/screenshot-2.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
03</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Return Orders in
Portal for View
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
Customer can see list of RMA orders in Portal / My Account.
</p>
</div>
</div>
<img src="./images/screenshot-3.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
04</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Return Orders tree
view in Portal.
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
The customer can see the basic details and status of the return order.
</p>
</div>
</div>
<img src="./images/screenshot-4.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
05</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Return Orders
detailed view in Portal.
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
The customer can see the detailed information of the return order in portal.
</p>
</div>
</div>
<img src="./images/screenshot-5.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
06</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">RMA Return Orders -
Backend
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
Return order tree view, Goto Sales -> Return Orders
</p>
</div>
</div>
<img src="./images/screenshot-6.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
07</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Return Orders form
view in backend.
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
Backend form view of return order.
</p>
</div>
</div>
<img src="./images/screenshot-7.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
08</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Delivery Order Tab
and Smart button
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
Shows all the delivery order's related with Sales order.
</p>
</div>
</div>
<img src="./images/screenshot-8.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
09</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Return Process on DO
picking.
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
Return picking creation from return order using confirm button.
</p>
</div>
</div>
<img src="./images/screenshot-9.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
10</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Delivery Order Return
Button
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
Return picking creation from return button in delivery (Odoo Standard process).
</p>
</div>
</div>
<img src="./images/screenshot-10.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
11</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Delivery Order Return
Wizard(Odoo Standard)
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
Odoo default wizard for product return.
</p>
</div>
</div>
<img src="./images/screenshot-11.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
12</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Return Picking Order
Tab and Smart button
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
Shows all the return picking order's related with Return Order.
</p>
</div>
</div>
<img src="./images/screenshot-12.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
13</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Smart Button on
Customer Form
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
On customer form smart button showing all return order related to that customer
</p>
</div>
</div>
<img src="./images/screenshot-13.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
14</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Smart Button on Sale
Order Form
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
On Sale Order form smart button showing all return order related to that sale order.
</p>
</div>
</div>
<img src="./images/screenshot-14.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
<!-- img -->
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;">
<div class="mr-3">
<h3
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;">
15</h3>
</div>
<div>
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;">Return Orders -
Report Sample
</h3>
<p
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;">
Print RMA PDF Report - Print Return Report.
</p>
</div>
</div>
<img src="./images/screenshot-15.png" class="img-responsive border"
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;">
<!-- endo of img -->
</div>
</div>
<!-- END OF SCREENSHOTS -->
<!-- SUGGESTED PRODUCTS -->
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center"
style="text-align: center; padding: 2.5rem 1rem !important;">
<h2 style="color: #212529 !important;">Suggested Products</h2>
<hr
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
<div id="demo1" class="row carousel slide" data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner">
<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/14.0/dynamic_accounts_report/"
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="./images/modules/dynamic_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/14.0/dashboard_pos/" 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="./images/modules/pos_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/14.0/product_approval_management/"
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="./images/modules/approval_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/14.0/multiple_reference_per_product/"
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="./images/modules/mulitple-ref_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/14.0/shopify_odoo_connector/"
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="./images/modules/shopify_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 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Our Services</h2>
<hr
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !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 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Our Industries</h2>
<hr
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !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 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Need Help?</h2>
<hr
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !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-4">
<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-4">
<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>WhatsApp</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>
</div>
<!--- COPY TO HERE-->
</div>

61
website_multi_product_return_management/static/src/js/sale_return.js

@ -0,0 +1,61 @@
odoo.define('website_multi_product_return_management.return', function (require) {
"use strict";
var publicWidget = require('web.public.widget');
var ajax = require('web.ajax');
$("#hidden_box_btn").on('click', function () {
$('#hidden_box').modal('show');
})
$(".js_add_json").on('click', function (ev) {
var $link = $(ev.currentTarget);
var $input = $link.closest('.input-group').find("input");
var min = parseFloat($input.data("min") || 0);
var max = parseFloat($input.data("max") || Infinity);
var previousQty = parseFloat($input.val() || 0, 10);
var quantity = ($link.has(".fa-minus").length ? -1 : 1) + previousQty;
var newQty = quantity > min ? (quantity < max ? quantity : max) : min;
if (newQty !== previousQty) {
$input.val(newQty).trigger('change');
}
return false;
})
$('#sale_return_form').on('submit', function(submission) {
var val = []
submission.preventDefault();
$("tr.order_line").each(function() {
var qty = parseFloat($(this).find(".quantity").val() || 0);
if (qty !== 0){
val.push({ 'order_id' : $(this).find(".quantity").data("order-id"),
'line_id' : $(this).find(".quantity").data("line-id"),
'deli_qty' : $(this).find(".quantity").data("delivered_qty"),
'quantity' : $(this).find(".quantity").val(),
'product_id' : $(this).find(".quantity").data('product-id'),
'reason' : $(this).find("#return_reason").val()});
}
});
if (val.length !== 0){
ajax.jsonRpc('/sale_return', 'call', {
'vals':val,
}).then(function(result){
if (result == true){
window.location.href = '/my/request-thank-you';
}
else{
alert("Retry again");
}
});
}
else{
alert("Please specify at least one return quantity");
submission.preventDefault();
}
});
});

18
website_multi_product_return_management/views/res_partner.xml

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_partners_form_sale_return" model="ir.ui.view">
<field name="name">view.res.partner.form.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>

349
website_multi_product_return_management/views/sale_order.xml

@ -0,0 +1,349 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_frontend" inherit_id="website.assets_frontend">
<xpath expr="link[last()]" position="after">
<script src="/website_multi_product_return_management/static/src/js/sale_return.js" type="text/javascript"/>
</xpath>
</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">
<form id="sale_return_form" >
<div id="hidden_box" class="modal fade">
<div class="modal-dialog modal-content"
style="border:solid 1px #604e5b; min-height:500px;max-width: 800px;">
<div class="modal-header">
<h5 class="modal-title">
<b>Sale Return</b>
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">X</span>
</button>
</div>
<div class="modal-body" id="pop_html">
<form>
<table t-att-data-order-id="sale_order.id" t-att-data-token="sale_order.access_token"
class="table table-sm" id="sales_return_order_table">
<thead class="bg-100">
<tr>
<th class="text-left">Products</th>
<th class="text-right">Quantity</th>
<th class="text-right">Return Quantity</th>
<th class="text-right" style="width:25px;"> Reason</th>
</tr>
</thead>
<tbody class="sale_tbody">
<tr t-foreach="sale_order.order_line.filtered(lambda x:x.product_id.type!='service' and not x.display_type)"
t-as="line" class="order_line">
<t t-att-class="'bg-200 font-weight-bold o_line_section' if line.display_type == 'line_section' else 'font-italic o_line_note' if line.display_type == 'line_note' else ''">
<td id="product_name">
<span t-field="line.name"/>
</td>
<td class="text-right">
<div id="quote_qty">
<span t-field="line.product_uom_qty"/>
<span t-field="line.product_uom"/>
</div>
</td>
<td>
<div class="css_quantity input-group">
<div class="input-group-prepend">
<a t-attf-href="#"
class="btn btn-link js_add_json d-none d-md-inline-block"
aria-label="Remove one" title="Remove one">
<i class="fa fa-minus"></i>
</a>
</div>
<input type="text" class="form-control quantity"
style="width: 50px;height: 50px;text-align: center;"
t-att-data-min="0"
t-att-data-max="int(line.product_uom_qty) == line.product_uom_qty and int(line.product_uom_qty) or line.product_uom_qty"
t-att-data-line-id="line.id"
t-att-data-order-id="sale_order.id"
t-att-data-product-id="line.product_id.id"
t-att-data-delivered_qty="int(line.product_uom_qty) == line.product_uom_qty and int(line.product_uom_qty) or line.product_uom_qty"
readonly="1"/>
<div class="input-group-append">
<a t-attf-href="#"
class="btn btn-link float_left d-none d-md-inline-block js_add_json"
aria-label="Add one" title="Add one">
<i class="fa fa-plus"></i>
</a>
</div>
</div>
</td>
<td style="width:20px;">
<textarea id="return_reason" name="reason" placeholder="Reason"/>
</td>
</t>
</tr>
</tbody>
</table>
</form>
</div>
<div class="modal-footer">
<button id='submit'
class="btn btn-secondary flex-grow-1 mb-1">
Submit
</button>
<button type="button" class="btn btn-secondary "
data-dismiss="modal">Close
</button>
</div>
</div>
</div>
<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-right">
<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"></i>
Return
</a>
</t>
</span>
</div>
</div>
</form>
</xpath>
</template>
<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>
<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>
<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">Sales Return</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"/>
</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>
<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>
<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"></i>
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 else 'd-none'">
<strong>Sale Order:</strong>
<span class="ml-1" t-field="orders.sale_order"/>
</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>
<th class="text-right">Reason</th>
</tr>
</thead>
<tbody>
<tr t-foreach="orders.return_line_ids" t-as="line">
<td>
<img t-att-src="image_data_uri(resize_to_48(line.product_id.image_1024))"
alt="Product" class="d-none d-lg-inline"/>
<span t-esc="line.product_id.name"/>
</td>
<td class="text-right">
<span t-esc="line.received_qty"/>
</td>
<td class="text-right">
<span t-esc="line.reason"/>
</td>
</tr>
</tbody>
</table>
<div class="row"/>
</div>
</div>
</div>
</div>
</div>
<div class="oe_structure mb32"/>
</t>
</template>
<record id="view_order_form_inherit_sales_return" model="ir.ui.view">
<field name="name">view.order.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>
</field>
</record>
</odoo>

124
website_multi_product_return_management/views/sale_return.xml

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="sale_return_form_view" 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"/>
<field name="partner_id"/>
</group>
<group>
<field name="create_date"/>
<field name="user_id"/>
<field name="stock_picking" invisible="1"/>
</group>
</group>
<notebook>
<page string="Return Lines" name="order_line">
<field name="return_line_ids" context="{'order_id':sale_order}">
<tree editable="bottom">
<field name="product_id" />
<field name="product_tmpl_id" invisible="1"/>
<field name="quantity" readonly="1" force_save="1"/>
<field name="received_qty"/>
<field name="reason"/>
<field name="to_refund" optional="hide"/>
</tree>
</field>
</page>
<page string="Delivery Order" name="delivery_order">
<field name="source_pick"/>
</page>
<page string="Return Picking" name="return_picking">
<field name="stock_picking"/>
</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>
<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"/>
<field name="partner_id"/>
<field name="create_date"/>
<field name="user_id"/>
<field name="state"/>
</tree>
</field>
</record>
<record id="view_sale_return_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" string="Sale order"/>
<field name="partner_id" string="Customer"/>
<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'}"/>
<filter string="Customer" name="customer" domain="[]" context="{'group_by':'partner_id'}"/>
</group>
</search>
</field>
</record>
<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>
<menuitem id="sale_return_menu"
parent="sale.sale_menu_root"
name="Return Orders"
action="website_multi_product_return_management.sale_return_action"/>
</odoo>

15
website_multi_product_return_management/views/stock_picking.xml

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="sale_return_origin_view" model="ir.ui.view">
<field name="name">sale.return.origin.view</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" attrs="{'invisible': [('return_order','=', False)]}"/>
<field name="return_order_pick" attrs="{'invisible': [('return_order_pick','=', False)]}"/>
<field name="return_order_picking" invisible="1"/>
</field>
</field>
</record>
</odoo>

32
website_multi_product_return_management/views/website_thankyou_template.xml

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<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 class="col-lg-4">
<t t-call="website.company_description"/>
</div>
</div>
</div>
<div class="oe_structure" id="oe_structure_website_form_contact_us_thanks_2"/>
</div>
</div>
</div>
</t>
</template>
</odoo>
Loading…
Cancel
Save