[MERGE] pos by ahu,mit,ddm,niv

bzr revid: al@openerp.com-20111010211623-lov3zpm0dl6jaf7p
This commit is contained in:
Antony Lesuisse 2011-10-10 23:16:23 +02:00
commit 7399463070
19 changed files with 3898 additions and 1 deletions

View File

@ -679,11 +679,22 @@ class pos_order_line(osv.osv):
pos_order_line()
class pos_category(osv.osv):
_name = 'pos.category'
_inherit = 'product.category'
_columns = {
'parent_id': fields.many2one('pos.category','Parent Category', select=True),
'child_id': fields.one2many('pos.category', 'parent_id', string='Child Categories'),
}
pos_category()
class product_product(osv.osv):
_inherit = 'product.product'
_columns = {
'income_pdt': fields.boolean('Product for Input'),
'expense_pdt': fields.boolean('Product for Output'),
'img': fields.binary('Pos Image, must be 50x50'),
'pos_categ_id': fields.many2one('pos.category','POS Category', change_default=True, domain="[('type','=','normal')]" ,help="Select a pos category for the current product")
}
product_product()

File diff suppressed because one or more lines are too long

View File

@ -594,6 +594,30 @@
</field>
</record>
<!-- Categories tree view -->
<record id="pos_category_tree_view" model="ir.ui.view">
<field name="name">pos.category.tree</field>
<field name="model">pos.category</field>
<field name="type">tree</field>
<field name="field_parent">child_id</field>
<field name="arch" type="xml">
<tree toolbar="True" string="Product Pos Categories">
<field name="name"/>
</tree>
</field>
</record>
<record id="pos_category_action" model="ir.actions.act_window">
<field name="name">Products by POS-Category</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">pos.category</field>
<field name="domain">[('parent_id','=',False)]</field>
<field name="view_type">tree</field>
<field name="view_id" ref="pos_category_tree_view"/>
<field name="help">Here is a list of all your products classified by POS category. You can click a category to get the list of all products linked to this category or to a child of this category.</field>
</record>
<menuitem action="pos_category_action" id="menu_pos_category" parent="menu_point_of_sale_product" sequence="0" />
<!-- END -->
<record id="product_input_output_form_view" model="ir.ui.view">
<field name="name">product.normal.form.inherit</field>
<field name="model">product.product</field>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,478 @@
.point-of-sale {
padding: 0;
margin: 0;
background-color: #f0eeee;
font-family: "Lucida Grande", Helvetica, Verdana, Arial;
color: #555555;
font-size: 12px;
position: relative;
width: 100%;
height: 100%;
}
.point-of-sale table {
border-spacing: 0;
border-collapse: collapse;
}
.point-of-sale td {
border: 1px solid #e9eaec;
}
.point-of-sale input {
color: #555555;
}
.point-of-sale a {
text-decoration: none;
color: #555555;
}
.point-of-sale button, .point-of-sale a.button {
display: inline-block;
cursor: pointer;
padding: 4px 10px;
font-size: 11px;
border: 1px solid #cacaca;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
background: #e2e2e2;
background: -moz-linear-gradient(#f0f0f0, #e2e2e2);
background: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#e2e2e2));
}
.point-of-sale ul, .point-of-sale ol {
padding: 0;
margin: 0;
}
.point-of-sale li {
list-style-type: none;
}
.point-of-sale button img {
vertical-align: bottom;
}
.point-of-sale .pos-rigth-align {
text-align: right;
}
.point-of-sale .pos-rigth-align input {
text-align: right;
}
.point-of-sale #container {
width: 100%;
height: 100%;
}
.point-of-sale #topheader {
width: 100%;
height: 54px;
color: gray;
border-top: solid 1px #d3d3d3;
border-bottom: solid 1px black;
background: #393939;
background: -moz-linear-gradient(#7b7979, #393939);
background: -webkit-gradient(linear, left top, left bottom, from(#7b7979), to(#393939));
}
.point-of-sale #topheader button {
color: black;
border: 1px solid black;
background: #7f82ac;
background: -moz-linear-gradient(#b2b3d7, #7f82ac);
background: -webkit-gradient(linear, left top, left bottom, from(#b2b3d7), to(#7f82ac));
}
.point-of-sale #branding, .point-of-sale #steps, .point-of-sale #rightheader {
float: left;
overflow: hidden;
height: 35px;
padding: 10px;
}
.point-of-sale #branding {
border-right: 1px solid #373737;
text-align: center;
}
.point-of-sale #branding img {
height: 32px;
width: 116px;
}
.point-of-sale #steps {
padding: 10px 17px;
border-right: solid 1px #3b3b3b;
vertical-align: top;
}
.point-of-sale #steps label {
width: 80px;
color: #A5A5A5;
font-weight: bold;
border-color: #454545;
background-color: #454545;
background-image: none;
border-bottom: solid 1px #5c5c5c;
border-top: solid 1px #373737;
vertical-align: top;
}
.point-of-sale #steps label:first-child {
border-left: solid 1px #373737;
}
.point-of-sale #steps label:last-child {
border-right: solid 1px #373737;
}
.point-of-sale #steps span {
padding: 2px 6px;
}
.point-of-sale #steps img {
height: 32px;
}
.point-of-sale #steps .ui-button, .point-of-sale #steps .ui-button-text-only {
padding-top: 4px;
height: 26px;
margin: 0 -4px;
}
.point-of-sale #neworder-button {
width: 32px;
padding: 1px;
font-size: 23px;
}
.point-of-sale #loggedas {
float: right;
padding: 5px 9px;
text-align: center;
color: white;
border-left: 1px solid #373737;
}
.point-of-sale #loggedas p {
margin: 0 0 3px 0;
}
.point-of-sale #content {
width: 100%;
position: absolute;
top: 56px;
bottom: 0;
}
.point-of-sale #leftpane {
height: 100%;
width: 440px;
position: relative;
border-right: solid 1px #afafb6;
background-color: white;
}
.point-of-sale #leftpane footer {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background-color: #e0e0e0;
background-image: url(../img/headerbackground.jpg);
}
.point-of-sale #current-order {
width: 100%;
position: absolute;
top: 0;
bottom: 271px;
overflow: auto;
}
.point-of-sale #current-order thead {
background-color: #cccccc;
background-image: url(../img/headerbackground.jpg);
border: 0px;
font-size: 12px;
width: 440px;
}
.point-of-sale #current-order thead td {
text-align: center;
padding: 8px 0px;
min-width: 40px;
font-size: 12px;
}
.point-of-sale #current-order td {
padding: 6px 4px;
font-size: 11px;
text-align: right;
min-width: 40px;
white-space: nowrap;
}
.point-of-sale #current-order td:first-child {
width: 320px;
padding: 6px;
text-align: left;
text-overflow: ellipsis;
}
.point-of-sale #current-order td:last-child {
border-right: none;
}
.point-of-sale #current-order tr.selected {
background-color: #e9eaf2;
}
.point-of-sale #current-order tr.selected td {
border-top: 2px solid #d5d6e0;
border-bottom: 1px solid #d5d6e0;
padding-top: 5px;
color: #555555;
}
.point-of-sale #amounts {
background: white;
border-bottom: solid 1px #d2d2d2;
border-top: solid 1px #e9eaec;
font-weight: bold;
text-align: right;
-webkit-margin-before: 0;
-webkit-margin-after: 0;
}
.point-of-sale #amounts li {
display: inline-block;
padding: 8px;
width: 29%;
}
.point-of-sale #paypad {
padding: 8px;
float: left;
text-align: center;
}
.point-of-sale #paypad button {
height: 54px;
width: 208px;
margin: 0 -3px;
font-weight: bold;
vertical-align: middle;
color: #555555;
border-top: 1px solid #efefef;
}
.point-of-sale #paypad button:hover {
color: white;
background: #7f82ac;
background: -moz-linear-gradient(#9d9fc5, #7f82ac);
background: -webkit-gradient(linear, left top, left bottom, from(#9d9fc5), to(#7f82ac));
}
.point-of-sale #numpad {
padding: 7px;
float: right;
text-align: center;
}
.point-of-sale #numpad button {
height: 54px;
width: 54px;
margin: 0 -3px;
font-weight: bold;
vertical-align: middle;
color: #555555;
border-top: 1px solid #efefef;
}
.point-of-sale #numpad button:hover {
color: white;
background: #7f82ac;
background: -moz-linear-gradient(#9d9fc5, #7f82ac);
background: -webkit-gradient(linear, left top, left bottom, from(#9d9fc5), to(#7f82ac));
}
.point-of-sale #numpad .selected-mode {
color: white;
background: #7f82ac;
background: -moz-linear-gradient(#9d9fc5, #7f82ac);
background: -webkit-gradient(linear, left top, left bottom, from(#9d9fc5), to(#7f82ac));
}
.point-of-sale .payment-button {
font-size: 14px;
}
.point-of-sale .input-button {
font-size: 24px;
}
.point-of-sale .mode-button, .point-of-sale #numpad-delete, .point-of-sale #numpad-minus {
font-size: 14px;
}
.point-of-sale #rightpane {
position: absolute;
top: 0;
bottom: 0;
left: 441px;
right: 0;
height: 100%;
vertical-align: top;
}
.point-of-sale #rightpane header {
padding: 0;
height: 32px;
border-bottom: 1px solid #cecbcb;
background: #d3d3d3;
background: -moz-linear-gradient(white, #d3d3d3);
background: -webkit-gradient(linear, left top, left bottom, from(white), to(#d3d3d3));
}
.point-of-sale .product-list {
overflow: auto;
position: absolute;
top: 72px;
bottom: 0;
}
.point-of-sale .breadcrumb li {
float: left;
line-height: 32px;
height: 32px;
}
.point-of-sale .breadcrumb li:last-child {
padding-right: 3px;
border-right: 1px solid #c5c5c5;
}
.point-of-sale .breadcrumb a {
display: inline-block;
padding: 0 9px;
vertical-align: top;
text-shadow: #f7f7f7 0 1px 1px;
color: #555555;
font-weight: bold;
}
.point-of-sale .bc-arrow {
height: 33px;
}
.point-of-sale .homeimg {
width: 19px;
height: 19px;
margin: 6px 0;
}
.point-of-sale .searchbox {
position: absolute;
right: 2px;
}
.point-of-sale .searchbox input {
width: 130px;
-moz-border-radius: 11px;
-webkit-border-radius: 11px;
border-radius: 11px;
border: 1px solid #cecbcb;
padding: 3px 19px;
margin: 6px;
background: url("../img/search.png") no-repeat 5px;
background-color: white;
}
.point-of-sale .search-clear {
position: absolute;
top: 11px;
right: 11px;
cursor: pointer;
display: none;
}
.point-of-sale #categories {
border-bottom: 1px solid #cecbcb;
}
.point-of-sale #categories h4 {
display: inline-block;
margin: 9px 5px;
}
.point-of-sale #categories ol {
display: inline;
}
.point-of-sale #categories li {
display: inline-block;
}
.point-of-sale #categories .button {
padding: 6px 14px;
margin: 4px 0;
font-size: 12px;
}
.point-of-sale .product {
vertical-align: top;
display: inline-block;
font-size: 11px;
margin: 5px;
max-width: 120px;
border: 1px solid lightgray;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
-moz-box-shadow: 0px 1px 4px #777777;
-webkit-box-shadow: 0px 1px 4px #777777;
-box-shadow: 0px 1px 4px #777777;
}
.point-of-sale .product-img {
position: relative;
width: 120px;
height: 100px;
background: white;
text-align: center;
}
.point-of-sale .price-tag {
position: absolute;
top: 2px;
right: 2px;
vertical-align: top;
color: white;
background: #7f82ac;
padding: 2px 5px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
}
.point-of-sale .product-name {
padding: 3px;
}
.point-of-sale #login-form label, .point-of-sale #login-form input {
display: block;
}
.point-of-sale #login-form input {
margin: 4px 0 12px;
padding: 4px;
width: 96%;
}
.point-of-sale div#order-selector {
display: inline;
}
.point-of-sale ol#orders {
display: inline;
}
.point-of-sale li.order-selector-button {
display: inline;
}
.point-of-sale li.selected-order button {
font-weight: 900;
}
.point-of-sale .step-screen {
text-align: center;
}
.point-of-sale .step-screen header h2 {
margin-top: 0px;
padding-top: 7px;
}
.point-of-sale .pos-step-container {
display: inline-block;
font-size: 1.5em;
}
.point-of-sale .pos-payment-container {
text-align: left;
}
.point-of-sale .pos-payment-container .payment-due {
display: block;
margin-top: 10px;
margin-bottom: 10px;
padding: 3px 6px 0px 6px;
background-color: white;
border:1px solid grey;
border-radius: 3px;
}
.point-of-sale .pos-payment-container table {
width: 100%;
margin-bottom: 20px;
}
.point-of-sale .pos-payment-container .paymentline-type {
font-size: 0.8em;
font-weight: bold;
}
.point-of-sale .step-screen button {
width: 50%;
text-align: center;
padding: 7px 0 7px 0;
font-size: 0.8em;
font-weight: bold;
}
.point-of-sale .pos-sale-ticket {
text-align: left;
width: 300px;
background-color: white;
margin: 20px;
padding: 10px;
display: inline-block;
}
.point-of-sale .pos-sale-ticket table {
width: 100%;
border: 0;
}
.point-of-sale .pos-sale-ticket table td {
border: 0;
}
.point-of-sale .pos-sale-ticket table td.receiptline-amount {
text-align: right;
}
.point-of-sale .pos-receipt-container {
font-size: 0.75em;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<title>Point of Sale</title>
<link rel="stylesheet" type="text/css" href="/web/static/lib/jquery.ui/css/smoothness/jquery-ui-1.8.9.custom.css">
<style type="text/css">
html, body {
height: 100%;
padding: 0;
margin: 0;
}
</style>
<link rel="stylesheet" type="text/css" href="/point_of_sale/static/src/css/pos.css">
<script type="text/javascript" src="/web/static/lib/jquery/jquery-1.6.2.js"></script>
<script type="text/javascript" src="/web/static/lib/jquery.ui/js/jquery-ui-1.8.9.custom.min.js"></script>
<script type="text/javascript" src="/web/static/lib/underscore/underscore.js"></script>
<script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script>
<script type="text/javascript" src="/web/static/src/js/boot.js"></script>
<script type="text/javascript" src="/web/static/src/js/core.js"></script>
<script type="text/javascript" src="/web/static/src/js/formats.js"></script>
<script type="text/javascript" src="/web/static/src/js/chrome.js"></script>
<script type="text/javascript" src="/web/static/src/js/data.js"></script>
<script type="text/javascript" src="/web/static/src/js/dates.js"></script>
<script type="text/javascript" src="/point_of_sale/static/lib/backbone/backbone-0.5.3.js"></script>
<script type="text/javascript" src="/point_of_sale/static/src/js/pos.js"></script>
<script type="text/javascript" src="/web/static/lib/datejs/globalization/en-US.js"></script>
<script type="text/javascript" src="/web/static/lib/datejs/core.js"></script>
<script type="text/javascript" src="/web/static/lib/datejs/parser.js"></script>
<script type="text/javascript" src="/web/static/lib/datejs/sugarpak.js"></script>
<script type="text/javascript" src="/web/static/lib/datejs/extras.js"></script>
<script type="text/javascript">
$(function() {
var db = openerp.init();
openerp.point_of_sale(db);
var session = new db.web.Session('DEBUG');
session.session_login('trunk', 'admin', 'a').then(function() {
var pos = new db.point_of_sale.PointOfSale({session: session});
pos.appendTo($("body"));
});
});
</script>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- vim:fdl=1:
-->
<templates id="template" xml:space="preserve">
<t t-name="PointOfSale">
<div class="point-of-sale">
<div id="topheader">
<div id="branding">
<img src="/point_of_sale/static/src/img/logo.png" />
</div>
<div id="steps">
<input type="radio" id="products-step-button" class="step-button" data-step='products' name="radio" checked="checked" />
<label for="products-step-button">Products</label>
<img src="/point_of_sale/static/src/img/steps-arrow.png" />
<input type="radio" id="payment-step-button" class="step-button" data-step='payment' name="radio" />
<label for="payment-step-button">Payment</label>
<img src="/point_of_sale/static/src/img/steps-arrow.png" />
<input type="radio" id="receipt-step-button" class="step-button" data-step='receipt' name="radio" />
<label for="receipt-step-button">Receipt</label>
</div>
<div id="rightheader">
<div id="order-selector">
<button id="neworder-button">+</button>
<ol id="orders"></ol>
</div>
</div>
</div>
<div id="content">
<div id="leftpane">
<div id="current-order">
<table>
<thead>
<tr>
<td>Product</td>
<td>Price</td>
<td>Disc (%)</td>
<td>Qty</td>
<td>Total</td>
</tr>
</thead>
<tbody id="current-order-content"></tbody>
</table>
</div>
<footer>
<ul id="amounts">
<li>
Subtotal:
<span id="subtotal">0</span>
</li>
<li>
Tax:
<span id="tax">0</span>
</li>
<li>
Total:
<span id="total">0</span>
</li>
</ul>
<div id="paypad"></div>
<div id="numpad">
<button class="input-button number-char">1</button>
<button class="input-button number-char">2</button>
<button class="input-button number-char">3</button>
<button class="mode-button selected-mode" data-mode='quantity'>Qty</button>
<br />
<button class="input-button number-char">4</button>
<button class="input-button number-char">5</button>
<button class="input-button number-char">6</button>
<button class="mode-button" data-mode='discount'>Disc</button>
<br />
<button class="input-button number-char">7</button>
<button class="input-button number-char">8</button>
<button class="input-button number-char">9</button>
<button class="mode-button" data-mode='list_price'>Price</button>
<br />
<button class="input-button" id="numpad-minus" >+/-</button>
<button class="input-button number-char">0</button>
<button class="input-button number-char">.</button>
<button class="input-button" id="numpad-backspace">
<img src="/point_of_sale/static/src/img/backspace.png" width="24" height="21" />
</button>
<br />
</div>
</footer>
</div>
<div id="rightpane">
<div id="products-screen" class="step-screen selected-step"></div>
<div id="payment-screen" class="step-screen" style="display:none">
<header><h2>Payment</h2></header>
<div class="pos-step-container">
<div class="pos-payment-container">
<span id="payment-due-total" class="payment-due pos-rigth-align"></span>
<table id="paymentlines">
</table>
<table>
<tr>
<td class="paymentline-type">Paid:</td>
<td class="paymentline-amount pos-rigth-align"><span id="payment-paid-total"></span></td>
</tr>
<tr>
<td class="paymentline-type">Change:</td>
<td class="paymentline-amount pos-rigth-align"><span id="payment-remaining"></span></td>
</tr>
</table>
</div>
<div class="pos-payment-buttons">
<button id="validate-order">
<img src="/web/static/src/img/icons/gtk-apply.png"></img>
Validate</button>
</div>
</div>
</div>
<div id="receipt-screen" class="step-screen" style="display:none">
<header><h2>Receipt</h2></header>
<div class="pos-step-container">
<div class="pos-receipt-container">
<div class="pos-sale-ticket">
OpenERP Point of Sale<br />
<br />
<div class="pos-rigth-align"><t t-esc="new Date().toString(Date.CultureInfo.formatPatterns.shortDate + ' ' +
Date.CultureInfo.formatPatterns.longTime)"/></div>
<br />
<table id="receiptlines"></table>
<br />
<table>
<tr><td>Total:</td><td class="pos-rigth-align"><span id="receipt-summary-total"></span></td></tr>
<tr><td>Tax:</td><td class="pos-rigth-align"><span id="receipt-summary-tax"></span></td></tr>
<tr><td>Change:</td><td class="pos-rigth-align"><span id="receipt-summary-change"></span></td></tr>
</table>
</div>
</div>
<button id="pos-finish-order">Next Order</button>
</div>
</div>
</div>
</div>
</div>
</t>
<t t-name="pos-category-template">
<header>
<ol class="breadcrumb">
<li>
<a href="#">
<img src="/point_of_sale/static/src/img/home.png" class="homeimg" />
</a>
</li>
<t t-foreach="breadcrumb" t-as="category">
<li>
<img src="/point_of_sale/static/src/img/bc-arrow.png" class="bc-arrow" />
<a t-att-href="'#category/' + category.id">
<t t-esc="category.name"/>
</a>
</li>
</t>
</ol>
<div class="searchbox">
<input placeholder="Search Products" />
<img class="search-clear" src="/point_of_sale/static/src/img/search_reset.gif" />
</div>
</header>
<div id="categories">
<h4>Categories:</h4>
<ol>
<t t-foreach="categories" t-as="category">
<li>
<a t-att-href="'#category/' + category.id" class="button">
<t t-esc="category.name"/>
</a>
</li>
</t>
</ol>
</div>
</t>
<t t-name="pos-product-template">
<a href="#">
<div class="product-img">
<img t-att-src="'data:image/gif;base64,'+ img" />
<span class="price-tag">
<t t-esc="list_price"/>
</span>
</div>
<div class="product-name">
<t t-esc="name"/>
</div>
</a>
</t>
<t t-name="pos-orderline-template">
<td>
<t t-esc="name"/>
</td>
<td>
<t t-esc="list_price.toFixed(2)"/>
</td>
<td>
<t t-esc="discount.toFixed(2)"/>
</td>
<td>
<t t-esc="quantity.toFixed(0)"/>
</td>
<td>
<t t-esc="(list_price * (1 - discount/100) * quantity).toFixed(2)"/>
</td>
</t>
<t t-name="pos-paymentline-template">
<td class="paymentline-type">
<t t-esc="name"/>
</td>
<td class="paymentline-amount pos-rigth-align">
<input type="text" t-att-value="amount.toFixed(2)" />
</td>
</t>
<t t-name="pos-receiptline-template">
<td class="receiptline-quantity pos-rigth-align">
<t t-esc="quantity.toFixed(0)"/>
</td>
<td class="receiptline-name">
<t t-esc="name"/>
</td>
<td class="receiptline-amount">
<t t-esc="(list_price * (1 - discount/100) * quantity).toFixed(2)"/>
</td>
</t>
<t t-name="pos-payment-button-template">
<button class="payment-button" t-att-cash-register-id="id">
<t t-esc="name"/>
</button>
<br />
</t>
<t t-name="pos-order-selector-button-template">
<button class="select-order">Order</button>
<button class="close-order">X</button>
</t>
</templates>