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.
		
		
		
		
		
			
		
			
				
					
					
						
							243 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							243 lines
						
					
					
						
							11 KiB
						
					
					
				
								# -*- coding: utf-8 -*-
							 | 
						|
								################################################################################
							 | 
						|
								#
							 | 
						|
								#    Cybrosys Technologies Pvt. Ltd.
							 | 
						|
								#
							 | 
						|
								#    Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
							 | 
						|
								#    Author: Vishnu KP @ Cybrosys, (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, _, Command
							 | 
						|
								from odoo.exceptions import UserError
							 | 
						|
								from datetime import date
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class SaleConsignment(models.Model):
							 | 
						|
								    _name = "sale.consignment"
							 | 
						|
								    _description = "Sale Consignment"
							 | 
						|
								    _inherit = ['mail.activity.mixin', 'mail.thread']
							 | 
						|
								
							 | 
						|
								    """This is the main model for the sale consignment feature"""
							 | 
						|
								
							 | 
						|
								    @api.model
							 | 
						|
								    def _settings_domain(self):
							 | 
						|
								        """This function return the customer domain fields
							 | 
						|
								        value from the settings page"""
							 | 
						|
								        customer_domain = self.env['ir.config_parameter'].get_param(
							 | 
						|
								            'sale_consignment.consignment_product_only')
							 | 
						|
								        return customer_domain
							 | 
						|
								
							 | 
						|
								    @api.model
							 | 
						|
								    def _default_destination(self):
							 | 
						|
								        """This function return the destination location fields
							 | 
						|
								                value from the settings page"""
							 | 
						|
								        location_dest_id = self.env['ir.config_parameter'].get_param(
							 | 
						|
								            'sale_consignment.location_dest_id')
							 | 
						|
								        return int(location_dest_id)
							 | 
						|
								
							 | 
						|
								    name = fields.Char(string='Name', help="Sequence of the consignment Sale",
							 | 
						|
								                       default='New')
							 | 
						|
								    company_id = fields.Many2one('res.company',
							 | 
						|
								                                 string='Company', help='default company',
							 | 
						|
								                                 default=lambda self: self.env.user.company_id)
							 | 
						|
								    partner_id = fields.Many2one('res.partner', string='Customer',
							 | 
						|
								                                 help="Partner Name", required=True)
							 | 
						|
								    end_date = fields.Date(string='Expiry Date',
							 | 
						|
								                           help="Expiry date of the sale consignment",
							 | 
						|
								                           required=True)
							 | 
						|
								    date = fields.Date(string='Date', default=date.today(),
							 | 
						|
								                       help="Date of the sale consignment", required=True)
							 | 
						|
								    price_list_id = fields.Many2one('product.pricelist', string='Price List',
							 | 
						|
								                                    help="Product price list based on the "
							 | 
						|
								                                         "customer",
							 | 
						|
								                                    compute='_compute_partner_id')
							 | 
						|
								    state = fields.Selection(
							 | 
						|
								        selection=[('draft', 'Draft'), ('confirm', 'Confirm')],
							 | 
						|
								        help="State of the sale consignment",
							 | 
						|
								        default="draft")
							 | 
						|
								    user_id = fields.Many2one("res.users", string='Sales Person',
							 | 
						|
								                              help="Responsible sales person for the sale "
							 | 
						|
								                                   "consignment",
							 | 
						|
								                              default=lambda self: self.env.user,
							 | 
						|
								                              required=True)
							 | 
						|
								    consignment_line_ids = fields.One2many('sale.consignment.line',
							 | 
						|
								                                           'consignment_id',
							 | 
						|
								                                           string='Order Line')
							 | 
						|
								    location_id = fields.Many2one(
							 | 
						|
								        'stock.location', 'Source Location',
							 | 
						|
								        help="Location where the product you want to pickup from.",
							 | 
						|
								        domain="[('usage','=','internal')]",
							 | 
						|
								        required=True)
							 | 
						|
								    sale_count = fields.Integer(string='Sale Order',
							 | 
						|
								                                help="Number of sale order related to "
							 | 
						|
								                                     "the consignment",
							 | 
						|
								                                compute='_compute_sale_count')
							 | 
						|
								    picking_count = fields.Integer(string='Picking Order',
							 | 
						|
								                                   help="Number of picking order "
							 | 
						|
								                                        "related to the consignment",
							 | 
						|
								                                   compute='_compute_picking_count')
							 | 
						|
								    sale_order_id = fields.Many2one('sale.order', help='Related sale order',
							 | 
						|
								                                    string='Sale Order')
							 | 
						|
								    ware_house_id = fields.Many2one('stock.warehouse',
							 | 
						|
								                                    string='Warehouse',
							 | 
						|
								                                    related='location_id.warehouse_id',
							 | 
						|
								                                    help='Choose the Warehouse')
							 | 
						|
								    condition_check = fields.Char(string='Condition',
							 | 
						|
								                                  compute='_compute_condition_check',
							 | 
						|
								                                  help="To check whether the consignment "
							 | 
						|
								                                       "is enable or not")
							 | 
						|
								    customer_domain = fields.Boolean(
							 | 
						|
								        default=lambda self: self._settings_domain(),
							 | 
						|
								        help='Customer domain',
							 | 
						|
								        string='Customer domain')
							 | 
						|
								    location_dest_id = fields.Many2one(
							 | 
						|
								        'stock.location', 'Destination Location',
							 | 
						|
								        required=True,
							 | 
						|
								        default=lambda self: self._default_destination(),
							 | 
						|
								        help="Location where you want to send the product.")
							 | 
						|
								
							 | 
						|
								    @api.depends('customer_domain')
							 | 
						|
								    def _compute_condition_check(self):
							 | 
						|
								        """Used to apply the condition into condition_check field if
							 | 
						|
								        customer_domain is true """
							 | 
						|
								        for record in self:
							 | 
						|
								            record.condition_check = [
							 | 
						|
								                ('is_consignment', '=', True)] if record.customer_domain else []
							 | 
						|
								
							 | 
						|
								    @api.model
							 | 
						|
								    def create(self, vals):
							 | 
						|
								        """Used to add the sequence"""
							 | 
						|
								        if vals.get('name', _('New')) == _('New'):
							 | 
						|
								            vals['name'] = self.env['ir.sequence'].next_by_code(
							 | 
						|
								                'sale.consignment') or _('New')
							 | 
						|
								        res = super(SaleConsignment, self).create(vals)
							 | 
						|
								        return res
							 | 
						|
								
							 | 
						|
								    @api.depends('consignment_line_ids')
							 | 
						|
								    def _compute_sale_count(self):
							 | 
						|
								        """Used to calculate the number of sales count"""
							 | 
						|
								        for rec in self:
							 | 
						|
								            rec.sale_count = self.env['sale.order'].search_count([
							 | 
						|
								                ('consignment_id', '=', rec.id)])
							 | 
						|
								
							 | 
						|
								    @api.depends('consignment_line_ids')
							 | 
						|
								    def _compute_picking_count(self):
							 | 
						|
								        """Used to calculate the number of picking count"""
							 | 
						|
								        for rec in self:
							 | 
						|
								            rec.picking_count = self.env['stock.picking'].search_count([
							 | 
						|
								                ('consignment_id', '=', rec.id)])
							 | 
						|
								
							 | 
						|
								    @api.depends('partner_id')
							 | 
						|
								    def _compute_partner_id(self):
							 | 
						|
								        """Used to find the price-list based on the partner"""
							 | 
						|
								        self.price_list_id = self.partner_id.property_product_pricelist.id
							 | 
						|
								
							 | 
						|
								    def action_order_confirm(self):
							 | 
						|
								        """Used to confirm the consignment order"""
							 | 
						|
								        picking_type = self.env['stock.picking.type'].search(
							 | 
						|
								            [('code', '=', 'internal'),
							 | 
						|
								             ('warehouse_id', '=', self.ware_house_id.id),
							 | 
						|
								             ('company_id', '=', self.env.company.id),
							 | 
						|
								             ('default_location_src_id.usage', '=', 'internal'),
							 | 
						|
								             ('default_location_dest_id.usage', '=', 'transit'),
							 | 
						|
								             ], limit=1)
							 | 
						|
								        if not picking_type:
							 | 
						|
								            raise UserError(_(
							 | 
						|
								                "There is no available Operation type like destination "
							 | 
						|
								                "to transit location Please create and try again"))
							 | 
						|
								        else:
							 | 
						|
								            self.env['stock.picking'].create({
							 | 
						|
								                'location_id': self.location_id.id,
							 | 
						|
								                'location_dest_id': self.location_dest_id.id,
							 | 
						|
								                'partner_id': self.partner_id.id,
							 | 
						|
								                'picking_type_id': picking_type.id,
							 | 
						|
								                'consignment_id': self.id,
							 | 
						|
								                'move_ids': [
							 | 
						|
								                    Command.create({
							 | 
						|
								                        'name': self.name,
							 | 
						|
								                        'product_id': line.product_id.id,
							 | 
						|
								                        'quantity': line.demand_quantity,
							 | 
						|
								                        'picked': True,
							 | 
						|
								                        'location_id': self.location_id.id,
							 | 
						|
								                        'location_dest_id': self.location_dest_id.id,
							 | 
						|
								                    }) for line in self.consignment_line_ids]
							 | 
						|
								            }).action_confirm()
							 | 
						|
								
							 | 
						|
								            self.write({'state': 'confirm'})
							 | 
						|
								
							 | 
						|
								    def create_sale_order(self):
							 | 
						|
								        """Used to create the related sale order for the consignment"""
							 | 
						|
								        self.sale_order_id = self.env['sale.order'].create({
							 | 
						|
								            'partner_id': self.partner_id.id,
							 | 
						|
								            'consignment_id': self.id,
							 | 
						|
								            'user_id': self.user_id.id,
							 | 
						|
								            'order_line': [
							 | 
						|
								                Command.create({
							 | 
						|
								                    'product_id': line.product_id.id,
							 | 
						|
								                    'product_uom': line.product_id.uom_id.id,
							 | 
						|
								                    'product_uom_qty': 1.0,
							 | 
						|
								                }) for line in self.consignment_line_ids]
							 | 
						|
								        }).id
							 | 
						|
								        return {
							 | 
						|
								            'name': 'Sale Order',
							 | 
						|
								            'view_mode': 'form',
							 | 
						|
								            'res_id': self.sale_order_id.id,
							 | 
						|
								            'res_model': 'sale.order',
							 | 
						|
								            'type': 'ir.actions.act_window',
							 | 
						|
								            'target': 'current'
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    def action_view_order(self):
							 | 
						|
								        """Used to view the sale order of the consignment order"""
							 | 
						|
								        return {
							 | 
						|
								            'name': 'Sale Order',
							 | 
						|
								            'view_mode': 'tree,form',
							 | 
						|
								            'domain': [('consignment_id', 'in', [rec.id for rec in self])],
							 | 
						|
								            'context': {'create': False},
							 | 
						|
								            'res_model': 'sale.order',
							 | 
						|
								            'type': 'ir.actions.act_window',
							 | 
						|
								            'target': 'current'
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    def action_view_pickings(self):
							 | 
						|
								        """Used to view the picking of the consignment order"""
							 | 
						|
								        return {
							 | 
						|
								            'name': 'Picking Order',
							 | 
						|
								            'view_mode': 'tree,form',
							 | 
						|
								            'domain': [('consignment_id', 'in', [rec.id for rec in self])],
							 | 
						|
								            'context': {'create': False},
							 | 
						|
								            'res_model': 'stock.picking',
							 | 
						|
								            'type': 'ir.actions.act_window',
							 | 
						|
								            'target': 'current'
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    def mail_update_to_salesman(self):
							 | 
						|
								        """this function is used to send a mail notification to salesman"""
							 | 
						|
								        orders = self.env['sale.consignment'].search(
							 | 
						|
								            [('end_date', '=', date.today())])
							 | 
						|
								        for rec in orders:
							 | 
						|
								            mail_template_id = 'sale_consignment.sale_consignment_expiry'
							 | 
						|
								            rendered_body = self.env['ir.qweb']._render(mail_template_id,
							 | 
						|
								                                                        {'expiry': rec})
							 | 
						|
								            body = self.env['mail.render.mixin']._replace_local_links(
							 | 
						|
								                rendered_body)
							 | 
						|
								            self.env['mail.mail'].sudo().create({
							 | 
						|
								                'author_id': self.env.user.partner_id.id,
							 | 
						|
								                'auto_delete': True,
							 | 
						|
								                'body_html': body,
							 | 
						|
								                'email_from': self.env.user.partner_id.email,
							 | 
						|
								                'email_to': rec.user_id.partner_id.email,
							 | 
						|
								                'subject': 'Reminder: Sale Consignment Date Expired',
							 | 
						|
								            }).send()
							 | 
						|
								
							 |