diff --git a/pos_sales_orders/README.rst b/pos_sales_orders/README.rst new file mode 100644 index 000000000..8028c461f --- /dev/null +++ b/pos_sales_orders/README.rst @@ -0,0 +1,36 @@ +====================== +Sale Order From POS V9 +====================== + +This module allow to create Sale Orders from POS. + +Installation +============ + +Just select it from available modules to install it, there is no need to extra installations. + +Configuration +============= + +Nothing to configure. + +Features +======== + +* 'Create Sale Order' button in POS. +* Create sale orders directly from POS. + +Usage +===== + +* We cannot create sale order if there is no customer selected or no order lines added. +* Otherwise it will raise an alert popup with invalid order line/ invalid customer. +* On confirming SO creation with invalid order date, display an error message. +* On confirming Order Creation, create quotation with order lines and it shows popup with sale order reference. + +Credits +======= + +Developer: Aswani pc @ cybrosys + + diff --git a/pos_sales_orders/__init__.py b/pos_sales_orders/__init__.py new file mode 100644 index 000000000..273189d81 --- /dev/null +++ b/pos_sales_orders/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2015-TODAY Cybrosys Technologies(). +# Author: Aswani P C() +# 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 . +# +############################################################################## +from . import models diff --git a/pos_sales_orders/__openerp__.py b/pos_sales_orders/__openerp__.py new file mode 100644 index 000000000..aa6d2fb91 --- /dev/null +++ b/pos_sales_orders/__openerp__.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2015-TODAY Cybrosys Technologies(). +# Author: Aswani P C() +# 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 . +# +############################################################################## +{ + 'name': "Sale Order From POS", + 'version': '9.0.1.0.0', + 'summary': """Sale Orders From POS""", + 'description': """This module allows to create sale orders from POS.""", + 'author': "Cybrosys Techno Solutions", + 'company': "Cybrosys Techno Solutions", + 'website': "https://www.cybrosys.com", + 'category': 'Point of Sale', + 'depends': ['base', 'point_of_sale'], + 'data': ['views/pos_so_templates.xml', 'views/so_pos_ref.xml'], + 'qweb': ['static/src/xml/pos_so.xml'], + 'images': ['static/description/banner.jpg'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, +} diff --git a/pos_sales_orders/models/__init__.py b/pos_sales_orders/models/__init__.py new file mode 100644 index 000000000..81ae81356 --- /dev/null +++ b/pos_sales_orders/models/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2015-TODAY Cybrosys Technologies(). +# Author: Aswani P C() +# 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 . +# +############################################################################## + +from . import models diff --git a/pos_sales_orders/models/models.py b/pos_sales_orders/models/models.py new file mode 100644 index 000000000..f9a5fa741 --- /dev/null +++ b/pos_sales_orders/models/models.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2015-TODAY Cybrosys Technologies(). +# Author: Aswani P C() +# 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 . +# +############################################################################## + +from openerp import models, fields + + +class PosSaleOrder(models.Model): + _inherit = 'sale.order' + + from_pos = fields.Boolean(string="Created From POS", default=False) + + def create_from_ui(self, cr, uid, orders, context=None): + order_id = self.create(cr, uid, orders, context=context) + order_ref = self.browse(cr, uid, order_id, context=context).name + return order_ref + diff --git a/pos_sales_orders/static/description/banner.jpg b/pos_sales_orders/static/description/banner.jpg new file mode 100644 index 000000000..e98f80236 Binary files /dev/null and b/pos_sales_orders/static/description/banner.jpg differ diff --git a/pos_sales_orders/static/description/cybro_logo.png b/pos_sales_orders/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/pos_sales_orders/static/description/cybro_logo.png differ diff --git a/pos_sales_orders/static/description/icon.png b/pos_sales_orders/static/description/icon.png new file mode 100644 index 000000000..f9a19e59b Binary files /dev/null and b/pos_sales_orders/static/description/icon.png differ diff --git a/pos_sales_orders/static/description/index.html b/pos_sales_orders/static/description/index.html new file mode 100644 index 000000000..6c004ad76 --- /dev/null +++ b/pos_sales_orders/static/description/index.html @@ -0,0 +1,90 @@ +
+
+

Sale Order From POS

+

Create Sale Orders from POS

+

Cybrosys Technologies

+
+

Features

+
+ 'Create Sale Order' button in POS.
+ Create sale orders directly from POS.
+
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+

We cannot create sale order if there is no customer selected or no order lines added. Otherwise it will raise an alert popup with invalid order line/ invalid customer.

+
+ +
+
+ +
+
+
+ +
+
+

Order Creation popup with confirm button & order date

+

On Confirming Order Creation, create Quotation with orderlines and it shows popup with sale order reference.

+
+ +
+
+
+ +
+
+

Sale Order Reference

+
+ +
+
+
+ +
+
+

Created Sale Order

+
+ +
+
+
+ +
+

Need Any Help?

+ +
+ + diff --git a/pos_sales_orders/static/description/pos_so_01.png b/pos_sales_orders/static/description/pos_so_01.png new file mode 100644 index 000000000..0ee82736b Binary files /dev/null and b/pos_sales_orders/static/description/pos_so_01.png differ diff --git a/pos_sales_orders/static/description/pos_so_02.png b/pos_sales_orders/static/description/pos_so_02.png new file mode 100644 index 000000000..345ee4a54 Binary files /dev/null and b/pos_sales_orders/static/description/pos_so_02.png differ diff --git a/pos_sales_orders/static/description/pos_so_03.png b/pos_sales_orders/static/description/pos_so_03.png new file mode 100644 index 000000000..f3ea13054 Binary files /dev/null and b/pos_sales_orders/static/description/pos_so_03.png differ diff --git a/pos_sales_orders/static/description/pos_so_04.png b/pos_sales_orders/static/description/pos_so_04.png new file mode 100644 index 000000000..37c9e7f46 Binary files /dev/null and b/pos_sales_orders/static/description/pos_so_04.png differ diff --git a/pos_sales_orders/static/description/pos_so_05.png b/pos_sales_orders/static/description/pos_so_05.png new file mode 100644 index 000000000..a10ba7fd5 Binary files /dev/null and b/pos_sales_orders/static/description/pos_so_05.png differ diff --git a/pos_sales_orders/static/description/pos_so_06.png b/pos_sales_orders/static/description/pos_so_06.png new file mode 100644 index 000000000..ee3364778 Binary files /dev/null and b/pos_sales_orders/static/description/pos_so_06.png differ diff --git a/pos_sales_orders/static/src/css/pos_so.css b/pos_sales_orders/static/src/css/pos_so.css new file mode 100644 index 000000000..186b6ee7c --- /dev/null +++ b/pos_sales_orders/static/src/css/pos_so.css @@ -0,0 +1,45 @@ +.sale_order_button { + display: inline-block; + margin-left:5px; + width: 405px; + height: 40px; + text-align: center; + color: #555555; + border-color: #bfbfbf; + +} +.sale_order_button p { + position: absolute; + left: 80px; + top: 0px; +} +.pos-so-cart{ + position: absolute; + left: 30px; + top: 13px; + margin-right: 8px; + font-size: 18px; + background: rgba(255, 255, 255, 0.5); + line-height: 30px; + width: 30px; + border-radius: 100%; + +} + +.sale_order_button:hover { + background: #efefef; +} + +.sale_order_button:active { + background: black; + border-color: black; + color: white; +} +.alert_msg{ + color:red; +} + +.popup_so_ref{ + height: 150px !important; +} + diff --git a/pos_sales_orders/static/src/js/pos_so.js b/pos_sales_orders/static/src/js/pos_so.js new file mode 100644 index 000000000..eae1b666e --- /dev/null +++ b/pos_sales_orders/static/src/js/pos_so.js @@ -0,0 +1,151 @@ +odoo.define('point_of_sale.pos_sales_orders', function (require) { +"use strict"; + +var screens = require('point_of_sale.screens'); +var gui = require('point_of_sale.gui'); +var Model = require('web.DataModel'); +var core = require('web.core'); +var PopupWidget = require('point_of_sale.popups'); +var ProductListWidget = screens.ProductListWidget; +var QWeb = core.qweb; +var _t = core._t; + +var SaleOrderButton = screens.ActionButtonWidget.extend({ + template: 'SaleOrderButton', + button_click: function(){ + var order_lines = this.pos.get_order().get_orderlines(); + var flag_negative = false; + for (var line in order_lines){ + if (order_lines[line].quantity < 0){ + flag_negative = true; + } + } + if(this.pos.get_order().get_orderlines().length > 0 && this.pos.get_client() && flag_negative == false && this.pos.get_order().get_total_with_tax()>0){ + this.gui.show_popup('pos_so'); + } + else if(flag_negative == true){ + this.gui.show_popup('alert',{ + 'title': _t('Alert: Invalid Order'), + 'body': _t('Negative Quantity is Not Allowed'), + }); + } + else if(this.pos.get_order().get_orderlines().length == 0 || this.pos.get_order().get_total_with_tax() <=0){ + this.gui.show_popup('alert',{ + 'title': _t('Alert: Invalid Order'), + 'body': _t('Please Add Some Order Lines'), + }); + } + else{ + this.gui.show_popup('alert',{ + 'title': _t('Alert: Invalid Customer'), + 'body': _t('Please Select Customer'), + }); + } + }, +}); + +screens.define_action_button({ + 'name': 'pos_sale_order', + 'widget': SaleOrderButton, +}); + +var SaleOrderPopupWidget = PopupWidget.extend({ + template: 'SaleOrderPopupWidget', + events: _.extend({}, PopupWidget.prototype.events,{ + "keyup .order_date" : "date_validate", + }), + show: function(options){ + options = options || {}; + var self = this; + this._super(options); + this.renderElement(); + }, + date_validate: function(){ + var v = $(".order_date").val(); + if (v.match(/^\d{4}$/) !== null) { + $(".order_date").val(v + '/'); + } + else if (v.match(/^\d{4}\/\d{2}$/) !== null) { + $(".order_date").val(v + '/'); + } + }, + click_confirm: function(){ + var self = this; + var sale_order = {}; + var today = new Date().toJSON().slice(0,10); + var order = this.pos.get_order(); + var order_lines = this.pos.get_order().get_orderlines(); + var order_date = this.$('.order_date').val(); + var valid_date = true; + var validatePattern = /^(\d{4})([/|-])(\d{1,2})([/|-])(\d{1,2})$/; + if (order_date){ + var dateValues = order_date.match(validatePattern); + if (dateValues == null){ + valid_date = false; + } + else{ + var orderYear = dateValues[1]; + var orderMonth = dateValues[3]; + var orderDate = dateValues[5]; + if ((orderMonth < 1) || (orderMonth > 12)) { + valid_date = false; + } + else if ((orderDate < 1) || (orderDate> 31)) { + valid_date = false; + } + else if ((orderMonth==4 || orderMonth==6 || orderMonth==9 || orderMonth==11) && orderDate ==31) { + valid_date = false; + } + else if (orderMonth == 2){ + var isleap = (orderYear % 4 == 0 && (orderYear % 100 != 0 || orderYear % 400 == 0)); + if (orderDate> 29 || (orderDate ==29 && !isleap)){ + valid_date = false; + } + } + var dates = [orderYear,orderMonth,orderDate]; + order_date = dates.join('-'); + } + } + sale_order.order_line = []; + $('.alert_msg').text(""); + if (order_date && order_date < today || valid_date==false){ + $('.alert_msg').text("Please Select Valid Order Date!"); + } + else{ + $('.alert_msg').text(""); + for (var line in order_lines){ + if (order_lines[line].quantity>0) + { + var sale_order_line = [0,false,{product_id:null,product_uom_qty:0}] + sale_order_line[2].product_id = order_lines[line].product.id; + sale_order_line[2].product_uom_qty = order_lines[line].quantity; + sale_order.order_line.push(sale_order_line); + } + } + sale_order.partner_id = this.pos.get_client().id; + if (order_date){ + sale_order.validity_date = order_date; + } + sale_order.from_pos = true; + var saleOrderModel = new Model('sale.order'); + saleOrderModel.call('create_from_ui',[sale_order]).then(function(order_ref){ + self.gui.close_popup(); + self.pos.delete_current_order(); + self.gui.show_popup('pos_so_ref',{ + 'body': _t('Sale Order Ref : ')+ order_ref , + }); + }); + } + } + +}); +gui.define_popup({name:'pos_so', widget: SaleOrderPopupWidget}); + +var SaleRefPopupWidget = PopupWidget.extend({ + template: 'SaleRefPopupWidget', +}); + +gui.define_popup({name:'pos_so_ref', widget: SaleRefPopupWidget}); + +}); + diff --git a/pos_sales_orders/static/src/xml/pos_so.xml b/pos_sales_orders/static/src/xml/pos_so.xml new file mode 100644 index 000000000..61c47ad70 --- /dev/null +++ b/pos_sales_orders/static/src/xml/pos_so.xml @@ -0,0 +1,53 @@ + + + + + + + diff --git a/pos_sales_orders/views/pos_so_templates.xml b/pos_sales_orders/views/pos_so_templates.xml new file mode 100644 index 000000000..3663e41a4 --- /dev/null +++ b/pos_sales_orders/views/pos_so_templates.xml @@ -0,0 +1,11 @@ + + + +