@ -0,0 +1 @@ |
|||
import models |
@ -0,0 +1,49 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2009-TODAY Cybrosys Technologies(<http://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/>. |
|||
# |
|||
############################################################################## |
|||
{ |
|||
'name': 'Beauty Spa Management', |
|||
'summary': """Beauty Parlour Management with Online Booking System""", |
|||
'version': '0.1', |
|||
'author': 'Cybrosys Techno Solutions', |
|||
'website': "http://www.cybrosys.com", |
|||
'company': 'Cybrosys Techno Solutions', |
|||
"category": "Tools", |
|||
'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', |
|||
], |
|||
'images': ['static/description/banner.jpg'], |
|||
'license': 'AGPL-3', |
|||
'installable': True, |
|||
'application': True, |
|||
} |
@ -0,0 +1,26 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2009-TODAY Cybrosys Technologies(<http://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 salon_management |
|||
import salon_booking |
|||
import salon_config |
|||
|
@ -0,0 +1,141 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2009-TODAY Cybrosys Technologies(<http://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 openerp.addons.web import http |
|||
from openerp import models, fields, _, SUPERUSER_ID, api |
|||
from openerp.addons.web.http import request |
|||
from datetime import datetime, date |
|||
|
|||
|
|||
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" |
|||
|
|||
|
|||
class SalonBookingWeb(http.Controller): |
|||
|
|||
@http.route('/page/salon_details', type='json', auth="public", website=True) |
|||
def salon_details(self, **kwargs): |
|||
booking_info = kwargs.get('salon_data') |
|||
name = booking_info[0] |
|||
date = booking_info[1] |
|||
phone = booking_info[2] |
|||
email = booking_info[3] |
|||
services = booking_info[4] |
|||
chair = booking_info[5] |
|||
salon_service_obj = request.env['salon.service'].search([('id', 'in', services)]) |
|||
date = str(date) |
|||
dates = date[0:10] |
|||
time = date[11:16] |
|||
dates_time = dates+" "+time+":00" |
|||
date_and_time = datetime.strptime(dates_time, '%Y-%m-%d %H:%M:%S') |
|||
salon_booking = request.registry['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(request.cr, SUPERUSER_ID, booking_data, context=request.context) |
|||
return |
|||
|
|||
@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_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.website.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,74 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2009-TODAY Cybrosys Technologies(<http://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 openerp 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,426 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2009-TODAY Cybrosys Technologies(<http://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 openerp import models, fields, api |
|||
from datetime import date, datetime, timedelta |
|||
from openerp.tools.translate import _ |
|||
from openerp.exceptions import UserError, ValidationError |
|||
|
|||
|
|||
class PartnerSalon(models.Model): |
|||
|
|||
_inherit = 'res.partner' |
|||
|
|||
partner_salon = fields.Boolean(string="Is a Salon Partner") |
|||
|
|||
|
|||
class CompanySalon(models.Model): |
|||
|
|||
_inherit = 'res.company' |
|||
|
|||
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['res.company'].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") |
|||
|
|||
@api.model |
|||
def create(self, cr): |
|||
sequence_code = 'chair.sequence' |
|||
sequence_number = self.env['ir.sequence'].next_by_code(sequence_code) |
|||
self.env['res.company'].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 = 0.0 |
|||
if time_takes != 0: |
|||
minutes = (time_takes % int(time_takes))*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") |
|||
|
|||
@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): |
|||
|
|||
self.chair_id.number_of_orders = len(self.env['salon.order'].search([("chair_id", "=", self.chair_id.id), |
|||
("stage_id", "in", [2, 3])])) |
|||
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 |
|||
|
|||
@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", translate=True, required=True) |
|
After Width: | Height: | Size: 186 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,249 @@ |
|||
<section class="oe_container"> |
|||
<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> |
|||
<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 class="oe_row oe_spaced"> |
|||
<div> |
|||
This Spa Management system contains Online Booking Facility to Enhance Your |
|||
Business.Also you can Managing your Accounting Sections through this Module. |
|||
Another Facility is, Online Booked Customers get the Notification of Booking information |
|||
through Mail. |
|||
</div> |
|||
</div> |
|||
<div class="oe_row oe_spaced"> |
|||
<div> |
|||
☛ Installation : When you Install This Module, The supporting modules website, |
|||
accounting...are installed |
|||
</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 class="oe_span12"> |
|||
<p class='oe_mt32'> |
|||
Go to Salon Menu</p> |
|||
<p class='oe_mt32'> |
|||
Salon Menu Direct you to the Dashboard of the Salon. |
|||
</p> |
|||
<p class='oe_mt32'> |
|||
*Note : First it is empty(False) because you have to create Chairs</p> |
|||
<p class='oe_mt32'> |
|||
Dashboard view is shown in the above image.Blue Chair Represents the Normal |
|||
Chair and the Rose Chair Represents the Chairs Reserved For Booking. |
|||
In the Dashboard, you get the today's collection on that chair.and how much time |
|||
it's take the chair free.You can also see the active orders on that chair |
|||
and go to that orders by clicking on it.You can change the settings of |
|||
chair by clicking the settings button in the dashboard</p> |
|||
</div> |
|||
</div> |
|||
</section> |
|||
|
|||
<section class="oe_container oe_dark"> |
|||
<div class="oe_row oe_padded"> |
|||
<div class="oe_span12"> |
|||
<p class='oe_mt32'> |
|||
Sub Menu : Salon -> Chair</p> |
|||
<p class='oe_mt32'> |
|||
Here you can create and edit each chair details. |
|||
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.By this Tab, you can Track which User |
|||
is Active on the Chair In 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 of Spa.You can create and edit Services here. |
|||
</p> |
|||
</div> |
|||
</div> |
|||
</section> |
|||
<section class="oe_container oe_dark"> |
|||
<div class="oe_row oe_padded"> |
|||
<p class='oe_mt32'> |
|||
Sub Menu : Salon -> Salon Orders</p> |
|||
<div class="oe_span6"> |
|||
<p> |
|||
Here you have the all 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 can 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 oe_dark"> |
|||
<div class="oe_row oe_padded"> |
|||
<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. Both cases the notification is send to the customer mail |
|||
address. The approved bookings 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"> |
|||
<p class='oe_mt32'> |
|||
Form View of Booking</p> |
|||
<p> |
|||
Here you can see all the salon orders on the corresponding date. |
|||
by checking the availability of the time, you can decide to approve the |
|||
booking. |
|||
</p> |
|||
</div> |
|||
<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> |
|||
</section> |
|||
|
|||
|
|||
|
|||
<section class="oe_container oe_dark"> |
|||
<div class="oe_row oe_padded"> |
|||
<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 book 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 oe_dark"> |
|||
<div class="oe_row oe_padded"> |
|||
<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 oe_dark"> |
|||
<h2 class="oe_slogan" style="margin-top:20px;" >Need Any Help?</h2> |
|||
<div class="oe_slogan" style="margin-top:10px !important;"> |
|||
<a class="btn btn-primary btn-lg mt8" |
|||
style="color: #FFFFFF !important;" href="http://www.cybrosys.com"><i |
|||
class="fa fa-envelope"></i> Email </a> <a |
|||
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;" |
|||
href="http://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;" |
|||
href="http://www.cybrosys.com/odoo-customization-and-installation/"><i |
|||
class="fa fa-check-square"></i> Request Customization </a> |
|||
</div> |
|||
<img src="cybro_logo.png" style="width: 190px; margin-bottom: 20px;" class="center-block"> |
|||
</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,34 @@ |
|||
odoo.define('website_salon_booking_system', function (require) { |
|||
'use strict'; |
|||
var ajax = require('web.ajax'); |
|||
$(document).on('click',"#submit_button",function() { |
|||
var name = $( "#name" ).val(); |
|||
var date = $( "#date" ).val(); |
|||
var phone = $( "#phone" ).val(); |
|||
var email = $( "#email" ).val(); |
|||
var service = $( "#service" ).val(); |
|||
var chair = $( "#chair" ).val(); |
|||
if (name != "" && date != "" && phone != "" && email != "" && service != "" && chair != "") |
|||
{ |
|||
var booking_record = [name, date, phone, email, service, chair]; |
|||
var salon_record = ajax.jsonRpc("/page/salon_details", 'call', {'salon_data':booking_record }) |
|||
.then(function(){ |
|||
window.location= "/page/salon_management.salon_booking_thank_you" |
|||
}) |
|||
} |
|||
else |
|||
{ |
|||
alert("Fill all the required fields") |
|||
} |
|||
}); |
|||
|
|||
$(document).on('click',"#check_button",function() { |
|||
var check_date = $( "#check_date" ).val(); |
|||
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 |
|||
}) |
|||
}); |
|||
}); |
|||
|
|||
|
@ -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" ?> |
|||
<openerp> |
|||
<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> |
|||
</openerp> |
@ -0,0 +1,229 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<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.website2_main_menu"/> |
|||
<field name="sequence" type="int">80</field> |
|||
<field name="website_id" ref="website.website2"/> |
|||
</record> |
|||
<template id="assets_editor" inherit_id="website.assets_editor" name="Website assets" groups="base.group_user"> |
|||
<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"> |
|||
<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="datetime-local" id="date" class="search-query form-control oe_search_box" required="True" placeholder="Choose your preferred time"/> |
|||
|
|||
</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="submit" 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;" type="date" id="check_date" 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> |
|||
</openerp> |
@ -0,0 +1,37 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<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" /> |
|||
</openerp> |
@ -0,0 +1,59 @@ |
|||
<?xml version="1.0"?> |
|||
<openerp> |
|||
<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> |
|||
</openerp> |
@ -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,33 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<openerp> |
|||
<data noupdate="1"> |
|||
<record model="salon.holiday" id="salon_holiday_01"> |
|||
<field name="name">Sunday</field> |
|||
<field name="holiday">0</field> |
|||
</record> |
|||
<record model="salon.holiday" id="salon_holiday_02"> |
|||
<field name="name">Monday</field> |
|||
<field name="holiday">0</field> |
|||
</record> |
|||
<record model="salon.holiday" id="salon_holiday_03"> |
|||
<field name="name">Tuesday</field> |
|||
<field name="holiday">0</field> |
|||
</record> |
|||
<record model="salon.holiday" id="salon_holiday_04"> |
|||
<field name="name">Wednesday</field> |
|||
<field name="holiday">0</field> |
|||
</record> |
|||
<record model="salon.holiday" id="salon_holiday_05"> |
|||
<field name="name">Thursday</field> |
|||
<field name="holiday">0</field> |
|||
</record> |
|||
<record model="salon.holiday" id="salon_holiday_06"> |
|||
<field name="name">Friday</field> |
|||
<field name="holiday">0</field> |
|||
</record> |
|||
<record model="salon.holiday" id="salon_holiday_07"> |
|||
<field name="name">Saturday</field> |
|||
<field name="holiday">0</field> |
|||
</record> |
|||
</data> |
|||
</openerp> |
@ -0,0 +1,91 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<openerp> |
|||
<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_collection_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">minutes</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> |
|||
</openerp> |
@ -0,0 +1,96 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<openerp> |
|||
<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> |
|||
</openerp> |
@ -0,0 +1,38 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<openerp> |
|||
<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> |
|||
</openerp> |
@ -0,0 +1,221 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<openerp> |
|||
<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> |
|||
</openerp> |
@ -0,0 +1,68 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<openerp> |
|||
<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> |
|||
</openerp> |