Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Noah Brackenbury
erp5
Commits
5130c514
Commit
5130c514
authored
Jun 08, 2016
by
Nicolas Wavrant
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_accounting: adds filtering on ledger for Aged Balance Report
parent
fe70bd53
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
329 additions
and
10 deletions
+329
-10
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_getAgedBalanceReportSectionList.py
...ntingTransactionModule_getAgedBalanceReportSectionList.py
+12
-7
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_getDetailedAgedBalanceLineList.py
...untingTransactionModule_getDetailedAgedBalanceLineList.py
+15
-1
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_viewAgedBalanceReport.xml
...ing/AccountingTransactionModule_viewAgedBalanceReport.xml
+1
-0
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_viewAgedBalanceReport/your_ledger.xml
...ngTransactionModule_viewAgedBalanceReport/your_ledger.xml
+84
-0
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_viewAgedBalanceReportDialog.xml
...countingTransactionModule_viewAgedBalanceReportDialog.xml
+1
-0
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_viewAgedBalanceReportDialog/your_ledger.xml
...sactionModule_viewAgedBalanceReportDialog/your_ledger.xml
+84
-0
product/ERP5/tests/testAccountingReports.py
product/ERP5/tests/testAccountingReports.py
+132
-2
No files found.
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_getAgedBalanceReportSectionList.py
View file @
5130c514
...
@@ -43,6 +43,17 @@ selection_columns.append(('period_%s' % (idx + 1),
...
@@ -43,6 +43,17 @@ selection_columns.append(('period_%s' % (idx + 1),
mapping
=
{
'day_count'
:
period_list
[
-
1
]}))))
mapping
=
{
'day_count'
:
period_list
[
-
1
]}))))
editable_columns
.
append
((
'period_%s'
%
(
idx
+
1
),
''
))
editable_columns
.
append
((
'period_%s'
%
(
idx
+
1
),
''
))
selection_params
=
dict
(
section_category
=
section_category
,
section_category_strict
=
section_category_strict
,
account_type
=
account_type
,
editable_columns
=
editable_columns
,
simulation_state
=
simulation_state
,
period_list
=
period_list
,
at_date
=
at_date
)
ledger
=
request
.
get
(
'ledger'
,
None
)
if
ledger
:
selection_params
[
'ledger'
]
=
ledger
return
[
ReportSection
(
form_id
=
(
detailed
and
return
[
ReportSection
(
form_id
=
(
detailed
and
'AccountingTransactionModule_viewDetailedAgedBalanceReportSection'
or
'AccountingTransactionModule_viewDetailedAgedBalanceReportSection'
or
...
@@ -52,10 +63,4 @@ return [ReportSection(form_id=(detailed and
...
@@ -52,10 +63,4 @@ return [ReportSection(form_id=(detailed and
selection_name
=
(
detailed
and
selection_name
=
(
detailed
and
'accounting_transaction_module_detailed_aged_balance_selection'
or
'accounting_transaction_module_detailed_aged_balance_selection'
or
'accounting_transaction_module_summary_aged_balance_selection'
),
'accounting_transaction_module_summary_aged_balance_selection'
),
selection_params
=
dict
(
section_category
=
section_category
,
selection_params
=
selection_params
)]
section_category_strict
=
section_category_strict
,
account_type
=
account_type
,
editable_columns
=
editable_columns
,
simulation_state
=
simulation_state
,
period_list
=
period_list
,
at_date
=
at_date
))]
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_getDetailedAgedBalanceLineList.py
View file @
5130c514
...
@@ -38,6 +38,19 @@ def getSectionTitle(uid):
...
@@ -38,6 +38,19 @@ def getSectionTitle(uid):
last_period_id
=
'period_%s'
%
len
(
period_list
)
last_period_id
=
'period_%s'
%
len
(
period_list
)
line_list
=
[]
line_list
=
[]
extra_kw
=
{}
ledger
=
kw
.
get
(
'ledger'
,
None
)
if
ledger
:
if
not
isinstance
(
ledger
,
list
):
# Allows the generation of reports on different ledgers as the same time
ledger
=
[
ledger
]
portal_categories
=
portal
.
portal_categories
ledger_value_list
=
[
portal_categories
.
restrictedTraverse
(
ledger_category
,
None
)
for
ledger_category
in
ledger
]
for
ledger_value
in
ledger_value_list
:
extra_kw
.
setdefault
(
'ledger_uid'
,
[]).
append
(
ledger_value
.
getUid
())
for
brain
in
portal
.
portal_simulation
.
getMovementHistoryList
(
for
brain
in
portal
.
portal_simulation
.
getMovementHistoryList
(
at_date
=
at_date
,
at_date
=
at_date
,
simulation_state
=
simulation_state
,
simulation_state
=
simulation_state
,
...
@@ -47,7 +60,8 @@ for brain in portal.portal_simulation.getMovementHistoryList(
...
@@ -47,7 +60,8 @@ for brain in portal.portal_simulation.getMovementHistoryList(
grouping_query
=
grouping_query
,
grouping_query
=
grouping_query
,
sort_on
=
((
'stock.mirror_section_uid'
,
'ASC'
),
sort_on
=
((
'stock.mirror_section_uid'
,
'ASC'
),
(
'stock.date'
,
'ASC'
),
(
'stock.date'
,
'ASC'
),
(
'stock.uid'
,
'ASC'
))):
(
'stock.uid'
,
'ASC'
)),
**
extra_kw
):
movement
=
brain
.
getObject
()
movement
=
brain
.
getObject
()
transaction
=
movement
.
getParentValue
()
transaction
=
movement
.
getParentValue
()
...
...
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_viewAgedBalanceReport.xml
View file @
5130c514
...
@@ -97,6 +97,7 @@
...
@@ -97,6 +97,7 @@
<string>
your_at_date
</string>
<string>
your_at_date
</string>
<string>
your_currency
</string>
<string>
your_currency
</string>
<string>
your_account_type
</string>
<string>
your_account_type
</string>
<string>
your_ledger
</string>
<string>
your_simulation_state
</string>
<string>
your_simulation_state
</string>
<string>
your_report_date
</string>
<string>
your_report_date
</string>
</list>
</list>
...
...
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_viewAgedBalanceReport/your_ledger.xml
0 → 100644
View file @
5130c514
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
your_ledger
</string>
</value>
</item>
<item>
<key>
<string>
message_values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
external_validator_failed
</string>
</key>
<value>
<string>
The input failed the external validator.
</string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
overrides
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string>
your_ledger
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
AccountModule_viewReportFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string>
Click to edit the target
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_viewAgedBalanceReportDialog.xml
View file @
5130c514
...
@@ -111,6 +111,7 @@
...
@@ -111,6 +111,7 @@
<list>
<list>
<string>
your_period_list
</string>
<string>
your_period_list
</string>
<string>
your_simulation_state
</string>
<string>
your_simulation_state
</string>
<string>
your_ledger
</string>
</list>
</list>
</value>
</value>
</item>
</item>
...
...
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransactionModule_viewAgedBalanceReportDialog/your_ledger.xml
0 → 100644
View file @
5130c514
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
your_ledger
</string>
</value>
</item>
<item>
<key>
<string>
message_values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
external_validator_failed
</string>
</key>
<value>
<string>
The input failed the external validator.
</string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
overrides
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string>
your_ledger
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
AccountModule_viewDialogFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string>
Click to edit the target
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/tests/testAccountingReports.py
View file @
5130c514
...
@@ -4515,7 +4515,7 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
...
@@ -4515,7 +4515,7 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
credit_price
=
0
,
credit_price
=
0
,
debit_price
=
300
,)
debit_price
=
300
,)
def
createAgedBalanceDataSet
(
self
):
def
createAgedBalanceDataSet
(
self
,
use_ledger
=
False
):
"""Create data set for aged balance:
"""Create data set for aged balance:
2013/07/30: Purchase invoice 1 (500)
2013/07/30: Purchase invoice 1 (500)
2013/07/30: Sale invoice 2 (300)
2013/07/30: Sale invoice 2 (300)
...
@@ -4533,6 +4533,7 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
...
@@ -4533,6 +4533,7 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
source_reference
=
'no'
,
source_reference
=
'no'
,
reference
=
'ref1'
,
reference
=
'ref1'
,
simulation_state
=
'delivered'
,
simulation_state
=
'delivered'
,
ledger
=
(
''
if
not
use_ledger
else
'accounting/general'
),
source_section_value
=
self
.
organisation_module
.
supplier
,
source_section_value
=
self
.
organisation_module
.
supplier
,
start_date
=
DateTime
(
2013
,
7
,
30
),
start_date
=
DateTime
(
2013
,
7
,
30
),
lines
=
(
dict
(
destination_value
=
account_module
.
goods_purchase
,
lines
=
(
dict
(
destination_value
=
account_module
.
goods_purchase
,
...
@@ -4546,6 +4547,7 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
...
@@ -4546,6 +4547,7 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
destination_reference
=
'no'
,
destination_reference
=
'no'
,
reference
=
'ref2'
,
reference
=
'ref2'
,
simulation_state
=
'delivered'
,
simulation_state
=
'delivered'
,
ledger
=
(
''
if
not
use_ledger
else
'accounting/general'
),
destination_section_value
=
self
.
organisation_module
.
client_1
,
destination_section_value
=
self
.
organisation_module
.
client_1
,
start_date
=
DateTime
(
2013
,
7
,
30
),
start_date
=
DateTime
(
2013
,
7
,
30
),
lines
=
(
dict
(
source_value
=
account_module
.
goods_sales
,
lines
=
(
dict
(
source_value
=
account_module
.
goods_sales
,
...
@@ -4559,6 +4561,7 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
...
@@ -4559,6 +4561,7 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
source_reference
=
'3'
,
source_reference
=
'3'
,
destination_reference
=
'no'
,
destination_reference
=
'no'
,
simulation_state
=
'delivered'
,
simulation_state
=
'delivered'
,
ledger
=
(
''
if
not
use_ledger
else
'accounting/general'
),
causality_value
=
purchase1
,
causality_value
=
purchase1
,
payment_mode
=
'payment_mode'
,
payment_mode
=
'payment_mode'
,
destination_section_value
=
self
.
organisation_module
.
supplier
,
destination_section_value
=
self
.
organisation_module
.
supplier
,
...
@@ -4576,6 +4579,7 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
...
@@ -4576,6 +4579,7 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
simulation_state
=
'delivered'
,
simulation_state
=
'delivered'
,
causality_value
=
sale2
,
causality_value
=
sale2
,
payment_mode
=
'payment_mode'
,
payment_mode
=
'payment_mode'
,
ledger
=
(
''
if
not
use_ledger
else
'accounting/general'
),
destination_section_value
=
self
.
organisation_module
.
client_1
,
destination_section_value
=
self
.
organisation_module
.
client_1
,
start_date
=
DateTime
(
2013
,
8
,
8
),
start_date
=
DateTime
(
2013
,
8
,
8
),
lines
=
(
dict
(
source_value
=
account_module
.
bank
,
lines
=
(
dict
(
source_value
=
account_module
.
bank
,
...
@@ -4584,8 +4588,77 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
...
@@ -4584,8 +4588,77 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
source_credit
=
300.0
)))
source_credit
=
300.0
)))
self
.
tic
()
self
.
tic
()
transaction_list
=
[
purchase1
,
sale2
,
payment3
,
payment4
]
if
use_ledger
:
self
.
createLedgerCategory
()
purchase5
=
self
.
_makeOne
(
portal_type
=
'Purchase Invoice Transaction'
,
title
=
'Purchase invoice 3'
,
destination_reference
=
'5'
,
source_reference
=
'no'
,
reference
=
'ref5'
,
simulation_state
=
'delivered'
,
ledger
=
'accounting/detailed'
,
source_section_value
=
self
.
organisation_module
.
supplier
,
start_date
=
DateTime
(
2013
,
7
,
30
),
lines
=
(
dict
(
destination_value
=
account_module
.
goods_purchase
,
destination_debit
=
700.0
),
dict
(
destination_value
=
account_module
.
payable
,
destination_credit
=
700.0
)))
sale6
=
self
.
_makeOne
(
portal_type
=
'Sale Invoice Transaction'
,
title
=
'Sale invoice 4'
,
source_reference
=
'5'
,
destination_reference
=
'no'
,
reference
=
'ref6'
,
simulation_state
=
'delivered'
,
ledger
=
'accounting/detailed'
,
destination_section_value
=
self
.
organisation_module
.
client_1
,
start_date
=
DateTime
(
2013
,
7
,
30
),
lines
=
(
dict
(
source_value
=
account_module
.
goods_sales
,
source_credit
=
900.0
),
dict
(
source_value
=
account_module
.
receivable
,
source_debit
=
900.0
),))
self
.
tic
()
payment7
=
self
.
_makeOne
(
portal_type
=
'Payment Transaction'
,
title
=
'Payment 3'
,
source_reference
=
'6'
,
destination_reference
=
'no'
,
simulation_state
=
'delivered'
,
ledger
=
'accounting/detailed'
,
causality_value
=
purchase5
,
payment_mode
=
'payment_mode'
,
destination_section_value
=
self
.
organisation_module
.
supplier
,
start_date
=
DateTime
(
2013
,
9
,
9
),
lines
=
(
dict
(
source_value
=
account_module
.
payable
,
source_debit
=
700.0
),
dict
(
source_value
=
account_module
.
bank
,
source_credit
=
700.0
)))
payment8
=
self
.
_makeOne
(
portal_type
=
'Payment Transaction'
,
title
=
'Payment 4'
,
source_reference
=
'7'
,
destination_reference
=
'7'
,
simulation_state
=
'delivered'
,
causality_value
=
sale6
,
payment_mode
=
'payment_mode'
,
ledger
=
'accounting/detailed'
,
destination_section_value
=
self
.
organisation_module
.
client_1
,
start_date
=
DateTime
(
2013
,
8
,
8
),
lines
=
(
dict
(
source_value
=
account_module
.
bank
,
source_debit
=
900.0
),
dict
(
source_value
=
account_module
.
receivable
,
source_credit
=
900.0
)))
self
.
tic
()
transaction_list
.
extend
([
purchase5
,
sale6
,
payment7
,
payment8
])
# we should have all receivable and payable lines grouped.
# we should have all receivable and payable lines grouped.
for
at
in
(
purchase1
,
sale2
,
payment3
,
payment4
)
:
for
at
in
transaction_list
:
for
line
in
at
.
getMovementList
():
for
line
in
at
.
getMovementList
():
if
line
.
getSourceValue
()
in
(
account_module
.
receivable
,
if
line
.
getSourceValue
()
in
(
account_module
.
receivable
,
account_module
.
payable
)
or
\
account_module
.
payable
)
or
\
...
@@ -4700,6 +4773,63 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
...
@@ -4700,6 +4773,63 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
total_price
=
500
,
total_price
=
500
,
period_1
=
500
)
period_1
=
500
)
def
test_simple_aged_creditor_with_ledger_report_summary
(
self
):
# Same test as above, with a filter on ledger
# If ledger works properly, results should be the same as
# test_simple_aged_creditor_report_summary
self
.
createAgedBalanceDataSet
(
use_ledger
=
True
)
request_form
=
self
.
portal
.
REQUEST
.
form
request_form
[
'at_date'
]
=
DateTime
(
2013
,
8
,
1
)
request_form
[
'section_category'
]
=
'group/demo_group'
request_form
[
'section_category_strict'
]
=
False
request_form
[
'detailed'
]
=
False
request_form
[
'account_type'
]
=
'account_type/asset/receivable'
request_form
[
'period_list'
]
=
(
1
,
2
,
3
)
request_form
[
'simulation_state'
]
=
[
'delivered'
]
request_form
[
'ledger'
]
=
'ledger/accounting/general'
report_section_list
=
self
.
getReportSectionList
(
self
.
portal
.
accounting_module
,
'AccountingTransactionModule_viewAgedBalanceReport'
)
self
.
assertEqual
(
1
,
len
(
report_section_list
))
line_list
=
self
.
getListBoxLineList
(
report_section_list
[
0
])
data_line_list
=
[
l
for
l
in
line_list
if
l
.
isDataLine
()]
self
.
assertEqual
(
1
,
len
(
data_line_list
))
self
.
checkLineProperties
(
data_line_list
[
0
],
mirror_section_title
=
'Client 1'
,
total_price
=
300
,
period_1
=
300
)
def
test_simple_aged_debtor_with_ledger_report_summary
(
self
):
# Same test as above, with a filter on ledger
# If ledger works properly, results should be the same as
# test_simple_aged_creditor_report_summary
self
.
createAgedBalanceDataSet
(
use_ledger
=
True
)
request_form
=
self
.
portal
.
REQUEST
.
form
request_form
[
'at_date'
]
=
DateTime
(
2013
,
8
,
1
)
request_form
[
'section_category_strict'
]
=
False
request_form
[
'detailed'
]
=
False
request_form
[
'section_category'
]
=
'group/demo_group'
request_form
[
'account_type'
]
=
'account_type/liability/payable'
request_form
[
'period_list'
]
=
(
1
,
2
,
3
)
request_form
[
'simulation_state'
]
=
[
'delivered'
]
request_form
[
'ledger'
]
=
'ledger/accounting/general'
report_section_list
=
self
.
getReportSectionList
(
self
.
portal
.
accounting_module
,
'AccountingTransactionModule_viewAgedBalanceReport'
)
self
.
assertEqual
(
1
,
len
(
report_section_list
))
line_list
=
self
.
getListBoxLineList
(
report_section_list
[
0
])
data_line_list
=
[
l
for
l
in
line_list
if
l
.
isDataLine
()]
self
.
assertEqual
(
1
,
len
(
data_line_list
))
self
.
checkLineProperties
(
data_line_list
[
0
],
mirror_section_title
=
'Supplier'
,
total_price
=
500
,
period_1
=
500
)
class
TestAccountingReportsWithAnalytic
(
AccountingTestCase
,
ERP5ReportTestCase
):
class
TestAccountingReportsWithAnalytic
(
AccountingTestCase
,
ERP5ReportTestCase
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment