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.
112 lines
5.0 KiB
112 lines
5.0 KiB
# -*- coding: utf-8 -*-
|
|
###############################################################################
|
|
#
|
|
# Cybrosys Technologies Pvt. Ltd.
|
|
#
|
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
|
|
# Author: Aysha Shalin (odoo@cybrosys.com)
|
|
#
|
|
# You can modify it under the terms of the GNU LESSER
|
|
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
|
|
#
|
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC
|
|
# LICENSE (LGPL v3) along with this program.
|
|
# If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
###############################################################################
|
|
from odoo import fields, models, _
|
|
from odoo.exceptions import UserError, ValidationError
|
|
import base64
|
|
import openpyxl
|
|
from io import BytesIO
|
|
|
|
|
|
class LotsAttachment(models.TransientModel):
|
|
""" Class for lots wizard """
|
|
_name = 'lot.attachment'
|
|
_description = "Lots Attachment"
|
|
|
|
picking_id = fields.Many2one('stock.picking',
|
|
string="Stock Picking",
|
|
help="Parent picking")
|
|
product_id = fields.Many2one('product.product',
|
|
string="Product",
|
|
help="Current product")
|
|
demanded_quantity = fields.Float(string="Quantity",
|
|
help="Product quantity demanded")
|
|
type = fields.Selection(string="Lots Type",
|
|
selection=[('lot', 'Lot'), ('serial', 'Serial')],
|
|
help="Choose a lot/serial")
|
|
move_id = fields.Many2one('stock.move')
|
|
attachment = fields.Binary(string="Upload", attachment=True)
|
|
attachment_name = fields.Char(string="Attachment Name",
|
|
help="Attachment file name")
|
|
|
|
def action_import_lot(self):
|
|
""" Importing lots """
|
|
current_move_id = self.env['stock.move'].browse(self.move_id.id)
|
|
if self.attachment:
|
|
wb = openpyxl.load_workbook(
|
|
filename=BytesIO(base64.b64decode(self.attachment)),
|
|
read_only=True) if self.attachment else ""
|
|
ws = wb.active
|
|
# Check if product exists in the sheet
|
|
product_found = any(
|
|
record[1] == current_move_id.product_id.display_name for
|
|
record in ws.iter_rows(min_row=2, values_only=True))
|
|
if not product_found:
|
|
raise UserError(
|
|
_('The product "%s" does not exist in the sheet.') %
|
|
current_move_id.product_id.display_name)
|
|
# Check if lot name already exists in move line ids
|
|
if (current_move_id.move_line_ids and
|
|
any(record[0] in set(current_move_id.move_line_ids.mapped('lot_name')) for
|
|
record in ws.iter_rows(min_row=2, values_only=True))):
|
|
raise UserError(
|
|
_('This Lot name already exists in the move line.'))
|
|
# Calculate total sheet quantity for the product
|
|
total_sheet_quantity = sum(
|
|
record[2] for record in ws.iter_rows
|
|
(min_row=2, values_only=True) if
|
|
record[1] == current_move_id.product_id.display_name)
|
|
# Check if total sheet quantity exceeds demand quantity of the
|
|
# product
|
|
if total_sheet_quantity > current_move_id.product_uom_qty:
|
|
raise UserError(
|
|
_('Total quantity in the sheet exceeds the demand '
|
|
'quantity of the product. Please adjust the quantities '
|
|
'in the sheet.'))
|
|
# Prepare move line values to be written
|
|
vals_list = []
|
|
for record in ws.iter_rows(min_row=2, values_only=True):
|
|
lot_name, product_name, quantity = record
|
|
if product_name == current_move_id.product_id.display_name:
|
|
vals_list.append((0, 0, {
|
|
'lot_name': lot_name,
|
|
'quantity': min(quantity, current_move_id.product_qty),
|
|
'move_id': current_move_id.id,
|
|
}))
|
|
# Write move line values
|
|
current_move_id.move_line_ids.unlink()
|
|
current_move_id.write({'move_line_ids': vals_list})
|
|
return {
|
|
'type': 'ir.actions.client',
|
|
'tag': 'reload',
|
|
}
|
|
else:
|
|
raise ValidationError(
|
|
_('Check whether you upload the document'))
|
|
|
|
def action_download_sample(self):
|
|
""" For downloading a sample excel file """
|
|
return {
|
|
'type': 'ir.actions.act_url',
|
|
'url': '/download/excel',
|
|
'target': 'self',
|
|
'file_name': 'my_excel_file.xlsx'
|
|
}
|
|
|