Fix liquidaciones. Cambia los creates a multi para evitar el warning.

Añade campos is desit y última fecha de liquidación a purchase.order. Se
asegura de linkar la línea de invoice con la línea de purchase order.
This commit is contained in:
snt 2024-09-20 16:11:57 +02:00
parent 5234d8ffc8
commit f9f99116bf
5 changed files with 138 additions and 101 deletions

View file

@ -2,34 +2,33 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api from odoo import models, fields, api
from odoo.exceptions import ValidationError, Warning from odoo.exceptions import ValidationError
import pdb
import logging
_logger = logging.getLogger(__name__)
class PurchaseOrde(models.Model): class PurchaseOrderDesposito(models.Model):
_inherit = 'purchase.order' _inherit = 'purchase.order'
is_deposit = fields.Boolean( is_deposit = fields.Boolean(
help='Éste proveedor nos deja material a depósito.', help='Éste proveedor nos deja material a depósito.',
string='Es a depósito', string='A depósito',
) )
deposit_last_liquidation_date = fields.Datetime( deposit_last_liquidation_date = fields.Datetime(
string='Fecha última liquidación compras', string='Última liquidación',
help="Cuándo se realizó la última liquidación de compras con éste proveedor." help="La fecha en la que se realizó la última liquidación de compras de éste depósito."
) )
@api.model @api.model_create_multi
def create(self, vals): def create(self, vals_list):
if self.is_deposit: pol = super().create(vals_list)
if not self.partner_id.deposit_buy_accept: for po in pol:
if po.is_deposit:
if not po.partner_id.deposit_buy_accept:
raise ValidationError("Este proveedor no suministra material en depósito, configúralo antes de crear un depósito para él.") raise ValidationError("Este proveedor no suministra material en depósito, configúralo antes de crear un depósito para él.")
vals['deposit_last_liquidation_date'] = fields.datetime.now() po.deposit_last_liquidation_date = fields.datetime.now()
return super(PurchaseOrde, self).create(vals) return pol
def make_liquidation_invoice(self, context = None): def get_products_sold_sales(self):
invoice_obj = self.env['account.move'] product_dict = {}
if self.deposit_last_liquidation_date: if self.deposit_last_liquidation_date:
sale_orders = self.env['sale.order'].search([ sale_orders = self.env['sale.order'].search([
('date_order', '>', self.deposit_last_liquidation_date), ('date_order', '>', self.deposit_last_liquidation_date),
@ -42,7 +41,6 @@ class PurchaseOrde(models.Model):
('state', 'in', ['sale', 'done']) ('state', 'in', ['sale', 'done'])
]) ])
product_dict = {}
if sale_orders: if sale_orders:
sale_lines = self.env['sale.order.line'].search([ sale_lines = self.env['sale.order.line'].search([
('order_id', 'in', sale_orders.ids), ('order_id', 'in', sale_orders.ids),
@ -62,9 +60,11 @@ class PurchaseOrde(models.Model):
'tax_ids': [(6, 0, line.product_id.supplier_taxes_id.ids)], 'tax_ids': [(6, 0, line.product_id.supplier_taxes_id.ids)],
'quantity': line.product_uom_qty 'quantity': line.product_uom_qty
} }
_logger.warning("product_dict %s", product_dict)
pdb.set_trace() return product_dict
pos_orders = False
def get_products_sold_pos(self):
product_dict = {}
if self.deposit_last_liquidation_date: if self.deposit_last_liquidation_date:
pos_orders = self.env['pos.order'].search([ pos_orders = self.env['pos.order'].search([
('date_order', '>', self.deposit_last_liquidation_date), ('date_order', '>', self.deposit_last_liquidation_date),
@ -76,7 +76,6 @@ class PurchaseOrde(models.Model):
('lines.product_id', 'in', self.order_line.mapped('product_id').ids), ('lines.product_id', 'in', self.order_line.mapped('product_id').ids),
('state', 'in', ['invoiced', 'done']) ('state', 'in', ['invoiced', 'done'])
]) ])
if pos_orders: if pos_orders:
pos_lines = self.env['pos.order.line'].search([ pos_lines = self.env['pos.order.line'].search([
('order_id', 'in', pos_orders.ids), ('order_id', 'in', pos_orders.ids),
@ -96,6 +95,12 @@ class PurchaseOrde(models.Model):
'tax_ids': [(6, 0, line.product_id.supplier_taxes_id.ids)], 'tax_ids': [(6, 0, line.product_id.supplier_taxes_id.ids)],
'quantity': line.qty 'quantity': line.qty
} }
return product_dict
def make_liquidation_invoice(self, context = None):
invoice_obj = self.env['account.move']
product_dict = self.get_products_sold_sales()
product_dict |= self.get_products_sold_pos() # > Python 3.9
if not product_dict: if not product_dict:
msg = "No se ha vendido ningún producto en depósito de éste proveedor desde la última liquidación.\n\n" msg = "No se ha vendido ningún producto en depósito de éste proveedor desde la última liquidación.\n\n"
@ -104,7 +109,7 @@ class PurchaseOrde(models.Model):
else: else:
msg += "Todavía no se ha realizado ninguna liquidación de compras a éste proveedor." msg += "Todavía no se ha realizado ninguna liquidación de compras a éste proveedor."
raise ValidationError(msg) raise ValidationError(msg)
_logger.warning("product_dict %s", product_dict)
invoice_vals = invoice_obj.default_get(invoice_obj._fields.keys()) invoice_vals = invoice_obj.default_get(invoice_obj._fields.keys())
invoice_vals.update({ invoice_vals.update({
'ref': "Liquidación Compras " + self.name, 'ref': "Liquidación Compras " + self.name,
@ -117,7 +122,19 @@ class PurchaseOrde(models.Model):
'purchase_id': self.id, 'purchase_id': self.id,
}) })
invoice = invoice_obj.create(invoice_vals) invoice = invoice_obj.create(invoice_vals)
self.update({'invoice_ids': [(4, invoice.id)]})
self.invoice_count = len(self.invoice_ids)
self.deposit_last_liquidation_date = fields.datetime.now() self.deposit_last_liquidation_date = fields.datetime.now()
for line in self.order_line:
if line:
invoice_line = invoice.invoice_line_ids.filtered(lambda x: x.product_id.id == line.product_id.id)
if invoice_line:
line.invoice_lines = [(4, invoice_line.id)]
self.message_post(body="Se ha creado la liquidación de compras %s" % invoice.name)
return { return {
'type': 'ir.actions.act_window', 'type': 'ir.actions.act_window',
'res_model': 'account.move', 'res_model': 'account.move',

View file

@ -2,7 +2,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api from odoo import models, fields, api
from odoo.exceptions import ValidationError, Warning from odoo.exceptions import ValidationError
class ResPartner(models.Model): class ResPartner(models.Model):
@ -35,8 +35,13 @@ class ResPartner(models.Model):
help="Cuándo se realizó la última liquidación de ventas con éste proveedor." help="Cuándo se realizó la última liquidación de ventas con éste proveedor."
) )
@api.model @api.model_create_multi
def create(self, vals): def create(self, vals_list):
for vals in vals_list:
vals = self.create_single(vals)
return super().create(vals_list)
def create_single(self, vals):
if vals.get('deposit_sale_accept', False) == True: if vals.get('deposit_sale_accept', False) == True:
vals['deposit_sale_location_id'] = self.env['stock.location'].create({ vals['deposit_sale_location_id'] = self.env['stock.location'].create({
'usage': 'transit', 'usage': 'transit',
@ -49,7 +54,7 @@ class ResPartner(models.Model):
'name': vals.get('name'), 'name': vals.get('name'),
'location_id': self.env.ref('stock_picking_deposito.location_deposit_buy').id 'location_id': self.env.ref('stock_picking_deposito.location_deposit_buy').id
}).id }).id
return super().create(vals) return vals
def write(self, vals): def write(self, vals):
if ( vals.get('deposit_sale_accept', False) == True ) and not self.deposit_sale_location_id: if ( vals.get('deposit_sale_accept', False) == True ) and not self.deposit_sale_location_id:
@ -91,13 +96,14 @@ class ResPartner(models.Model):
'name': mv.product_id.name, 'name': mv.product_id.name,
'price_unit': mv.product_id.lst_price, 'price_unit': mv.product_id.lst_price,
'tax_ids' : mv.product_id.supplier_taxes_id, 'tax_ids' : mv.product_id.supplier_taxes_id,
} }])
])
if len(product_list): if len(product_list):
invoice_vals = invoice_obj.default_get(invoice_obj._fields.keys()) invoice_vals = invoice_obj.default_get(invoice_obj._fields.keys())
inv_lines = [] if self.deposit_buy_last_liquidation_date:
invoice_vals['ref'] = "Liquidación de compras desde " + self.deposit_buy_last_liquidation_date.strftime("%Y-%m-%d %H:%M:%S")
else:
invoice_vals['ref'] = "Primera Liquidación de Compras."
invoice_vals.update({ invoice_vals.update({
'ref': "Liquidación Compras " + self.deposit_buy_last_liquidation_date.strftime("%d-%m-%Y"),
'financial_type': 'payable', 'financial_type': 'payable',
'journal_id': self.env.user.company_id.deposit_journal_id.id, 'journal_id': self.env.user.company_id.deposit_journal_id.id,
'partner_id': self.id, 'partner_id': self.id,
@ -106,6 +112,7 @@ class ResPartner(models.Model):
}) })
invoice = invoice_obj.create(invoice_vals) invoice = invoice_obj.create(invoice_vals)
self.deposit_buy_last_liquidation_date = fields.datetime.now() self.deposit_buy_last_liquidation_date = fields.datetime.now()
self.message_post(body="Se ha creado la liquidación de compras %s" %invoice.name)
views = [(self.env.ref('account.view_move_form').id, 'form')] views = [(self.env.ref('account.view_move_form').id, 'form')]
return { return {
'type': 'ir.actions.act_window', 'type': 'ir.actions.act_window',
@ -149,6 +156,7 @@ class ResPartner(models.Model):
}) })
sale_order = self.env['sale.order'].sudo().create(so_vals) sale_order = self.env['sale.order'].sudo().create(so_vals)
self.message_post(body="Se ha creado la liquidación de ventas %s" %sale_order.name)
views = [(self.env.ref('sale.view_order_form').id, 'form')] views = [(self.env.ref('sale.view_order_form').id, 'form')]
return { return {
'type': 'ir.actions.act_window', 'type': 'ir.actions.act_window',

View file

@ -20,13 +20,18 @@ class PickingType(models.Model):
class Picking(models.Model): class Picking(models.Model):
_inherit = 'stock.picking' _inherit = 'stock.picking'
@api.model @api.model_create_multi
def create(self, vals): def create(self, vals_list):
for vals in vals_list:
vals = self.create_single(vals)
return super().create(vals_list)
def create_single(self, vals):
if vals.get('picking_type_id'): if vals.get('picking_type_id'):
picking_type = self.env['stock.picking.type'].browse(vals.get('picking_type_id')) picking_type = self.env['stock.picking.type'].browse(vals.get('picking_type_id'))
if picking_type.is_deposit: if picking_type.is_deposit:
self.change_dest_location(vals, picking_type.code) self.change_dest_location(vals, picking_type.code)
return super().create(vals) return vals
def write(self, vals): def write(self, vals):
if vals.get("picking_type_id"): if vals.get("picking_type_id"):

View file

@ -19,9 +19,16 @@
class="oe_stat_button" class="oe_stat_button"
icon="fa-calendar" icon="fa-calendar"
help="Realiza el informe de liquidación para éste proveedor." help="Realiza el informe de liquidación para éste proveedor."
groups="stock.group_stock_manager" groups="account.group_account_invoice"
attrs="{'invisible': ['|',('is_deposit', '=', False),('state', '!=', 'purchase')]}"
/> />
</div> </div>
<xpath expr="//field[@name='partner_ref']" position="after">
<span><label for="is_deposit" /></span>
<span><field name="is_deposit" /></span>
<span><label for="deposit_last_liquidation_date" /></span>
<span><field name="deposit_last_liquidation_date" /></span>
</xpath>
</field> </field>
</record> </record>

View file

@ -31,7 +31,7 @@
</group> </group>
<group attrs="{'invisible': [('deposit_sale_accept', '!=', True)]}"> <group attrs="{'invisible': [('deposit_sale_accept', '!=', True)]}">
<field name="deposit_sale_location_id" readonly="1" /> <field name="deposit_sale_location_id" readonly="1" />
<field name="deposit_sale_last_liquidation_date" readonly="1" /> <field name="deposit_sale_last_liquidation_date" readonly="0" />
<!-- <button string="Current Stock" <!-- <button string="Current Stock"
class="oe_stat_button" class="oe_stat_button"
icon="fa-building-o" icon="fa-building-o"
@ -48,7 +48,7 @@
</group> </group>
<group attrs="{'invisible': [('deposit_buy_accept', '!=', True)]}"> <group attrs="{'invisible': [('deposit_buy_accept', '!=', True)]}">
<field name="deposit_buy_location_id" readonly="1" /> <field name="deposit_buy_location_id" readonly="1" />
<field name="deposit_buy_last_liquidation_date" readonly="1" /> <field name="deposit_buy_last_liquidation_date" readonly="0" />
<!-- <button string="Current Stock" <!-- <button string="Current Stock"
class="oe_stat_button" class="oe_stat_button"
icon="fa-building-o" icon="fa-building-o"