715 lines
24 KiB
Python
715 lines
24 KiB
Python
# This file is part sale_shop module for Tryton.
|
|
# The COPYRIGHT file at the top level of this repository contains the full
|
|
# copyright notices and license terms.
|
|
import calendar
|
|
from decimal import Decimal
|
|
from datetime import date
|
|
from trytond.pool import Pool
|
|
from trytond.model import Workflow, ModelView, ModelSQL, fields
|
|
from trytond.pyson import Eval
|
|
from trytond.wizard import Wizard, StateView, Button, StateAction, StateReport
|
|
from trytond.report import Report
|
|
from trytond.transaction import Transaction
|
|
|
|
_STATES = {
|
|
'readonly': Eval('state') != 'draft',
|
|
}
|
|
|
|
KIND = [
|
|
('salesman', 'Salesman'),
|
|
('product', 'Product'),
|
|
('category', 'Category'),
|
|
]
|
|
|
|
TYPE = [
|
|
('monthly', 'Monthly'),
|
|
('bimonthly', 'Bimonthly'),
|
|
('quarterly', 'Quarterly'),
|
|
('annual', 'Annual'),
|
|
]
|
|
|
|
_ZERO = Decimal(0)
|
|
|
|
|
|
class Goal(Workflow, ModelSQL, ModelView):
|
|
"Goal"
|
|
__name__ = 'sale.goal'
|
|
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscalyear',
|
|
required=True, states=_STATES, context={
|
|
'fiscalyear': Eval('fiscalyear')
|
|
})
|
|
company = fields.Many2One('company.company', 'Company', required=True,
|
|
states=_STATES)
|
|
lines = fields.One2Many('sale.goal.line', 'goal', 'Lines',
|
|
states=_STATES)
|
|
state = fields.Selection([
|
|
('draft', 'Draft'),
|
|
('open', 'Open'),
|
|
('closed', 'Closed'),
|
|
], 'State', readonly=True)
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(Goal, cls).__setup__()
|
|
cls._buttons.update({
|
|
'draft': {
|
|
'invisible': Eval('state') != 'open',
|
|
},
|
|
'open': {
|
|
'invisible': Eval('state') != 'draft',
|
|
},
|
|
'close': {
|
|
'invisible': Eval('state') != 'open',
|
|
},
|
|
})
|
|
cls._transitions |= set((
|
|
('draft', 'open'),
|
|
('open', 'draft'),
|
|
('open', 'closed'),
|
|
))
|
|
|
|
def get_rec_name(self, name):
|
|
if self.fiscalyear:
|
|
return self.fiscalyear.name
|
|
|
|
@staticmethod
|
|
def default_company():
|
|
return Transaction().context.get('company')
|
|
|
|
@staticmethod
|
|
def default_fiscalyear():
|
|
FiscalYear = Pool().get('account.fiscalyear')
|
|
return FiscalYear.find(
|
|
Transaction().context.get('company'), exception=False)
|
|
|
|
@staticmethod
|
|
def default_state():
|
|
return 'draft'
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('draft')
|
|
def draft(cls, lines):
|
|
pass
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('open')
|
|
def open(cls, lines):
|
|
pass
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('closed')
|
|
def close(cls, lines):
|
|
pass
|
|
|
|
@classmethod
|
|
def get_periods_zeros(cls, fiscalyear):
|
|
periods_zeros = {}
|
|
for p in fiscalyear.periods:
|
|
month = p.name[-2:]
|
|
if month.isdigit() and int(month) >= 1 and int(month) <= 12:
|
|
periods_zeros[month] = _ZERO
|
|
return periods_zeros
|
|
|
|
@classmethod
|
|
def get_periods_goal(cls, fiscalyear):
|
|
periods_goal = []
|
|
for p in fiscalyear.periods:
|
|
month = p.name[-2:]
|
|
if month.isdigit() and int(month) >= 1 and int(month) <= 12:
|
|
periods_goal.append(p)
|
|
return periods_goal
|
|
|
|
|
|
class GoalLine(ModelSQL, ModelView):
|
|
"Goal Line"
|
|
__name__ = 'sale.goal.line'
|
|
goal = fields.Many2One('sale.goal', 'Goal', required=True)
|
|
kind = fields.Selection(KIND, 'kind', states={
|
|
'required': True
|
|
})
|
|
type = fields.Selection(TYPE, 'Type', required=True)
|
|
|
|
start_date = fields.Date('Start Date', required=True)
|
|
end_date = fields.Date('End Date', required=True)
|
|
lines = fields.One2Many('sale.indicator', 'goal_line', 'Goal Lines')
|
|
fixed_amount = fields.Numeric('Fixed Amount', digits=(16, 2))
|
|
type_string = type.translated('type')
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(GoalLine, cls).__setup__()
|
|
|
|
@classmethod
|
|
def __register__(cls, module_name):
|
|
super(GoalLine, cls).__register__(module_name)
|
|
sql_table = cls.__table_handler__(module_name)
|
|
|
|
if sql_table.column_exist('indicator'):
|
|
sql_table.drop_column('indicator')
|
|
if sql_table.column_exist('period'):
|
|
sql_table.drop_column('period')
|
|
if sql_table.column_exist('amount'):
|
|
sql_table.column_rename('amount', 'fixed_amount')
|
|
|
|
def get_sales_period(self, period):
|
|
Invoice = Pool().get('account.invoice')
|
|
InvoiceLine = Pool().get('account.invoice.line')
|
|
res = _ZERO
|
|
if self.indicator.kind in ['salesman', 'shop']:
|
|
dom_invoice = [
|
|
('invoice_date', '>=', period.start_date),
|
|
('invoice_date', '<=', period.end_date),
|
|
('type', '=', 'out'),
|
|
('state', 'in', ['posted', 'paid', 'validated']),
|
|
]
|
|
if self.indicator.kind == 'salesman':
|
|
dom_invoice.append(('salesman', '=', self.indicator.salesman))
|
|
elif self.indicator.kind == 'shop':
|
|
dom_invoice.append(('shop', '=', self.indicator.shop))
|
|
res = sum(s.untaxed_amount for s in Invoice.search(dom_invoice))
|
|
else:
|
|
dom_invoice = [
|
|
('invoice.invoice_date', '>=', period.start_date),
|
|
('invoice.invoice_date', '<=', period.end_date),
|
|
('invoice.state', 'in', ['posted', 'paid', 'validated']),
|
|
]
|
|
if self.indicator.kind == 'product':
|
|
dom_invoice.append(('product', '=', self.indicator.product))
|
|
elif self.indicator.kind == 'category':
|
|
dom_invoice.append(('product.template.account_category', '=', self.indicator.category))
|
|
res = sum([sl.amount for sl in InvoiceLine.search(dom_invoice)])
|
|
return res
|
|
|
|
|
|
class SaleIndicator(ModelSQL, ModelView):
|
|
"Sale Indicator"
|
|
__name__ = 'sale.indicator'
|
|
# _rec_name = 'name'
|
|
|
|
name = fields.Function(fields.Char('Name'), 'get_rec_name')
|
|
goal_line = fields.Many2One('sale.goal.line', 'Goal Line', required=True)
|
|
salesman = fields.Many2One('company.employee', 'Salesman')
|
|
product = fields.Many2One('product.product', 'Product',
|
|
domain=[
|
|
('template.type', 'in', ['goods', 'services']),
|
|
('template.salable', '=', True),
|
|
])
|
|
category = fields.Many2One('product.category', 'Category')
|
|
|
|
amount = fields.Numeric('Amount', digits=(16, 2), required=False)
|
|
|
|
@classmethod
|
|
def __register__(cls, module_name):
|
|
super(SaleIndicator, cls).__register__(module_name)
|
|
table = cls.__table_handler__(module_name)
|
|
|
|
if table.column_exist('name'):
|
|
table.drop_column('name')
|
|
|
|
if table.column_exist('kind'):
|
|
table.drop_column('kind')
|
|
|
|
def get_rec_name(self, name):
|
|
if self.goal_line:
|
|
type = ''
|
|
if self.goal_line.type:
|
|
type = self.goal_line.type
|
|
attribute = self.goal_line.kind
|
|
return getattr(self, attribute).name + '_' + type
|
|
|
|
def get_period_name(self, name):
|
|
if self.goal_line and self.goal_line.type:
|
|
pass
|
|
|
|
|
|
class SaleGoalReport(Report):
|
|
__name__ = 'sale.goal.report'
|
|
|
|
@classmethod
|
|
def get_context(cls, records, header, data):
|
|
report_context = super().get_context(records, header, data)
|
|
pool = Pool()
|
|
Goal = pool.get('sale.goal')
|
|
total_amounts = []
|
|
|
|
lines = {}
|
|
for obj in records:
|
|
report_context.update(obj.get_periods_zeros(obj.fiscalyear))
|
|
for line in obj.lines:
|
|
if line.indicator.id not in lines.keys():
|
|
lines[line.indicator.id] = {
|
|
'name': line.indicator.name,
|
|
'total': _ZERO,
|
|
}
|
|
lines[line.indicator.id].update(Goal.get_periods_zeros(obj.fiscalyear))
|
|
month = line.period.name[-2:]
|
|
lines[line.indicator.id][month] = line.amount
|
|
lines[line.indicator.id]['total'] += line.amount
|
|
data[month] += line.amount
|
|
total_amounts.append(line.amount)
|
|
report_context['fiscalyear'] = obj.fiscalyear.name
|
|
|
|
report_context['data'] = data
|
|
report_context['sum_total_amount'] = sum(total_amounts)
|
|
report_context['objects'] = lines.values()
|
|
return report_context
|
|
|
|
|
|
class SaleGoalJournalStart(ModelView):
|
|
'Sale Goal Journal Start'
|
|
__name__ = 'sale.goal_journal.start'
|
|
company = fields.Many2One('company.company', 'Company', required=True)
|
|
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscalyear', required=True)
|
|
indicator = fields.Many2One('sale.indicator', 'Indicator', required=True,
|
|
domain=[('kind', 'in', ('salesman', 'shop'))])
|
|
type = fields.Selection([
|
|
('monthly', 'Monthly'),
|
|
('annual', 'Annual'),
|
|
], 'Type', required=True)
|
|
period = fields.Many2One('account.period', 'Period',
|
|
states = {
|
|
'required': Eval('type') == 'monthly',
|
|
},
|
|
domain=[
|
|
('fiscalyear', '=', Eval('fiscalyear')),
|
|
], depends=['fiscalyear'],)
|
|
|
|
@staticmethod
|
|
def default_company():
|
|
return Transaction().context.get('company')
|
|
|
|
@fields.depends('fiscalyear')
|
|
def on_change_fiscalyear(self):
|
|
self.period = None
|
|
|
|
@staticmethod
|
|
def default_fiscalyear():
|
|
FiscalYear = Pool().get('account.fiscalyear')
|
|
return FiscalYear.find(
|
|
Transaction().context.get('company'), exception=False)
|
|
|
|
|
|
class SaleGoalJournal(Wizard):
|
|
'Sale Goal Journal'
|
|
__name__ = 'sale.goal_journal'
|
|
start = StateView('sale.goal_journal.start',
|
|
'sale_goal.sale_goal_journal_start_view_form', [
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
|
])
|
|
print_ = StateReport('sale_goal.goal_journal_report')
|
|
|
|
def do_print_(self, action):
|
|
indicator_id = None
|
|
if self.start.indicator:
|
|
indicator_id = self.start.indicator.id
|
|
|
|
data = {
|
|
'company': self.start.company.id,
|
|
'fiscalyear': self.start.fiscalyear.id,
|
|
'period': self.start.period.id,
|
|
'indicator': indicator_id,
|
|
}
|
|
return action, data
|
|
|
|
def transition_print_(self):
|
|
return 'end'
|
|
|
|
|
|
class SaleGoalJournalReport(Report):
|
|
__name__ = 'sale_goal.goal_journal_report'
|
|
|
|
@classmethod
|
|
def get_context(cls, records, header, data):
|
|
report_context = super().get_context(records, header, data)
|
|
pool = Pool()
|
|
Invoice = pool.get('account.invoice')
|
|
Goal = pool.get('sale.goal')
|
|
Fiscalyear = pool.get('account.fiscalyear')
|
|
Period = pool.get('account.period')
|
|
Indicator = pool.get('sale.indicator')
|
|
GoalLine = pool.get('sale.goal.line')
|
|
|
|
fiscalyear = Fiscalyear(data['fiscalyear'])
|
|
goals = Goal.search([
|
|
('fiscalyear', '=', data['fiscalyear']),
|
|
])
|
|
period = Period(data['period'])
|
|
indicator = Indicator(data['indicator'])
|
|
|
|
goal_amount = _ZERO
|
|
if goals:
|
|
goal = goals[0]
|
|
lines = GoalLine.search([
|
|
('goal', '=', goal.id),
|
|
('period', '=', data['period']),
|
|
('indicator', '=', data['indicator']),
|
|
])
|
|
if lines:
|
|
goal_amount = lines[0].amount
|
|
|
|
kind = getattr(indicator, 'kind')
|
|
val_id = getattr(indicator, kind)
|
|
|
|
dom_sale = [
|
|
('invoice_date', '>=', period.start_date),
|
|
('invoice_date', '<=', period.end_date),
|
|
('type', '=', 'out'),
|
|
('state', 'in', ['posted', 'paid', 'validated']),
|
|
(kind, '=', val_id),
|
|
]
|
|
records = Invoice.search(dom_sale, order=[('invoice_date', 'ASC')])
|
|
result = sum(invoice.untaxed_amount for invoice in records)
|
|
|
|
report_context['records'] = records
|
|
report_context['year'] = fiscalyear.name
|
|
report_context['total_amount'] = result
|
|
report_context['today'] = date.today()
|
|
report_context['period'] = period.name
|
|
report_context['goal_amount'] = goal_amount
|
|
report_context['result'] = result
|
|
report_context['indicator'] = indicator.name
|
|
if goal_amount > _ZERO:
|
|
achieve = (float(result) / float(goal_amount)) * 100
|
|
else:
|
|
achieve = _ZERO
|
|
report_context['achieve'] = achieve
|
|
|
|
return report_context
|
|
|
|
|
|
class SaleGoalMonthRankingStart(ModelView):
|
|
'Goal Month Ranking Start'
|
|
__name__ = 'sale_goal.month_ranking.start'
|
|
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year', required=True)
|
|
company = fields.Many2One('company.company', 'Company', required=True)
|
|
period = fields.Many2One('account.period', 'Period',
|
|
depends=['fiscalyear'], required=True, domain=[
|
|
('fiscalyear', '=', Eval('fiscalyear')),
|
|
])
|
|
|
|
@staticmethod
|
|
def default_company():
|
|
return Transaction().context.get('company')
|
|
|
|
@fields.depends('fiscalyear')
|
|
def on_change_fiscalyear(self):
|
|
self.period = None
|
|
|
|
@staticmethod
|
|
def default_fiscalyear():
|
|
FiscalYear = Pool().get('account.fiscalyear')
|
|
return FiscalYear.find(
|
|
Transaction().context.get('company'), exception=False)
|
|
|
|
|
|
class SaleGoalMonthRanking(Wizard):
|
|
'Goal Month Ranking'
|
|
__name__ = 'sale_goal.month_ranking'
|
|
start = StateView('sale_goal.month_ranking.start',
|
|
'sale_goal.sale_goal_month_ranking_start_view_form', [
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
|
])
|
|
print_ = StateAction('sale_goal.report_sale_goal_month_ranking')
|
|
|
|
def do_print_(self, action):
|
|
data = {
|
|
'company': self.start.company.id,
|
|
'fiscalyear': self.start.fiscalyear.id,
|
|
'period': self.start.period.id,
|
|
}
|
|
return action, data
|
|
|
|
def transition_print_(self):
|
|
return 'end'
|
|
|
|
|
|
class SaleGoalMonthRankingReport(Report):
|
|
__name__ = 'sale_goal.month_ranking.report'
|
|
|
|
@classmethod
|
|
def get_context(cls, records, header, data):
|
|
report_context = super().get_context(records, header, data)
|
|
pool = Pool()
|
|
|
|
GoalLine = pool.get('sale.goal.line')
|
|
Fiscalyear = pool.get('account.fiscalyear')
|
|
Period = pool.get('account.period')
|
|
fiscalyear = Fiscalyear(data['fiscalyear'])
|
|
period = Period(data['period'])
|
|
|
|
goal_lines = GoalLine.search([
|
|
('goal.fiscalyear', '=', data['fiscalyear']),
|
|
('period', '=', data['period']),
|
|
])
|
|
|
|
sum_goal_amount = 0
|
|
sum_total_amount = 0
|
|
objects = []
|
|
for line in goal_lines:
|
|
sales_period = line.get_sales_period(period)
|
|
# setattr(line, 'total_amount', sales_period)
|
|
achieve = (float(sales_period) / float(line.amount)) * 100
|
|
# setattr(line, 'achieve', achieve)
|
|
sum_goal_amount += line.amount
|
|
sum_total_amount += sales_period
|
|
objects.append({'line': line, 'total_amount': sales_period, 'achieve': achieve})
|
|
avg_achieve = 0
|
|
if sum_goal_amount:
|
|
avg_achieve = (float(sum_total_amount) / float(sum_goal_amount)) * 100
|
|
report_context['records'] = objects
|
|
report_context['fiscalyear'] = fiscalyear.name
|
|
report_context['period'] = period.name
|
|
report_context['sum_goal_amount'] = sum_goal_amount
|
|
report_context['sum_total_amount'] = sum_total_amount
|
|
report_context['avg_achieve'] = avg_achieve
|
|
return report_context
|
|
|
|
|
|
class SaleGoalAnnualRankingStart(ModelView):
|
|
'Goal Annual Ranking Start'
|
|
__name__ = 'sale_goal.annual_ranking.start'
|
|
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year', required=True)
|
|
company = fields.Many2One('company.company', 'Company', required=True)
|
|
indicator = fields.Selection([
|
|
('salesman', 'Salesman'),
|
|
('by_category', 'By Category'),
|
|
], 'Indicator', required=True)
|
|
report_kind = fields.Selection([
|
|
('profit', 'Profit'),
|
|
('total_sale', 'Total Sale'),
|
|
], 'Report Kind', required=True)
|
|
|
|
@staticmethod
|
|
def default_report_class():
|
|
return 'total_sale'
|
|
|
|
@staticmethod
|
|
def default_company():
|
|
return Transaction().context.get('company')
|
|
|
|
@staticmethod
|
|
def default_fiscalyear():
|
|
FiscalYear = Pool().get('account.fiscalyear')
|
|
return FiscalYear.find(
|
|
Transaction().context.get('company'), exception=False)
|
|
|
|
|
|
class SaleGoalAnnualRanking(Wizard):
|
|
'Goal Annual Ranking'
|
|
__name__ = 'sale_goal.annual_ranking'
|
|
start = StateView('sale_goal.annual_ranking.start',
|
|
'sale_goal.sale_goal_annual_ranking_start_view_form', [
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
|
])
|
|
print_ = StateReport('sale_goal.annual_ranking_report')
|
|
|
|
def do_print_(self, action):
|
|
data = {
|
|
'report_kind': self.start.report_kind,
|
|
'company': self.start.company.id,
|
|
'fiscalyear': self.start.fiscalyear.id,
|
|
'indicator': self.start.indicator,
|
|
}
|
|
return action, data
|
|
|
|
def transition_print_(self):
|
|
return 'end'
|
|
|
|
|
|
class SaleGoalAnnualRankingReport(Report):
|
|
'Goal Annual Ranking Report'
|
|
__name__ = 'sale_goal.annual_ranking_report'
|
|
|
|
@classmethod
|
|
def _get_sales_month(cls, period, indicator_id, data):
|
|
#FIXME bug when any period is missing in fiscal year
|
|
pool = Pool()
|
|
Invoice = pool.get('account.invoice')
|
|
indicator_field = data['indicator']
|
|
if indicator_id == 0:
|
|
indicator_id = None
|
|
dom_ = [
|
|
('company', '=', data['company']),
|
|
('invoice_date', '>=', period.start_date),
|
|
('invoice_date', '<=', period.end_date),
|
|
('type', '=', 'out'),
|
|
('state', 'in', ['posted', 'paid', 'validated']),
|
|
(indicator_field, '=', indicator_id),
|
|
]
|
|
|
|
invoices = Invoice.search(dom_)
|
|
if data['report_kind'] == 'total_sale':
|
|
amount = sum([i.total_amount for i in invoices])
|
|
else:
|
|
amount = sum([i.untaxed_amount - cls.get_inv_cost(i) for i in invoices])
|
|
return amount
|
|
|
|
@classmethod
|
|
def _get_sales_by_category_month(cls, period, indicator_id, data):
|
|
#FIXME bug when any period is missing in fiscal year
|
|
pool = Pool()
|
|
InvoiceLine = pool.get('account.invoice.line')
|
|
if indicator_id == 0:
|
|
indicator_id = None
|
|
dom_ = [
|
|
('invoice.company', '=', data['company']),
|
|
('invoice.invoice_date', '>=', period.start_date),
|
|
('invoice.invoice_date', '<=', period.end_date),
|
|
('invoice.type', '=', 'out'),
|
|
('invoice.state', 'in', ['posted', 'paid']),
|
|
('product.template.account_category', '=', indicator_id),
|
|
]
|
|
if data.get('shop'):
|
|
dom_.append([('invoice.shop', '=', data['shop']), ])
|
|
|
|
lines = InvoiceLine.search(dom_)
|
|
if data['report_kind'] == 'total_sale':
|
|
amount = sum([i.amount for i in lines])
|
|
else:
|
|
amount = sum([i.amount - l.product.template.cost_price for l in lines])
|
|
return amount
|
|
|
|
@classmethod
|
|
def get_inv_cost(cls, invoice):
|
|
res = []
|
|
for line in invoice.lines:
|
|
expense = 0
|
|
if line.type != 'line':
|
|
return res
|
|
if hasattr(line.product.template, 'expense'):
|
|
expense = line.product.template.expense or Decimal('0.0')
|
|
res.append((line.product.template.cost_price + expense) * Decimal(line.quantity))
|
|
return sum(res)
|
|
|
|
@classmethod
|
|
def get_records_to_eval(cls, fiscalyear, data):
|
|
pool = Pool()
|
|
Employee = pool.get('company.employee')
|
|
Category = pool.get('product.category')
|
|
records = []
|
|
if data['indicator'] == 'by_category':
|
|
records = Category.search([('templates', '!=', None)])
|
|
else:
|
|
cursor = Transaction().connection.cursor()
|
|
query = "SELECT salesman FROM account_invoice WHERE invoice_date>='%s' AND invoice_date<='%s' GROUP BY salesman"
|
|
cursor.execute(query % (fiscalyear.start_date, fiscalyear.end_date))
|
|
values = [i[0] for i in cursor.fetchall()]
|
|
if None in values:
|
|
records.append(None)
|
|
values.remove(None)
|
|
records.extend(Employee.browse(values))
|
|
return records
|
|
|
|
@classmethod
|
|
def get_context(cls, records, header, data):
|
|
report_context = super().get_context(records, header, data)
|
|
pool = Pool()
|
|
Fiscalyear = pool.get('account.fiscalyear')
|
|
|
|
Shop = pool.get('sale.shop')
|
|
Goal = pool.get('sale.goal')
|
|
fiscalyear = Fiscalyear(data['fiscalyear'])
|
|
|
|
indicators = {}
|
|
shop_name = ''
|
|
periods_zeros = Goal.get_periods_zeros(fiscalyear)
|
|
periods_goal = Goal.get_periods_goal(fiscalyear)
|
|
|
|
sum_annual_goal = []
|
|
data.update(periods_zeros.copy())
|
|
if data['indicator'] == 'shop':
|
|
records = Shop.search([])
|
|
|
|
records = cls.get_records_to_eval(fiscalyear, data)
|
|
total_year = []
|
|
if len(records) < 1:
|
|
records = [None]
|
|
for ind in records:
|
|
if ind:
|
|
if data['indicator'] == 'shop':
|
|
ind_name = ind.name
|
|
elif data['indicator'] == 'by_category':
|
|
ind_name = ind.name
|
|
else:
|
|
ind_name = ind.party.name
|
|
ind_id = ind.id
|
|
else:
|
|
ind_id = 0
|
|
ind_name = 'N.D.'
|
|
|
|
if ind_id not in indicators.keys():
|
|
indicators[ind_id] = {
|
|
'indicator': ind_name,
|
|
'total': _ZERO,
|
|
'annual_goal': _ZERO,
|
|
'achieve': _ZERO,
|
|
}
|
|
indicators[ind_id].update(periods_zeros.copy())
|
|
|
|
dom_goal = [
|
|
('goal.fiscalyear', '=', data['fiscalyear'])
|
|
]
|
|
|
|
if data['indicator'] == 'shop':
|
|
attribute = 'indicator.shop'
|
|
elif data['indicator'] == 'salesman':
|
|
attribute = 'indicator.salesman'
|
|
else:
|
|
attribute = None
|
|
|
|
if attribute:
|
|
dom_goal.append(
|
|
(attribute, '=', ind_id),
|
|
)
|
|
goal_lines = GoalLine.search(dom_goal)
|
|
annual_goal = sum([l.amount for l in goal_lines])
|
|
indicators[ind_id]['annual_goal'] = annual_goal
|
|
sum_annual_goal.append(annual_goal)
|
|
|
|
res_total = _ZERO
|
|
for p in periods_goal:
|
|
nperiod = p.name[-2:]
|
|
if data['indicator'] in ('salesman', 'shop'):
|
|
res = cls._get_sales_month(
|
|
p,
|
|
ind_id,
|
|
data,
|
|
)
|
|
else: # by_category
|
|
res = cls._get_sales_by_category_month(
|
|
p,
|
|
ind_id,
|
|
data,
|
|
)
|
|
indicators[ind_id][nperiod] = res
|
|
|
|
res_total += res
|
|
data[nperiod] += res
|
|
total_year.append(res)
|
|
|
|
indicators[ind_id]['total'] = res_total
|
|
if annual_goal > 0:
|
|
achieve = (float(res_total) / float(annual_goal)) * 100
|
|
else:
|
|
achieve = '---'
|
|
indicators[ind_id]['achieve'] = achieve
|
|
|
|
report_context['data'] = data
|
|
report_context['shop'] = shop_name
|
|
report_context['records'] = indicators.values()
|
|
report_context['year'] = fiscalyear.name
|
|
report_context['total_year'] = sum(total_year)
|
|
report_context['sum_annual_goal'] = sum(sum_annual_goal)
|
|
if sum(sum_annual_goal) > 0:
|
|
res = (float(report_context['total_year']) / float(sum(sum_annual_goal))) * 100
|
|
else:
|
|
res = '---'
|
|
report_context['avg_achieve'] = res
|
|
return report_context
|