Browse Source

Jan 01 [ADD] : Initial Commit 'all_in_one_website_kit'

pull/254/merge
AjmalCybro 4 months ago
parent
commit
1624da00ca
  1. 48
      all_in_one_website_kit/README.rst
  2. 22
      all_in_one_website_kit/__init__.py
  3. 95
      all_in_one_website_kit/__manifest__.py
  4. 25
      all_in_one_website_kit/controllers/__init__.py
  5. 68
      all_in_one_website_kit/controllers/all_in_one_website_kit.py
  6. 64
      all_in_one_website_kit/controllers/main.py
  7. 415
      all_in_one_website_kit/controllers/portal.py
  8. 95
      all_in_one_website_kit/controllers/website_sale.py
  9. 11
      all_in_one_website_kit/data/insta_profile_sequence_data.xml
  10. 13
      all_in_one_website_kit/data/ir_sequence_data.xml
  11. 6
      all_in_one_website_kit/doc/RELEASE_NOTES.md
  12. 33
      all_in_one_website_kit/models/__init__.py
  13. 67
      all_in_one_website_kit/models/call_price.py
  14. 57
      all_in_one_website_kit/models/insta_post.py
  15. 119
      all_in_one_website_kit/models/insta_profile.py
  16. 61
      all_in_one_website_kit/models/portal_dashboard_data.py
  17. 32
      all_in_one_website_kit/models/product_product.py
  18. 33
      all_in_one_website_kit/models/product_template.py
  19. 66
      all_in_one_website_kit/models/res_config_settings.py
  20. 60
      all_in_one_website_kit/models/sale_order.py
  21. 264
      all_in_one_website_kit/models/sale_return.py
  22. 53
      all_in_one_website_kit/models/stock_picking.py
  23. 40
      all_in_one_website_kit/models/stock_return_picking.py
  24. 92
      all_in_one_website_kit/models/website.py
  25. 14
      all_in_one_website_kit/report/sale_return_reports.xml
  26. 75
      all_in_one_website_kit/report/sale_return_templates.xml
  27. 5
      all_in_one_website_kit/security/ir.model.access.csv
  28. BIN
      all_in_one_website_kit/static/description/assets/icons/check.png
  29. BIN
      all_in_one_website_kit/static/description/assets/icons/chevron.png
  30. BIN
      all_in_one_website_kit/static/description/assets/icons/cogs.png
  31. BIN
      all_in_one_website_kit/static/description/assets/icons/consultation.png
  32. BIN
      all_in_one_website_kit/static/description/assets/icons/ecom-black.png
  33. BIN
      all_in_one_website_kit/static/description/assets/icons/education-black.png
  34. BIN
      all_in_one_website_kit/static/description/assets/icons/hotel-black.png
  35. BIN
      all_in_one_website_kit/static/description/assets/icons/license.png
  36. BIN
      all_in_one_website_kit/static/description/assets/icons/lifebuoy.png
  37. BIN
      all_in_one_website_kit/static/description/assets/icons/manufacturing-black.png
  38. BIN
      all_in_one_website_kit/static/description/assets/icons/pos-black.png
  39. BIN
      all_in_one_website_kit/static/description/assets/icons/puzzle.png
  40. BIN
      all_in_one_website_kit/static/description/assets/icons/restaurant-black.png
  41. BIN
      all_in_one_website_kit/static/description/assets/icons/service-black.png
  42. BIN
      all_in_one_website_kit/static/description/assets/icons/trading-black.png
  43. BIN
      all_in_one_website_kit/static/description/assets/icons/training.png
  44. BIN
      all_in_one_website_kit/static/description/assets/icons/update.png
  45. BIN
      all_in_one_website_kit/static/description/assets/icons/user.png
  46. BIN
      all_in_one_website_kit/static/description/assets/icons/wrench.png
  47. BIN
      all_in_one_website_kit/static/description/assets/misc/categories.png
  48. BIN
      all_in_one_website_kit/static/description/assets/misc/check-box.png
  49. BIN
      all_in_one_website_kit/static/description/assets/misc/compass.png
  50. BIN
      all_in_one_website_kit/static/description/assets/misc/corporate.png
  51. BIN
      all_in_one_website_kit/static/description/assets/misc/customer-support.png
  52. BIN
      all_in_one_website_kit/static/description/assets/misc/cybrosys-logo.png
  53. BIN
      all_in_one_website_kit/static/description/assets/misc/features.png
  54. BIN
      all_in_one_website_kit/static/description/assets/misc/logo.png
  55. BIN
      all_in_one_website_kit/static/description/assets/misc/pictures.png
  56. BIN
      all_in_one_website_kit/static/description/assets/misc/pie-chart.png
  57. BIN
      all_in_one_website_kit/static/description/assets/misc/right-arrow.png
  58. BIN
      all_in_one_website_kit/static/description/assets/misc/star.png
  59. BIN
      all_in_one_website_kit/static/description/assets/misc/support.png
  60. BIN
      all_in_one_website_kit/static/description/assets/misc/whatsapp.png
  61. BIN
      all_in_one_website_kit/static/description/assets/modules/odoo_website_helpdesk.png
  62. BIN
      all_in_one_website_kit/static/description/assets/modules/odoo_website_helpdesk_dashboard.png
  63. BIN
      all_in_one_website_kit/static/description/assets/modules/product_visibility_website.png
  64. BIN
      all_in_one_website_kit/static/description/assets/modules/website_multi_product_return_management.png
  65. BIN
      all_in_one_website_kit/static/description/assets/modules/website_product_attachments.png
  66. BIN
      all_in_one_website_kit/static/description/assets/modules/website_return_management.png
  67. BIN
      all_in_one_website_kit/static/description/assets/screenshots/attachment_1.png
  68. BIN
      all_in_one_website_kit/static/description/assets/screenshots/attachment_2.png
  69. BIN
      all_in_one_website_kit/static/description/assets/screenshots/barcode1.png
  70. BIN
      all_in_one_website_kit/static/description/assets/screenshots/barcode2.png
  71. BIN
      all_in_one_website_kit/static/description/assets/screenshots/barcode3.png
  72. BIN
      all_in_one_website_kit/static/description/assets/screenshots/barcode4.png
  73. BIN
      all_in_one_website_kit/static/description/assets/screenshots/barcode5.png
  74. BIN
      all_in_one_website_kit/static/description/assets/screenshots/call_price1.png
  75. BIN
      all_in_one_website_kit/static/description/assets/screenshots/call_price2.png
  76. BIN
      all_in_one_website_kit/static/description/assets/screenshots/call_price3.png
  77. BIN
      all_in_one_website_kit/static/description/assets/screenshots/call_price4.png
  78. BIN
      all_in_one_website_kit/static/description/assets/screenshots/call_price5.png
  79. BIN
      all_in_one_website_kit/static/description/assets/screenshots/clear_cart1.png
  80. BIN
      all_in_one_website_kit/static/description/assets/screenshots/clear_cart2.png
  81. BIN
      all_in_one_website_kit/static/description/assets/screenshots/custom_contact1.png
  82. BIN
      all_in_one_website_kit/static/description/assets/screenshots/custom_contact2.png
  83. BIN
      all_in_one_website_kit/static/description/assets/screenshots/custom_contact3.png
  84. BIN
      all_in_one_website_kit/static/description/assets/screenshots/hero.gif
  85. BIN
      all_in_one_website_kit/static/description/assets/screenshots/hide_variant1.png
  86. BIN
      all_in_one_website_kit/static/description/assets/screenshots/hide_variant2.png
  87. BIN
      all_in_one_website_kit/static/description/assets/screenshots/hide_variant3.png
  88. BIN
      all_in_one_website_kit/static/description/assets/screenshots/icon.png
  89. BIN
      all_in_one_website_kit/static/description/assets/screenshots/icon2.png
  90. BIN
      all_in_one_website_kit/static/description/assets/screenshots/icon3.png
  91. BIN
      all_in_one_website_kit/static/description/assets/screenshots/instagram1.png
  92. BIN
      all_in_one_website_kit/static/description/assets/screenshots/instagram2.png
  93. BIN
      all_in_one_website_kit/static/description/assets/screenshots/instagram3.png
  94. BIN
      all_in_one_website_kit/static/description/assets/screenshots/instagram4.png
  95. BIN
      all_in_one_website_kit/static/description/assets/screenshots/order_comment1.png
  96. BIN
      all_in_one_website_kit/static/description/assets/screenshots/order_comment2.png
  97. BIN
      all_in_one_website_kit/static/description/assets/screenshots/order_comment3.png
  98. BIN
      all_in_one_website_kit/static/description/assets/screenshots/portal1.png
  99. BIN
      all_in_one_website_kit/static/description/assets/screenshots/portal2.png
  100. BIN
      all_in_one_website_kit/static/description/assets/screenshots/portal3.png

48
all_in_one_website_kit/README.rst

@ -0,0 +1,48 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
All In One Website Kit
======================
All In One Website Kit for odoo15 enables multiple website features.
Configuration
=============
* No additional configurations needed
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
License
-------
Affero General Public License, Version 3 (AGPL v3).
(https://www.gnu.org/licenses/agpl-3.0-standalone.html)
Credits
-------
* Developers: (V15) Aysha Shalin,
(V16) Yadhukrishnan,
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>`__

22
all_in_one_website_kit/__init__.py

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

95
all_in_one_website_kit/__manifest__.py

@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
{
'name': 'All In One Website Kit',
'version': '15.0.1.0.0',
'category': 'Website',
'summary': """All In One Website Kit for odoo16 community edition enables
multiple website features.""",
'description': """This module enables the features of the following modules,
Website Call For Price, Customer Order Comment, Ecommerce Barcode Search,
Instagram Feed Snippet, Portal Dashboard, Website Clear Cart, Hide Variants,
Website Custom Contact Us, Product Attachments on the Website,
Website Return Order Management and Whatsapp Floating Icon in Website.""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': "https://www.cybrosys.com",
'depends': [
'base', 'website_sale_wishlist', 'website_sale_comparison', 'stock',
'sale_management', 'project', 'crm', 'purchase'
],
'data': [
'security/ir.model.access.csv',
'data/ir_sequence_data.xml',
'data/insta_profile_sequence_data.xml',
'report/sale_return_reports.xml',
'report/sale_return_templates.xml',
'views/shop_hide_call_price_templates.xml',
'views/wishlist_hide_price_templates.xml',
'views/compare_hide_price_templates.xml',
'views/call_price_views.xml',
'views/sale_order_views.xml',
'views/product_template_views.xml',
'views/res_config_settings_views.xml',
'views/customer_order_comment_templates.xml',
'views/products_barcode_scan_templates.xml',
'views/portal_dashboard_templates.xml',
'views/clear_cart_templates.xml',
'views/website_views.xml',
'views/website_contact_us_template.xml',
'views/product_product_views.xml',
'views/product_attachments_templates.xml',
'views/website_thankyou_templates.xml',
'views/sale_return_views.xml',
'views/sale_return_templates.xml',
'views/stock_picking_views.xml',
'views/insta_post_views.xml',
'views/insta_profile_views.xml',
'views/sale_order_views.xml',
'views/carousal_dashboard_templates.xml',
'views/portal_whatsapp_templates.xml',
],
'assets': {
'web.assets_frontend': [
'/all_in_one_website_kit/static/src/js/create_call_price.js',
'/all_in_one_website_kit/static/src/js/review_and_rating.js',
'/all_in_one_website_kit/static/src/css/review_and_rating.css',
'/all_in_one_website_kit/static/src/js/sale_barcode.js',
'/all_in_one_website_kit/static/src/js/portal_dashboard_graph.js',
'/all_in_one_website_kit/static/src/js/variants.js',
'/all_in_one_website_kit/static/src/js/sale_return.js',
'/all_in_one_website_kit/static/src/js/caroursel.js',
'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js',
'/all_in_one_website_kit/static/src/scss/style.scss',
'/all_in_one_website_kit/static/src/js/quagga.js',
]
},
'external_dependencies': {
'python': ['pytz', 'geopy'],
},
'images': ['static/description/banner.png'],
'license': 'AGPL-3',
'installable': True,
'auto_install': False,
'application': False,
}

25
all_in_one_website_kit/controllers/__init__.py

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

68
all_in_one_website_kit/controllers/all_in_one_website_kit.py

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
import time
from odoo import http
from odoo.http import request
class WebsiteClearCart(http.Controller):
"""
The class WebsiteClearCart is used to clear the cart.
Methods:
remove_cart_items(self):
It will remove all items from cart and redirect to shop page
"""
@http.route(['/shop/remove_items'], type="http", auth="public",
website=True)
def remove_cart_items(self):
""" This will remove all items from cart and redirect to shop page """
current_orders = request.website.sale_get_order()
for line in current_orders.website_order_line:
line.unlink()
return request.redirect('/shop/cart')
@http.route('/final/customer_rating', type='http', auth="public",
website=True, sitemap=False)
def customer_order_rating(self, **kw):
""" This function helps to fetch the values of comment and rating """
order_id = request.env['sale.order'].sudo().browse(int(kw['order_id']))
order_id.comment = kw['comment']
order_id.rating = kw['rate_value']
return request.redirect('/shop/confirmation')
@http.route('/get_dashboard_carousel', auth="public", type='json')
def get_dashboard_carousel(self):
""" Getting data to the carousel """
events_per_slide = 3
records = request.env['insta.post'].sudo().search([])
records_grouped = [records[post:post + events_per_slide] for po3333333333333333333333st in
range(0, len(records), events_per_slide)]
values = {
"objects": records_grouped,
"events_per_slide": events_per_slide,
"num_slides": len(records_grouped),
"uniqueId": "pc-%d" % int(time.time() * 1000),
}
response = http.Response(
template='all_in_one_website_kit.s_carousel_template_items',
qcontext=values)
return response.render()

64
all_in_one_website_kit/controllers/main.py

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

415
all_in_one_website_kit/controllers/portal.py

@ -0,0 +1,415 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
import base64
from collections import OrderedDict
from geopy import Nominatim
import json
import pytz
from odoo import http
from odoo.exceptions import AccessError, MissingError
from odoo.http import request, route
from odoo.tools import image_process
from odoo.tools.translate import _
from odoo.addons.portal.controllers.portal import CustomerPortal
class ReturnCustomerPortal(CustomerPortal):
""" Passing values to the sale return templates. """
def _prepare_home_portal_values(self, counters):
"""getting count of total sale returns"""
values = super()._prepare_home_portal_values(counters)
if 'return_count' in counters:
values['return_count'] = request.env['sale.return'].search_count([
('state', 'in', ['draft', 'confirm', 'done', 'cancel'])])
return values
@http.route(['/my/return_orders', '/my/return_orders/page/<int:page>'],
type='http', auth="user", website=True)
def portal_my_sale_return(self, page=1, date_begin=None, date_end=None,
sortby=None, filterby=None):
""" Passing data to the /my/return_orders page. """
values = self._prepare_portal_layout_values()
sale_return = request.env['sale.return']
domain = []
searchbar_sortings = {
'date': {'label': _('Newest'), 'order': 'create_date desc'},
'name': {'label': _('Name'), 'order': 'name'},
'sale': {'label': _('Sale Order'), 'order': 'order_id'},
}
# default sort by value
if not sortby:
sortby = 'date'
order = searchbar_sortings[sortby]['order']
if date_begin and date_end:
domain += [('create_date', '>', date_begin),
('create_date', '<=', date_end)]
searchbar_filters = {
'all': {'label': _('All'), 'domain': [
('state', 'in', ['draft', 'confirm', 'done', 'cancel'])]},
'confirm': {'label': _('Confirmed'),
'domain': [('state', '=', 'confirm')]},
'cancel': {'label': _('Cancelled'),
'domain': [('state', '=', 'cancel')]},
'done': {'label': _('Done'), 'domain': [('state', '=', 'done')]},
}
# default filter by value
if not filterby:
filterby = 'all'
domain += searchbar_filters[filterby]['domain']
# pager
pager = request.website.pager(
url="/my/return_orders",
url_args={'date_begin': date_begin, 'date_end': date_end,
'sortby': sortby},
total=sale_return.search_count(domain),
page=page,
step=self._items_per_page
)
# content according to pager and archive selected
orders = sale_return.search(domain, order=order,
limit=self._items_per_page,
offset=pager['offset'])
request.session['my_return_history'] = orders.ids[:100]
values.update({
'date': date_begin,
'orders': orders.sudo(),
'page_name': 'Sale_Return',
'default_url': '/my/return_orders',
'pager': pager,
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
'searchbar_sortings': searchbar_sortings,
'sortby': sortby,
})
return request.render("all_in_one_website_kit.portal_my_returns",
values)
@http.route(['/my/return_orders/<int:order_id>'], type='http',
auth="public", website=True)
def portal_my_return_detail(self, order_id=None, access_token=None,
report_type=None, download=False, **kw):
""" Passing data to individual return orders. """
try:
order_sudo = self._document_check_access('sale.return', order_id,
access_token)
except (AccessError, MissingError):
return request.redirect('/my')
if report_type in ('html', 'pdf', 'text'):
return self._show_report(
model=order_sudo, report_type=report_type,
report_ref='all_in_one_website_kit.report_sale_returns',
download=download)
values = self._sale_return_get_page_view_values(order_sudo,
access_token, **kw)
return request.render("all_in_one_website_kit.portal_sale_return_page",
values)
def _sale_return_get_page_view_values(self, order, access_token, **kwargs):
""" Getting values to the function portal_my_return_detail. """
def resize_to_48(b64source):
if not b64source:
b64source = request.env['ir.binary']._placeholder()
else:
b64source = base64.b64decode(b64source)
return base64.b64encode(image_process(b64source, size=(48, 48)))
values = {
'orders': order,
'resize_to_48': resize_to_48,
}
return self._get_page_view_values(order, access_token, values,
'my_return_history', False, **kwargs)
@route(['/my', '/my/home'], type='http', auth="user", website=True)
def home(self, **kw):
""" Replaces already existing work flow of portal view to redirect to
new template with record values and count. """
user = request.env.user.id
partners = request.env.user
group_id = request.env.ref('base.group_user')
order_id = request.env['sale.order'].sudo()
purchase_order = request.env['purchase.order'].sudo()
account_move = request.env['account.move']
project = request.env['project.project'].sudo()
task = request.env['project.task'].sudo()
config_parameters = request.env['ir.config_parameter'].sudo()
number_project = ""
projects_limited = ""
tasks_limited = ""
number_account = ""
invoices_limited = ""
show_project = request.env[
'ir.config_parameter'
].sudo().get_param('all_in_one_website_kit.is_show_project')
show_account = request.env['ir.config_parameter'].sudo().get_param(
'all_in_one_website_kit.is_show_recent_invoice_bill')
show_so_q = request.env['ir.config_parameter'].sudo().get_param(
'all_in_one_website_kit.is_show_recent_so_q')
show_po_rfq = request.env[
'ir.config_parameter'
].sudo().get_param('all_in_one_website_kit.is_show_recent_po_rfq')
number_order = ""
sale_orders_limited = ""
quotations_limited = ""
number_po = ""
purchase_orders_limited = ""
rfq_limited = ""
if group_id in partners.groups_id:
if show_so_q:
number_order = request.env[
'ir.config_parameter'
].sudo().get_param('all_in_one_website_kit.sale_count', 0)
sale_orders_limited = order_id.search([
'|', ('user_id', '=', user),
('partner_id', '=', request.env.user.partner_id.id),
('state', 'not in', ['draft', 'sent'])
], limit=int(number_order))
quotations_limited = order_id.search([
'|', ('user_id', '=', user),
('partner_id', '=', request.env.user.partner_id.id),
('state', 'in', ['sent'])
], limit=int(number_order))
if show_po_rfq:
number_po = config_parameters.get_param(
'all_in_one_website_kit.purchase_count', 0)
purchase_orders_limited = purchase_order.search([
'|', ('user_id', '=', user),
('partner_id', '=', request.env.user.partner_id.id),
('state', 'not in', ['draft', 'sent', 'to approve'])
], limit=int(number_po))
rfq_limited = purchase_order.search([
'|', ('user_id', '=', user),
('partner_id', '=', request.env.user.partner_id.id),
('state', 'in', ['draft', 'sent', 'to approve'])
], limit=int(number_po))
if show_project:
number_project = config_parameters.get_param(
'all_in_one_website_kit.project_count', 0)
projects_limited = project.search([],
limit=int(number_project))
tasks_limited = task.search([], limit=int(number_project))
if show_account:
number_account = config_parameters.get_param(
'all_in_one_website_kit.account_count', 0)
invoices_limited = account_move.search([
('partner_id', '=', user.partner_id.id),
('state', 'not in', ['draft', 'cancel'])
], limit=int(number_account))
sale_orders = order_id.search([
'|', ('user_id', '=', user),
('partner_id', '=', request.env.user.partner_id.id),
('access_token', '!=', False),
('state', 'not in', ['draft', 'sent'])
])
quotations = request.env['sale.order'].sudo().search([
'|', ('user_id', '=', user),
('partner_id', '=', request.env.user.partner_id.id),
('state', '=', 'sent')
])
purchase_orders = purchase_order.search([
'|', ('user_id', '=', user),
('partner_id', '=', request.env.user.partner_id.id),
('state', 'not in', ['draft', 'sent', 'to approve'])
])
rfq = purchase_order.search([
'|', ('user_id', '=', user),
('partner_id', '=', request.env.user.partner_id.id),
('state', '=', 'sent')
])
projects = project.search([])
tasks = task.search([])
invoices = account_move.search([('access_token', '!=', False)])
else:
if show_so_q:
number_order = config_parameters.get_param(
'all_in_one_website_kit.sale_count', 0)
sale_orders_limited = order_id.search([
('partner_id', '=', partners.partner_id.id),
('state', 'not in', ['draft', 'sent'])
], limit=int(number_order))
quotations_limited = order_id.search([
('partner_id', '=', partners.partner_id.id),
('state', 'in', ['sent'])
], limit=int(number_order))
if show_po_rfq:
number_po = config_parameters.get_param(
'all_in_one_website_kit.purchase_count', 0)
purchase_orders_limited = purchase_order.search([
('partner_id', '=', partners.partner_id.id),
('state', 'not in', ['draft', 'sent', 'to approve'])
], limit=int(number_po))
rfq_limited = purchase_order.search([
('partner_id', '=', partners.partner_id.id),
('state', 'in', ['draft', 'sent', 'to approve'])
], limit=int(number_po))
if show_project:
number_project = config_parameters.get_param(
'all_in_one_website_kit.project_count', 0)
projects_limited = project.search([('user_id', '=', user)],
limit=int(number_project))
tasks_limited = task.search([('user_id', '=', user)],
limit=int(number_project))
if show_account:
number_account = config_parameters.get_param(
'all_in_one_website_kit.account_count', 0)
invoices_limited = account_move.search([
('partner_id', '=', partners.partner_id.id),
('state', 'not in', ['draft', 'cancel'])
], limit=int(number_account))
sale_orders = order_id.search([
'|', ('user_id', '=', user),
('partner_id', '=', partners.partner_id.id),
('state', 'not in', ['draft', 'sent'])
])
quotations = order_id.search([
'|', ('user_id', '=', user),
('partner_id', '=', partners.partner_id.id),
('state', 'in', ['sent'])
])
purchase_orders = purchase_order.search([
'|', ('user_id', '=', user),
('partner_id', '=', partners.partner_id.id),
('state', 'not in', ['draft', 'sent', 'to approve'])
])
rfq = purchase_order.search([
'|', ('user_id', '=', user),
('partner_id', '=', partners.partner_id.id),
('state', 'in', ['sent', 'to approve'])
])
projects = project.search([
('user_id', '=', user)
])
tasks = task.search([('user_id', '=', user)])
invoices = account_move.search([
('access_token', '!=', False)
])
values = self._prepare_portal_layout_values()
values['sale_order_portal'] = sale_orders
values['quotation_portal'] = quotations
values['counts_quotation'] = len(quotations)
values['purchase_orders_portal'] = purchase_orders
values['rfq_portal'] = rfq
values['projects_portal'] = projects
values['tasks_portal'] = tasks
values['invoices_portal'] = invoices
values['number_so_portal'] = number_order
values['number_po_portal'] = number_po
values['number_account_portal'] = number_account
values['number_project_portal'] = number_project
values['sale_orders_limited'] = sale_orders_limited
values['quotations_limited'] = quotations_limited
values['purchase_orders_limited'] = purchase_orders_limited
values['rfq_limited'] = rfq_limited
values['invoices_limited'] = invoices_limited
values['projects_limited'] = projects_limited
values['tasks_limited'] = tasks_limited
values['show_so_q'] = show_so_q
values['show_po_rfq'] = show_po_rfq
values['show_project'] = show_project
values['show_account'] = show_account
values['count_return_order'] = request.env['sale.return'].search_count(
[('user_id', '=', request.env.uid)])
return request.render(
"all_in_one_website_kit.portal_dashboard_data",
values)
@route()
def account(self, **post):
""" Super CustomerPortal class function and pass the api key value
from settings using params to website view file. """
res = super(ReturnCustomerPortal, self).account(**post)
params = request.env['ir.config_parameter'].sudo()
values = params.get_param('base_geolocalize.google_map_api_key')
res.qcontext.update({
'api': values
})
return res
@http.route(['/geo/change/<coordinates>'], type='json', auth="none",
website=False, csrf=False)
def geo_changer(self, coordinates):
""" Controller function for get address details from latitude and
longitude that we pinpointed in map using geopy package from python
Parameters ---------- coordinates :The stringify value from map that
contains latitude and longitude
Returns ------- Returning the address details back to view file from
the converted Latitude and longitude
"""
res = json.loads(coordinates)
geolocator = Nominatim(user_agent="geoapiExercises")
location = geolocator.reverse(
str(res.get('lat')) + "," + str(res.get('lng')))
city = "Undefined"
suburb = "Undefined"
state = "Undefined"
country = "Undefined"
p_code = "Undefined"
if location:
addresses = location.raw['address']
if addresses.get('village'):
city = addresses.get('village')
if addresses.get('suburb'):
suburb = addresses.get('suburb')
state = addresses.get('state')
country_code = addresses.get('country_code')
country = pytz.country_names[country_code]
if addresses.get('postcode'):
p_code = addresses.get('postcode')
return {
'city': city,
'suburb': suburb,
'state': state,
'country': country,
'p_code': p_code,
}
@http.route(['/geo/location/<address>'], type='json', auth="none",
website=False, csrf=False)
def geo_location(self, address):
""" Get value from city field in 'my_account' page and convert into
lat and long and return back to website and set the map and fields
Parameters ---------- address : The city name that in city field in
website
Returns
-------
Pass the value to website view and set required fields and map
"""
locator = Nominatim(user_agent="myGeocoder")
location = locator.geocode(address)
geolocator = Nominatim(user_agent="geoapiExercises")
location_country = geolocator.reverse(
str(location.latitude) + "," + str(location.longitude))
addresses = location_country.raw['address']
country_code = addresses.get('country_code')
country = pytz.country_names[country_code]
p_code = "undefined"
if addresses.get('postcode'):
p_code = addresses.get('postcode')
return {
'lat': location.latitude,
'lng': location.longitude,
'country': country,
'p_code': p_code
}

95
all_in_one_website_kit/controllers/website_sale.py

@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
import base64
import io
from werkzeug.utils import redirect
from odoo import http
from odoo.http import request
from odoo.addons.http_routing.models.ir_http import slug
from odoo.addons.website_sale.controllers.main import WebsiteSale
class WebsiteSale(WebsiteSale):
""" The class WebsiteProductBarcode is used for getting product with scanned
barcode. """
@http.route([
'/shop/barcodeproduct'], type='json', auth="user", website=True,
methods=['GET', 'POST'])
def product_barcode(self, **kwargs):
""" checking the is scanned or not and passes the corresponding
values"""
barcode_product = request.env['product.product'].search(
[('barcode', '=', kwargs.get('last_code'))])
if barcode_product:
return {
'type': 'ir.actions.act_url',
'url': '/shop/%s' % slug(barcode_product.product_tmpl_id)
}
else:
return False
@http.route(['/shop/<model("product.template"):product>'], type='http',
auth="public", website=True)
def product(self, product, category='', search='', **kwargs):
""" Supering the controller to pass the values. """
res = super(WebsiteSale, self).product(product, category='', search='',
**kwargs)
res.qcontext['attachments'] = request.env[
'ir.attachment'].sudo().search(
[('res_model', '=', 'product.template'),
('res_id', '=', product.id)], order='id')
return res
def _get_attribute_exclusion(self, product, reference_product=None):
""" Check the product variant. """
parent_combination = request.env['product.template.attribute.value']
if reference_product:
parent_combination |= reference_product.product_template_attribute_value_ids
if reference_product.env.context.get('no_variant_attribute_values'):
# Add "no_variant" attribute values' exclusions
# They are kept in the context since they are not linked to this
# product variant
parent_combination |= reference_product.env.context.get(
'no_variant_attribute_values')
return product._get_attribute_exclusions(parent_combination)
@http.route(['/attachment/download', ], type='http', auth='public')
def download_attachment(self, attachment_id):
""" To download the document of the product. """
# Check if this is a valid attachment id
attachment = request.env['ir.attachment'].sudo().browse(
int(attachment_id))
if attachment:
attachment = attachment[0]
else:
return redirect('/shop')
if attachment["type"] == "url":
if attachment["url"]:
return redirect(attachment["url"])
else:
return request.not_found()
elif attachment["datas"]:
data = io.BytesIO(base64.standard_b64decode(attachment["datas"]))
return http.send_file(data, filename=attachment['name'],
as_attachment=True)
else:
return request.not_found()

11
all_in_one_website_kit/data/insta_profile_sequence_data.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data noupdate="1">
<record id="insta_profile_id" model="ir.sequence">
<field name="name">Profile ID</field>
<field name="code">insta.profile</field>
<field name="prefix">INST</field>
<field name="padding">2</field>
</record>
</data>
</odoo>

13
all_in_one_website_kit/data/ir_sequence_data.xml

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

6
all_in_one_website_kit/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module <all_in_one_website_kit>
#### 03.09.2024
#### Version 15.0.1.0.0
##### ADD
- Initial Commit for All In One Website Kit

33
all_in_one_website_kit/models/__init__.py

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

67
all_in_one_website_kit/models/call_price.py

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import api, fields, models
class CallPrice(models.Model):
""" Creating a model to record all the request for price from website. """
_name = 'call.price'
_description = 'Call for Price'
_rec_name = 'product_id'
first_name = fields.Char(string="First Name", help="First Name of user")
last_name = fields.Char(string="Last Name", help="Last Name of user")
product_id = fields.Many2one('product.template', string="Product",
help="In which product "
"they are requesting price")
email = fields.Char(string="Email", help="Users email for contact")
phone = fields.Char(string="Contact No.",
help="Users contact number for contacting")
quantity = fields.Float(string="Quantity",
help="How much quantity of product price "
"they want know")
message = fields.Char(string="Message",
help="If any messages for referring")
state = fields.Selection(
[('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Cancel')],
default="draft", help="Call for price requests stage", string="State")
def action_done(self):
""" Change state of the form to 'done'. """
self.write({'state': 'done'})
def action_cancel(self):
""" Cancel the form and change the state to cancel. """
self.write({'state': 'cancel'})
@api.model
def create_form(self, first, last, product_id, phone, email, message, qty):
""" Create the request from the users in the backend. """
self.create({
'product_id': product_id,
'first_name': first,
'last_name': last,
'phone': phone,
'email': email,
'quantity': qty,
'message': message
})

57
all_in_one_website_kit/models/insta_post.py

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
import requests
from odoo import _, fields, models
from odoo.exceptions import UserError
class InstaPost(models.Model):
""" In the class InstaPost getting the posts of corresponding selected
instagram account. """
_name = 'insta.post'
_description = 'Insta Post'
name = fields.Char(string="Media ID", help="The field defines Media ID")
caption = fields.Char(string="Caption",
help="This field defines the caption")
post_image = fields.Binary(string='Post Image', attachment=True,
help="The field is defined for attaching the"
"post image")
profile_id = fields.Many2one('insta.profile',
string="Profile ID",
help="The field defines the insta profile id")
def action_update_post(self, access_token):
""" Action for updating the posts """
url = ('https://graph.facebook.com/v15.0/%s?fields=id,caption,' +
'comments_count,is_comment_enabled,like_count,' +
'media_product_type,media_type,media_url,owner,permalink,' +
'thumbnail_url,timestamp,username&access_token=%s') % (
self.name, access_token)
media_content = requests.get(url, timeout=5).json()
if not media_content.get('error'):
if media_content.get('caption'):
self.write({
'caption': media_content['caption'],
})
else:
raise UserError(_('%s', media_content['error']['message']))

119
all_in_one_website_kit/models/insta_profile.py

@ -0,0 +1,119 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
import base64
import requests
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class InstaProfile(models.Model):
"""class for adding instagram account"""
_name = 'insta.profile'
_description = 'Insta Profile'
name = fields.Char(string="Name", readonly=True,
help="The name for the insta profile.")
access_token = fields.Char(string="Access Token", required=True,
help="The Access Token for the insta profile.")
username = fields.Char(string='Username', readonly=True,
help="The field defines the user name")
account_id = fields.Char(string='Account ID', readonly=True,
help="The field defines the Account id for the"
" insta profile")
profile_image_url = fields.Binary(attachment=True, string="Profile Image",
help="The profile image can upload here.")
@api.model
def create(self, vals):
"""" To generate sequence for instagram profiles """
if vals.get('name', 'New') == 'New':
vals['name'] = self.env['ir.sequence'].next_by_code(
'insta.profile') or 'New'
result = super(InstaProfile, self).create(vals)
return result
def action_fetch(self):
""" The action is to check the accounts with the given
access token """
url = ('https://graph.facebook.com/v15.0/me/accounts?access_token=%s'
% self.access_token)
page = requests.get(url)
page_content = page.json()
if not page_content.get('error'):
if page_content['data'][0]['id']:
url = 'https://graph.facebook.com/v14.0/%s?fields=instagram_business_account&access_token=%s' % (
page_content['data'][0]['id'], self.access_token)
business_account = requests.get(url)
instagram_business_account = \
business_account.json()['instagram_business_account']['id']
url = ('https://graph.facebook.com/v15.0/%s?fields=name,username,biography,website,followers_count,follows_count,media_count,profile_picture_url&access_token=%s'
% (instagram_business_account, self.access_token))
val = requests.get(url)
content = val.json()
if content.get('name'):
self.name = content['name']
if content.get('username'):
self.username = content['username']
if content.get('id'):
self.account_id = content['id']
if content.get('profile_picture_url'):
img = base64.b64encode(
requests.get(content['profile_picture_url']).content)
self.profile_image_url = img
else:
raise UserError(_('%s', page_content['error']['message']))
def action_get_post(self):
""" For getting and write posts to insta post model """
url = 'https://graph.facebook.com/v15.0/%s/media?access_token=%s' % (
self.account_id, self.access_token)
content = requests.get(url, timeout=5).json()
if not content.get('error'):
post_list = [post.name for post in
self.env['insta.post'].search([])]
if content.get('data'):
for vals in content['data']:
if vals['id'] not in post_list:
url = 'https://graph.facebook.com/v14.0/%s?fields=id,caption,comments_count,is_comment_enabled,like_count,media_product_type,media_type,media_url,owner,permalink,thumbnail_url,timestamp,username&access_token=%s' % (
vals['id'], self.access_token)
media_content = requests.get(url, timeout=5).json()
if media_content.get('media_type'):
if media_content['media_type'] == 'IMAGE':
res = self.env['insta.post'].create({
'name': media_content['id'],
'profile_id': self.id,
})
image_data = base64.b64encode(requests.get(
media_content['media_url']).content)
res.write({
'post_image': image_data,
})
if media_content.get('caption'):
res.write({
'caption': media_content['caption'],
})
else:
record = self.env['insta.post'].search(
[('name', '=', vals['id'])])
record.action_update_post(self.access_token)
else:
raise UserError(_('%s', content['error']['message']))

61
all_in_one_website_kit/models/portal_dashboard_data.py

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import api, models
class PortalDashboardData(models.Model):
""" Used to set graphs in portal dashboard template """
_name = 'portal.dashboard.data'
_description = 'Portal Dashboard Data'
@api.model
def datafetch(self):
""" To fetch data of backend documents to display in the portal
dashboard depending on count of records. """
user = self.env.user
group_id = self.env.ref('base.group_user')
if group_id in user.groups_id:
all_invoice = self.env['account.move'].search_count([
('state', 'not in', ['draft', 'cancel']),
('partner_id', '=', user.partner_id.id)])
all_accounting = [all_invoice]
else:
all_invoice = self.env['account.move'].search_count([
('partner_id', '=', user.partner_id.id),
('state', 'not in', ['draft', 'cancel'])])
all_accounting = [all_invoice]
order_id = self.env['sale.order'].search_count([
('user_id', '=', user.id),
('state', 'not in', ['draft', 'sent'])])
quotations = self.env['sale.order'].search_count([
('user_id', '=', user.id), ('state', 'in', ['sent'])])
purchase_order = self.env['purchase.order'].search_count([
('user_id', '=', user.id),
('state', 'not in', ['draft', 'sent', 'to approve'])])
purchase_rfq = self.env['purchase.order'].search_count([
('user_id', '=', user.id),
('state', 'in', ['sent', 'to approve'])])
return {
'target': [order_id, quotations],
'target_po': [purchase_order, purchase_rfq],
'target_accounting': all_accounting
}

32
all_in_one_website_kit/models/product_product.py

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
class ProductProduct(models.Model):
""" Field to hide the product variants in website """
_inherit = 'product.product'
website_hide_variants = fields.Boolean(string="Hide on Website",
help="Check right if you want to "
"hide the variant in your "
"website")

33
all_in_one_website_kit/models/product_template.py

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
class ProductTemplate(models.Model):
""" Inheriting product template model for adding a field that will hide
price from website. """
_inherit = 'product.template'
price_call = fields.Boolean(string="Call for Price",
help="This will hide the price and cart button"
" from shop and customer can request by "
"calling for price")

66
all_in_one_website_kit/models/res_config_settings.py

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
""" Inherits res.config.settings to add new setting for enabling cusomer
ratings and displaying records in portal. """
_inherit = 'res.config.settings'
comment_configuration = fields.Boolean(
config_parameter='all_in_one_website_kit.comment_configuration',
string='Comment Configuration', help='Enable/ Disable the feature.')
is_show_recent_so_q = fields.Boolean(
string='Is show recent quotation and sale order table',
config_parameter='all_in_one_website_kit.is_show_recent_so_q',
help="Enable the field for show the recent quotation and"
"sale order table ")
sale_count = fields.Integer(
string='How many recent records do you want to show?',
config_parameter='all_in_one_website_kit.sale_count',
help="The field shows the number of recent records want to show")
is_show_recent_po_rfq = fields.Boolean(
string='Is show recent RFQ table?',
config_parameter='all_in_one_website_kit.is_show_recent_po_rfq',
help="Enable the field to show the recent RFQ table.")
purchase_count = fields.Integer(
string='How many recent records do you want to show?',
config_parameter='all_in_one_website_kit.purchase_count',
help="The field shows the number of purchase records want to show.")
is_show_project = fields.Boolean(
string='Is show project task table?',
config_parameter='all_in_one_website_kit.is_show_project',
help="Enable the field to show the project task table.")
project_count = fields.Integer(
string='How many recent records do you want to show?',
config_parameter='all_in_one_website_kit.project_count',
help="The field shows the recent project records want to show.")
is_show_recent_invoice_bill = fields.Boolean(
string='Is show recent invoice/bill table?',
config_parameter='all_in_one_website_kit.is_show_recent_invoice_bill',
help="Enable the field to show the recent invoice/bill.")
account_count = fields.Integer(
string='How many recent records do you want to show?',
config_parameter='all_in_one_website_kit.account_count',
help="The field shows the number of recent invoice/bill records"
"want to show.")

60
all_in_one_website_kit/models/sale_order.py

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@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):
""" Inherits sale order to add the fields comment and rating """
_inherit = 'sale.order'
comment = fields.Char(string='Comment', readonly=True,
help='The comment provided by the customer.')
rating = fields.Selection([
('1', 'Poor'), ('2', 'Too Bad'), ('3', 'Average Quality'),
('4', 'Nice'), ('5', 'Good')], string='Rating', readonly=True,
help='The rating provided by the customer.')
return_order_count = fields.Integer(compute="_compute_return_order_count",
string='Return Orders')
def _compute_return_order_count(self):
""" Method to compute return count """
sale_return_groups = self.env['sale.return'].sudo().read_group(
domain=[('order_id', '=', self.ids)],
fields=['order_id'], groupby=['order_id'])
orders = self.browse()
for group in sale_return_groups:
order_id = self.browse(group['order_id'][0])
while order_id:
if order_id in self:
order_id.return_order_count += group['order_id_count']
orders |= order_id
order_id = False
(self - orders).return_order_count = 0
def action_open_returns(self):
""" This function returns an action that displays the return orders
from sale order. """
action = self.env['ir.actions.act_window']._for_xml_id(
'all_in_one_website_kit.sale_return_action')
action['domain'] = [('order_id', '=', self.id)]
action['context'] = {'search_default_order': 1}
return action

264
all_in_one_website_kit/models/sale_return.py

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

53
all_in_one_website_kit/models/stock_picking.py

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
class StockPicking(models.Model):
""" Inheriting the model stock picking and adding custom fields """
_inherit = 'stock.picking'
return_order_id = fields.Many2one('sale.return',
string='Return order',
help="Shows the return order of current"
"transfer")
return_order_pick_id = fields.Many2one('sale.return',
string='Return order Pick',
help="Shows the return order picking"
"of current return order")
return_order_picking = fields.Boolean(string='Return order picking',
help="Helps to identify delivery and "
"return picking, if true the tra"
"nsfer is return picking else de"
"livery")
def button_validate(self):
""" Supering the function validating the stock moves """
res = super(StockPicking, self).button_validate()
for rec in self:
if rec.return_order_pick_id:
if any(line.state != 'done' for line in
rec.return_order_pick_id.stock_picking_ids):
return res
else:
rec.return_order_pick_id.write({'state': 'done'})
return res

40
all_in_one_website_kit/models/stock_return_picking.py

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

92
all_in_one_website_kit/models/website.py

@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
class Website(models.Model):
""" Inheriting Website to add contact fields """
_inherit = 'website'
mobile_number = fields.Char(string='Mobile Number',
help="Defines the mobile number")
company = fields.Boolean(string="Company Name",
help='If it is true it will show company name on '
'website')
address = fields.Boolean(string="Address",
help='If it is true it will show address on '
'website')
phone = fields.Boolean(string="Phone",
help='If it is true it will show phone number on '
'website')
mobile = fields.Boolean(string="Mobile",
help='If it is true it will show mobile '
'number on website')
email = fields.Boolean(string="Email",
help='If it is true it will show email '
'on website')
website = fields.Boolean(string="Website",
help='If it is true it will show '
'website name on website')
vat = fields.Boolean(string="VAT", help='If it is true it will show tax id '
'on website')
address_in_online = fields.Boolean(string="Address in one line",
help='If it is true it will show address'
' in one line on website')
hide_marker_icons = fields.Boolean(string="Hide Marker Icons",
help='If it is true it will hide all ico'
'ns of address on website')
show_phone_icon = fields.Boolean(string="Show Phone Icons",
help='If it is true it will show only phon'
'e icons on website')
country_flag = fields.Boolean(string="Country Flag",
help='If it is true it will '
'show country flag on website')
facebook = fields.Boolean(string="Facebook",
help='If it is true it will show '
'company name on website')
social_facebook = fields.Char(string="Facebook Account",
related='company_id.social_facebook',
readonly=False,
help="Company Facebook Account")
twitter = fields.Boolean(string="Twitter", help='If it is true it will'
'show twitter on website')
social_twitter = fields.Char(string="Twitter Account",
related='company_id.social_twitter',
readonly=False, help='Twitter account')
linked_in = fields.Boolean(string="LinkedIn",
help='If it is true it will show twitter '
'on website')
social_linked_in = fields.Char(string="Linkedin Account",
related='company_id.social_linkedin',
readonly=False, help='Linkedin account')
instagram = fields.Boolean(string="Instagram",
help='If it is true it will show twitter on '
'website')
social_instagram = fields.Char(string="Instagram Account",
related='company_id.social_instagram',
readonly=False, help='Instagram account')
git_hub = fields.Boolean(string="GitHub",
help='If it is true it will show twitter on'
' website')
social_git_hub = fields.Char(string="Github Account",
related='company_id.social_github',
readonly=False, help='Github Account')

14
all_in_one_website_kit/report/sale_return_reports.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Sales Return Report Record -->
<record id="report_sale_return" model="ir.actions.report">
<field name="name">Sale Return</field>
<field name="model">sale.return</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">all_in_one_website_kit.report_salereturn</field>
<field name="report_file">all_in_one_website_kit.report_salereturn</field>
<field name="print_report_name">'Sale Retun - %s' % object.name</field>
<field name="binding_model_id" ref="model_sale_return"/>
<field name="binding_type">report</field>
</record>
</odoo>

75
all_in_one_website_kit/report/sale_return_templates.xml

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Sales Return Report Template -->
<template id="report_salereturn">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="all_in_one_website_kit.report_sale_return_template"
t-lang="doc.partner_id.lang"/>
</t>
</t>
</template>
<template id="report_sale_return_template">
<t t-call="web.external_layout">
<t t-set="doc"
t-value="doc.with_context(lang=doc.partner_id.lang)"/>
<div class="page">
<div class="oe_structure"/>
<h2 class="mt16">
<span>Return Order #</span>
<span t-field="doc.name"/>
</h2>
<div class="row mt32 mb32" id="informations">
<div t-if="doc.partner_id"
class="col-auto col-3 mw-100 mb-2">
<strong>Customer:</strong>
<p class="m-0" t-field="doc.partner_id"/>
</div>
<div t-if="doc.order_id" class="col-auto col-3 mw-100 mb-2">
<strong>Sale Order:</strong>
<p class="m-0" t-field="doc.order_id"/>
</div>
<div t-if="doc.create_date"
class="col-auto col-3 mw-100 mb-2">
<strong>Creation Date:</strong>
<p class="m-0" t-field="doc.create_date"
t-options='{"widget": "date"}'/>
</div>
<div t-if="doc.user_id"
class="col-auto col-3 mw-100 mb-2"
name="expiration_date">
<strong>Responsible:</strong>
<p class="m-0" t-field="doc.user_id"/>
</div>
</div>
<table class="table table-sm o_main_table">
<!-- In case we want to repeat the header, remove "display: table-row-group" -->
<thead style="display: table-row-group">
<tr>
<th name="th_description" class="text-left">
Product
</th>
<th name="th_quantity" class="text-right">Quantity
</th>
</tr>
</thead>
<tbody class="sale_tbody">
<tr t-att-class="'bg-200 font-weight-bold'">
<td name="td_product">
<span t-field="doc.product_id"/>
</td>
<td name="td_quantity" class="text-right">
<span t-field="doc.quantity"/>
<span t-field="doc.product_id.uom_id"/>
</td>
</tr>
</tbody>
</table>
<div t-if="doc.partner_id" class="col-auto col-3 mw-100 mb-2">
<strong>Reason:</strong>
<p class="m-0" t-field="doc.reason"/>
</div>
</div>
</t>
</template>
</odoo>

5
all_in_one_website_kit/security/ir.model.access.csv

@ -0,0 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_call_price_user,access.call.price.user,model_call_price,base.group_user,1,1,1,1
access_sale_return_user,access.sale.return.user,model_sale_return,base.group_user,1,1,1,1
access_insta_profile_user,access.insta.profile.user,model_insta_profile,base.group_user,1,1,1,1
access_insta_post_user,access.insta.post.user,model_insta_post,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_call_price_user access.call.price.user model_call_price base.group_user 1 1 1 1
3 access_sale_return_user access.sale.return.user model_sale_return base.group_user 1 1 1 1
4 access_insta_profile_user access.insta.profile.user model_insta_profile base.group_user 1 1 1 1
5 access_insta_post_user access.insta.post.user model_insta_post base.group_user 1 1 1 1

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
all_in_one_website_kit/static/description/assets/modules/odoo_website_helpdesk.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
all_in_one_website_kit/static/description/assets/modules/odoo_website_helpdesk_dashboard.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
all_in_one_website_kit/static/description/assets/modules/product_visibility_website.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
all_in_one_website_kit/static/description/assets/modules/website_multi_product_return_management.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
all_in_one_website_kit/static/description/assets/modules/website_product_attachments.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/attachment_1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/attachment_2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/barcode1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/barcode2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/barcode3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/barcode4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/barcode5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/call_price1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/call_price2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/call_price3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/call_price4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/call_price5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/clear_cart1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/clear_cart2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/custom_contact1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/custom_contact2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/custom_contact3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/hide_variant1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/hide_variant2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/hide_variant3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/icon2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/icon3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/instagram1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/instagram2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/instagram3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/instagram4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/order_comment1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/order_comment2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/order_comment3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/portal1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/portal2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
all_in_one_website_kit/static/description/assets/screenshots/portal3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

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

Loading…
Cancel
Save