Juliana
5 years ago
7 changed files with 134 additions and 285 deletions
-
1__init__.py
-
2models/__init__.py
-
46models/product_pack_line.py
-
133models/sale_order.py
-
84models/sale_order_line.py
-
4wizard/__init__.py
-
145wizard/sale_make_invoice_advance.py
@ -1,4 +1,3 @@ |
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). |
|||
|
|||
from . import models |
|||
from . import wizard |
@ -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) |
@ -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) |
@ -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 |
@ -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, |
|||
# } |
Write
Preview
Loading…
Cancel
Save
Reference in new issue