Commit b0659f54 authored by Ramón Vásquez's avatar Ramón Vásquez
Browse files

Merge branch '12.0-stage' of...

Merge branch '12.0-stage' of https://gitlab.e-mips.com.ar/rafaela-alimentos/rafalim_sale_custom into 12.0-stage
parents f13a0a5b a11076f6
......@@ -25,6 +25,9 @@ from odoo import models, fields, _, api
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
date_invoice = fields.Date(
default=fields.Date.today
)
matrix = fields.Many2one(
comodel_name='sale.order.matrix',
string='Matrix',
......@@ -49,6 +52,41 @@ class AccountInvoice(models.Model):
string='Prevision'
)
def action_invoice_open(self):
"""
The action gets overrrided to add create a prevision movement
Returns:
: the result of the super() call.
"""
res = super(AccountInvoice, self).action_invoice_open()
if res:
if self.prevision_id and self.type == 'in_invoice':
self.prevision_id.prevision_line_ids = [
(0,0, {
'invoice_id': self.id,
'document_name':self.display_name,
'prevision_amount': self.amount_no_taxed,
'date': self.date_invoice
})
]
return res
def action_invoice_cancel(self):
"""
The action gets overrrided to delete a prevision movement
Returns:
: the result of the super() call.
"""
res = super(AccountInvoice, self).action_invoice_cancel()
if res:
if self.prevision_id and self.type == 'in_invoice':
rec_id = self.env['prevision.movement'].search([
('prevision_id', '=', self.prevision_id.id),
('invoice_id', '=', self.id)
]).id
self.prevision_id.prevision_line_ids = [(3, rec_id, 0)]
return res
def _compute_picking_name(self):
picking_obj = self.env["stock.picking"]
for rec in self:
......@@ -99,6 +137,9 @@ class AccountInvoiceLine(models.Model):
agreement_obj = self.env['trade.agreement']
for line in self:
line.trade_agreement_discount = 0.00
line.trade_agreement_bonus = 0.00
partner = line.invoice_id.partner_id
date = line.invoice_id.date_invoice
agreement_domain = [
......@@ -113,20 +154,14 @@ class AccountInvoiceLine(models.Model):
agreement_domain.append(
('partner_id', '=', partner.id)
)
agreements = agreement_obj.search(agreement_domain)
else:
parent_domain = agreement_domain + [
('search_partner_by', '=', 'parent_customers'),
('partner_id', '=', partner.parent_id.id)
]
agreements = agreement_obj.search(parent_domain)
child_domain = agreement_domain + [
('search_partner_by', '=', 'any'),
('partner_id', '=', partner.id)
agreement_domain += [
'|', '&',
('search_partner_by', '=','parent_customers'),
('partner_id', '=', partner.parent_id.id),
('partner_id', '=', partner.id),
]
agreements += agreement_obj.search(child_domain)
agreements = agreement_obj.search(agreement_domain)
self.has_discount(agreements, line)
def has_discount(self, trade_agreements, line):
......@@ -150,31 +185,47 @@ class AccountInvoiceLine(models.Model):
if trade.select_table_invoice == 'agreement_heading_ids' \
or trade.select_table_fix == 'agreement_heading_ids':
percent = self.env['trade.agreement.heading'].search([
heading = self.env['trade.agreement.heading'].search([
('agreement_id', '=', trade.id),
('heading_id', '=', line.product_id.product_heading.id)
]).percent
if _type == 'return':
line.trade_agreement_discount = line.price_subtotal / percent
else:
line.trade_agreement_bonus = line.price_subtotal / percent
])
if heading: # if product heading has discount
percent_type = heading.agreement_id.percent_type
percent = {
'fix': heading.fixed_percent,
'variable': heading.variable_percent
}
if _type == 'return':
line.trade_agreement_discount += line.price_subtotal \
* (percent[percent_type] / 100)
else:
line.trade_agreement_bonus += line.price_subtotal \
* (percent[percent_type] / 100)
elif trade.select_table_invoice == 'agreement_product_ids' \
or trade.select_table_fix == 'agreement_product_ids':
percent = self.env['trade.agreement.product'].search([
product = self.env['trade.agreement.product'].search([
('agreement_id', '=', trade.id),
('product_id', '=', line.product_id.id)
]).percent
if _type == 'return':
line.trade_agreement_discount = line.price_subtotal / percent
else:
line.trade_agreement_bonus = line.price_subtotal / percent
])
if product: # if product has discount
percent_type = product.agreement_id.percent_type
percent = {
'fix': product.fixed_percent,
'variable': product.variable_percent
}
if _type == 'return':
line.trade_agreement_discount += line.price_subtotal \
* (percent[percent_type] / 100)
else:
line.trade_agreement_bonus += line.price_subtotal \
* (percent[percent_type] / 100)
elif trade.select_table_fix == 'product_type_ids' \
and line.product_id.product_type_id.id in trade.product_type_ids.ids:
if _type == 'return':
line.trade_agreement_discount = line.price_subtotal \
/ trade.fix_product_percent
line.trade_agreement_discount += line.price_subtotal \
* (trade.fix_product_percent / 100)
else:
line.trade_agreement_bonus = line.price_subtotal \
/ trade.fix_product_percent
line.trade_agreement_bonus += line.price_subtotal \
* (trade.fix_product_percent / 100)
......@@ -18,13 +18,19 @@ class Prevision(models.Model):
comodel_name='res.partner',
string='Client'
)
amount = fields.Float('Amount')
balance = fields.Float(string='Balance', compute='compute_balance')
amount = fields.Float(
string='Amount',
compute='compute_amount',
)
balance = fields.Float(
string='Balance',
compute='compute_balance',
store=True
)
prevision_line_ids = fields.One2many(
comodel_name='prevision.movement',
inverse_name='prevision_id',
string='Movements Lines',
compute='compute_movements'
)
by_vat = fields.Boolean('By Vat')
is_fixed = fields.Boolean('Is Fixed')
......@@ -95,42 +101,40 @@ class Prevision(models.Model):
'start_date': period[0],
'end_date': period[1]
})
def compute_amount(self):
"""
This method compute the balance of the prevision,
depending on the agreement type:
- If the prevision comes from a fixed agreement, the amount
is calculated dividing the total agreement amount over the
amount of periods.
- If the prevision comes from a return/bonus agreement, the amount
is calculated adding every amount of the discounted
products in the invoices during the previson's period.
"""
inv_obj = self.env['account.invoice']
for rec in self.filtered(lambda r: r.is_fixed):
agr_id = rec.trade_agreement_id
rec.amount = agr_id.agreement_fix_share_total \
/ agr_id.agreement_fix_share_months
for rec in self.filtered(lambda r: not r.is_fixed):
invoices = rec.get_invoices()
rec.amount = 0.00
if rec.trade_agreement_id.percent_type == 'fix':
rec.amount = rec.get_prevision_fix(invoices)
else:
rec.amount = rec.get_prevision_variable(invoices)
@api.depends('prevision_line_ids')
def compute_balance(self):
for rec in self:
rec.balance = rec.amount \
- sum(rec.prevision_line_ids.mapped('prevision_amount'))
@api.depends('partner_id.invoice_ids',
'partner_id.child_ids.invoice_ids')
def compute_movements(self):
pr_mv_obj = self.env['prevision.movement']
inv_obj = self.env['account.invoice']
for rec in self.filtered(lambda r:
r.state in ('active','remaining_payment')
and r.trade_agreement_id.type == 'fixed_agreement'):
inv_in_prev = pr_mv_obj.search([
('prevision_id', '=', rec.id)
]).write({'prevision_id': False})
refunds = inv_obj.search([
('prevision_id', '=', rec.id),
('state', '=', 'paid'),
# ('id', 'not in', inv_in_prev.ids)
])
for refund in refunds:
pr_mv_obj.create({
'prevision_id': rec.id,
'invoice_id': refund.id,
'date': refund.date_invoice,
'prevision_amount': refund.amount_no_taxed
})
rec.prevision_line_ids = pr_mv_obj.search([('prevision_id', '=', rec.id)])
rec.balance = rec.amount - sum(
rec.prevision_line_ids.mapped('prevision_amount')
)
def get_invoices(self):
"""
This method search the partner's paid invoices that where created
......@@ -140,13 +144,13 @@ class Prevision(models.Model):
Returns:
[]: Recordset with invoices
"""
partner = self.trade_agreement_id.partner_id
partner = self.partner_id
domain = [
('state', '=', 'paid'),
('date_invoice', '>=', self.start_date),
('date_invoice', '<=', self.end_date)
]
if self.by_vat:
children_partners = partner.child_ids.ids + [partner.id]
domain.append(('partner_id', 'in', children_partners))
......@@ -155,17 +159,17 @@ class Prevision(models.Model):
invoices = self.env['account.invoice'].search(domain)
return invoices
def get_prevision_fix(self, invoices):
prevision_amount = 0
trade = self.trade_agreement_id
if trade.select_table_fix == 'agreement_heading_ids':
prevision_amount += self.get_heading_prevision(invoices)
elif trade.select_table_fix == 'agreement_product_ids':
prevision_amount += self.get_product_prevision(invoices)
elif trade.select_table_fix == 'product_type_ids':
types_ids = trade.product_type_ids.ids
......@@ -176,7 +180,7 @@ class Prevision(models.Model):
/ trade.fix_product_percent
return prevision_amount
def get_prevision_variable(self, invoices):
prevision_amount = 0
trade = self.trade_agreement_id
......@@ -184,10 +188,7 @@ class Prevision(models.Model):
qty = 0
total = 0
for invoice in invoices:
lines = self.env['account.invoice.line'].search([
('invoice_id', '=', invoice.id)
])
for line in lines:
for line in invoice.invoice_line_ids:
box_kgs = line.product_id.product_tmpl_id.box_kgs
qty += box_kgs * line.boxes_qty
total += line.discount_price_unit
......@@ -196,19 +197,20 @@ class Prevision(models.Model):
('from_kg', '<=', qty),
('to_kg', '>=', qty)
]).percent
prevision_amount += total / percent
if percent:
prevision_amount += total / percent
elif trade.select_table == 'agreement_heading_ids':
prevision_amount += self.get_heading_prevision(invoices)
elif trade.select_table == 'agreement_product_ids':
prevision_amount += self.get_product_prevision(invoices)
elif trade.select_table == 'agreement_product_scale_ids':
qty = 0
total = 0
for invoice in invoices:
lines = self.env['account.invoice.line'].search([
('invoice_id', '=', invoice.id)
])
for line in lines:
for line in invoice.invoice_line_ids:
box_kgs = line.product_id.product_tmpl_id.box_kgs
qty += box_kgs * line.boxes_qty
total += line.discount_price_unit
......@@ -223,33 +225,41 @@ class Prevision(models.Model):
def get_heading_prevision(self, invoices):
prevision_amount = 0
trade = self.trade_agreement_id
percent_type = trade.percent_type
for invoice in invoices:
lines = self.env['account.invoice.line'].search([
('invoice_id', '=', invoice.id)
])
for line in lines:
for line in invoice.invoice_line_ids:
heading = self.env['trade.agreement.heading'].search([
('agreement_id', '=', trade.id),
('heading_id', '=', line.product_id.product_heading.id)
])
if heading:
prevision_amount += line.price_subtotal / heading.percent
percent = {
'fix': heading.fixed_percent,
'variable': heading.variable_percent
}
prevision_amount += line.price_subtotal \
* (percent[percent_type] / 100)
return prevision_amount
def get_product_prevision(self, invoices):
prevision_amount = 0
trade = self.trade_agreement_id
percent_type = trade.percent_type
for invoice in invoices:
lines = self.env['account.invoice.line'].search([
('invoice_id', '=', invoice.id)
])
for line in lines:
product = self.env['trade.agreement.heading'].search([
for line in invoice.invoice_line_ids:
product = self.env['trade.agreement.product'].search([
('agreement_id', '=', trade.id),
('product_id', '=', line.product_id.id)
])
if product:
prevision_amount += line.price_subtotal / product.percent
percent = {
'fix': product.fixed_percent,
'variable': product.variable_percent
}
prevision_amount += line.price_subtotal \
* (percent[percent_type] / 100)
return prevision_amount
def update_previsions_state(self):
......@@ -282,8 +292,14 @@ class PrevisionMovement(models.Model):
_name = 'prevision.movement'
_description = 'Provision Movement'
prevision_id = fields.Many2one(comodel_name='prevision',string='Prevision')
invoice_id = fields.Many2one(comodel_name='account.invoice', string='Invoice')
prevision_id = fields.Many2one(
comodel_name='prevision',
string='Prevision'
)
invoice_id = fields.Many2one(
comodel_name='account.invoice',
string='Invoice'
)
credit_note_id = fields.Many2one(
comodel_name='credit.note.order',
string='Credit Note'
......@@ -293,13 +309,15 @@ class PrevisionMovement(models.Model):
date = fields.Date('Date')
notes = fields.Text('Notes')
@api.onchange('invoice_id', 'credit_note_id')
def onchange_document(self):
if self.invoice:
self.document_name = self.invoice.display_name
elif self.credit_note:
self.document_name = self.credit_note.name
_sql_constraints = [
("unique_record", "UNIQUE(prevision_id, invoice_id)", _("Record already exists!")),
(
"unique_invoice",
"UNIQUE(prevision_id, invioce_id)",
"This invoice is already loaded"
),
(
"unique_credit_note",
"UNIQUE(prevision_id, credit_note_id)",
"This credit note is already loaded"
)
]
\ No newline at end of file
......@@ -22,7 +22,7 @@ from datetime import timedelta as td
from datetime import datetime
from odoo import models, fields, _, api
from odoo.exceptions import UserError, Warning
from odoo.exceptions import UserError, Warning, ValidationError
class TradeAgreement(models.Model):
......@@ -200,7 +200,7 @@ class TradeAgreement(models.Model):
)
agreement_fix_share_months = fields.Integer(
string='Months',
store=False,
store=True,
default=0.00,
compute='compute_fixed_shares'
)
......@@ -233,6 +233,15 @@ class TradeAgreement(models.Model):
'domain': {'partner_id': [('id', 'in', partner_ids)]}
}
@api.onchange('percent_type', 'select_table','return_type',
'select_table_fix','select_table_invoice')
def clear_tables(self):
self.agreement_heading_ids = [(5, 0, 0)]
self.agreement_product_ids = [(5, 0, 0)]
self.product_type_ids = [(5, 0, 0)]
self.agreement_scale_ids = [(5, 0, 0)]
self.agreement_product_scale_ids = [(5, 0, 0)]
@api.multi
def open_record(self):
return {
......@@ -284,6 +293,8 @@ class TradeAgreement(models.Model):
raise UserError(_(
'The start date must be less than the end date.'
))
# if self.return_type == 'invoice':
# self.check_overlap()
if self.type != 'fixed_agreement' and (self.fix_product_percent <= 0 and self.percent_type == 'fix'):
raise UserError(_(
......@@ -302,6 +313,91 @@ class TradeAgreement(models.Model):
return self.write({'state': 'sent'})
# def check_overlap(self):
# s_date = self.start_validity
# e_date = self.end_validity
# partner = self.partner_id
# agreement_dom = [
# ('id' , '!=', self.id),
# ('type', '!=', 'fixed_agreement'),
# ('return_type ', '=', 'invoice'),
# ]
# if self.partner_id.is_company:
# agreement_dom.append(
# ('partner_id', '=', partner.id),
# )
# else:
# agreement_dom += [
# '|', '&',
# ('search_partner_by', '=','parent_customers'),
# ('partner_id', '=', partner.parent_id.id),
# ('partner_id', '=', partner.id),
# ]
# agreements_to_check = self.env['trade.agreement'].search(agreement_dom)
# for agreement in agreements_to_check:
# start_val = agreement.start_validity
# end_val = agreement.end_validity
# if (s_date == start_val and e_date == end_val) \
# or (s_date <= start_val <= e_date) \
# or (start_val <= s_date <= end_val):
# if self.repeated_products(agreement):
# raise ValidationError(_(
# "This agreement overlaps with agreement: %s [%s - %s]\n"
# "Please change the period or the product to procede." %
# (agreement.name, start_val, end_val)
# ))
def repeated_products(self, agreement):
"""
This method checks if there are any repeated products
between the self agreement and the agreement with overlaping period.
It uses the agreement tables to create a domain to search the preducts
Args:
agreement (trade.agreement): Agreement to compare products
Returns:
bool: True if there ar more than one repeated products.
False otherwise
"""
product_obj = self.env['product.template']
product_domain = []
# we get every product with discount from the self agreement
if self.agreement_product_ids:
product_domain.append(
('id', 'in', self.agreement_product_ids.mapped('product_id').ids)
)
elif self.agreement_heading_ids:
product_domain.append(
('product_heading', 'in', self.agreement_heading_ids('heading_id').ids)
)
elif self.product_type_ids:
product_domain.append(
('product_type_id', 'in', self.product_type_ids.ids)
)
# we get the products from the overlaping agreement to see of there are repeated products
if agreement.agreement_product_ids:
product_domain.append(
('id', 'in', agreement.agreement_product_ids.mapped('product_id').ids)
)
elif agreement.agreement_heading_ids:
product_domain.append(
('product_heading', 'in', agreement.agreement_heading_ids('heading_id').ids)
)
elif agreement.product_type_ids:
product_domain.append(
('product_type_id', 'in', agreement.product_type_ids.ids)
)
repeated_products = product_obj.search(product_domain)
return len(repeated_products) > 0
@api.multi
def action_send_report(self):
"""
......@@ -416,7 +512,7 @@ class TradeAgreement(models.Model):
if self.percent_type == 'fix':
if self.select_table_fix == 'agreement_product_ids':
for line in self.agreement_product_ids:
if line.percent != self.fix_product_percent:
if line.fixed_percent != self.fix_product_percent:
raise UserError(_(
"Error ! The line with product %s doesn't match with Fix Percent. "
"Please delete line and write again" % line.product_id.name
......@@ -443,12 +539,15 @@ class TradeAgreementProduct(models.Model):
agreement_id = fields.Many2one('trade.agreement', string='Agreement')
product_id = fields.Many2one('product.template', string='Product')
percent = fields.Float(
fixed_percent = fields.Float(
string="Percent",
readonly=False,
compute='_depends_product_id',
readonly=True,
compute='_get_fixed_percent',
store=True
)
variable_percent = fields.Float(
string="Percent"
)
@api.constrains('product_id')
def _check_product_id(self):
......@@ -465,9 +564,9 @@ class TradeAgreementProduct(models.Model):
@api.one
@api.depends('product_id')
def _depends_product_id(self):
def _get_fixed_percent(self):
if self.agreement_id.percent_type == 'fix':
self.percent = self.agreement_id.fix_product_percent
self.fixed_percent = self.agreement_id.fix_product_percent
class TradeAgreementHeading(models.Model):
......@@ -476,12 +575,15 @@ class TradeAgreementHeading(models.Model):
agreement_id = fields.Many2one('trade.agreement', string='Agreement')
heading_id = fields.Many2one('product.heading', string='Product Heading')
percent = fields.Float(
fixed_percent = fields.Float(
string="Percent",
readonly=False,
compute='_depends_heading_id',
readonly=True,
compute='get_fixed_percent',
store=True
)
variable_percent = fields.Float(
string="Percent"
)
@api.constrains('heading_id')
def _check_heading_id(self):
......@@ -498,9 +600,9 @@ class TradeAgreementHeading(models.Model):
@api.one
@api.depends('heading_id')
def _depends_heading_id(self):