Browse Source

add sudoku & quotation_handler [ADD]

pull/87/head
Nikhil Krishnan 7 years ago
parent
commit
a831a485db
  1. 20
      game_sudoku/README.rst
  2. 25
      game_sudoku/__init__.py
  3. 49
      game_sudoku/__manifest__.py
  4. 26
      game_sudoku/models/__init__.py
  5. 75
      game_sudoku/models/game.py
  6. 4
      game_sudoku/security/ir.model.access.csv
  7. 26
      game_sudoku/security/security_data.xml
  8. BIN
      game_sudoku/static/description/Game Request.png
  9. BIN
      game_sudoku/static/description/Just wait for approval.png
  10. BIN
      game_sudoku/static/description/Level.png
  11. BIN
      game_sudoku/static/description/May i play.png
  12. BIN
      game_sudoku/static/description/Sudoku.png
  13. BIN
      game_sudoku/static/description/banner.jpg
  14. BIN
      game_sudoku/static/description/color code.png
  15. BIN
      game_sudoku/static/description/cybro_logo.png
  16. BIN
      game_sudoku/static/description/icon.png
  17. 192
      game_sudoku/static/description/index.html
  18. BIN
      game_sudoku/static/description/sudoku 1.png
  19. BIN
      game_sudoku/static/description/user group.png
  20. BIN
      game_sudoku/static/description/won.png
  21. 283
      game_sudoku/static/src/css/sudoku.css
  22. BIN
      game_sudoku/static/src/img/application-switcher-bg.jpg
  23. 54
      game_sudoku/static/src/js/game.js
  24. 1008
      game_sudoku/static/src/js/sudoku.js
  25. 119
      game_sudoku/static/src/less/games.less
  26. 20
      game_sudoku/static/src/xml/game.xml
  27. 161
      game_sudoku/static/src/xml/sudoku.xml
  28. 9
      game_sudoku/views/game_approve_sequence.xml
  29. 13
      game_sudoku/views/game_template.xml
  30. 48
      game_sudoku/views/main_menu.xml
  31. 14
      game_sudoku/views/sudoku_menu.xml
  32. 19
      quotation_handler/README.rst
  33. 23
      quotation_handler/__init__.py
  34. 44
      quotation_handler/__manifest__.py
  35. 69
      quotation_handler/data/mail_template_data_exp_date.xml
  36. 24
      quotation_handler/models/__init__.py
  37. 144
      quotation_handler/models/sale.py
  38. 62
      quotation_handler/models/sale_config_settings_exp_date_views.py
  39. BIN
      quotation_handler/static/description/banner.jpg
  40. BIN
      quotation_handler/static/description/cybro_logo.png
  41. BIN
      quotation_handler/static/description/editable line.png
  42. BIN
      quotation_handler/static/description/email template.png
  43. BIN
      quotation_handler/static/description/icon.png
  44. 189
      quotation_handler/static/description/index.html
  45. BIN
      quotation_handler/static/description/revised form view.png
  46. BIN
      quotation_handler/static/description/revised state.png
  47. BIN
      quotation_handler/static/description/revised tree.png
  48. BIN
      quotation_handler/static/description/sent state not editable.png
  49. BIN
      quotation_handler/static/description/sent state.png
  50. BIN
      quotation_handler/static/description/settings.png
  51. 112
      quotation_handler/views/quotation_handler.xml
  52. 112
      quotation_handler/views/quotation_handler.xml~
  53. 42
      quotation_handler/views/sale_config_settings_exp_date_views.xml

20
game_sudoku/README.rst

@ -0,0 +1,20 @@
Odoo Games - Sudoku v11
=======================
The classic Sudoku game involves a grid of 81 squares. The grid is divided into nine blocks,
each containing nine squares.
The rules of the game are simple:
Each of the nine blocks has to contain all the numbers 1-9 within its squares. Each number can
only appear once in a row, column or box.
You can select the squares by clicking. Enter the numbers.
Space button is use to erase the entry.
Features
========
* We can play SUDOKU Game.
* Play only By the approval of HR Manager.
Credits
=======
Nikhil Krishnan @ nikhilkrishnan0101@gmail.com

25
game_sudoku/__init__.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Nikhil krishnan(<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 . import models

49
game_sudoku/__manifest__.py

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Nikhil krishnan(nikhilkrishnan0101@gmail.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': 'Odoo Games - Sudoku',
'version': '11.0.1.0.0',
'summary': """Sudoku Game.""",
'description': """We can play SUDOKU.""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'website': 'http://www.cybrosys.com',
'category': '',
'depends': ['base', 'hr', 'hr_attendance'],
'license': 'LGPL-3',
'data': [
'security/security_data.xml',
'security/ir.model.access.csv',
'views/game_approve_sequence.xml',
'views/game_template.xml',
'views/main_menu.xml',
'views/sudoku_menu.xml',
],
'demo': [],
'qweb': [
"static/src/xml/sudoku.xml",
"static/src/xml/game.xml",
],
'images': ['static/description/banner.jpg'],
'installable': True,
'auto_install': False,
}

26
game_sudoku/models/__init__.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Nikhil krishnan(<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 . import game

75
game_sudoku/models/game.py

@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>).
# Author: Nikhil krishnan(<nikhilkrishnan0101@gmail.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 datetime
from odoo import models, fields
class EntertainmentGames(models.Model):
_name = 'employee.game.approve'
_order = 'sequence desc'
name = fields.Char(string='Name', related='employee_id.name')
approve_datetime = fields.Datetime(string='Datetime', readonly=1)
employee_id = fields.Many2one('hr.employee', string='Employee', required=True)
user_id = fields.Many2one('res.users', string='User')
department_id = fields.Many2one('hr.department', string='Department', related='employee_id.department_id')
game_user = fields.Boolean(string='Is Game User')
state = fields.Selection([
('draft', 'Requested'),
('approve', 'Approved'),
('cancel', 'Cancelled'),
], string='Status', readonly=True, copy=False, default='draft')
sequence = fields.Integer('Sequence')
def create_employee_game_approve(self, empl_id, user):
rec = self.search([('employee_id', '=', empl_id)])
if rec:
seq = self.env['ir.sequence'].next_by_code('employee.game')
rec.write({'sequence': seq, 'state': 'draft', 'approve_datetime': datetime.now()})
else:
vals = {
'employee_id': empl_id,
'user_id': user,
'approve_datetime': datetime.now(),
'sequence': self.env['ir.sequence'].next_by_code('employee.game')
}
self.create(vals)
def approve(self):
group_game_approve = self.env.ref('game_sudoku.odoo_gamer_group', False)
group_game_approve.write({'users': [(4, self.user_id.id)]})
group_game_req = self.env.ref('game_sudoku.odoo_gamer_approve_req', False)
group_game_req.write({'users': [(3, self.user_id.id)]})
return self.write({'game_user': True, 'state': 'approve'})
def cancel(self):
group_game_approve = self.env.ref('game_sudoku.odoo_gamer_group', False)
group_game_approve.write({'users': [(3, self.user_id.id)]})
group_game_req = self.env.ref('game_sudoku.odoo_gamer_approve_req', False)
group_game_req.write({'users': [(4, self.user_id.id)]})
return self.write({'game_user': False, 'state': 'cancel'})

4
game_sudoku/security/ir.model.access.csv

@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_game_gamer,employee.game.approve.user,game_sudoku.model_employee_game_approve,base.group_user,1,1,1,0
access_game_gamer_manager,employee.game.approve.manager,game_sudoku.model_employee_game_approve,hr.group_hr_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_game_gamer employee.game.approve.user game_sudoku.model_employee_game_approve base.group_user 1 1 1 0
3 access_game_gamer_manager employee.game.approve.manager game_sudoku.model_employee_game_approve hr.group_hr_manager 1 1 1 1

26
game_sudoku/security/security_data.xml

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record model="ir.module.category" id="module_category_game">
<field name="name">Game</field>
<field name="sequence">10</field>
<field name="visible" eval="False" />
</record>
<record id="odoo_gamer_group" model="res.groups">
<field name="name">Odoo Gamer</field>
<field name="category_id" ref="game_sudoku.module_category_game"/>
</record>
<record id="odoo_gamer_approve_req" model="res.groups">
<field name="name">Odoo Game Request</field>
<field name="category_id" ref="game_sudoku.module_category_game"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
<record id="base.default_user" model="res.users">
<field name="groups_id" eval="[(4,ref('game_sudoku.odoo_gamer_approve_req')),(4,ref('base.group_partner_manager'))]"/>
</record>
</data>
</odoo>

BIN
game_sudoku/static/description/Game Request.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
game_sudoku/static/description/Just wait for approval.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
game_sudoku/static/description/Level.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
game_sudoku/static/description/May i play.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
game_sudoku/static/description/Sudoku.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
game_sudoku/static/description/banner.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
game_sudoku/static/description/color code.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
game_sudoku/static/description/cybro_logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
game_sudoku/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

192
game_sudoku/static/description/index.html

@ -0,0 +1,192 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">Odoo Games - Sudoku</h2>
<h3 class="oe_slogan">Brain-Teaser game.!!</h3>
<h4 class="oe_slogan"><a href="https://www.cybrosys.com">Cybrosys Technologies</a> </h4>
<div>
<h4><p>Features:</p></h4>
<ul>
<li style="list-style:none !important;"><span style="color:green;"> &#9745;</span>&nbsp;&nbsp; We can play SUDOKU.</li>
<li style="list-style:none !important;"><span style="color:green;"> &#9745;</span>&nbsp;&nbsp; Play only By the approval of HR Manager.</li>
</ul>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">How to start the game.?</h3>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="May i play.png">
</div>
</div>
<div class="oe_span12">
<p class="oe_mt32">
To start playing the game, user should click the button (<i class="fa fa-gamepad" style="color: #f9f9f9;background: #a3498b;"/>)
for send a request.
</p>
</div>
<div class="oe_span12">
<p class="oe_mt32">
Wait for the approval of HR manager.
</p>
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="Just wait for approval.png">
</div>
<p class="oe_mt32">
A record is generated. And from the record the HR manager can give approval to play the game.
</p>
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan"> Admin, please check with the user form to enable the option " Odoo Game Request".</h3>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="user group.png">
</div>
</div>
</div>
<div class="oe_row oe_spaced">
Admin can directly give the permission to play the game. Just enable "Odoo Gamer"
<p>Ps:- if we directly give permission to play game, don't forget to remove Odoo Game Request"</p>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Approve the game request by HR Manager</h3>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="Game Request.png">
</div>
</div>
<div class="oe_span12">
<p class="oe_mt32">
HR managers can see this request from the menu "Game Request" under Game.
</p>
<p class="oe_mt32">
We can see 2 buttons here.
<p>
1.This icon( <i class="fa fa-check" aria-hidden="true"></i>) for approve the request
</p>
<p>
2. This icon (<i class="fa fa-times" aria-hidden="true"></i>) for avoid/cancel the request
</p>
</p>
<p class="oe_mt32">
We can easily identify the states of the request by color.
<ul>
<li>Red is in draft state.</li>
</ul>
<ul>
<li>Green is in approve state.</li>
</ul>
<ul>
<li>Grey is in cancel state.</li>
</ul>
</p>
</div>
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="color code.png">
</div>
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">SUDOKU</h3>
<div class="oe_row oe_spaced">
Click on the "New Game" button to start the game.
</div>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="Sudoku.png">
</div>
</div>
</div>
<div class="oe_row oe_spaced">
Select your level of game.
</div>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="Level.png">
</div>
</div>
</div>
<div class="oe_row oe_spaced">
Let's play..!!
<p>
The classic Sudoku game involves a grid of 81 squares.
The grid is divided into nine blocks, each containing nine squares.
<p><b>The rules of the game are simple: </b></p>
<i>each of the nine blocks should contain all the numbers 1-9 within its squares.
Each number can appear only once in a row, column or box.</i>
</p>
<p><b>You can select the squares by clicking. Read the numbers from key boards.</b></p>
<p><b>Space button can be used to erase the entry.</b></p>
</div>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="sudoku 1.png">
</div>
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">WON the game</h3>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="won.png">
</div>
</div>
</div>
</div>
</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;">
<div>
<a class="btn btn-primary btn-lg mt8"
style="color: #FFFFFF !important;border-radius: 0;" 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;border-radius: 0;"
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;border-radius: 0;"
href="http://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>

BIN
game_sudoku/static/description/sudoku 1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
game_sudoku/static/description/user group.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
game_sudoku/static/description/won.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

283
game_sudoku/static/src/css/sudoku.css

@ -0,0 +1,283 @@
.o_entertainment_games_req_footer{
display:none;
}
.sudokupage
{
height: 650px;
width:100%;
background-color: #CDD5F4;
}
.sudokupage1
{
height: auto;
width:25%;
float: left;
margin-top: 250px;
}
.sudokupage2
{
height: 650px;
width:55%;
float: left;
background-color: #CDD5F4;
}
.sudokupage2 h3
{
color: red;
font-size: 28px;
}
.sudokupage2 h4
{
color: red;
font-size: 20px;
}
.sudokupage3
{
height: auto;
width:20%;
float:right;
background-color: #CDD5F4;
}
.sudokunewbutton {
border-radius: 4px;
background-color: #4CAF50;
border: none;
color: #FFFFFF;
text-align: center;
font-size: 22px;
padding: 15px;
width: 170px;
height:55px;
transition: all 0.5s;
cursor: pointer;
margin: 5px;
}
.sudokulevelbutton {
border-radius: 3px;
background-color: #4CAF50;
border: none;
color: #FFFFFF;
text-align: center;
font-size: 22px;
padding: 15px;
width: 170px;
height:55px;
transition: all 0.5s;
cursor: pointer;
margin: 5px;
}
.sudokulevelbuttonreset {
border-radius: 3px;
display: none;
background-color: #4CAF50;
border: none;
color: #FFFFFF;
text-align: center;
font-size: 22px;
padding: 15px;
width: 170px;
height:55px;
transition: all 0.5s;
cursor: pointer;
margin: 5px;
}
.sudokulevelbuttoncheck {
border-radius: 3px;
display: none;
background-color: #4CAF50;
border: none;
color: #FFFFFF;
text-align: center;
font-size: 22px;
padding: 15px;
width: 170px;
height:55px;
transition: all 0.5s;
cursor: pointer;
margin: 5px;
}
.sudokulevelbuttoncheckback {
border-radius: 3px;
display: none;
background-color: #4CAF50;
border: none;
color: #FFFFFF;
text-align: center;
font-size: 22px;
padding: 15px;
width: 170px;
height:55px;
transition: all 0.5s;
cursor: pointer;
margin: 5px;
}
.sudokulevelbuttonsolve {
border-radius: 3px;
display: none;
background-color: #4CAF50;
border: none;
color: #FFFFFF;
text-align: center;
font-size: 22px;
padding: 15px;
width: 170px;
height:55px;
transition: all 0.5s;
cursor: pointer;
margin: 5px;
}
.sudokulevelbutton1 {
border-radius: 3px;
background-color: #00b3b3;
border: none;
color: #FFFFFF;
text-align: center;
font-size: 22px;
padding: 15px;
width: 170px;
height:55px;
transition: all 0.5s;
cursor: pointer;
margin: 5px;
}
.sudokulevelbutton2 {
border-radius: 3px;
background-color: #00b3b3;
border: none;
color: #FFFFFF;
text-align: center;
font-size: 22px;
padding: 15px;
width: 170px;
height:55px;
transition: all 0.5s;
cursor: pointer;
margin: 5px;
}
.sudokulevelbutton3 {
border-radius: 3px;
background-color: #00b3b3;
border: none;
color: #FFFFFF;
text-align: center;
font-size: 22px;
padding: 15px;
width: 170px;
height:55px;
transition: all 0.5s;
cursor: pointer;
margin: 5px;
}
.sudokulevelselection {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
.sudokulevelselection-content {
position: relative;
background-color: #fefefe;
margin: auto;
padding: 0;
border: 1px solid #888;
width: 80%;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
-webkit-animation-name: animatetop;
-webkit-animation-duration: 0.4s;
animation-name: animatetop;
animation-duration: 0.4s
}
@-webkit-keyframes animatetop {
from {top:-300px; opacity:0}
to {top:0; opacity:1}
}
@keyframes animatetop {
from {top:-300px; opacity:0}
to {top:0; opacity:1}
}
.sudokulevelselectionclose {
color: white;
float: right;
font-size: 28px;
font-weight: bold;
}
.sudokulevelselection:hover,
.sudokulevelselection:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.sudokulevelselection-header {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
.sudokulevelselection-body {padding: 2px 16px;}
.sudokulevelselection-footer {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
table.sudoright td {width: 50px; height:80px;
font-weight: bold;
text-align: center
}
table.sudoright {
margin-top: 120px;
}
table.sudoku td {width: 55px; height:55px;
border-width: 1px;
border-style: solid;
border-color: black;
font-weight: bold;
text-align: center
}
table.sudoku {
border-width: 3px;
border-style: solid;
border-color:black;
}
table.sudoku td[id^=cell_0] {border-bottom-width: 3px;border-bottom-style: double;}
table.sudoku td[id^=cell_1] {border-bottom-width: 3px;border-bottom-style: double;}
table.sudoku td[id^=cell_2] {border-bottom-width: 3px}
table.sudoku td[id^=cell_3] {border-bottom-width: 3px;border-bottom-style: double;}
table.sudoku td[id^=cell_4] {border-bottom-width: 3px;border-bottom-style: double;}
table.sudoku td[id^=cell_5] {border-bottom-width: 3px}
table.sudoku td[id^=cell_6] {border-bottom-width: 3px;border-bottom-style: double;}
table.sudoku td[id^=cell_7] {border-bottom-width: 3px;border-bottom-style: double;}
table.sudoku td[id$=_0] {border-right-width: 3px;border-right-style: double;}
table.sudoku td[id$=_1] {border-right-width: 3px;border-right-style: double;}
table.sudoku td[id$=_2] {border-right-width: 3px}
table.sudoku td[id$=_3] {border-right-width: 3px;border-right-style: double;}
table.sudoku td[id$=_4] {border-right-width: 3px;border-right-style: double;}
table.sudoku td[id$=_5] {border-right-width: 3px}
table.sudoku td[id$=_6] {border-right-width: 3px;border-right-style: double;}
table.sudoku td[id$=_7] {border-right-width: 3px;border-right-style: double;}
td.selected {background-color: rgb(100%, 70%, 0%)}
td.tofill {color: blue;background-color: #f2ffde }
td.filled {color: blue;background-color: #c0ff96}
td.green{color:green;background-color: #fff}
td.red{color:red;background-color:#FC9E9E;border-color: red;border-width: 1.5px}
td.notfill {color: green;font-style:bold;background-color: #cac5c3;}

BIN
game_sudoku/static/src/img/application-switcher-bg.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

54
game_sudoku/static/src/js/game.js

@ -0,0 +1,54 @@
odoo.define('game_sudoku.models_entertainment_game', function (require) {
"use strict";
var core = require('web.core');
var Widget = require('web.Widget');
var QWeb = core.qweb;
var _t = core._t;
var MyGame = Widget.extend({
events: {
"click .o_entertainment_games_log_in_icon": function() {
this.$('.o_entertainment_games_log_in_icon').attr("disabled", "disabled");
this.$('.o_entertainment_games_req_footer').css('display', 'block');
this.game_request();
},
},
start: function () {
var self = this;
var def = this._rpc({
model: 'hr.employee',
method: 'search_read',
args: [[['user_id', '=', this.getSession().uid]], ['attendance_state', 'name']],
})
.then(function (res) {
if (_.isEmpty(res) ) {
self.$('.o_hr_attendance_employee').append(_t("Error : Could not find employee linked to user"));
return;
}
self.employee = res[0];
self.$el.html(QWeb.render("EntertainmentGamesMainMenu", {widget: self}));
});
return $.when(def, this._super.apply(this, arguments));
},
game_request: function () {
var self = this;
this._rpc({
model: 'employee.game.approve',
method: 'create_employee_game_approve',
args: [1, this.employee.id, this.getSession().uid],
})
},
});
core.action_registry.add('entertainment_games_my_game', MyGame);
return MyGame;
});

1008
game_sudoku/static/src/js/sudoku.js

File diff suppressed because it is too large

119
game_sudoku/static/src/less/games.less

@ -0,0 +1,119 @@
.o_entertainment_games_log_in_icon {
font-size: 15em;
cursor: pointer;
margin: 20px 0px 20px 0px;
padding: 0px 15px 0px 15px;
border-radius: 10%;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.6);
}
.o_entertainment_games_kiosk_mode_container {
.o-flex-display();
.o-flex-flow(column, nowrap);
.o-justify-content(center);
.o-align-items(center);
@media (min-width: @screen-xs-max) {
background: url("../img/application-switcher-bg.jpg") no-repeat center center fixed;
background-size: cover;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}
/************** MIXINS for ANIMATIONS *************/
.o-display-marked(@content, @top, @left, @color) {
position: absolute;
top: @top;
left: @left;
font-size: 150px;
font-family: "FontAwesome";
content: @content;
color: @color;
animation: markAnim ease-in-out 10s;
animation-iteration-count: 5;
transform-origin: 50% 50%;
animation-fill-mode:forwards; /*when the spec is finished*/
-webkit-animation: markAnim ease-in-out 10s;
-webkit-animation-iteration-count: 1;
-webkit-transform-origin: 50% 50%;
-webkit-animation-fill-mode:forwards; /*Chrome 16+, Safari 4+*/
-moz-animation: markAnim ease-in-out 10s;
-moz-animation-iteration-count: 1;
-moz-transform-origin: 50% 50%;
-moz-animation-fill-mode:forwards; /*FF 5+*/
-o-animation: markAnim ease-in-out 10s;
-o-animation-iteration-count: 1;
-o-transform-origin: 50% 50%;
-o-animation-fill-mode:forwards; /*Not implemented yet*/
-ms-animation: markAnim ease-in-out 10s;
-ms-animation-iteration-count: 1;
-ms-transform-origin: 50% 50%;
-ms-animation-fill-mode:forwards; /*IE 10+*/
@media (max-width: 992px) {
left: 40%;
font-size: 30vw;
}
}
.o_wow_thumbs:after {
.o-display-marked("You Won \A \f164 \00a0 - \f118", 20%, 40%, #21b799);
white-space: pre;
}
.o_lost_thumbs:after {
.o-display-marked("You Lost \A \f165 \00a0 - \f119", 20%, 40%, #b73720);
white-space: pre;
}
.o_entertainment_games_kiosk_mode {
width: 100%;
text-align: center;
position: relative;
background-color: #fff;
padding: 2em;
h1 {
margin: 0 0 2rem 0;
}
.message_demo_barcodes {
font-size: 0.9em;
margin: 0;
}
img {
overflow:hidden; // prevent margins colapsing with h1
margin-top: 3rem;
width: 200px;
}
p {
text-align: left;
margin: 3rem 0;
}
> button {
font-size: 1.2em;
margin-bottom: 2rem;
width: 100%;
}
> button:last-child {
margin-bottom: 0;
}
@media (min-width: @screen-xs-max) {
flex: 0 0 auto;
width: 550px;
border-radius: 10px;
background-color: rgba(255,255,255,0.8);
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.6);
font-size: 1.2em;
padding: 3em;
}
}

20
game_sudoku/static/src/xml/game.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<template xml:space="preserve">
<t t-name="EntertainmentGamesMainMenu">
<div class="o_entertainment_games_kiosk_mode_container">
<div class="o_entertainment_games_kiosk_mode">
<t t-if="widget.employee">
<h1>Welcome <t t-esc="widget.employee.name"/></h1>
<h2>Click to start Games</h2>
<i class="fa fa-gamepad btn-primary o_entertainment_games_log_in_icon" style="color: #f9f9f9;background: #a3498b;"/>
<div class="o_entertainment_games_req_footer">
<h3>Just wait for approval</h3>
</div>
</t>
<t t-if="!widget.employee">
Error : Could not find employee linked to user.
</t>
</div>
</div>
</t>
</template>

161
game_sudoku/static/src/xml/sudoku.xml

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<template xml:space="preserve">
<t t-name="EntertainmentGamesSudoku">
<div class="sudokupage" groups="hr.group_hr_user">
<div class ="sudokupage1">
</div>
<div class="sudokupage2">
<h3 align='center' class="sudo"> </h3>
<table align="center" class="sudoku" cellspacing="0">
<tr>
<td id="cell_0_0">s</td>
<td id="cell_0_1">8</td>
<td id="cell_0_2"></td>
<td id="cell_0_3"></td>
<td id="cell_0_4">d</td>
<td id="cell_0_5">4</td>
<td id="cell_0_6"></td>
<td id="cell_0_7">k</td>
<td id="cell_0_8">1</td>
</tr>
<tr>
<td id="cell_1_0"></td>
<td id="cell_1_1">1</td>
<td id="cell_1_2">d</td>
<td id="cell_1_3"></td>
<td id="cell_1_4">3</td>
<td id="cell_1_5">s</td>
<td id="cell_1_6"></td>
<td id="cell_1_7">7</td>
<td id="cell_1_8">u</td>
</tr>
<tr>
<td id="cell_2_0">u</td>
<td id="cell_2_1">5</td>
<td id="cell_2_2"></td>
<td id="cell_2_3"></td>
<td id="cell_2_4"></td>
<td id="cell_2_5">S</td>
<td id="cell_2_6">9</td>
<td id="cell_2_7"></td>
<td id="cell_2_8"></td>
</tr>
<tr>
<td id="cell_3_0"></td>
<td id="cell_3_1"></td>
<td id="cell_3_2">8</td>
<td id="cell_3_3"></td>
<td id="cell_3_4"></td>
<td id="cell_3_5">4</td>
<td id="cell_3_6">D</td>
<td id="cell_3_7"></td>
<td id="cell_3_8">o</td>
</tr>
<tr>
<td id="cell_4_0">d</td>
<td id="cell_4_1"></td>
<td id="cell_4_2"></td>
<td id="cell_4_3"></td>
<td id="cell_4_4">
<h4>SUDOKU</h4>
</td>
<td id="cell_4_5"></td>
<td id="cell_4_6">5</td>
<td id="cell_4_7"></td>
<td id="cell_4_8"></td>
</tr>
<tr>
<td id="cell_5_0">o</td>
<td id="cell_5_1">5</td>
<td id="cell_5_2">k</td>
<td id="cell_5_3">6</td>
<td id="cell_5_4"></td>
<td id="cell_5_5">s</td>
<td id="cell_5_6">2</td>
<td id="cell_5_7"></td>
<td id="cell_5_8"></td>
</tr>
<tr>
<td id="cell_6_0"></td>
<td id="cell_6_1">8</td>
<td id="cell_6_2"></td>
<td id="cell_6_3"></td>
<td id="cell_6_4">4</td>
<td id="cell_6_5"></td>
<td id="cell_6_6"></td>
<td id="cell_6_7">3</td>
<td id="cell_6_8"></td>
</tr>
<tr>
<td id="cell_7_0">k</td>
<td id="cell_7_1">1</td>
<td id="cell_7_2"></td>
<td id="cell_7_3"></td>
<td id="cell_7_4">8</td>
<td id="cell_7_5"></td>
<td id="cell_7_6">k</td>
<td id="cell_7_7"></td>
<td id="cell_7_8">9</td>
</tr>
<tr>
<td id="cell_8_0">u</td>
<td id="cell_8_1">u</td>
<td id="cell_8_2">3</td>
<td id="cell_8_3">9</td>
<td id="cell_8_4">s</td>
<td id="cell_8_5"></td>
<td id="cell_8_6">5</td>
<td id="cell_8_7"></td>
<td id="cell_8_8"></td>
</tr>
</table>
</div>
<div class= "sudokupage3">
<h2 id="demo"> </h2>
<form>
<table align="center" class="sudoright" cellspacing="20" style="margin top=10px:">
<tr>
<td>
<input type="button" class="sudokunewbutton" value="New Game" />
<div id="sudoku_level_selection_modal" class="sudokulevelselection">
<div class="sudokulevelselection-content">
<div class="sudokulevelselection-header">
<span class="sudokulevelselectionclose">*</span>
<h2>Level of Mode</h2>
</div>
<div class="sudokulevelselection-body">
<input type="button" class="sudokulevelbutton1" value="Easy" />
<input type="button" class="sudokulevelbutton2" value="Medium" />
<input type="button" class="sudokulevelbutton3" value="Hard" />
</div>
<div class="sudokulevelselection-footer">
<h3>Test Your Skill with Different Levels.</h3>
</div>
</div>
</div>
</td>
</tr>
<tr>
<td>
<input type="button" class="sudokulevelbuttonreset" value="Reset"/>
</td>
</tr>
<tr>
<td>
<input type="button" class="sudokulevelbuttoncheck" value="Check it"/>
<input type="button" class="sudokulevelbuttoncheckback" value="Redo"/>
</td>
</tr>
<tr>
<td>
<input type="button" class="sudokulevelbuttonsolve" value="Solution"/>
</td>
</tr>
</table>
</form>
</div>
</div>
</t>
</template>

9
game_sudoku/views/game_approve_sequence.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="sequence_game_approve_sequence" model="ir.sequence">
<field name="name">Game Approve</field>
<field name="code">employee.game</field>
</record>
</data>
</odoo>

13
game_sudoku/views/game_template.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="assets_backend" name="entertainment_games assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/game_sudoku/static/src/js/game.js"></script>
<script type="text/javascript" src="/game_sudoku/static/src/js/sudoku.js"></script>
<link rel="stylesheet" href="/game_sudoku/static/src/less/games.less"/>
<link rel="stylesheet" href="/game_sudoku/static/src/css/sudoku.css"/>
</xpath>
</template>
</data>
</odoo>

48
game_sudoku/views/main_menu.xml

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="action_entertainment_games_request" model="ir.actions.client">
<field name="name">Game Approval</field>
<field name="tag">entertainment_games_my_game</field>
<field name="target">main</field>
</record>
<record id="game_approval_tree" model="ir.ui.view">
<field name="name">employee.game.approve.tree</field>
<field name="model">employee.game.approve</field>
<field name="arch" type="xml">
<tree string="Game Approval" create="false" edit="false">
<field name="name"/>
<field name="department_id"/>
<field name="approve_datetime"/>
<field name="game_user"/>
<field name="user_id" invisible="1"/>
<field name="state" invisible="1"/>
<button name="approve" string="Confirm" type="object" icon="fa-check"
attrs="{'invisible':[('state','!=', 'draft')]}"/>
<button name="cancel" string="Cancel" type="object" icon="fa-close"
attrs="{'invisible':[('state','=', 'cancel')]}"/>
</tree>
</field>
</record>
<record id="action_entertainment_games_approval_tree" model="ir.actions.act_window">
<field name="name">Game Approval</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">employee.game.approve</field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="view_id" ref="game_approval_tree"/>
</record>
<menuitem id="entertainment_games_menu" name="Games" sequence="105" groups="base.group_user"/>
<menuitem id="entertainment_games_approval_request_menu" name="May I Play?" sequence="1"
action="action_entertainment_games_request" parent="entertainment_games_menu"
groups="game_sudoku.odoo_gamer_approve_req"/>
<menuitem id="entertainment_games_approval_menu" name="Game Request" sequence="2"
action="action_entertainment_games_approval_tree" parent="entertainment_games_menu"
groups="hr.group_hr_manager"/>
</data>
</odoo>

14
game_sudoku/views/sudoku_menu.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="action_entertainment_games_sudoku" model="ir.actions.client">
<field name="name">Sudoku</field>
<field name="tag">entertainment_games_sudoku</field>
<field name="target">main</field>
</record>
<menuitem id="entertainment_games_sudoku_menu" name="Sudoku" sequence="5"
action="action_entertainment_games_sudoku" parent="entertainment_games_menu"
groups="game_sudoku.odoo_gamer_group"/>
</data>
</odoo>

19
quotation_handler/README.rst

@ -0,0 +1,19 @@
Quotation Revised History v10
=============================
The clients will require negotiations whenever we sent a quotation to them.In such cases we need to edit the
Quotation's order lines. We have included the 'Revise the Quotation' button for it. The order lines can be edited
by a click on this button. At the same time a history or copy of the quotation will also be generated automatically.
We can track the history using the smart buttons.
Every quotations have a expiration date which we set manually.On configuring the above shown settings we can
automatically set the expiration date very easily.
Features
========
* Retrieve the History of Revised Quotations.
* Automatically Set Expiration Date For Quotation.
* Email Template Contains The Expiration Date.
Credits
=======
Nikhil Krishnan @ cybrosys, nikhil@cybrosys.in

23
quotation_handler/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2018-TODAY NIKHIL KRISHNAN(nikhilkrishnan0101@gmail.com).
# Author: Nikhil krishnan(nikhilkrishnan0101@gmail.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 . import models

44
quotation_handler/__manifest__.py

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2018-TODAY NIKHIL KRISHNAN(nikhilkrishnan0101@gmail.com).
# Author: Nikhil krishnan(nikhilkrishnan0101@gmail.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': 'Quotation Revised History',
'version': '11.0.1.0.0',
'summary': """We Can Retrieve the History of Revised Quotations.""",
'description': """ Negotiations with clients and we resent multiple Quotations,
This module store the History of Every Quotations""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'website': 'http://www.cybrosys.com',
'category': 'Sales Management',
'depends': ['sale'],
'license': 'LGPL-3',
'data': [
'views/quotation_handler.xml',
'views/sale_config_settings_exp_date_views.xml',
'data/mail_template_data_exp_date.xml',
],
'demo': [],
'images': ['static/description/banner.jpg'],
'installable': True,
'auto_install': False,
}

69
quotation_handler/data/mail_template_data_exp_date.xml

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!--Email template -->
<record id="sale.email_template_edi_sale" model="mail.template">
<field name="name">Sales Order - Send by Email</field>
<field name="email_from">${(object.user_id.email and '&quot;%s&quot; &lt;%s&gt;' % (object.user_id.name, object.user_id.email) or '')|safe}</field>
<field name="subject">${object.company_id.name} ${object.state in ('draft','pre', 'sent') and 'Quotation' or 'Order'} (Ref ${object.name or 'n/a' })</field>
<field name="partner_to">${object.partner_id.id}</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="sale.action_report_saleorder"/>
<field name="report_name">${(object.name or '').replace('/','_')}${object.state == 'draft' and '_draft' or ''}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="body_html"><![CDATA[
<p>Dear ${object.partner_id.name}
% set access_action = object.with_context(force_website=True).get_access_action()
% set is_online = access_action and access_action['type'] == 'ir.actions.act_url'
% set doc_name = 'quotation' if object.state in ('draft','pre', 'sent') else 'order confirmation'
% set pay_sign_name = object.get_portal_confirmation_action()
% set access_name = is_online and object.state in ('draft', 'pre', 'sent') and pay_sign_name in ('pay', 'sign') and 'Accept and %s online' % pay_sign_name or 'View %s' % doc_name
% set access_url = is_online and object.get_mail_url() or ''
% if object.partner_id.parent_id:
(<i>${object.partner_id.parent_id.name}</i>)
% endif
,</p>
<p>
Here is
% if ctx.get('proforma')
in attachment, your pro-forma invoice
% else
the ${doc_name} <strong>${object.name}</strong>
% endif
% if object.origin:
(with reference: ${object.origin} )
% endif
amounting in <strong>${format_amount(object.amount_total, object.currency_id)}</strong>
from ${object.company_id.name}.
</p>
% if is_online and not ctx.get('proforma'):
<br/><br/>
<center>
<a href="${access_url}" style="background-color: #1abc9c; padding: 20px; text-decoration: none; color: #fff; border-radius: 5px; font-size: 16px;" class="o_default_snippet_text">${access_name}</a>
<br/><br/><br/>
<span style="color:#888888">(or view attached PDF)</span>
</center>
<br/>
% endif
% if object.state == "pre" or object.state == "draft" or object.state == "sent" :
% if object.validity_date:
<p> Your quotation will expire on <strong>${object.validity_date}</strong>.</p>
% endif
% endif
<p>You can reply to this email if you have any questions.</p>
<p>Thank you,</p>
<p style="color:#888888;">
% if object.user_id and object.user_id.signature:
${object.user_id.signature | safe}
% endif
</p>
]]></field>
</record>
</data>
</odoo>

24
quotation_handler/models/__init__.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2018-TODAY NIKHIL KRISHNAN(nikhilkrishnan0101@gmail.com).
# Author: Nikhil krishnan(nikhilkrishnan0101@gmail.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 . import sale
from . import sale_config_settings_exp_date_views

144
quotation_handler/models/sale.py

@ -0,0 +1,144 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2018-TODAY NIKHIL KRISHNAN(nikhilkrishnan0101@gmail.com).
# Author: Nikhil krishnan(nikhilkrishnan0101@gmail.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, _
from datetime import timedelta, datetime
class SaleOrder(models.Model):
_inherit = 'sale.order'
name = fields.Char(string='Order Reference', required=True, copy=False, readonly=True,
index=True, default='New')
parent_so_id = fields.Many2one('sale.order', 'Parent SO', copy=False)
revised_order_count = fields.Integer(string='# of Revised Orders', compute='_revised_count')
validity_date = fields.Date(string='Expiration Date', readonly=True, states={'draft': [('readonly', False)],
'pre': [('readonly', False)]},
help="Automatically expiration date of your quotation (offer) will set as 14 days "
"later, or it will set the date automatically based on the settings, We can set "
"it manually too.")
state = fields.Selection([
('pre', 'Revised Quotation'),
('draft', 'Quotation'),
('sent', 'Quotation Sent'),
('revised', 'Revised'),
('sale', 'Sale Order'),
('done', 'Done'),
('cancel', 'Cancelled'),
], string='Status', readonly=True, copy=False, index=True, track_visibility='onchange', default='draft')
revision_number = fields.Integer(string='Revision', copy=False, default=1)
org_name = fields.Char(string='Origin', copy=False)
@api.model
def create(self, vals):
date_type = self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date'),
date_start = self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date_start'),
if int(date_type[0]):
if not int(date_start[0]):
if 'validity_date' in vals:
if vals.get('validity_date'):
pass
else:
date_no = self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date_no')
date_today = fields.Date.today()
date_object = datetime.strptime(date_today, '%Y-%m-%d')
if not int(date_no):
pass
else:
v_date = date_object + timedelta(days=int(date_no))
vals['validity_date'] = v_date
return super(SaleOrder, self).create(vals)
@api.multi
def _revised_count(self):
for sale in self:
revised_count = sale.search([('parent_so_id', '=', sale.id)])
sale.revised_order_count = len(revised_count)
# ********************Overwrite the print button to give expiration date********************
@api.multi
def print_quotation(self):
is_date = int(self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date'))
date_start = int(self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date_start'))
date_no = int(self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date_no'))
if is_date:
if date_start:
if date_no:
for doc in self:
if doc.state in ['pre', 'draft']:
date_today = fields.Date.today()
date_object = datetime.strptime(date_today, '%Y-%m-%d')
v_date = date_object + timedelta(days=date_no)
doc.validity_date = v_date
self.filtered(lambda s: s.state == 'pre').write({'state': 'sent'})
return super(SaleOrder, self).print_quotation()
@api.multi
def make_revision(self):
for rec in self:
if not rec.org_name:
namee = rec.name + '/R' + str(rec.revision_number)
rec.org_name = rec.name
else:
namee = rec.org_name + '/R' + str(rec.revision_number)
if not rec.org_name:
names = rec.name
else:
names = rec.org_name
vals = {
'name': names + "-" + str(rec.revision_number),
'state': 'revised',
'parent_so_id': rec.id
}
new_so_copy = rec.copy(default=vals)
rec.state = 'pre'
rec.name = namee
rec.revision_number += 1
date_start = self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date_start')
if date_start:
rec.validity_date = False
class MailComposeMessage(models.TransientModel):
_inherit = 'mail.compose.message'
@api.multi
def send_mail(self, auto_commit=False):
if self._context.get('default_model') == 'sale.order' and self._context.get('default_res_id') and self._context.get('mark_so_as_sent'):
order = self.env['sale.order'].browse([self._context['default_res_id']])
# ********************Email Sent action Change the State in pre stage too********************
if order.state in ('draft', 'pre'):
order.state = 'sent'
date_start = int(self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date_start'))
if date_start:
# ********************Email Sent action Set the Exp Date From settings********************
date_no = int(self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date_no'))
date_today = fields.Date.today()
date_object = datetime.strptime(date_today, '%Y-%m-%d')
if date_no:
v_date = date_object + timedelta(days=date_no)
order.validity_date = v_date
self = self.with_context(mail_post_autofollow=True)
return super(MailComposeMessage, self).send_mail(auto_commit=auto_commit)

62
quotation_handler/models/sale_config_settings_exp_date_views.py

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2018-TODAY NIKHIL KRISHNAN(nikhilkrishnan0101@gmail.com).
# Author: Nikhil krishnan(nikhilkrishnan0101@gmail.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 api, fields, models
class SaleConfiguration(models.TransientModel):
_inherit = 'res.config.settings'
so_expiration_date = fields.Selection([('0', "No Default Expiration Date"), ('1', "Default 14 days"),
('2', 'Created as company rule')], "Expiration Date",
default='0', help="Allows you to set Expiration Date.")
so_expiration_date_start = fields.Selection([('0', "Quotation Creation Date"),
('1', "Quotation Sent Date")],
"Expiration Date Start from", default='0',
help="Allows you to set Expiration Date Start from.")
so_expiration_date_no = fields.Integer(string="No.of Days")
@api.model
def get_values(self):
res = super(SaleConfiguration, self).get_values()
a = self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date_no')
res.update(
so_expiration_date=self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date'),
so_expiration_date_start=self.env['ir.config_parameter'].sudo().get_param('quotation_handler.so_expiration_date_start'),
so_expiration_date_no=int(a)
)
return res
@api.multi
def set_values(self):
super(SaleConfiguration, self).set_values()
a = self.so_expiration_date
print("type", type(a))
if a == '0':
so_expiration_date_nos = False
elif a == '1':
so_expiration_date_nos = 14
else:
so_expiration_date_nos = self.so_expiration_date_no
self.env['ir.config_parameter'].sudo().set_param('quotation_handler.so_expiration_date', self.so_expiration_date)
self.env['ir.config_parameter'].sudo().set_param('quotation_handler.so_expiration_date_start', self.so_expiration_date_start)
self.env['ir.config_parameter'].sudo().set_param('quotation_handler.so_expiration_date_no', int(so_expiration_date_nos))

BIN
quotation_handler/static/description/banner.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
quotation_handler/static/description/cybro_logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
quotation_handler/static/description/editable line.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
quotation_handler/static/description/email template.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
quotation_handler/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

189
quotation_handler/static/description/index.html

@ -0,0 +1,189 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">Quotation Revised History</h2>
<h3 class="oe_slogan">Retrieve the History of Revised Quotations</h3>
<h4 class="oe_slogan">Author : Cybrosys Techno Solutions , www.cybrosys.com</h4>
<div>
<h4><p>Features:</p></h4>
<ul>
<li style="list-style:none !important;"><span style="color:green;"> &#9745;</span>&nbsp;&nbsp; Retrieve the history of revised quotations.</li>
<li style="list-style:none !important;"><span style="color:green;"> &#9745;</span>&nbsp;&nbsp; Automatically set expiration date for quotation.</li>
<li style="list-style:none !important;"><span style="color:green;"> &#9745;</span>&nbsp;&nbsp; Email template contains the expiration date.</li>
</ul>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Quotation in "Quotation Sent" state</h3>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="sent state.png">
</div>
</div>
<div class="oe_span12">
<p class="oe_mt32">
The clients will require negotiations whenever we sent a quotation to them.In such cases we need to edit the Quotation's order lines.
We have included the 'Revise the Quotation' button for it. The order lines can be edited by a click on this button.
At the same time a history or copy of the quotation will also be generated automatically.We can track the history using the smart buttons.
</p>
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Quotation in "Revised Quotation" state</h3>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="revised state.png">
</div>
</div>
<div class="oe_span12">
<p class="oe_mt32">
In the Revised Quotation state, we can edit the order lines and resent to the client.
<p>Quotation Sent ---> Revised Quotation ---> Quotation Sent</p>
<p>The smart button on the top right of the form will provide the entire revised history of quotation.
The revised quotation will be indicated by a change in name format as (initial name/R1) in a recurring manner.</p>
</p>
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img src="sent state not editable.png">
</div>
<p class="oe_mt32">
<p>In the Quotation Sent state we can't edit the Order lines. When we need to revise just click on
the "Revise the Quotation" button.</p>
</p>
</div>
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img src="editable line.png">
</div>
<p class="oe_mt32">
<p>In the Revised Quotation state we can edit the order lines and resend it through mail or
take print out with new order lines.</p>
</p>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Quotation History</h3>
<div class="oe_row oe_spaced">
<p>
<ul>
<li>Smart button redirect you to the Quotation History.</li>
</ul>
<ul>
<li>Tree view of the Revised Quotations of the particular parent quotation.</li>
</ul>
</p>
</div>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="revised tree.png">
</div>
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Quotation in "Revised" state</h3>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="revised form view.png">
</div>
</div>
<div class="oe_span12">
<p class="oe_mt32">
In this state we can't edit anything, it's just for a view.
</p>
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Quotation Email template</h3>
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="email template.png">
</div>
</div>
<div class="oe_span12">
<p class="oe_mt32">
If we gave expiration date then it will mention in the Email
</p>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Quotations & Sales Settings</h3>
<div class="oe_span12">
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="settings.png">
</div>
</div>
<div class="oe_span12">
<p class="oe_mt32">
Sales --> Configuration --> Settings ---> Quotations & Sales --> Expiration Date
</p>
<p>
Every quotations have a expiration date which we set manually.On configuring the above shown settings we can
automatically set the expiration date very easily.
<p>No Expiration date: No changes(we have to set the date manually)</p>
<p>Default 14 days: The expiration date calculated from Quotation Creation Date or form Quotation Sent Date is set for 14 days.</p>
<p>Created as company rule: The quotation will expire as per the custom days set by user from Quotation Creation Date or from the Quotation Sent Date . </p>
</p>
<p>Expiration Date Calculated From : Choose either of the two, Quotation Creation Date or Quotation Sent Date</p>
</div>
</div>
</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="http://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="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;border-radius: 0;"
href="http://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>

BIN
quotation_handler/static/description/revised form view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
quotation_handler/static/description/revised state.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
quotation_handler/static/description/revised tree.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
quotation_handler/static/description/sent state not editable.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
quotation_handler/static/description/sent state.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
quotation_handler/static/description/settings.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

112
quotation_handler/views/quotation_handler.xml

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="act_sale_order_2_revised" model="ir.actions.act_window">
<field name="name">Revised Quotation Orders</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="sale.view_quotation_tree"/>
<field name="domain">[('parent_so_id', '=', active_id)]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Revised order against this Quotation Order.
</p>
</field>
</record>
<!--In sale order menu, we need to avoid the 'revised' state orders. -->
<record id="sale.action_orders" model="ir.actions.act_window">
<field name="name">Sales Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
<field name="search_view_id" ref="sale.sale_order_view_search_inherit_sale"/>
<field name="context">{}</field>
<field name="domain">[('state', 'not in', ('draft','revised','sent', 'cancel'))]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Create a Quotation, the first step of a new sale.
</p><p>
Once the quotation is confirmed, it becomes a sales order.
You'll be able to invoice it and collect payments.
From the <i>Sales Orders</i> menu, you can track delivery
orders or services.
</p>
</field>
</record>
<record id="sale.action_quotations" model="ir.actions.act_window">
<field name="name">Quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_id" ref="sale.view_quotation_tree"/>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
<field name="context">{}</field>
<field name="domain">[('state','in',('pre','draft','sent','cancel'))]</field>
<field name="search_view_id" ref="sale.view_sales_order_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Create a Quotation, the first step of a new sale.
</p><p>
Your next actions should flow efficiently: confirm the Quotation
to a Sale Order, then create the Invoice and collect the Payment.
</p><p>
Note that once a Quotation becomes a Sale Order, it will be moved
from the Quotations list to the Sales Order list.
</p>
</field>
</record>
<record id="view_order_form_revised" model="ir.ui.view">
<field name="name">sale.order.form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form" />
<field name="arch" type="xml">
<xpath expr="//button[@name='action_confirm']" position="after">
<button name="make_revision" string="Revise the Quotation" type="object" states="sent" class="btn-primary"/>
<button name="action_quotation_send" string="Send by Email" type="object" states="pre" class="btn-primary"/>
<button name="print_quotation" string="Print" type="object" states="pre" class="btn-primary"/>
<button name="action_cancel" states="pre" type="object" string="Cancel"/>
</xpath>
<xpath expr="//div[@name='button_box']" position="inside">
<button class="oe_inline oe_stat_button" type="action" name="%(act_sale_order_2_revised)d"
icon="fa-bars" attrs="{'invisible':[('state','in',('draft','revised'))]}">
<field string="Revised Quotation Orders" name="revised_order_count" widget="statinfo"/>
</button>
</xpath>
<xpath expr="//field[@name='order_line']" position="attributes">
<attribute name="attrs">{'readonly': [('state', 'in', ('sent','revised','done','cancel'))]}</attribute>
</xpath>
<xpath expr="//field[@name='payment_term_id']" position="attributes">
<attribute name="attrs">{'readonly': [('state', 'in', ('sent','revised','done','cancel'))]}</attribute>
</xpath>
<xpath expr="//field[@name='user_id']" position="attributes">
<attribute name="attrs">{'readonly': [('state', 'in', ('sent','revised','done','cancel'))]}</attribute>
</xpath>
<xpath expr="//field[@name='team_id']" position="attributes">
<attribute name="attrs">{'readonly': [('state', 'in', ('sent','revised','done','cancel'))]}</attribute>
</xpath>
</field>
</record>
<record id="view_quotation_handler_tree" model="ir.ui.view">
<field name="name">sale.order.tree</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_quotation_tree" />
<field name="arch" type="xml">
<xpath expr="//field[@name='state']" position="replace">
<field name="state"/>
</xpath>
</field>
</record>
</data>
</odoo>

112
quotation_handler/views/quotation_handler.xml~

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="act_sale_order_2_revised" model="ir.actions.act_window">
<field name="name">Revised Quotation Orders</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="sale.view_quotation_tree"/>
<field name="domain">[('parent_so_id', '=', active_id)]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Revised order against this Quotation Order.
</p>
</field>
</record>
<!--In sale order menu, we need to avoid the 'revised' state orders. -->
<record id="sale.action_orders" model="ir.actions.act_window">
<field name="name">Sales Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
<field name="search_view_id" ref="sale.sale_order_view_search_inherit_sale"/>
<field name="context">{}</field>
<field name="domain">[('state', 'not in', ('draft','revised','sent', 'cancel'))]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Create a Quotation, the first step of a new sale.
</p><p>
Once the quotation is confirmed, it becomes a sales order.
You'll be able to invoice it and collect payments.
From the <i>Sales Orders</i> menu, you can track delivery
orders or services.
</p>
</field>
</record>
<record id="sale.action_quotations" model="ir.actions.act_window">
<field name="name">Quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_id" ref="sale.view_quotation_tree"/>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
<field name="context">{}</field>
<field name="domain">[('state','in',('pre','draft','sent','cancel'))]</field>
<field name="search_view_id" ref="sale.view_sales_order_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Create a Quotation, the first step of a new sale.
</p><p>
Your next actions should flow efficiently: confirm the Quotation
to a Sale Order, then create the Invoice and collect the Payment.
</p><p>
Note that once a Quotation becomes a Sale Order, it will be moved
from the Quotations list to the Sales Order list.
</p>
</field>
</record>
<record id="view_order_form_revised" model="ir.ui.view">
<field name="name">sale.order.form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form" />
<field name="arch" type="xml">
<xpath expr="//button[@name='action_confirm']" position="after">
<button name="make_revision" string="Revise the Quotation" type="object" states="sent" class="btn-primary"/>
<button name="action_quotation_send" string="Send by Email" type="object" states="pre" class="btn-primary"/>
<button name="print_quotation" string="Print" type="object" states="pre" class="btn-primary"/>
<button name="action_cancel" states="pre" type="object" string="Cancel"/>
</xpath>
<xpath expr="//div[@name='button_box']" position="inside">
<button class="oe_inline oe_stat_button" type="action" name="%(act_sale_order_2_revised)d"
icon="fa-bars" attrs="{'invisible':[('state','in',[('draft','revised')]}">
<field string="Revised Quotation Orders" name="revised_order_count" widget="statinfo"/>
</button>
</xpath>
<xpath expr="//field[@name='order_line']" position="attributes">
<attribute name="attrs">{'readonly': [('state', 'in', ('sent','revised','done','cancel'))]}</attribute>
</xpath>
<xpath expr="//field[@name='payment_term_id']" position="attributes">
<attribute name="attrs">{'readonly': [('state', 'in', ('sent','revised','done','cancel'))]}</attribute>
</xpath>
<xpath expr="//field[@name='user_id']" position="attributes">
<attribute name="attrs">{'readonly': [('state', 'in', ('sent','revised','done','cancel'))]}</attribute>
</xpath>
<xpath expr="//field[@name='team_id']" position="attributes">
<attribute name="attrs">{'readonly': [('state', 'in', ('sent','revised','done','cancel'))]}</attribute>
</xpath>
</field>
</record>
<record id="view_quotation_handler_tree" model="ir.ui.view">
<field name="name">sale.order.tree</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_quotation_tree" />
<field name="arch" type="xml">
<xpath expr="//field[@name='state']" position="replace">
<field name="state"/>
</xpath>
</field>
</record>
</data>
</odoo>

42
quotation_handler/views/sale_config_settings_exp_date_views.xml

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="res_config_sale_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.sale</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="10"/>
<field name="inherit_id" ref="base.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]/div[hasclass('app_settings_block')]/div[hasclass('o_settings_container')][3]" position="inside">
<div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_right_pane">
<label for="so_expiration_date" string="Quotation Revised History"/>
<div class="text-muted">
Expiration Date
</div>
<div>
<field name="so_expiration_date" widget="radio" />
<div attrs="{'invisible': [('so_expiration_date', 'not in', ['2'])]}">
<field name="so_expiration_date_no" class="oe_inline"/>
<label for="so_expiration_date_no" string="Days"/>
</div>
</div>
<label for="so_expiration_date_start" string="Expiration Date"
attrs="{'invisible': [('so_expiration_date', 'not in', ['1','2'])]}"/>
<div class="text-muted" attrs="{'invisible': [('so_expiration_date', 'not in', ['1','2'])]}">
Calculated From
</div>
<div>
<div attrs="{'invisible': [('so_expiration_date', 'not in', ['1','2'])]}">
<field name="so_expiration_date_start" widget="radio"/>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</data>
</odoo>
Loading…
Cancel
Save