add website_decimal_quantity
This commit is contained in:
parent
0323b6672e
commit
9d69e5f095
67 changed files with 1858 additions and 0 deletions
23
website_decimal_quantity/controllers/__init__.py
Normal file
23
website_decimal_quantity/controllers/__init__.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#############################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Vivek @ cybrosys,(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 main
|
||||
from . import website_sale_product_configurator
|
||||
202
website_decimal_quantity/controllers/main.py
Normal file
202
website_decimal_quantity/controllers/main.py
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#############################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Vivek @ cybrosys,(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
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from werkzeug.exceptions import NotFound
|
||||
from odoo.tools.json import scriptsafe as json_scriptsafe
|
||||
from odoo.addons.payment import utils as payment_utils
|
||||
from odoo.addons.website_sale.controllers.main import WebsiteSale
|
||||
|
||||
|
||||
class WebsiteSaleDecimal(WebsiteSale):
|
||||
"""
|
||||
WebsiteSaleDecimal extends WebsiteSale class to update the methods: cart, cart_update,
|
||||
cart_update_json and cart_quantity.
|
||||
"""
|
||||
@http.route()
|
||||
def cart(self, access_token=None, revive='', **post):
|
||||
"""
|
||||
Main cart management + abandoned cart revival
|
||||
access_token: Abandoned cart SO access token
|
||||
revive: Revival method when abandoned cart. Can be 'merge' or 'squash'
|
||||
"""
|
||||
order = request.website.sale_get_order()
|
||||
if order and order.state != 'draft':
|
||||
request.session['sale_order_id'] = None
|
||||
order = request.website.sale_get_order()
|
||||
request.session['website_sale_cart_quantity'] = \
|
||||
round(sum(order.mapped('website_order_line.product_uom_qty')), 1)
|
||||
|
||||
values = {}
|
||||
if access_token:
|
||||
abandoned_order = request.env['sale.order'].sudo().search(
|
||||
[('access_token', '=', access_token)], limit=1)
|
||||
if not abandoned_order:
|
||||
raise NotFound()
|
||||
if abandoned_order.state != 'draft':
|
||||
values.update({'abandoned_proceed': True})
|
||||
elif revive == 'squash' or (
|
||||
revive == 'merge' and not request.session.get(
|
||||
'sale_order_id')):
|
||||
request.session['sale_order_id'] = abandoned_order.id
|
||||
return request.redirect('/shop/cart')
|
||||
elif revive == 'merge':
|
||||
abandoned_order.order_line.write(
|
||||
{'order_id': request.session['sale_order_id']})
|
||||
abandoned_order.action_cancel()
|
||||
elif abandoned_order.id != request.session.get(
|
||||
'sale_order_id'):
|
||||
values.update({'access_token': abandoned_order.access_token})
|
||||
|
||||
values.update({
|
||||
'website_sale_order': order,
|
||||
'date': fields.Date.today(),
|
||||
'suggested_products': [],
|
||||
})
|
||||
if order:
|
||||
order.order_line.filtered(
|
||||
lambda l: not l.product_id.active).unlink()
|
||||
values['suggested_products'] = order._cart_accessories()
|
||||
values.update(self._get_express_shop_payment_values(order))
|
||||
|
||||
if post.get('type') == 'popover':
|
||||
# force no-cache so IE11 doesn't cache this XHR
|
||||
return request.render("website_sale.cart_popover", values,
|
||||
headers={'Cache-Control': 'no-cache'})
|
||||
|
||||
return request.render("website_sale.cart", values)
|
||||
|
||||
@http.route()
|
||||
def cart_update(
|
||||
self, product_id, add_qty=1, set_qty=0,
|
||||
product_custom_attribute_values=None, no_variant_attribute_values=None,
|
||||
express=False, **kwargs
|
||||
):
|
||||
"""This route is called when adding a product to cart (no options)."""
|
||||
sale_order = request.website.sale_get_order(force_create=True)
|
||||
if sale_order.state != 'draft':
|
||||
request.session['sale_order_id'] = None
|
||||
sale_order = request.website.sale_get_order(force_create=True)
|
||||
|
||||
if product_custom_attribute_values:
|
||||
product_custom_attribute_values = \
|
||||
json_scriptsafe.loads(product_custom_attribute_values)
|
||||
|
||||
if no_variant_attribute_values:
|
||||
no_variant_attribute_values = \
|
||||
json_scriptsafe.loads(no_variant_attribute_values)
|
||||
|
||||
sale_order._cart_update(
|
||||
product_id=int(product_id),
|
||||
add_qty=add_qty,
|
||||
set_qty=set_qty,
|
||||
product_custom_attribute_values=product_custom_attribute_values,
|
||||
no_variant_attribute_values=no_variant_attribute_values,
|
||||
**kwargs
|
||||
)
|
||||
request.session['website_sale_cart_quantity'] = round(
|
||||
sum(sale_order.mapped('website_order_line.product_uom_qty')), 1)
|
||||
|
||||
if express:
|
||||
return request.redirect("/shop/checkout?express=1")
|
||||
|
||||
return request.redirect("/shop/cart")
|
||||
|
||||
@http.route()
|
||||
def cart_update_json(
|
||||
self, product_id, line_id=None, add_qty=None, set_qty=None,
|
||||
display=True, product_custom_attribute_values=None,
|
||||
no_variant_attribute_values=None, **kw
|
||||
):
|
||||
"""
|
||||
This route is called :
|
||||
- When changing quantity from the cart.
|
||||
- When adding a product from the wishlist.
|
||||
- When adding a product to cart on the same page
|
||||
(without redirection).
|
||||
"""
|
||||
order = request.website.sale_get_order(force_create=True)
|
||||
if order.state != 'draft':
|
||||
request.website.sale_reset()
|
||||
if kw.get('force_create'):
|
||||
order = request.website.sale_get_order(force_create=True)
|
||||
else:
|
||||
return {}
|
||||
|
||||
if product_custom_attribute_values:
|
||||
product_custom_attribute_values = \
|
||||
json_scriptsafe.loads(product_custom_attribute_values)
|
||||
|
||||
if no_variant_attribute_values:
|
||||
no_variant_attribute_values = \
|
||||
json_scriptsafe.loads(no_variant_attribute_values)
|
||||
|
||||
values = order._cart_update(
|
||||
product_id=product_id,
|
||||
line_id=line_id,
|
||||
add_qty=add_qty,
|
||||
set_qty=set_qty,
|
||||
product_custom_attribute_values=product_custom_attribute_values,
|
||||
no_variant_attribute_values=no_variant_attribute_values,
|
||||
**kw
|
||||
)
|
||||
request.session['website_sale_cart_quantity'] = round(
|
||||
sum(order.mapped('website_order_line.product_uom_qty')), 1)
|
||||
|
||||
if not order.cart_quantity:
|
||||
request.website.sale_reset()
|
||||
return values
|
||||
|
||||
values['cart_quantity'] = round(
|
||||
sum(order.mapped('website_order_line.product_uom_qty')), 1)
|
||||
values['minor_amount'] = payment_utils.to_minor_currency_units(
|
||||
order.amount_total, order.currency_id
|
||||
),
|
||||
values['amount'] = order.amount_total
|
||||
|
||||
if not display:
|
||||
return values
|
||||
|
||||
values['website_sale.cart_lines'] = \
|
||||
request.env['ir.ui.view']._render_template(
|
||||
"website_sale.cart_lines", {
|
||||
'website_sale_order': order,
|
||||
'date': fields.Date.today(),
|
||||
'suggested_products': order._cart_accessories()
|
||||
}
|
||||
)
|
||||
values['website_sale.short_cart_summary'] = \
|
||||
request.env['ir.ui.view']._render_template(
|
||||
"website_sale.short_cart_summary", {'website_sale_order': order}
|
||||
)
|
||||
return values
|
||||
|
||||
@http.route()
|
||||
def cart_quantity(self):
|
||||
"""
|
||||
This method updates the cart quantity count in the session based on the order's website order lines.
|
||||
"""
|
||||
if 'website_sale_cart_quantity' not in request.session:
|
||||
return request.website.sale_get_order().mapped(
|
||||
'website_order_line.product_uom_qty')
|
||||
return request.session['website_sale_cart_quantity']
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#############################################################################
|
||||
#
|
||||
# Cybrosys Technologies Pvt. Ltd.
|
||||
#
|
||||
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
||||
# Author: Vivek @ cybrosys,(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 json
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.addons.website_sale_product_configurator.controllers.main import \
|
||||
WebsiteSale
|
||||
|
||||
|
||||
class WebsiteSaleDecimal(WebsiteSale):
|
||||
"""
|
||||
WebsiteSaleDecimal extends WebsiteSale class to update the methods: cart_options_update_json.
|
||||
"""
|
||||
@http.route()
|
||||
def cart_options_update_json(self, product_and_options, goto_shop=None,
|
||||
lang=None, **kwargs):
|
||||
"""This route is called when submitting the optional product modal.
|
||||
The product without parent is the main product, the other are
|
||||
options.
|
||||
Options need to be linked to their parents with a unique ID.
|
||||
The main product is the first product in the list and the options
|
||||
need to be right after their parent.
|
||||
product_and_options {
|
||||
'product_id',
|
||||
'product_template_id',
|
||||
'quantity',
|
||||
'parent_unique_id',
|
||||
'unique_id',
|
||||
'product_custom_attribute_values',
|
||||
'no_variant_attribute_values'
|
||||
}
|
||||
"""
|
||||
if lang:
|
||||
request.website = request.website.with_context(lang=lang)
|
||||
|
||||
order = request.website.sale_get_order(force_create=True)
|
||||
if order.state != 'draft':
|
||||
request.session['sale_order_id'] = None
|
||||
order = request.website.sale_get_order(force_create=True)
|
||||
|
||||
product_and_options = json.loads(product_and_options)
|
||||
if product_and_options:
|
||||
# The main product is the first, optional products are the rest
|
||||
main_product = product_and_options[0]
|
||||
value = order._cart_update(
|
||||
product_id=main_product['product_id'],
|
||||
add_qty=main_product['quantity'],
|
||||
product_custom_attribute_values=main_product[
|
||||
'product_custom_attribute_values'],
|
||||
no_variant_attribute_values=main_product[
|
||||
'no_variant_attribute_values'],
|
||||
**kwargs
|
||||
)
|
||||
|
||||
if value['line_id']:
|
||||
# Link option with its parent iff line has been created.
|
||||
option_parent = {main_product['unique_id']: value['line_id']}
|
||||
for option in product_and_options[1:]:
|
||||
parent_unique_id = option['parent_unique_id']
|
||||
option_value = order._cart_update(
|
||||
product_id=option['product_id'],
|
||||
set_qty=option['quantity'],
|
||||
linked_line_id=option_parent[parent_unique_id],
|
||||
product_custom_attribute_values=option[
|
||||
'product_custom_attribute_values'],
|
||||
no_variant_attribute_values=option[
|
||||
'no_variant_attribute_values'],
|
||||
**kwargs
|
||||
)
|
||||
option_parent[option['unique_id']] = option_value['line_id']
|
||||
request.session['website_sale_cart_quantity'] = round(
|
||||
sum(order.mapped('website_order_line.product_uom_qty')), 1)
|
||||
|
||||
return str(round(
|
||||
sum(order.mapped('website_order_line.product_uom_qty')), 1))
|
||||
Loading…
Add table
Add a link
Reference in a new issue