diff --git a/pos_claims/README.rst b/pos_claims/README.rst new file mode 100644 index 000000000..8e3ed90e5 --- /dev/null +++ b/pos_claims/README.rst @@ -0,0 +1,20 @@ +POS Claims v9 +============= + +This application allows you to track your customers/vendors pos claims and grievances. + +Installation +============ + +Just select it from available modules to install it, there is no need to extra installations. + +Configuration +============= + +Nothing to configure. + +Credits +======= +Developers: Jesni Banu & Saritha +Guidance: Nilmar Shereef @ cybrosys, shereef@cybrosys.in + diff --git a/pos_claims/__init__.py b/pos_claims/__init__.py new file mode 100644 index 000000000..5acbcb6db --- /dev/null +++ b/pos_claims/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Cybrosys Technologies () +# 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_claims/__openerp__.py b/pos_claims/__openerp__.py new file mode 100644 index 000000000..c58391abf --- /dev/null +++ b/pos_claims/__openerp__.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Cybrosys Technologies () +# 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': "POS Claims", + 'version': '9.0.1.0.0', + 'summary': """Manage your customer claims""", + 'description': """ This application allows you to manage your customers claims.""", + 'category': 'Point of sale', + 'author': "Cybrosys Techno Solutions", + 'website': "http://www.cybrosys.com", + 'company': 'Cybrosys Techno Solutions', + 'depends': ['base', 'point_of_sale'], + 'data': ['views/pos_claims_views.xml', 'views/pos_claims_popup.xml', 'views/pos_claim_sequence.xml'], + 'qweb': ['static/src/xml/pos_claim.xml'], + 'images': ['static/description/banner.jpg'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} \ No newline at end of file diff --git a/pos_claims/models/__init__.py b/pos_claims/models/__init__.py new file mode 100644 index 000000000..85199dac7 --- /dev/null +++ b/pos_claims/models/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Cybrosys Technologies () +# 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 pos_claim diff --git a/pos_claims/models/pos_claim.py b/pos_claims/models/pos_claim.py new file mode 100644 index 000000000..a6e4d1d26 --- /dev/null +++ b/pos_claims/models/pos_claim.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Cybrosys Technologies () +# 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 SUPERUSER_ID +from openerp import models, fields, api, _ + + +class PosClaims(models.Model): + _name = 'pos.claims' + _description = "Claim" + _inherit = ['mail.thread'] + + name = fields.Many2one('pos.order', string='Claim Order', required=True) + ref_name = fields.Char(string="Claim Ticket", readonly=True, default=lambda self: _('New')) + claim_product = fields.Many2one('pos.order.line', string="Product", + domain="[('order_id', '=',name)]", required=True) + claim_qty = fields.Integer(string="Quantity") + claim_date = fields.Datetime(string='Claim Date', default=fields.Datetime.now, required=True) + session_id = fields.Many2one('pos.session', string='Session', related='name.session_id') + user_id = fields.Many2one('res.users', string="Assigned Person") + priority = fields.Selection([('0', 'Low'), ('1', 'Normal'), ('2', 'High')], 'Priority') + partner_id = fields.Many2one('res.partner', string='Partner', required=1) + partner_phone = fields.Char(string='Phone') + partner_email = fields.Char(string='Email', related='partner_id.email') + description = fields.Text(string='Description') + user_fault = fields.Char(string='Trouble Responsible') + cate_id = fields.Selection([('0', 'Factual Claims'), ('1', 'Value Claims'), ('2', 'Policy Claim')], 'Category Id', + ) + date_action_next = fields.Datetime(string='Next Action Date') + action_next = fields.Char(string='Next Action') + resolution = fields.Text(string='Resolution') + cause = fields.Text(string='Root Cause') + type_action = fields.Selection([('correction', 'Corrective Action'), + ('prevention', 'Preventive Action')], 'Action Type') + date_closed = fields.Datetime('Closed') + state = fields.Selection([ + ('new', 'New'), + ('assigned', 'Assigned'), + ('feedback', 'Feedback'), + ('paid', 'Paid'), + ('settle', 'Settled'), + ('reject', 'Rejected'), + ], default='new') + + def create_from_ui(self, cr, uid, claim, context=None): + """ create claims from the point of sale ui. """ + claim_id = self.create(cr, uid, claim, context=context) + return claim_id + + @api.model + def create(self, vals): + if vals.get('ref_name', 'New') == 'New': + vals['ref_name'] = self.env['ir.sequence'].next_by_code('pos.claims') or 'New' + + if vals.get('user_id'): + vals['state'] = 'assigned' + result = super(PosClaims, self).create(vals) + result.claim_ticket() + return result + + @api.multi + def write(self, vals): + if vals.get('user_id'): + vals['state'] = 'assigned' + result = super(PosClaims, self).write(vals) + return result + + @api.multi + def action_settle(self): + self.state = 'settle' + + @api.multi + def action_reject(self): + self.state = 'reject' + + @api.one + def claim_ticket(self): + su_id = self.env['res.partner'].browse(SUPERUSER_ID) + self.ensure_one() + ir_model_data = self.env['ir.model.data'] + try: + template_id = ir_model_data.get_object_reference('pos_claims', 'email_template_edi_pos_ticket')[1] + except ValueError: + template_id = False + email_template_obj = self.env['mail.template'].browse(template_id) + if template_id: + values = email_template_obj.generate_email(self.id, fields=None) + values['email_from'] = su_id.email + values['email_to'] = self.partner_id.email + values['res_id'] = False + mail_mail_obj = self.env['mail.mail'] + msg_id = mail_mail_obj.create(values) + if msg_id: + msg_id.send() + + @api.multi + def action_sent(self): + self.ensure_one() + ir_model_data = self.env['ir.model.data'] + try: + template_id = ir_model_data.get_object_reference('pos_claims', 'email_template_edi_pos_claims')[1] + except ValueError: + template_id = False + try: + compose_form_id = ir_model_data.get_object_reference('mail', 'email_compose_message_wizard_form')[1] + except ValueError: + compose_form_id = False + ctx = dict() + ctx.update({ + 'default_model': 'pos.claims', + 'default_res_id': self.ids[0], + 'default_use_template': bool(template_id), + 'default_template_id': template_id, + 'default_composition_mode': 'comment', + }) + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'mail.compose.message', + 'views': [(compose_form_id, 'form')], + 'view_id': compose_form_id, + 'target': 'new', + 'context': ctx, + } + + +class MailComposeMessage(models.TransientModel): + _inherit = 'mail.compose.message' + + @api.multi + def send_mail(self, auto_commit=False): + if self._context.get('default_model') == 'pos.claims' and self._context.get('default_res_id'): + order = self.env['pos.claims'].browse([self._context['default_res_id']]) + if order.state == 'assigned': + order.state = 'feedback' + order.sent = True + self = self.with_context(mail_post_autofollow=True) + return super(MailComposeMessage, self).send_mail(auto_commit=auto_commit) + + + + + + + diff --git a/pos_claims/static/description/banner.jpg b/pos_claims/static/description/banner.jpg new file mode 100644 index 000000000..103ef4a5e Binary files /dev/null and b/pos_claims/static/description/banner.jpg differ diff --git a/pos_claims/static/description/calender.png b/pos_claims/static/description/calender.png new file mode 100644 index 000000000..e6f70043a Binary files /dev/null and b/pos_claims/static/description/calender.png differ diff --git a/pos_claims/static/description/claim.png b/pos_claims/static/description/claim.png new file mode 100644 index 000000000..b679949ac Binary files /dev/null and b/pos_claims/static/description/claim.png differ diff --git a/pos_claims/static/description/claim_state_change.png b/pos_claims/static/description/claim_state_change.png new file mode 100644 index 000000000..3bfd885db Binary files /dev/null and b/pos_claims/static/description/claim_state_change.png differ diff --git a/pos_claims/static/description/email.png b/pos_claims/static/description/email.png new file mode 100644 index 000000000..5062c7e5b Binary files /dev/null and b/pos_claims/static/description/email.png differ diff --git a/pos_claims/static/description/icon.png b/pos_claims/static/description/icon.png new file mode 100644 index 000000000..c9c82793e Binary files /dev/null and b/pos_claims/static/description/icon.png differ diff --git a/pos_claims/static/description/index.html b/pos_claims/static/description/index.html new file mode 100644 index 000000000..91c0ff970 --- /dev/null +++ b/pos_claims/static/description/index.html @@ -0,0 +1,114 @@ +
+
+

POS Claims

+

Manage Customer Claims

+

Cybrosys Technologies , www.cybrosys.com

+
+

Features:

+
    +
    + ☀Easily create claims from POS interface.
    + ☀ Automatic stage changes for assignment of claims.
    + ☀ Email Notification.
    + ☀ Calender view.
    + +
    +
+
+
+
+ +
+
+
+
+ +
+
+
+

+ This application allows you to manage your customers claims. +

+
+
+
+ +
+
+

Create Claims

+
+
+ +
+
+
+

+ Create claims easily from pos interface.Ticket is generated automatically and + it is send to corresponding user on creation of claims. +

+
+
+
+ +
+
+

Automatic Stage Change

+
+

+ On assigning claim to responsible user,state of claim is changed. +

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

Email Notification

+
+
+ +
+
+
+

+ An email is sent to corresponding customer +

+
+
+
+ +
+
+

Calender view

+
+

+ You can see all your next action on calender view +

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

View your claims

+
+
+ +
+
+
+
+ + + + diff --git a/pos_claims/static/description/interface_pos.png b/pos_claims/static/description/interface_pos.png new file mode 100644 index 000000000..0d602fb1f Binary files /dev/null and b/pos_claims/static/description/interface_pos.png differ diff --git a/pos_claims/static/description/pos_claims.png b/pos_claims/static/description/pos_claims.png new file mode 100644 index 000000000..8729de383 Binary files /dev/null and b/pos_claims/static/description/pos_claims.png differ diff --git a/pos_claims/static/description/pos_interface_order.png b/pos_claims/static/description/pos_interface_order.png new file mode 100644 index 000000000..ca4f4e4e1 Binary files /dev/null and b/pos_claims/static/description/pos_interface_order.png differ diff --git a/pos_claims/static/src/js/pos_claim.js b/pos_claims/static/src/js/pos_claim.js new file mode 100644 index 000000000..0a8dadb7e --- /dev/null +++ b/pos_claims/static/src/js/pos_claim.js @@ -0,0 +1,184 @@ +odoo.define('point_of_sale.pos_claims', function (require) { +"use strict"; +var chrome = require('point_of_sale.chrome'); +var db = require('point_of_sale.DB'); +var gui = require('point_of_sale.gui'); +var models = require('point_of_sale.models'); +var Model = require('web.DataModel'); +var popup = require('point_of_sale.popups'); +var Model = require('web.DataModel'); +var core = require('web.core'); +var QWeb = core.qweb; +var _t = core._t; + +models.load_models({ + model: 'pos.order', + fields: ['name', 'lines', 'partner_id'], + loaded: function(self,claim_orders){ + self.order = []; + for (var i = 0; i < claim_orders.length; i++) { + self.order[i] = claim_orders[i]; + } + }, +}); + +models.load_models({ + model: 'res.partner', + fields: ['name', 'id', 'email'], + loaded: function(self,claim_customers){ + self.customer = []; + for (var i = 0; i < claim_customers.length; i++) { + self.customer[i] = claim_customers[i]; + } + }, +}); + +models.load_models({ + model: 'pos.order.line', + fields: ['product_id','qty'], + loaded: function(self,claim_products){ + self.order_line = []; + for (var i = 0; i < claim_products.length; i++) { + self.order_line[i] = claim_products[i]; + } + }, +}); + +chrome.Chrome.include({ + events: { + "click .pos-claims": "on_click_pos_claims", + }, + renderElement: function(){ + var self = this; + return this._super(); + }, + on_click_pos_claims: function () { + var list =[]; + var list1 =[]; + for (var i = 0; i < this.pos.order.length; i++) { + var orders = this.pos.order[i]; + if (orders.name){ + list.push({ + 'label': orders.name, + 'id':orders.id, + }); + } + } + for (var i = 0; i < this.pos.customer.length; i++) { + var customers = this.pos.customer[i]; + if (customers.name){ + list1.push({ + 'label': customers.name, + 'id':customers.id, + }); + } + } + this.gui.show_popup('pos_claim',{orders:list, customers:list1}); + }, +}); + +var PosClaimWidget = popup.extend({ + template:'PosClaimWidget', + events : { + 'click .selected_order': 'on_click_select_order', + 'click .selected_customer': 'on_click_select_customer', + 'click .button.confirm': 'click_confirm', + 'click .button.cancel': 'click_cancel', + }, + show : function(options){ + options = options || []; + var self = this; + this._super(options); + this.orders = options.orders || []; + this.customers = options.customers || []; + this.product = options.product || []; + this.renderElement(); + }, + + on_click_select_order:function(){ + var selected_order = $('.selected_order').val(); + for (var i = 0; i < this.pos.order.length; i++) { + if (this.pos.order[i].id==selected_order){ + var orders = this.pos.order[i]; + } + } + if (orders) { + var x = document.getElementsByClassName('selected_customer'); + x[0].selectedIndex = orders.partner_id[0]; + if (orders.partner_id) + { + for (var i = 0; i < this.pos.customer.length; i++) { + if (this.pos.customer[i].id==orders.partner_id[0]){ + var customers = this.pos.customer[i]; + } + } + if (customers) + { + var x = document.getElementsByClassName('select_email'); + x[0].value = customers.email; + } + } + } + var product = []; + if (orders) + { + for (var i = 0; i < this.pos.order_line.length; i++){ + for (var j = 0; j < orders.lines.length; j++){ + if (this.pos.order_line[i].id == orders.lines[j]){ + var product_line = this.pos.order_line[i]; + if (product_line.product_id){ + product.push({ + 'label': product_line.product_id[1], + 'id':product_line.id, + }); + } + } + } + } + this.$('.selected_product').html(QWeb.render('PosClaimProductWidget',{product:product})); + } + }, + + on_click_select_customer:function() { + var selected_customer = $('.selected_customer').val(); + for (var i = 0; i < this.pos.customer.length; i++) { + if (this.pos.customer[i].id==selected_customer){ + var customers = this.pos.customer[i]; + } + } + if (customers) + { + var x = document.getElementsByClassName('select_email'); + x[0].value = customers.email; + } + }, + + click_confirm: function(){ + var self = this; + var fields = {}; + this.$('.popup .detail').each(function(idx,el){ + fields[el.name] = el.value; + }); + if (fields.partner_id && fields.claim_product) { + new Model('pos.claims').call('create_from_ui', [fields]); + this.gui.close_popup(); + } + else{ + alert('You need to specify the Product and Customer') + } + }, + + click_cancel: function(){ + this.gui.close_popup(); + if (this.options.cancel) { + this.options.cancel.call(this); + } + }, + + renderElement: function(){ + var self = this; + return this._super(); + }, +}); +gui.define_popup({name:'pos_claim', widget: PosClaimWidget}); +}); diff --git a/pos_claims/static/src/xml/pos_claim.xml b/pos_claims/static/src/xml/pos_claim.xml new file mode 100644 index 000000000..a55fc3c59 --- /dev/null +++ b/pos_claims/static/src/xml/pos_claim.xml @@ -0,0 +1,105 @@ + + \ No newline at end of file diff --git a/pos_claims/views/pos_claim_sequence.xml b/pos_claims/views/pos_claim_sequence.xml new file mode 100644 index 000000000..88d1bfb47 --- /dev/null +++ b/pos_claims/views/pos_claim_sequence.xml @@ -0,0 +1,13 @@ + + + + + POS Claims + pos.claims + Ticket/ + 001 + 1 + 3 + + + \ No newline at end of file diff --git a/pos_claims/views/pos_claims_popup.xml b/pos_claims/views/pos_claims_popup.xml new file mode 100644 index 000000000..f7254216f --- /dev/null +++ b/pos_claims/views/pos_claims_popup.xml @@ -0,0 +1,10 @@ + + + +