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()
 | |
| 
 |