diff --git a/daily_target_achievement/README.rst b/daily_target_achievement/README.rst new file mode 100644 index 000000000..0c3f8e720 --- /dev/null +++ b/daily_target_achievement/README.rst @@ -0,0 +1,34 @@ +Daily Target vs Achievement v11 +=============================== + +Daily salesperson target and achievement. + +Depends +======= +[account] addon Odoo + +Tech +==== +* [Python] - Models +* [XML] - Odoo views + +Installation +============ +- www.odoo.com/documentation/11.0/setup/install.html +- Install our custom addon + + +Bug Tracker +=========== +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Credits +======= +* Cybrosys Techno Solutions + +Maintainer +---------- + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com. diff --git a/daily_target_achievement/__init__.py b/daily_target_achievement/__init__.py new file mode 100644 index 000000000..a0fdc10fe --- /dev/null +++ b/daily_target_achievement/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import models diff --git a/daily_target_achievement/__manifest__.py b/daily_target_achievement/__manifest__.py new file mode 100644 index 000000000..6e79c72da --- /dev/null +++ b/daily_target_achievement/__manifest__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2019-TODAY Cybrosys Technologies (). +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### +{ + 'name': 'Daily Target vs Achievement', + 'version': '11.0.1.0.0', + 'summary': 'Daily salesperson target and achievement', + 'category': 'Extra Tools', + 'author': 'Cybrosys Techno solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'depends': ['base', 'account_invoicing'], + 'data': [ + 'views/daily_target_form.xml', + 'security/ir.model.access.csv', + 'security/target_record_rules.xml', + ], + 'images': ['static/description/banner.png'], + 'installable': True, + 'application': True, + 'auto_install': False, + 'license': 'AGPL-3', +} diff --git a/daily_target_achievement/models/__init__.py b/daily_target_achievement/models/__init__.py new file mode 100644 index 000000000..f5f131ea2 --- /dev/null +++ b/daily_target_achievement/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import daily_target +from . import account_invoice diff --git a/daily_target_achievement/models/account_invoice.py b/daily_target_achievement/models/account_invoice.py new file mode 100644 index 000000000..cc81d4b33 --- /dev/null +++ b/daily_target_achievement/models/account_invoice.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields, api + + +class AccountInvoice(models.Model): + _inherit = 'account.invoice' + + @api.multi + def action_invoice_open(self): + res = super(AccountInvoice, self).action_invoice_open() + obj_incentive = self.env['daily.target'].search([('user_id', '=', self.user_id.id), ('state', '=', 'open')]) + if obj_incentive: + try: + obj_target = self.env['target.day'].search([('date_today', '=', self.date_invoice), + ('incentive_id', '=', obj_incentive.id)]) + for i in obj_target: + i.write({'amount': i.amount + self.amount_untaxed}) + tot = obj_incentive.achieve_amount + self.amount_untaxed + obj_incentive.write({'achieve_amount': tot}) + except Exception: + pass + return res + + @api.multi + def action_invoice_cancel(self): + res = super(AccountInvoice, self).action_invoice_cancel() + obj_incentive = self.env['daily.target'].search([('user_id', '=', self.user_id.id), ('state', '=', 'open')]) + if obj_incentive: + try: + obj_target = self.env['target.day'].search([('date_today', '=', self.date_invoice), + ('incentive_id', '=', obj_incentive.id)]) + for i in obj_target: + day_total = i.amount - self.amount_untaxed + i.write({'amount': day_total}) + tot = obj_incentive.achieve_amount - self.amount_untaxed + obj_incentive.write({'achieve_amount': tot}) + except Exception: + pass + + return res diff --git a/daily_target_achievement/models/daily_target.py b/daily_target_achievement/models/daily_target.py new file mode 100644 index 000000000..ce7bcc971 --- /dev/null +++ b/daily_target_achievement/models/daily_target.py @@ -0,0 +1,118 @@ +# !/usr/bin/env python +# -*- coding: utf-8 -*- + +import time +from datetime import datetime +import babel + +from odoo import fields, models, api, _, tools +from odoo import exceptions +from odoo.exceptions import Warning, UserError + + +class DailyTarget(models.Model): + _name = 'daily.target' + _description = 'Daily Target' + _order = "id desc" + + name = fields.Char(string='Reference', readonly=True) + target_amount = fields.Float(string='Target', compute='calculate_target') + achieve_amount = fields.Float(string='Achievement', readonly=True, copy=False) + invoice_id = fields.Many2one('account.invoice', string='Invoice') + user_id = fields.Many2one('res.users', string='Sales Person', copy=False) + date = fields.Date(string='Date', default=lambda self: fields.Date.today()) + to_date = fields.Date(string='To Date', default=lambda self: fields.Date.today()) + company_id = fields.Many2one('res.company', string='Company', + default=lambda self: self.env.user.company_id) + internal_note = fields.Text(string='Internal Note') + target_id = fields.One2many('daily.target.line', 'target_id', string='Target') + state = fields.Selection([('draft', 'Draft'), + ('open', 'Open'), + ('done', 'Done'), + ('cancel', 'Cancel')], string='State', default='draft', copy=False) + + @api.model + def create(self, values): + """ + Over writted this method to give the name for record + :param values: + :return: + """ + res = super(DailyTarget, self).create(values) + for this in res: + ttyme = datetime.fromtimestamp(time.mktime(time.strptime(this.date, "%Y-%m-%d"))) + locale = res.env.context.get('lang') or 'en_US' + this.name = 'Target of ' + this.user_id.name + ' _ ' + tools.ustr( + babel.dates.format_date(date=ttyme, format='MMMM-y', locale=locale)) + + return res + + @api.one + def action_open_target(self): + """ + This method is used to change the record state to open + """ + obj_config = self.env['daily.target'].search([('state', '=', 'open')]) + for i in obj_config: + if self.user_id == i.user_id: + raise exceptions.Warning(_("Warning"), _( + "You have already created a incentive program for this sales person")) + self.state = 'open' + + @api.one + def calculate_target(self): + """This method is used to calculate the target of the salesperson from lines""" + target_total = 0 + if self.target_id: + for i in self.target_id: + target_total = target_total + i.target + self.target_amount = target_total + + @api.one + def action_target_cancel(self): + """ + This method is used to change the record state to cancel + """ + self.state = 'cancel' + + @api.one + def target_done(self): + """ + This method is used to change the record state to Done + """ + self.state = 'done' + + @api.constrains('user_id') + def _checking_another_config(self): + """ + Only one record is in open state to avoid further mistake + """ + obj_config = self.env['daily.target'].search([('state', '=', 'open')]) + for i in obj_config: + if self.user_id == i.user_id: + raise exceptions.Warning(_("Warning"), _( + "You have already created a incentive program for current sales person")) + + @api.multi + def unlink(self): + """ + will not able to delete a record which is in open or done state + :return: + """ + for rec in self: + if rec.state in ('open', 'done'): + raise UserError(_("You can not delete a Target Program that are in Open/Done State")) + return super(DailyTarget, self).unlink() + + +class DailyTargetLine(models.Model): + _name = 'daily.target.line' + _description = 'Daily Target Line' + _order = "id desc" + + date_today = fields.Date(string='Date', default=lambda self: fields.Date.today()) + amount = fields.Float(string='Amount', readonly=True) + target = fields.Float(string='Target') + target_id = fields.Many2one('daily.target', string='Target Program') + company_id = fields.Many2one('res.company', string='Company', + default=lambda self: self.env.user.company_id) diff --git a/daily_target_achievement/models/test_dailyTarget.py b/daily_target_achievement/models/test_dailyTarget.py new file mode 100644 index 000000000..68ba9c2a9 --- /dev/null +++ b/daily_target_achievement/models/test_dailyTarget.py @@ -0,0 +1,6 @@ +from unittest import TestCase + + +class TestDailyTarget(TestCase): + def test_unlink(self): + self.fail() diff --git a/daily_target_achievement/security/ir.model.access.csv b/daily_target_achievement/security/ir.model.access.csv new file mode 100644 index 000000000..8984e5e36 --- /dev/null +++ b/daily_target_achievement/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_target,access_target,model_daily_target,base.group_user,1,1,1,1 +a_target_day,access_daily_target_line,model_daily_target_line,base.group_user,1,1,1,1 + diff --git a/daily_target_achievement/security/target_record_rules.xml b/daily_target_achievement/security/target_record_rules.xml new file mode 100644 index 000000000..54966203e --- /dev/null +++ b/daily_target_achievement/security/target_record_rules.xml @@ -0,0 +1,27 @@ + + + + + Daily Target of my Company + + + + + + + [('company_id','=',user.company_id.id)] + + + + + + Target User + + + + Target Manager + + + + + \ No newline at end of file diff --git a/daily_target_achievement/static/description/banner.png b/daily_target_achievement/static/description/banner.png new file mode 100644 index 000000000..05563790d Binary files /dev/null and b/daily_target_achievement/static/description/banner.png differ diff --git a/daily_target_achievement/static/description/daily_target.png b/daily_target_achievement/static/description/daily_target.png new file mode 100644 index 000000000..c90552b10 Binary files /dev/null and b/daily_target_achievement/static/description/daily_target.png differ diff --git a/daily_target_achievement/static/description/icon.png b/daily_target_achievement/static/description/icon.png new file mode 100644 index 000000000..5fa4b4757 Binary files /dev/null and b/daily_target_achievement/static/description/icon.png differ diff --git a/daily_target_achievement/static/description/index.html b/daily_target_achievement/static/description/index.html new file mode 100644 index 000000000..35bb59211 --- /dev/null +++ b/daily_target_achievement/static/description/index.html @@ -0,0 +1,332 @@ +
+
+

+ Daily Target vs Achievement +

+

+ Daily salesperson target and achievement +

+
+ Cybrosys Technologies +
+ +
+ cybrosys technologies +
+
+
+
+ +
+
+

+ Overview +

+

+ Now you can add daily target to your employees
+ +

+
+
+ +
+
+

+ Features +

+

+ + Assign Daily Target +

+

+ + Get Daily Achievement +

+
+
+ +
+
+

+ Screenshots +

+

+ + Create a Target program for an employee. +

+
+ +
+

+ + The daily achievement is calculated once the invoice is validated, + only untaxed amount is considered as the achievement. +

+
+
+ +
+
+ cybrosys technologies +
+
+
+
+

+ Our Services +

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

+ + Odoo Support +

+ +
+ +
+
+
+
+
+

+ Our Industries +

+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Trading + +

+

+ Easily procure and sell your products. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Manufacturing +

+

+ Plan, track and schedule your operations. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Restaurant +

+

+ Run your bar or restaurant methodical. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + POS +

+

+ Easy configuring and convivial selling. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + E-commerce & Website +

+

+ Mobile friendly, awe-inspiring product pages. +

+
+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Hotel Management +

+

+ An all-inclusive hotel management application. +

+
+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Education +

+

+ A Collaborative platform for educational management. +

+
+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Service Management +

+

+ Keep track of services and invoice accordingly. +

+
+
+
+
+
+
+ +
diff --git a/daily_target_achievement/views/daily_target_form.xml b/daily_target_achievement/views/daily_target_form.xml new file mode 100644 index 000000000..db8baf63f --- /dev/null +++ b/daily_target_achievement/views/daily_target_form.xml @@ -0,0 +1,108 @@ + + + + + Daily Target Filter + daily.target + + + + + + + + + + + + + + + + + + + + + + + Daily Target + daily.target + +
+
+
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + Daily Target + daily.target + + + + + + + + + + + + + Daily Target + daily.target + form + tree,form + + + + + + + +
+