| @ -0,0 +1,24 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ############################################################################## | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| #    Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Avinash Nk(<https://www.cybrosys.com>) | |||
| #    you can modify it under the terms of the GNU LESSER | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3), Version 3. | |||
| # | |||
| #    It is forbidden to publish, distribute, sublicense, or sell copies | |||
| #    of the Software or modified copies of the Software. | |||
| # | |||
| #    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | |||
| # | |||
| #    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3) along with this program. | |||
| #    If not, see <http://www.gnu.org/licenses/>. | |||
| # | |||
| ############################################################################## | |||
| import models | |||
| import controllers | |||
| @ -0,0 +1,52 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ############################################################################## | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| #    Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Avinash Nk(<https://www.cybrosys.com>) | |||
| #    you can modify it under the terms of the GNU LESSER | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3), Version 3. | |||
| # | |||
| #    It is forbidden to publish, distribute, sublicense, or sell copies | |||
| #    of the Software or modified copies of the Software. | |||
| # | |||
| #    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | |||
| # | |||
| #    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3) along with this program. | |||
| #    If not, see <http://www.gnu.org/licenses/>. | |||
| # | |||
| ############################################################################## | |||
| { | |||
|     'name': 'Beauty Spa Management', | |||
|     'summary': """Beauty Parlour Management with Online Booking System""", | |||
|     'version': '10.0.1.0.0', | |||
|     'author': 'Cybrosys Techno Solutions', | |||
|     'website': "http://www.cybrosys.com", | |||
|     'company': 'Cybrosys Techno Solutions', | |||
|     "category": "Industries", | |||
|     'depends': ['base', 'account', 'mail', 'website'], | |||
|     'data': ['views/salon_holiday.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_bookings.xml', | |||
|              'views/salon_email_template.xml', | |||
|              'views/salon_config.xml', | |||
|              'views/working_hours.xml', | |||
|              'security/ir.model.access.csv', | |||
|              ], | |||
|     'demo': [ | |||
|         'views/booking_demo.xml', | |||
|     ], | |||
|     'images': ['static/description/banner.jpg'], | |||
|     'license': 'LGPL-3', | |||
|     'installable': True, | |||
|     'application': True, | |||
| } | |||
| @ -0,0 +1,23 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ############################################################################## | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| #    Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Avinash Nk(<http://www.cybrosys.com>) | |||
| #    you can modify it under the terms of the GNU LESSER | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3), Version 3. | |||
| # | |||
| #    It is forbidden to publish, distribute, sublicense, or sell copies | |||
| #    of the Software or modified copies of the Software. | |||
| # | |||
| #    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | |||
| # | |||
| #    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3) along with this program. | |||
| #    If not, see <http://www.gnu.org/licenses/>. | |||
| # | |||
| ############################################################################## | |||
| import main | |||
| @ -0,0 +1,88 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ############################################################################## | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| #    Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Avinash Nk(<http://www.cybrosys.com>) | |||
| #    you can modify it under the terms of the GNU LESSER | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3), Version 3. | |||
| # | |||
| #    It is forbidden to publish, distribute, sublicense, or sell copies | |||
| #    of the Software or modified copies of the Software. | |||
| # | |||
| #    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | |||
| # | |||
| #    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3) along with this program. | |||
| #    If not, see <http://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'] | |||
|         date = 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 = date+" "+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,26 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ############################################################################## | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| #    Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Avinash Nk(<https://www.cybrosys.com>) | |||
| #    you can modify it under the terms of the GNU LESSER | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3), Version 3. | |||
| # | |||
| #    It is forbidden to publish, distribute, sublicense, or sell copies | |||
| #    of the Software or modified copies of the Software. | |||
| # | |||
| #    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | |||
| # | |||
| #    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3) along with this program. | |||
| #    If not, see <http://www.gnu.org/licenses/>. | |||
| # | |||
| ############################################################################## | |||
| import salon_management | |||
| import salon_booking | |||
| import salon_config | |||
| 
 | |||
| @ -0,0 +1,84 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ############################################################################## | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| #    Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Avinash Nk(<http://www.cybrosys.com>) | |||
| #    you can modify it under the terms of the GNU LESSER | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3), Version 3. | |||
| # | |||
| #    It is forbidden to publish, distribute, sublicense, or sell copies | |||
| #    of the Software or modified copies of the Software. | |||
| # | |||
| #    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | |||
| # | |||
| #    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3) along with this program. | |||
| #    If not, see <http://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,75 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ############################################################################## | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| #    Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Avinash Nk(<http://www.cybrosys.com>) | |||
| #    you can modify it under the terms of the GNU LESSER | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3), Version 3. | |||
| # | |||
| #    It is forbidden to publish, distribute, sublicense, or sell copies | |||
| #    of the Software or modified copies of the Software. | |||
| # | |||
| #    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | |||
| # | |||
| #    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3) along with this program. | |||
| #    If not, see <http://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 WorkshopSetting(models.Model): | |||
|     _name = "salon.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,418 @@ | |||
| # -*- coding: utf-8 -*- | |||
| ############################################################################## | |||
| # | |||
| #    Cybrosys Technologies Pvt. Ltd. | |||
| #    Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | |||
| #    Author: Avinash Nk(<https://www.cybrosys.com>) | |||
| #    you can modify it under the terms of the GNU LESSER | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3), Version 3. | |||
| # | |||
| #    It is forbidden to publish, distribute, sublicense, or sell copies | |||
| #    of the Software or modified copies of the Software. | |||
| # | |||
| #    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | |||
| # | |||
| #    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | |||
| #    GENERAL PUBLIC LICENSE (LGPL v3) along with this program. | |||
| #    If not, see <http://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, cr): | |||
|         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 cr.keys(): | |||
|             if cr['user_line']: | |||
|                 date_changer = [] | |||
|                 for elements in cr['user_line']: | |||
|                     date_changer.append(elements[2]['start_date']) | |||
|                 number = 0 | |||
|                 for elements in cr['user_line']: | |||
|                     number += 1 | |||
|                     if len(cr['user_line']) == number: | |||
|                         break | |||
|                     elements[2]['end_date'] = date_changer[number] | |||
|                 cr['user_of_chair'] = cr['user_line'][len((cr['user_line']))-1][2]['user_id'] | |||
|                 cr['date'] = cr['user_line'][len((cr['user_line']))-1][2]['start_date'] | |||
|         return super(SalonChair, self).create(cr) | |||
| 
 | |||
|     @api.multi | |||
|     def write(self, cr): | |||
|         if 'user_line' in cr.keys(): | |||
|             if cr['user_line']: | |||
|                 date_changer = [] | |||
|                 for elements in cr['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 cr['user_line']: | |||
|                     number += 1 | |||
|                     if elements[2] is not False: | |||
|                         num += 1 | |||
|                         if len(cr['user_line']) == number: | |||
|                             break | |||
|                         elements[2]['end_date'] = date_changer[num] | |||
|                 cr['user_of_chair'] = cr['user_line'][len((cr['user_line']))-1][2]['user_id'] | |||
|                 cr['date'] = cr['user_line'][len((cr['user_line']))-1][2]['start_date'] | |||
|         return super(SalonChair, self).write(cr) | |||
| 
 | |||
|     def collection_today_updater(self, cr, uid, context=None): | |||
|         salon_chair = self.pool.get('salon.chair') | |||
|         for values in self.search(cr, uid, []): | |||
|             chair_obj = salon_chair.browse(cr, 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, cr): | |||
|         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}) | |||
|         cr['read_only_checker'] = True | |||
|         return super(SalonChairUserLines, self).create(cr) | |||
| 
 | |||
| 
 | |||
| 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 | |||
|             for line in order.order_line: | |||
|                 amount_untaxed += line.price_subtotal | |||
|             order.price_subtotal = amount_untaxed | |||
|         for order in self: | |||
|             total_time_taken = 0.0 | |||
|             for line in order.order_line: | |||
|                 total_time_taken += line.time_taken | |||
|             order.time_taken_total = total_time_taken | |||
|         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)}) | |||
|         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, cr): | |||
|         if 'stage_id' in cr.keys(): | |||
|             if self.stage_id.id == 3 and cr['stage_id'] != 4: | |||
|                 raise ValidationError(_("You can't perform that move !")) | |||
|             if self.stage_id.id == 1 and cr['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 (cr['stage_id'] == 1 or cr['stage_id'] == 4): | |||
|                 raise ValidationError(_("You can't perform that move !")) | |||
|             if self.stage_id.id == 2 and cr['stage_id'] == 3 and self.inv_stage_identifier is False: | |||
|                 self.salon_invoice_create() | |||
|         if 'stage_id' in cr.keys() and self.name == "Draft Salon Order": | |||
|             if cr['stage_id'] == 2: | |||
|                 self.salon_confirm() | |||
|         return super(SalonOrder, self).write(cr) | |||
| 
 | |||
|     @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: 72 KiB | 
| After Width: | Height: | Size: 50 KiB | 
| After Width: | Height: | Size: 11 KiB | 
| @ -0,0 +1,278 @@ | |||
| <section class="oe_container oe_dark"> | |||
|     <div class="oe_row oe_spaced"> | |||
|         <h2 class="oe_slogan">Beauty Spa Management</h2> | |||
|         <h3 class="oe_slogan">This Module is for Managing the Process's in a Spa</h3> | |||
|          <h4 class="oe_slogan">Author : Cybrosys Techno Solutions, www.cybrosys.com</h4> | |||
|         <div> | |||
|             <h3>Major Features</h3> | |||
|             <ul> | |||
|                 <li style="list-style:none !important;"><span style="color:green;">☑</span>Online Booking Facility</li> | |||
|                 <li style="list-style:none !important;"><span style="color:green;"> ☑</span>Accounting Facility</li> | |||
|                 <li style="list-style:none !important;"><span style="color:green;"> ☑</span>Customer Notification Through Mail</li> | |||
|                 <li style="list-style:none !important;"><span style="color:green;"> ☑</span>User Interactive Dashboard</li> | |||
|                 <li style="list-style:none !important;"><span style="color:green;"> ☑</span>Customer Can view the Available chairs and order details</li> | |||
|                 <li style="list-style:none !important;"><span style="color:green;"> ☑</span>Different access levels for Users and Administrator</li> | |||
|                 <li style="list-style:none !important;"><span style="color:green;"> ☑</span>Track the chair user by date</li> | |||
|             </ul> | |||
|         </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container"> | |||
|     <div class="oe_row oe_spaced"> | |||
|         <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 class='oe_mt32'>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> | |||
|     </div> | |||
|     <div class="oe_row oe_spaced"> | |||
|         <div class="oe_span10"> | |||
|             <div class="oe_demo oe_picture oe_screenshot"> | |||
|                 <img src="screenshot_salon_dashboard.png"> | |||
|             </div> | |||
|         </div> | |||
| 
 | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container oe_dark"> | |||
|     <div class="oe_row oe_padded"> | |||
|         <div class="oe_span12"> | |||
|         <p class='oe_mt32'> | |||
|             Go to 'Salon Menu'</p> | |||
|         <p class='oe_mt32'> | |||
|             'Salon Menu' will direct you to the 'Dashboard' of the Salon. | |||
|         </p> | |||
|         <p class='oe_mt32'> | |||
|             *Note : It will be shown as empty(False) if you have not created chairs</p> | |||
|         <p class='oe_mt32'> | |||
|             Dashboard view is shown in the above image. Your customers can book | |||
|             the service in two ways, direct booking and online booking. The pink | |||
|             color chairs are the only ones available for online booking and blue | |||
|             chairs for direct booking.</p> | |||
|         <p class='oe_mt32'>In Dashboard, you get the daily collection of that chair | |||
|             and also the customer will be able to know when will be the chair 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.</p> | |||
|         <p class='oe_mt32'>If you want to change the settings of chair, you can just | |||
|             click the settings button in the dashboard.</p> | |||
|     </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container"> | |||
|     <div class="oe_row oe_spaced"> | |||
|         <div class="oe_span12"> | |||
|             <p class='oe_mt32'> | |||
|                 Sub Menu : Salon -> Chair</p> | |||
|             <p class='oe_mt32'>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.</p> | |||
|         </div> | |||
|         <div class="oe_span12"> | |||
|             <div class="oe_row_img oe_centered"> | |||
|                 <img class="oe_picture oe_screenshot" | |||
|                      src="screenshot_salon_chair.png"> | |||
|             </div> | |||
|         </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container oe_dark"> | |||
|     <div class="oe_row oe_padded"> | |||
|         <div class="oe_span6"> | |||
|             <div class="oe_row_img oe_centered"> | |||
|                 <img class="oe_picture oe_screenshot" | |||
|                      src="screenshot_salon_ services.png"> | |||
|             </div> | |||
|         </div> | |||
|         <div class="oe_span6"> | |||
|             <p class='oe_mt32'> | |||
|                 Sub Menu : Salon -> Services</p> | |||
|             <p> | |||
|                 List of services provided by the Spa. You can create and edit services here. | |||
|             </p> | |||
|         </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container"> | |||
|     <div class="oe_row oe_spaced"> | |||
|         <p class='oe_mt32'> | |||
|                 Sub Menu : Salon -> Salon Orders</p> | |||
|         <div class="oe_span6"> | |||
|             <p> | |||
|                 Here you have all the orders in the Spa. | |||
|             </p> | |||
|         </div> | |||
|         <div class="oe_span6"> | |||
|             <div class="oe_row_img oe_centered"> | |||
|                 <img class="oe_picture oe_screenshot" | |||
|                      src="screenshot_salon_order_kanban.png"> | |||
|             </div> | |||
|         </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container oe_dark"> | |||
|     <div class="oe_row oe_padded"> | |||
|         <div class="oe_span6"> | |||
|             <div class="oe_row_img oe_centered"> | |||
|                 <img class="oe_picture oe_screenshot" | |||
|                      src="screenshot_salon_order_form.png"> | |||
|             </div> | |||
|         </div> | |||
|         <div class="oe_span6"> | |||
|             <p> | |||
|                 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. | |||
|             </p> | |||
|         </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container"> | |||
|     <div class="oe_row oe_spaced"> | |||
|         <div class="oe_span6"> | |||
|             <p class='oe_mt32'> | |||
|                 Sub Menu : Salon -> Bookings</p> | |||
|             <p> | |||
|                 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. | |||
|             </p> | |||
|         </div> | |||
|         <div class="oe_span6"> | |||
|             <div class="oe_row_img oe_centered"> | |||
|                 <img class="oe_picture oe_screenshot" | |||
|                      src="screenshot_salon_booking_tree.png"> | |||
|             </div> | |||
|         </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container oe_dark"> | |||
|     <div class="oe_row oe_padded"> | |||
|         <div class="oe_span6"> | |||
|             <div class="oe_row_img oe_centered"> | |||
|                 <img class="oe_picture oe_screenshot" | |||
|                      src="screenshot_salon_booking_forms.png"> | |||
|             </div> | |||
|         </div> | |||
|         <div class="oe_span6"> | |||
|             <p class='oe_mt32'> | |||
|                 Form View of Booking</p> | |||
|             <p> | |||
|                 Here you can see all the salon orders on the corresponding date. | |||
|                 After checking the time available, | |||
|                 you can decide to approve/reject the booking accordingly. | |||
|             </p> | |||
|         </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| 
 | |||
| 
 | |||
| <section class="oe_container"> | |||
|     <div class="oe_row oe_spaced"> | |||
|         <div class="oe_span6"> | |||
|             <p class='oe_mt32'> | |||
|                 Sub Menu : Salon -> Settings</p> | |||
|             <p> | |||
|                 Here you can assign the chairs for booking purpose. | |||
|                 Only the assigned chairs can be booked by a customer through online. | |||
|             </p> | |||
|         </div> | |||
|         <div class="oe_span6"> | |||
|             <div class="oe_row_img oe_centered"> | |||
|                 <img class="oe_picture oe_screenshot" | |||
|                      src="screenshot_salon_settings.png"> | |||
|             </div> | |||
|         </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container oe_dark"> | |||
|     <div class="oe_row oe_padded"> | |||
|         <div> | |||
|                  ☛ Online Booking Form | |||
|         </div> | |||
|     </div> | |||
|     <div class="oe_row oe_spaced"> | |||
|         <div class="oe_span10"> | |||
|             <div class="oe_demo oe_picture oe_screenshot"> | |||
|                 <img src="screenshot_salon_online_1.png"> | |||
|             </div> | |||
|         </div> | |||
|         <div class="oe_span12"> | |||
|             <p class='oe_mt32'> | |||
|                 Here the customer can fill the details. and send the form.</p> | |||
|         </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container"> | |||
|     <div class="oe_row oe_spaced"> | |||
|         <div> | |||
|                  ☛ Online Booking Chair Details | |||
|         </div> | |||
|     </div> | |||
|     <div class="oe_row oe_spaced"> | |||
|         <div class="oe_span10"> | |||
|             <div class="oe_demo oe_picture oe_screenshot"> | |||
|                 <img src="screenshot_salon_online_2.png"> | |||
|             </div> | |||
|         </div> | |||
|         <div class="oe_span12"> | |||
|             <p class='oe_mt32'> | |||
|                 Here the customer can check the availability of the chair by date.</p> | |||
|         </div> | |||
|     </div> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container oe_dark"> | |||
|     <h2 class="oe_slogan" style="margin-top:20px;" >You Looking for  a free Documentation of this Application.?</h2> | |||
|     <h3 class="oe_slogan">Give a Request Mail to:  <i class="fa fa-envelope" aria-hidden="true"></i>  <a href="#" style="color:blue;">odoo@cybrosys.com</a></h3> | |||
| </section> | |||
| 
 | |||
| <section class="oe_container"> | |||
| 		<h2 class="oe_slogan" style="margin-top:20px;" >Need Any Help?</h2> | |||
| 		<div class="oe_slogan" style="margin-top:10px !important;"> | |||
|             <div> | |||
| 				<a  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 </a> <a | |||
| 				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 | |||
| 				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="cybro_logo.png" style="width: 190px; margin-bottom: 20px;" 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;"></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;"></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;padding-left: 8px;"></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;"></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;"></i></a></td> | |||
|             </div> | |||
| 		</div> | |||
| </section> | |||
| 
 | |||
| 
 | |||
| After Width: | Height: | Size: 44 KiB | 
| After Width: | Height: | Size: 71 KiB | 
| After Width: | Height: | Size: 66 KiB | 
| After Width: | Height: | Size: 50 KiB | 
| After Width: | Height: | Size: 72 KiB | 
| After Width: | Height: | Size: 69 KiB | 
| After Width: | Height: | Size: 53 KiB | 
| After Width: | Height: | Size: 40 KiB | 
| After Width: | Height: | Size: 72 KiB | 
| After Width: | Height: | Size: 33 KiB | 
| @ -0,0 +1,57 @@ | |||
| .style_chair{ | |||
|     text-align: center; | |||
|     color: black; | |||
|     font-size: 21px; | |||
|     background: #337ab7; | |||
| } | |||
| .style_chair_booking{ | |||
|     text-align: center; | |||
|     color: black; | |||
|     font-size: 21px; | |||
|     background: #a52694; | |||
| } | |||
| .style_collection{ | |||
|     color: black !important; | |||
|     font-size: 12px; | |||
|     text-align: center; | |||
|     background: #337ab7 !important; | |||
|     padding: 2px 0px 2px 3px; | |||
| } | |||
| .style_collection_booking{ | |||
|     color: black !important; | |||
|     font-size: 12px; | |||
|     text-align: center; | |||
|     background: #a52694 !important; | |||
|     padding: 2px 0px 2px 3px; | |||
| } | |||
| .no_of_people{ | |||
|     text-align: center; | |||
|     font-size: 60px; | |||
|     margin: 0px; | |||
|     background: #337ab7; | |||
|     color: white; | |||
|     border-bottom: 1px solid #fff; | |||
|     border-top: 1px solid #fff; | |||
| } | |||
| .no_of_people_booking{ | |||
|     text-align: center; | |||
|     font-size: 60px; | |||
|     margin: 0px; | |||
|     background: #a52694; | |||
|     color: white; | |||
|     border-bottom: 1px solid #fff; | |||
|     border-top: 1px solid #fff; | |||
| } | |||
| .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: #fff; | |||
| } | |||
| @ -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,16 @@ | |||
| @dashboard-bg-color: white; | |||
| 
 | |||
| .o_kanban_view.o_kanban_dashboard.o_salon_kanban { | |||
|     @sale-table-spacing: 10px; | |||
| 
 | |||
|     .o_kanban_record { | |||
|         min-height: 120px; | |||
|         max-width: 180px !important; | |||
|         box-shadow: 0px 0px 1px 3px #000 !important; | |||
|         @media (min-width: @screen-sm-min) { | |||
|             min-width: 20px; | |||
| 
 | |||
|         } | |||
|     } | |||
| 
 | |||
| } | |||
| @ -0,0 +1,61 @@ | |||
| <?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"/> | |||
|                                 <field name="state" invisible="1"/> | |||
|                             </group> | |||
|                         </group> | |||
|                         <notebook> | |||
|                             <page> | |||
|                                 <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,12 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <odoo> | |||
|     <data> | |||
|         <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> | |||
|     </data> | |||
| </odoo> | |||
| @ -0,0 +1,234 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <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> | |||
|         <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> | |||
|         <template id="salon_booking_form" name="Salon Booking" page="True"> | |||
|             <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"/> | |||
|             <link rel="stylesheet" href="/resources/demos/style.css"/> | |||
|             <script src="https://code.jquery.com/jquery-1.12.4.js"></script> | |||
|             <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> | |||
|             <script>$( function() {$( "#date" ).datepicker();} );</script> | |||
|             <script>$( function() {$( "#check_date" ).datepicker();} );</script> | |||
|             <t t-call="website.layout"> | |||
|                 <div class="container"> | |||
|                     <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:avinashnk916@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 class="container"> | |||
|                     <h1 style="text-align:center;">Working Time</h1> | |||
|                     <div> | |||
|                        <table class="table"> | |||
|                            <th>Day</th> | |||
|                            <th>Starting Time</th> | |||
|                            <th>Closing Time</th> | |||
|                            <div> | |||
|                                <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> | |||
|                            </div> | |||
|                        </table> | |||
|                     </div> | |||
|                 </div> | |||
|                 <section id="chair_details"> | |||
|                     <div class="container" style="margin-bottom:100px"> | |||
|                         <h1 style="text-align:center;">Available Chairs and Details</h1> | |||
|                         <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;" > | |||
|                                 <h3 style="text-align:left; float:left; margin-top: 4px;font-weight: 600;">Date :</h3> | |||
|                                 <h3 style="float:left; margin-top: 4px;font-weight: 600;"><t t-esc="date_search"/></h3> | |||
|                             </div> | |||
|                             <div class="col-sm-3 col-md-5" style="padding-left: 0px;" > | |||
|                                 <h3 style="text-align:left; float:left; margin-top: 4px;font-weight: 600; padding-right:6px;">Holidays :</h3> | |||
|                                 <div t-foreach="holiday" t-as="holiday_obj"> | |||
|                                     <h4 t-field="holiday_obj.name" style="float:left;font-weight: 600; "/> | |||
|                                     <h4 style="float:left;font-weight: 600;">&nbsp;</h4> | |||
|                                 </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: 268px!important; text-align: center; border: 1px solid #666;padding: 15px 0px;box-shadow: 7px 8px 5px #888888;background-color: #a52694;color: #fff;margin-bottom: 10px;"> | |||
|                                         <span style="font-size: 40px;" t-field="chair_obj.name"/><br/> | |||
|                                         <a style="color: #fff;font-size: 40px;">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: #a52694; | |||
|                                                     width:8px !important; | |||
|                                                 } | |||
| 
 | |||
|                                                 #style-2::-webkit-scrollbar | |||
|                                                 { | |||
|                                                     width: 12px; | |||
|                                                     background-color: #a52694; | |||
|                                                       width:8px !important; | |||
|                                                 } | |||
| 
 | |||
|                                                 #style-2::-webkit-scrollbar-thumb | |||
|                                                 { | |||
|                                                     border-radius: 10px; | |||
|                                                     -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); | |||
|                                                     background-color: rgba(130, 0, 112, 0.69); | |||
|                                                     width:8px !important; | |||
|                                                 } | |||
|                                         </style> | |||
|                                        <div id="style-2" style="overflow: overlay; height: 136px; padding-right: 25px;padding-left: 25px;"> | |||
|                                            <table class="table"> | |||
|                                                <th>Order No.</th> | |||
|                                                <th>Start Time</th> | |||
|                                                <th>End Time</th> | |||
|                                                <div> | |||
|                                                    <tbody> | |||
|                                                        <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> | |||
|                 </t> | |||
|             </template> | |||
|         <template id="salon_booking_thank_you" name="Thank you" page="True"> | |||
|             <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> | |||
|     </data> | |||
| </odoo> | |||
| @ -0,0 +1,37 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <odoo> | |||
|     <record id="salon_config_settings_view" model="ir.ui.view"> | |||
|     <field name="name">salon settings</field> | |||
|     <field name="model">salon.config.settings</field> | |||
|     <field name="arch" type="xml"> | |||
|         <form string="Configure Salon" class="oe_form_configuration"> | |||
|             <header> | |||
|                 <button string="Apply" type="object" name="execute" class="oe_highlight"/> | |||
|                 <button string="Cancel" name="cancel" class="oe_link"/> | |||
|             </header> | |||
|             <div id="main"> | |||
|                 <group string="Booking Chairs(Choose the chair when its free)"> | |||
|                     <field name="salon_booking_chairs" widget="many2many_checkboxes"/> | |||
|                 </group> | |||
|                 <group string="Holidays"> | |||
|                     <field name="salon_holidays" widget="many2many_checkboxes"/> | |||
|                 </group> | |||
|             </div> | |||
|         </form> | |||
|     </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">salon.config.settings</field> | |||
|         <field name="view_id" ref="salon_config_settings_view"/> | |||
|         <field name="view_mode">form</field> | |||
|         <field name="target">inline</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" /> | |||
| </odoo> | |||
| @ -0,0 +1,65 @@ | |||
| <?xml version="1.0"?> | |||
| <odoo> | |||
|   <data> | |||
|     <record id="user_salon_boolean" model="ir.ui.view"> | |||
|         <field name="name">user_salon_boolean.view</field> | |||
|         <field name="model">res.users</field> | |||
|         <field name="inherit_id" ref="base.view_users_form"/> | |||
|         <field name="arch" type="xml"> | |||
|             <xpath expr="//field[@name='in_group_12']" position="after"> | |||
|                 <field name="user_salon_active"/> | |||
|             </xpath> | |||
|         </field> | |||
|     </record> | |||
|     <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,91 @@ | |||
| <?xml version="1.0" encoding="utf-8" ?> | |||
| <odoo> | |||
|     <data noupdate="1"> | |||
|         <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> | |||
|     </data> | |||
|     <data> | |||
|         <record forcecreate="True" id="ir_cron_collections_today" model="ir.cron"> | |||
|             <field name="name">Collection Today</field> | |||
|             <field eval="True" name="active" /> | |||
|             <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="False" name="doall" /> | |||
|             <field eval="'salon.chair'" name="model" /> | |||
|             <field eval="'collection_today_updater'" name="function" /> | |||
|         </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 fa-spin"/></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 fa-spin"/></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> | |||
|                     <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> | |||