@ -0,0 +1,21 @@ |
|||
Beauty Spa Management v11 |
|||
========================= |
|||
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. |
|||
|
|||
Features |
|||
======== |
|||
* Online Booking Facility. |
|||
* Accounting Facility. |
|||
* Customer Notification Through Mail. |
|||
* User Interactive Dashboard |
|||
* Customer Can view the Available chairs and order details |
|||
* Different access levels for Users and Administrator |
|||
* Track the chair user by date. |
|||
|
|||
|
|||
Credits |
|||
======= |
|||
Developer : Avinash N K |
|||
|
@ -0,0 +1,25 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2018-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 models |
|||
from . import controllers |
@ -0,0 +1,55 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2018-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/>. |
|||
# |
|||
################################################################################### |
|||
{ |
|||
'name': 'Beauty Spa Management', |
|||
'summary': """Beauty Parlour Management with Online Booking System""", |
|||
'version': '11.0.1.0.0', |
|||
'author': 'Cybrosys Techno Solutions', |
|||
'website': "http://www.cybrosys.com", |
|||
'company': 'Cybrosys Techno Solutions', |
|||
"category": "Industries", |
|||
'depends': ['base', 'account_invoicing', 'mail', 'website'], |
|||
'data': ['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', |
|||
'security/ir.model.access.csv', |
|||
], |
|||
'demo': [ |
|||
'views/booking_demo.xml', |
|||
], |
|||
'images': ['static/description/banner.jpg'], |
|||
'license': 'AGPL-3', |
|||
'installable': True, |
|||
'application': True, |
|||
} |
@ -0,0 +1,24 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2018-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,89 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2018-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_info = kwargs.get('check_date') |
|||
return date_info |
|||
|
|||
@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() |
|||
if 'x' in post.keys(): |
|||
date_check = post['x'] |
|||
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])]) |
|||
date_check = str(date_check) |
|||
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,11 @@ |
|||
<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> |
|||
<field name="website_id" ref="website.default_website"/> |
|||
</record> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,17 @@ |
|||
<?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="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,27 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2018-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 salon_management |
|||
from . import salon_booking |
|||
from . import salon_config |
|||
|
@ -0,0 +1,85 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2018-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") |
|||
|
|||
@api.multi |
|||
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" |
|||
|
|||
@api.multi |
|||
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,76 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2018-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) |
|||
|
|||
@api.multi |
|||
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,417 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2018-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) |
|||
|
|||
@api.multi |
|||
def write(self, values): |
|||
if 'user_line' in values.keys(): |
|||
if values['user_line']: |
|||
date_changer = [] |
|||
for elements in values['user_line']: |
|||
if elements[1] is False: |
|||
date_changer.append(elements[2]['start_date']) |
|||
number = 0 |
|||
num = 0 |
|||
for records in self.user_line: |
|||
if records.end_date is False: |
|||
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, val, uid, context=None): |
|||
salon_chair = self.pool.get('salon.chair') |
|||
for values in self.search(val, uid, []): |
|||
chair_obj = salon_chair.browse(val, uid, values, context=context) |
|||
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 = 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=date.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(self.start_time, "%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 = 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=date.today(), required=True) |
|||
end_time = fields.Datetime(string="End time") |
|||
date = fields.Datetime(string="Date", required=True, default=date.today()) |
|||
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) |
|||
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 = self.start_time |
|||
salon_start_time_date = salon_start_time[0:10] |
|||
self.write({'start_date_only': salon_start_time_date}) |
|||
|
|||
@api.multi |
|||
def action_view_invoice_salon(self): |
|||
imd = self.env['ir.model.data'] |
|||
action = imd.xmlid_to_object('account.action_invoice_tree1') |
|||
list_view_id = imd.xmlid_to_res_id('account.invoice_tree') |
|||
form_view_id = imd.xmlid_to_res_id('account.invoice_form') |
|||
result = { |
|||
'name': action.name, |
|||
'help': action.help, |
|||
'type': action.type, |
|||
'views': [[form_view_id, 'form'], [list_view_id, 'tree'], [False, 'graph'], [False, 'kanban'], |
|||
[False, 'calendar'], [False, 'pivot']], |
|||
'target': action.target, |
|||
'context': action.context, |
|||
'res_model': action.res_model, |
|||
'res_id': self.invoice_number, |
|||
} |
|||
return result |
|||
|
|||
@api.multi |
|||
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) |
|||
|
|||
@api.multi |
|||
def salon_confirm(self): |
|||
sequence_code = 'salon.order.sequence' |
|||
order_date = 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 |
|||
|
|||
@api.multi |
|||
def salon_validate(self): |
|||
self.validation_controller = True |
|||
|
|||
@api.multi |
|||
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) |
|||
|
|||
@api.multi |
|||
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) |
|||
|
|||
@api.multi |
|||
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'] |
|||
|
|||
@api.multi |
|||
def salon_invoice_create(self): |
|||
inv_obj = self.env['account.invoice'] |
|||
inv_line_obj = self.env['account.invoice.line'] |
|||
if self.partner_id: |
|||
supplier = self.partner_id |
|||
else: |
|||
supplier = self.partner_id.search([("name", "=", "Salon Default Customer")]) |
|||
company_id = self.env['res.users'].browse(1).company_id |
|||
currency_salon = company_id.currency_id.id |
|||
|
|||
inv_data = { |
|||
'name': supplier.name, |
|||
'reference': supplier.name, |
|||
'account_id': supplier.property_account_payable_id.id, |
|||
'partner_id': supplier.id, |
|||
'currency_id': currency_salon, |
|||
'journal_id': 1, |
|||
'origin': self.name, |
|||
'company_id': company_id.id, |
|||
} |
|||
inv_id = inv_obj.create(inv_data) |
|||
self.invoice_number = inv_id |
|||
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)) |
|||
inv_line_data = { |
|||
'name': records.service_id.name, |
|||
'account_id': income_account, |
|||
'price_unit': records.price, |
|||
'quantity': 1, |
|||
'product_id': product_id.id, |
|||
'invoice_id': inv_id.id, |
|||
} |
|||
inv_line_obj.create(inv_line_data) |
|||
|
|||
imd = self.env['ir.model.data'] |
|||
action = imd.xmlid_to_object('account.action_invoice_tree1') |
|||
list_view_id = imd.xmlid_to_res_id('account.invoice_tree') |
|||
form_view_id = imd.xmlid_to_res_id('account.invoice_form') |
|||
|
|||
result = { |
|||
'name': action.name, |
|||
'help': action.help, |
|||
'type': 'ir.actions.act_window', |
|||
'views': [[list_view_id, 'tree'], [form_view_id, 'form'], [False, 'graph'], [False, 'kanban'], |
|||
[False, 'calendar'], [False, 'pivot']], |
|||
'target': action.target, |
|||
'context': action.context, |
|||
'res_model': 'account.invoice', |
|||
} |
|||
if len(inv_id) > 1: |
|||
result['domain'] = "[('id','in',%s)]" % inv_id.ids |
|||
elif len(inv_id) == 1: |
|||
result['views'] = [(form_view_id, 'form')] |
|||
result['res_id'] = inv_id.ids[0] |
|||
else: |
|||
result = {'type': 'ir.actions.act_window_close'} |
|||
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 = 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 |
|||
|
|||
@api.multi |
|||
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' |
|||
|
|||
name = fields.Char(string="Name", required=True, translate=True) |
|
After Width: | Height: | Size: 107 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 108 KiB |
After Width: | Height: | Size: 53 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 123 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,395 @@ |
|||
|
|||
<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> |
|||
</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'> |
|||
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. |
|||
</p> |
|||
<p > |
|||
Another advantage of having this Spa management system is your customers |
|||
who have done the online booking will get the booking information via email. |
|||
By using an app like this, you can enhance 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;"> |
|||
<i class="fa fa-check" aria-hidden="true" style="color: #cd2d47;font-size: 15px;"></i> |
|||
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;"> |
|||
<i class="fa fa-check" aria-hidden="true" style="color: #cd2d47;font-size: 15px;"></i> |
|||
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;"> |
|||
<i class="fa fa-check" aria-hidden="true" style="color: #cd2d47;font-size: 15px;"></i> |
|||
Customer Notification Through Mail.. |
|||
</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;"> |
|||
<i class="fa fa-check" aria-hidden="true" style="color: #cd2d47;font-size: 15px;"></i> |
|||
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;"> |
|||
<i class="fa fa-check" aria-hidden="true" style="color: #cd2d47;font-size: 15px;"></i> |
|||
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;"> |
|||
<i class="fa fa-check" aria-hidden="true" style="color: #cd2d47;font-size: 15px;"></i> |
|||
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;"> |
|||
<i class="fa fa-check" aria-hidden="true" style="color: #cd2d47;font-size: 15px;"></i> |
|||
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 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;"> |
|||
Dashboard |
|||
</h2> |
|||
<br> |
|||
<icon> Dashboard view is shown in the below image. Your customers can book the service in two ways, direct booking and online booking. The chairs with Black font's are the only ones available for online booking and the White ones for direct booking. |
|||
|
|||
In Dashboard, you get the daily collection of that chair and when that chair will be free, in case if that chair is currently in use. Also you can see the active orders of that chair and if you click on it, that will directly take you to the active orders of that chair. |
|||
|
|||
If you want to change the settings of chair, you 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 o_animate o_animate_in_children o_animate_offset_min" 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 o_animate o_animate_in_children o_animate_offset_min"> |
|||
<img src="2.png" alt="" style="width: 95%;"/> |
|||
</div> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" 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 o_animate o_animate_in_children o_animate_offset_min"> |
|||
<img src="3.png" alt="" style="width: 95%;"/> |
|||
</div> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" 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 o_animate o_animate_in_children o_animate_offset_min"> |
|||
<img src="4.png" alt="" style="width: 95%;"/> |
|||
</div> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" 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 o_animate o_animate_in_children o_animate_offset_min"> |
|||
<img src="5.png" alt="" style="width: 95%;"/> |
|||
</div> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" 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 o_animate o_animate_in_children o_animate_offset_min"> |
|||
<img src="6.png" alt="" style="width: 95%;"/> |
|||
</div> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" 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 o_animate o_animate_in_children o_animate_offset_min"> |
|||
<img src="7.png" alt="" style="width: 95%;"/> |
|||
</div> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" 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 o_animate o_animate_in_children o_animate_offset_min"> |
|||
<img src="8.png" alt="" style="width: 95%;"/> |
|||
</div> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
|||
|
|||
</h2> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" 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 o_animate o_animate_in_children o_animate_offset_min"> |
|||
<img src="9.png" alt="" style="width: 95%;"/> |
|||
</div> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
|||
|
|||
</h2> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" 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 o_animate o_animate_in_children o_animate_offset_min"> |
|||
<img src="10.png" alt="" style="width: 95%;"/> |
|||
</div> |
|||
<h2 class="oe_slogan o_animate o_animate_in_children o_animate_offset_min" style="text-align: left;font-size: 28px;font-weight: 600;margin: 0px !important;"> |
|||
</h2> |
|||
</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 Service |
|||
</h2> |
|||
<div style="display:flex;padding-top: 20px;justify-content: space-between;"> |
|||
<div style="flex-basis: 18%;"> |
|||
<a href="https://www.cybrosys.com/odoo-customization-and-installation/" target="_blank"> |
|||
<div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-customization.png" style="width: 100%;border-radius: 100%;"/> |
|||
</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;"> |
|||
Odoo <br/>Customization |
|||
</h3> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 18%;"> |
|||
<a href="https://www.cybrosys.com/odoo-erp-implementation/" target="_blank"> |
|||
<div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-erp-implementation.png" style="width: 100%;border-radius: 100%;"/> |
|||
</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;"> |
|||
Odoo <br/>Implementation |
|||
</h3> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 18%;"> |
|||
<a href="https://www.cybrosys.com/odoo-erp-integration/" target="_blank"> |
|||
<div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-erp-integration.png" style="width: 100%;border-radius: 100%;"/> |
|||
</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;"> |
|||
Odoo <br/>Integration |
|||
</h3> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 18%;"> |
|||
<a href="https://www.cybrosys.com/odoo-erp-support/" target="_blank"> |
|||
<div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-erp-support.png" style="width: 100%;border-radius: 100%;"/> |
|||
</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;"> |
|||
Odoo <br/>Support |
|||
</h3> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 18%;"> |
|||
<a href="https://www.cybrosys.com/hire-odoo-developer/" target="_blank"> |
|||
<div style="width:75px;height:75px;background:#fff; border-radius:100%;margin: auto;"> |
|||
<img src="https://www.cybrosys.com/images/hire-odoo-developer.png" style="width: 100%;border-radius: 100%;"/> |
|||
</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;"> |
|||
Hire <br/>Odoo Developer |
|||
</h3> |
|||
</a> |
|||
</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;"> |
|||
<a href="https://www.cybrosys.com/odoo/industries/best-trading-erp/" target="_blank"> |
|||
<div style="width:30%; float:left;"> |
|||
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-index-industry-1.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
|||
</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;"> |
|||
Trading |
|||
</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> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 32%;padding-top: 20px;"> |
|||
<a href="https://www.cybrosys.com/odoo/industries/manufacturing-erp-software/" target="_blank"> |
|||
<div style="width:30%; float:left;"> |
|||
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-index-industry-2.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
|||
</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;"> |
|||
Manufacturing |
|||
</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> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 32%;padding-top: 20px;"> |
|||
<a href="https://www.cybrosys.com/odoo/industries/restaurant-management/" target="_blank"> |
|||
<div style="width:30%; float:left;"> |
|||
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-index-industry-3.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
|||
</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;"> |
|||
Restaurant |
|||
</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> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 32%;padding-top: 20px;"> |
|||
<a href="https://www.cybrosys.com/odoo/industries/pos/" target="_blank"> |
|||
<div style="width:30%; float:left;"> |
|||
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-index-industry-4.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
|||
|
|||
</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;"> |
|||
POS |
|||
</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> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 32%;padding-top: 20px;"> |
|||
<a href="https://www.cybrosys.com/odoo/industries/ecommerce-website/" target="_blank"> |
|||
<div style="width:30%; float:left;"> |
|||
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-index-industry-5.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
|||
|
|||
</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;"> |
|||
E-commerce & Website |
|||
</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> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 32%;padding-top: 20px;"> |
|||
<a href="https://www.cybrosys.com/odoo/industries/hotel-management-erp/" target="_blank"> |
|||
<div style="width:30%; float:left;"> |
|||
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-index-industry-9.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
|||
|
|||
</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;"> |
|||
Hotel Management |
|||
</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> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 32%;padding-top: 20px;"> |
|||
<a href="https://www.cybrosys.com/odoo/industries/education-erp-software/" target="_blank"> |
|||
<div style="width:30%; float:left;"> |
|||
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-index-industry-7.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
|||
|
|||
</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;"> |
|||
Education |
|||
</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> |
|||
</a> |
|||
</div> |
|||
<div style="flex-basis: 32%;padding-top: 20px;"> |
|||
<a href="https://www.cybrosys.com/odoo/industries/service-management/" target="_blank"> |
|||
<div style="width:30%; float:left;"> |
|||
<div style="width:75px;height:75px;background:#CE2D48; border-radius:100%;float: left;text-align: left;"> |
|||
<img src="https://www.cybrosys.com/images/odoo-index-industry-8.png" alt="Odoo Industry" style=" border-radius: 100%;width:100%;"/> |
|||
|
|||
</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;"> |
|||
Service Management |
|||
</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> |
|||
</a> |
|||
</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,65 @@ |
|||
.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; |
|||
} |
|||
.chair_box_website{ |
|||
text-align: center; |
|||
border: 1px solid #666; |
|||
padding: 10px 15px; |
|||
box-shadow: 7px 8px 5px #888888; |
|||
background-color: #337ab7; |
|||
color: #000000; |
|||
} |
@ -0,0 +1,74 @@ |
|||
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; |
|||
$(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 = $( "#service" ).val(); |
|||
var chair = $( "#chair" ).val(); |
|||
var list_service = []; |
|||
var number = service.length |
|||
for (var i=0; i<(service.length); i++){ |
|||
var k = {i : service[i]} |
|||
list_service.push(k) |
|||
} |
|||
var time_left_char = time.substring(0, 2) |
|||
var time_right_char = time.substring(3, 5) |
|||
var time_separator = time.substring(2,3) |
|||
if(date != ""){ |
|||
if (isNaN(time_left_char) || isNaN(time_right_char) || time_separator != ":"){ |
|||
if(time != ""){ |
|||
alert("Select a valid Time") |
|||
} |
|||
} |
|||
else{ |
|||
var time_left = parseInt(time_left_char) |
|||
var time_right = parseInt(time_right_char) |
|||
if ((time_left < 24) && (time_right < 60) && (time_left >= 0) && (time_right >= 0)){ |
|||
if (name != "" && phone != "" && email != "" && service != "" && chair != ""){ |
|||
var booking_record = {'name': name, 'date': date, 'time': time, 'phone': phone, |
|||
'email': email, service, 'list_service':list_service,'chair': chair,'number': number } |
|||
$.ajax({ |
|||
url: "/page/salon_details", |
|||
method: "POST", |
|||
dataType: "json", |
|||
data: booking_record, |
|||
success: function( data ) { |
|||
window.location.href = "/page/salon_management.salon_booking_thank_you"; |
|||
}, |
|||
error: function (error) { |
|||
alert('error: ' + error); |
|||
} |
|||
}); |
|||
} |
|||
else{ |
|||
alert("Fill all the required fields") |
|||
} |
|||
} |
|||
else { |
|||
alert("Select a valid time") |
|||
} |
|||
} |
|||
} |
|||
}); |
|||
$(document).on('click',"#check_button",function() { |
|||
var check_date = $( "#check_date" ).val(); |
|||
if (check_date != "") |
|||
{ |
|||
var salon_check_date = ajax.jsonRpc("/page/salon_check_date", 'call', {'check_date':check_date }) |
|||
.then(function(date_info){ |
|||
window.location= "/page/salon_management.salon_booking_form?x=" + date_info |
|||
}) |
|||
} |
|||
else |
|||
{ |
|||
alert("Fill the Field") |
|||
} |
|||
}); |
|||
}); |
@ -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: 166px; |
|||
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,273 @@ |
|||
<?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> |
|||
<div style="width:215px;margin-top:10px;margin-left:10px;float:left;"> |
|||
<p style="text-align:center;font-size:24px;"> |
|||
Working Time |
|||
</p> |
|||
<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 style="float:left;width:940px;"> |
|||
<section id="chair_details"> |
|||
<div class="container"> |
|||
<h3 style="text-align:center;">Available Chairs and Details</h3> |
|||
<hr/> |
|||
<div class="form-group form-field o_website_form_required_custom"> |
|||
<div class="col-md-12" style="margin-bottom:10px;"> |
|||
<label class="col-md-1 col-sm-4 control-label" |
|||
style="padding-top: 8px; padding-right:0px !important" for="search">TIME |
|||
</label> |
|||
<div class="col-md-2 col-sm-4" style="padding-left: 0px;"> |
|||
<input style="padding-right:0px;" id="check_date" type="text" |
|||
class="search-query form-control oe_search_box" required="" |
|||
placeholder="Select a date"/> |
|||
</div> |
|||
<div class="col-sm-2 col-md-1" style="padding-left: 0px;"> |
|||
<button type="submit" id="check_button" |
|||
class="btn btn-primary btn-md o_website_form_send">Check |
|||
</button> |
|||
<span id="o_website_form_result"></span> |
|||
</div> |
|||
<div class="col-sm-3 col-md-3" style="padding-left: 33px;"> |
|||
<h5 style="text-align:left; float:left; margin-top: 4px;font-weight: 600;">DATE : |
|||
</h5> |
|||
<h5 style="float:left; margin-top: 4px;font-weight: 600;"> |
|||
<t t-esc="date_search"/> |
|||
</h5> |
|||
</div> |
|||
<div class="col-sm-3 col-md-5" style="padding-left: 0px;"> |
|||
<h5 style="text-align:left; float:left; margin-top: 4px;font-weight: 600; padding-right:6px;"> |
|||
HOLIDAYS : |
|||
</h5> |
|||
<div t-foreach="holiday" t-as="holiday_obj"> |
|||
<h5 t-field="holiday_obj.name" style="float:left;margin-top: 4px;font-weight: 600; "/> |
|||
<h5 style="float:left;font-weight: 600;">&nbsp;</h5> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="col-md-12"> |
|||
<div t-foreach="chair_details" t-as="chair_obj"> |
|||
<div class="col-md-4" 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> |
|||
<style> |
|||
#style-2::-webkit-scrollbar-track |
|||
{ |
|||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); |
|||
border-radius: 10px; |
|||
background-color: #7c7bad; |
|||
width:8px !important; |
|||
} |
|||
|
|||
#style-2::-webkit-scrollbar |
|||
{ |
|||
width: 12px; |
|||
background-color: #7c7bad; |
|||
width:8px !important; |
|||
height: 115px; |
|||
} |
|||
|
|||
#style-2::-webkit-scrollbar-thumb |
|||
{ |
|||
border-radius: 10px; |
|||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); |
|||
background-color: #7c7bad; |
|||
width:8px !important; |
|||
} |
|||
</style> |
|||
<div id="style-2" |
|||
style="overflow:overlay;height:115px;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> |
|||
</div> |
|||
<div style="margin-bottom:100px;float:left;"> |
|||
<h1 style="text-align:center;padding-bottom: 26px;padding-top: 20px;">Book Your Chair</h1> |
|||
|
|||
<form> |
|||
<div class="form-group form-field o_website_form_required_custom"> |
|||
<div class="col-md-12" style="margin-bottom:10px;"> |
|||
<label class="col-md-offset-1 col-md-1 col-sm-4 control-label" style="padding-top: 8px;" |
|||
for="search">NAME* |
|||
</label> |
|||
<div class="col-md-5 col-sm-8"> |
|||
<input type="text" id="name" class="search-query form-control oe_search_box" |
|||
required="True" placeholder="Enter your Name"/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="form-group form-field o_website_form_required_custom"> |
|||
<div class="col-md-12" style="margin-bottom:10px;"> |
|||
<label class="col-md-offset-1 col-md-1 col-sm-4 control-label" style="padding-top: 8px;" |
|||
for="search">SERVICE* |
|||
</label> |
|||
<div class="col-md-5 col-sm-8"> |
|||
<select multiple="multiple" id="service" required="True" class="form-control" |
|||
style="width: 432px; height: 40px;"> |
|||
<t t-foreach="salon_services" t-as="service"> |
|||
<option t-att-value="service.id" t-esc="service.name"/> |
|||
</t> |
|||
</select> |
|||
</div> |
|||
<div class="col-md-5" style="padding-left:0px !important;"> |
|||
<p style="font-size: 16px;">( You can select multiple services or Remove a selection by |
|||
pressing down on the Ctrl button ) |
|||
</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="form-group form-field o_website_form_required_custom"> |
|||
<div class="col-md-12" style="margin-bottom:10px;"> |
|||
<label class="col-md-offset-1 col-md-1 col-sm-4 control-label" style="padding-top: 8px;" |
|||
for="search">TIME* |
|||
</label> |
|||
<div class="col-md-5 col-sm-8"> |
|||
<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" |
|||
style="width: 250px;height: 35px;"/> |
|||
<input type="text" id="time" placeholder="HH:MM" |
|||
onkeyup="var v = this.value;if (v.match(/^\d{2}$/) !== null) {this.value = v + ':';}" |
|||
maxlength="5" |
|||
style="width: 178px;height: 35px;"/> |
|||
</div> |
|||
<div class="col-md-5" style="padding-left:0px !important;"> |
|||
<p style="font-size: 16px;padding-top: 9px;">( Select a date and time based on the |
|||
availability of the chair ) |
|||
</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="form-group form-field o_website_form_required_custom"> |
|||
<div class="col-md-12" style="margin-bottom:10px;"> |
|||
<label class="col-md-offset-1 col-md-1 col-sm-4 control-label" style="padding-top: 8px;" |
|||
for="search">CHAIR* |
|||
</label> |
|||
<div class="col-md-5 col-sm-8"> |
|||
<select id="chair" required="True" class="form-control" |
|||
style="width: 432px; height: 35px;"> |
|||
<t t-foreach="chair_details" t-as="chair"> |
|||
<option t-att-value="chair.id" t-esc="chair.name"/> |
|||
</t> |
|||
</select> |
|||
</div> |
|||
<div class="col-md-5" style="padding-left:0px !important;"> |
|||
<p style="font-size: 16px;padding-top: 9px;">( Select the chair that free in the |
|||
preferred time ) |
|||
</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="form-group form-field o_website_form_required_custom"> |
|||
<div class="col-md-12" style="margin-bottom:10px;"> |
|||
<label class="col-md-offset-1 col-md-1 col-sm-4 control-label" style="padding-top: 8px;" |
|||
for="search">PHONE* |
|||
</label> |
|||
<div class="col-md-5 col-sm-8"> |
|||
<input type="text" id="phone" class="search-query form-control oe_search_box" |
|||
required="True" placeholder="Enter your Phone number(eg:999**12345)"/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="form-group form-field o_website_form_required_custom"> |
|||
<div class="col-md-12" style="margin-bottom:10px;"> |
|||
<label class="col-md-offset-1 col-md-1 col-sm-4 control-label" style="padding-top: 8px;" |
|||
for="search">E-MAIL* |
|||
</label> |
|||
<div class="col-md-5 col-sm-8"> |
|||
<input type="email" id="email" class="search-query form-control oe_search_box" |
|||
required="True" |
|||
placeholder="Enter your E-Mail Address(eg:avinashnk94@gmail.com)"/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="form-group"> |
|||
<div class="col-md-12"> |
|||
<div class="col-md-offset-1 col-md-1 col-sm-4"></div> |
|||
<div class="col-sm-8 col-md-5"> |
|||
<button type="button" id="submit_button" |
|||
class="btn btn-primary btn-md o_website_form_send">Send |
|||
</button> |
|||
<span id="o_website_form_result"></span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
|
|||
|
|||
|
|||
</div> |
|||
|
|||
|
|||
|
|||
</t> |
|||
</template> |
|||
<template id="salon_booking_thank_you" name="Thank you"> |
|||
<t t-call="website.layout"> |
|||
<form> |
|||
<div class="form-group" style="text-align: center; padding-top: 11%; padding-bottom: 10%;"> |
|||
<h1>Thank you</h1> |
|||
</div> |
|||
</form> |
|||
</t> |
|||
</template> |
|||
</odoo> |
@ -0,0 +1,60 @@ |
|||
<?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 colors="#046a8c:state=='draft';#f20b07:state=='rejected';#01471f:state=='approved'"> |
|||
<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_type">form</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,11 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
|
|||
<record id="website_menu_salon_booking_demo" model="website.menu"> |
|||
<field name="name">Bookings</field> |
|||
<field name="url">/page/salon_management.salon_booking_form</field> |
|||
<field name="parent_id" ref="website.website2_main_menu"/> |
|||
<field name="sequence" type="int">80</field> |
|||
<field name="website_id" ref="website.website2"/> |
|||
</record> |
|||
</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" 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" 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" |
|||
string="Settings" action="salon_config_settings_action" /> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,55 @@ |
|||
<?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"/> |
|||
</h1> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<record model="salon.stages" id="salon_stage_00"> |
|||
<field name="name">Draft</field> |
|||
</record> |
|||
|
|||
<record model="salon.stages" id="salon_stage_01"> |
|||
<field name="name">Open</field> |
|||
</record> |
|||
|
|||
<record model="salon.stages" id="salon_stage_02"> |
|||
<field name="name">Invoiced</field> |
|||
</record> |
|||
|
|||
<record model="salon.stages" id="salon_stage_03"> |
|||
<field name="name">Closed</field> |
|||
</record> |
|||
|
|||
<record model="salon.stages" id="salon_stage_04"> |
|||
<field name="name">Cancelled</field> |
|||
</record> |
|||
|
|||
<record model="res.partner" id="salon_partner_01"> |
|||
<field name="name">Salon Default Customer</field> |
|||
<field name="partner_salon">1</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,78 @@ |
|||
<?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_type">form</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_type">form</field> |
|||
<field name="view_mode">tree,form</field> |
|||
</record> |
|||
<menuitem id="salon_management_menu" name="Salon"/> |
|||
<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="button_background" > <i class="fa fa-cog"/></button> |
|||
</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="button_background" > <i class="fa fa-cog"/></button> |
|||
</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,38 @@ |
|||
<?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> |
|||
<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_type">form</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,221 @@ |
|||
<?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='customer']" 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"> |
|||
<field name="color"/> |
|||
<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 class="dropdown-toggle btn" data-toggle="dropdown" href="#" > |
|||
<span class="fa fa-bars fa-lg"/> |
|||
</a> |
|||
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel"> |
|||
<t t-if="widget.editable"><li><a type="edit">Edit</a></li></t> |
|||
<t t-if="widget.deletable"><li><a type="delete">Delete</a></li></t> |
|||
<li> |
|||
<ul class="oe_kanban_colorpicker" data-field="color"/> |
|||
</li> |
|||
</ul> |
|||
</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])]}" |
|||
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="res_model">salon.order</field> |
|||
<field name="view_type">form</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_type">form</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,68 @@ |
|||
<?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_type">form</field> |
|||
<field name="view_mode">tree,form</field> |
|||
</record> |
|||
<menuitem id="salon_working_hours_menu" parent="salon_config_settings_menu" |
|||
string="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> |