From 578ba5275cadb9ada04209ffbb6c058d28c7aaa9 Mon Sep 17 00:00:00 2001 From: Juliana Date: Wed, 8 Apr 2020 15:47:11 +0200 Subject: [PATCH] Modif hors prise en compte modif OCA pack --- __init__.py | 1 - models/__init__.py | 4 +- models/product_pack_line.py | 46 +++++++++ models/sale_order.py | 135 +------------------------- models/sale_order_line.py | 84 ++++++++++++++++ wizard/__init__.py | 4 - wizard/sale_make_invoice_advance.py | 145 ---------------------------- 7 files changed, 134 insertions(+), 285 deletions(-) create mode 100644 models/product_pack_line.py create mode 100644 models/sale_order_line.py delete mode 100644 wizard/__init__.py delete mode 100644 wizard/sale_make_invoice_advance.py diff --git a/__init__.py b/__init__.py index 10c548c..31660d6 100644 --- a/__init__.py +++ b/__init__.py @@ -1,4 +1,3 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import models -from . import wizard \ No newline at end of file diff --git a/models/__init__.py b/models/__init__.py index 94e27f1..8b9e6d4 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -2,4 +2,6 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # # from . import product_product -from . import sale_order \ No newline at end of file +from . import sale_order +from . import sale_order_line +from . import product_pack_line \ No newline at end of file diff --git a/models/product_pack_line.py b/models/product_pack_line.py new file mode 100644 index 0000000..ce8dd01 --- /dev/null +++ b/models/product_pack_line.py @@ -0,0 +1,46 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import api, fields, models +import odoo.addons.decimal_precision as dp + + +class ProductPack(models.Model): + _inherit = 'product.pack.line' + + @api.multi + def get_sale_order_line_vals(self, line, order): + self.ensure_one() + vals = super().get_sale_order_line_vals(line, order) + + quantity = self.quantity * line.product_uom_qty + line_vals = { + 'order_id': order.id, + 'product_id': self.product_id.id or False, + 'pack_parent_line_id': line.id, + 'pack_depth': line.pack_depth + 1, + 'company_id': order.company_id.id, + } + sol = line.new(line_vals) + sol.product_id_change() + sol.product_uom_qty = quantity + sol.product_uom_change() + sol._onchange_discount() + vals = sol._convert_to_write(sol._cache) + + sale_discount = 0.0 + if (line.product_id.pack_component_price == 'detailed'): + sale_discount = 100.0 - ( + (100.0 - sol.discount) * (100.0 - self.sale_discount) / 100.0) + + vals.update({ + 'discount': sale_discount, + 'name': '%s%s' % ( + '> ' * (line.pack_depth + 1), sol.name + ), + }) + return vals + + @api.multi + def get_price(self): + self.ensure_one() + return super().get_price() * (1 - self.sale_discount / 100.0) diff --git a/models/sale_order.py b/models/sale_order.py index a710ba7..857101d 100644 --- a/models/sale_order.py +++ b/models/sale_order.py @@ -4,17 +4,6 @@ from odoo import models, fields, api -class AccountInvoice(models.Model): - _inherit = "account.invoice" - - @api.model - def create(self, vals): - invoice = super(AccountInvoice, self).create(vals) - print("---- invoice -----", str(invoice)) - print("---- invoice line -----", str(invoice.invoice_line_ids)) - return invoice - - class SaleOrder(models.Model): _inherit = "sale.order" @@ -22,126 +11,4 @@ class SaleOrder(models.Model): def _compute_website_order_line(self): self.website_order_line = self.order_line.filtered( lambda t: not t.pack_parent_line_id.exists(), - ) - - @api.multi - def action_invoice_create(self, grouped=False, final=False): - res = super(SaleOrder, self).action_invoice_create(grouped, final) - print("------ res ------", str(res)) - print("------ grouped ------", str(grouped)) - print("------ final ------", str(final)) - return res -# """ -# Create the invoice associated to the SO. -# :param grouped: if True, invoices are grouped by SO id. If False, invoices are grouped by -# (partner_invoice_id, currency) -# :param final: if True, refunds will be generated if necessary -# :returns: list of created invoices -# """ -# res = super(SaleOrder, self).action_invoice_create(grouped, final) -# inv_obj = self.env['account.invoice'] -# precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') -# invoices = {} -# references = {} -# invoices_origin = {} -# invoices_name = {} - -# for order in self: -# group_key = order.id if grouped else (order.partner_invoice_id.id, order.currency_id.id) - -# # We only want to create sections that have at least one invoiceable line -# pending_section = None - -# for line in order.order_line: -# print("---line---", str(line)) -# if line.display_type == 'line_section': -# pending_section = line -# continue -# if group_key not in invoices: -# inv_data = order._prepare_invoice() -# invoice = inv_obj.create(inv_data) -# references[invoice] = order -# invoices[group_key] = invoice -# invoices_origin[group_key] = [invoice.origin] -# invoices_name[group_key] = [invoice.name] -# elif group_key in invoices: -# if order.name not in invoices_origin[group_key]: -# invoices_origin[group_key].append(order.name) -# if order.client_order_ref and order.client_order_ref not in invoices_name[group_key]: -# invoices_name[group_key].append(order.client_order_ref) - -# if line.qty_to_invoice > 0 or (line.qty_to_invoice < 0 and final): -# print("---invoice lune create---", str(line)) -# if pending_section: -# pending_section.invoice_line_create(invoices[group_key].id, pending_section.qty_to_invoice) -# pending_section = None -# line.invoice_line_create(invoices[group_key].id, line.qty_to_invoice) - -# if references.get(invoices.get(group_key)): -# if order not in references[invoices[group_key]]: -# references[invoices[group_key]] |= order - -# for group_key in invoices: -# invoices[group_key].write({'name': ', '.join(invoices_name[group_key]), -# 'origin': ', '.join(invoices_origin[group_key])}) -# sale_orders = references[invoices[group_key]] -# if len(sale_orders) == 1: -# invoices[group_key].reference = sale_orders.reference - -# # if not invoices: -# # raise UserError(_('There is no invoiceable line. If a product has a Delivered quantities invoicing policy, please make sure that a quantity has been delivered.')) - -# for invoice in invoices.values(): -# print("--- invoice ---", str(invoice)) -# invoice.compute_taxes() -# if not invoice.invoice_line_ids: -# raise UserError(_('There is no invoiceable line. If a product has a Delivered quantities invoicing policy, please make sure that a quantity has been delivered.')) -# # If invoice is negative, do a refund invoice instead -# if invoice.amount_total < 0: -# invoice.type = 'out_refund' -# for line in invoice.invoice_line_ids: -# line.quantity = -line.quantity -# # Use additional field helper function (for account extensions) -# for line in invoice.invoice_line_ids: -# line._set_additional_fields(invoice) -# # Necessary to force computation of taxes. In account_invoice, they are triggered -# # by onchanges, which are not triggered when doing a create. -# invoice.compute_taxes() -# # Idem for partner -# so_payment_term_id = invoice.payment_term_id.id -# invoice._onchange_partner_id() -# # To keep the payment terms set on the SO -# invoice.payment_term_id = so_payment_term_id -# invoice.message_post_with_view('mail.message_origin_link', -# values={'self': invoice, 'origin': references[invoice]}, -# subtype_id=self.env.ref('mail.mt_note').id) -# return [inv.id for inv in invoices.values()] - - -class SaleOrderLine(models.Model): - _inherit = "sale.order.line" - - @api.multi - def invoice_line_create(self, invoice_id, qty): - print("---- TEST sans rien----") - print("---- TEST ----", str(invoice_id)) - invoice_lines = super(SaleOrderLine, self).invoice_line_create( - invoice_id, qty) - print("---- invoice_lines ----", str(invoice_lines)) - return invoice_lines - # invoice_lines = self.env['account.invoice.line'] - # for line in self: - # # Check if line has a pack_parent_line_id - # print("---- self.pack_parent_line_id.exists() -----", str(self.pack_parent_line_id.exists())) - # if self.pack_parent_line_id.exists(): - # # Get the ref of parent pack - # sale_id_ref = self.env['sale.order.line'].search([('id', '=', self.pack_parent_line_id.id)]) - # print("--- sale_id_ref ---", str(sale_id_ref)) - # print("--- sale_id_ref.product_id.product_tmpl_id.pack_type ---", str(sale_id_ref.product_id.product_tmpl_id.pack_type)) - # print("--- sale_id_ref.product_id.product_tmpl_id.pack_component_price ---", str(sale_id_ref.product_id.product_tmpl_id.pack_component_price)) - # # Check if product is Pack detailed and option Totalized - # if sale_id_ref.product_id.product_tmpl_id.pack_type == 'detailed' and sale_id_ref.product_id.product_tmpl_id.pack_component_price == 'totalized': - # return invoice_lines - # invoice_lines = super(SaleOrderLine, self).invoice_line_create( - # invoice_id, qty) - # return invoice_lines \ No newline at end of file + ) \ No newline at end of file diff --git a/models/sale_order_line.py b/models/sale_order_line.py new file mode 100644 index 0000000..50721e3 --- /dev/null +++ b/models/sale_order_line.py @@ -0,0 +1,84 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import fields, models, api, _ +from odoo.exceptions import UserError + + +class SaleOrderLine(models.Model): + _inherit = 'sale.order.line' + + @api.multi + def expand_pack_line(self, write=False): + self.ensure_one() + # if we are using update_pricelist or checking out on ecommerce we + # only want to update prices + do_not_expand = self._context.get('update_prices') or \ + self._context.get('update_pricelist', False) + if ( + self.state == 'draft' and + self.product_id.pack_ok and + self.pack_type == 'detailed'): + for subline in self.product_id.get_pack_lines(): + vals = subline.get_sale_order_line_vals(self, self.order_id) + vals['sequence'] = self.sequence + vals['active'] = False + if write: + existing_subline = self.search([ + ('product_id', '=', subline.product_id.id), + ('pack_parent_line_id', '=', self.id), + ], limit=1) + # if subline already exists we update, if not we create + if existing_subline: + if do_not_expand: + vals.pop('product_uom_qty') + existing_subline.write(vals) + elif not do_not_expand: + self.create(vals) + else: + self.create(vals) + + @api.model + def create(self, vals): + record = super().create(vals) + record.expand_pack_line() + return record + + @api.multi + def write(self, vals): + super().write(vals) + if 'product_id' in vals or 'product_uom_qty' in vals: + for record in self: + record.expand_pack_line(write=True) + + def _get_real_price_currency( + self, product, rule_id, qty, uom, pricelist_id): + new_list_price, currency_id = super()._get_real_price_currency( + product, rule_id, qty, uom, pricelist_id) + pack_types = {'totalized', 'ignored'} + parent_line = self.pack_parent_line_id + if parent_line and parent_line.pack_type == 'details' \ + and parent_line.pack_component_price in pack_types: + new_list_price = 0.0 + return new_list_price, currency_id + + @api.onchange('product_id', 'product_uom_qty', 'product_uom', 'price_unit', + 'discount', 'name', 'tax_id') + def check_pack_line_modify(self): + """ Do not let to edit a sale order line if this one belongs to pack + """ + if self._origin.pack_parent_line_id and \ + not self._origin.pack_parent_line_id.product_id.pack_modifiable: + raise UserError(_( + 'You can not change this line because is part of a pack' + ' included in this order')) + + @api.multi + def _get_display_price(self, product): + # We do this to clean the price if the parent of the + # component it's that type + pack_types = {'totalized', 'ignored'} + parent_line = self.pack_parent_line_id + if parent_line.pack_type == 'detailed' \ + and parent_line.pack_component_price in pack_types: + return 0.0 + return super()._get_display_price(product) diff --git a/wizard/__init__.py b/wizard/__init__.py deleted file mode 100644 index e14586d..0000000 --- a/wizard/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from . import sale_make_invoice_advance \ No newline at end of file diff --git a/wizard/sale_make_invoice_advance.py b/wizard/sale_make_invoice_advance.py deleted file mode 100644 index 2ea9afe..0000000 --- a/wizard/sale_make_invoice_advance.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -import time - -from odoo import api, fields, models, _ -from odoo.addons import decimal_precision as dp -from odoo.exceptions import UserError - - -class SaleAdvancePaymentInv(models.TransientModel): - _inherit = "sale.advance.payment.inv" - - @api.multi - def _create_invoice(self, order, so_line, amount): - print("---- _create_invoice ----") - return super(SaleAdvancePaymentInv, self)._create_invoice(order, so_line, amount) - # inv_obj = self.env['account.invoice'] - # ir_property_obj = self.env['ir.property'] - - # account_id = False - # if self.product_id.id: - # account_id = self.product_id.property_account_income_id.id or self.product_id.categ_id.property_account_income_categ_id.id - # if not account_id: - # inc_acc = ir_property_obj.get('property_account_income_categ_id', 'product.category') - # account_id = order.fiscal_position_id.map_account(inc_acc).id if inc_acc else False - # if not account_id: - # raise UserError( - # _('There is no income account defined for this product: "%s". You may have to install a chart of account from Accounting app, settings menu.') % - # (self.product_id.name,)) - - # if self.amount <= 0.00: - # raise UserError(_('The value of the down payment amount must be positive.')) - # context = {'lang': order.partner_id.lang} - # if self.advance_payment_method == 'percentage': - # amount = order.amount_untaxed * self.amount / 100 - # name = _("Down payment of %s%%") % (self.amount,) - # else: - # amount = self.amount - # name = _('Down Payment') - # del context - # taxes = self.product_id.taxes_id.filtered(lambda r: not order.company_id or r.company_id == order.company_id) - # if order.fiscal_position_id and taxes: - # tax_ids = order.fiscal_position_id.map_tax(taxes, self.product_id, order.partner_shipping_id).ids - # else: - # tax_ids = taxes.ids - - # invoice = inv_obj.create({ - # 'name': order.client_order_ref or order.name, - # 'origin': order.name, - # 'type': 'out_invoice', - # 'reference': False, - # 'account_id': order.partner_id.property_account_receivable_id.id, - # 'partner_id': order.partner_invoice_id.id, - # 'partner_shipping_id': order.partner_shipping_id.id, - # 'invoice_line_ids': [(0, 0, { - # 'name': name, - # 'origin': order.name, - # 'account_id': account_id, - # 'price_unit': amount, - # 'quantity': 1.0, - # 'discount': 0.0, - # 'uom_id': self.product_id.uom_id.id, - # 'product_id': self.product_id.id, - # 'sale_line_ids': [(6, 0, [so_line.id])], - # 'invoice_line_tax_ids': [(6, 0, tax_ids)], - # 'analytic_tag_ids': [(6, 0, so_line.analytic_tag_ids.ids)], - # 'account_analytic_id': order.analytic_account_id.id or False, - # })], - # 'currency_id': order.pricelist_id.currency_id.id, - # 'payment_term_id': order.payment_term_id.id, - # 'fiscal_position_id': order.fiscal_position_id.id or order.partner_id.property_account_position_id.id, - # 'team_id': order.team_id.id, - # 'user_id': order.user_id.id, - # 'comment': order.note, - # }) - # invoice.compute_taxes() - # invoice.message_post_with_view('mail.message_origin_link', - # values={'self': invoice, 'origin': order}, - # subtype_id=self.env.ref('mail.mt_note').id) - # return invoice - - @api.multi - def create_invoices(self): - print("---- create_invoices ----") - return super(SaleAdvancePaymentInv, self).create_invoices() - # sale_orders = self.env['sale.order'].browse(self._context.get('active_ids', [])) - - # if self.advance_payment_method == 'delivered': - # sale_orders.action_invoice_create() - # elif self.advance_payment_method == 'all': - # sale_orders.action_invoice_create(final=True) - # else: - # # Create deposit product if necessary - # if not self.product_id: - # vals = self._prepare_deposit_product() - # self.product_id = self.env['product.product'].create(vals) - # self.env['ir.config_parameter'].sudo().set_param('sale.default_deposit_product_id', self.product_id.id) - - # sale_line_obj = self.env['sale.order.line'] - # for order in sale_orders: - # if self.advance_payment_method == 'percentage': - # amount = order.amount_untaxed * self.amount / 100 - # else: - # amount = self.amount - # if self.product_id.invoice_policy != 'order': - # raise UserError(_('The product used to invoice a down payment should have an invoice policy set to "Ordered quantities". Please update your deposit product to be able to create a deposit invoice.')) - # if self.product_id.type != 'service': - # raise UserError(_("The product used to invoice a down payment should be of type 'Service'. Please use another product or update this product.")) - # taxes = self.product_id.taxes_id.filtered(lambda r: not order.company_id or r.company_id == order.company_id) - # if order.fiscal_position_id and taxes: - # tax_ids = order.fiscal_position_id.map_tax(taxes, self.product_id, order.partner_shipping_id).ids - # else: - # tax_ids = taxes.ids - # context = {'lang': order.partner_id.lang} - # analytic_tag_ids = [] - # for line in order.order_line: - # analytic_tag_ids = [(4, analytic_tag.id, None) for analytic_tag in line.analytic_tag_ids] - # so_line = sale_line_obj.create({ - # 'name': _('Advance: %s') % (time.strftime('%m %Y'),), - # 'price_unit': amount, - # 'product_uom_qty': 0.0, - # 'order_id': order.id, - # 'discount': 0.0, - # 'product_uom': self.product_id.uom_id.id, - # 'product_id': self.product_id.id, - # 'analytic_tag_ids': analytic_tag_ids, - # 'tax_id': [(6, 0, tax_ids)], - # 'is_downpayment': True, - # }) - # del context - # self._create_invoice(order, so_line, amount) - # if self._context.get('open_invoices', False): - # return sale_orders.action_view_invoice() - # return {'type': 'ir.actions.act_window_close'} - - # def _prepare_deposit_product(self): - # return { - # 'name': 'Down payment', - # 'type': 'service', - # 'invoice_policy': 'order', - # 'property_account_income_id': self.deposit_account_id.id, - # 'taxes_id': [(6, 0, self.deposit_taxes_id.ids)], - # 'company_id': False, - # }