You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

118 lines
4.4 KiB

# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ayana KP(odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import api, fields, models
from odoo.tools import float_compare
class StockLot(models.Model):
_inherit = "stock.lot"
is_taken = fields.Boolean(string='Taken lot', default=False,
help='If enables this lot number is taken')
@api.model
def check_product_stock_in_location(self, product_id, location_id):
"""Check if product has positive stock in the given location"""
product = self.env['product.product'].browse(product_id)
# Get on hand quantity using Odoo's built-in method
stock_quant = self.env['stock.quant'].search([
('product_id', '=', product_id),
('location_id', '=', location_id)
])
total_qty = sum(stock_quant.mapped('quantity'))
return {
'has_positive_stock': total_qty > 0,
'total_quantity': total_qty
}
@api.model
def get_available_lots_for_pos(self, product_id, pos_config_id=None):
"""Get available lots for a product in POS location"""
# Get POS location
if pos_config_id:
pos_config = self.env['pos.config'].browse(pos_config_id)
location_id = pos_config.picking_type_id.default_location_src_id.id
else:
pos_session = self.env['pos.session'].search([
('state', '=', 'opened'),
('user_id', '=', self.env.uid)
], limit=1)
if pos_session:
location_id = pos_session.config_id.picking_type_id.default_location_src_id.id
else:
return {'has_positive_stock': False, 'lots': []}
# Check total stock in location
stock_check = self.check_product_stock_in_location(product_id, location_id)
# If no positive stock, return immediately
if not stock_check['has_positive_stock']:
return {
'has_positive_stock': False,
'total_quantity': stock_check['total_quantity'],
'lots': []
}
# Stock is positive, get lots with FEFO/FIFO
product = self.env['product.product'].browse(product_id)
company_id = self.env.company.id
removal_strategy = product.product_tmpl_id.categ_id.removal_strategy_id.method or 'fifo'
# Get all lots for this product
lot_domain = [
('product_id', '=', product_id),
'|', ('company_id', '=', company_id), ('company_id', '=', False)
]
if removal_strategy == 'fefo':
lots = self.sudo().search(lot_domain, order='expiration_date asc')
else:
lots = self.sudo().search(lot_domain, order='create_date asc')
# Get lots with positive quantity in the location
available_lots = []
for lot in lots:
quants = self.env['stock.quant'].sudo().search([
('lot_id', '=', lot.id),
('location_id', '=', location_id),
('product_id', '=', product_id)
])
lot_qty = sum(quants.mapped('quantity'))
if lot_qty > 0:
available_lots.append({
'lot_name': lot.name,
'lot_id': lot.id,
'available_qty': lot_qty,
'expiration_date': str(lot.expiration_date) if lot.expiration_date else False,
})
return {
'has_positive_stock': True,
'total_quantity': stock_check['total_quantity'],
'lots': available_lots
}