[IMP] membership: report, yml

bzr revid: hmo@tinyerp.com-20100609151036-9ynxz71j28y71yb9
This commit is contained in:
atp (OpenERP) 2010-06-09 20:40:36 +05:30 committed by Harry (OpenERP)
parent ccd09bcef3
commit ff1681b22f
4 changed files with 523 additions and 0 deletions

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
import report_membership

View File

@ -0,0 +1,175 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
import tools
class ReportPartnerMemberYear(osv.osv):
'''Membership by Years'''
_name = 'report.partner_member.year'
_description = __doc__
_auto = False
_rec_name = 'year'
_columns = {
'year': fields.char('Year', size='4', readonly=True, select=1),
'canceled_number': fields.integer('Canceled', readonly=True),
'waiting_number': fields.integer('Waiting', readonly=True),
'invoiced_number': fields.integer('Invoiced', readonly=True),
'paid_number': fields.integer('Paid', readonly=True),
'canceled_amount': fields.float('Canceled', digits=(16, 2), readonly=True),
'waiting_amount': fields.float('Waiting', digits=(16, 2), readonly=True),
'invoiced_amount': fields.float('Invoiced', digits=(16, 2), readonly=True),
'paid_amount': fields.float('Paid', digits=(16, 2), readonly=True),
'currency': fields.many2one('res.currency', 'Currency', readonly=True,
select=2),
}
def init(self, cr):
'''Create the view'''
cr.execute("""
CREATE OR REPLACE VIEW report_partner_member_year AS (
SELECT
MIN(id) AS id,
COUNT(ncanceled) as canceled_number,
COUNT(npaid) as paid_number,
COUNT(ninvoiced) as invoiced_number,
COUNT(nwaiting) as waiting_number,
SUM(acanceled) as canceled_amount,
SUM(apaid) as paid_amount,
SUM(ainvoiced) as invoiced_amount,
SUM(awaiting) as waiting_amount,
year,
currency
FROM (SELECT
CASE WHEN ai.state = 'cancel' THEN ml.id END AS ncanceled,
CASE WHEN ai.state = 'paid' THEN ml.id END AS npaid,
CASE WHEN ai.state = 'open' THEN ml.id END AS ninvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN ml.id END AS nwaiting,
CASE WHEN ai.state = 'cancel'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS acanceled,
CASE WHEN ai.state = 'paid'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS apaid,
CASE WHEN ai.state = 'open'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS ainvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS awaiting,
TO_CHAR(ml.date_from, 'YYYY') AS year,
ai.currency_id AS currency,
MIN(ml.id) AS id
FROM membership_membership_line ml
JOIN (account_invoice_line ail
LEFT JOIN account_invoice ai
ON (ail.invoice_id = ai.id))
ON (ml.account_invoice_line = ail.id)
JOIN res_partner p
ON (ml.partner = p.id)
GROUP BY TO_CHAR(ml.date_from, 'YYYY'), ai.state,
ai.currency_id, ml.id) AS foo
GROUP BY year, currency)
""")
ReportPartnerMemberYear()
class ReportPartnerMemberYearNew(osv.osv):
'''New Membership by Years'''
_name = 'report.partner_member.year_new'
_description = __doc__
_auto = False
_rec_name = 'year'
_columns = {
'year': fields.char('Year', size='4', readonly=True, select=1),
'canceled_number': fields.integer('Canceled', readonly=True),
'waiting_number': fields.integer('Waiting', readonly=True),
'invoiced_number': fields.integer('Invoiced', readonly=True),
'paid_number': fields.integer('Paid', readonly=True),
'canceled_amount': fields.float('Canceled', digits=(16, 2), readonly=True),
'waiting_amount': fields.float('Waiting', digits=(16, 2), readonly=True),
'invoiced_amount': fields.float('Invoiced', digits=(16, 2), readonly=True),
'paid_amount': fields.float('Paid', digits=(16, 2), readonly=True),
'currency': fields.many2one('res.currency', 'Currency', readonly=True,
select=2),
}
def init(self, cursor):
'''Create the view'''
cursor.execute("""
CREATE OR REPLACE VIEW report_partner_member_year_new AS (
SELECT
MIN(id) AS id,
COUNT(ncanceled) AS canceled_number,
COUNT(npaid) AS paid_number,
COUNT(ninvoiced) AS invoiced_number,
COUNT(nwaiting) AS waiting_number,
SUM(acanceled) AS canceled_amount,
SUM(apaid) AS paid_amount,
SUM(ainvoiced) AS invoiced_amount,
SUM(awaiting) AS waiting_amount,
year,
currency
FROM (SELECT
CASE WHEN ai.state = 'cancel' THEN ml2.id END AS ncanceled,
CASE WHEN ai.state = 'paid' THEN ml2.id END AS npaid,
CASE WHEN ai.state = 'open' THEN ml2.id END AS ninvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN ml2.id END AS nwaiting,
CASE WHEN ai.state = 'cancel'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS acanceled,
CASE WHEN ai.state = 'paid'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS apaid,
CASE WHEN ai.state = 'open'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS ainvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS awaiting,
TO_CHAR(ml2.date_from, 'YYYY') AS year,
ai.currency_id AS currency,
MIN(ml2.id) AS id
FROM (SELECT
partner AS id,
MIN(date_from) AS date_from
FROM membership_membership_line
GROUP BY partner
) AS ml1
JOIN membership_membership_line ml2
JOIN (account_invoice_line ail
LEFT JOIN account_invoice ai
ON (ail.invoice_id = ai.id))
ON (ml2.account_invoice_line = ail.id)
ON (ml1.id = ml2.partner AND ml1.date_from = ml2.date_from)
JOIN res_partner p
ON (ml2.partner = p.id)
GROUP BY TO_CHAR(ml2.date_from, 'YYYY'), ai.state,
ai.currency_id, ml2.id) AS foo
GROUP BY year, currency
)
""")
ReportPartnerMemberYearNew()

View File

@ -0,0 +1,211 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- REPORTING/MEMBERSHIP BY YEAR -->
<record model="ir.ui.view" id="view_report_partner_member_year_tree1">
<field name="name">report.partner_member.year.tree</field>
<field name="model">report.partner_member.year</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Membership by Years">
<field name="canceled_number"/>
<field name="waiting_number"/>
<field name="invoiced_number"/>
<field name="paid_number"/>
<field name="year"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_tree2">
<field name="name">report.partner_member.year.tree</field>
<field name="model">report.partner_member.year</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Membership by Years">
<field name="canceled_amount"/>
<field name="waiting_amount"/>
<field name="invoiced_amount"/>
<field name="paid_amount"/>
<field name="currency"/>
<field name="year"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_graph1">
<field name="name">report.partner_member.year.graph1</field>
<field name="model">report.partner_member.year</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Membership by Years" type="bar">
<field name="year"/>
<field name="canceled_number"/>
<field name="waiting_number"/>
<field name="invoiced_number"/>
<field name="paid_number"/>
</graph>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_graph2">
<field name="name">report.partner_member.year.graph2</field>
<field name="model">report.partner_member.year</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Membership by Years" type="bar">
<field name="year"/>
<field name="canceled_amount"/>
<field name="waiting_amount"/>
<field name="invoiced_amount"/>
<field name="paid_amount"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_partner_member_year_tree">
<field name="res_model">report.partner_member.year</field>
<field name="view_type">form</field>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_tree_view1">
<field name="sequence" eval="3"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_partner_member_year_tree1"/>
<field name="act_window_id" ref="action_report_partner_member_year_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_tree_view4">
<field name="sequence" eval="4"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_partner_member_year_tree2"/>
<field name="act_window_id" ref="action_report_partner_member_year_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_tree_view2">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_partner_member_year_graph1"/>
<field name="act_window_id" ref="action_report_partner_member_year_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_tree_view3">
<field name="sequence" eval="2"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_partner_member_year_graph2"/>
<field name="act_window_id" ref="action_report_partner_member_year_tree"/>
</record>
<menuitem name="Membership by Years" parent="menu_reporting"
action="action_report_partner_member_year_tree"
id="menu_report_partner_member_year"/>
<!-- REPORTING/NEW MEMBERSHIP BY YEAR -->
<record model="ir.ui.view" id="view_report_partner_member_year_new_tree1">
<field name="name">report.partner_member.year_new.tree</field>
<field name="model">report.partner_member.year_new</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="New Membership by Years">
<field name="canceled_number"/>
<field name="waiting_number"/>
<field name="invoiced_number"/>
<field name="paid_number"/>
<field name="year"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_new_tree2">
<field name="name">report.partner_member.year_new.tree</field>
<field name="model">report.partner_member.year_new</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="New Membership by Years">
<field name="canceled_amount"/>
<field name="waiting_amount"/>
<field name="invoiced_amount"/>
<field name="paid_amount"/>
<field name="currency"/>
<field name="year"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_new_graph1">
<field name="name">report.partner_member.year_new.graph1</field>
<field name="model">report.partner_member.year_new</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="New Membership by Years" type="bar">
<field name="year"/>
<field name="canceled_number"/>
<field name="waiting_number"/>
<field name="invoiced_number"/>
<field name="paid_number"/>
</graph>
</field>
</record>
<record model="ir.ui.view" id="view_report_partner_member_year_new_graph2">
<field name="name">report.partner_member.year_new.graph2</field>
<field name="model">report.partner_member.year_new</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="New Membership by Years" type="bar">
<field name="year"/>
<field name="canceled_amount"/>
<field name="waiting_amount"/>
<field name="invoiced_amount"/>
<field name="paid_amount"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="action_report_partner_member_year_new_tree">
<field name="res_model">report.partner_member.year_new</field>
<field name="view_type">form</field>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_new_tree_view4">
<field name="sequence" eval="4"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_partner_member_year_new_tree2"/>
<field name="act_window_id" ref="action_report_partner_member_year_new_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_new_tree_view1">
<field name="sequence" eval="3"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_partner_member_year_new_tree1"/>
<field name="act_window_id" ref="action_report_partner_member_year_new_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_new_tree_view2">
<field name="sequence" eval="1"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_partner_member_year_new_graph1"/>
<field name="act_window_id" ref="action_report_partner_member_year_new_tree"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_partner_member_year_new_tree_view3">
<field name="sequence" eval="2"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_partner_member_year_new_graph2"/>
<field name="act_window_id" ref="action_report_partner_member_year_new_tree"/>
</record>
<menuitem name="New Membership by Years" parent="menu_reporting"
action="action_report_partner_member_year_new_tree"
id="menu_report_partner_member_year_new"/>
</data>
</openerp>

View File

@ -0,0 +1,115 @@
- |
In Order to test the Membership in OpenERP, which allows us to manage all operations for managing memberships.
- |
We have to create "Membership Products" to make it available for partner or customer to make membership with it.
select product type to "service" type and membership field is ticked to visible this product while creating membership for the partner.
-
!record {model: product.product, id: product_product_membershipproduct0}:
categ_id: product.cat1
membership: 1
membership_date_from: '2009-06-01'
membership_date_to: '2010-06-01'
name: Membership Products
type: service
list_price: 80.00
- |
I create new member "Mark Johnson" and I provide an address to this
new customer, as well as an email "info@mycustomer.com".
-
!record {model: res.partner, id: res_partner_markjohnson0}:
address:
- city: paris
country_id: base.fr
name: Arthur Grosbonnet
street: 1 rue Rockfeller
title: M.
type: default
zip: '75016'
credit_limit: 0.0
membership_amount: 0.0
name: Mark Johnson
property_account_payable: account.a_pay
property_account_receivable: account.a_recv
- |
I check that "Current membership state" is set to "Non Member".
-
!assert {model: res.partner, id: res_partner_markjohnson0}:
- membership_state == 'none'
- |
I can make it a Free member by selecting the "Free member" check box.
-
!record {model: res.partner, id: membership.res_partner_markjohnson0}:
free_member: 1
- |
Now, I create Membership Invoices using wizard available on partner and Select Membership Product.
-
!record {model: membership.invoice, id: membership_invoice_0}:
product_id: membership.product_product_membershipproduct0
- |
I check that address is defined or not for this Member.
-
!python {model: membership.invoice}: |
partner_ids = [ref('res_partner_markjohnson0')]
addre_obj = self.pool.get('res.partner.address')
ids = addre_obj.search(cr, uid, [('partner_id', '=', partner_ids)])
addre_id = addre_obj.browse(cr, uid, ids)[0]
assert addre_id.partner_id
assert addre_id.id
assert addre_id.type
- |
I click on "Confirm" button of this wizard.
-
!python {model: membership.invoice}: |
self.membership_invoice(cr, uid, [ref("membership_invoice_0")], {"active_ids": [ref("membership.res_partner_markjohnson0")]})
- |
I check that Invoice is created for this members.
-
!python {model: res.partner}: |
invoice_obj = self.pool.get('account.invoice')
partner_obj = self.pool.get('res.partner')
product_obj = self.pool.get('product.product')
invoice_line_obj = self.pool.get(('account.invoice.line'))
partner_id = self.browse(cr, uid, [ref('res_partner_markjohnson0')])[0]
ids = invoice_obj.search(cr, uid, [('partner_id', '=', partner_id.id), ('account_id', '=', partner_id.property_account_receivable.id)])
invoice_id = invoice_obj.browse(cr, uid, ids)[0]
product = product_obj.browse(cr, uid, [ref('product_product_membershipproduct0')], context=context)[0]
line_ids = invoice_line_obj.search(cr, uid, [('product_id', '=', product.id), ('invoice_id', '=', invoice_id.id)])
line_id = invoice_line_obj.browse(cr, uid, line_ids)[0]
assert line_id.product_id.id == product.id
assert invoice_id.partner_id.id == partner_id.id
- |
I check that the "Current membership state" will remain same untill opening the invoice.
-
!assert {model: res.partner, id: res_partner_markjohnson0}:
- membership_state == 'free'
- |
"Current membership state" of any member depends on the state of invoice.
So, I check that invoice is in draft state then the "membership state" of a member is "Waiting member".
-
!python {model: membership.membership_line}: |
partner_id = self.pool.get('res.partner').browse(cr, uid, [ref('res_partner_markjohnson0')])[0]
ids = self.search(cr, uid, [('partner', '=', partner_id.id)])
current_id = self.browse(cr, uid, ids)[0]
partner_obj = self.pool.get('res.partner')
inv_obj = self.pool.get('account.invoice')
ids = inv_obj.search(cr, uid, [('partner_id', '=', partner_id.id), ('account_id', '=', partner_id.property_account_receivable.id)])
inv_id = inv_obj.browse(cr, uid, ids)[0]
if inv_id.state == 'draft':
assert current_id == 'waiting'
- |
When the invoice is in open state it become Invoiced Member, When the invoice is in paid state the same "Current membership state" changed to Paid Member.
Now, If we cancel the invoice "Current membership state" changed to Cancel Member.