Browse Source

Nov 16 : [ADD] Initial Commit 'delivery_slot'

pull/295/head
RisvanaCybro 1 year ago
parent
commit
536c6de93b
  1. 46
      delivery_slot/README.rst
  2. 23
      delivery_slot/__init__.py
  3. 58
      delivery_slot/__manifest__.py
  4. 22
      delivery_slot/controllers/__init__.py
  5. 104
      delivery_slot/controllers/delivery_slot.py
  6. 40
      delivery_slot/data/slot_time_data.xml
  7. 6
      delivery_slot/doc/RELEASE_NOTES.md
  8. 26
      delivery_slot/models/__init__.py
  9. 99
      delivery_slot/models/delivery_slot.py
  10. 31
      delivery_slot/models/res_config_settings.py
  11. 147
      delivery_slot/models/sale_order.py
  12. 61
      delivery_slot/models/slot_time.py
  13. 81
      delivery_slot/models/stock_move.py
  14. 3
      delivery_slot/security/ir.model.access.csv
  15. BIN
      delivery_slot/static/description/assets/icons/check.png
  16. BIN
      delivery_slot/static/description/assets/icons/chevron.png
  17. BIN
      delivery_slot/static/description/assets/icons/cogs.png
  18. BIN
      delivery_slot/static/description/assets/icons/consultation.png
  19. BIN
      delivery_slot/static/description/assets/icons/ecom-black.png
  20. BIN
      delivery_slot/static/description/assets/icons/education-black.png
  21. BIN
      delivery_slot/static/description/assets/icons/hotel-black.png
  22. BIN
      delivery_slot/static/description/assets/icons/license.png
  23. BIN
      delivery_slot/static/description/assets/icons/lifebuoy.png
  24. BIN
      delivery_slot/static/description/assets/icons/logo.png
  25. BIN
      delivery_slot/static/description/assets/icons/manufacturing-black.png
  26. BIN
      delivery_slot/static/description/assets/icons/pos-black.png
  27. BIN
      delivery_slot/static/description/assets/icons/puzzle.png
  28. BIN
      delivery_slot/static/description/assets/icons/restaurant-black.png
  29. BIN
      delivery_slot/static/description/assets/icons/service-black.png
  30. BIN
      delivery_slot/static/description/assets/icons/trading-black.png
  31. BIN
      delivery_slot/static/description/assets/icons/training.png
  32. BIN
      delivery_slot/static/description/assets/icons/update.png
  33. BIN
      delivery_slot/static/description/assets/icons/user.png
  34. BIN
      delivery_slot/static/description/assets/icons/wrench.png
  35. BIN
      delivery_slot/static/description/assets/misc/categories.png
  36. BIN
      delivery_slot/static/description/assets/misc/check-box.png
  37. BIN
      delivery_slot/static/description/assets/misc/compass.png
  38. BIN
      delivery_slot/static/description/assets/misc/corporate.png
  39. BIN
      delivery_slot/static/description/assets/misc/customer-support.png
  40. BIN
      delivery_slot/static/description/assets/misc/cybrosys-logo.png
  41. BIN
      delivery_slot/static/description/assets/misc/features.png
  42. BIN
      delivery_slot/static/description/assets/misc/logo.png
  43. BIN
      delivery_slot/static/description/assets/misc/pictures.png
  44. BIN
      delivery_slot/static/description/assets/misc/pie-chart.png
  45. BIN
      delivery_slot/static/description/assets/misc/right-arrow.png
  46. BIN
      delivery_slot/static/description/assets/misc/star.png
  47. BIN
      delivery_slot/static/description/assets/misc/support.png
  48. BIN
      delivery_slot/static/description/assets/misc/whatsapp.png
  49. BIN
      delivery_slot/static/description/assets/modules/dynamic_product_fields.png
  50. BIN
      delivery_slot/static/description/assets/modules/dynamic_sale_order_fields.png
  51. BIN
      delivery_slot/static/description/assets/modules/picking_order_line_view.png
  52. BIN
      delivery_slot/static/description/assets/modules/sale_discount_total.png
  53. BIN
      delivery_slot/static/description/assets/modules/sale_order_line_views.png
  54. BIN
      delivery_slot/static/description/assets/modules/sale_purchase_previous_product_cost.png
  55. BIN
      delivery_slot/static/description/assets/screenshots/0.png
  56. BIN
      delivery_slot/static/description/assets/screenshots/1.png
  57. BIN
      delivery_slot/static/description/assets/screenshots/2.png
  58. BIN
      delivery_slot/static/description/assets/screenshots/3.png
  59. BIN
      delivery_slot/static/description/assets/screenshots/4.png
  60. BIN
      delivery_slot/static/description/assets/screenshots/5.png
  61. BIN
      delivery_slot/static/description/assets/screenshots/6.png
  62. BIN
      delivery_slot/static/description/assets/screenshots/hero.gif
  63. BIN
      delivery_slot/static/description/banner.jpg
  64. BIN
      delivery_slot/static/description/icon.png
  65. 675
      delivery_slot/static/description/index.html
  66. 37
      delivery_slot/static/src/js/delivery_slot.js
  67. 34
      delivery_slot/static/src/js/slot_time.js
  68. 24
      delivery_slot/static/src/js/website_sale_utils.js
  69. 52
      delivery_slot/views/delivery_slot_views.xml
  70. 28
      delivery_slot/views/res_config_settings_views.xml
  71. 34
      delivery_slot/views/sale_order_views.xml
  72. 43
      delivery_slot/views/slot_time_views.xml
  73. 61
      delivery_slot/views/website_delivery_slot_templates.xml
  74. 32
      delivery_slot/views/website_slot_time_templates.xml

46
delivery_slot/README.rst

@ -0,0 +1,46 @@
.. 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
Delivery Slot
=============
This module helps you to choose different delivery slot for each product.
Configuration
=============
* No additional configurations needed
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
License
-------
Gnu Affero General Public License, Version 3 (AGPL v3).
(https://www.gnu.org/licenses/agpl-3.0-standalone.html)
Credits
-------
* Developer : (V16) Muhsina V, 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>`__

23
delivery_slot/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Muhsina V (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 controllers
from . import models

58
delivery_slot/__manifest__.py

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Muhsina V (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': 'Delivery Slot',
'version': '16.0.1.0.0',
'category': 'Sales',
'summary': "Time slot selection for deliveries",
'description': """This module helps to choose a different delivery date
and time for each product in the order line. Multiple deliveries and
corresponding delivery slots are created for each line in the sale order,
based on the chosen date and slot.""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': ['sale_management', 'stock', 'account', 'website_sale'],
'data': [
'security/ir.model.access.csv',
'data/slot_time_data.xml',
'views/delivery_slot_views.xml',
'views/res_config_settings_views.xml',
'views/sale_order_views.xml',
'views/slot_time_views.xml',
'views/website_delivery_slot_templates.xml',
'views/website_slot_time_templates.xml',
],
'assets': {
'web.assets_frontend': [
'delivery_slot/static/src/js/delivery_slot.js',
'delivery_slot/static/src/js/slot_time.js',
'delivery_slot/static/src/js/website_sale_utils.js',
],
},
'images': ['static/description/banner.jpg'],
'licence': 'AGPL-3',
'installable': True,
'auto_install': False,
'application': False,
}

22
delivery_slot/controllers/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Muhsina V (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 delivery_slot

104
delivery_slot/controllers/delivery_slot.py

@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Muhsina V (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 http
from odoo.http import request
from odoo.addons.website_sale.controllers.main import WebsiteSale
class WebsiteSale(WebsiteSale):
"""Extends the WebsiteSale controller to add delivery slot functionality.
"""
@http.route(['/shop/cart'], type='http', auth="public", website=True)
def cart(self, **post):
""" Adding extra field to choose delivery date and slot for each
cart lines"""
val = super().cart(**post)
is_delivery_slot = request.env['ir.config_parameter'].sudo().get_param(
'delivery_slot.enable_delivery_date')
slots = request.env['slot.time'].search([])
slot_home = request.env['slot.time'].search([]).filtered(
lambda l: l.slot_type == 'home')
slot_office = request.env['slot.time'].search([]).filtered(
lambda l: l.slot_type == 'office')
val.qcontext.update({
'is_delivery_slot': is_delivery_slot,
'slots': slots,
'slot_home': slot_home,
'slot_office': slot_office,
})
return val
@http.route(['/shop/cart/update_json'], type='json', auth="public",
methods=['POST'], website=True, csrf=False)
def cart_update_json(self, **kw):
"""Passing delivery date and slot values"""
val = super().cart_update_json(**kw)
is_delivery_slot = request.env['ir.config_parameter'].sudo().get_param(
'delivery_slot.enable_delivery_date')
slots = request.env['slot.time'].search([])
slot_home = request.env['slot.time'].search([]).filtered(
lambda l: l.slot_type == 'home')
slot_office = request.env['slot.time'].search([]).filtered(
lambda l: l.slot_type == 'office')
val.update({
'is_delivery_slot': is_delivery_slot,
'slots': slots,
'slot_home': slot_home,
'slot_office': slot_office,
})
return val
@http.route(['/shop/cart/get_option'], type='json', auth="public",
website=True)
def get_option(self, **kw):
""" Called when changing the slot timing ie office hours or home hours
returns the option chosen"""
option = kw.get('selected_option')
slot_filtered = request.env['slot.time'].search([]).filtered(
lambda l: l.slot_type == option)
options = [[slot.id, slot.name] for slot in slot_filtered]
return options
@http.route(['/shop/cart/set_delivery_date'], type='json', auth="public",
website=True)
def set_delivery_date(self, **kwargs):
"""Sets the delivery date for each order line of sale order created"""
order = request.website.sale_get_order()
date = kwargs.get('delivery_date')
line_id = int(kwargs.get('line_id'))
for line in order.order_line:
if line.id == line_id:
if date:
line.delivery_date = date
@http.route(['/shop/cart/set_delivery_slot'], type='json', auth="public",
website=True)
def set_delivery_slot(self, **kwargs):
"""Sets the delivery slots for each order line of sale order created"""
order = request.website.sale_get_order()
slot_id = int(kwargs.get('delivery_slot'))
line_id = int(kwargs.get('line_id'))
for line in order.order_line:
if line.id == line_id:
if slot_id:
line.slot_id = request.env['slot.time'].browse(slot_id)

40
delivery_slot/data/slot_time_data.xml

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data noupdate="1">
<!-- Slot Time record 1 -->
<record id="record_1" model="slot.time">
<field name="name">6AM TO 6PM</field>
<field name="slot_type">home</field>
<field name="time_from">6</field>
<field name="time_to">18</field>
</record>
<!-- Slot Time record 2 -->
<record id="record_2" model="slot.time">
<field name="name">9AM TO 5PM</field>
<field name="slot_type">office</field>
<field name="time_from">9</field>
<field name="time_to">17</field>
</record>
<!-- Slot Time record 3 -->
<record id="record_3" model="slot.time">
<field name="name">10AM TO 6PM</field>
<field name="slot_type">office</field>
<field name="time_from">10</field>
<field name="time_to">18</field>
</record>
<!-- Slot Time record 4 -->
<record id="record_4" model="slot.time">
<field name="name">2PM TO 5PM</field>
<field name="slot_type">office</field>
<field name="time_from">2</field>
<field name="time_to">17</field>
</record>
<!-- Slot Time record 5 -->
<record id="record_5" model="slot.time">
<field name="name">7AM TO 10PM</field>
<field name="slot_type">home</field>
<field name="time_from">7</field>
<field name="time_to">22</field>
</record>
</data>
</odoo>

6
delivery_slot/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module <delivery_slot>
#### 13.11.2023
#### Version 16.0.1.0.0
##### ADD
- Initial Commit for Delivery Slot

26
delivery_slot/models/__init__.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Muhsina V (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 delivery_slot
from . import res_config_settings
from . import sale_order
from . import slot_time
from . import stock_move

99
delivery_slot/models/delivery_slot.py

@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Muhsina V (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 DeliverySlot(models.Model):
""" Delivery slot model"""
_name = 'delivery.slot'
_description = 'Delivery slot'
_rec_name = 'delivery_date'
delivery_date = fields.Date(
string='Delivery Date', default=fields.Date.today(),
help="Choose a delivery date")
slot_id = fields.Many2one('slot.time', string="slot",
help="Choose Delivery slot")
delivery_ids = fields.One2many(
'sale.order', 'delivery_slot_id', string="Delivery",
compute="_compute_sale_ids", help="Related Deliveries")
delivery_limit = fields.Integer(string="Delivery Limit", default=100,
help="Limit of this delivery slot")
total_delivery = fields.Integer(
string="Total No of Deliveries", compute='_compute_total_delivery',
help="Current deliveries in this slot")
remaining_slots = fields.Integer(
string="Available No of Deliveries", compute='_compute_remaining_slots'
, help="Remaining no of deliveries in this slot")
active = fields.Boolean(
string='Active', default=True, help="Active or not")
@api.depends('delivery_ids')
def _compute_total_delivery(self):
""" Update the total deliveries of the delivery slot"""
for rec in self:
rec.total_delivery = len(rec.delivery_ids or [])
@api.depends('total_delivery', 'delivery_limit')
def _compute_remaining_slots(self):
"""Calculate the remaining slots for each delivery slot and deactivate
the slot if it is full"""
self.remaining_slots = self.delivery_limit - self.total_delivery
if self.remaining_slots <= 0:
self.active = False
@api.model
def create(self, vals):
"""Override create method to update delivery_ids"""
delivery_slot = super(DeliverySlot, self).create(vals)
delivery_slot.update_delivery_ids()
return delivery_slot
def write(self, vals):
"""Override write method to update delivery_ids"""
if 'delivery_ids' not in vals:
res = super(DeliverySlot, self).write(vals)
self.update_delivery_ids()
return res
else:
return super(DeliverySlot, self).write(vals)
def update_delivery_ids(self):
"""Update the delivery_ids field based on related sale orders"""
sale_orders = self.env['sale.order'].search(
[('slot_per_product', '=', True)])
delivery_orders = sale_orders.filtered(lambda order: any(
line.slot_id == self.slot_id and line.delivery_date ==
self.delivery_date
for line in order.order_line))
self.delivery_ids = delivery_orders
def _compute_sale_ids(self):
"""Computing the related sale orders of each delivery slot"""
for rec in self:
sale_orders = self.env['sale.order'].search(
[('slot_per_product', '=', True)])
delivery_orders = sale_orders.filtered(lambda order: any(
line.slot_id == rec.slot_id and line.delivery_date ==
rec.delivery_date
for line in order.order_line))
rec.delivery_ids = delivery_orders

31
delivery_slot/models/res_config_settings.py

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Muhsina V (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):
""" Inhering to add a field to enable delivery slot"""
_inherit = 'res.config.settings'
enable_delivery_date = fields.Boolean(
string='Enable Delivery Date Feature', config_parameter=
'delivery_slot.enable_delivery_date', help="Enable delivery slot")

147
delivery_slot/models/sale_order.py

@ -0,0 +1,147 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Muhsina V (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 datetime import timedelta
from odoo import fields, models
from odoo.addons.sale_stock.models.sale_order_line import SaleOrderLine
class SaleOrder(models.Model):
"""Inheriting sale order to add boolean field to enable delivery slot"""
_inherit = 'sale.order'
slot_per_product = fields.Boolean(
string="Delivery Slot per Product",
default=lambda self: self.env['ir.config_parameter'].sudo().get_param(
'delivery_slot.enable_delivery_date'),
help="Enable delivery slot feature")
delivery_slot_id = fields.Many2one('delivery.slot', string='Delivery Slot',
help="Delivery slot")
slot_count = fields.Integer(
string='Slot Count', compute='_compute_delivery_slot_count',
help="Total no of delivery slot related to this sale order")
def action_confirm(self):
"""Confirm the order and update delivery slot information.
If `slot_per_product` is enabled, for each order line, the
corresponding delivery slot is searched in the system.
If found, the total delivery count is incremented. If not found,
a new delivery slot is created with a delivery count of 1.
:return: The result of the super method `action_confirm()`."""
if self.slot_per_product:
for line in self.order_line:
delivery_slot = self.env['delivery.slot'].search(
[('delivery_date', '=', line.delivery_date),
('slot_id', '=', line.slot_id.id),
('active', '=', True)])
if delivery_slot:
delivery_slot.total_delivery += 1
else:
if line.slot_id:
if line.delivery_date:
self.env['delivery.slot'].create({
'delivery_date': line.delivery_date,
'slot_id': line.slot_id.id,
'total_delivery': 1,
})
return super().action_confirm()
def _compute_delivery_slot_count(self):
"""Returns total number of delivery slots per record"""
for record in self:
if record.slot_per_product:
recs = {
slot_record.id
for line in record.order_line
if line.delivery_date
for slot_record in self.env['delivery.slot'].search([
('delivery_date', '=', line.delivery_date),
('slot_id', '=', line.slot_id.id),
('active', '=', True)], limit=1)
}
record.slot_count = len(recs)
else:
record.slot_count = 0
def action_view_delivery_slot(self):
"""Returns all delivery slot related to the sale order"""
rec = [
slot_record.id
for record in self
if record.slot_per_product
for line in record.order_line
for slot_record in self.env['delivery.slot'].search([
('delivery_date', '=', line.delivery_date or self.date_order),
('slot_id', '=', line.slot_id.id),
('active', '=', True)], limit=1)
]
return {
'type': 'ir.actions.act_window',
'name': 'Delivery Slots',
'view_mode': 'tree,form',
'res_model': 'delivery.slot',
'domain': [('id', 'in', rec)],
'context': "{'create': False}"
}
class SaleOrderLine(models.Model):
"""Inheriting sale order line to add slot fields"""
_inherit = 'sale.order.line'
delivery_date = fields.Date(string="Delivery Date", help="Delivery date")
slot_id = fields.Many2one('slot.time', string="Time Slot",
help="Delivery time")
delivery_slot_id = fields.Many2one(
'delivery.slot', string='Delivery Slot', help="Related Delivery Slot")
def _prepare_procurement_values(self, group_id=False):
""" Prepare specific key for moves or other components that will be
created from a stock rule coming from a sale order line. This method
could be overridden in order to add other custom key that could
be used in move/po creation.
"""
date_deadline = self.delivery_date or (
self.order_id.date_order + timedelta(
days=self.customer_lead or 0.0))
date_planned = date_deadline - timedelta(
days=self.order_id.company_id.security_lead)
values = {
'group_id': group_id,
'sale_line_id': self.id,
'date_planned': date_planned,
'date_deadline': date_deadline,
'route_ids': self.route_id,
'warehouse_id': self.order_id.warehouse_id or False,
'product_description_variants': self.with_context(
lang=self.order_id.partner_id.lang).
_get_sale_order_line_multiline_description_variants(),
'company_id': self.order_id.company_id,
'product_packaging_id': self.product_packaging_id,
'sequence': self.sequence,
}
if self.order_id.slot_per_product:
values.update({"slot_per_product": 'True'})
if self.slot_id:
values.update({'slot_time_id': self.slot_id.id})
return values
SaleOrderLine._prepare_procurement_values = _prepare_procurement_values

61
delivery_slot/models/slot_time.py

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Muhsina V (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 SlotTime(models.Model):
"""Slot time model"""
_name = 'slot.time'
_description = 'Delivery time'
name = fields.Char(string='Slot', help="Slot name")
slot_type = fields.Selection([
('home', 'Home Hours'), ('office', 'Office Hours')],
string="Slot type", help="Slot will be shown based on this slot type")
time_from = fields.Selection([
('0', '12:00 AM'), ('1', '1:00 AM'),
('2', '2:00 AM'), ('3', '3:00 AM'),
('4', '4:00 AM'), ('5', '5:00 AM'),
('6', '6:00 AM'), ('7', '7:00 AM'),
('8', '8:00 AM'), ('9', '9:00 AM'),
('10', '10:00 AM'), ('11', '11:00 AM'),
('12', '12:00 PM'), ('13', '1:00 PM'),
('14', '2:00 PM'), ('15', '3:00 PM'),
('16', '4:00 PM'), ('17', '5:00 PM'),
('18', '6:00 PM'), ('19', '7:00 PM'),
('20', '8:00 PM'), ('21', '9:00 PM'),
('22', '10:00 PM'), ('23', '11:00 PM')
], string='Time From', help="From time")
time_to = fields.Selection([
('0', '12:00 AM'), ('1', '1:00 AM'),
('2', '2:00 AM'), ('3', '3:00 AM'),
('4', '4:00 AM'), ('5', '5:00 AM'),
('6', '6:00 AM'), ('7', '7:00 AM'),
('8', '8:00 AM'), ('9', '9:00 AM'),
('10', '10:00 AM'), ('11', '11:00 AM'),
('12', '12:00 PM'), ('13', '1:00 PM'),
('14', '2:00 PM'), ('15', '3:00 PM'),
('16', '4:00 PM'), ('17', '5:00 PM'),
('18', '6:00 PM'), ('19', '7:00 PM'),
('20', '8:00 PM'), ('21', '9:00 PM'),
('22', '10:00 PM'), ('23', '11:00 PM')],
string='Time To', help="To time")

81
delivery_slot/models/stock_move.py

@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Muhsina V (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
from odoo.tools import float_compare
from odoo.tools.misc import groupby
from odoo.addons.stock.models.stock_move import StockMove
class StockMoves(models.Model):
"""Inheriting the stock move model"""
_inherit = 'stock.move'
def _assign_picking(self):
""" Try to assign the moves to an existing picking that has not been
reserved yet and has the same procurement group, locations, and picking
type (moves should already have them identical). Otherwise, create a
new picking to assign them to. """
picking_obj = self.env['stock.picking']
grouped_moves = groupby(self,
key=lambda m: m._key_assign_picking())
for group, moves in grouped_moves:
moves = self.env['stock.move'].concat(*moves)
# Could pass the arguments contained in group, but they are the
# same for each move that's why moves[0] is acceptable
picking = moves[0]._search_picking_for_assignation()
if picking:
# If a picking is found, we'll append `move` to its move list
# and thus its `partner_id` and `ref` field will refer to
# multiple records.
# In this case, we chose to wipe them.
vals = {}
if any(picking.partner_id.id != m.partner_id.id for m in
moves):
vals['partner_id'] = False
if any(picking.origin != m.origin for m in moves):
vals['origin'] = False
if vals:
picking.write(vals)
else:
# Don't create picking for negative moves since they will be
# reversed and assigned to another picking
moves = moves.filtered(lambda m: float_compare(
m.product_uom_qty, 0.0, precision_rounding=
m.product_uom.rounding) >= 0)
if not moves:
continue
pick_values = moves._get_new_picking_values()
sale_order = self.env['sale.order'].search([
('name', '=', pick_values['origin'])])
if sale_order.slot_per_product:
for move in moves:
new_picking = picking_obj.create(
move._get_new_picking_values())
move.write({'picking_id': new_picking.id})
move._assign_picking_post_process(new=new_picking)
else:
new_picking = picking_obj.create(
moves._get_new_picking_values())
moves.write({'picking_id': new_picking.id})
moves._assign_picking_post_process(new=new_picking)
return True
StockMove._assign_picking = _assign_picking

3
delivery_slot/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_slot_time_user,access.slot.time.user,model_slot_time,base.group_user,1,1,1,1
access_delivery_slot_user,access.delivery.slot.user,model_delivery_slot,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_slot_time_user access.slot.time.user model_slot_time base.group_user 1 1 1 1
3 access_delivery_slot_user access.delivery.slot.user model_delivery_slot base.group_user 1 1 1 1

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
delivery_slot/static/description/assets/icons/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
delivery_slot/static/description/assets/modules/dynamic_product_fields.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
delivery_slot/static/description/assets/modules/dynamic_sale_order_fields.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
delivery_slot/static/description/assets/modules/picking_order_line_view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
delivery_slot/static/description/assets/modules/sale_discount_total.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
delivery_slot/static/description/assets/modules/sale_order_line_views.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
delivery_slot/static/description/assets/modules/sale_purchase_previous_product_cost.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
delivery_slot/static/description/assets/screenshots/0.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
delivery_slot/static/description/assets/screenshots/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

BIN
delivery_slot/static/description/assets/screenshots/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
delivery_slot/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
delivery_slot/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

BIN
delivery_slot/static/description/assets/screenshots/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

BIN
delivery_slot/static/description/assets/screenshots/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

BIN
delivery_slot/static/description/banner.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
delivery_slot/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

675
delivery_slot/static/description/index.html

@ -0,0 +1,675 @@
<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
style="color: #875A7B; 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>Enterprise
</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;">
Delivery Slot
</h1>
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">
A Module For Adding Delivery Slot For Each Product
</p>
<!-- END OF APP HERO -->
<img src="assets/screenshots/hero.gif" class="img-responsive"
style="width: 100%; margin-left: auto; margin-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">
In Odoo, currently delivery will be created to the whole
products at once in sales order. Using Delivery Slot,
we can create multiple deliveries based on delivery date and delivery
slot
added in each sale order line.
</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-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> Community &amp; Enterprise Support.
</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Option to Enable/Disable Delivery Slot.</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Set Delivery Date and Delivery Slot For Each Product.</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Multiple deliveries are Created.</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Limited number of Deliveries In Each Slots.</span>
</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;">
Configure Slot Time and Delivery Slot
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Go to Sale => Configuration => Slot Timing to create time
slots.
We can also configure delivery slot , though they will be
automatically created when confirming the sale order.</p>
<img src="assets/screenshots/0.png"
class="img-responsive img-thumbnail border" width="100%"
height="auto">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Enable Delivery Slot
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Enable 'Delivery Slot Feature' in website configuration then we
can add delivery slot for each product from the cart.</p>
<img src="assets/screenshots/1.png"
class="img-responsive img-thumbnail border" width="100%"
height="auto">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Choose Delivery Date And Delivery Slot
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
When the Delivery Slot feature is enabled, we can add a
delivery date and delivery slot for each cart line.It is
mandatory
to provide both delivery date and slot to create separate
delivery slot for each product.
We have the option to choose both office hours and home
hours.</p>
<img src="assets/screenshots/2.png"
class="img-responsive img-thumbnail border" width="100%"
height="auto">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Multiple Deliveries
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
After the payment, a sale order is created with multiple
deliveries,
and we can see the corresponding delivery slots.</p>
<img src="assets/screenshots/3.png"
class="img-responsive img-thumbnail border" width="100%"
height="auto">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
When creating a sale order from the backend, we have the option
to enable the delivery slot per product.
Then, we can choose the delivery date and slot for each product
from the order line.
Both delivery date and slot should be added to the orderline
for which we want to create separate delivery slot.
</p>
<img src="assets/screenshots/4.png"
class="img-responsive img-thumbnail border" width="100%"
height="auto">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Upon confirming the sale order, multiple deliveries are created
based on
the selected delivery date and slot. </p>
<img src="assets/screenshots/5.png"
class="img-responsive img-thumbnail border" width="100%"
height="auto">
</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/odoo_sale_order_line_views/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="./assets/modules/sale_order_line_views.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/odoo_picking_order_line_views/#"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="./assets/modules/picking_order_line_view.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/sale_discount_total/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="./assets/modules/sale_discount_total.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/dynamic_sale_order_fields/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="./assets/modules/dynamic_sale_order_fields.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/sale_purchase_previous_product_cost/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="./assets/modules/sale_purchase_previous_product_cost.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/dynamic_product_fields/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="./assets/modules/dynamic_product_fields.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 -->

37
delivery_slot/static/src/js/delivery_slot.js

@ -0,0 +1,37 @@
odoo.define('delivery_slot.cart_line', function(require) {
'use strict';
/**
* Module for handling delivery slot selection in the shopping cart.
*/
var publicWidget = require('web.public.widget');
const ajax = require('web.ajax');
publicWidget.registry.websiteDeliverySlot = publicWidget.Widget.extend({
selector: '.delivery_slot_div',
events: {
'change #slot_id': '_onDateChange',
'change #date': '_onDateChange',
},
/**
* Handles the change event of the date or slot selection.
* @param {Event} ev - The change event.
*/
_onDateChange: function(ev) {
if (ev.currentTarget.id == 'date') {
var delivery_date = ev.currentTarget.value
var line_id = $(ev.currentTarget).attr('data-line-id')
ajax.jsonRpc('/shop/cart/set_delivery_date', "call", {
'delivery_date': delivery_date,
'line_id': line_id
});
}
else if (ev.currentTarget.id == 'slot_id') {
var delivery_slot = ev.currentTarget.value
var line_id = $(ev.currentTarget).attr('data-line-id')
ajax.jsonRpc('/shop/cart/set_delivery_slot', "call", {
'delivery_slot': delivery_slot,
'line_id': line_id
});
}
},
});
});

34
delivery_slot/static/src/js/slot_time.js

@ -0,0 +1,34 @@
odoo.define('delivery_slot.cart', function(require) {
'use strict';
var publicWidget = require('web.public.widget');
const ajax = require('web.ajax');
/**
* Widget that handles the slot time selection on the cart line.
*/
publicWidget.registry.websiteSlotTimeHours = publicWidget.Widget.extend({
selector: '.slot-time-div',
events: {
'change input[type="radio"][name="slot_hour"]': '_onSlotTime',
},
_onSlotTime: function(ev) {
var selected_option = $("input[type='radio'][name='slot_hour']:checked").val()
ajax.jsonRpc('/shop/cart/get_option', "call", {
'selected_option': selected_option,
})
.then(function(result) {
const selects = document.querySelectorAll('select');
const input = document.querySelector('input');
selects.forEach((select) => {
const options = Array.from(select.options);
options.forEach((option) => {
option.remove();
});
result.forEach((item) => {
let newOption = new Option(item[1], item[0]);
select.add(newOption, undefined);
});
});
});
},
});
});

24
delivery_slot/static/src/js/website_sale_utils.js

@ -0,0 +1,24 @@
odoo.define('delivery_slot.website_sale_utils', function (require) {
"use strict";
const utils = require('website_sale.utils');
/**
* Custom implementation of the updateCartNavBar function.
*
* @param {Object} data - The data to update the cart navbar.
*/
utils.updateCartNavBar = function (data) {
$(".my_cart_quantity")
.parents('li.o_wsale_my_cart').removeClass('d-none').end()
.addClass('o_mycart_zoom_animation').delay(300)
.queue(function () {
$(this)
.toggleClass('fa fa-warning', !data.cart_quantity)
.attr('title', data.warning)
.text(data.cart_quantity || '')
.removeClass('o_mycart_zoom_animation')
.dequeue();
});
$(".js_cart_summary").replaceWith(data['website_sale.short_cart_summary']);
};
return utils;
});

52
delivery_slot/views/delivery_slot_views.xml

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- View for the delivery slot tree -->
<record id="delivery_slot_view_tree" model="ir.ui.view">
<field name="name">delivery.slot.view.tree</field>
<field name="model">delivery.slot</field>
<field name="arch" type="xml">
<tree>
<field name="delivery_date"/>
<field name="slot_id"/>
</tree>
</field>
</record>
<!-- View for the delivery slot form -->
<record id="delivery_slot_view_form" model="ir.ui.view">
<field name="name">delivery.slot.view.form</field>
<field name="model">delivery.slot</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="delivery_date"/>
<field name="slot_id"/>
<field name="active"/>
<field name="delivery_limit"/>
<field name="total_delivery"/>
<field name="remaining_slots"/>
<field name="delivery_ids">
<tree create="false">
<field name="name"
string="Order Reference"/>
<field name="company_id" invisible="1"/>
<field name="partner_id"
string="Customer"/>
</tree>
</field>
</group>
</sheet>
</form>
</field>
</record>
<!-- Action for the delivery slot -->
<record id="delivery_slot_action" model="ir.actions.act_window">
<field name="name">Delivery Slot</field>
<field name="res_model">delivery.slot</field>
<field name="view_mode">tree,form</field>
</record>
<!-- Menu item for the delivery slot -->
<menuitem id="delivery_slot_menu" name="Delivery Slot"
action="delivery_slot_action"
parent="sale.menu_sale_config" sequence="14"/>
</odoo>

28
delivery_slot/views/res_config_settings_views.xml

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- inheriting the res.config.setting form view -->
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">
res.config.settings.view.form.inherit.delivery.slot
</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="90"/>
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@id='website_info_settings']" position="inside">
<!-- Adding a new setting for the delivery slot feature -->
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<span class="o_form_label">Enable Delivery Slot
Feature
</span>
<div class="text-muted content-group mt16">
<field name="enable_delivery_date"/>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

34
delivery_slot/views/sale_order_views.xml

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- inheriting the sale order form view -->
<record id="view_order_form" model="ir.ui.view">
<field name="name">sale.order.view.form.inherit.delivery.slot</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="model">sale.order</field>
<field name="arch" type="xml">
<!-- Adding a new field for Delivery Slot Per Product -->
<field name="sale_order_template_id" position="after">
<field name="slot_per_product"
string="Delivery Slot Per Product"/>
</field>
<div name="button_box" position="inside">
<!-- Adding a button to view Delivery Slots -->
<button class="oe_stat_button" type="object"
name="action_view_delivery_slot"
icon="fa-clock-o"
attrs="{'invisible':[('slot_count','=',0)]}">
<field string="Delivery Slots" name="slot_count"
widget="statinfo"/>
</button>
</div>
<xpath expr="//field[@name='order_line']/tree/field[@name='price_unit']"
position="before">
<!-- Adding fields for Delivery Date and Delivery Slot -->
<field name="delivery_date"
attrs="{'column_invisible':[('parent.slot_per_product', '=', False)]}"/>
<field name="slot_id"
attrs="{'column_invisible':[('parent.slot_per_product', '=', False)]}"/>
</xpath>
</field>
</record>
</odoo>

43
delivery_slot/views/slot_time_views.xml

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- View for the slot time tree -->
<record id="slot_time_view_tree" model="ir.ui.view">
<field name="name">slot.time.view.tree</field>
<field name="model">slot.time</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="slot_type"/>
<field name="time_from"/>
<field name="time_to"/>
</tree>
</field>
</record>
<!-- View for the slot time form -->
<record id="slot_time_view_form" model="ir.ui.view">
<field name="name">slot.time.view.form</field>
<field name="model">slot.time</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="name"/>
<field name="slot_type"/>
<field name="time_from"/>
<field name="time_to"/>
</group>
</sheet>
</form>
</field>
</record>
<!-- Action for the slot time -->
<record id="slot_time_action" model="ir.actions.act_window">
<field name="name">Slots</field>
<field name="res_model">slot.time</field>
<field name="view_mode">tree,form</field>
</record>
<!-- Menu item for the slot time -->
<menuitem id="slot_sub_menu" name="Slot Timing"
action="slot_time_action"
parent="sale.menu_sale_config" sequence="13"/>
</odoo>

61
delivery_slot/views/website_delivery_slot_templates.xml

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="website_delivery_slot" inherit_id="website_sale.cart_lines">
<xpath expr="//td[hasclass('td-product_name')]" position="inside">
<!-- Checking if delivery slot is enabled -->
<t t-set="delivery_slot"
t-value="request.env['ir.config_parameter'].sudo().get_param('delivery_slot.enable_delivery_date')"/>
<t t-if="delivery_slot">
<div class="delivery_slot_div">
<div class="form-group col-12 s_website_form_field s_website_form_required"
data-type="char" data-name="Field" id="date_div">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label"
style="width: 200px"
for="date">
<span class="s_website_form_label_content">
Delivery Date
</span>
</label>
<div class="col-sm">
<input id="date"
type="date"
class="form-control link-style"
placeholder="Delivery Date"
name="date" required="1"
t-att-data-line-id="line.id"
t-att-data-product-id="line.product_id.id"/>
</div>
</div>
</div>
<div class="form-group col-12 s_website_form_field s_website_form_required"
data-type="char" data-name="Field" id="divs">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label"
style="width: 200px"
for="search">
<span class="s_website_form_label_content">
Delivery Slot
</span>
</label>
<div class="col-sm">
<select name="slot_id" id="slot_id"
class="form-control link-style"
t-att-data-line-id="line.id"
t-att-data-product-id="line.product_id.id">
<option value=""> </option>
<t t-foreach="slots" t-as="slot">
<option t-att-value="slot.id">
<t t-esc="slot.name"
t-att-value="slot.id"/>
</option>
</t>
</select>
</div>
</div>
</div>
</div>
</t>
</xpath>
</template>
</odoo>

32
delivery_slot/views/website_slot_time_templates.xml

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="website_slot_time" inherit_id="website_sale.cart">
<!-- Inserting delivery slot selection before the cart lines table -->
<xpath expr="//t[@t-call='website_sale.cart_lines']" position="before">
<!-- Checking if delivery slot is enabled -->
<t t-set="delivery_slot"
t-value="request.env['ir.config_parameter'].sudo().get_param('delivery_slot.enable_delivery_date')"/>
<t t-if="delivery_slot">
<div class="slot-time-div">
<div class="form-group col-12">
<span class="s_website_form_label_content">
<b>Choose A Delivery Time</b>
<br/>
</span>
<div class="col-sm" id="hour_value">
<input type="radio" id="home" name="slot_hour"
value="home"/>
<label for="html">Home Hours</label>
</div>
<div class="col-sm">
<input type="radio" id="office" name="slot_hour"
value="office"/>
<label for="css">Office Hours</label>
</div>
<br/>
</div>
</div>
</t>
</xpath>
</template>
</odoo>
Loading…
Cancel
Save