Browse Source

May 30: [ADD] Initial Commit 'sale_consignment'

pull/320/head
RisvanaCybro 11 months ago
parent
commit
54a82c1f27
  1. 42
      sale_consignment/README.rst
  2. 22
      sale_consignment/__init__.py
  3. 50
      sale_consignment/__manifest__.py
  4. 31
      sale_consignment/data/consignment_expiry_mail.xml
  5. 23
      sale_consignment/data/sequence.xml
  6. 5
      sale_consignment/doc/RELEASE_NOTES.md
  7. 28
      sale_consignment/models/__init__.py
  8. 30
      sale_consignment/models/product_product.py
  9. 43
      sale_consignment/models/res_config_settings.py
  10. 30
      sale_consignment/models/res_partner.py
  11. 213
      sale_consignment/models/sale_consignment.py
  12. 67
      sale_consignment/models/sale_consignment_line.py
  13. 29
      sale_consignment/models/sale_order.py
  14. 52
      sale_consignment/models/stock_picking.py
  15. 3
      sale_consignment/security/ir.model.access.csv
  16. 7
      sale_consignment/security/sale_consignment_groups.xml
  17. BIN
      sale_consignment/static/description/assets/icons/check.png
  18. BIN
      sale_consignment/static/description/assets/icons/chevron.png
  19. BIN
      sale_consignment/static/description/assets/icons/cogs.png
  20. BIN
      sale_consignment/static/description/assets/icons/consultation.png
  21. BIN
      sale_consignment/static/description/assets/icons/ecom-black.png
  22. BIN
      sale_consignment/static/description/assets/icons/education-black.png
  23. BIN
      sale_consignment/static/description/assets/icons/hotel-black.png
  24. BIN
      sale_consignment/static/description/assets/icons/license.png
  25. BIN
      sale_consignment/static/description/assets/icons/lifebuoy.png
  26. BIN
      sale_consignment/static/description/assets/icons/manufacturing-black.png
  27. BIN
      sale_consignment/static/description/assets/icons/pos-black.png
  28. BIN
      sale_consignment/static/description/assets/icons/puzzle.png
  29. BIN
      sale_consignment/static/description/assets/icons/restaurant-black.png
  30. BIN
      sale_consignment/static/description/assets/icons/service-black.png
  31. BIN
      sale_consignment/static/description/assets/icons/trading-black.png
  32. BIN
      sale_consignment/static/description/assets/icons/training.png
  33. BIN
      sale_consignment/static/description/assets/icons/update.png
  34. BIN
      sale_consignment/static/description/assets/icons/user.png
  35. BIN
      sale_consignment/static/description/assets/icons/wrench.png
  36. BIN
      sale_consignment/static/description/assets/misc/categories.png
  37. BIN
      sale_consignment/static/description/assets/misc/check-box.png
  38. BIN
      sale_consignment/static/description/assets/misc/compass.png
  39. BIN
      sale_consignment/static/description/assets/misc/corporate.png
  40. BIN
      sale_consignment/static/description/assets/misc/customer-support.png
  41. BIN
      sale_consignment/static/description/assets/misc/cybrosys-logo.png
  42. BIN
      sale_consignment/static/description/assets/misc/features.png
  43. BIN
      sale_consignment/static/description/assets/misc/logo.png
  44. BIN
      sale_consignment/static/description/assets/misc/pictures.png
  45. BIN
      sale_consignment/static/description/assets/misc/pie-chart.png
  46. BIN
      sale_consignment/static/description/assets/misc/right-arrow.png
  47. BIN
      sale_consignment/static/description/assets/misc/star.png
  48. BIN
      sale_consignment/static/description/assets/misc/support.png
  49. BIN
      sale_consignment/static/description/assets/misc/whatsapp.png
  50. BIN
      sale_consignment/static/description/assets/modules/educational.png
  51. BIN
      sale_consignment/static/description/assets/modules/frond.png
  52. BIN
      sale_consignment/static/description/assets/modules/insurance.png
  53. BIN
      sale_consignment/static/description/assets/modules/laundry.png
  54. BIN
      sale_consignment/static/description/assets/modules/legal.png
  55. BIN
      sale_consignment/static/description/assets/modules/spa.png
  56. BIN
      sale_consignment/static/description/assets/screenshots/consignment _moves.png
  57. BIN
      sale_consignment/static/description/assets/screenshots/consignment_order.png
  58. BIN
      sale_consignment/static/description/assets/screenshots/hero.gif
  59. BIN
      sale_consignment/static/description/assets/screenshots/mail_notification.png
  60. BIN
      sale_consignment/static/description/assets/screenshots/operation.png
  61. BIN
      sale_consignment/static/description/assets/screenshots/pickings.png
  62. BIN
      sale_consignment/static/description/assets/screenshots/sale_order.png
  63. BIN
      sale_consignment/static/description/assets/screenshots/settings.png
  64. BIN
      sale_consignment/static/description/assets/screenshots/tr_loc.png
  65. BIN
      sale_consignment/static/description/banner.png
  66. BIN
      sale_consignment/static/description/cybro_logo.png
  67. BIN
      sale_consignment/static/description/icon.png
  68. 635
      sale_consignment/static/description/index.html
  69. 17
      sale_consignment/views/product_product_views.xml
  70. 68
      sale_consignment/views/res_config_settings_views.xml
  71. 16
      sale_consignment/views/res_partner_views.xml
  72. 49
      sale_consignment/views/sale_consignment_line_views.xml
  73. 120
      sale_consignment/views/sale_consignment_views.xml
  74. 13
      sale_consignment/views/sale_order_views.xml

42
sale_consignment/README.rst

@ -0,0 +1,42 @@
.. 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 helps you to Sale products as Consignment Order
Configuration
=============
* No additional configurations needed.
License
-------
General Public License, Version 3 (AGPL v3).
(https://www.gnu.org/licenses/agpl-3.0-standalone.html)
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
Credits
-------
Developer: (V16) Vishnu Kp, Contact : odoo@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>`__

22
sale_consignment/__init__.py

@ -0,0 +1,22 @@
# -*- 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 . import models

50
sale_consignment/__manifest__.py

@ -0,0 +1,50 @@
# -*- 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/>.
################################################################################
{
'name': "Sale Consignment",
'version': "16.0.1.0.0",
'category': 'Sales',
'summary': """This Module Helps to manage the sales order with consignment mode""",
'description': """To create sale order with consignment option""",
'author': "Cybrosys Techno Solutions",
'company': "Cybrosys Techno Solutions",
'maintainer': "Cybrosys Techno Solutions",
'website': "https://www.cybrosys.com",
'depends': ['base', 'sale_management', 'sale_stock', 'mail'],
'data': ['security/sale_consignment_groups.xml',
'security/ir.model.access.csv',
'data/consignment_expiry_mail.xml',
'data/sequence.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_product_views.xml',
'views/sale_order_views.xml'],
'images': [
'static/description/banner.png',
],
'license': "AGPL-3",
'installable': True,
'auto_install': False,
'application': False
}

31
sale_consignment/data/consignment_expiry_mail.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<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&amp;model=sale.consignment&amp;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>

23
sale_consignment/data/sequence.xml

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<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>
<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="numbercall">-1</field>
<field name="priority">3</field>
</record>
</odoo>

5
sale_consignment/doc/RELEASE_NOTES.md

@ -0,0 +1,5 @@
## Module <sale_consignment>
#### 08.03.2024
#### Version 16.0.1.0.0
##### ADD
- Initial Commit for Sale Consignment

28
sale_consignment/models/__init__.py

@ -0,0 +1,28 @@
# -*- 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 . import product_product
from . import res_config_settings
from . import sale_consignment
from . import sale_consignment_line
from . import sale_order
from . import stock_picking
from . import res_partner

30
sale_consignment/models/product_product.py

@ -0,0 +1,30 @@
# -*- 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 models, fields
class ProductProduct(models.Model):
_inherit = 'product.product'
is_consignment = fields.Boolean(
string='Consignment Product', help="Enable it will consider as a "
"Consignment product")

43
sale_consignment/models/res_config_settings.py

@ -0,0 +1,43 @@
# -*- 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 models, fields
class ResConfigSettings(models.TransientModel):
_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 unbuild 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',
implied_group='sale_consignment.group_consignment_order')
consignment_product_only = fields.Boolean(string='Consignment Product',
config_parameter='sale_consignment.consignment_product_only', )
consignment_customer_only = fields.Boolean(string='Consignment Customer',
config_parameter='sale_consignment.consignment_customer_only', )

30
sale_consignment/models/res_partner.py

@ -0,0 +1,30 @@
# -*- 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 models, fields
class ResPartner(models.Model):
_inherit = 'res.partner'
is_consignment = fields.Boolean(
string="Consignment Customer",
help='Enable Customer as Consignment Category')

213
sale_consignment/models/sale_consignment.py

@ -0,0 +1,213 @@
# -*- 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']
@api.model
def _settings_domain(self):
customer_domain = self.env['ir.config_parameter'].get_param(
'sale_consignment.consignment_product_only')
return customer_domain
@api.model
def _default_destination(self):
location_dest_id = self.env['ir.config_parameter'].get_param(
'sale_consignment.location_dest_id')
return int(location_dest_id)
@api.depends('customer_domain')
def _partner_domain(self):
if self.env['ir.config_parameter'].get_param(
'sale_consignment.consignment_customer_only'):
return [('is_consignment', '=', True)]
else:
return []
name = fields.Char(string='Name', help="Sequence of the consignment Sale",
default='New')
company_id = fields.Many2one('res.company',
default=lambda self: self.env.user.company_id)
partner_id = fields.Many2one('res.partner', string='Customer',
domain=lambda self: self._partner_domain(),
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')
state = fields.Selection(
selection=[('draft', 'Draft'), ('confirm', 'Confirm')],
default="draft")
user_id = fields.Many2one("res.users", string='Sales Person',
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',
compute='_compute_sale_count')
picking_count = fields.Integer(string='Picking Order',
compute='_compute_picking_count')
sale_order_id = fields.Many2one('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='')
customer_domain = fields.Boolean(
default=lambda self: self._settings_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.model
def create(self, vals):
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):
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):
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):
self.price_list_id = self.partner_id.property_product_pricelist.id
def action_order_confirm(self):
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,
'product_uom_qty': line.demand_quantity,
'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):
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):
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):
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):
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()

67
sale_consignment/models/sale_consignment_line.py

@ -0,0 +1,67 @@
# -*- 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 fields, models, api
class SaleConsignmentLine(models.Model):
_name = "sale.consignment.line"
_description = "Sale Consignment Line"
@api.model
def _settings_domain(self):
product_domain = self.env[
'ir.config_parameter'].get_param(
'sale_consignment.consignment_product_only')
return product_domain
@api.depends('product_domain')
def _product_domain(self):
if self.env['ir.config_parameter'].get_param(
'sale_consignment.consignment_product_only'):
return [('is_consignment', '=', True)]
else:
return []
product_id = fields.Many2one('product.product', string='Products',
help="Product in the consignment order line",
domain=lambda self: self._product_domain(),
required=True)
demand_quantity = fields.Integer(string='Demand Quantity',
help="Demanded quantity of the product",
required=True)
done_quantity = fields.Integer(string='Done Quantity',
help="Done quantity of the product")
remaining_quantity = fields.Integer(string='Remaining Quantity',
help="Quantity of remaining product",
compute='_compute_remaining_quantity')
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()
product_domain = fields.Boolean(
default=lambda self: self._settings_domain())
def _compute_remaining_quantity(self):
for rec in self:
rec.remaining_quantity = rec.demand_quantity - rec.done_quantity

29
sale_consignment/models/sale_order.py

@ -0,0 +1,29 @@
# -*- 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 models, fields
class SaleOrder(models.Model):
_inherit = 'sale.order'
consignment_id = fields.Many2one('sale.consignment',
string='Source Document')

52
sale_consignment/models/stock_picking.py

@ -0,0 +1,52 @@
# -*- 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
class StockPicking(models.Model):
_inherit = 'stock.picking'
consignment_id = fields.Many2one('sale.consignment',
help='Related Consignment Id')
def button_validate(self):
res = super().button_validate()
consignment_id = self.sale_id.consignment_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
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
location_dest_id = int(self.env['ir.config_parameter'].get_param(
'sale_consignment.location_dest_id'))
sale_name = res.origin
sale = self.env['sale.order'].search([('name', '=', sale_name)])
if sale.consignment_id:
res.location_id = location_dest_id
return res

3
sale_consignment/security/ir.model.access.csv

@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sale_consignment_user,access.sale.consignment.user,model_sale_consignment,base.group_user,1,1,1,1
access_sale_consignment_line_user,access.sale.consignment.line.user,model_sale_consignment_line,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sale_consignment_user access.sale.consignment.user model_sale_consignment base.group_user 1 1 1 1
3 access_sale_consignment_line_user access.sale.consignment.line.user model_sale_consignment_line base.group_user 1 1 1 1

7
sale_consignment/security/sale_consignment_groups.xml

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<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>

BIN
sale_consignment/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
sale_consignment/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
sale_consignment/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
sale_consignment/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
sale_consignment/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
sale_consignment/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
sale_consignment/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
sale_consignment/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
sale_consignment/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sale_consignment/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
sale_consignment/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
sale_consignment/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
sale_consignment/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
sale_consignment/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
sale_consignment/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
sale_consignment/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
sale_consignment/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sale_consignment/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
sale_consignment/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sale_consignment/static/description/assets/misc/categories.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
sale_consignment/static/description/assets/misc/check-box.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
sale_consignment/static/description/assets/misc/compass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
sale_consignment/static/description/assets/misc/corporate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
sale_consignment/static/description/assets/misc/customer-support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
sale_consignment/static/description/assets/misc/cybrosys-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
sale_consignment/static/description/assets/misc/features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

BIN
sale_consignment/static/description/assets/misc/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
sale_consignment/static/description/assets/misc/pictures.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
sale_consignment/static/description/assets/misc/pie-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
sale_consignment/static/description/assets/misc/right-arrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

BIN
sale_consignment/static/description/assets/misc/star.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
sale_consignment/static/description/assets/misc/support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
sale_consignment/static/description/assets/misc/whatsapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
sale_consignment/static/description/assets/modules/educational.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

BIN
sale_consignment/static/description/assets/modules/frond.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
sale_consignment/static/description/assets/modules/insurance.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
sale_consignment/static/description/assets/modules/laundry.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
sale_consignment/static/description/assets/modules/legal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
sale_consignment/static/description/assets/modules/spa.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
sale_consignment/static/description/assets/screenshots/consignment _moves.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
sale_consignment/static/description/assets/screenshots/consignment_order.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
sale_consignment/static/description/assets/screenshots/hero.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
sale_consignment/static/description/assets/screenshots/mail_notification.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
sale_consignment/static/description/assets/screenshots/operation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
sale_consignment/static/description/assets/screenshots/pickings.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
sale_consignment/static/description/assets/screenshots/sale_order.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

BIN
sale_consignment/static/description/assets/screenshots/settings.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
sale_consignment/static/description/assets/screenshots/tr_loc.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
sale_consignment/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
sale_consignment/static/description/cybro_logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
sale_consignment/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

635
sale_consignment/static/description/index.html

@ -0,0 +1,635 @@
<div style="background-color: #714B67; height: 810px; width: 100%; padding: 15px; position: relative;">
<!-- TITLE BAR -->
<div class="d-flex align-items-center justify-content-between"
style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;">
<img src="assets/misc/cybrosys-logo.png" width="42" height="42" style="width: 42px; height: 42px;" />
<div>
<div style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Community
</div>
</div>
</div>
<!-- END OF TITLE BAR -->
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12">
<!-- APP HERO -->
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;">
Sales Consignment
</h1>
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">
Customer Can Sell Product as a Consignment Order.
</p>
<!-- END OF APP HERO -->
<img src="assets/screenshots/hero.gif"
style="width: 75%; height: auto; position: absolute; margin-left: auto; margin-right: auto; top: 45%; left: 12%; right: auto;"/>
</div>
</div>
</div>
</div>
<!-- NAVIGATION SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px; margin-top: 300px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/compass.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Explore This
Module</h2>
</div>
<div class="row my-4" style="font-family: 'Montserrat', sans-serif;">
<div class="col-sm-12 col-md-6 my-3">
<a href="#overview">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Overview</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">Learn
more about this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36" />
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#features">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Features</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
features of this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36" />
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#screenshots">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Screenshots</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
screenshots for this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36" />
</div>
</a>
</div>
</div>
<!-- END OF NAVIGATION SECTION -->
<!-- OVERVIEW SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="overview">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pie-chart.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Overview
</h2>
</div>
<div class="row" style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 py-4">
The Sale Consignment module is a valuable application for managing product
sales through consignment orders. It enables you to sell products under
consignment terms, with automatic updates sent to the sales team via email
when consignment expiry times are reached. This functionality ensures
efficient management of consignment sales and timely notifications for
salesmen, enhancing overall sales processes and customer satisfaction.
</div>
</div>
<!-- END OF OVERVIEW SECTION -->
<!-- FEATURES SECTION -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="features">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/features.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Features
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-start"
style="margin-top: 40px; margin-bottom: 40px">
<img src="./assets/misc/check-box.png" class="mr-2"/>
<div>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Sell Products as Consignment
</span>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 12px;">
User can Sell Products as Consignment Method.
</span>
</div>
</div>
<div class="d-flex align-items-start"
style="margin-top: 40px; margin-bottom: 40px">
<img src="./assets/misc/check-box.png" class="mr-2"/>
<div>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Picking and Sales direct access
</span>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 12px;">
Direct Pickings and Sales Records access from Consignment order.
</span>
</div>
</div>
<div class="d-flex align-items-start"
style="margin-top: 40px; margin-bottom: 40px">
<img src="./assets/misc/check-box.png" class="mr-2"/>
<div>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Move History
</span>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 12px;">
User can View the Move history
</span>
</div>
</div>
<div class="d-flex align-items-start"
style="margin-top: 40px; margin-bottom: 40px">
<img src="./assets/misc/check-box.png" class="mr-2"/>
<div>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Multi Sale Order for one Consignment
</span>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 12px;">
User can Create more than one sale order for a Consignment order
</span>
</div>
</div>
<div class="d-flex align-items-start"
style="margin-top: 40px; margin-bottom: 40px">
<img src="./assets/misc/check-box.png" class="mr-2"/>
<div>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Mail Notification
</span>
<span style="display: block; font-family: 'Montserrat', sans-serif; font-size: 12px;">
After the consignment expires, the salesperson will receive a mail notification.
</span>
</div>
</div>
</div>
</div>
<!-- END OF FEATURES SECTION -->
<!-- SCREENSHOTS SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="screenshots">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="./assets/misc/pictures.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Screenshots
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Configuration Settings
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Enable the Feature from here.
</p>
<img src="./assets/screenshots/settings.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Location
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Create Consignment Location as the transit location.
</p>
<img src="./assets/screenshots/tr_loc.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Operation type
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Create the Operation type for the Consignment move from location your location and to as consignment location
</p>
<img src="./assets/screenshots/operation.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Order
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Can create the order here.
</p>
<img src="./assets/screenshots/consignment_order.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Related Sale order
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
We can see the created sale order from here.
</p>
<img src="./assets/screenshots/sale_order.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Related Pickings
</h3>
<img src="./assets/screenshots/pickings.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Consignment Moves Records
</h3>
<img src="./assets/screenshots/consignment _moves.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Mail Notification
</h3>
<img src="./assets/screenshots/mail_notification.png"
class="img-thumbnail">
</div>
</div>
</div>
<!-- END OF SCREENSHOTS SECTION -->
<!-- RELATED PRODUCTS -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/categories.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Related
Products
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div id="demo1" class="row carousel slide" data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner" style="padding: 30px;">
<div class="carousel-item" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/insurance_management_cybro/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/insurance.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/front_office_management/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/frond.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/salon_management/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/spa.png">
</div>
</a>
</div>
</div>
<div class="carousel-item active"
style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/laundry_management/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/laundry.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/legal_case_management/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/legal.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/education_attendances/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/educational.png">
</div>
</a>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#demo1" data-slide="prev"
style="width:35px; color:#000"> <span
class="carousel-control-prev-icon"><i
class="fa fa-chevron-left"
style="font-size:24px"></i></span>
</a> <a class="carousel-control-next" href="#demo1"
data-slide="next" style="width:35px; color:#000">
<span class="carousel-control-next-icon"><i
class="fa fa-chevron-right"
style="font-size:24px"></i></span>
</a>
</div>
</div>
</div>
<!-- END OF RELATED PRODUCTS -->
<!-- OUR SERVICES -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/star.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Our Services
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/cogs.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Customization</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/wrench.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/lifebuoy.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Support</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/user.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Hire
Odoo
Developer</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/puzzle.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Integration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/update.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Migration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/consultation.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Consultancy</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/training.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/license.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Licensing Consultancy</h6>
</div>
</div>
</div>
<!-- END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/corporate.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Our
Industries
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/trading-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Trading
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easily procure
and
sell your products</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/pos-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
POS
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easy
configuration
and convivial experience</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/education-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Education
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
A platform for
educational management</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/manufacturing-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Manufacturing
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Plan, track and
schedule your operations</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/ecom-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
E-commerce &amp; Website
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Mobile
friendly,
awe-inspiring product pages</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/service-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Service Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Keep track of
services and invoice</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/restaurant-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Restaurant
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Run your bar or
restaurant methodically</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/hotel-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Hotel Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
An
all-inclusive
hotel management application</p>
</div>
</div>
</div>
</div>
<!--END OF OUR INDUSTRIES -->
<!-- SUPPORT -->
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/customer-support.png" />
</div>
<h2 class="mt-2" style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">Support
</h2>
</div>
<div class="container mt-5">
<div class="row">
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #714B67; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/support.png" height="48" width="48" style="width: 42px; height: 42px;" />
</div>
<div>
<h4>Need Help?</h4>
<p style="line-height: 100%;">Got questions or need help? Get in touch.</p>
<a href="mailto:odoo@cybrosys.com">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
odoo@cybrosys.com</p>
</a>
</div>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #2AC44D; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/whatsapp.png" height="52" width="52" style="width: 52px; height: 52px;" />
</div>
<div>
<h4>WhatsApp</h4>
<p style="line-height: 100%;">Say hi to us on WhatsApp!</p>
<a href="https://api.whatsapp.com/send?phone=918606827707">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">+91 86068
27707</p>
</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 my-5 d-flex justify-content-center align-items-center">
<img src="assets/misc/logo.png" width="144" height="31" style="width:144px; height: 31px; margin-top: 40px;" />
</div>
</div>
</div>
<!-- END OF SUPPORT -->

17
sale_consignment/views/product_product_views.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="product_normal_form_view" model="ir.ui.view">
<field name="name">product.product.view.form.inherit.sale.consignment
</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<xpath expr="//label[@for='purchase_ok']"
position="after">
<field name="is_consignment"/>
<label for="is_consignment"/>
</xpath>
</field>
</record>
</odoo>

68
sale_consignment/views/res_config_settings_views.xml

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.delivery
</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="sale.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='quotation_order_setting_container']"
position="after">
<h2>Sale Consignment</h2>
<div class="row mt16 o_settings_container"
name="consignment_order">
<div class="col-12 col-lg-6 o_setting_box"
id="settings_consignment_order">
<div class="o_setting_left_pane">
<field name="group_consignment_order"/>
</div>
<div class="o_setting_right_pane">
<label for="group_consignment_order"/>
<div class="text-muted">
Enable the sale consignment order
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
id="settings_consignment_destination"
attrs="{'invisible': [('group_consignment_order', '!=', True)]}">
<div class="o_setting_right_pane">
<field name="location_dest_id"/>
<div class="text-muted">
Choose the product destination location.
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
id="settings_consignment_product"
attrs="{'invisible': [('group_consignment_order', '!=', True)]}">
<div class="o_setting_left_pane">
<field name="consignment_product_only"/>
</div>
<div class="o_setting_right_pane">
<label for="consignment_product_only"/>
<div class="text-muted">
Enable product filtered in consignment by
consignment product.
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
id="settings_consignment_customer"
attrs="{'invisible': [('group_consignment_order', '!=', True)]}">
<div class="o_setting_left_pane">
<field name="consignment_customer_only"/>
</div>
<div class="o_setting_right_pane">
<label for="consignment_customer_only"/>
<div class="text-muted">
Enable customer filtered in consignment by
consignment customer.
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

16
sale_consignment/views/res_partner_views.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_partner_form" model="ir.ui.view">
<field name="name">res.partner.form.inherit.sale.consignment</field>
<field name="model">res.partner</field>
<field name="priority">20</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='category_id']" position="before">
<field name="is_consignment"/>
</xpath>
</data>
</field>
</record>
</odoo>

49
sale_consignment/views/sale_consignment_line_views.xml

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record model="ir.ui.view" id="sale_consignment_line_view_tree">
<field name="name">sale.consignment.line</field>
<field name="model">sale.consignment.line</field>
<field name="arch" type="xml">
<tree create="false">
<field name="product_id"/>
<field name="consignment_id" string="Consignment"/>
<field name="demand_quantity"/>
<field name="done_quantity"/>
<field name="remaining_quantity"/>
<field name="price"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="sale_consignment_line_view_form">
<field name="name">sale.consignment.line</field>
<field name="model">sale.consignment.line</field>
<field name="arch" type="xml">
<form string="Consignment line">
<group>
<field name="product_id"/>
<field name="demand_quantity"/>
<field name="done_quantity"/>
<field name="remaining_quantity"/>
<field name="product_domain" invisible="1"/>
<field name="price"/>
</group>
</form>
</field>
</record>
<record id="sale_consignment_line_action" model="ir.actions.act_window">
<field name="name">Consignment lines</field>
<field name="res_model">sale.consignment.line</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem
name="Consignment moves"
id="sale_consignment_line_menu"
parent="sale.sale_menu_root"
action="sale_consignment_line_action"
groups="sale_consignment.group_consignment_order"
sequence="22"/>
</odoo>

120
sale_consignment/views/sale_consignment_views.xml

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Action-->
<record id="sale_consignment_action" model="ir.actions.act_window">
<field name="name">Consignment</field>
<field name="res_model">sale.consignment</field>
<field name="view_mode">tree,form</field>
</record>
<record model="ir.ui.view" id="sale_consignment_view_form">
<field name="name">sale.consignment</field>
<field name="model">sale.consignment</field>
<field name="arch" type="xml">
<form string="Consignment">
<header>
<field name="state" widget="statusbar"/>
<button name="action_order_confirm" string="Confirm"
type="object" class="btn-primary"
attrs="{'invisible': [('state', '!=', 'draft')]}"
/>
<button name="create_sale_order" string="Create Sale Order"
type="object" class="btn-primary"
attrs="{'invisible': [('state', '!=', 'confirm')]}"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="action_view_order"
attrs="{'invisible': [('sale_count', '=', 0)]}"
string="Sale order"
type="object"
class="oe_stat_button"
icon="fa-pencil-square-o">
<field name="sale_count" widget="statinfo"
attrs="{'invisible': [('sale_count', '=', 0)]}"
string=" Sale order"> </field>
</button>
<button name="action_view_pickings"
attrs="{'invisible': [('picking_count', '=', 0)]}"
string="Pickings"
type="object"
class="oe_stat_button"
icon="fa-pencil-square-o">
<field name="picking_count" widget="statinfo"
attrs="{'invisible': [('picking_count', '=', 0)]}"
string=" Pickings"> </field>
</button>
</div>
<div class="oe_title">
<h1>
<field name="name" readonly="1"/>
</h1>
</div>
<group>
<group col="4">
<field name="partner_id"/>
<field name="user_id"/>
<field name="company_id"/>
<field name="location_id"/>
<field name="customer_domain" invisible="1"/>
</group>
<group col="4">
<field name="date"/>
<field name="price_list_id"/>
<field name="end_date"/>
</group>
</group>
<notebook>
<page string="Order line" name="Order line">
<field name="consignment_line_ids" attrs="{'readonly': [('state', '=', 'confirm')]}">
<tree string="Order lines" editable="bottom" >
<field name="product_id"/>
<field name="demand_quantity"/>
<field name="done_quantity"/>
<field name="remaining_quantity"/>
<field name="product_domain"
invisible="1"/>
<field name="price"/>
</tree>
</field>
</page>
<page string="Other Info" name="Other Info">
<group>
<field name="location_dest_id"/>
<field name="ware_house_id"/>
</group>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" groups="base.group_user"
options="{'post_refresh': 'recipients'}"/>
<field name="activity_ids"/>
<field name="message_ids"/>
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="sale_consignment_view_tree">
<field name="name">sale.consignment</field>
<field name="model">sale.consignment</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="user_id"/>
<field name="partner_id"/>
<field name="date"/>
<field name="end_date"/>
</tree>
</field>
</record>
<menuitem
name="Consignment"
id="sale_consignment_menu"
parent="sale.sale_menu_root"
action="sale_consignment_action"
groups="sale_consignment.group_consignment_order"
sequence="20"/>
</odoo>

13
sale_consignment/views/sale_order_views.xml

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<odoo>
<record id="view_order_form" model="ir.ui.view">
<field name="name">sale.order.form.inherit</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='sale_order_template_id']" position="after">
<field name="consignment_id"/>
</xpath>
</field>
</record>
</odoo>
Loading…
Cancel
Save