From 89673b0be382130e562b58055a4239c898a233ee Mon Sep 17 00:00:00 2001 From: root Date: Fri, 11 Feb 2022 16:21:32 +0000 Subject: [PATCH] don en ligne panier 3:00 --- __manifest__.py | 5 +- controllers/controllers.py | 45 ++++++++- models/__init__.py | 3 +- models/operation.py | 10 +- models/sale_order.py | 170 +++++++++++++++++++++++++++++++++ static/src/js/payment_batch.js | 7 ++ views/website_sale.xml | 45 +++++++++ 7 files changed, 276 insertions(+), 9 deletions(-) create mode 100644 models/sale_order.py create mode 100644 static/src/js/payment_batch.js create mode 100644 views/website_sale.xml diff --git a/__manifest__.py b/__manifest__.py index 85daeb3..d12647c 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -20,7 +20,7 @@ 'version': '0.1', # any module necessary for this one to work correctly - 'depends': ['base','mail','mass_mailing','donation_recurring'], + 'depends': ['base','mail','mass_mailing','donation_recurring','website_sale'], # always loaded 'data': [ @@ -36,7 +36,8 @@ 'views/templates.xml', 'views/mail_mail.xml', 'views/returnmail.xml', - 'views/payment_batch.xml' + 'views/payment_batch.xml', + 'views/website_sale.xml' ], # only loaded in demonstration mode diff --git a/controllers/controllers.py b/controllers/controllers.py index 7cd2042..56ad1bc 100644 --- a/controllers/controllers.py +++ b/controllers/controllers.py @@ -1,5 +1,48 @@ # -*- coding: utf-8 -*- -# from odoo import http +from odoo import http +from odoo.http import request +from odoo.exceptions import UserError +from odoo.addons.website_sale.controllers.main import WebsiteSale +import json + + +class SalesProduct(WebsiteSale): + + @http.route(['/shop/cart/update'], type='http', auth="public", methods=['POST'], website=True) + def cart_update(self, product_id, add_qty=1, set_qty=0, **kw): + """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) + + product_custom_attribute_values = None + if kw.get('product_custom_attribute_values'): + product_custom_attribute_values = json.loads(kw.get('product_custom_attribute_values')) + + no_variant_attribute_values = None + if kw.get('no_variant_attribute_values'): + no_variant_attribute_values = json.loads(kw.get('no_variant_attribute_values')) + product=request.env['product.product'].search([('id','=',int(product_id))]) + + donation_amount=0 + if 'donation_amount' in kw: + donation_amount=int(kw.get('donation_amount')) + + 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, + donation_amount=donation_amount + ) + + if kw.get('express'): + return request.redirect("/shop/checkout?express=1") + + return request.redirect("/shop/cart") + # class DonationQualifier(http.Controller): diff --git a/models/__init__.py b/models/__init__.py index 78754b5..cfa5438 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -10,4 +10,5 @@ from . import operation from . import mailing_mailing from . import relationship from . import returnmail -from . import payment_batch \ No newline at end of file +from . import payment_batch +from . import sale_order \ No newline at end of file diff --git a/models/operation.py b/models/operation.py index 39bf6e3..a529288 100644 --- a/models/operation.py +++ b/models/operation.py @@ -28,7 +28,7 @@ class opendons_operation(models.Model): _description = 'opération marketing : mailing, emailing evenements' _inherit = ['mail.thread'] - code=fields.Char(string='Code',required=True, translate=True,track_visibility='always') + #code=fields.Char(string='Code',required=True, translate=True,track_visibility='always') name=fields.Char(string='Name',required=True, translate=True,track_visibility='always') partner_count = fields.Integer(string="count",readonly=True) #begin_date=fields.Date(string='Date begin',required=True, translate=True,track_visibility='always') @@ -60,8 +60,8 @@ class opendons_operation(models.Model): default=_default_currency ) _sql_constraints = [ - ('name_uniq', 'unique (name)', "Name already exists !"), - ('code_uniq', 'unique (code)', "Code already exists !"), + ('name_uniq', 'unique (name)', "Name already exists !") + ] number_of_sending = fields.Integer( @@ -169,7 +169,7 @@ class opendons_operation(models.Model): vals2={} vals2['operation_id']=res.id vals2['sequence']=1 - vals2['code']='EXCL' + vals2['name']='Exclusion' vals2['exclusion']=True res2=self.env['opendons.segment'].create(vals2) @@ -207,7 +207,7 @@ class opendons_segment(models.Model): _description = 'operation marketing segment : a segment is a part of contacts selected for an operation ' _inherit = ['mail.thread'] sequence = fields.Integer(string="sequence", default=10) - code=fields.Char(string='Code',required=True, translate=True,track_visibility='always') + #code=fields.Char(string='Code',required=True, translate=True,track_visibility='always') name=fields.Char(string='Name',required=True, translate=True,track_visibility='always') exclusion=fields.Boolean(String='segment d\'exclusion',default=False,readonly=True) logical_operator = fields.Selection([('union','union'),('inter','intersection')],'Type',default='union') diff --git a/models/sale_order.py b/models/sale_order.py new file mode 100644 index 0000000..6913c8b --- /dev/null +++ b/models/sale_order.py @@ -0,0 +1,170 @@ +from odoo import models, fields, api +from odoo.exceptions import UserError, ValidationError +from psycopg2 import sql, DatabaseError +from odoo.tools.safe_eval import safe_eval, datetime + +from werkzeug import utils + + + + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + + + def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0,donation_amount=0, **kwargs): + """ Add or set product quantity, add_qty can be negative """ + self.ensure_one() + product_context = dict(self.env.context) + product_context.setdefault('lang', self.sudo().partner_id.lang) + SaleOrderLineSudo = self.env['sale.order.line'].sudo().with_context(product_context) + # change lang to get correct name of attributes/values + product_with_context = self.env['product.product'].with_context(product_context) + product = product_with_context.browse(int(product_id)) + + try: + if add_qty: + add_qty = int(add_qty) + except ValueError: + add_qty = 1 + try: + if set_qty: + set_qty = int(set_qty) + except ValueError: + set_qty = 0 + quantity = 0 + order_line = False + if self.state != 'draft': + request.session['sale_order_id'] = None + raise UserError(_('It is forbidden to modify a sales order which is not in draft status.')) + if line_id is not False: + order_line = self._cart_find_product_line(product_id, line_id, **kwargs)[:1] + + # Create line if no line with product_id can be located + if not order_line: + if not product: + raise UserError(_("The given product does not exist therefore it cannot be added to cart.")) + + no_variant_attribute_values = kwargs.get('no_variant_attribute_values') or [] + received_no_variant_values = product.env['product.template.attribute.value'].browse([int(ptav['value']) for ptav in no_variant_attribute_values]) + received_combination = product.product_template_attribute_value_ids | received_no_variant_values + product_template = product.product_tmpl_id + + # handle all cases where incorrect or incomplete data are received + combination = product_template._get_closest_possible_combination(received_combination) + + # get or create (if dynamic) the correct variant + product = product_template._create_product_variant(combination) + + if not product: + raise UserError(_("The given combination does not exist therefore it cannot be added to cart.")) + + product_id = product.id + + values = self._website_product_id_change(self.id, product_id, qty=1) + + # add no_variant attributes that were not received + for ptav in combination.filtered(lambda ptav: ptav.attribute_id.create_variant == 'no_variant' and ptav not in received_no_variant_values): + no_variant_attribute_values.append({ + 'value': ptav.id, + }) + + # save no_variant attributes values + if no_variant_attribute_values: + values['product_no_variant_attribute_value_ids'] = [ + (6, 0, [int(attribute['value']) for attribute in no_variant_attribute_values]) + ] + + # add is_custom attribute values that were not received + custom_values = kwargs.get('product_custom_attribute_values') or [] + received_custom_values = product.env['product.template.attribute.value'].browse([int(ptav['custom_product_template_attribute_value_id']) for ptav in custom_values]) + + for ptav in combination.filtered(lambda ptav: ptav.is_custom and ptav not in received_custom_values): + custom_values.append({ + 'custom_product_template_attribute_value_id': ptav.id, + 'custom_value': '', + }) + + # save is_custom attributes values + if custom_values: + values['product_custom_attribute_value_ids'] = [(0, 0, { + 'custom_product_template_attribute_value_id': custom_value['custom_product_template_attribute_value_id'], + 'custom_value': custom_value['custom_value'] + }) for custom_value in custom_values] + + if donation_amount>0: + values['product_uom_qty']=1 + values['price_unit']=int(donation_amount) + values['price_total']=int(donation_amount) + + # create the line + order_line = SaleOrderLineSudo.create(values) + + try: + order_line._compute_tax_id() + except ValidationError as e: + # The validation may occur in backend (eg: taxcloud) but should fail silently in frontend + _logger.debug("ValidationError occurs during tax compute. %s" % (e)) + if add_qty: + add_qty -= 1 + + # compute new quantity + if set_qty: + quantity = set_qty + elif add_qty is not None: + quantity = order_line.product_uom_qty + (add_qty or 0) + + # Remove zero of negative lines + if quantity <= 0: + linked_line = order_line.linked_line_id + order_line.unlink() + if linked_line: + # update description of the parent + linked_product = product_with_context.browse(linked_line.product_id.id) + linked_line.name = linked_line.get_sale_order_line_multiline_description_sale(linked_product) + else: + # update line + no_variant_attributes_price_extra = [ptav.price_extra for ptav in order_line.product_no_variant_attribute_value_ids] + values = self.with_context(no_variant_attributes_price_extra=tuple(no_variant_attributes_price_extra))._website_product_id_change(self.id, product_id, qty=quantity) + if self.pricelist_id.discount_policy == 'with_discount' and not self.env.context.get('fixed_price'): + order = self.sudo().browse(self.id) + product_context.update({ + 'partner': order.partner_id, + 'quantity': quantity, + 'date': order.date_order, + 'pricelist': order.pricelist_id.id, + }) + product_with_context = self.env['product.product'].with_context(product_context).with_company(order.company_id.id) + product = product_with_context.browse(product_id) + values['price_unit'] = self.env['account.tax']._fix_tax_included_price_company( + order_line._get_display_price(product), + order_line.product_id.taxes_id, + order_line.tax_id, + self.company_id + ) + if donation_amount>0: + values['product_uom_qty']=1 + values['price_unit']=int(donation_amount) + values['price_total']=int(donation_amount) + order_line.write(values) + + # link a product to the sales order + if kwargs.get('linked_line_id'): + linked_line = SaleOrderLineSudo.browse(kwargs['linked_line_id']) + order_line.write({ + 'linked_line_id': linked_line.id, + }) + linked_product = product_with_context.browse(linked_line.product_id.id) + linked_line.name = linked_line.get_sale_order_line_multiline_description_sale(linked_product) + # Generate the description with everything. This is done after + # creating because the following related fields have to be set: + # - product_no_variant_attribute_value_ids + # - product_custom_attribute_value_ids + # - linked_line_id + order_line.name = order_line.get_sale_order_line_multiline_description_sale(product) + + option_lines = self.order_line.filtered(lambda l: l.linked_line_id.id == order_line.id) + + return {'line_id': order_line.id, 'quantity': quantity, 'option_ids': list(set(option_lines.ids))} \ No newline at end of file diff --git a/static/src/js/payment_batch.js b/static/src/js/payment_batch.js new file mode 100644 index 0000000..fbb818d --- /dev/null +++ b/static/src/js/payment_batch.js @@ -0,0 +1,7 @@ +odoo.define('opendons.payment_batch', function (require) { + "use strict"; + + //opendons + + +}); \ No newline at end of file diff --git a/views/website_sale.xml b/views/website_sale.xml new file mode 100644 index 0000000..09bdbf5 --- /dev/null +++ b/views/website_sale.xml @@ -0,0 +1,45 @@ + + + + + + + + \ No newline at end of file