@ -0,0 +1,40 @@ |
|||||
|
Beauty Spa Management v14 |
||||
|
========================= |
||||
|
This Spa management system developed by Cybrosys Techno Solutions helps |
||||
|
your customers to do the online booking for using the service. This module |
||||
|
integrates with other Odoo modules like accounting and website. |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
* No additional configurations needed |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
* Developer: AVINASH N K @ cybrosys, Contact: odoo@cybrosys.com |
||||
|
Version 13: Vaishnavi B@cybrosys,Contact: odoo@cybrosys.com |
||||
|
Version 14: JIBIN JAMES, Contact: odoo@cybrosys.com |
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
----------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2019-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Avinash N K (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# 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 for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################### |
||||
|
|
||||
|
from . import models |
||||
|
from . import controllers |
@ -0,0 +1,52 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2020-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# 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 for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################### |
||||
|
{ |
||||
|
'name': 'Beauty Spa Management', |
||||
|
'summary': """Beauty Parlour Management with Online Booking System""", |
||||
|
'version': '14.0.1.0.0', |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'website': "https://www.cybrosys.com", |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
"category": "Industries", |
||||
|
'depends': ['base','base_setup', 'account', 'mail', 'website'], |
||||
|
'data': [ |
||||
|
'security/salon_security.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
'data/data_chair.xml', |
||||
|
'data/data_booking.xml', |
||||
|
'views/salon_holiday.xml', |
||||
|
'views/js_view.xml', |
||||
|
'views/salon_data.xml', |
||||
|
'views/salon_management_chair.xml', |
||||
|
'views/salon_management_services.xml', |
||||
|
'views/salon_order_view.xml', |
||||
|
'views/salon_management_dashboard.xml', |
||||
|
'views/booking_backend.xml', |
||||
|
'views/salon_email_template.xml', |
||||
|
'views/salon_config.xml', |
||||
|
'views/working_hours.xml', |
||||
|
'templates/salon_booking_templates.xml', |
||||
|
], |
||||
|
'images': ['static/description/banner.png'], |
||||
|
'license': 'AGPL-3', |
||||
|
'installable': True, |
||||
|
'application': True, |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
||||
|
# |
||||
|
# Author: AVINASH NK(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# 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 for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################### |
||||
|
|
||||
|
from . import main |
@ -0,0 +1,101 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
||||
|
# |
||||
|
# Author: AVINASH NK(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# 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 for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################### |
||||
|
|
||||
|
import json |
||||
|
from datetime import datetime, date |
||||
|
from odoo import http |
||||
|
from odoo.http import request |
||||
|
|
||||
|
|
||||
|
class SalonBookingWeb(http.Controller): |
||||
|
|
||||
|
@http.route('/page/salon_details', csrf=False, type="http", methods=['POST', 'GET'], auth="public", website=True) |
||||
|
def salon_details(self, **kwargs): |
||||
|
|
||||
|
name = kwargs['name'] |
||||
|
dates = kwargs['date'] |
||||
|
time = kwargs['time'] |
||||
|
phone = kwargs['phone'] |
||||
|
email = kwargs['email'] |
||||
|
chair = kwargs['chair'] |
||||
|
j = 0 |
||||
|
service_list = [] |
||||
|
while j < (int(kwargs['number'])): |
||||
|
item = "list_service["+str(j)+"][i]" |
||||
|
service_list.append(int(kwargs[item])) |
||||
|
j += 1 |
||||
|
salon_service_obj = request.env['salon.service'].search([('id', 'in', service_list)]) |
||||
|
dates_time = dates+" "+time+":00" |
||||
|
date_and_time = datetime.strptime(dates_time, '%m/%d/%Y %H:%M:%S') |
||||
|
|
||||
|
salon_booking = request.env['salon.booking'] |
||||
|
booking_data = { |
||||
|
'name': name, |
||||
|
'phone': phone, |
||||
|
'time': date_and_time, |
||||
|
'email': email, |
||||
|
'chair_id': chair, |
||||
|
'services': [(6, 0, [x.id for x in salon_service_obj])], |
||||
|
} |
||||
|
salon_booking.create(booking_data) |
||||
|
return json.dumps({'result': True}) |
||||
|
|
||||
|
@http.route('/page/salon_check_date', type='json', auth="public", website=True) |
||||
|
def salon_check(self, **kwargs): |
||||
|
date_check = str(kwargs.get('check_date')) |
||||
|
order_obj = request.env['salon.order'].search([('chair_id.active_booking_chairs', '=', True), |
||||
|
('stage_id', 'in', [1, 2, 3]), |
||||
|
('start_date_only', '=', datetime.strptime(date_check, '%m/%d/%Y').strftime('%Y-%m-%d'))]) |
||||
|
order_details = {} |
||||
|
for orders in order_obj: |
||||
|
data = { |
||||
|
'number': orders.id, |
||||
|
'start_time_only': orders.start_time_only, |
||||
|
'end_time_only': orders.end_time_only |
||||
|
} |
||||
|
if orders.chair_id.id not in order_details: |
||||
|
order_details[orders.chair_id.id] = {'name': orders.chair_id.name, 'orders': [data]} |
||||
|
else: |
||||
|
order_details[orders.chair_id.id]['orders'].append(data) |
||||
|
return order_details |
||||
|
|
||||
|
@http.route('/page/salon_management.salon_booking_thank_you', type='http', auth="public", website=True) |
||||
|
def thank_you(self, **post): |
||||
|
return request.render('salon_management.salon_booking_thank_you', {}) |
||||
|
|
||||
|
@http.route('/page/salon_management/salon_booking_form', type='http', auth="public", website=True) |
||||
|
def chair_info(self, **post): |
||||
|
salon_service_obj = request.env['salon.service'].search([]) |
||||
|
salon_working_hours_obj = request.env['salon.working.hours'].search([]) |
||||
|
salon_holiday_obj = request.env['salon.holiday'].search([('holiday', '=', True)]) |
||||
|
date_check = date.today() |
||||
|
chair_obj = request.env['salon.chair'].search([('active_booking_chairs', '=', True)]) |
||||
|
order_obj = request.env['salon.order'].search([('chair_id.active_booking_chairs', '=', True), |
||||
|
('stage_id', 'in', [1, 2, 3])]) |
||||
|
order_obj = order_obj.search([('start_date_only', '=', date_check)]) |
||||
|
return request.render('salon_management.salon_booking_form', |
||||
|
{'chair_details': chair_obj, 'order_details': order_obj, |
||||
|
'salon_services': salon_service_obj, 'date_search': date_check, |
||||
|
'holiday': salon_holiday_obj, |
||||
|
'working_time': salon_working_hours_obj |
||||
|
}) |
@ -0,0 +1,10 @@ |
|||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="website_menu_salon_booking" model="website.menu"> |
||||
|
<field name="name">Bookings</field> |
||||
|
<field name="url">/page/salon_management/salon_booking_form</field> |
||||
|
<field name="parent_id" ref="website.main_menu"/> |
||||
|
<field name="sequence" type="int">80</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,18 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<data noupdate="0"> |
||||
|
<record forcecreate="True" id="ir_cron_collections_today" model="ir.cron"> |
||||
|
<field name="name">Collection Today</field> |
||||
|
<field eval="True" name="active" /> |
||||
|
<field name="model_id" ref="salon_management.model_salon_chair"/> |
||||
|
<field name="code">model.collection_today_updater()</field> |
||||
|
<field name="user_id" ref="base.user_root" /> |
||||
|
<field name="interval_number">1</field> |
||||
|
<field name="interval_type">days</field> |
||||
|
<field name="numbercall">-1</field> |
||||
|
<field eval="True" name="doall" /> |
||||
|
<!-- <field eval="'salon.chair'" name="model" />--> |
||||
|
<!-- <field eval="'collection_today_updater'" name="function" />--> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,6 @@ |
|||||
|
## Module <salon_management> |
||||
|
|
||||
|
#### 20.10.2020 |
||||
|
#### Version 14.0.1.0.0 |
||||
|
##### ADD |
||||
|
- Initial Commit salon_management |
@ -0,0 +1,25 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2019-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Avinash N k (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 salon_management |
||||
|
from . import salon_booking |
||||
|
from . import salon_config |
||||
|
|
@ -0,0 +1,83 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
||||
|
# |
||||
|
# Author: AVINASH NK(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# 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 for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################### |
||||
|
|
||||
|
from datetime import date |
||||
|
from odoo import models, fields, api |
||||
|
|
||||
|
|
||||
|
class SalonBookingBackend(models.Model): |
||||
|
_name = 'salon.booking' |
||||
|
|
||||
|
name = fields.Char(string="Name") |
||||
|
state = fields.Selection([('draft', 'Draft'), ('approved', 'Approved'), ('rejected', 'Rejected')], default="draft") |
||||
|
time = fields.Datetime(string="Date") |
||||
|
phone = fields.Char(string="Phone") |
||||
|
email = fields.Char(string="E-Mail") |
||||
|
services = fields.Many2many('salon.service', string="Services") |
||||
|
chair_id = fields.Many2one('salon.chair', string="Chair") |
||||
|
company_id = fields.Many2one('res.company', 'Company', |
||||
|
default=lambda self: self.env['res.company'].browse(1)) |
||||
|
lang = fields.Many2one('res.lang', 'Language', |
||||
|
default=lambda self: self.env['res.lang'].browse(1)) |
||||
|
|
||||
|
def all_salon_orders(self): |
||||
|
if self.time: |
||||
|
date_only = str(self.time)[0:10] |
||||
|
else: |
||||
|
date_only = date.today() |
||||
|
all_salon_service_obj = self.env['salon.order'].search([('chair_id', '=', self.chair_id.id), |
||||
|
('start_date_only', '=', date_only)]) |
||||
|
self.filtered_orders = [(6, 0, [x.id for x in all_salon_service_obj])] |
||||
|
|
||||
|
filtered_orders = fields.Many2many('salon.order', string="Salon Orders", compute="all_salon_orders") |
||||
|
|
||||
|
def booking_approve(self): |
||||
|
salon_order_obj = self.env['salon.order'] |
||||
|
salon_service_obj = self.env['salon.order.lines'] |
||||
|
order_data = { |
||||
|
'customer_name': self.name, |
||||
|
'chair_id': self.chair_id.id, |
||||
|
'start_time': self.time, |
||||
|
'date': date.today(), |
||||
|
'stage_id': 1, |
||||
|
'booking_identifier': True, |
||||
|
} |
||||
|
order = salon_order_obj.create(order_data) |
||||
|
for records in self.services: |
||||
|
service_data = { |
||||
|
'service_id': records.id, |
||||
|
'time_taken': records.time_taken, |
||||
|
'price': records.price, |
||||
|
'price_subtotal': records.price, |
||||
|
'salon_order': order.id, |
||||
|
} |
||||
|
salon_service_obj.create(service_data) |
||||
|
template = self.env.ref('salon_management.salon_email_template_approved') |
||||
|
self.env['mail.template'].browse(template.id).send_mail(self.id) |
||||
|
self.state = "approved" |
||||
|
|
||||
|
def booking_reject(self): |
||||
|
template = self.env.ref('salon_management.salon_email_template_rejected') |
||||
|
self.env['mail.template'].browse(template.id).send_mail(self.id) |
||||
|
self.state = "rejected" |
||||
|
|
@ -0,0 +1,75 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
||||
|
# |
||||
|
# Author: AVINASH NK(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# 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 for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################### |
||||
|
|
||||
|
from odoo import models, fields, api |
||||
|
|
||||
|
|
||||
|
class SalonWorkingHours(models.Model): |
||||
|
_name = 'salon.working.hours' |
||||
|
|
||||
|
name = fields.Char(string="Name") |
||||
|
from_time = fields.Float(string="Starting Time") |
||||
|
to_time = fields.Float(string="Closing Time") |
||||
|
|
||||
|
|
||||
|
class SalonHoliday(models.Model): |
||||
|
_name = 'salon.holiday' |
||||
|
|
||||
|
name = fields.Char(string="Name") |
||||
|
holiday = fields.Boolean(string="Holiday") |
||||
|
|
||||
|
|
||||
|
class ConfigurationSettings(models.TransientModel): |
||||
|
_inherit = 'res.config.settings' |
||||
|
|
||||
|
@api.model |
||||
|
def booking_chairs(self): |
||||
|
return self.env['salon.chair'].search([('active_booking_chairs', '=', True)]) |
||||
|
|
||||
|
@api.model |
||||
|
def holidays(self): |
||||
|
return self.env['salon.holiday'].search([('holiday', '=', True)]) |
||||
|
|
||||
|
salon_booking_chairs = fields.Many2many('salon.chair', string="Booking Chairs", default=booking_chairs) |
||||
|
salon_holidays = fields.Many2many('salon.holiday', string="Holidays", default=holidays) |
||||
|
|
||||
|
def execute(self): |
||||
|
salon_chair_obj = self.env['salon.chair'].search([]) |
||||
|
book_chair = [] |
||||
|
for chairs in self.salon_booking_chairs: |
||||
|
book_chair.append(chairs.id) |
||||
|
for records in salon_chair_obj: |
||||
|
if records.id in book_chair: |
||||
|
records.active_booking_chairs = True |
||||
|
else: |
||||
|
records.active_booking_chairs = False |
||||
|
|
||||
|
salon_holiday_obj = self.env['salon.holiday'].search([]) |
||||
|
holiday = [] |
||||
|
for days in self.salon_holidays: |
||||
|
holiday.append(days.id) |
||||
|
for records in salon_holiday_obj: |
||||
|
if records.id in holiday: |
||||
|
records.holiday = True |
||||
|
else: |
||||
|
records.holiday = False |
@ -0,0 +1,411 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2019-TODAY Cybrosys Technologies (<https://www.cybrosys.com>). |
||||
|
# |
||||
|
# Author: AVINASH NK(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is free software: you can modify |
||||
|
# it under the terms of the GNU Affero General Public License (AGPL) as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# 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 for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################### |
||||
|
|
||||
|
from datetime import date, datetime, timedelta |
||||
|
from odoo import models, fields, api |
||||
|
from odoo.tools.translate import _ |
||||
|
from odoo.exceptions import UserError, ValidationError |
||||
|
|
||||
|
|
||||
|
class PartnerSalon(models.Model): |
||||
|
_inherit = 'res.partner' |
||||
|
|
||||
|
partner_salon = fields.Boolean(string="Is a Salon Partner") |
||||
|
|
||||
|
|
||||
|
class SequenceUpdaterSalon(models.Model): |
||||
|
_name = 'salon.sequence.updater' |
||||
|
|
||||
|
sequence_salon = fields.Char(string="Salon Sequence") |
||||
|
|
||||
|
|
||||
|
class UserSalon(models.Model): |
||||
|
_inherit = 'res.users' |
||||
|
|
||||
|
user_salon_active = fields.Boolean(string="Active Salon Users") |
||||
|
|
||||
|
|
||||
|
class SalonChair(models.Model): |
||||
|
_name = 'salon.chair' |
||||
|
|
||||
|
name = fields.Char(string="Chair", required=True, |
||||
|
default=lambda self: self.env['salon.sequence.updater'].browse(1).sequence_salon or "Chair-1") |
||||
|
number_of_orders = fields.Integer(string="No.of Orders") |
||||
|
collection_today = fields.Float(string="Today's Collection") |
||||
|
user_of_chair = fields.Many2one('res.users', string="User", readonly=True, |
||||
|
help="You can select the user from the Users Tab." |
||||
|
"Last user from the Users Tab will be selected as the Current User.") |
||||
|
date = fields.Datetime(string="Date", readonly=True) |
||||
|
user_line = fields.One2many('salon.chair.user', 'salon_chair', string="Users") |
||||
|
total_time_taken_chair = fields.Float(string="Time Reserved(Hrs)") |
||||
|
active_booking_chairs = fields.Boolean(string="Active booking chairs") |
||||
|
chair_created_user = fields.Integer(string="Salon Chair Created User", |
||||
|
default=lambda self: self._uid) |
||||
|
|
||||
|
@api.model |
||||
|
def create(self, values): |
||||
|
sequence_code = 'chair.sequence' |
||||
|
sequence_number = self.env['ir.sequence'].next_by_code(sequence_code) |
||||
|
self.env['salon.sequence.updater'].browse(1).write({'sequence_salon': sequence_number}) |
||||
|
if 'user_line' in values.keys(): |
||||
|
if values['user_line']: |
||||
|
date_changer = [] |
||||
|
for elements in values['user_line']: |
||||
|
date_changer.append(elements[2]['start_date']) |
||||
|
number = 0 |
||||
|
for elements in values['user_line']: |
||||
|
number += 1 |
||||
|
if len(values['user_line']) == number: |
||||
|
break |
||||
|
elements[2]['end_date'] = date_changer[number] |
||||
|
values['user_of_chair'] = values['user_line'][len((values['user_line'])) - 1][2]['user_id'] |
||||
|
values['date'] = values['user_line'][len((values['user_line'])) - 1][2]['start_date'] |
||||
|
return super(SalonChair, self).create(values) |
||||
|
|
||||
|
def write(self, values): |
||||
|
if 'user_line' in values.keys(): |
||||
|
if values['user_line']: |
||||
|
date_changer = [] |
||||
|
for elements in values['user_line']: |
||||
|
if str(elements[1]).startswith('v'): |
||||
|
date_changer.append(elements[2]['start_date']) |
||||
|
number = 0 |
||||
|
num = 0 |
||||
|
for records in self.user_line: |
||||
|
if records.end_date is False: |
||||
|
if date_changer: |
||||
|
records.end_date = date_changer[0] |
||||
|
for elements in values['user_line']: |
||||
|
number += 1 |
||||
|
if elements[2] is not False: |
||||
|
num += 1 |
||||
|
if len(values['user_line']) == number: |
||||
|
break |
||||
|
elements[2]['end_date'] = date_changer[num] |
||||
|
values['user_of_chair'] = values['user_line'][len((values['user_line'])) - 1][2]['user_id'] |
||||
|
values['date'] = values['user_line'][len((values['user_line'])) - 1][2]['start_date'] |
||||
|
return super(SalonChair, self).write(values) |
||||
|
|
||||
|
def collection_today_updater(self): |
||||
|
salon_chair = self.env['salon.chair'] |
||||
|
for values in self.search([]): |
||||
|
chair_obj = salon_chair.browse(values.ids) |
||||
|
invoiced_records = chair_obj.env['salon.order'].search([('stage_id', 'in', [3, 4]), |
||||
|
('chair_id', '=', chair_obj.id)]) |
||||
|
total = 0 |
||||
|
for rows in invoiced_records: |
||||
|
invoiced_date = str(rows.date) |
||||
|
invoiced_date = invoiced_date[0:10] |
||||
|
if invoiced_date == str(date.today()): |
||||
|
total = total + rows.price_subtotal |
||||
|
chair_obj.collection_today = total |
||||
|
|
||||
|
|
||||
|
class SalonChairUserLines(models.Model): |
||||
|
_name = 'salon.chair.user' |
||||
|
|
||||
|
read_only_checker = fields.Boolean(string="Checker", default=False) |
||||
|
user_id = fields.Many2one('res.users', string="User", required=True) |
||||
|
start_date = fields.Datetime(string="Start Date", default=datetime.today(), required=True) |
||||
|
end_date = fields.Datetime(string="End Date", readonly=True, default=False) |
||||
|
salon_chair = fields.Many2one('salon.chair', string="Chair", required=True, ondelete='cascade', |
||||
|
index=True, copy=False) |
||||
|
|
||||
|
@api.model |
||||
|
def create(self, val): |
||||
|
chairs = self.env['salon.chair'].search([]) |
||||
|
all_active_users = [] |
||||
|
for records in chairs: |
||||
|
if records.user_of_chair: |
||||
|
all_active_users.append(records.user_of_chair.id) |
||||
|
records.user_of_chair.write({'user_salon_active': True}) |
||||
|
users = self.env['res.users'].search([('id', 'not in', all_active_users)]) |
||||
|
for records in users: |
||||
|
records.write({'user_salon_active': False}) |
||||
|
val['read_only_checker'] = True |
||||
|
return super(SalonChairUserLines, self).create(val) |
||||
|
|
||||
|
|
||||
|
class SalonOrder(models.Model): |
||||
|
_name = 'salon.order' |
||||
|
|
||||
|
@api.depends('order_line.price_subtotal') |
||||
|
def sub_total_update(self): |
||||
|
for order in self: |
||||
|
amount_untaxed = 0.0 |
||||
|
total_time_taken = 0.0 |
||||
|
for line in order.order_line: |
||||
|
amount_untaxed += line.price_subtotal |
||||
|
total_time_taken += line.time_taken |
||||
|
self.price_subtotal = amount_untaxed |
||||
|
time_takes = total_time_taken |
||||
|
hours = int(time_takes) |
||||
|
minutes = (time_takes - hours) * 60 |
||||
|
start_time_store = datetime.strptime(str(self.start_time).split(".")[0], "%Y-%m-%d %H:%M:%S") |
||||
|
self.write({'end_time': start_time_store + timedelta(hours=hours, minutes=minutes), |
||||
|
'time_taken_total': total_time_taken}) |
||||
|
if self.end_time: |
||||
|
self.write({'end_time_only': str(self.end_time)[11:16]}) |
||||
|
if self.start_time: |
||||
|
salon_start_time = str(self.start_time) |
||||
|
salon_start_time_date = salon_start_time[0:10] |
||||
|
self.write({'start_date_only': salon_start_time_date}) |
||||
|
self.write({'start_time_only': str(self.start_time)[11:16]}) |
||||
|
|
||||
|
name = fields.Char(string='Salon', required=True, copy=False, readonly=True, |
||||
|
default='Draft Salon Order') |
||||
|
start_time = fields.Datetime(string="Start time", default=datetime.now(), required=True) |
||||
|
end_time = fields.Datetime(string="End time") |
||||
|
date = fields.Datetime(string="Date", required=True, default=datetime.now()) |
||||
|
color = fields.Integer(string="Colour", default=6) |
||||
|
partner_id = fields.Many2one('res.partner', string="Customer", required=False, |
||||
|
help="If the customer is a regular customer, " |
||||
|
"then you can add the customer in your database") |
||||
|
customer_name = fields.Char(string="Name", required=True) |
||||
|
amount = fields.Float(string="Amount") |
||||
|
chair_id = fields.Many2one('salon.chair', string="Chair", required=True) |
||||
|
price_subtotal = fields.Float(string='Total', compute='sub_total_update', readonly=True, store=True) |
||||
|
time_taken_total = fields.Float(string="Total time taken") |
||||
|
note = fields.Text('Terms and conditions') |
||||
|
order_line = fields.One2many('salon.order.lines', 'salon_order', string="Order Lines") |
||||
|
stage_id = fields.Many2one('salon.stages', string="Stages", default=1, group_expand='_read_group_stage_ids') |
||||
|
inv_stage_identifier = fields.Boolean(string="Stage Identifier") |
||||
|
invoice_number = fields.Integer(string="Invoice Number") |
||||
|
validation_controller = fields.Boolean(string="Validation controller", default=False) |
||||
|
start_date_only = fields.Date(string="Date Only") |
||||
|
booking_identifier = fields.Boolean(string="Booking Identifier") |
||||
|
start_time_only = fields.Char(string="Start Time Only") |
||||
|
end_time_only = fields.Char(string="End Time Only") |
||||
|
chair_user = fields.Many2one('res.users', string="Chair User") |
||||
|
salon_order_created_user = fields.Integer(string="Salon Order Created User", |
||||
|
default=lambda self: self._uid) |
||||
|
|
||||
|
@api.onchange('start_time') |
||||
|
def start_date_change(self): |
||||
|
salon_start_time = str(self.start_time) |
||||
|
salon_start_time_date = salon_start_time[0:10] |
||||
|
self.write({'start_date_only': salon_start_time_date}) |
||||
|
|
||||
|
count = fields.Integer(string='Delivery Orders', |
||||
|
compute='_compute_invoice_saloon_ids') |
||||
|
|
||||
|
def _compute_invoice_saloon_ids(self): |
||||
|
"""getting saloon invoice count""" |
||||
|
for orders in self: |
||||
|
orders.count = self.env['account.move']. \ |
||||
|
search_count([('invoice_origin', '=', self.name)]) |
||||
|
|
||||
|
|
||||
|
# if orders.count != 0: |
||||
|
# orders.inv_stage_identifier = True |
||||
|
# orders.stage_id = 3 |
||||
|
|
||||
|
def action_view_invoice_salon(self): |
||||
|
|
||||
|
return { |
||||
|
'name': 'Invoices', |
||||
|
'domain': [('invoice_origin', '=', self.name)], |
||||
|
'res_model': 'account.move', |
||||
|
'view_id': False, |
||||
|
'view_mode': 'tree,form', |
||||
|
'type': 'ir.actions.act_window', |
||||
|
} |
||||
|
|
||||
|
@api.model |
||||
|
def _read_group_stage_ids(self, stages, domain, order): |
||||
|
stage_ids = self.env['salon.stages'].search([]) |
||||
|
return stage_ids |
||||
|
|
||||
|
def write(self, values): |
||||
|
if 'stage_id' in values.keys(): |
||||
|
if self.stage_id.id == 3 and values['stage_id'] != 4: |
||||
|
raise ValidationError(_("You can't perform that move !")) |
||||
|
if self.stage_id.id == 1 and values['stage_id'] not in [2, 5]: |
||||
|
raise ValidationError(_("You can't perform that move!")) |
||||
|
if self.stage_id.id == 4: |
||||
|
raise ValidationError(_("You can't move a salon order from closed stage !")) |
||||
|
if self.stage_id.id == 5: |
||||
|
raise ValidationError(_("You can't move a salon order from cancel stage !")) |
||||
|
if self.stage_id.id == 2 and (values['stage_id'] == 1 or values['stage_id'] == 4): |
||||
|
raise ValidationError(_("You can't perform that move !")) |
||||
|
if self.stage_id.id == 2 and values['stage_id'] == 3 and self.inv_stage_identifier is False: |
||||
|
self.salon_invoice_create() |
||||
|
|
||||
|
if 'stage_id' in values.keys() and self.name == "Draft Salon Order": |
||||
|
if values['stage_id'] == 2: |
||||
|
self.salon_confirm() |
||||
|
return super(SalonOrder, self).write(values) |
||||
|
|
||||
|
def salon_confirm(self): |
||||
|
sequence_code = 'salon.order.sequence' |
||||
|
order_date = str(self.date) |
||||
|
order_date = order_date[0:10] |
||||
|
self.name = self.env['ir.sequence'].with_context(ir_sequence_date=order_date).next_by_code(sequence_code) |
||||
|
if self.partner_id: |
||||
|
self.partner_id.partner_salon = True |
||||
|
self.stage_id = 2 |
||||
|
self.chair_id.number_of_orders = len(self.env['salon.order'].search([("chair_id", "=", self.chair_id.id), |
||||
|
("stage_id", "in", [2, 3])])) |
||||
|
self.chair_id.total_time_taken_chair = (self.chair_id.total_time_taken_chair + self.time_taken_total) |
||||
|
self.chair_user = self.chair_id.user_of_chair |
||||
|
|
||||
|
def salon_validate(self): |
||||
|
self.validation_controller = True |
||||
|
|
||||
|
def salon_close(self): |
||||
|
|
||||
|
self.stage_id = 4 |
||||
|
self.chair_id.number_of_orders = len(self.env['salon.order'].search([("chair_id", "=", self.chair_id.id), |
||||
|
("stage_id", "in", [2, 3])])) |
||||
|
self.chair_id.total_time_taken_chair = (self.chair_id.total_time_taken_chair - self.time_taken_total) |
||||
|
|
||||
|
def salon_cancel(self): |
||||
|
self.stage_id = 5 |
||||
|
self.chair_id.number_of_orders = len(self.env['salon.order'].search([("chair_id", "=", self.chair_id.id), |
||||
|
("stage_id", "in", [2, 3])])) |
||||
|
if self.stage_id.id != 1: |
||||
|
self.chair_id.total_time_taken_chair = (self.chair_id.total_time_taken_chair - self.time_taken_total) |
||||
|
|
||||
|
def button_total_update(self): |
||||
|
for order in self: |
||||
|
amount_untaxed = 0.0 |
||||
|
for line in order.order_line: |
||||
|
amount_untaxed += line.price_subtotal |
||||
|
order.price_subtotal = amount_untaxed |
||||
|
|
||||
|
|
||||
|
@api.onchange('chair_id') |
||||
|
def onchange_chair(self): |
||||
|
if 'active_id' in self._context.keys(): |
||||
|
self.chair_id = self._context['active_id'] |
||||
|
|
||||
|
def salon_invoice_create(self): |
||||
|
if self.partner_id: |
||||
|
supplier = self.partner_id |
||||
|
else: |
||||
|
supplier = self.partner_id.search([("name", "=", "Salon Default Customer")]) |
||||
|
lines = [] |
||||
|
product_id = self.env['product.product'].search([("name", "=", "Salon Service")]) |
||||
|
for records in self.order_line: |
||||
|
if product_id.property_account_income_id.id: |
||||
|
income_account = product_id.property_account_income_id.id |
||||
|
elif product_id.categ_id.property_account_income_categ_id.id: |
||||
|
income_account = product_id.categ_id.property_account_income_categ_id.id |
||||
|
else: |
||||
|
raise UserError(_('Please define income account for this product: "%s" (id:%d).') % (product_id.name, |
||||
|
product_id.id)) |
||||
|
|
||||
|
value = (0, 0, { |
||||
|
'name': records.service_id.name, |
||||
|
'account_id': income_account, |
||||
|
'price_unit': records.price, |
||||
|
'quantity': 1, |
||||
|
'product_id': product_id.id, |
||||
|
}) |
||||
|
lines.append(value) |
||||
|
|
||||
|
invoice_line = { |
||||
|
'move_type': 'out_invoice', |
||||
|
'partner_id': supplier.id, |
||||
|
'l10n_in_gst_treatment': 'consumer', |
||||
|
'invoice_user_id': self.env.user.id, |
||||
|
'invoice_origin': self.name, |
||||
|
'invoice_line_ids': lines, |
||||
|
} |
||||
|
inv = self.env['account.move'].create(invoice_line) |
||||
|
|
||||
|
|
||||
|
imd = self.env['ir.model.data'] |
||||
|
|
||||
|
action = imd.xmlid_to_object('account.action_move_out_invoice_type') |
||||
|
result = { |
||||
|
'name': action.name, |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'views': [[False, 'form']], |
||||
|
'target': 'current', |
||||
|
'res_id':inv.id, |
||||
|
'res_model': 'account.move', |
||||
|
} |
||||
|
|
||||
|
self.inv_stage_identifier = True |
||||
|
self.stage_id = 3 |
||||
|
invoiced_records = self.env['salon.order'].search([('stage_id', 'in', [3, 4]), |
||||
|
('chair_id', '=', self.chair_id.id)]) |
||||
|
total = 0 |
||||
|
for rows in invoiced_records: |
||||
|
invoiced_date = str(rows.date) |
||||
|
invoiced_date = invoiced_date[0:10] |
||||
|
if invoiced_date == str(date.today()): |
||||
|
total = total + rows.price_subtotal |
||||
|
self.chair_id.collection_today = total |
||||
|
self.chair_id.number_of_orders = len(self.env['salon.order'].search([("chair_id", "=", self.chair_id.id), |
||||
|
("stage_id", "in", [2, 3])])) |
||||
|
|
||||
|
return result |
||||
|
|
||||
|
def unlink(self): |
||||
|
for order in self: |
||||
|
if order.stage_id.id == 3 or order.stage_id.id == 4: |
||||
|
raise UserError(_("You can't delete an invoiced salon order!")) |
||||
|
return super(SalonOrder, self).unlink() |
||||
|
|
||||
|
|
||||
|
class SalonServices(models.Model): |
||||
|
_name = 'salon.service' |
||||
|
|
||||
|
name = fields.Char(string="Name") |
||||
|
price = fields.Float(string="Price") |
||||
|
time_taken = fields.Float(string="Time Taken", help="Approximate time taken for this service in Hours") |
||||
|
|
||||
|
|
||||
|
class SalonOrderLine(models.Model): |
||||
|
_name = 'salon.order.lines' |
||||
|
|
||||
|
service_id = fields.Many2one('salon.service', string="Service") |
||||
|
price = fields.Float(string="Price") |
||||
|
salon_order = fields.Many2one('salon.order', string="Salon Order", required=True, ondelete='cascade', |
||||
|
index=True, copy=False) |
||||
|
price_subtotal = fields.Float(string='Subtotal') |
||||
|
time_taken = fields.Float(string='Time Taken') |
||||
|
|
||||
|
@api.onchange('service_id') |
||||
|
def onchange_service(self): |
||||
|
self.price = self.service_id.price |
||||
|
self.price_subtotal = self.service_id.price |
||||
|
self.time_taken = self.service_id.time_taken |
||||
|
|
||||
|
@api.onchange('price') |
||||
|
def onchange_price(self): |
||||
|
self.price_subtotal = self.price |
||||
|
|
||||
|
@api.onchange('price_subtotal') |
||||
|
def onchange_subtotal(self): |
||||
|
self.price = self.price_subtotal |
||||
|
|
||||
|
|
||||
|
class SalonStages(models.Model): |
||||
|
_name = 'salon.stages' |
||||
|
_order = "sequence" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True, translate=True) |
||||
|
sequence = fields.Integer('Sequence', default=1, help="Used to order stages. Lower is better.") |
|
@ -0,0 +1,25 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
|
||||
|
<record model="ir.module.category" id="module_category_salon_management"> |
||||
|
<field name="name">Salon Management</field> |
||||
|
<field name="description">Helps you handle your salon needs</field> |
||||
|
<field name="sequence">5</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="group_salon_user" model="res.groups"> |
||||
|
<field name="name">Chair User</field> |
||||
|
<field name="category_id" ref="salon_management.module_category_salon_management"/> |
||||
|
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/> |
||||
|
</record> |
||||
|
|
||||
|
<record id="group_salon_manager" model="res.groups"> |
||||
|
<field name="name">Salon Manager </field> |
||||
|
<field name="category_id" ref="salon_management.module_category_salon_management"/> |
||||
|
<field name="implied_ids" eval="[(4, ref('group_salon_user'))]"/> |
||||
|
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</odoo> |
After Width: | Height: | Size: 135 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 118 KiB |
After Width: | Height: | Size: 31 KiB |
@ -0,0 +1,443 @@ |
|||||
|
|
||||
|
<section class="oe_container" style="background-image:url(https://www.cybrosys.com/images/odoo-index-header-banner.png); background-repeat:no-repeat; background-size:cover;padding: 13% 0% 22% 15%;"> |
||||
|
<div class="oe_row oe_spaced o_animate o_animate_in_children o_animate_offset_min"> |
||||
|
<h2 class="oe_slogan" style="font-size: 35px;color: #fff;font-weight: 900;text-transform: uppercase;text-align: left;margin: 0;margin-bottom: 16px;"> |
||||
|
Beauty Spa Management |
||||
|
</h2> |
||||
|
<h3 class="oe_slogan" style="font-size: 25px;color: #fff;font-weight: 600;text-align: left;opacity: 1;margin: 0 !important;"> |
||||
|
Easy to manage Beauty Spa |
||||
|
</h3> |
||||
|
<h5 class="oe_slogan" style="text-align: left;background: #fff;width: 293px;padding: 10px;color: #080808 !important;opacity: 1 !important;font-weight: 600;font-size: 20px;"> |
||||
|
<a style="color: #080808 !important;" href="https://www.cybrosys.com">Cybrosys Technologies</a> |
||||
|
</h5> |
||||
|
<a style="color: #080808 !important;" href="https://www.cybrosys.com" target="_blank"> |
||||
|
<div style="width: 215px;margin-left: 57%;text-align: center;background: #ffffff;height: 215px;border-radius: 100%;display: flex;justify-content: center;align-items: center;box-shadow: 0 0 12px 4px #00000059;"> |
||||
|
<img src="https://www.cybrosys.com/images/cybro-logo-oca.png" alt="cybrosys technologies" style="width: 180px;"/> </div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<section class="oe_container" style="padding: 3% 0% 3% 15%;"> |
||||
|
<div class="oe_row oe_spaced o_animate o_animate_in_children o_animate_offset_min"> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Overview |
||||
|
</h2> |
||||
|
<h3 class="oe_slogan" style="text-align: left;font-size: 16px;width: 90%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 24px;"> |
||||
|
<div> |
||||
|
<p class='oe_mt32'> |
||||
|
Cybrosys Techno Solution’s Spa Management System envisions in giving a complete |
||||
|
new experience to client in availing their spa services. |
||||
|
The Spa Management System helps the customer in processing their online booking |
||||
|
for spa services. The module comes integrated with Odoo Accounting and Website, offering |
||||
|
comprehensive plethora of functions. |
||||
|
</p> |
||||
|
<p > |
||||
|
One of the significant advantage of using the Spa Management System is that, it offers your |
||||
|
customer their booking information via email. The client is equipped with the status of |
||||
|
their booking, enhancing the customary experience and brand building of your business. |
||||
|
</p> |
||||
|
</div> |
||||
|
</h3> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container" style="background-image:url(https://www.cybrosys.com/images/odoo-index-banner.png); background-repeat:no-repeat; background-size:cover;padding: 19% 0% 30% 15%;"> |
||||
|
<div class="oe_row oe_spaced o_animate o_animate_in_children o_animate_offset_min"> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Features |
||||
|
</h2> |
||||
|
<h3 class="oe_slogan" style="text-align: left;font-size: 16px;width: 90%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 18px;"> |
||||
|
<img src="https://www.cybrosys.com/images/ico-tick.png"> |
||||
|
Online booking facility. |
||||
|
</h3> |
||||
|
<h3 class="oe_slogan" style="text-align: left;font-size: 16px;width: 90%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 18px;"> |
||||
|
<img src="https://www.cybrosys.com/images/ico-tick.png"> |
||||
|
Accounting facility. |
||||
|
</h3><h3 class="oe_slogan" style="text-align: left;font-size: 16px;width: 90%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 18px;"> |
||||
|
<img src="https://www.cybrosys.com/images/ico-tick.png"> |
||||
|
Customer notification via email. |
||||
|
</h3> |
||||
|
<h3 class="oe_slogan" style="text-align: left;font-size: 16px;width: 90%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 18px;"> |
||||
|
<img src="https://www.cybrosys.com/images/ico-tick.png"> |
||||
|
User interactive dashboard.</h3> |
||||
|
<h3 class="oe_slogan" style="text-align: left;font-size: 16px;width: 90%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 18px;"> |
||||
|
<img src="https://www.cybrosys.com/images/ico-tick.png"> |
||||
|
Customer can view the available chairs and order details.</h3> |
||||
|
<h3 class="oe_slogan" style="text-align: left;font-size: 16px;width: 90%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 18px;"> |
||||
|
<img src="https://www.cybrosys.com/images/ico-tick.png"> |
||||
|
Different access levels for users and administrator.</h3> |
||||
|
<h3 class="oe_slogan" style="text-align: left;font-size: 16px;width: 90%;margin: 0;margin-top: 14px;color: #000 !important;opacity: 1 !important;line-height: 18px;"> |
||||
|
<img src="https://www.cybrosys.com/images/ico-tick.png"> |
||||
|
Track the chair user by date. |
||||
|
</h3> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container" style="padding: 3% 0% 0% 15%;"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Dashboard |
||||
|
</h2> |
||||
|
<br> |
||||
|
<icon> Dashboard view is shown in the below image. |
||||
|
Your customer can book the service in two ways, either via direct booking or online booking. |
||||
|
The chairs with Black font's denote the ones available for online booking and the White ones |
||||
|
for direct booking. From dashboard, one get all information about the chair, whether the |
||||
|
particular chair is free or is in currently use. Also one can see the |
||||
|
active orders of that chair. If the end user clicks in , it will directly navigate to the |
||||
|
active orders of that chair. In case, if the end user want to change the |
||||
|
settings of chair, they can just click the settings button in the dashboard.</icon> |
||||
|
<div class="oe_row oe_spaced o_animate o_animate_in_children o_animate_offset_min"> |
||||
|
<img src="1.png" alt="" style="width: 95%;"/> |
||||
|
</div> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Chair |
||||
|
</h2> |
||||
|
<h3> |
||||
|
Go to Salon --> Chair</h3> |
||||
|
<icon> |
||||
|
Here you can create and edit details of each chair. You can assign a user to the chair by adding new user to the users tab in the form view of chair(Check the image shown below). The last added user will be turned to the current user of the chair. Using this tab, you can track which user is active on the Chair on a particular date or time. |
||||
|
</icon> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<img src="2.png" alt="" style="width: 95%;"/> |
||||
|
</div> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Services |
||||
|
</h2> |
||||
|
<h3>Go to Salon --> Services</h3> |
||||
|
<icon> |
||||
|
List of services provided by the Spa. You can create and edit services here. |
||||
|
</icon> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<img src="3.png" alt="" style="width: 95%;"/> |
||||
|
</div> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Salon Orders |
||||
|
</h2> |
||||
|
<h3>Go to Salon --> Salon Orders</h3> |
||||
|
<icon>Here you have all the orders in the Spa.</icon> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<img src="4.png" alt="" style="width: 95%;"/> |
||||
|
</div> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Salon Order Form View |
||||
|
</h2> |
||||
|
<h3>Go to Salon --> Salon Orders --> Form View</h3> |
||||
|
<icon>Form view of the salon order is shown in the image. You will get the corresponding invoice details of the order by clicking the Invoice button in the upper right side of the form view. </icon> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<img src="5.png" alt="" style="width: 95%;"/> |
||||
|
</div> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Booking |
||||
|
</h2> |
||||
|
<h3>Go to Salon --> Bookings</h3> |
||||
|
<icon>Here you can see all the online bookings. You can either approve a booking or reject a booking. In both cases the notification is send to the customer mail address. The approved bookings will be changed to salon orders. </icon> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<img src="6.png" alt="" style="width: 95%;"/> |
||||
|
</div> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Booking Form View |
||||
|
</h2> |
||||
|
<h3></i>Go to Salon --> Bookings --> Form View</h3> |
||||
|
<icon>Here you can see all existing salon orders on the corresponding date on that chair. After checking the time availability, you can decide to approve/reject the booking.</icon> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<img src="7.png" alt="" style="width: 95%;"/> |
||||
|
</div> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Settings |
||||
|
</h2> |
||||
|
<h3></i>Go to Salon --> Configuration --> Settings</h3> |
||||
|
<icon>Here you can assign the chairs for booking purpose. Only the assigned chairs can be booked by a customer through online. Also you can select the holidays here</icon> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<img src="8.png" alt="" style="width: 95%;"/> |
||||
|
</div> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
|
||||
|
</h2> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Online Booking |
||||
|
</h2> |
||||
|
<h3>Go to Website --> Bookings</h3> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<img src="9.png" alt="" style="width: 95%;"/> |
||||
|
</div> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Check the availability of Chair |
||||
|
</h2> |
||||
|
<h3>Go to Website --> Bookings</h3> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<img src="10.png" alt="" style="width: 95%;"/> |
||||
|
</div> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
</h2> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container" style="padding: 7px 0% 0% 3%;"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<a style="color: #080808 !important;" href="https://apps.odoo.com/apps/modules/browse?search=cybrosys" target="_blank"><img src="https://www.cybrosys.com/images/view-more-apps.jpg" alt="cybrosys technologies" style="width: 100%;margin-bottom: 50px;"/></a> |
||||
|
</div> |
||||
|
</section> |
||||
|
<section class="oe_container" style="padding: 1% 0% 0% 3%;"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Our Services |
||||
|
</h2> |
||||
|
<div style="display:flex;padding-top: 20px;justify-content: space-between;"> |
||||
|
<div style="flex-basis: 18%;"> |
||||
|
|
||||
|
<div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> |
||||
|
<a href="https://www.cybrosys.com/odoo-customization-and-installation/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-customization.png" style="width: 100%;border-radius: 100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
<h3 class="oe_slogan" style="text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo-customization-and-installation/" target="_blank"> |
||||
|
Odoo Customization |
||||
|
</a> |
||||
|
</h3> |
||||
|
|
||||
|
</div> |
||||
|
<div style="flex-basis: 18%;"> |
||||
|
|
||||
|
<div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> |
||||
|
<a href="https://www.cybrosys.com/odoo-erp-implementation/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-erp-implementation.png" style="width: 100%;border-radius: 100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
<h3 class="oe_slogan" style="text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo-erp-implementation/" target="_blank"> |
||||
|
Odoo Implementation |
||||
|
</a> |
||||
|
</h3> |
||||
|
</div> |
||||
|
<div style="flex-basis: 18%;"> |
||||
|
|
||||
|
<div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> |
||||
|
<a href="https://www.cybrosys.com/odoo-erp-integration/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-erp-integration.png" style="width: 100%;border-radius: 100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
<h3 class="oe_slogan" style="text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo-erp-integration/" target="_blank"> |
||||
|
Odoo Integration |
||||
|
</a> |
||||
|
</h3> |
||||
|
</div> |
||||
|
<div style="flex-basis: 18%;"> |
||||
|
|
||||
|
<div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> |
||||
|
<a href="https://www.cybrosys.com/odoo-erp-support/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-erp-support.png" style="width: 100%;border-radius: 100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
<h3 class="oe_slogan" style="text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo-erp-support/" target="_blank"> |
||||
|
Odoo Support |
||||
|
</a> |
||||
|
</h3> |
||||
|
</div> |
||||
|
<div style="flex-basis: 18%;"> |
||||
|
|
||||
|
<div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> |
||||
|
<a href="https://www.cybrosys.com/hire-odoo-developer/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/hire-odoo-developer.png" style="width: 100%;border-radius: 100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
<h3 class="oe_slogan" style="text-align: center;font-size: 14px;width: 100%;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;"> |
||||
|
<a href="https://www.cybrosys.com/hire-odoo-developer/" target="_blank"> |
||||
|
Hire Odoo Developer |
||||
|
</a> |
||||
|
</h3> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<section class="oe_container" style="padding: 3% 0% 0% 3%;"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h2 class="oe_slogan" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
||||
|
Our Industries |
||||
|
</h2> |
||||
|
<div style="display:flex;justify-content: space-between;flex-wrap:wrap;"> |
||||
|
<div style="flex-basis: 32%;padding-top: 20px;"> |
||||
|
|
||||
|
<div style="width:30%; float:left;"> |
||||
|
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/best-trading-erp/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-index-industry-1.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="width:70%;float:left;"> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:600;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/best-trading-erp/" target="_blank"> |
||||
|
Trading |
||||
|
</a> |
||||
|
</h3> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 13px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;"> |
||||
|
Easily procure and sell your products. |
||||
|
</h3> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="flex-basis: 32%;padding-top: 20px;"> |
||||
|
|
||||
|
<div style="width:30%; float:left;"> |
||||
|
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/manufacturing-erp-software/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-index-industry-2.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="width:70%;float:left;"> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:600;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/manufacturing-erp-software/" target="_blank"> |
||||
|
Manufacturing |
||||
|
</a> |
||||
|
</h3> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 13px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;"> |
||||
|
Plan, track and schedule your operations. |
||||
|
</h3> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="flex-basis: 32%;padding-top: 20px;"> |
||||
|
|
||||
|
<div style="width:30%; float:left;"> |
||||
|
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/restaurant-management/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-index-industry-3.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="width:70%;float:left;"> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:600;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/restaurant-management/" target="_blank"> |
||||
|
Restaurant |
||||
|
</a> |
||||
|
</h3> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 13px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;"> |
||||
|
Run your bar or restaurant methodical. |
||||
|
</h3> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="flex-basis: 32%;padding-top: 20px;"> |
||||
|
|
||||
|
<div style="width:30%; float:left;"> |
||||
|
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/pos/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-index-industry-4.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="width:70%;float:left;"> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:600;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/pos/" target="_blank"> |
||||
|
POS |
||||
|
</a> |
||||
|
</h3> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 13px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;"> |
||||
|
Easy configuring and convivial selling. |
||||
|
</h3> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="flex-basis: 32%;padding-top: 20px;"> |
||||
|
|
||||
|
<div style="width:30%; float:left;"> |
||||
|
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/ecommerce-website/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-index-industry-5.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="width:70%;float:left;"> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:600;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 0px;margin-left: 16px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/ecommerce-website/" target="_blank"> |
||||
|
E-commerce & Website |
||||
|
</a> |
||||
|
</h3> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 13px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;"> |
||||
|
Mobile friendly, awe-inspiring product pages. |
||||
|
</h3> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="flex-basis: 32%;padding-top: 20px;"> |
||||
|
|
||||
|
<div style="width:30%; float:left;"> |
||||
|
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/hotel-management-erp/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-index-industry-6.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="width:70%;float:left;"> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:600;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/hotel-management-erp/" target="_blank"> |
||||
|
Hotel Management |
||||
|
</a> |
||||
|
</h3> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 13px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;"> |
||||
|
An all-inclusive hotel management application. |
||||
|
</h3> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="flex-basis: 32%;padding-top: 20px;"> |
||||
|
|
||||
|
<div style="width:30%; float:left;"> |
||||
|
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/education-erp-software/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-index-industry-7.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="width:70%;float:left;"> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:600;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/education-erp-software/" target="_blank"> |
||||
|
Education |
||||
|
</a> |
||||
|
</h3> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 13px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;"> |
||||
|
A Collaborative platform for educational management. |
||||
|
</h3> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="flex-basis: 32%;padding-top: 20px;"> |
||||
|
|
||||
|
<div style="width:30%; float:left;"> |
||||
|
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/service-management/" target="_blank"> |
||||
|
<img src="https://www.cybrosys.com/images/odoo-index-industry-8.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="width:70%;float:left;"> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 14px;font-weight:600;width: auto;margin: 0;margin-top: 14px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 4px;margin-left: 16px;"> |
||||
|
<a href="https://www.cybrosys.com/odoo/industries/service-management/" target="_blank"> |
||||
|
Service Management |
||||
|
</a> |
||||
|
</h3> |
||||
|
<h3 class="oe_slogan" style=" text-align: left;font-size: 13px;width: auto;margin: 0;margin-top:5px;color: #000 !important;margin-top: 5px;opacity: 1 !important;line-height: 17px;float: left;margin-top: 5px;margin-left: 16px;"> |
||||
|
Keep track of services and invoice accordingly. |
||||
|
</h3> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container" style="background-image:url(https://www.cybrosys.com/images/odoo-index-footer-bg.png); background-repeat:no-repeat; background-size:100%;padding: 13% 0% 6% 0%;"> |
||||
|
<div class="oe_slogan" style="margin-top:10px !important;margin-bottom: 0px;"> |
||||
|
<div> |
||||
|
<a style="color: #5c5c5c !important;border-radius: 0;background: none;border: none;background: #fff;box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62, 57, 107, 0.05);border-radius: 30px;font-size: 14px;padding: 9px 26px;margin-right: 9px;width: 200px;text-transform: capitalize;" class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" href="https://www.cybrosys.com"><i class="fa fa-envelope"></i> Email us </a> |
||||
|
<a style="color: #5c5c5c !important;border-radius: 0;background: none;border: none;background: #fff;box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62, 57, 107, 0.05);border-radius: 30px;font-size: 14px;padding: 9px 26px;margin-right: 9px;width: 200px;text-transform: capitalize;" class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" href="https://www.cybrosys.com/contact/"><i class="fa fa-phone"></i> Contact Us </a> |
||||
|
<a style="color: #5c5c5c !important;border-radius: 0;background: none;border: none;background: #fff;box-shadow: 0 10px 40px 0 rgba(62,57,107,0.07), 0 2px 9px 0 rgba(62, 57, 107, 0.05);border-radius: 30px;font-size: 14px;padding: 9px 26px;margin-right: 9px;width: 200px;text-transform: capitalize;" class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" href="https://www.cybrosys.com/odoo-customization-and-installation/"><i class="fa fa-check-square"></i> Request Customization </a> |
||||
|
</div> |
||||
|
<br> |
||||
|
<img src="https://www.cybrosys.com/images/logo.png" style="width: 190px; margin-bottom: 25px;margin-top: 30px;" class="center-block"> |
||||
|
<div> |
||||
|
<a href="https://twitter.com/cybrosys" target="_blank"><i class="fa fa-2x fa-twitter" style="color:white;background: #00a0d1;width:35px;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a></td> |
||||
|
<a href="https://www.linkedin.com/company/cybrosys-technologies-pvt-ltd" target="_blank"><i class="fa fa-2x fa-linkedin" style="color:white;background: #31a3d6;width:35px;padding-left: 3px;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a></td> |
||||
|
<a href="https://www.facebook.com/cybrosystechnologies" target="_blank"><i class="fa fa-2x fa-facebook" style="color:white;background: #3b5998;width:35px; ;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a></td> |
||||
|
<a href="https://plus.google.com/106641282743045431892/about" target="_blank"><i class="fa fa-2x fa-google-plus" style="color:white;background: #c53c2c;width:35px;padding-left: 3px;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a></td> |
||||
|
<a href="https://in.pinterest.com/cybrosys" target="_blank"><i class="fa fa-2x fa-pinterest" style="color:white;background: #ac0f18;width:35px;padding-left: 3px;height: 35px;padding-top: 7px;font-size: 21px;margin-right: 6px;border-radius: 100%;"></i></a></td> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
@ -0,0 +1,59 @@ |
|||||
|
.style_chair { |
||||
|
text-align: center; |
||||
|
color: white; |
||||
|
font-size: 17px; |
||||
|
background: #0f101000; |
||||
|
padding: 0 !important; |
||||
|
text-transform: uppercase; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
.style_chair_booking{ |
||||
|
text-align: center; |
||||
|
color: #000000; |
||||
|
font-size: 17px; |
||||
|
background: #0f101000; |
||||
|
padding: 0 !important; |
||||
|
text-transform: uppercase; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
.style_collection { |
||||
|
color: black !important; |
||||
|
font-size: 12px; |
||||
|
text-align: center; |
||||
|
background: #29292900 !important; |
||||
|
padding: 0 !important; |
||||
|
} |
||||
|
.style_collection_booking{ |
||||
|
color: black !important; |
||||
|
font-size: 12px; |
||||
|
text-align: center; |
||||
|
background: #29292900 !important; |
||||
|
padding: 0 !important; |
||||
|
} |
||||
|
.no_of_people { |
||||
|
text-align: center; |
||||
|
font-size: 41px; |
||||
|
padding: 0 !important; |
||||
|
background: #4f535600; |
||||
|
color: white; |
||||
|
margin-top: 9px; |
||||
|
margin-bottom: 30px; |
||||
|
} |
||||
|
span.o_primary.style_collection { |
||||
|
color: #fff !important; |
||||
|
} |
||||
|
.no_of_people_booking{ |
||||
|
text-align: center; |
||||
|
font-size: 41px; |
||||
|
padding: 0 !important; |
||||
|
background: #4f535600; |
||||
|
color: #000000; |
||||
|
margin-top: 9px; |
||||
|
margin-bottom: 30px; |
||||
|
} |
||||
|
.button_background{ |
||||
|
background-color: Transparent; |
||||
|
border: transparent; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
|
@ -0,0 +1,46 @@ |
|||||
|
.chair_box_website{ |
||||
|
text-align: center; |
||||
|
border: 1px solid #666; |
||||
|
padding: 10px 15px; |
||||
|
box-shadow: 7px 8px 5px #888888; |
||||
|
background-color: #337ab7; |
||||
|
color: #000000; |
||||
|
} |
||||
|
.field_booking_chair{ |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
input[type="text"]{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
input[type="email"]{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
input[type=checkbox] + label { |
||||
|
color: #7c7bad; |
||||
|
font-style: italic; |
||||
|
} |
||||
|
input[type=checkbox]:checked + label { |
||||
|
color: #00a09d; |
||||
|
font-style: normal; |
||||
|
} |
||||
|
select{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
.selection_service{ |
||||
|
height: 6em; |
||||
|
overflow: auto; |
||||
|
border: 1px solid #b3b3b3; |
||||
|
border-radius: 5px; |
||||
|
background-color: #fcfcfc; |
||||
|
} |
||||
|
#booking_chair_details{ |
||||
|
height: 200px!important; |
||||
|
text-align: center; |
||||
|
border: 1px solid #666; |
||||
|
padding: 15px 0px; |
||||
|
box-shadow: 7px 8px 5px #888888; |
||||
|
background-color:#7c7bad; |
||||
|
border-radius:58px; |
||||
|
color:#fff; |
||||
|
margin-bottom: 10px; |
||||
|
} |
@ -0,0 +1,105 @@ |
|||||
|
odoo.define('salon_management.website_salon_booking_system', function (require) { |
||||
|
'use strict'; |
||||
|
var ajax = require('web.ajax'); |
||||
|
var base = require('web_editor.base'); |
||||
|
var core = require('web.core'); |
||||
|
var _t = core._t; |
||||
|
var rpc = require('web.rpc'); |
||||
|
var QWeb = core.qweb; |
||||
|
$(document).on('click',"#submit_button",function() { |
||||
|
var name = $("#name").val(); |
||||
|
var date = $("#date").val(); |
||||
|
var time = $("#time").val(); |
||||
|
var phone = $("#phone").val(); |
||||
|
var email = $("#email").val(); |
||||
|
var service = $('.check_box_salon:checkbox:checked'); |
||||
|
var chair = $( "#chair" ).val(); |
||||
|
console.log(date,time) |
||||
|
var list_service = []; |
||||
|
var number = service.length; |
||||
|
for (var i=0; i<(service.length); i++){ |
||||
|
var k = {i : service[i].attributes['service-id'].value}; |
||||
|
list_service.push(k); |
||||
|
}; |
||||
|
if (name == "" || date == "" || time == "" || phone == "" || email == "" || list_service.length == 0){ |
||||
|
alert("All fields are mandatory"); |
||||
|
} |
||||
|
else{ |
||||
|
var time_left_char = time.substring(0, 2); |
||||
|
var time_right_char = time.substring(3, 5); |
||||
|
var time_separator = time.substring(2,3); |
||||
|
if (isNaN(time_left_char) || isNaN(time_right_char) || time_separator != ":"){ |
||||
|
alert("Select a valid Time"); |
||||
|
} |
||||
|
else{ |
||||
|
var time_left = parseInt(time_left_char); |
||||
|
var time_right = parseInt(time_right_char); |
||||
|
console.log(time_left,time_right) |
||||
|
if ((time_left < 24) && (time_right < 60) && (time_left >= 0) && (time_right >= 0)){ |
||||
|
var booking_record = {'name': name, 'date': date, 'time': time, 'phone': phone, 'email': email, 'list_service':list_service,'chair': chair,'number': number }; |
||||
|
$.ajax({ |
||||
|
url: "/page/salon_details", |
||||
|
type: "POST", |
||||
|
dataType: "json", |
||||
|
data: booking_record, |
||||
|
type: 'POST', |
||||
|
success: function( data ) { |
||||
|
window.location.href = "/page/salon_management.salon_booking_thank_you"; |
||||
|
}, |
||||
|
error: function (error) { |
||||
|
alert('error: ' + error); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
else { |
||||
|
alert("Select a valid time"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
$(document).on('click',"#check_button",function() { |
||||
|
var check_date = $( "#check_date" ).val(); |
||||
|
if (check_date != ""){ |
||||
|
ajax.jsonRpc("/page/salon_check_date", 'call', {'check_date':check_date }) |
||||
|
.then(function(order_details){ |
||||
|
var x; |
||||
|
var total_orders = ""; |
||||
|
var order = ""; |
||||
|
var chair_name; |
||||
|
for (x in order_details) { |
||||
|
var chair_name = order_details[x]['name'] |
||||
|
var i; |
||||
|
var lines = ""; |
||||
|
for (i = 0; i < order_details[x]['orders'].length; i++) { |
||||
|
lines += '<tr><td><span>' + order_details[x]['orders'][i]['number'] + |
||||
|
'</span></td><td><span>' + order_details[x]['orders'][i]['start_time_only'] + |
||||
|
'</span></td><td><span>' + order_details[x]['orders'][i]['end_time_only'] + '</span></td></tr>' |
||||
|
} |
||||
|
order += '<div class="col-lg-4 s_title pt16 pb16"><div style="height: 200px!important; text-align: center;' + |
||||
|
'border: 1px solid #666;padding: 15px 0px;box-shadow: 7px 8px 5px #888888;background-color:#7c7bad;border-radius:58px;color:#fff;margin-bottom: 10px;">' + |
||||
|
'<span style="font-size: 15px;">' + chair_name + '</span>' + |
||||
|
'<br/><a style="color:#fff;font-size:15px;">Order Details</a>' + |
||||
|
'<div id="style-2" style="overflow-y:scroll;height:105px;padding-right:25px;padding-left:25px;margin-right:10px;">' + |
||||
|
'<table class="table"><th style="font-size:11px;">Order No.</th><th style="font-size:11px;">Start Time</th>' + |
||||
|
'<th style="font-size:11px;">End Time</th><div><tbody style="font-size: 10px;">' + |
||||
|
lines + '</tbody></div></table></div></div></div>' |
||||
|
|
||||
|
} |
||||
|
total_orders += '<div id="booking_chair_div" class="col-lg-12 s_title pt16 pb16 row">' + order + '</div>' |
||||
|
var res = document.getElementById('booking_chair_div') |
||||
|
res.innerHTML = ""; |
||||
|
res.innerHTML = total_orders; |
||||
|
var date_value = 'DATE : <t>' + check_date + '</t>' |
||||
|
var date_field = document.getElementById('searched_date') |
||||
|
date_field.innerHTML = ""; |
||||
|
date_field.innerHTML = date_value; |
||||
|
}) |
||||
|
} |
||||
|
else { |
||||
|
alert("Fill the Field"); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
}); |
@ -0,0 +1,39 @@ |
|||||
|
.o_kanban_view.o_kanban_dashboard.o_salon_kanban .o_kanban_record { |
||||
|
width: 180px; |
||||
|
height: 200px; |
||||
|
border-radius: 90px 90px 20px 20px; |
||||
|
background: #cc1f2f; |
||||
|
background: linear-gradient(#cc1f2f 0%, #cc1f2f 63%, #6d0b0b 63%, #cc1f2f 73%); |
||||
|
position: relative; |
||||
|
margin: 25px; |
||||
|
display: inline-block; |
||||
|
} |
||||
|
.o_kanban_view.o_kanban_dashboard.o_salon_kanban .o_kanban_record:after, |
||||
|
.o_kanban_view.o_kanban_dashboard.o_salon_kanban .o_kanban_record:before { |
||||
|
content: ""; |
||||
|
display: block; |
||||
|
width: 33.33333333px; |
||||
|
height: 111.11111111px; |
||||
|
position: absolute; |
||||
|
background: #cc1f2f; |
||||
|
border-radius: 20px; |
||||
|
border: 1px solid #000; |
||||
|
bottom: 25px; |
||||
|
right: 0; |
||||
|
left: 185px; |
||||
|
top: 64px; |
||||
|
} |
||||
|
.o_kanban_view.o_kanban_dashboard.o_salon_kanban .o_kanban_record:before { |
||||
|
left: -20px; |
||||
|
} |
||||
|
.o_kanban_view.o_kanban_dashboard.o_salon_kanban .o_kanban_record:after { |
||||
|
right: -20px; |
||||
|
} |
||||
|
.o_kanban_view.o_kanban_dashboard.o_salon_kanban .o_kanban_record.notvacant { |
||||
|
background: #ccc; |
||||
|
background: linear-gradient(#ccc 0%, #ccc 70%, #000 70%, #ccc 77%); |
||||
|
} |
||||
|
.o_kanban_view.o_kanban_dashboard.o_salon_kanban .o_kanban_record.notvacant:before, |
||||
|
.o_kanban_view.o_kanban_dashboard.o_salon_kanban .o_kanban_record.notvacant:after { |
||||
|
background: #ccc; |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
|
||||
|
.o_kanban_view.o_kanban_dashboard.o_salon_kanban { |
||||
|
|
||||
|
.o_kanban_record { |
||||
|
width: 180px; |
||||
|
height: 200px; |
||||
|
border-radius: 90px 90px 20px 20px; |
||||
|
background: #cc1f2f; |
||||
|
background: linear-gradient(#cc1f2f 0%, #cc1f2f 63%, #6d0b0b 63%, #cc1f2f 73%); |
||||
|
position: relative; |
||||
|
margin: 25px; |
||||
|
display: inline-block; |
||||
|
} |
||||
|
.o_kanban_record:after, .o_kanban_record:before { |
||||
|
content: ""; |
||||
|
display: block; |
||||
|
width: 33.3333333333px; |
||||
|
height: 111.1111111111px; |
||||
|
position: absolute; |
||||
|
background: #cc1f2f; |
||||
|
border-radius: 20px; |
||||
|
border: 1px solid #000; |
||||
|
bottom: 25px; |
||||
|
right: 0; |
||||
|
left: 185px; |
||||
|
top: 64px; |
||||
|
} |
||||
|
.o_kanban_record:before { |
||||
|
left: -20px; |
||||
|
} |
||||
|
.o_kanban_record:after { |
||||
|
right: -20px; |
||||
|
} |
||||
|
.o_kanban_record.notvacant { |
||||
|
background: #ccc; |
||||
|
background: linear-gradient(#ccc 0%, #ccc 70%, #000 70%, #ccc 77%); |
||||
|
} |
||||
|
.o_kanban_record.notvacant:before, .o_kanban_record.notvacant:after { |
||||
|
background: #ccc; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,248 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<template id="salon_booking_form" name="Salon Booking"> |
||||
|
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"/> |
||||
|
<link rel="stylesheet" href="/resources/demos/style.css"/> |
||||
|
<script src="https://code.jquery.com/jquery-1.12.4.js"></script> |
||||
|
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> |
||||
|
<script>$( function() {$( "#date" ).datepicker();} );</script> |
||||
|
<script>$( function() {$( "#check_date" ).datepicker();} );</script> |
||||
|
<t t-call="website.layout"> |
||||
|
<div class="container"> |
||||
|
|
||||
|
<div class="row s_nb_column_fixed"> |
||||
|
|
||||
|
<div class="col-lg-6 s_title pt16 pb16"> |
||||
|
<h3> |
||||
|
Working Time |
||||
|
</h3> |
||||
|
<table border="1"> |
||||
|
<th>Day</th> |
||||
|
<th>Starting Time</th> |
||||
|
<th>Closing Time</th> |
||||
|
<tbody> |
||||
|
<t t-foreach="working_time" t-as="working_time_obj"> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<span t-field="working_time_obj.name"/>. |
||||
|
</td> |
||||
|
<td> |
||||
|
<span t-field="working_time_obj.from_time"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span t-field="working_time_obj.to_time"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-6 s_title pt16 pb16"> |
||||
|
<h3>Book Your Chair</h3> |
||||
|
<form> |
||||
|
<div class="row s_nb_column_fixed"> |
||||
|
<div class="col-lg-2 s_title pt16 pb16 field_booking_chair"> |
||||
|
NAME * |
||||
|
</div> |
||||
|
<div class="col-lg-10 s_title pt16 pb16"> |
||||
|
<input type="text" id="name" placeholder="Enter your Name"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row s_nb_column_fixed"> |
||||
|
<div class="col-lg-2 s_title pt16 pb16 field_booking_chair"> |
||||
|
SERVICES* |
||||
|
</div> |
||||
|
<div class="col-lg-10 s_title pt16 pb16"> |
||||
|
<div class="selection_service"> |
||||
|
<div style="padding-left: 15px;padding-top: 15px;"> |
||||
|
<t t-foreach="salon_services" t-as="service"> |
||||
|
<div> |
||||
|
<input type="checkbox" t-att-service-id="service.id" |
||||
|
class="check_box_salon"/> |
||||
|
<label for="service.id" t-esc="service.name"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row s_nb_column_fixed"> |
||||
|
<div class="col-lg-2 s_title pt16 pb16 field_booking_chair"> |
||||
|
TIME * |
||||
|
</div> |
||||
|
<div class="col-lg-10 s_title pt16 pb16 row"> |
||||
|
<div class="col-lg-4 s_title pt16 pb16"> |
||||
|
<input type="text" id="date" placeholder="dd/mm/yyyy" |
||||
|
onkeyup="var v = this.value;if (v.match(/^\d{2}$/) !== null) {this.value = v + '/';} else if (v.match(/^\d{2}\/\d{2}$/) !== null) {this.value = v + '/';}" |
||||
|
maxlength="10"/> |
||||
|
</div> |
||||
|
<div class="col-lg-3 s_title pt16 pb16"> |
||||
|
<input type="text" id="time" placeholder="HH:MM" |
||||
|
onkeyup="var v = this.value;if (v.match(/^\d{2}$/) !== null) {this.value = v + ':';}" |
||||
|
maxlength="5"/> |
||||
|
</div> |
||||
|
<div class="col-lg-5 s_title pt16 pb16" style="font-size: 12px;"> |
||||
|
(Select date & time based on availability of chair) |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row s_nb_column_fixed"> |
||||
|
<div class="col-lg-2 s_title pt16 pb16 field_booking_chair"> |
||||
|
CHAIR * |
||||
|
</div> |
||||
|
<div class="col-lg-10 s_title pt16 pb16 row"> |
||||
|
<div class="col-lg-5 s_title pt16 pb16"> |
||||
|
<select id="chair" required="True"> |
||||
|
<t t-foreach="chair_details" t-as="chair"> |
||||
|
<option t-att-value="chair.id" t-esc="chair.name"/> |
||||
|
</t> |
||||
|
</select> |
||||
|
</div> |
||||
|
<div class="col-lg-7 s_title pt16 pb16" style="font-size: 12px;"> |
||||
|
(Select the chair that free in the preferred time) |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row s_nb_column_fixed"> |
||||
|
<div class="col-lg-2 s_title pt16 pb16 field_booking_chair"> |
||||
|
PHONE * |
||||
|
</div> |
||||
|
<div class="col-lg-10 s_title pt16 pb16"> |
||||
|
<input type="text" id="phone" required="True" |
||||
|
placeholder="Enter your Phone number(eg:999**12345)"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row s_nb_column_fixed"> |
||||
|
<div class="col-lg-2 s_title pt16 pb16 field_booking_chair"> |
||||
|
E-MAIL * |
||||
|
</div> |
||||
|
<div class="col-lg-10 s_title pt16 pb16"> |
||||
|
<input type="email" id="email" required="True" |
||||
|
placeholder="Enter your E-Mail Address(eg:avinashnk94@gmail.com)"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row s_nb_column_fixed"> |
||||
|
<div class="col-lg-12 s_title pt16 pb16"> |
||||
|
<button type="button" id="submit_button" |
||||
|
class="btn btn-primary btn-md o_website_form_send">Send |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div> |
||||
|
<t t-call="salon_management.salon_booking_chair_details"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</template> |
||||
|
|
||||
|
<template id="salon_booking_chair_details" name="Chair Details"> |
||||
|
<section id="chair_details"> |
||||
|
<div class="container"> |
||||
|
<h3>Already Booked Chairs and Details</h3> |
||||
|
<hr/> |
||||
|
<div class="row s_nb_column_fixed"> |
||||
|
<div class="col-lg-12 s_title pt16 pb16"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-5 s_title pt16 pb16"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-2 s_title pt16 pb16"> |
||||
|
TIME : |
||||
|
</div> |
||||
|
<div class="col-lg-6 s_title pt16 pb16"> |
||||
|
<input id="check_date" type="text" placeholder="Select a date"/> |
||||
|
</div> |
||||
|
<div class="col-lg-4 s_title pt16 pb16"> |
||||
|
<button type="submit" id="check_button" |
||||
|
class="btn btn-primary btn-md o_website_form_send">Check |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3 s_title pt16 pb16"> |
||||
|
<div class="col-lg-12 s_title pt16 pb16" id="searched_date"> |
||||
|
DATE : |
||||
|
<t t-esc="date_search"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 s_title pt16 pb16 row"> |
||||
|
<div class="col-lg-4 s_title pt16 pb16"> |
||||
|
HOLIDAYS : |
||||
|
</div> |
||||
|
<div t-foreach="holiday" t-as="holiday_obj" class="col-lg-2 s_title pt16 pb16"> |
||||
|
<span t-field="holiday_obj.name"/> |
||||
|
<span>&nbsp;</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="booking_chair_div" class="col-lg-12 s_title pt16 pb16 row"> |
||||
|
<div t-foreach="chair_details" t-as="chair_obj" class="col-lg-4 s_title pt16 pb16"> |
||||
|
<div t-if="chair_obj.active_booking_chairs == 1"> |
||||
|
<div style="height: 200px!important; text-align: center; border: 1px solid #666;padding: 15px 0px;box-shadow: 7px 8px 5px #888888;background-color:#7c7bad;border-radius:58px;color:#fff;margin-bottom: 10px;"> |
||||
|
<span style="font-size: 15px;" t-field="chair_obj.name"/> |
||||
|
<br/> |
||||
|
<a style="color:#fff;font-size:15px;">Order Details</a> |
||||
|
<div id="style-2" |
||||
|
style="overflow-y:scroll;height:105px;padding-right:25px;padding-left:25px;margin-right:10px;"> |
||||
|
<table class="table"> |
||||
|
<th style="font-size:11px;">Order No.</th> |
||||
|
<th style="font-size:11px;">Start Time</th> |
||||
|
<th style="font-size:11px;">End Time</th> |
||||
|
<div> |
||||
|
<tbody style="font-size: 10px;"> |
||||
|
<t t-foreach="order_details" t-as="order_obj"> |
||||
|
<t t-if="order_obj.chair_id.id == chair_obj.id"> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<span t-field="order_obj.id"/>. |
||||
|
</td> |
||||
|
<td> |
||||
|
<span t-field="order_obj.start_time_only"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span t-field="order_obj.end_time_only"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
</t> |
||||
|
</tbody> |
||||
|
</div> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
<template id="salon_booking_thank_you" name="Thank you"> |
||||
|
<t t-call="website.layout"> |
||||
|
<form> |
||||
|
<div style="text-align: center;padding: 125px;"> |
||||
|
<h1>Thank you</h1> |
||||
|
</div> |
||||
|
</form> |
||||
|
</t> |
||||
|
</template> |
||||
|
|
||||
|
<template id="assets_frontend" name="salon website assets" inherit_id="web.assets_frontend"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<link rel="stylesheet" |
||||
|
href="/salon_management/static/src/css/salon_website.css"/> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
|
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,59 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="salons_booking_form" model="ir.ui.view"> |
||||
|
<field name="name">salon_booking_form.form</field> |
||||
|
<field name="model">salon.booking</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form> |
||||
|
<header> |
||||
|
<button name="booking_approve" states="draft" string="Approve" class="oe_highlight" type="object"/> |
||||
|
<button name="booking_reject" states="draft" string="Reject" class="oe_highlight" type="object"/> |
||||
|
<field name="state" widget="statusbar" statusbar_visible="draft,approved,rejected"/> |
||||
|
</header> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="name"/> |
||||
|
<field name="phone"/> |
||||
|
<field name="services" widget="many2many_tags"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="time"/> |
||||
|
<field name="email"/> |
||||
|
<field name="chair_id"/> |
||||
|
<field name="lang" invisible="1"/> |
||||
|
<field name="company_id" invisible="1"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<notebook> |
||||
|
<page string="Current Bookings"> |
||||
|
<field name="filtered_orders"/> |
||||
|
</page> |
||||
|
</notebook> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="salons_booking_tree" model="ir.ui.view"> |
||||
|
<field name="name">salon_booking_tree.tree</field> |
||||
|
<field name="model">salon.booking</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree decoration-info="state == 'draft'"> |
||||
|
<field name="name"/> |
||||
|
<field name="time"/> |
||||
|
<field name="phone"/> |
||||
|
<field name="email"/> |
||||
|
<field name="state"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="salon_booking_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Salon Bookings</field> |
||||
|
<field name="res_model">salon.booking</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
<menuitem id="salon_management_bookings" name="Bookings" parent="salon_management_salon" action="salon_booking_action"/> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,8 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<template id="salon_web" inherit_id="website.assets_frontend" name="Website assets"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<script type="text/javascript" src="/salon_management/static/src/js/salon_booking.js"></script> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</odoo> |
@ -0,0 +1,64 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
|
||||
|
<record id="salon_config_settings_view_form" model="ir.ui.view"> |
||||
|
<field name="name">res.config.settings.salon</field> |
||||
|
<field name="model">res.config.settings</field> |
||||
|
<field name="priority" eval="45"/> |
||||
|
<field name="inherit_id" ref="base.res_config_settings_view_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//div[hasclass('settings')]" position="inside"> |
||||
|
<div class="app_settings_block" data-string="Salon" string="Salon" data-key="salon_management"> |
||||
|
|
||||
|
<h2>Booking Chairs(Choose the chair when its free)</h2> |
||||
|
<div class="row mt16 o_settings_container"> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"/> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<div class="content-group"> |
||||
|
<div class="row mt16"> |
||||
|
<label string="Booking Chairs" for="salon_booking_chairs" class="col-md-3 o_light_label"/> |
||||
|
<field name="salon_booking_chairs" widget="many2many_tags"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<h2>Holidays</h2> |
||||
|
<div class="row mt16 o_settings_container"> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"/> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<div class="content-group"> |
||||
|
<div class="row mt16"> |
||||
|
<label string="Holidays" for="salon_holidays" class="col-md-3 o_light_label"/> |
||||
|
<field name="salon_holidays" widget="many2many_tags"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
|
||||
|
<record id="salon_config_settings_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Settings</field> |
||||
|
<field name="type">ir.actions.act_window</field> |
||||
|
<field name="res_model">res.config.settings</field> |
||||
|
<field name="view_mode">form</field> |
||||
|
<field name="target">inline</field> |
||||
|
<field name="context">{'module' : 'salon_management'}</field> |
||||
|
</record> |
||||
|
|
||||
|
<menuitem id="salon_config_settings_menu" parent="salon_management_menu" |
||||
|
name="Configuration"/> |
||||
|
<menuitem id="salon_settings_menu" parent="salon_config_settings_menu" |
||||
|
name="Settings" action="salon_config_settings_action" /> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,61 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="salon_stages_form" model="ir.ui.view"> |
||||
|
<field name="name">salon_stages_form.form</field> |
||||
|
<field name="model">salon.stages</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form> |
||||
|
<sheet> |
||||
|
<h1> |
||||
|
<field name="name"/> |
||||
|
<field name="sequence" invisible="1"/> |
||||
|
</h1> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record model="salon.stages" id="salon_stage_00"> |
||||
|
<field name="name">Draft</field> |
||||
|
<field name="sequence">1</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="salon.stages" id="salon_stage_01"> |
||||
|
<field name="name">Open</field> |
||||
|
<field name="sequence">2</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="salon.stages" id="salon_stage_02"> |
||||
|
<field name="name">Invoiced</field> |
||||
|
<field name="sequence">3</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="salon.stages" id="salon_stage_03"> |
||||
|
<field name="name">Closed</field> |
||||
|
<field name="sequence">4</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="salon.stages" id="salon_stage_04"> |
||||
|
<field name="name">Cancelled</field> |
||||
|
<field name="sequence">5</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="res.partner" id="salon_partner_01"> |
||||
|
<field name="name">Salon Default Customer</field> |
||||
|
<field name="partner_salon">5</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="product.template" id="salon_service_product_01"> |
||||
|
<field name="name">Salon Service</field> |
||||
|
<!-- <field name="partner_salon">1</field>--> |
||||
|
<field name="type">service</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
<data noupdate="1"> |
||||
|
<record model="salon.sequence.updater" id="salon_sequence_updater_01"> |
||||
|
<!-- <field name="name">Salon Sequence Updater</field>--> |
||||
|
<field name="sequence_salon">Chair-1</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,41 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="salon_email_template_approved" model="mail.template"> |
||||
|
<field name="name">Salon e-mail template</field> |
||||
|
<field name="email_from">${object.company_id and object.company_id.email or ''}</field> |
||||
|
<field name="subject">Congratz ${object.name}</field> |
||||
|
<field name="email_to">${object.email|safe}</field> |
||||
|
<field name="lang">${object.lang}</field> |
||||
|
<field name="model_id" ref="salon_management.model_salon_booking"/> |
||||
|
<field name="auto_delete" eval="True"/> |
||||
|
<field name="body_html"> |
||||
|
<![CDATA[ |
||||
|
<p>Dear ${(object.name)},<br/><br/> |
||||
|
Thank you for choosing ${(object.company_id.name)}, your booking was registered!<br/></p> |
||||
|
Regards,<br/> |
||||
|
${(object.company_id.name)} |
||||
|
]]> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="salon_email_template_rejected" model="mail.template"> |
||||
|
<field name="name">Salon e-mail template</field> |
||||
|
<field name="email_from">${object.company_id and object.company_id.email or ''}</field> |
||||
|
<field name="subject">We are Sorry ${object.name}</field> |
||||
|
<field name="email_to">${object.email|safe}</field> |
||||
|
<field name="lang">${object.lang}</field> |
||||
|
<field name="model_id" ref="salon_management.model_salon_booking"/> |
||||
|
<field name="auto_delete" eval="True"/> |
||||
|
<field name="body_html"> |
||||
|
<![CDATA[ |
||||
|
<p>Dear ${(object.name)},<br/><br/> |
||||
|
Thank you for choosing ${(object.company_id.name)}, but your booking was rejected!<br/> |
||||
|
there is no seats available for the time you chosen.<br/> |
||||
|
better luck next time.<br/></p> |
||||
|
Regards,<br/> |
||||
|
${(object.company_id.name)} |
||||
|
]]> |
||||
|
</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,27 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<data noupdate="1"> |
||||
|
<record model="salon.holiday" id="salon_holiday_01"> |
||||
|
<field name="name">Sunday</field> |
||||
|
<field name="holiday">True</field> |
||||
|
</record> |
||||
|
<record model="salon.holiday" id="salon_holiday_02"> |
||||
|
<field name="name">Monday</field> |
||||
|
</record> |
||||
|
<record model="salon.holiday" id="salon_holiday_03"> |
||||
|
<field name="name">Tuesday</field> |
||||
|
</record> |
||||
|
<record model="salon.holiday" id="salon_holiday_04"> |
||||
|
<field name="name">Wednesday</field> |
||||
|
</record> |
||||
|
<record model="salon.holiday" id="salon_holiday_05"> |
||||
|
<field name="name">Thursday</field> |
||||
|
</record> |
||||
|
<record model="salon.holiday" id="salon_holiday_06"> |
||||
|
<field name="name">Friday</field> |
||||
|
</record> |
||||
|
<record model="salon.holiday" id="salon_holiday_07"> |
||||
|
<field name="name">Saturday</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,76 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="sequence_chair" model="ir.sequence"> |
||||
|
<field name="name">Chair Sequence</field> |
||||
|
<field name="code">chair.sequence</field> |
||||
|
<field name="prefix">Chair-</field> |
||||
|
<field name="number_next">2</field> |
||||
|
<field name="number_increment">1</field> |
||||
|
<field name="padding">1</field> |
||||
|
</record> |
||||
|
<record id="salon_chair_form" model="ir.ui.view"> |
||||
|
<field name="name">salon_chair_form.form</field> |
||||
|
<field name="model">salon.chair</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form> |
||||
|
<sheet> |
||||
|
<h1> |
||||
|
<field name="name"/> |
||||
|
</h1> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="user_of_chair"/> |
||||
|
<field name="number_of_orders" invisible="1"/> |
||||
|
<field name="collection_today" invisible="1"/> |
||||
|
<field name="active_booking_chairs" invisible="1"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="date"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<notebook> |
||||
|
<page string="Users"> |
||||
|
<field name="user_line" mode="tree"> |
||||
|
<tree string="Salon User Lines" editable="bottom" delete="false"> |
||||
|
<field name="read_only_checker" invisible="1"/> |
||||
|
<field name="user_id" domain="[('user_salon_active', '=', False)]" |
||||
|
attrs="{'readonly':[ ('read_only_checker', '!=', False)]}"/> |
||||
|
<field name="start_date" |
||||
|
attrs="{'readonly':[ ('read_only_checker', '!=', False)]}"/> |
||||
|
<field name="end_date"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</page> |
||||
|
</notebook> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="salon_chair_tree" model="ir.ui.view"> |
||||
|
<field name="name">salon_chair_tree.tree</field> |
||||
|
<field name="model">salon.chair</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree> |
||||
|
<field name="name"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="salon_dashboard_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Dashboard</field> |
||||
|
<field name="res_model">salon.chair</field> |
||||
|
<field name="view_mode">kanban,form</field> |
||||
|
<field name="context">{}</field> |
||||
|
</record> |
||||
|
<record id="salon_chair_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Chair</field> |
||||
|
<field name="res_model">salon.chair</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
<menuitem id="salon_management_menu" name="Salon" groups="salon_management.group_salon_user"/> |
||||
|
<menuitem id="salon_management_dashboard" parent="salon_management_menu" action="salon_dashboard_action"/> |
||||
|
<menuitem id="salon_management_salon" name="Salon" parent="salon_management_menu"/> |
||||
|
<menuitem id="salon_management_chair" name="Chair" parent="salon_management_salon" action="salon_chair_action"/> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,96 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="salon_management_kanban" model="ir.ui.view" > |
||||
|
<field name="name">salon_management_kanban.dashboard</field> |
||||
|
<field name="model">salon.chair</field> |
||||
|
<field name="type">kanban</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<kanban class="oe_background_grey o_kanban_dashboard o_salon_kanban" create="0"> |
||||
|
<field name="name"/> |
||||
|
<field name="number_of_orders"/> |
||||
|
<field name="active_booking_chairs"/> |
||||
|
<templates> |
||||
|
<t t-name="kanban-box"> |
||||
|
<div> |
||||
|
<div t-if="record.active_booking_chairs.raw_value == false"> |
||||
|
<div class="o_primary style_chair"> |
||||
|
<field name="name"/> |
||||
|
<div> |
||||
|
<button type="edit" string="Settings" class="fa fa-cog button_background"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div t-if="record.active_booking_chairs.raw_value == true"> |
||||
|
<div class="o_primary style_chair_booking"> |
||||
|
<field name="name"/> |
||||
|
<div> |
||||
|
<button type="edit" string="Settings" class="fa fa-cog button_background"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<a href="#" name="%(salon_active_orders_action_dashboard)d" type="action" string="Active Orders"> |
||||
|
<div t-if="record.active_booking_chairs.raw_value == false"> |
||||
|
<div class="o_primary no_of_people"> |
||||
|
<field name="number_of_orders"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div t-if="record.active_booking_chairs.raw_value == true"> |
||||
|
<div class="o_primary no_of_people_booking"> |
||||
|
<field name="number_of_orders"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</a> |
||||
|
<div t-if="record.active_booking_chairs.raw_value == false"> |
||||
|
<div class=" o_primary style_collection"> |
||||
|
<span class=" o_primary style_collection"> |
||||
|
<span class=" o_primary style_collection" style="float: left;">Today's Collection :</span> |
||||
|
<span class=" o_primary style_collection" style="float: center;"> |
||||
|
<field name="collection_today"/> |
||||
|
</span> |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div t-if="record.active_booking_chairs.raw_value == true"> |
||||
|
<div class=" o_primary style_collection_booking"> |
||||
|
<span class=" o_primary style_collection_booking"> |
||||
|
<span class=" o_primary style_collection_booking" style="float: left;">Today's Collection :</span> |
||||
|
<span class=" o_primary style_collection_booking" style="float: center;"> |
||||
|
<field name="collection_today"/> |
||||
|
</span> |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div t-if="record.active_booking_chairs.raw_value == false"> |
||||
|
<div class=" o_primary style_collection"> |
||||
|
<span class=" o_primary style_collection"> |
||||
|
<span class=" o_primary style_collection" style="float: left;">Free After (Hours) :</span> |
||||
|
<span class=" o_primary style_collection" style="float: center;"> |
||||
|
<field name="total_time_taken_chair" widget="float_time"/> |
||||
|
</span> |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div t-if="record.active_booking_chairs.raw_value == true"> |
||||
|
<div class=" o_primary style_collection_booking"> |
||||
|
<span class=" o_primary style_collection_booking"> |
||||
|
<span class=" o_primary style_collection_booking" style="float: center;">Reserved For Booking</span> |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</templates> |
||||
|
</kanban> |
||||
|
</field> |
||||
|
</record> |
||||
|
<template id="assets_backend" name="sales_team assets" inherit_id="web.assets_backend"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<link rel="stylesheet" |
||||
|
href="/salon_management/static/src/less/salon_dashboard.less"/> |
||||
|
<link rel="stylesheet" |
||||
|
href="/salon_management/static/src/css/salon_dashboard.css"/> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,37 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="salon_service_form" model="ir.ui.view"> |
||||
|
<field name="name">salon_service_form.form</field> |
||||
|
<field name="model">salon.service</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<field name="name"/> |
||||
|
<field name="price"/> |
||||
|
<field name="time_taken" widget="float_time"/> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="salon_service_tree" model="ir.ui.view"> |
||||
|
<field name="name">salon_service_tree.tree</field> |
||||
|
<field name="model">salon.service</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree editable="bottom"> |
||||
|
<field name="name"/> |
||||
|
<field name="price"/> |
||||
|
<field name="time_taken" widget="float_time"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="salon_service_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Services</field> |
||||
|
<field name="res_model">salon.service</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
<menuitem id="salon_management_service" parent="salon_management_salon" action="salon_service_action"/> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,224 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="partner_salon_boolean" model="ir.ui.view"> |
||||
|
<field name="name">partner_salon_boolean.view</field> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="inherit_id" ref="base.view_partner_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//field[@name='user_id']" position="after"> |
||||
|
<field name="partner_salon"/> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="sequence_salon_order" model="ir.sequence"> |
||||
|
<field name="name">Salon Order Sequence</field> |
||||
|
<field name="code">salon.order.sequence</field> |
||||
|
<field name="prefix">SALON/%(range_year)s/</field> |
||||
|
<field eval="1" name="number_next"/> |
||||
|
<field eval="1" name="number_increment"/> |
||||
|
<field eval="True" name="use_date_range"/> |
||||
|
<field name="padding">4</field> |
||||
|
</record> |
||||
|
<record id="salon_order_tree" model="ir.ui.view"> |
||||
|
<field name="name">salon_order_tree.tree</field> |
||||
|
<field name="model">salon.order</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree> |
||||
|
<field name="name"/> |
||||
|
<field name="chair_id"/> |
||||
|
<field name="start_time"/> |
||||
|
<field name="end_time"/> |
||||
|
<field name="time_taken_total" widget="float_time"/> |
||||
|
<field name="price_subtotal"/> |
||||
|
<field name="stage_id"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="salon_order_kanban" model="ir.ui.view"> |
||||
|
<field name="name">salon_order_kanban.kanban</field> |
||||
|
<field name="model">salon.order</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<kanban default_group_by="stage_id" class="o_kanban_small_column" quick_create="false" on_create="quick_create"> |
||||
|
<field name="color"/> |
||||
|
<field name="stage_id"/> |
||||
|
|
||||
|
<templates> |
||||
|
<t t-name="kanban-box"> |
||||
|
<div t-attf-class="#{kanban_color(record.color.raw_value)} oe_kanban_global_click"> |
||||
|
|
||||
|
<div class="o_dropdown_kanban dropdown"> |
||||
|
|
||||
|
<a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> |
||||
|
<span class="fa fa-ellipsis-v"/> |
||||
|
</a> |
||||
|
<div class="dropdown-menu" role="menu"> |
||||
|
<t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit...</a></t> |
||||
|
<t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t> |
||||
|
<ul class="oe_kanban_colorpicker" data-field="color"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="oe_kanban_content"> |
||||
|
<div> |
||||
|
<strong><field name="name"/></strong> |
||||
|
</div> |
||||
|
<div class="text-muted"> |
||||
|
<a>Customer :</a> |
||||
|
<field name="customer_name"/> |
||||
|
<div style="float: right;"> |
||||
|
<a>Chair :</a> |
||||
|
<field name="chair_id"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="text-muted"> |
||||
|
<a>Amount :</a> |
||||
|
<field name="price_subtotal"/> |
||||
|
</div> |
||||
|
<div class="text-muted"> |
||||
|
<a>Total time taken :</a> |
||||
|
<field name="time_taken_total" widget="float_time"/> |
||||
|
</div> |
||||
|
<div class="text-muted"> |
||||
|
<a>Date :</a> |
||||
|
<field name="date"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_clear"></div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</templates> |
||||
|
</kanban> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="salon_order_form" model="ir.ui.view"> |
||||
|
<field name="name">salon_order_form.form</field> |
||||
|
<field name="model">salon.order</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form> |
||||
|
<header> |
||||
|
<button name="salon_validate" attrs="{'invisible': ['|',('stage_id', '!=', 1), ('validation_controller', '=', True)]}" string="Validate" type="object" |
||||
|
class="oe_highlight"/> |
||||
|
<button name="salon_confirm" attrs="{'invisible': ['|',('stage_id', '!=', 1), ('validation_controller', '!=', True)]}" string="Confirm" type="object" |
||||
|
class="oe_highlight"/> |
||||
|
<button name="salon_invoice_create" attrs="{'invisible': [('stage_id', '!=', 2)]}" string="Create Invoice" |
||||
|
type="object" class="oe_highlight"/> |
||||
|
<button name="salon_cancel" string="Cancel" attrs="{'invisible': [('stage_id', 'not in', [1,2])]}" type="object"/> |
||||
|
<button name="salon_close" attrs="{'invisible': [('stage_id', '!=', 3)]}" string="Close" type="object"/> |
||||
|
<field name="stage_id" widget="statusbar" domain="[('id','in',[1,2,4])]"/> |
||||
|
</header> |
||||
|
<sheet> |
||||
|
<div class="oe_button_box" name="button_box"> |
||||
|
<button name="action_view_invoice_salon" |
||||
|
type="object" |
||||
|
class="oe_stat_button" |
||||
|
icon="fa-pencil-square-o" |
||||
|
attrs="{'invisible': [('stage_id', 'not in', [3,4])]}"> |
||||
|
<field name="count" widget="statinfo" string="Invoice"/> |
||||
|
</button> |
||||
|
</div> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="partner_id" domain="[('partner_salon','=',True)]" attrs="{'readonly': [('stage_id', '!=', 1)]}"/> |
||||
|
<field name="customer_name" attrs="{'readonly': [('stage_id', '!=', 1)]}"/> |
||||
|
<field name="chair_id" domain="[('active_booking_chairs','!=',True)]" attrs="{'readonly': [('stage_id', '!=', 1)]}"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="booking_identifier" invisible="1"/> |
||||
|
<field name="date" attrs="{'readonly': [('stage_id', '!=', 1)]}"/> |
||||
|
<field name="start_time" attrs="{'readonly': [('stage_id', '!=', 1)], 'invisible': ['|',('stage_id', '!=', 1), ('booking_identifier', '!=', True)]}"/> |
||||
|
<field name="end_time" attrs="{'readonly': [('stage_id', '!=', 1)], 'invisible': ['|',('stage_id', '!=', 1), ('booking_identifier', '!=', True)]}"/> |
||||
|
<field name="start_date_only" invisible="1"/> |
||||
|
<field name="inv_stage_identifier" invisible="1"/> |
||||
|
<field name="invoice_number" invisible="1"/> |
||||
|
<field name="time_taken_total" invisible="1"/> |
||||
|
<field name="validation_controller" invisible="1"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<notebook> |
||||
|
<page string="Order Lines"> |
||||
|
<field name="order_line" mode="tree,kanban" attrs="{'readonly': [('stage_id', '!=', 1)]}"> |
||||
|
<form string="Salon Order Lines"> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="service_id"/> |
||||
|
<field name="time_taken"/> |
||||
|
<field name="price"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</form> |
||||
|
<tree string="Salon Order Lines" editable="bottom"> |
||||
|
<field name="service_id"/> |
||||
|
<field name="time_taken" widget="float_time"/> |
||||
|
<field name="price"/> |
||||
|
<field name="price_subtotal"/> |
||||
|
</tree> |
||||
|
<kanban class="o_kanban_mobile"> |
||||
|
<field name="service_id"/> |
||||
|
<field name="time_taken"/> |
||||
|
<field name="price_subtotal"/> |
||||
|
<templates> |
||||
|
<t t-name="kanban-box"> |
||||
|
<div t-attf-class="oe_kanban_card oe_kanban_global_click"> |
||||
|
<div class="row"> |
||||
|
<div class="col-xs-12"> |
||||
|
<strong> |
||||
|
<span> |
||||
|
<t t-esc="record.service_id.value"/> |
||||
|
</span> |
||||
|
</strong> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-xs-4 text-muted"> |
||||
|
<span class="pull-right text-right"> |
||||
|
<t t-esc="record.time_taken.value"/> |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-xs-4 text-muted"> |
||||
|
<span class="pull-right text-right"> |
||||
|
<t t-esc="record.price_subtotal.value"/> |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</t> |
||||
|
</templates> |
||||
|
</kanban> |
||||
|
</field> |
||||
|
<group class="oe_subtotal_footer oe_right" colspan="2" name="salon_total"> |
||||
|
<div class="oe_subtotal_footer_separator oe_inline o_td_label"> |
||||
|
<label for="price_subtotal"/> |
||||
|
<button name="button_total_update" string="(update)" type="object" |
||||
|
class="oe_edit_only oe_link"/> |
||||
|
</div> |
||||
|
<field name="price_subtotal" nolabel="1" class="oe_subtotal_footer_separator"/> |
||||
|
</group> |
||||
|
<field name="note" class="oe_inline" |
||||
|
placeholder="Setup default terms and conditions in your company settings."/> |
||||
|
<div class="oe_clear"/> |
||||
|
</page> |
||||
|
</notebook> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="salon_order_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Salon</field><!-- <field name="view_type">form</field>--> |
||||
|
|
||||
|
<field name="res_model">salon.order</field> |
||||
|
<field name="view_mode">kanban,tree,form</field> |
||||
|
</record> |
||||
|
<record id="salon_active_orders_action_dashboard" model="ir.actions.act_window"> |
||||
|
<field name="name">Salon Orders</field> |
||||
|
<field name="res_model">salon.order</field> |
||||
|
<field name="view_mode">kanban,tree,form</field> |
||||
|
<field name="domain">[('chair_id', '=', active_id)]</field> |
||||
|
</record> |
||||
|
<menuitem id="salon_order" parent="salon_management_salon" name="Salon Orders" action="salon_order_action"/> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,72 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
|
||||
|
<data> |
||||
|
<record id="salon_working_form" model="ir.ui.view"> |
||||
|
<field name="name">salon_working_form.form</field> |
||||
|
<field name="model">salon.working.hours</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form> |
||||
|
<sheet> |
||||
|
<h1> |
||||
|
<field name="name"/> |
||||
|
</h1> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="from_time" widget="float_time"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="to_time" widget="float_time"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="salon_working_tree" model="ir.ui.view"> |
||||
|
<field name="name">salon_working_tree.tree</field> |
||||
|
<field name="model">salon.working.hours</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree editable="bottom"> |
||||
|
<field name="name"/> |
||||
|
<field name="from_time" widget="float_time"/> |
||||
|
<field name="to_time" widget="float_time"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
|
||||
|
<record id="salon_config_working_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Working Hours</field> |
||||
|
<field name="res_model">salon.working.hours</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
<menuitem id="salon_working_hours_menu" parent="salon_config_settings_menu" |
||||
|
name="Working Hours" action="salon_config_working_action" /> |
||||
|
|
||||
|
|
||||
|
<data noupdate="1"> |
||||
|
<record model="salon.working.hours" id="salon_working_01"> |
||||
|
<field name="name">Sunday</field> |
||||
|
</record> |
||||
|
<record model="salon.working.hours" id="salon_working_02"> |
||||
|
<field name="name">Monday</field> |
||||
|
</record> |
||||
|
<record model="salon.working.hours" id="salon_working_03"> |
||||
|
<field name="name">Tuesday</field> |
||||
|
</record> |
||||
|
<record model="salon.working.hours" id="salon_working_04"> |
||||
|
<field name="name">Wednesday</field> |
||||
|
</record> |
||||
|
<record model="salon.working.hours" id="salon_working_05"> |
||||
|
<field name="name">Thursday</field> |
||||
|
</record> |
||||
|
<record model="salon.working.hours" id="salon_working_06"> |
||||
|
<field name="name">Friday</field> |
||||
|
</record> |
||||
|
<record model="salon.working.hours" id="salon_working_07"> |
||||
|
<field name="name">Saturday</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</odoo> |