Browse Source

Dec 19 [ADD] : Initial Commit 'multi_vendor_marketplace'

pull/301/merge
AjmalCybro 4 months ago
parent
commit
2cec0b9746
  1. 48
      multi_vendor_marketplace/README.rst
  2. 34
      multi_vendor_marketplace/__init__.py
  3. 103
      multi_vendor_marketplace/__manifest__.py
  4. 23
      multi_vendor_marketplace/controller/__init__.py
  5. 77
      multi_vendor_marketplace/controller/seller_dashboard.py
  6. 286
      multi_vendor_marketplace/controller/seller_signup.py
  7. 10
      multi_vendor_marketplace/data/account_journal_data.xml
  8. 200
      multi_vendor_marketplace/data/email_template_data.xml
  9. 11
      multi_vendor_marketplace/data/ir_config_parameter_data.xml
  10. 10
      multi_vendor_marketplace/data/product_template_data.xml
  11. 14
      multi_vendor_marketplace/data/res_users_data.xml
  12. 33
      multi_vendor_marketplace/data/social_media_data.xml
  13. 10
      multi_vendor_marketplace/data/website_menu_data.xml
  14. 6
      multi_vendor_marketplace/doc/RELEASE_NOTES.md
  15. 41
      multi_vendor_marketplace/models/__init__.py
  16. 35
      multi_vendor_marketplace/models/helpful_info.py
  17. 89
      multi_vendor_marketplace/models/inventory_request.py
  18. 50
      multi_vendor_marketplace/models/multi_vendor_pricelist.py
  19. 40
      multi_vendor_marketplace/models/product_pricelist_item.py
  20. 184
      multi_vendor_marketplace/models/product_template.py
  21. 81
      multi_vendor_marketplace/models/request_payment.py
  22. 290
      multi_vendor_marketplace/models/res_config_settings.py
  23. 344
      multi_vendor_marketplace/models/res_partner.py
  24. 57
      multi_vendor_marketplace/models/res_users.py
  25. 92
      multi_vendor_marketplace/models/sale_order.py
  26. 107
      multi_vendor_marketplace/models/sale_order_line.py
  27. 151
      multi_vendor_marketplace/models/seller_payment.py
  28. 65
      multi_vendor_marketplace/models/seller_recommend.py
  29. 115
      multi_vendor_marketplace/models/seller_review.py
  30. 80
      multi_vendor_marketplace/models/seller_shop.py
  31. 34
      multi_vendor_marketplace/models/social_media.py
  32. 43
      multi_vendor_marketplace/models/stock_picking.py
  33. 29
      multi_vendor_marketplace/models/vendor_dashboard.py
  34. 31
      multi_vendor_marketplace/models/website.py
  35. 40
      multi_vendor_marketplace/models/website_menu.py
  36. 21
      multi_vendor_marketplace/security/inventory_request_security.xml
  37. 14
      multi_vendor_marketplace/security/ir.model.access.csv
  38. 26
      multi_vendor_marketplace/security/multi_vendor_marketplace_groups.xml
  39. 17
      multi_vendor_marketplace/security/product_template_security.xml
  40. 18
      multi_vendor_marketplace/security/sale_order_line_security.xml
  41. 17
      multi_vendor_marketplace/security/seller_payment_security.xml
  42. 20
      multi_vendor_marketplace/security/seller_shop_security.xml
  43. 18
      multi_vendor_marketplace/security/stock_picking_security.xml
  44. BIN
      multi_vendor_marketplace/static/description/assets/icons/check.png
  45. BIN
      multi_vendor_marketplace/static/description/assets/icons/chevron.png
  46. BIN
      multi_vendor_marketplace/static/description/assets/icons/cogs.png
  47. BIN
      multi_vendor_marketplace/static/description/assets/icons/consultation.png
  48. BIN
      multi_vendor_marketplace/static/description/assets/icons/ecom-black.png
  49. BIN
      multi_vendor_marketplace/static/description/assets/icons/education-black.png
  50. BIN
      multi_vendor_marketplace/static/description/assets/icons/hotel-black.png
  51. BIN
      multi_vendor_marketplace/static/description/assets/icons/license.png
  52. BIN
      multi_vendor_marketplace/static/description/assets/icons/lifebuoy.png
  53. BIN
      multi_vendor_marketplace/static/description/assets/icons/manufacturing-black.png
  54. BIN
      multi_vendor_marketplace/static/description/assets/icons/pos-black.png
  55. BIN
      multi_vendor_marketplace/static/description/assets/icons/puzzle.png
  56. BIN
      multi_vendor_marketplace/static/description/assets/icons/restaurant-black.png
  57. BIN
      multi_vendor_marketplace/static/description/assets/icons/service-black.png
  58. BIN
      multi_vendor_marketplace/static/description/assets/icons/trading-black.png
  59. BIN
      multi_vendor_marketplace/static/description/assets/icons/training.png
  60. BIN
      multi_vendor_marketplace/static/description/assets/icons/update.png
  61. BIN
      multi_vendor_marketplace/static/description/assets/icons/user.png
  62. BIN
      multi_vendor_marketplace/static/description/assets/icons/wrench.png
  63. BIN
      multi_vendor_marketplace/static/description/assets/misc/categories.png
  64. BIN
      multi_vendor_marketplace/static/description/assets/misc/check-box.png
  65. BIN
      multi_vendor_marketplace/static/description/assets/misc/compass.png
  66. BIN
      multi_vendor_marketplace/static/description/assets/misc/corporate.png
  67. BIN
      multi_vendor_marketplace/static/description/assets/misc/customer-support.png
  68. BIN
      multi_vendor_marketplace/static/description/assets/misc/cybrosys-logo.png
  69. BIN
      multi_vendor_marketplace/static/description/assets/misc/features.png
  70. BIN
      multi_vendor_marketplace/static/description/assets/misc/logo.png
  71. BIN
      multi_vendor_marketplace/static/description/assets/misc/pictures.png
  72. BIN
      multi_vendor_marketplace/static/description/assets/misc/pie-chart.png
  73. BIN
      multi_vendor_marketplace/static/description/assets/misc/right-arrow.png
  74. BIN
      multi_vendor_marketplace/static/description/assets/misc/star.png
  75. BIN
      multi_vendor_marketplace/static/description/assets/misc/support.png
  76. BIN
      multi_vendor_marketplace/static/description/assets/misc/whatsapp.png
  77. BIN
      multi_vendor_marketplace/static/description/assets/modules/1.png
  78. BIN
      multi_vendor_marketplace/static/description/assets/modules/2.png
  79. BIN
      multi_vendor_marketplace/static/description/assets/modules/3.png
  80. BIN
      multi_vendor_marketplace/static/description/assets/modules/4.png
  81. BIN
      multi_vendor_marketplace/static/description/assets/modules/5.gif
  82. BIN
      multi_vendor_marketplace/static/description/assets/modules/6.png
  83. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/1.png
  84. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/10.png
  85. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/11.png
  86. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/12.png
  87. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/13.png
  88. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/14.png
  89. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/15.png
  90. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/2.png
  91. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/3.png
  92. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/4.png
  93. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/5.png
  94. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/6.png
  95. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/7.png
  96. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/8.png
  97. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/9.png
  98. BIN
      multi_vendor_marketplace/static/description/assets/screenshots/hero.gif
  99. BIN
      multi_vendor_marketplace/static/description/banner.png
  100. BIN
      multi_vendor_marketplace/static/description/icon.png

48
multi_vendor_marketplace/README.rst

@ -0,0 +1,48 @@
.. image:: image:: https://img.shields.io/badge/license-LGPL--3-green.svg
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
Odoo Multi Vendor Marketplace
===============================
This Module Create your own marketplace and facilitate the exchange of buyers and sellers
Configuration
=============
* No additional configurations needed
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
License
-------
Lesser General Public License, Version 3 (LGPL v3).
(https://www.gnu.org/licenses/lgpl-3.0-standalone.html)
Credits
-------
* Developers: (V16) Gokul P I,
Farha V C,
Sreeshanth V S, Contact: odoo@cybrosys.com
Contacts
--------
* Mail Contact : odoo@cybrosys.com
* Website : https://cybrosys.com
Bug Tracker
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
Maintainer
==========
.. image:: https://cybrosys.com/images/logo.png
:target: https://cybrosys.com
This module is maintained by Cybrosys Technologies.
For support and more information, please visit `Our Website <https://cybrosys.com/>`__
Further information
===================
HTML Description: `<static/description/index.html>`__

34
multi_vendor_marketplace/__init__.py

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import controller
from . import models
from . import wizard
from odoo import api, SUPERUSER_ID
@api.model
def test_pre_init_hook(cr):
"""For hiding some menus after login a seller user"""
env = api.Environment(cr, SUPERUSER_ID, {})
res = env.ref('stock.menu_stock_root')
res1 = env.ref('stock.group_stock_user')
res.write({'groups_id': [(3, res1.id, 0)]})

103
multi_vendor_marketplace/__manifest__.py

@ -0,0 +1,103 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
{
'name': "Odoo Multi Vendor Marketplace",
'version': "16.0.1.0.0",
'category': 'eCommerce,Sales ,Warehouse',
'summary': 'Odoo Multi Vendor Marketplace, Odoo16, Multi Vendor',
'description': 'The Multi-Vendor Marketplace module in Odoo enables '
'businesses to establish an online platform where multiple'
'vendors can offer their products or services to customers.'
'Vendors can manage their own profiles, products, and '
'orders, while the admin can set commission rates, manage '
'payments, maintain quality control. The module provides'
'customization options, and user-friendly interfaces for a '
'seamless marketplace experience. ',
'author': 'Cybrosys Techno solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': ['base', 'sale_management', 'account', 'website', 'stock',
'website_sale'],
'data': [
'security/multi_vendor_marketplace_groups.xml',
'security/inventory_request_security.xml',
'security/product_template_security.xml',
'security/sale_order_line_security.xml',
'security/seller_payment_security.xml',
'security/seller_shop_security.xml',
'security/stock_picking_security.xml',
'security/ir.model.access.csv',
'data/res_users_data.xml',
'data/ir_config_parameter_data.xml',
'data/social_media_data.xml',
'data/account_journal_data.xml',
'data/product_template_data.xml',
'data/email_template_data.xml',
'data/website_menu_data.xml',
'views/vendor_dashboard_views.xml',
'views/stock_moves_views.xml',
'views/sell_page_templates.xml',
'views/res_partner_views.xml',
'views/seller_payment_views.xml',
'views/request_payment_views.xml',
'views/multi_vendor_pricelist_views.xml',
'views/product_product_views.xml',
'views/product_template_views.xml',
'views/seller_shop_views.xml',
'views/res_config_settings_views.xml',
'views/seller_review_views.xml',
'views/helpful_info_views.xml',
'views/product_public_category_views.xml',
'views/account_payment_method_views.xml',
'views/stock_picking_views.xml',
'views/inventory_request_views.xml',
'views/seller_recommend_views.xml',
'views/social_media_views.xml',
'views/seller_web_templates.xml',
'views/seller_product_templates.xml',
'views/sale_order_line_views.xml',
'views/multi_vendor_marketplace_menus.xml',
'views/seller_shop_information_templates.xml',
'views/seller_list_templates.xml',
'wizard/settings_view_views.xml',
],
'assets': {
'web.assets_backend': [
'multi_vendor_marketplace/static/src/xml/saller_dashboard.xml',
'multi_vendor_marketplace/static/src/js/seller_dashboard_action.js',
],
'web.assets_frontend': [
'multi_vendor_marketplace/static/src/js/rating.js',
'multi_vendor_marketplace/static/src/scss/partner_rating.css',
'https://unpkg.com/sweetalert/dist/sweetalert.min.js',
],
},
'images': [
'static/description/banner.png',
],
'license': 'LGPL-3',
'installable': True,
'application': True,
'auto install': False,
'pre_init_hook': 'test_pre_init_hook',
}

23
multi_vendor_marketplace/controller/__init__.py

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

77
multi_vendor_marketplace/controller/seller_dashboard.py

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import http
from odoo.http import request
class SellerDashboard(http.Controller):
"""This Class for creating dashboard"""
@http.route(['/seller_dashboard'], type='json', auth="public",
website=True)
def seller_dashboard(self):
"""Load the dashboard information"""
return {'pending': request.env['product.template'].search_count(
[('state', '=', 'pending')]),
'approved': request.env['product.template'].search_count(
[('state', '=', 'approved')]),
'rejected': request.env['product.template'].search_count(
[('state', '=', 'rejected')]),
'user_type': request.env['res.users'].has_group(
'multi_vendor_marketplace.multi_vendor_marketplace_admin'),
'seller_pending': request.env['res.partner'].search_count(
[('state', '=', 'Pending for Approval')]),
'seller_approved': request.env['res.partner'].search_count(
[('state', '=', 'Approved')]),
'seller_rejected': request.env['res.partner'].search_count(
[('state', '=', 'Denied')]),
'inventory_pending': request.env['inventory.request'].search_count(
[('state', '=', 'Requested')]),
'inventory_approved': request.env[
'inventory.request'].search_count(
[('state', '=', 'Approved')]),
'inventory_rejected': request.env[
'inventory.request'].search_count(
[('state', '=', 'Rejected')]),
'payment_pending': request.env['seller.payment'].search_count(
[('state', '=', 'Requested')]),
'payment_approved': request.env['seller.payment'].search_count(
[('state', '=', 'Validated')]),
'payment_rejected': request.env['seller.payment'].search_count(
[('state', '=', 'Rejected')]),
'order_pending': request.env['sale.order.line'].search_count(
[('state', '=', 'pending')]),
'order_approved': request.env['sale.order.line'].search_count(
[('state', '=', 'approved')]),
'order_shipped': request.env['sale.order.line'].search_count(
[('state', '=', 'shipped')]),
'order_cancel': request.env['sale.order.line'].search_count(
[('state', '=', 'cancel')]),
'sale_order_kanban_id': request.env['ir.ui.view'].search(
[('name', '=', 'multi.vendor.sale.order.line.kanban')]).id,
'product_kanban_id': request.env['ir.ui.view'].search(
[('name', '=', 'multi.vendor.view.kanban')]).id,
'sale_order_form_id': request.env['ir.ui.view'].search(
[(
'name', '=',
'multi.vendor.sale.order.line.form.readonly')]).id
}

286
multi_vendor_marketplace/controller/seller_signup.py

@ -0,0 +1,286 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
import logging
import werkzeug
from werkzeug.urls import url_encode
from odoo import http, _
from odoo.exceptions import UserError
from odoo.http import request
from odoo.addons.auth_signup.models.res_users import SignupError
from odoo.addons.auth_signup.controllers.main import AuthSignupHome
from odoo.addons.auth_signup.controllers.main import ensure_db, \
LOGIN_SUCCESSFUL_PARAMS, SIGN_UP_REQUEST_PARAMS
_logger = logging.getLogger(__name__)
LOGIN_SUCCESSFUL_PARAMS.add('account_created')
class SellerSignup(AuthSignupHome):
"""Class for sellers signup"""
@http.route(['/seller/list'], type="http", auth="public",
website="True")
def seller_list(self):
""" Goto the Sellers List"""
return http.Response(
template='multi_vendor_marketplace.seller_list',
qcontext={
'seller': request.env['res.partner'].sudo().search(
[('state', '=', 'Approved'), ('is_published', '=', True)])
})
@http.route(['/seller/profile/<string:profile_url>'], type="http",
auth="public", website="True")
def seller_profile(self, **kwargs):
"""Goto The corresponding seller-shop Using Profile URl"""
user_obj = request.env['res.partner'].sudo().search(
[('profile_url_value', '=', kwargs.get('profile_url'))])
recent_products = request.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.recent_products')
review_count = request.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.seller_review_count')
current_user = request.env.user.sudo()
review = request.env['seller.review'].sudo().search(
[('seller_id', '=', user_obj.id), ('state', '=', 'published')],
limit=int(review_count))
product = request.env['product.template'].sudo().search(
[('seller_id', '=', user_obj.id), ('is_published', '=', True)])
recently_add_product = request.env['product.template'].sudo().search(
[('seller_id', '=', user_obj.id), ('is_published', '=', True)],
limit=int(recent_products),
order='seller_id desc')
params = request.env['res.config.settings'].sudo().search(
[], order='create_date DESC', limit=1)
partner = request.env['res.partner'].sudo().browse(user_obj.id)
avg_rating = partner.avg_rating
total = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', partner.id)])
if total != 0:
five = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', partner.id), ('rating', '=', '5')])
four = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', partner.id), ('rating', '=', '4')])
three = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', partner.id), ('rating', '=', '3')])
two = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', partner.id), ('rating', '=', '2')])
one = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', partner.id), ('rating', '=', '1')])
five = round(five / total * 100)
four = round(four / total * 100)
three = round(three / total * 100)
two = round(two / total * 100)
one = round(one / total * 100)
else:
five = four = three = two = one = 0
values = {
'res_users': user_obj,
'product': product,
'recently_add_product': recently_add_product,
'config': params,
'cr_user': current_user,
'avg': round(avg_rating, 2),
'prod_count': request.env['product.template'].sudo().search_count(
[('seller_id', '=', user_obj.id),
('is_published', '=', True)]),
'sale_count': request.env['sale.order.line'].sudo().search_count(
[('seller_id', '=', user_obj.id)]),
'average': avg_rating,
'five': str(five),
'four': str(four),
'three': str(three),
'two': str(two),
'one': str(one),
'review': review
}
response = http.Response(
template='multi_vendor_marketplace.seller_product',
qcontext=values)
return response.render()
@http.route(['/sell'], type="http", auth="public", website="True")
def home_page(self, **post):
"""Goto the sell menu and here we can see the seller registration
button """
params = request.env['res.config.settings'].sudo().search(
[], order='create_date desc', limit=1)
values = {
'config': params}
response = http.Response(
template='multi_vendor_marketplace.sell_page',
qcontext=values)
return response.render()
@http.route(['/seller_shop'], type="http", auth="public",
website="True", csrf=False)
def seller_shop(self, seller_id=None, product_id=None, **kwargs):
"""Goto the corresponding Seller shop"""
if product_id:
pr = request.env['product.product'].sudo().browse(int(product_id))
user_obj = pr.seller_id
else:
pr = request.env['res.partner'].sudo().browse(int(seller_id))
user_obj = pr
recent_products = request.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.recent_products')
review_count = request.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.seller_review_count')
current_user = request.env.user.sudo()
review = request.env['seller.review'].sudo().search(
[('seller_id', '=', user_obj.id), ('state', '=', 'published')],
limit=int(review_count))
product = request.env['product.template'].sudo().search(
[('seller_id', '=', user_obj.id), ('is_published', '=', True)])
recently_add_product = request.env['product.template'].sudo().search(
[('seller_id', '=', user_obj.id), ('is_published', '=', True)],
limit=int(recent_products),
order='seller_id desc')
params = request.env['res.config.settings'].sudo().search(
[], order='create_date DESC', limit=1)
res_partner = request.env['res.partner'].sudo().browse(user_obj.id)
avg_rating = res_partner.avg_rating
total = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', res_partner.id)])
if total != 0:
five = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', res_partner.id), ('rating', '=', '5')])
four = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', res_partner.id), ('rating', '=', '4')])
three = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', res_partner.id), ('rating', '=', '3')])
two = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', res_partner.id), ('rating', '=', '2')])
one = request.env['seller.review'].sudo().search_count(
[('seller_id', '=', res_partner.id), ('rating', '=', '1')])
five = round(five / total * 100)
four = round(four / total * 100)
three = round(three / total * 100)
two = round(two / total * 100)
one = round(one / total * 100)
else:
five = four = three = two = one = 0
values = {
'res_users': user_obj,
'product': product,
'recently_add_product': recently_add_product,
'config': params,
'cr_user': current_user,
'avg': round(avg_rating, 2),
'prod_count': request.env['product.template'].sudo().search_count(
[('seller_id', '=', user_obj.id),
('is_published', '=', True)]),
'sale_count': request.env['sale.order.line'].sudo().search_count(
[('seller_id', '=', user_obj.id)]),
'average': avg_rating,
'five': str(five),
'four': str(four),
'three': str(three),
'two': str(two),
'one': str(one),
'review': review
}
response = http.Response(
template='multi_vendor_marketplace.seller_product',
qcontext=values)
return response.render()
@http.route('/seller_reg', type='http', auth='public', website=True,
sitemap=False, csrf=False)
def seller_signup(self, *args, **kw):
"""Seller Registration Form"""
qcontext = self.get_auth_signup_qcontext()
if not qcontext.get('token') and not qcontext.get('signup_enabled'):
raise werkzeug.exceptions.NotFound()
if 'error' not in qcontext and request.httprequest.method == 'POST':
if request.env["res.partner"].sudo().search(
[("profile_url_value", "=", kw.get("profile_url"))]):
qcontext["error"] = _(
"Another user has already registered using this Profile "
"url.")
else:
try:
profile_url = {'profile_url': 1}
qcontext.update(profile_url)
self.do_signup(qcontext)
base_url = request.env[
'ir.config_parameter'].sudo().get_param(
'web.base.url')
request.env["res.partner"].sudo().search(
[('email', '=', kw.get('login'))]).write(
{'profile_url': base_url + "/seller/profile/" + kw.get(
'profile_url'),
'profile_url_value': kw.get('profile_url')})
if qcontext.get('token'):
user = self.env['res.users']
user_sudo = user.sudo().search(
user._get_login_domain(qcontext.get('login')),
order=user._get_login_order(), limit=1
)
template = request.env.ref(
'auth_signup.mail_template_user_input_invite',
raise_if_not_found=False)
if user_sudo and template:
template.sudo().send_mail(user_sudo.id,
force_send=True)
return self.web_login(*args, **kw)
except UserError as e:
qcontext['error'] = e.args[0]
except (SignupError, AssertionError) as e:
if request.env["res.users"].sudo().search(
[("login", "=", qcontext.get("login"))]):
qcontext["error"] = _(
"Another user is already registered using this "
"email address.")
else:
_logger.error("%s", e)
qcontext['error'] = _(
"Could not create a new account.")
elif 'signup_email' in qcontext:
user = request.env['res.users'].sudo().search(
[('email', '=', qcontext.get('signup_email')),
('state', '!=', 'new')], limit=1)
if user:
return request.redirect('/web/login?%s' % url_encode(
{'login': user.login, 'redirect': '/web'}))
response = request.render('multi_vendor_marketplace.mark', qcontext)
return response
def _prepare_signup_values(self, qcontext):
"""Super The _prepare_signup_values function to pass values not to
Override The Default Sign Up"""
values = {key: qcontext.get(key) for key in
('login', 'name', 'password')}
if not values:
raise UserError(_("The form was not properly filled in."))
if values.get('password') != qcontext.get('confirm_password'):
raise UserError(
_("Passwords do not match; please retype them."))
supported_lang_codes = [code for code, _ in
request.env['res.lang'].get_installed()]
lang = request.context.get('lang', '')
if lang in supported_lang_codes:
values['lang'] = lang
values['profile_url'] = int(
qcontext.get('profile_url')) if qcontext.get(
'profile_url') else 0
return values

10
multi_vendor_marketplace/data/account_journal_data.xml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo noupdate="1">
<!--Creating journal for seller-->
<record id="seller_payment_journal_creation"
model="account.journal">
<field name='name'>Seller Payment</field>
<field name='type'>purchase</field>
<field name='code'>SLP</field>
</record>
</odoo>

200
multi_vendor_marketplace/data/email_template_data.xml

@ -0,0 +1,200 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<!-- Mail templates for Admins when a new request comes -->
<record id="seller_request_admin_mail_template"
model="mail.template">
<field name="name">New Seller Request- Admin mail</field>
<field name="model_id"
ref="multi_vendor_marketplace.model_res_partner"/>
<field name="auto_delete" eval="True"/>
<field name="email_from">"{{ object.company_id.name }}" &lt;{{
(object.company_id.email or user.email) }}&gt;
</field>
<field name="email_to">{{object.company_id.email}}</field>
<field name="subject">New Seller request from {{
ctx['seller']}}
</field>
<field name="body_html" type="html">
<p>
Dear Admin,
<br/>
A new seller
<t t-out="ctx['seller']"/>
has been requested.
Please Approve or Reject.
</p>
</field>
</record>
<!-- Mail templates for Seller when a new request comes-->
<record id="seller_request_seller_mail_template"
model="mail.template">
<field name="name">New Seller Request- Seller mail</field>
<field name="model_id"
ref="multi_vendor_marketplace.model_res_partner"/>
<field name="auto_delete" eval="True"/>
<field name="email_from">{{object.company_id.email}}</field>
<field name="email_to">{{ctx['seller_mail']}}</field>
<field name="subject">Seller Request under progress</field>
<field name="body_html" type="html">
<p>
Dear Mr/Ms
<t t-out="ctx['seller']"/>
,
<br/>
You have requested for perform as a seller. Please
wait for
your approval.
</p>
</field>
</record>
<!-- Mail templates for Admins to inform the state of the seller-->
<record id="seller_state_admin_mail_template"
model="mail.template">
<field name="name">Seller Approve/Reject-Admin mail</field>
<field name="model_id"
ref="multi_vendor_marketplace.model_res_partner"/>
<field name="auto_delete" eval="True"/>
<field name="email_from">{{object.company_id.email}}</field>
<field name="email_to">{{object.company_id.email}}</field>
<field name="subject">Seller {{ object.name }} Status</field>
<field name="body_html" type="html">
<p>
Dear Admin,
<t t-if="object.state== 'Approved'">
<p>
New Seller
<t t-out="object.display_name"/>
has been approved by you
</p>
</t>
<t t-if="object.state== 'Denied'">
<p>
New Seller
<t t-out="object.display_name"/>
has been rejected by you
</p>
</t>
</p>
</field>
</record>
<!-- Mail templates for Seller to inform the state of the seller-->
<record id="seller_state_seller_mail_template"
model="mail.template">
<field name="name">Seller Approve/Reject- Seller mail</field>
<field name="model_id"
ref="multi_vendor_marketplace.model_res_partner"/>
<field name="auto_delete" eval="True"/>
<field name="email_from">{{object.company_id.email}}</field>
<field name="email_to">{{ object.email }}</field>
<field name="subject">Seller {{ object.name }} Status</field>
<field name="body_html" type="html">
<t t-if="object.state== 'Approved'">
<p>
Dear Mr/Ms<t t-out="object.display_name"/>,
<br/>
Congrats..! You have been approved to work as a
new
seller.
</p>
</t>
<t t-if="object.state== 'Denied'">
<p>
Dear Mr/Ms<t t-out="object.display_name"/>,
<br/>
Sorry, you have been rejected to work as a
seller.
</p>
</t>
</field>
</record>
<!-- Mail templates for Admins to inform the state of the product-->
<record id="product_state_admin_mail_template"
model="mail.template">
<field name="name">Product Approve/Reject - Admin mail
</field>
<field name="model_id"
ref="multi_vendor_marketplace.model_product_template"/>
<field name="auto_delete" eval="True"/>
<field name="email_from">{{object.company_id.email}}</field>
<field name="email_to">{{object.company_id.email}}</field>
<field name="subject">New product {{ object.name }} from {{
object.seller_id.name }}
</field>
<field name="body_html" type="html">
<t t-if="object.state== 'approved'">
<p>
Dear Admin,
<br/>
New Product
<t t-out="object.name"/>
request from
<t t-out="object.seller_id.name"/>
has been approved by you.
</p>
</t>
<t t-if="object.state== 'rejected'">
<p>
Dear Admin,
<br/>
New Product
<t t-out="object.name"/>
request from
<t t-out="object.seller_id.name"/>
has been rejected by you.
</p>
</t>
</field>
</record>
<!-- Mail templates for Seller to inform the state of the product-->
<record id="product_state_seller_mail_template"
model="mail.template">
<field name="name">Product Approve/Reject - Seller mail
</field>
<field name="model_id"
ref="multi_vendor_marketplace.model_product_template"/>
<field name="auto_delete" eval="True"/>
<field name="email_from">{{object.company_id.email}}</field>
<field name="email_to">{{ object.seller_id.email }}</field>
<field name="subject">Your new product {{ object.name }}
</field>
<field name="body_html" type="html">
<t t-if="object.state== 'approved'">
<p>
Dear Mr/Ms<t t-out="object.seller_id.name"/>,
<br/>
Congrats..!!
Your new Product
<t t-out="object.name"/>
is approved for sale.
</p>
</t>
<t t-if="object.state== 'rejected'">
<p>
Dear Mr/Ms<t t-out="object.seller_id.name"/>,
<br/>
Sorry.. Your new Product
<t t-out="object.name"/>
is not approved for sale
</p>
</t>
</field>
</record>
<!-- Mail templates for Seller to inform when a sale order comes-->
<record id="new_order_seller_mail_template"
model="mail.template">
<field name="name">New Sale Order - Seller mail</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="auto_delete" eval="True"/>
<field name="email_from">{{object.company_id.email}}</field>
<field name="email_to">{{ object.seller_id.email }}</field>
<field name="subject">SO {{ object.name }} created</field>
<field name="body_html" type="html">
<p>
Dear Mr/Ms<t t-out="object.display_name"/>,
<br/>
New Sale Order {{ object.name }} from your shop
</p>
</field>
</record>
</odoo>

11
multi_vendor_marketplace/data/ir_config_parameter_data.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo noupdate="1">
<!-- Data for config parameter model for the template-->
<record id="default_template_seller_user"
model="ir.config_parameter">
<field name="key">
multi_vendor_marketplace.template_seller_user
</field>
<field name="value" ref="template_seller_user"/>
</record>
</odoo>

10
multi_vendor_marketplace/data/product_template_data.xml

@ -0,0 +1,10 @@
<?xml version="1.0" ?>
<odoo noupdate="1">
<!--Creating products for seller-->
<record id="seller_payment_product_creation"
model="product.template">
<field name="name">seller payment</field>
<field name="categ_id" ref="product.product_category_all"/>
<field name="detailed_type">consu</field>
</record>
</odoo>

14
multi_vendor_marketplace/data/res_users_data.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo noupdate="1">
<!-- Seller User Template-->
<record id="template_seller_user" model="res.users">
<field name="name">Seller User Template</field>
<field name="login">Seller Template</field>
<field name="active" eval="False"/>
<field name="groups_id"
eval="[Command.set(
[ref(
'multi_vendor_marketplace.multi_vendor_marketplace_req_seller'),
ref('base.group_user'),ref('sales_team.group_sale_manager')])]"/>
</record>
</odoo>

33
multi_vendor_marketplace/data/social_media_data.xml

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo noupdate="1">
<!-- Data for facebook-->
<record id="fb" model="social.media">
<field name="name">Facebook</field>
<field name="base_url">https://www.facebook.com/</field>
</record>
<!-- Data for google-->
<record id="g+" model="social.media">
<field name="name">Google+</field>
<field name="base_url">https://plus.google.com</field>
</record>
<!-- Data for twitter-->
<record id="twitter" model="social.media">
<field name="name">Twitter</field>
<field name="base_url">https://twitter.com/</field>
</record>
<!-- Data for you tube-->
<record id="youtube" model="social.media">
<field name="name">YouTube</field>
<field name="base_url">https://youtube.com/user/</field>
</record>
<!-- Data for linkedin-->
<record id="linkedin" model="social.media">
<field name="name">LinkedIn</field>
<field name="base_url">https://linkedin.com/in/</field>
</record>
<!-- Data for instagram-->
<record id="insta" model="social.media">
<field name="name">Instagram</field>
<field name="base_url">https://instagram.com/</field>
</record>
</odoo>

10
multi_vendor_marketplace/data/website_menu_data.xml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<!-- Sell menu in the website-->
<record id="menu_sell" model="website.menu">
<field name="name">Sell</field>
<field name="url">/sell</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">10</field>
</record>
</odoo>

6
multi_vendor_marketplace/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module <multi_vendor_marketplace>
#### 14.11.2024
#### Version 16.0.1.0.0
#### ADD
- Initial commit for Odoo Multi Vendor Marketplace

41
multi_vendor_marketplace/models/__init__.py

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import helpful_info
from . import inventory_request
from . import multi_vendor_pricelist
from . import product_pricelist_item
from . import product_template
from . import res_config_settings
from . import res_partner
from . import request_payment
from . import res_users
from . import sale_order
from . import sale_order_line
from . import seller_payment
from . import seller_recommend
from . import seller_review
from . import social_media
from . import seller_shop
from . import stock_picking
from . import vendor_dashboard
from . import website
from . import website_menu

35
multi_vendor_marketplace/models/helpful_info.py

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class HelpfulInfo(models.Model):
"""Class for helpful information """
_name = 'helpful.info'
_description = "Help full Info"
customer_id = fields.Many2one('res.partner', string='Customer',
help='Customer')
msg = fields.Selection([('yes', 'Yes'), ('no', 'No')],
string='Was this review helpful?',
help='Message')
review_id = fields.Many2one('seller.review', string='Review',
help='Review')

89
multi_vendor_marketplace/models/inventory_request.py

@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
class InventoryRequest(models.Model):
"""Creating class inventoryRequest for requesting products"""
_name = 'inventory.request'
_description = "Inventory Request"
name = fields.Char(string='Title', required=True, help='Name of the '
'request')
product_id = fields.Many2one('product.template',
string='Product', help='Product name',
required=True)
seller_id = fields.Many2one(related='product_id.seller_id', help='Seller',
string='Seller')
qty_new = fields.Integer(string='New quantity',
help='New quantity on hand',
required=True)
location_id = fields.Many2one('stock.location',
string='Location', help='Location',
required=True)
date = fields.Datetime(string='Created Date', help='Date',
default=fields.Datetime.today())
note = fields.Text(string='Note', help='Note')
state = fields.Selection(
selection=[('Draft', 'Draft'), ('Requested', 'Requested'),
('Approved', 'Approved'), ('Rejected', 'Rejected')],
string='Inventory Req Status', group_expand='_group_expand_states',
help="For adding state", default='Draft', track_visibility='always',
readonly=True)
@api.onchange('name')
def _onchange_name(self):
""" Fetch location details from settings and search that id """
id_in_location_frm_settings = self.env[
'ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.seller_location_id')
id_in_location = self.env['stock.location'].browse(id_in_location_frm_settings)
self.location_id = id_in_location.id
def _group_expand_states(self):
"""Expands the selection options for the 'state' field in a group-by
operation."""
return [key for key, val in type(self).state.selection]
def approve_request(self):
""" Product request approve """
self.state = 'Approved'
product_ids = self.env['product.template'].browse(self.product_id.id)
products_ids = self.env['product.product'].browse(product_ids.id)
product_ids.qty_available = product_ids.qty_available + self.qty_new
self.env['stock.quant'].with_context(inventory_mode=True).create(
[{'product_id': products_ids.id,
'inventory_quantity': product_ids.qty_available,
'location_id': self.location_id.id,
}]).action_apply_inventory()
def reject_request(self):
""" Reject seller new product """
self.state = 'Rejected'
def request(self):
""" Used in seller for request to approve new product for selling """
if self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.quantity_approval'):
self.approve_request()
else:
self.state = 'Requested'

50
multi_vendor_marketplace/models/multi_vendor_pricelist.py

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
class MultiVendorPriceList(models.Model):
"""Create a new class MultiVendorPriceList for vendor price-list."""
_name = 'multi.vendor.pricelist'
_description = "Multi vendor pricelist"
price_list_id = fields.Many2one('product.pricelist',
string='Price list', help='Price list')
price_of_pricelist = fields.Float(required=True, String='Price',
help='Price')
min_qty = fields.Integer(required=True, string='Minimum quantity',
help='Minimum quantity')
start_date = fields.Date(required=True, string='Start Date',
help='Start Date')
end_date = fields.Date(required=True, string='Start Date',
help='Start Date')
product_inv_id = fields.Many2one('product.template',
string='Product', help='Product',
ondelete='cascade')
@api.ondelete(at_uninstall=False)
def delete_pricelist(self):
""" PRICE-LIST LINE DELETE FROM PRODUCT FORM VIEW AND
PRICE-LIST-VIEW """
query = """delete from product_pricelist_item where
pricelist_multivendor_id = %s """ % self.id
self.env.cr.execute(query)

40
multi_vendor_marketplace/models/product_pricelist_item.py

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, models, fields
class ProductPricelistItem(models.Model):
"""For deleting price-list items"""
_inherit = 'product.pricelist.item'
pricelist_multivendor_id = fields.Many2one(
'multi.vendor.pricelist',
string='Price list Item',
help='Price list items')
@api.ondelete(at_uninstall=False)
def delete_pricelist(self):
""" PRICE-LIST LINE DELETE FROM PRODUCT FORM VIEW AND PRICE-LISTVIEW
TRIGGER FROM PRICE-LIST VIEW """
query = (""" delete from multi_vendor_price-list where id = %s """ %
self.pricelist_multivendor_id.id)
self.env.cr.execute(query)

184
multi_vendor_marketplace/models/product_template.py

@ -0,0 +1,184 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
class ProductTemplate(models.Model):
"""Inheriting ProductTemplate For adding new fields and Functions"""
_inherit = "product.template"
website_category_id = fields.Many2one('product.public.category',
string='Website category',
help='Website category')
cmpy_email = fields.Text(
default=lambda self: self.env.user.company_id.email,
string='Company email',
help='Company address')
seller_id = fields.Many2one(
'res.partner', string='Seller',
help='Seller',
default=lambda self: self.env.user.partner_id.id,
domain=[('state', '=', 'Approved')])
seller_pic = fields.Binary(related='seller_id.image_1920',
string='Seller image', help='Seller image')
web = fields.Many2one("website", string="Website",
help='Website')
alt_pro_id = fields.Many2one("product.template",
string="Alternative Products",
help='Alternative Products')
acc_pro_id = fields.Many2one("product.template",
string="Accessory Products",
help='Accessory products')
forcasted_qty = fields.Integer(string='Forcasted quantity',
help='Forcasted quantity')
initial_qty = fields.Integer(string='Initial quantity',
help='Initial quantity')
state = fields.Selection(
[('draft', 'Draft'), ('pending', 'pending'),
('approved', 'Approved'), ('rejected', 'Rejected')],
string='Product Status', group_expand='_group_expand_states',
default='draft', help='Product Status', track_visibility='always',
readonly=True)
item_ids = fields.One2many('multi.vendor.pricelist',
'product_inv_id', string='Items',
help='Items')
product_price_setting = fields.Boolean(string='Product price setting',
help='Product price setting')
product_variants_setting = fields.Boolean(string='Product variants '
'settings',
help='Product variants settings')
product_uom = fields.Boolean(string='Product uom', help='Product uom')
def _create(self, data_list):
"""Supering the create function to change category """
res = super(ProductTemplate, self)._create(data_list)
self.categ_id = [self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.internal_categ_id')]
return res
def write(self, vals):
""" Pricelist Creation from Product form view """
res = super(ProductTemplate, self).write(vals)
for wdata in self.item_ids:
data_module = self.env['product.pricelist.item'].search(
[('pricelist_id', '=', wdata.price_list_id.id)])
if data_module:
dictionary = {}
dictionary.clear()
for data in data_module:
dictionary[data.pricelist_multivendor_id.id] = data
if wdata._origin.id in dictionary.keys():
dictionary[wdata._origin.id].update({
'product_tmpl_id': self._origin.id,
'min_quantity': wdata.min_qty,
'fixed_price': wdata.price_of_pricelist,
'date_start': wdata.start_date,
'date_end': wdata.end_date,
})
else:
wdata.price_list_id.write({'item_ids': [(0, 0, {
'product_tmpl_id': self._origin.id,
'min_quantity': wdata.min_qty,
'fixed_price': wdata.price_of_pricelist,
'date_start': wdata.start_date,
'date_end': wdata.end_date,
'pricelist_multivendor_id': wdata._origin.id
})]})
else:
wdata.price_list_id.write({'item_ids': [(0, 0, {
'product_tmpl_id': self._origin.id,
'min_quantity': wdata.min_qty,
'fixed_price': wdata.price_of_pricelist,
'date_start': wdata.start_date,
'date_end': wdata.end_date,
'pricelist_multivendor_id': wdata._origin.id
})]})
return res
def send_product_status_mail(self):
"""For sending product status mail"""
params = self.env[
'res.config.settings'].search([],
order='create_date desc', limit=1)
product_approve_admin_mail = params.product_approve_admin_mail
product_approve_seller_mail = params.product_approve_seller_mail
if product_approve_admin_mail:
name = params.product_approve_admin_mail_template_id.name
template = self.env['mail.template'].sudo().search(
[('name', '=', name)], limit=1)
self.env['mail.template'].browse(template.id).send_mail(
self.id, force_send=True)
if product_approve_seller_mail:
name = params.product_approve_seller_mail_template_id.name
template = self.env['mail.template'].sudo().search(
[('name', '=', name)], limit=1)
self.env['mail.template'].browse(
template.id).send_mail(self.id, force_send=True)
def change_state_approved(self):
""" Change product state to Approved when Admin approved """
self.state = 'approved'
self.send_product_status_mail()
self.product_price_setting = self.env[
'ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.product_pricing')
self.product_variants_setting = self.env[
'ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.product_variants')
self.product_uom = self.env[
'ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.uom')
@api.onchange('name')
def _onchange_name(self):
"""Automatically updates the product's internal category when the
product name is changed."""
internal_category = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.internal_categ_id')
self.categ_id = self.env['product.category'].browse(
internal_category).id
def change_state_pending(self):
""" CHANGE PRODUCT TO PENDING STATE WHEN USER SEND REQUEST FOR
PRODUCT """
if self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.product_approval'):
self.state = 'approved'
self.sudo().send_product_status_mail()
else:
self.state = 'pending'
self.sudo().send_product_status_mail()
def change_state_reject(self):
""" WHEN ADMIN REJECT THE PRODUCT REQUEST STATE CHANGE TO REJECTED """
self.state = 'rejected'
self.send_product_status_mail()
def toggle_website_published(self):
""" PUBLISH THE PRODUCT IN WEBSITE """
self.is_published = not self.is_published
def _group_expand_states(self):
"""Expands the selection options for the 'state' field in a group-by
operation."""
return [key for key, val in type(self).state.selection]

81
multi_vendor_marketplace/models/request_payment.py

@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class RequestPayment(models.Model):
"""Create a RequestPayment class for request for payment"""
_name = 'request.payment'
seller_id = fields.Many2one('res.partner', string='Seller',
required=True, help='Seller', default=lambda
self: self.env.user.partner_id.id)
cashable_amount = fields.Float(string='Commission', help='Commission',
readonlt=True)
request_amount = fields.Float(string='Requested Payment Amount',
help='Requested Amount', required=True)
payment_description = fields.Text(string='Payment Description',
help='Payment Description',
required=True)
@api.onchange('seller_id')
def onchange_seller(self):
""" Display commission in seller profile tab """
partner_id = self.env['res.partner'].browse(self.seller_id.id)
self.cashable_amount = partner_id.commission
def request_payment(self):
""" Request payment """
amount_limit = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.amt_limit')
min_gap = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.min_gap')
partner_id = self.env['res.partner'].search(
[('id', '=', self.seller_id.id)])
today_date = fields.Date.today()
mingap_date = fields.Date.subtract(today_date, days=int(min_gap))
date_info_record = self.env['seller.payment'].search(
[('seller_id', '=', self.seller_id.id),
('state', '=', 'Validated'), ('date', '>=', mingap_date)],
order='date DESC')
for checkdate in date_info_record:
if (self.request_amount > partner_id.total_commission or
self.request_amount > int(amount_limit) or
checkdate.date >= mingap_date):
raise ValidationError(
_("Entered amount is greater than your commission or "
"Amount limit is " + amount_limit + " and Minimum gap "
"for next payment "
"request " +
min_gap + " days"))
break
self.env['seller.payment'].create({
'seller_id': self.seller_id.id,
'payment_mode': 'Cash',
'commission': partner_id.commission,
'payable_amount': self.request_amount,
'date': fields.Date.today(),
'type_id': 1,
'memo': self.payment_description,
'state': 'Requested',
})

290
multi_vendor_marketplace/models/res_config_settings.py

@ -0,0 +1,290 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
class ResConfigSettings(models.TransientModel):
"""Inheriting ResConfigSettings to add fields and functions"""
_inherit = 'res.config.settings'
seller_approval = fields.Boolean(
string='Seller Approval',
help='Seller Approval',
config_parameter='multi_vendor_marketplace.seller_approval')
quantity_approval = fields.Boolean(
string='Quantity Approval',
help='Quantity Approval',
config_parameter='multi_vendor_marketplace.quantity_approval')
product_approval = fields.Boolean(
string='Product Approval',
help='Product Approval',
config_parameter='multi_vendor_marketplace.product_approval')
internal_categ_id = fields.Many2one(
'product.category',
required=True,
string='Internal category',
help='Internal category',
config_parameter='multi_vendor_marketplace.internal_categ_id',
default=lambda self: self.env.ref(
'product.product_category_all'))
product_variants = fields.Boolean(
string='Product variants',
help='Product variants',
config_parameter='multi_vendor_marketplace.product_variants')
@api.onchange('product_variants')
def _onchange_product_variants(self):
"""Changing the product variants settings"""
for data in self.env['product.template'].search([]):
data.product_variants_setting = self.product_variants
product_pricing = fields.Boolean(
string='Product Price',
help='Product Price',
config_parameter='multi_vendor_marketplace.product_pricing')
@api.onchange('product_pricing')
def _onchange_product_pricing(self):
"""Changing the product price settings"""
for data in self.env['product.template'].search([]):
data.product_price_setting = self.product_pricing
uom = fields.Boolean(string='UOM', help='Units of Measurement',
config_parameter='multi_vendor_marketplace.uom')
@api.onchange('uom')
def _onchange_uom(self):
"""Changing product uom"""
for data in self.env['product.template'].search([]):
data.product_uom = self.uom
seller_location_id = fields.Many2one(
'stock.location',
string='Location', required=True,
help='Location',
config_parameter='multi_vendor_marketplace.seller_location_id',
default=lambda self: self.env.ref(
'stock.stock_location_stock'))
seller_warehouse_id = fields.Many2one(
'stock.warehouse',
string='Warehouse', help='Warehouse',
required=True,
config_parameter='multi_vendor_marketplace.seller_warehouse_id',
default=lambda self: self.env.ref(
'stock.warehouse0'))
seller_shop = fields.Boolean(
string='Seller shop', help='Seller shop',
config_parameter='multi_vendor_marketplace.seller_shop')
commission = fields.Float(
string='Seller shop', help='Seller shop',
default=2,
config_parameter='multi_vendor_marketplace.commission')
currency = fields.Many2one(
'res.currency',
string='Marketplace Currency',
help='Marketplace Currency',
config_parameter='multi_vendor_marketplace.currency',
required=True, default=lambda self: self.env.company.currency_id)
amt_limit = fields.Integer(
string='Amount limit', help='Amount limit',
config_parameter='multi_vendor_marketplace.amt_limit')
min_gap = fields.Integer(
string='Minimum Gap', help='Minimum Gap',
config_parameter='multi_vendor_marketplace.min_gap',
default='2')
pay_journal = fields.Many2one(
'account.journal',
string='Seller Payment Journal',
help='Seller Payment Journal',
config_parameter='multi_vendor_marketplace.pay_journal',
default=lambda self: self.env.ref(
'multi_vendor_marketplace.seller_payment_journal_creation'))
pay_product = fields.Many2one(
'product.product',
string='Payment Product',
help='Payment Product',
config_parameter='multi_vendor_marketplace.pay_product',
default=lambda self: self.env.ref(
'multi_vendor_marketplace.seller_payment_product_creation'))
seller_request_admin_mail = fields.Boolean(
string='Mail notification',
help='Enable notification for '
'Admin',
config_parameter='multi_vendor_marketplace.seller_request_admin_mail')
seller_request_admin_mail_template_id = fields.Many2one(
'mail.template',
string='Email Template',
help='Email Template',
config_parameter=
'multi_vendor_marketplace.seller_request_admin_mail_template_id',
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id(
'multi_vendor_marketplace.seller_request_admin_mail_template'),
required=True)
seller_request_seller_mail = fields.Boolean(
string='Seller notification', help='Enable notification for Seller',
config_parameter='multi_vendor_marketplace.seller_request_seller_mail')
seller_request_seller_mail_template_id = fields.Many2one(
'mail.template',
string='Email Template',
help='Email template',
config_parameter=
'multi_vendor_marketplace.seller_request_seller_mail_template_id',
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id(
'multi_vendor_marketplace.seller_request_seller_mail_template'),
required=True, )
seller_approve_admin_mail = fields.Boolean(
string='Admin notification',
help='Enable notification for Admin',
config_parameter='multi_vendor_marketplace.seller_approve_admin_mail')
seller_approve_admin_mail_template_id = fields.Many2one(
'mail.template',
string='Email Template', help='Email template',
config_parameter=
'multi_vendor_marketplace.seller_approve_admin_mail_template_id',
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id(
'multi_vendor_marketplace.seller_state_admin_mail_template'),
required=True)
seller_approve_seller_mail = fields.Boolean(
'Enable notification for Seller',
config_parameter='multi_vendor_marketplace.seller_approve_seller_mail')
seller_approve_seller_mail_template_id = fields.Many2one(
'mail.template', string='Email Template',
help='Email Template',
config_parameter=
'multi_vendor_marketplace.seller_approve_seller_mail_template_id',
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id(
'multi_vendor_marketplace.seller_state_seller_mail_template'),
required=True)
product_approve_admin_mail = fields.Boolean(
string='Admin Notification', help='Enable notification for Admin',
config_parameter='multi_vendor_marketplace.product_approve_admin_mail')
product_approve_admin_mail_template_id = fields.Many2one(
'mail.template', 'Email Template',
config_parameter=
'multi_vendor_marketplace.product_approve_admin_mail_template_id',
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id(
'multi_vendor_marketplace.product_state_admin_mail_template'),
required=True)
product_approve_seller_mail = fields.Boolean(
'Enable notification for Seller',
config_parameter='multi_vendor_marketplace.product_approve_seller_mail')
product_approve_seller_mail_template_id = fields.Many2one(
'mail.template', 'Email Template',
config_parameter=
'multi_vendor_marketplace.product_approve_seller_mail_template_id',
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id(
'multi_vendor_marketplace.product_state_seller_mail_template'),
required=True)
new_order_seller_mail = fields.Boolean(
'Enable notification for Seller',
config_parameter='multi_vendor_marketplace.new_order_admin_mail')
new_order_seller_mail_template_id = fields.Many2one(
'mail.template', 'Email Template',
config_parameter=
'multi_vendor_marketplace.new_order_admin_mail_template_id',
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id(
'multi_vendor_marketplace.new_order_seller_mail_template'),
required=True)
prod_count = fields.Boolean('Product Count',
config_parameter=
'multi_vendor_marketplace.prod_count')
sale_count = fields.Boolean(
config_parameter='multi_vendor_marketplace.sale_count')
seller_addr = fields.Boolean('Seller Address',
config_parameter=
'multi_vendor_marketplace.seller_addr')
seller_since = fields.Boolean(
config_parameter='multi_vendor_marketplace.seller_since')
ret_policy = fields.Boolean('Return Policy',
config_parameter=
'multi_vendor_marketplace.ret_policy')
ship_policy = fields.Boolean('Shipping Policy',
config_parameter=
'multi_vendor_marketplace.ship_policy')
shop_tnc = fields.Boolean('Seller Shop Terms & Conditions',
config_parameter=
'multi_vendor_marketplace.shop_tnc')
contact_seller_button = fields.Boolean(
'Contact Seller Button',
config_parameter='multi_vendor_marketplace.contact_seller_button')
bcome_seller = fields.Boolean('Become a Seller Button',
config_parameter=
'multi_vendor_marketplace.bcome_seller')
recent_products = fields.Integer('Recently Added Products',
config_parameter=
'multi_vendor_marketplace.recent_products')
show_seller_review = fields.Boolean(
config_parameter=
'multi_vendor_marketplace.show_seller_review')
auto_publish_seller_review = fields.Boolean(
config_parameter=
'multi_vendor_marketplace.auto_publish_seller_review')
seller_review_count = fields.Integer(
'Display Seller Reviews',
config_parameter=
'multi_vendor_marketplace.seller_review_count')
show_sell_menu_header = fields.Boolean(
'Sell Menu on Header',
config_parameter=
'multi_vendor_marketplace.show_sell_menu_header')
show_sell_menu_footer = fields.Boolean(
'Sell Menu on Footer',
config_parameter=
'multi_vendor_marketplace.show_sell_menu_footer')
show_sellers_list = fields.Boolean(
'Sellers List',
config_parameter=
'multi_vendor_marketplace.show_sellers_list')
sell_link_label = fields.Char(
config_parameter=
'multi_vendor_marketplace.sell_link_label')
seller_list_link_label = fields.Char(
config_parameter=
'multi_vendor_marketplace.seller_list_link_label')
seller_shop_list_link_label = fields.Char(
config_parameter=
'multi_vendor_marketplace.seller_shop_list_link_label')
new_status_msg = fields.Text('For New Satus', )
pending_status_msg = fields.Text('For Pending Satus')
image = fields.Binary('Landing page banner',
related='website_id.seller_banner',
readonly=False)
show_t_and_c = fields.Boolean('Marketplace Terms and Conditions',
config_parameter=
'multi_vendor_marketplace.show_t_and_c')
def set_values(self):
"""Supering the function to set the values"""
super(ResConfigSettings, self).set_values()
set_param = self.env['ir.config_parameter'].sudo().set_param
set_param('res.config.settings.new_status_msg', self.new_status_msg)
set_param('res.config.settings.pending_status_msg',
self.pending_status_msg)
set_param('res.config.settings.pay_journal', self.pay_journal)
@api.model
def get_values(self):
"""Supering the function to get the values"""
res = super(ResConfigSettings, self).get_values()
get_param = self.env['ir.config_parameter'].sudo().get_param
res['new_status_msg'] = get_param('res.config.settings.new_status_msg')
res['pending_status_msg'] = get_param(
'res.config.settings.pending_status_msg')
res['pay_journal'] = get_param('res.config.settings.pay_journal')
return res

344
multi_vendor_marketplace/models/res_partner.py

@ -0,0 +1,344 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
class ResPartner(models.Model):
""" Inheriting partner to add sellers,marketplace and commission
information etc"""
_inherit = 'res.partner'
profile_url = fields.Char(string='Profile Url', help="Url of the Profile")
allow_product_variant = fields.Boolean(
string='Allow Product Variant',
help="True if access product variant")
payment_method_ids = fields.Many2many('account.payment.method',
string="Payment Methods",
help="For accessing payment methods")
total_amount = fields.Float(string='Total Amount',
help="Total amount by the seller")
balance_amount = fields.Float(string='Balance Amount',
hrlp="Amount balance for the seller")
paid_amount = fields.Float(string='Paid Amount', help="Amount total paid")
market_place_currency = fields.Monetary(string="Market Place Currency",
help="Currency for the "
"marketplace ")
currency_id = fields.Many2one("res.currency",
string="Currency",
help="Currency",
default=lambda self: self.env
['res.currency'].search([
('name', '=', 'USD')]).id,
readonly=True, hide=True)
return_policy = fields.Html(string='Return Policies',
help="Product return policy for seller")
shipping_policy = fields.Html(string='Shipping Policies',
help="Product shipping policy can be set")
profile_image = fields.Binary(string='Profile Image',
help="Profile image in the website")
profile_banner = fields.Binary(string='Profile Banner',
help="Profile banner for the seller")
profile_message = fields.Html(string="profile Message",
help="Profile message for the seller")
sale_count = fields.Integer(compute='_compute_sale_count',
sting="Sale Count",
help="For getting total sale count for seller")
amount_available = fields.Float(compute='_compute_amount_available',
string="Amount available")
avg_rating = fields.Float(compute='_compute_avg_rating',
string="Average rating",
help="Average rating received by the seller")
recommend_count = fields.Float(compute='_compute_recommend_count',
string="Recommended count of the seller",
help="Total recommended count of the seller")
is_publish = fields.Boolean(string="Is publish", help="Check if it is "
"Published")
publish = fields.Boolean(string="publish", help="Published")
seller_shop_id = fields.Many2one('seller.shop',
string="Seller shop",
help="Seller shop details", domain="[('seller_id', '=', id)]")
state = fields.Selection(
selection=[('new', 'New'),
('Pending for Approval', 'Pending for Approval'),
('Approved', 'Approved'), ('Denied', 'Denied')],
default="new",
string='Seller Status', help="The status of the seller",
group_expand='_group_expand_states',
track_visibility='always')
default_commission = fields.Float(string='Default Sale Commission(%)',
help="For getting the default commission")
amount_limit = fields.Float(
string='Amount limit for seller payment request',
help="Amount limit to be set for the seller payment request")
min_gap = fields.Integer(string='Minimum gap for next payment request',
help="Minimum gap for the next payment request")
auto_product_approve = fields.Boolean(string="Auto Product Approve",
help="Automatically approve"
"for product for sellers")
auto_quality_approve = fields.Boolean()
location_id = fields.Many2one('stock.location',
string='Default Location',
help="For getting stock location in "
"warehouse")
warehouse_id = fields.Many2one('stock.warehouse',
string='Default Warehouse',
help="For getting default warehouse")
total_commission = fields.Float(string="Total commission",
help="Total commission for the seller")
commission = fields.Float(string="Commission",
help="For getting commission percentage")
profile_url_value = fields.Char(string='Profile Url Value',
help="profile url value")
def req_approve(self):
""" New user requested for approve to sell products """
auto_approval = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.seller_approval')
if auto_approval:
self.sudo().approve_seller()
self.state = 'Approved'
else:
self.state = 'Pending for Approval'
def user_my_profile(self):
""" Fetch user profile """
return {
'type': 'ir.actions.act_window',
'name': 'My Profile',
'res_model': 'res.partner',
'view_mode': 'form',
'res_id': self.env['res.users'].broswe(
self.env.user.id).partner_id.id,
'target': 'new',
}
def new_user_my_profile(self):
""" Fetch user profile """
user_id = self.env['res.users'].search([('id', '=', self.env.user.id)])
return {
'type': 'ir.actions.act_window',
'name': 'My Profile',
'res_model': 'res.partner',
'view_mode': 'form',
'res_id': user_id.partner_id.id,
}
def publish(self):
""" Publish user profile in website seller list """
if not self.is_published:
self.is_published = True
else:
self.is_published = False
def view_settings(self):
""" View default settings for sellers """
commission_value = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.commission')
min_gap_value = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.min_gap')
amt_limit_value = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.amt_limit')
return {
'name': 'Default Settings',
'res_model': 'settings.view',
'type': 'ir.actions.act_window',
'view_mode': 'form',
'view_type': 'form',
'target': 'new',
'context': dict(
self.env.context,
default_commission=commission_value,
default_amt_limit=amt_limit_value,
default_minimum_gap=min_gap_value,
),
}
def approve(self):
""" Seller approve state also changed """
self.state = 'Approved'
def _group_expand_states(self):
"""Returns a list of states"""
return [key for key, val in type(self).state.selection]
def register_payment(self):
""" fast payment request form """
return {
'name': 'Payment Request',
'domain': [],
'res_model': 'request.payment',
'type': 'ir.actions.act_window',
'view_mode': 'form',
'view_type': 'form',
'context': {},
'target': 'new',
}
@api.model
def create(self, vals):
res = super(ResPartner, self).create(vals)
params = self.env[
'res.config.settings'].search([],
order='create_date desc', limit=1)
context = {'seller': vals['name'], }
if params.seller_request_admin_mail:
name = params.seller_request_admin_mail_template_id.name
template = self.env['mail.template'].sudo().search(
[('name', '=', name)], limit=1)
self.env['mail.template'].browse(template.id).with_context(
context).send_mail(self.id, force_send=True)
if params.seller_request_seller_mail:
name = params.seller_request_seller_mail_template_id.name
template = self.env['mail.template'].sudo().search(
[('name', '=', name)], limit=1)
self.env['mail.template'].browse(template.id).with_context(
context).send_mail(self.id,
force_send=True)
return res
def send_seller_status_mail(self):
"""Send the seller status email"""
params = self.env[
'res.config.settings'].sudo().search([],
order='create_date desc',
limit=1)
if params.sudo().seller_approve_admin_mail:
name = params.sudo().seller_approve_admin_mail_template_id.name
template = self.env['mail.template'].sudo().search(
[('name', '=', name)], limit=1)
self.env['mail.template'].sudo().browse(
template.id).send_mail(self.id, force_send=True)
if params.sudo().seller_approve_seller_mail:
name = params.sudo().seller_approve_seller_mail_template_id.name
template = self.env['mail.template'].sudo().search(
[('name', '=', name)], limit=1)
self.env['mail.template'].sudo().browse(
template.id).send_mail(self.id, force_send=True)
def approve_seller(self):
"""Approve the seller"""
user1 = self.env["res.users"].search([("name", "=", self.name)])
internal = self.env.ref('base.group_user')
stock_group = self.env.ref('stock.group_stock_user')
sale_group = self.env.ref('sales_team.group_sale_manager')
seller_user = self.env.ref(
"multi_vendor_marketplace.multi_vendor_marketplace_seller")
user1.sudo().write({'groups_id': [(6, 0, [
internal.id,
seller_user.id,
stock_group.id,
sale_group.id
])]})
result = self.env.ref('sales_team.group_sale_salesman')
result1 = self.env.ref('sales_team.group_sale_salesman_all_leads')
for user in result.users:
if user in user1:
result.write({'users': [(3, user.id, 0)]})
for user in result1.users:
if user in user1:
result1.write({'users': [(3, user.id, 0)]})
if self.state == 'Pending for Approval':
self.state = 'Approved'
self.send_seller_status_mail()
def reject_seller(self):
"""Change the state to denied"""
self.state = 'Denied'
self.send_seller_status_mail()
def create_shop(self):
"""Create a new shop"""
return {
'name': 'Seller Shop',
'domain': [],
'res_model': 'seller.shop',
'type': 'ir.actions.act_window',
'view_mode': 'form',
'view_type': 'form',
'target': 'new',
}
def _group_expand_states(self):
""" For expanding the values for selection field """
return [key for
key, val in type(self).state.selection]
def _compute_sale_count(self):
""" count seller sale count and display in the profile """
for record in self:
record.sale_count = self.env['sale.order.line'].search_count(
[('seller_id', '=', self.id)])
def _compute_amount_available(self):
""" display available amount in seller profile """
for avl_amt in self:
avl_amt.amount_available = self.commission
def view_sale_order(self):
""" view sale order from seller profile """
return {
'type': 'ir.actions.act_window',
'name': 'Orders',
'view_mode': 'kanban,form',
'res_model': 'sale.order.line',
'domain': [('seller_id', '=', self.id)],
}
def _compute_avg_rating(self):
"""Compute the rating of seller"""
for record in self:
count = self.env['seller.review'].search_count(
[('seller_id', '=', record.id)])
if count:
record.avg_rating = sum_rating = 0.0
for rec in self.env['seller.review'].search([('seller_id', '=',
record.id)]):
sum_rating += rec.rating
record.avg_rating += sum_rating / count
else:
record.avg_rating = 0
def view_rating(self):
"""Return the seller review"""
return {
'type': 'ir.actions.act_window',
'name': 'Rating in Review',
'view_mode': 'tree,form',
'res_model': 'seller.review',
'domain': [('seller_id', '=', self.id)],
}
def _compute_recommend_count(self):
"""Compute recommendations"""
for record in self:
record.recommend_count = self.env['seller.recommend'].search_count(
[('seller_id', '=', record.id), ('recommend', '=', 'yes')])
def view_recommend(self):
"""Return the number of recommendations"""
return {
'type': 'ir.actions.act_window',
'name': 'Recommendations',
'view_mode': 'kanban',
'res_model': 'seller.recommend',
'domain': [('seller_id', '=', self.id), ('recommend', '=', 'yes')],
}

57
multi_vendor_marketplace/models/res_users.py

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from ast import literal_eval
from odoo import fields, models, _
from odoo.tools.misc import ustr
from odoo.addons.auth_signup.models.res_partner import SignupError, now
class ResUsers(models.Model):
""" Added shop information and user creation from website"""
_inherit = 'res.users'
profile_url = fields.Integer(string='Shop Url', help='Shop url')
def _create_user_from_template(self, values):
""" Creating user through the website"""
if values['profile_url'] != 0:
template_user_id = self.env.ref(
'multi_vendor_marketplace.template_seller_user').id
else:
template_user_id = literal_eval(
self.env['ir.config_parameter'].sudo().get_param(
'base.template_portal_user_id', 'False'))
template_user = self.browse(template_user_id)
if not template_user.exists():
raise ValueError(_('Signup: invalid template user'))
if not values.get('login'):
raise ValueError(_('Signup: no login given for new user'))
if not values.get('partner_id') and not values.get('name'):
raise ValueError(
_('Signup: no name or partner given for new user'))
values['active'] = True
try:
with self.env.cr.savepoint():
return template_user.with_context(no_reset_password=True).copy(
values)
except Exception as e:
raise SignupError(ustr(e))

92
multi_vendor_marketplace/models/sale_order.py

@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class SaleOrder(models.Model):
""" Added product information to the sale order """
_inherit = 'sale.order'
product_id = fields.Many2one('product.template',
string="Product",
help="For getting product information "
"on the order")
seller_id = fields.Many2one('res.partner', readonly=True,
string="Seller",
help="Seller details",
related='product_id.seller_id')
quantity = fields.Float(related='order_line.product_uom_qty',
string="Quantity", help="Getting product quantity",
readonly=False)
qty_delivered = fields.Float(related='order_line.qty_delivered',
string="Quantity Delivered ",
help="Getting delivered quantity",
readonly=False)
state = fields.Selection(selection_add=[('pending', 'Pending'),
('approved', 'Approved'),
('shipped', 'Shipped'),
('cancel', 'Cancel')],
string="state", help="State of the sale order")
unit_price = fields.Float(related='order_line.price_unit',
string="Unit Price",
help="Unit price of the product", readonly=False)
discount = fields.Float(related='order_line.discount', string="Discount",
help="Discount applied on the order line",
readonly=False)
subtotal = fields.Monetary(related='order_line.price_subtotal',
string="Subtotal",
help="Getting subtotal amount", readonly=False)
create_date = fields.Datetime(string="Create Date",
help="Date of the record creation",
default=fields.Datetime.today(),
readonly=False)
description = fields.Text(string="Description",
help="Adding description on the product")
def action_confirm(self):
""" Super sale order confirm function and add to commission based on
settings commission value"""
res = super(SaleOrder, self).action_confirm()
self.state = 'pending'
for rec in self.order_line:
if rec.product_id.seller_id.default_commission:
partner_ids = self.env['res.partner'].search(
[('id', '=', rec.product_id.seller_id.id)])
partner_ids.total_commission = (
partner_ids.total_commission + rec.price_subtotal * (
rec.product_id.seller_id.default_commission / 100))
partner_ids.commission = (
partner_ids.total_commission + rec.price_subtotal * (
rec.product_id.seller_id.default_commission / 100))
else:
commission = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.commission')
commission_value = float(commission)
partner_ids = self.env['res.partner'].search(
[('id', '=', rec.product_id.seller_id.id)])
partner_ids.total_commission = (
partner_ids.total_commission + rec.price_subtotal * (
commission_value / 100))
partner_ids.commission = (
partner_ids.total_commission + rec.price_subtotal * (
rec.product_id.seller_id.default_commission / 100))
return res

107
multi_vendor_marketplace/models/sale_order_line.py

@ -0,0 +1,107 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class SaleOrder(models.Model):
""" Added seller information"""
_inherit = 'sale.order.line'
seller_id = fields.Many2one('res.partner', readonly=True,
string="Seller",
help="For getting seller information",
related='product_id.seller_id')
partner_id = fields.Many2one('res.partner',
related='order_id.partner_id',
string="Customer",
Help="Get the partner information")
state = fields.Selection(selection=[('pending', 'Pending'),
('approved', 'Approved'),
('shipped', 'Shipped'),
('cancel', 'Cancel')], string="State",
help="Get the approval states")
def cancel_order(self):
""" Function to cancel the current order from order line"""
self.state = 'cancel'
def approve_order(self):
""" Approve sale order and change to state in approved only in seller
order view and its created new delivery form for that product """
data_stock_pick = self.env['stock.picking'].sudo().search(
[('origin', '=', self.order_id.name)])
partner_id = data_stock_pick.partner_id
opr_type = data_stock_pick.picking_type_id
location_id = data_stock_pick.location_id
location_dst_id = data_stock_pick.location_dest_id
name = data_stock_pick.name
vals = []
qty_info = self.env['stock.quant'].search(
[('product_id', '=', self.product_id.id), ('location_id', '=', 8)])
if qty_info.quantity <= self.product_uom_qty:
qty_reserved = self.product_uom_qty
else:
qty_reserved = qty_info.quantity
vals.append({'product_id': self.product_id,
'product_uom_qty': self.product_uom_qty,
'forecast_availability': qty_reserved,
'location_id': location_id,
'location_dest_id': location_dst_id,
'name': name})
if data_stock_pick.state != 'cancel':
data_stock_pick.state = 'cancel'
new_rec = self.env['stock.picking'].create({
'partner_id': partner_id.id,
'picking_type_id': opr_type.id,
'seller_id': self.seller_id.id,
'move_ids_without_package': vals,
'origin': ' ' + self.order_id.name,
})
new_rec.update({
'ref_id': self.id
})
new_rec.state = 'assigned'
self.state = 'approved'
else:
new_rec = self.env['stock.picking'].create({
'partner_id': partner_id.id,
'picking_type_id': opr_type.id,
'move_ids_without_package': vals,
'origin': ' ' + self.order_id.name,
})
new_rec.update({
'ref_id': self.id
})
new_rec.state = 'assigned'
self.state = 'approved'
def shipped(self):
""" Redirect to delivery form for validating """
stock_picking_record = self.env['stock.picking'].search(
[('ref_id', '=', self.id)])
return {
'type': 'ir.actions.act_window',
'name': 'Stock Picking',
'res_model': 'stock.picking',
'view_mode': 'form',
'res_id': stock_picking_record.id,
}

151
multi_vendor_marketplace/models/seller_payment.py

@ -0,0 +1,151 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
from odoo.http import request
class SellerPayment(models.Model):
""" Managing seller payments"""
_name = 'seller.payment'
_description = "Seller Payment"
name = fields.Char(string='Record Reference', required=True,
help="Sequence of the payment", readonly=True,
default='New')
seller_id = fields.Many2one(
'res.partner', string='Seller',
required=True,
default=lambda self: self.env.user.partner_id.id,
help="Seller details")
payment_mode = fields.Selection(
selection=[('Cash', 'Cash'),
('Bank', 'Bank')],
string="Payment Mode",
help="To select the mode of payment",
required=True, default='Cash')
memo = fields.Char(string='Memo', help="Description", required=True)
payable_amount = fields.Float(string='Payable Amount', help="Total amount",
required=True)
date = fields.Date(string='Payment Date', required=True,
help="Date of the payment", default=fields.Date.today)
type_id = fields.Many2one('account.payment.method',
string='Type', help="Payment method",
required=True)
invoice_cashable = fields.Boolean(string='Invoice Cashable',
help="Total amount that to invoice")
description = fields.Text(string='Description', help="Description")
commission = fields.Float(string="Commission",
help="Total commission amount")
state = fields.Selection(selection=[('Draft', 'Draft'),
('Requested', 'Requested'),
('Validated', 'Validated'),
('Rejected', 'Rejected'),
('cancelled', 'Cancelled')],
string="state",
help="State of the seller payment",
default="Draft")
def request(self):
""" Request for payment and check payment term settings values """
self.state = 'Requested'
amount_limit = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.amt_limit')
min_gap = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.min_gap')
partner_id = self.env['res.partner'].search(
[('id', '=', self.seller_id.id)])
today_date = fields.Date.today()
mingap_date = fields.Date.subtract(today_date, days=int(min_gap))
date_info_record = self.env['seller.payment'].search(
[('seller_id', '=', self.seller_id.id),
('state', '=', 'Validated'), ('date', '>=', mingap_date)],
order='date DESC')
for checkdate in date_info_record:
if (self.payable_amount > partner_id.total_commission
or self.payable_amount > int(
amount_limit) or checkdate.date >= mingap_date):
raise ValidationError(
_("Entered amount is greater than your commission or "
"Amount limit is " + amount_limit + " and Minimum gap "
"for next payment request " + min_gap + " days"))
break
def reject(self):
""" Payment request will reject """
self.state = 'Rejected'
def cancel(self):
""" Payment request will cancel """
self.state = 'cancelled'
def validate(self):
""" Payment request will validte and substarct that amount
from commission """
self.state = 'Validated'
params = request.env['ir.config_parameter'].sudo()
partner_id = self.env['res.partner'].search(
[('id', '=', self.seller_id.id)])
if self.payable_amount < partner_id.commission:
raise ValidationError(
_("Entered amount is greater than the commission"))
product = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.pay_product')
currency = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.currency')
currency_id = self.env['res.currency'].search([('id', '=', currency)])
self.env['account.move'].create({
'move_type': 'in_invoice',
'partner_id': self.seller_id.id,
'ref': self.seller_id.profile_url,
'invoice_date': self.date,
'invoice_payment_term_id': 1,
'currency_id': currency_id.id,
'journal_id': 3,
'invoice_line_ids':
[(0, 0,
{
'product_id': product,
'name': self.memo,
'quantity': 1,
'price_unit': self.payable_amount,
'currency_id': currency_id.id,
'tax_ids': False,
})]
})
partner_id.commission = partner_id.commission - self.payable_amount
@api.onchange('seller_id')
def onchange_seller(self):
""" For getting default commission"""
partner_id = self.env['res.partner'].search(
[('id', '=', self.seller_id.id)])
self.commission = partner_id.commission
@api.model
def create(self, vals):
""" For getting the sequence number"""
if vals.get('name', 'New'):
vals['name'] = self.env['ir.sequence'].next_by_code(
'seller.payment')
res = super(SellerPayment, self).create(vals)
return res

65
multi_vendor_marketplace/models/seller_recommend.py

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
class SellerRecommend(models.Model):
"""Managing Seller Recommendations"""
_name = 'seller.recommend'
_description = 'Seller Recommendation'
_rec_name = 'partner_id'
_inherit = 'mail.thread'
partner_id = fields.Many2one('res.partner', string="Customer",
help="For getting customer name",
required=True)
seller_id = fields.Many2one('res.partner', string="Seller",
help="For getting seller name", required=True)
recommend = fields.Selection(selection=[('no', 'NO'), ('yes', 'YES')],
default='NO', track_visibility='always')
date = fields.Date(string="Date", help="Storing date",
default=fields.Date.today, required=True)
state = fields.Selection(selection=[('unpublished', 'Unpublished'),
('published', 'Published')],
string='Status',
help="Status of the Recommendation",
default='unpublished', track_visibility='always')
@api.model
def recommend_func(self, vals):
"""Create or update the recommendation for the seller by customers"""
check = self.search([('seller_id', '=', int(vals['seller_id'])),
('customer_id', '=', int(vals['customer_id']))])
if check:
check.write({'recommend': vals['recommend']})
else:
return super(SellerRecommend, self).create(vals)
def action_publish(self):
""" Function to change the state when publish the seller
recommendation"""
self.write({'state': "published"})
def action_unpublish(self):
""" Function to change the state when the seller recommendation
got unpublished """
self.write({'state': "unpublished"})

115
multi_vendor_marketplace/models/seller_review.py

@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
class SellerReview(models.Model):
"""Managing Seller Reviews"""
_name = 'seller.review'
_description = 'Seller Review'
_rec_name = 'review_title'
_inherit = 'mail.thread'
seller_id = fields.Many2one('res.partner', string="Seller",
help="Getting seller name",
required=True)
customer_id = fields.Many2one('res.partner', required=True,
string="Customer",
help="Getting partner name")
customer_email = fields.Char(related='customer_id.email',
string="Email", help="Getting customer email")
rating = fields.Float(string="Rating", help="Getting rating",
required=True)
review_title = fields.Char(string="Review Title",
help="Title of the review")
date = fields.Date(string="Date", help="Date field",
default=fields.Date.today)
message = fields.Text(string="Message",
help="Field to enter the review text", size=150)
like_count = fields.Integer(string='Helpful Count',
help="Count of the positive review",
compute='_compute_count')
unlike_count = fields.Integer('Found Not Helpful',
help="Count of all negative reviews",
compute='_compute_count')
state = fields.Selection(selection=[('unpublished', 'Unpublished'),
('published', 'Published')],
string='Status', help="state of the review",
default='unpublished', track_visibility='always')
help_info_ids = fields.One2many('helpful.info', 'review_id',
string="Help info",
help="Helpful info details")
_sql_constraints = [
('rating_range', 'check(rating >= 0 and rating <= 5)',
'Rating should be between 0 and 5')]
@api.model
def rate_review(self, vals):
"""For adding Seller review"""
check = self.sudo().search([('seller_id', '=', int(vals['seller_id'])),
('customer_id', '=',
int(vals['customer_id']))])
publish = self.env['ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.auto_publish_seller_review')
if check:
if publish:
check.sudo().write({'rating': vals['rating'],
'message': vals['message']})
check.pub()
else:
check.write({'rating': vals['rating'],
'message': vals['message']})
check.unpub()
else:
if publish:
check.sudo().pub()
return super(SellerReview, self).sudo().create(vals)
else:
check.sudo().unpub()
return super(SellerReview, self).sudo().create(vals)
def action_publish(self):
""" Function to publish the review"""
self.state = 'published'
def action_unpublish(self):
""" Function to un publish the review"""
self.state = 'unpublished'
def _compute_count(self):
""" Function to compute the total count """
count = None
for record in self:
count = record.env['helpful.info'].search_count(
[('review_id', '=', record.id)])
if count:
for record in self:
for rec in record.help_info_ids:
record.like_count = rec.search_count([('msg', '=', 'yes'),
('review_id', '=',
record.id)])
record.unlike_count = rec.search_count([('msg', '=', 'no'),
('review_id', '=',
record.id)])
else:
for record in self:
record.like_count = record.unlike_count = 0

80
multi_vendor_marketplace/models/seller_shop.py

@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models,_
from odoo.exceptions import UserError
class SellerShop(models.Model):
"""Managing Seller Shops"""
_name = 'seller.shop'
_description = "Seller Shop"
name = fields.Char(string="Name", help="Name of the shop")
shop_url = fields.Char(string='Shop Url',
help="Shop url which can redirect from the website",
required=True)
shop_banner = fields.Char(string="Shop Banner",
help="Banner of the shop which can be displayed "
"on the website")
tag_line = fields.Char(string='Tag Line', help="Tag line for the shop")
description = fields.Char(string='Description',
help="Description for the shop")
seller_id = fields.Many2one('res.partner', string='Seller',
help="Seller name", default=lambda
self: self.env.user.partner_id.id,
domain=[('state', '=', 'Approved')])
seller_image = fields.Binary(related='seller_id.image_1920',
string="Seller image",
help="Image of the seller")
address = fields.Text(string='Address', help="Address of the seller")
phone = fields.Integer(string='Phone', help="Phone number of the seller")
mobile_number = fields.Integer(string='Mobile Number',
help="Mobile number of the Seller shop")
email = fields.Char(string='E-mail', help="Email address of the seller")
fax = fields.Char(string='Fax', help="Fax of the seller")
is_publish = fields.Boolean(string="Is Publish",
help="for identifying seller shop is published"
"or not in the website")
product_count = fields.Integer(string='Product Count',
help="Total product count in the shop")
product_ids = fields.Many2many('product.template',
string="Product",
help="Product details")
state = fields.Selection(selection=[
('Pending for Approval', 'Pending for Approval'),
('Approved', 'Approved'), ('Denied', 'Denied')], string="State",
help="State of the shop", default="Pending for Approval")
def approve_request(self):
""" Approve the seller shop request"""
self.state = 'Approved'
def reject_request(self):
""" Reject the seller request"""
self.state = 'Denied'
def action_toggle_is_published(self):
""" Toggle the field `is_published`."""
if self.state == 'Approved':
self.is_publish = not self.is_publish
else:
raise UserError(_("You can only publish the approved shops"))

34
multi_vendor_marketplace/models/social_media.py

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class SocialMedia(models.Model):
""" Added social media platform details"""
_name = 'social.media'
_description = "Social Media"
name = fields.Char(string="Name", help="For getting name", required=True)
icon = fields.Binary(sting="Icon", help="Icon for the Social media")
base_url = fields.Char(
string="Base Url",
help="For storing the base url of the social media page", required=True)

43
multi_vendor_marketplace/models/stock_picking.py

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class StockPicking(models.Model):
"""Picking added with seller's extra details for the products the sell"""
_inherit = 'stock.picking'
seller_id = fields.Many2one('res.partner', string="Seller",
help="Seller information")
ref_id = fields.Integer(string="Refer id", help="For adding the reference")
def button_validate(self):
""" Super stock picking function for fetch deliverd qty from delivery
form to sale order """
res = super(StockPicking, self).button_validate()
sale_order_line_rec = self.env['sale.order.line'].sudo().search(
[('id', '=', self.ref_id)])
sale_order_line_rec.state = 'shipped'
sale_order_line_rec.update({
'qty_delivered': self.move_ids_without_package.quantity_done
})
return res

29
multi_vendor_marketplace/models/vendor_dashboard.py

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class VendorDashboard(models.Model):
"""Vendor details maintained for the Dashboard"""
_name = 'vendor.dashboard'
sample = fields.Boolean(string='Sample', help='Sample dashboard')

31
multi_vendor_marketplace/models/website.py

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class WebSite(models.Model):
"""Added Seller banner fields which shows a banner in the website"""
_inherit = 'website'
seller_banner = fields.Binary(string="Seller Banner",
help="To store the seller banner which is "
"displayed on the website")

40
multi_vendor_marketplace/models/website_menu.py

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models
class WebsiteMenu(models.Model):
""" Adding website menu"""
_inherit = "website.menu"
def _compute_visible(self):
"""Make the 'Sell' menu visible on thw website based on the setting
done from backend"""
super()._compute_visible()
show_sell_menu_header = self.env[
'ir.config_parameter'].sudo().get_param(
'multi_vendor_marketplace.show_sell_menu_header')
for menu in self:
if menu.name == 'Sell' and not show_sell_menu_header:
menu.is_visible = False
if menu.name == 'Sell' and show_sell_menu_header:
menu.is_visible = True

21
multi_vendor_marketplace/security/inventory_request_security.xml

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Seller record rule -->
<record id="inventory_request_rule_seller"
model="ir.rule">
<field name="name">Record Rule for seller in inventory request
view
</field>
<field ref="model_inventory_request" name="model_id"/>
<field name="groups"
eval="[(4, ref('multi_vendor_marketplace.multi_vendor_marketplace_seller'))]"/>
<field name="domain_force">[('seller_id.id', '=',
user.partner_id.id)]
</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="True"/>
</record>
</odoo>

14
multi_vendor_marketplace/security/ir.model.access.csv

@ -0,0 +1,14 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_vendor_dashboard_user,access.vendor.dashboard.user,model_vendor_dashboard,base.group_user,1,1,1,1
access_pay_to_seller_user,access.pay.to.seller.user,model_pay_to_seller,base.group_user,1,1,1,1
access_request_payment,access.request.payment,model_request_payment,base.group_user,1,1,1,1
access_seller_payment,access.seller.payment,model_seller_payment,base.group_user,1,1,1,1
access_social_media,access.social.media,model_social_media,base.group_user,1,1,1,1
access_seller_review,access.seller.review,model_seller_review,base.group_user,1,1,1,1
access_helpful_info,access.helpful.info,model_helpful_info,base.group_user,1,1,1,1
access_seller_recommend,access.seller.recommend,model_seller_recommend,base.group_user,1,1,1,1
access_seller_shop,acces.seller.shop,model_seller_shop,base.group_user,1,1,1,1
access_inventory_request,access.inventory.request,model_inventory_request,base.group_user,1,1,1,1
access_multi_vendor_pricelist,access.multi.vendor.pricelist,model_multi_vendor_pricelist,base.group_user,1,1,1,1
base.ir_ui_menu.access1,access_base_ir_ui_menu,base.model_ir_ui_menu,multi_vendor_marketplace.multi_vendor_marketplace_seller,1,0,0,0
multi_vendor_marketplace.access_settings_view,access_settings_view,multi_vendor_marketplace.model_settings_view,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_vendor_dashboard_user access.vendor.dashboard.user model_vendor_dashboard base.group_user 1 1 1 1
3 access_pay_to_seller_user access.pay.to.seller.user model_pay_to_seller base.group_user 1 1 1 1
4 access_request_payment access.request.payment model_request_payment base.group_user 1 1 1 1
5 access_seller_payment access.seller.payment model_seller_payment base.group_user 1 1 1 1
6 access_social_media access.social.media model_social_media base.group_user 1 1 1 1
7 access_seller_review access.seller.review model_seller_review base.group_user 1 1 1 1
8 access_helpful_info access.helpful.info model_helpful_info base.group_user 1 1 1 1
9 access_seller_recommend access.seller.recommend model_seller_recommend base.group_user 1 1 1 1
10 access_seller_shop acces.seller.shop model_seller_shop base.group_user 1 1 1 1
11 access_inventory_request access.inventory.request model_inventory_request base.group_user 1 1 1 1
12 access_multi_vendor_pricelist access.multi.vendor.pricelist model_multi_vendor_pricelist base.group_user 1 1 1 1
13 base.ir_ui_menu.access1 access_base_ir_ui_menu base.model_ir_ui_menu multi_vendor_marketplace.multi_vendor_marketplace_seller 1 0 0 0
14 multi_vendor_marketplace.access_settings_view access_settings_view multi_vendor_marketplace.model_settings_view base.group_user 1 1 1 1

26
multi_vendor_marketplace/security/multi_vendor_marketplace_groups.xml

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Module category for the roles-->
<record model="ir.module.category" id="multi_vendor_marketplace">
<field name="name">Multi Vendor Marketplace</field>
<field name="description">User access rights</field>
<field name="sequence">20</field>
</record>
<!-- Admin role-->
<record id="multi_vendor_marketplace_admin" model="res.groups">
<field name="name">Admin</field>
<field name="category_id" ref="multi_vendor_marketplace"/>
<field name="users"
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<!-- Seller role-->
<record id="multi_vendor_marketplace_seller" model="res.groups">
<field name="name">Seller</field>
<field name="category_id" ref="multi_vendor_marketplace"/>
</record>
<!-- Requested Seller role-->
<record id="multi_vendor_marketplace_req_seller" model="res.groups">
<field name="name">Requested Seller</field>
<field name="category_id" ref="multi_vendor_marketplace"/>
</record>
</odoo>

17
multi_vendor_marketplace/security/product_template_security.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Seller record rule-->
<record id="product_template_rule_seller" model="ir.rule">
<field name="name">Record Rule for seller product</field>
<field ref="model_product_template" name="model_id"/>
<field name="groups"
eval="[(4, ref('multi_vendor_marketplace.multi_vendor_marketplace_seller'))]"/>
<field name="domain_force">[('seller_id.id', '=',
user.partner_id.id)]
</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="True"/>
</record>
</odoo>

18
multi_vendor_marketplace/security/sale_order_line_security.xml

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Seller record rule-->
<record id="sale_order_line_rule_seller"
model="ir.rule">
<field name="name">Record Rule for seller sale order</field>
<field ref="model_sale_order_line" name="model_id"/>
<field name="groups"
eval="[(4, ref('multi_vendor_marketplace.multi_vendor_marketplace_seller'))]"/>
<field name="domain_force">[('seller_id.id', '=',
user.partner_id.id)]
</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="True"/>
</record>
</odoo>

17
multi_vendor_marketplace/security/seller_payment_security.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Seller record rule-->
<record id="seller_payment_rule_seller" model="ir.rule">
<field name="name">Record Rule for seller payment</field>
<field ref="model_seller_payment" name="model_id"/>
<field name="groups"
eval="[(4, ref('multi_vendor_marketplace.multi_vendor_marketplace_seller'))]"/>
<field name="domain_force">[('seller_id.id', '=',
user.partner_id.id)]
</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="True"/>
</record>
</odoo>

20
multi_vendor_marketplace/security/seller_shop_security.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Seller record rule-->
<record id="seller_shop_rule_seller"
model="ir.rule">
<field name="name">Record Rule for seller shop
view
</field>
<field ref="model_seller_shop" name="model_id"/>
<field name="groups"
eval="[(4, ref('multi_vendor_marketplace.multi_vendor_marketplace_seller'))]"/>
<field name="domain_force">[('seller_id.id', '=',
user.partner_id.id)]
</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="True"/>
</record>
</odoo>

18
multi_vendor_marketplace/security/stock_picking_security.xml

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Seller record rule-->
<record id="stock_picking_rule_seller"
model="ir.rule">
<field name="name">Record Rule for seller Delivery Order</field>
<field ref="model_stock_picking" name="model_id"/>
<field name="groups"
eval="[(4, ref('multi_vendor_marketplace.multi_vendor_marketplace_seller'))]"/>
<field name="domain_force">[('seller_id.id', '=',
user.partner_id.id)]
</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="True"/>
</record>
</odoo>

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/categories.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/check-box.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/compass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/corporate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/customer-support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/cybrosys-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

BIN
multi_vendor_marketplace/static/description/assets/misc/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/pictures.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/pie-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/right-arrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

BIN
multi_vendor_marketplace/static/description/assets/misc/star.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
multi_vendor_marketplace/static/description/assets/misc/whatsapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
multi_vendor_marketplace/static/description/assets/modules/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
multi_vendor_marketplace/static/description/assets/modules/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
multi_vendor_marketplace/static/description/assets/modules/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
multi_vendor_marketplace/static/description/assets/modules/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
multi_vendor_marketplace/static/description/assets/modules/5.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
multi_vendor_marketplace/static/description/assets/modules/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/15.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
multi_vendor_marketplace/static/description/assets/screenshots/9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

BIN
multi_vendor_marketplace/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
multi_vendor_marketplace/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save