@ -0,0 +1,48 @@ | 
				
			|||||
 | 
					.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg | 
				
			||||
 | 
					   :target: https://www.gnu.org/licenses/agpl-3.0-standalone.html | 
				
			||||
 | 
					   :alt: License: AGPL-3 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Sale Consignment | 
				
			||||
 | 
					================ | 
				
			||||
 | 
					This module provide Sale Orders as Consignment Order. | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Configuration | 
				
			||||
 | 
					============= | 
				
			||||
 | 
					* No additional configuration is needed. | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Company | 
				
			||||
 | 
					------- | 
				
			||||
 | 
					* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					License | 
				
			||||
 | 
					------- | 
				
			||||
 | 
					Affero General Public License, Version 3 (AGPL v3). | 
				
			||||
 | 
					(https://www.gnu.org/licenses/agpl-3.0-standalone.html) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Credits | 
				
			||||
 | 
					------- | 
				
			||||
 | 
					* Developers : (V17) Vishnu Kp, | 
				
			||||
 | 
					               (V18) Aysha Shalin | 
				
			||||
 | 
					  Contact : odoo@cybrosys.com | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Contacts | 
				
			||||
 | 
					-------- | 
				
			||||
 | 
					* Mail Contact : odoo@cybrosys.com | 
				
			||||
 | 
					* Website : https://cybrosys.com | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Bug Tracker | 
				
			||||
 | 
					----------- | 
				
			||||
 | 
					Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Maintainer | 
				
			||||
 | 
					========== | 
				
			||||
 | 
					.. image:: https://cybrosys.com/images/logo.png | 
				
			||||
 | 
					   :target: https://cybrosys.com | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					This module is maintained by Cybrosys Technologies. | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					For support and more information, please visit `Our Website <https://cybrosys.com/>`__ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Further information | 
				
			||||
 | 
					=================== | 
				
			||||
 | 
					HTML Description: `<static/description/index.html>`__ | 
				
			||||
@ -0,0 +1,22 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					################################################################################ | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    Author: Aysha Shalin (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 . import models | 
				
			||||
@ -0,0 +1,50 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					################################################################################ | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    Author: Aysha Shalin (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/>. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					################################################################################ | 
				
			||||
 | 
					{ | 
				
			||||
 | 
					    'name': "Sale Consignment", | 
				
			||||
 | 
					    'version': "18.0.1.0.0", | 
				
			||||
 | 
					    'category': 'Sales', | 
				
			||||
 | 
					    'summary': """Consignment of Sale Orders.""", | 
				
			||||
 | 
					    'description': """This module provide Sale Orders with consignment option""", | 
				
			||||
 | 
					    'author': "Cybrosys Techno Solutions", | 
				
			||||
 | 
					    'company': "Cybrosys Techno Solutions", | 
				
			||||
 | 
					    'maintainer': "Cybrosys Techno Solutions", | 
				
			||||
 | 
					    'website': "https://www.cybrosys.com", | 
				
			||||
 | 
					    'depends': ['base','sale_management', 'stock', 'mail'], | 
				
			||||
 | 
					    'data': [ | 
				
			||||
 | 
					        'security/ir.model.access.csv', | 
				
			||||
 | 
					        'security/sale_consignment_groups.xml', | 
				
			||||
 | 
					        'data/sequence.xml', | 
				
			||||
 | 
					        'data/consignment_expiry_mail.xml', | 
				
			||||
 | 
					        'views/sale_consignment_views.xml', | 
				
			||||
 | 
					        'views/sale_consignment_line_views.xml', | 
				
			||||
 | 
					        'views/res_config_settings_views.xml', | 
				
			||||
 | 
					        'views/res_partner_views.xml', | 
				
			||||
 | 
					        'views/product_template_views.xml', | 
				
			||||
 | 
					        'views/sale_order_views.xml' | 
				
			||||
 | 
					    ], | 
				
			||||
 | 
					    'images': ['static/description/banner.jpg'], | 
				
			||||
 | 
					    'license': "AGPL-3", | 
				
			||||
 | 
					    'installable': True, | 
				
			||||
 | 
					    'auto_install': False, | 
				
			||||
 | 
					    'application': False | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,33 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="UTF-8" ?> | 
				
			||||
 | 
					<odoo> | 
				
			||||
 | 
					    <!-- Template for consignment expiry email --> | 
				
			||||
 | 
					    <template id="sale_consignment_expiry"> | 
				
			||||
 | 
					        <p>Hi <t t-out="expiry.user_id.name"/>, | 
				
			||||
 | 
					        </p> | 
				
			||||
 | 
					        <p> | 
				
			||||
 | 
					            We hope this message finds you well. | 
				
			||||
 | 
					            We would like to kindly remind you that the consignment date for | 
				
			||||
 | 
					            Sale order | 
				
			||||
 | 
					            <t t-if="expiry.name"> | 
				
			||||
 | 
					                <t t-out="expiry.name"> </t> | 
				
			||||
 | 
					            </t> | 
				
			||||
 | 
					            has ended today. | 
				
			||||
 | 
					            If you have not yet created the sale order for this consignment, | 
				
			||||
 | 
					            please do so at your earliest convenience. | 
				
			||||
 | 
					            If you have already taken care of this, please disregard this email. | 
				
			||||
 | 
					            Thank you for your attention to this matter. | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            Best regards, | 
				
			||||
 | 
					        </p> | 
				
			||||
 | 
					        <p t-if="expiry.company_id.name"> | 
				
			||||
 | 
					            <t t-out="expiry.company_id.name"/> | 
				
			||||
 | 
					        </p> | 
				
			||||
 | 
					        <p t-if="expiry.user_id"> | 
				
			||||
 | 
					            <br/> | 
				
			||||
 | 
					            <a t-att-href="'/web#id=%s&model=sale.consignment&view_type=form' % (expiry.id)" | 
				
			||||
 | 
					               style="background-color: #9E588B; margin-top: 10px; padding: 10px; text-decoration: none; color: #fff; border-radius: 5px; font-size: 16px;"> | 
				
			||||
 | 
					                View Consignment | 
				
			||||
 | 
					            </a> | 
				
			||||
 | 
					        </p> | 
				
			||||
 | 
					    </template> | 
				
			||||
 | 
					</odoo> | 
				
			||||
@ -0,0 +1,25 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="UTF-8" ?> | 
				
			||||
 | 
					<odoo> | 
				
			||||
 | 
					    <!-- Sequence for consignment orders --> | 
				
			||||
 | 
					    <data noupdate="1"> | 
				
			||||
 | 
					        <record id="seq_consignment_sale" model="ir.sequence"> | 
				
			||||
 | 
					            <field name="name">Sale Consignment</field> | 
				
			||||
 | 
					            <field name="code">sale.consignment</field> | 
				
			||||
 | 
					            <field name="prefix">SC</field> | 
				
			||||
 | 
					            <field name="padding">5</field> | 
				
			||||
 | 
					            <field name="company_id" eval="False"/> | 
				
			||||
 | 
					        </record> | 
				
			||||
 | 
					    </data> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    <!-- Scheduled action for sending consignment expiration reminder email --> | 
				
			||||
 | 
					    <record id="automated_mail_job" model="ir.cron"> | 
				
			||||
 | 
					        <field name="name">Reminder: Sale Consignment Expiry date</field> | 
				
			||||
 | 
					        <field name="model_id" ref="model_sale_consignment"/> | 
				
			||||
 | 
					        <field name="state">code</field> | 
				
			||||
 | 
					        <field name="code">model.mail_update_to_salesman()</field> | 
				
			||||
 | 
					        <field name='interval_number'>1</field> | 
				
			||||
 | 
					        <field name='interval_type'>days</field> | 
				
			||||
 | 
					        <field name="priority">3</field> | 
				
			||||
 | 
					    </record> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					</odoo> | 
				
			||||
@ -0,0 +1,6 @@ | 
				
			|||||
 | 
					## Module <sale_consignment> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					#### 27.06.2025 | 
				
			||||
 | 
					#### Version 18.0.1.0.0 | 
				
			||||
 | 
					##### ADD | 
				
			||||
 | 
					- Initial Commit for Sale Consignment | 
				
			||||
@ -0,0 +1,28 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					############################################################################### | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    Author: Aysha Shalin (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 . import product_product | 
				
			||||
 | 
					from . import res_config_settings | 
				
			||||
 | 
					from . import res_partner | 
				
			||||
 | 
					from . import sale_consignment | 
				
			||||
 | 
					from . import sale_consignment_line | 
				
			||||
 | 
					from . import sale_order | 
				
			||||
 | 
					from . import stock_picking | 
				
			||||
@ -0,0 +1,31 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					################################################################################ | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    Author: Aysha Shalin (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 fields, models | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class ProductTemplate(models.Model): | 
				
			||||
 | 
					    """ Class inherited to add the custom fields to the model """ | 
				
			||||
 | 
					    _inherit = 'product.template' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    is_consignment = fields.Boolean(string='Is Consignment', | 
				
			||||
 | 
					                                    help="If enabled, it will be considered as " | 
				
			||||
 | 
					                                    "a Consignment product") | 
				
			||||
@ -0,0 +1,48 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					################################################################################ | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    Author: Aysha Shalin (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 fields, models | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class ResConfigSettings(models.TransientModel): | 
				
			||||
 | 
					    """ This transient model is used to add the custom fields to the | 
				
			||||
 | 
					    settings page. """ | 
				
			||||
 | 
					    _inherit = 'res.config.settings' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    location_dest_id = fields.Many2one( | 
				
			||||
 | 
					        'stock.location', 'Destination Location', | 
				
			||||
 | 
					        help="Location where you want to send the components resulting " | 
				
			||||
 | 
					             "from the un-build order.", | 
				
			||||
 | 
					        config_parameter='sale_consignment.location_dest_id', | 
				
			||||
 | 
					        readonly=False) | 
				
			||||
 | 
					    group_consignment_order = fields.Boolean( | 
				
			||||
 | 
					        string='Consignment', readonly=False, default=True, | 
				
			||||
 | 
					        config_parameter='sale_consignment.group_consignment_order', | 
				
			||||
 | 
					        help="Consignment Orders", | 
				
			||||
 | 
					        implied_group='sale_consignment.group_consignment_order') | 
				
			||||
 | 
					    consignment_product_only = fields.Boolean( | 
				
			||||
 | 
					        string='Consignment Product', | 
				
			||||
 | 
					        config_parameter='sale_consignment.consignment_product_only', | 
				
			||||
 | 
					        help='Enable Product Filtered in consignment by Consignment Product') | 
				
			||||
 | 
					    consignment_customer_only = fields.Boolean( | 
				
			||||
 | 
					        string='Consignment Customer', | 
				
			||||
 | 
					        config_parameter='sale_consignment.consignment_customer_only', | 
				
			||||
 | 
					        help='Enable Customer Filtered in consignment by Consignment Customer') | 
				
			||||
@ -0,0 +1,31 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					################################################################################ | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    Author: Aysha Shalin (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 fields, models | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class ResPartner(models.Model): | 
				
			||||
 | 
					    """ Class is used to add the custom fields """ | 
				
			||||
 | 
					    _inherit = 'res.partner' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    is_consignment = fields.Boolean(string="Consignment Customer", | 
				
			||||
 | 
					                                    help='If Enabled, customer as consignment type' | 
				
			||||
 | 
					                                         'category') | 
				
			||||
@ -0,0 +1,243 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					################################################################################ | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    Author: Aysha Shalin (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, Command, fields, models, _ | 
				
			||||
 | 
					from odoo.exceptions import UserError | 
				
			||||
 | 
					from datetime import date | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class SaleConsignment(models.Model): | 
				
			||||
 | 
					    """ This is the main model for the sale consignment feature """ | 
				
			||||
 | 
					    _name = "sale.consignment" | 
				
			||||
 | 
					    _description = "Sale Consignment" | 
				
			||||
 | 
					    _inherit = ['mail.activity.mixin', 'mail.thread'] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @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_customer_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', default='New', | 
				
			||||
 | 
					                       copy=False, help="Sequence of the consignment Sale") | 
				
			||||
 | 
					    company_id = fields.Many2one('res.company', string='Company', | 
				
			||||
 | 
					                                 default=lambda self: self.env.user.company_id, | 
				
			||||
 | 
					                                 help='default company') | 
				
			||||
 | 
					    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', | 
				
			||||
 | 
					                                    compute='_compute_partner_id', | 
				
			||||
 | 
					                                    help="Product price list based on the " | 
				
			||||
 | 
					                                         "customer") | 
				
			||||
 | 
					    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', | 
				
			||||
 | 
					                                           help="Consignment Lines") | 
				
			||||
 | 
					    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', | 
				
			||||
 | 
					                                compute='_compute_sale_count', | 
				
			||||
 | 
					                                help="Number of sale order related to " | 
				
			||||
 | 
					                                     "the consignment") | 
				
			||||
 | 
					    picking_count = fields.Integer(string='Picking Order', | 
				
			||||
 | 
					                                   compute='_compute_picking_count', | 
				
			||||
 | 
					                                   help="Number of picking order " | 
				
			||||
 | 
					                                        "related to the consignment") | 
				
			||||
 | 
					    sale_order_id = fields.Many2one('sale.order', | 
				
			||||
 | 
					                                    string='Sale Order', | 
				
			||||
 | 
					                                    help='Related 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(string='Customer domain', | 
				
			||||
 | 
					                                     default=lambda self: self._settings_domain(), | 
				
			||||
 | 
					                                    help='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': 'list,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': 'list,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() | 
				
			||||
@ -0,0 +1,68 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					################################################################################ | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    Author: Aysha Shalin (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 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class SaleConsignmentLine(models.Model): | 
				
			||||
 | 
					    """ This class is used to manage the sale consignment line """ | 
				
			||||
 | 
					    _name = "sale.consignment.line" | 
				
			||||
 | 
					    _rec_name = "consignment_id" | 
				
			||||
 | 
					    _description = "Sale Consignment Line" | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.model | 
				
			||||
 | 
					    def _settings_domain(self): | 
				
			||||
 | 
					        """This function is used to get the settings domain""" | 
				
			||||
 | 
					        product_domain = self.env[ | 
				
			||||
 | 
					            'ir.config_parameter'].get_param( | 
				
			||||
 | 
					            'sale_consignment.consignment_product_only') | 
				
			||||
 | 
					        return product_domain | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    product_id = fields.Many2one('product.product', string='Products', | 
				
			||||
 | 
					                                 help="Product in the consignment order line", | 
				
			||||
 | 
					                                 required=True) | 
				
			||||
 | 
					    demand_quantity = fields.Integer(string='Demand Quantity', required=True, | 
				
			||||
 | 
					                                     help="Demanded quantity of the product") | 
				
			||||
 | 
					    done_quantity = fields.Integer(string='Done Quantity', | 
				
			||||
 | 
					                                   help="Done quantity of the product") | 
				
			||||
 | 
					    remaining_quantity = fields.Integer(string='Remaining Quantity', | 
				
			||||
 | 
					                                        compute='_compute_remaining_quantity', | 
				
			||||
 | 
					                                        help="Quantity of remaining product") | 
				
			||||
 | 
					    price = fields.Float(string='Price', help="Price of the product") | 
				
			||||
 | 
					    consignment_id = fields.Many2one('sale.consignment', | 
				
			||||
 | 
					                                     string='Consignment ID', | 
				
			||||
 | 
					                                     help="consignment ID for connect the" | 
				
			||||
 | 
					                                          "consignment") | 
				
			||||
 | 
					    condition_check_line = fields.Char(compute='_compute_condition_check') | 
				
			||||
 | 
					    product_domain = fields.Boolean(default=lambda self: self._settings_domain()) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.depends('product_domain') | 
				
			||||
 | 
					    def _compute_condition_check(self): | 
				
			||||
 | 
					        """ Used to apply the condition into condition_check_line field if | 
				
			||||
 | 
					        is_consignment is true. """ | 
				
			||||
 | 
					        for record in self: | 
				
			||||
 | 
					            record.condition_check_line = [('is_consignment', '=', True)] if record.product_domain else [] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _compute_remaining_quantity(self): | 
				
			||||
 | 
					        """ This function is used to compute the remaining quantity of the | 
				
			||||
 | 
					        consignment order. """ | 
				
			||||
 | 
					        for rec in self: | 
				
			||||
 | 
					            rec.remaining_quantity = rec.demand_quantity - rec.done_quantity | 
				
			||||
@ -0,0 +1,31 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					################################################################################ | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | 
				
			||||
 | 
					#    Author: Aysha Shalin (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 fields, models | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class SaleOrder(models.Model): | 
				
			||||
 | 
					    """ This class inherited to add the custom fields """ | 
				
			||||
 | 
					    _inherit = 'sale.order' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    consignment_id = fields.Many2one('sale.consignment', | 
				
			||||
 | 
					                                     string='Source Document', | 
				
			||||
 | 
					                                     help="Related Consignment") | 
				
			||||
@ -0,0 +1,49 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					################################################################################ | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    Author: Aysha Shalin (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 fields, models | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class StockPicking(models.Model): | 
				
			||||
 | 
					    """ This class is inherited to add custom fields and also | 
				
			||||
 | 
					        super the validate button. """ | 
				
			||||
 | 
					    _inherit = 'stock.picking' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    consignment_id = fields.Many2one('sale.consignment', | 
				
			||||
 | 
					                                     string="Consignment ID", | 
				
			||||
 | 
					                                     help='Related Consignment Id') | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def button_validate(self): | 
				
			||||
 | 
					        """ This method is used to calculate the number of done quantity | 
				
			||||
 | 
					         related to the consignment order. """ | 
				
			||||
 | 
					        res = super().button_validate() | 
				
			||||
 | 
					        consignment_id = self.sale_id.consignment_id | 
				
			||||
 | 
					        if consignment_id: | 
				
			||||
 | 
					            self.location_id = consignment_id.location_dest_id | 
				
			||||
 | 
					            self.move_line_ids.location_id = consignment_id.location_dest_id | 
				
			||||
 | 
					        sale_order = self.env['sale.order'].search([ | 
				
			||||
 | 
					            ('consignment_id', '=', consignment_id.id)]) | 
				
			||||
 | 
					        for record in consignment_id.consignment_line_ids: | 
				
			||||
 | 
					            quantity = sum( | 
				
			||||
 | 
					                rec.product_uom_qty for order in sale_order for rec in | 
				
			||||
 | 
					                order.order_line if rec.product_id.id == record.product_id.id) | 
				
			||||
 | 
					            record.done_quantity = quantity | 
				
			||||
 | 
					        return res | 
				
			||||
		
		
			
  | 
@ -0,0 +1,8 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="UTF-8" ?> | 
				
			||||
 | 
					<odoo> | 
				
			||||
 | 
					    <!-- Security group --> | 
				
			||||
 | 
					    <record id="group_consignment_order" model="res.groups"> | 
				
			||||
 | 
					        <field name="name">Manage Consignment order</field> | 
				
			||||
 | 
					        <field name="category_id" ref="base.module_category_hidden"/> | 
				
			||||
 | 
					    </record> | 
				
			||||
 | 
					</odoo> | 
				
			||||
| 
		 After Width: | Height: | Size: 2.2 KiB  | 
| 
		 After Width: | Height: | Size: 28 KiB  | 
| 
		 After Width: | Height: | Size: 628 KiB  | 
| 
		 After Width: | Height: | Size: 1.1 KiB  | 
| 
		 After Width: | Height: | Size: 210 KiB  | 
| 
		 After Width: | Height: | Size: 209 KiB  | 
| 
		 After Width: | Height: | Size: 109 KiB  | 
| 
		 After Width: | Height: | Size: 495 B  | 
| 
		 After Width: | Height: | Size: 1.0 KiB  | 
| 
		 After Width: | Height: | Size: 624 B  | 
| 
		 After Width: | Height: | Size: 136 KiB  | 
| 
		 After Width: | Height: | Size: 214 KiB  | 
| 
		 After Width: | Height: | Size: 36 KiB  | 
| 
		 After Width: | Height: | Size: 3.6 KiB  | 
| 
		 After Width: | Height: | Size: 310 B  | 
| 
		 After Width: | Height: | Size: 929 B  | 
| 
		 After Width: | Height: | Size: 1.3 KiB  | 
| 
		 After Width: | Height: | Size: 3.3 KiB  | 
| 
		 After Width: | Height: | Size: 1.4 KiB  | 
| 
		 After Width: | Height: | Size: 17 KiB  | 
| 
		 After Width: | Height: | Size: 542 B  | 
| 
		 After Width: | Height: | Size: 576 B  | 
| 
		 After Width: | Height: | Size: 733 B  | 
| 
		 After Width: | Height: | Size: 4.3 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 4.0 KiB  | 
| 
		 After Width: | Height: | Size: 1.7 KiB  | 
| 
		 After Width: | Height: | Size: 738 KiB  | 
| 
		 After Width: | Height: | Size: 2.2 KiB  | 
| 
		 After Width: | Height: | Size: 911 B  | 
| 
		 After Width: | Height: | Size: 1.1 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 600 B  | 
| 
		 After Width: | Height: | Size: 673 B  | 
| 
		 After Width: | Height: | Size: 2.0 KiB  | 
| 
		 After Width: | Height: | Size: 462 B  | 
| 
		 After Width: | Height: | Size: 2.1 KiB  | 
| 
		 After Width: | Height: | Size: 926 B  | 
| 
		 After Width: | Height: | Size: 9.0 KiB  | 
| 
		 After Width: | Height: | Size: 23 KiB  | 
| 
		 After Width: | Height: | Size: 7.0 KiB  | 
| 
		 After Width: | Height: | Size: 878 B  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 653 B  | 
| 
		 After Width: | Height: | Size: 800 B  | 
| 
		 After Width: | Height: | Size: 905 B  | 
| 
		 After Width: | Height: | Size: 189 KiB  | 
| 
		 After Width: | Height: | Size: 4.3 KiB  | 
| 
		 After Width: | Height: | Size: 839 B  | 
| 
		 After Width: | Height: | Size: 1.7 KiB  | 
| 
		 After Width: | Height: | Size: 5.9 KiB  | 
| 
		 After Width: | Height: | Size: 1.6 KiB  | 
| 
		 After Width: | Height: | Size: 34 KiB  | 
| 
		 After Width: | Height: | Size: 26 KiB  | 
| 
		 After Width: | Height: | Size: 3.8 KiB  | 
| 
		 After Width: | Height: | Size: 23 KiB  | 
| 
		 After Width: | Height: | Size: 1.9 KiB  | 
| 
		 After Width: | Height: | Size: 2.3 KiB  | 
| 
		 After Width: | Height: | Size: 427 B  | 
| 
		 After Width: | Height: | Size: 627 B  | 
| 
		 After Width: | Height: | Size: 1.1 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 988 B  | 
| 
		 After Width: | Height: | Size: 3.7 KiB  | 
| 
		 After Width: | Height: | Size: 5.0 KiB  | 
| 
		 After Width: | Height: | Size: 875 B  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 92 KiB  | 
| 
		 After Width: | Height: | Size: 131 KiB  | 
| 
		 After Width: | Height: | Size: 88 KiB  | 
| 
		 After Width: | Height: | Size: 87 KiB  | 
| 
		 After Width: | Height: | Size: 92 KiB  | 
| 
		 After Width: | Height: | Size: 87 KiB  | 
| 
		 After Width: | Height: | Size: 114 KiB  | 
| 
		 After Width: | Height: | Size: 101 KiB  | 
| 
		 After Width: | Height: | Size: 66 KiB  | 
| 
		 After Width: | Height: | Size: 83 KiB  | 
| 
		 After Width: | Height: | Size: 160 KiB  | 
| 
		 After Width: | Height: | Size: 57 KiB  | 
| 
		 After Width: | Height: | Size: 114 KiB  | 
| 
		 After Width: | Height: | Size: 35 KiB  | 
| 
		 After Width: | Height: | Size: 80 KiB  | 
| 
		 After Width: | Height: | Size: 60 KiB  |