1 #############################################################################
3 # Copyright (c) 2006-2010 Nexedi SA and Contributors. All Rights Reserved.
4 # Aurelien Calonne <aurel@nexedi.com>
6 # WARNING: This program as such is intended to be used by professional
7 # programmers who take the whole responsability of assessing all potential
8 # consequences resulting from its eventual inadequacies and bugs
9 # End users who are looking for a ready-to-use solution with commercial
10 # garantees and support are strongly adviced to contract a Free Software
13 # This program is Free Software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; either version 2
16 # of the License, or (at your option) any later version.
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 ##############################################################################
29 from DateTime
import DateTime
30 from Products
.ERP5Type
.tests
.ERP5TypeTestCase
import ERP5TypeTestCase
39 return len(a
) == len(b
)
41 class TestERP5BankingMixin(ERP5TypeTestCase
):
43 Mixin class for unit test of banking operations
46 def getBusinessTemplateList(self
):
48 Return the list of business templates we need to run the test.
49 This method is called during the initialization of the unit test by
50 the unit test framework in order to know which business templates
51 need to be installed to run the test on.
53 return ('erp5_core_proxy_field_legacy',
59 'erp5_banking_inventory',
64 def enableLightInstall(self
):
66 Return if we should do a light install (1) or not (0)
67 Light install variable is used at installation of categories in business template
68 to know if we wrap the category or not, if 1 we don't use and installation is faster
70 return 1 # here we want a light install for a faster installation
72 def enableActivityTool(self
):
74 Return if we should create (1) or not (0) an activity tool
75 This variable is used at the creation of the site to know if we use
76 the activity tool or not
78 return 1 # here we want to use the activity tool
80 def checkUserFolderType(self
):
82 Check the type of user folder to let the test working with both NuxUserGroup and PAS.
84 self
.user_folder
= self
.getUserFolder()
85 self
.PAS_installed
= 0
86 if self
.user_folder
.meta_type
== 'Pluggable Auth Service':
88 self
.PAS_installed
= 1
90 def updateRoleMappings(self
, portal_type_list
=None):
91 """Update the local roles in existing objects.
93 portal_catalog
= self
.portal
.portal_catalog
94 for portal_type
in portal_type_list
:
95 for brain
in portal_catalog(portal_type
= portal_type
):
96 obj
= brain
.getObject()
97 userdb_path
, user_id
= obj
.getOwnerTuple()
98 obj
.assignRoleToSecurityGroup(user_name
= user_id
)
100 def assignPASRolesToUser(self
, user_name
, role_list
):
102 Assign a list of roles to one user with PAS.
104 for role
in role_list
:
105 if role
not in self
.user_folder
.zodb_roles
.listRoleIds():
106 self
.user_folder
.zodb_roles
.addRole(role
)
107 self
.user_folder
.zodb_roles
.assignRoleToPrincipal(role
, user_name
)
109 def createManagerAndLogin(self
):
111 Create a simple user in user_folder with manager rights.
112 This user will be used to initialize data in the method afterSetup
114 self
.getUserFolder()._doAddUser('manager', '', ['Manager'], [])
115 self
.login('manager')
117 def createERP5Users(self
, user_dict
):
119 Create all ERP5 users needed for the test.
120 ERP5 user = Person object + Assignment object in erp5 person_module.
122 for user_login
, user_data
in user_dict
.items():
123 user_roles
= user_data
[0]
125 main_site
= '/'.join(user_data
[4].split('/')[0:2])
126 person
= self
.person_module
.newContent(id=user_login
,
127 portal_type
='Person', reference
=user_login
, career_role
="internal",
129 # Create the Assignment.
130 assignment
= person
.newContent( portal_type
= 'Assignment'
131 , destination_value
= user_data
[1]
132 , function
= "function/%s" %user_data
[2]
133 , group
= "group/%s" %user_data
[3]
134 , site
= "%s" %user_data
[4]
135 , start_date
= '01/01/1900'
136 , stop_date
= '01/01/2900'
138 if self
.PAS_installed
and len(user_roles
) > 0:
139 # In the case of PAS, if we want global roles on user, we have to do it manually.
140 self
.assignPASRolesToUser(user_login
, user_roles
)
141 elif not self
.PAS_installed
:
142 # The user_folder counterpart of the erp5 user must be
143 # created manually in the case of NuxUserGroup.
144 self
.user_folder
.userFolderAddUser( name
= user_login
149 # User assignment to security groups is also required, but is taken care of
150 # by the assignment workflow when NuxUserGroup is used and
151 # by ERP5Security PAS plugins in the context of PAS use.
154 if self
.PAS_installed
:
155 # reindexing is required for the security to work
160 def getUserFolder(self
):
161 return self
.getPortal().acl_users
163 def getPersonModule(self
):
164 return self
.getPortal().person_module
166 def getOrganisationModule(self
):
167 return self
.getPortal().organisation_module
169 def getCurrencyCashModule(self
):
170 return self
.getPortal().currency_cash_module
172 def getCashInventoryModule(self
):
173 return self
.getPortal().cash_inventory_module
175 def getBankAccountInventoryModule(self
):
176 return self
.getPortal().bank_account_inventory_module
178 def getCurrencyModule(self
):
179 return self
.getPortal().currency_module
181 def getCategoryTool(self
):
182 return self
.getPortal().portal_categories
184 def getWorkflowTool(self
):
185 return self
.getPortal().portal_workflow
187 def getSimulationTool(self
):
188 return self
.getPortal().portal_simulation
190 def getCheckPaymentModule(self
):
191 return self
.getPortal().check_payment_module
193 def getStopPaymentModule(self
):
194 return self
.getPortal().stop_payment_module
196 def getCheckDepositModule(self
):
197 return self
.getPortal().check_deposit_module
199 def getCheckbookModule(self
):
200 return self
.getPortal().checkbook_module
202 def getCheckbookModelModule(self
):
203 return self
.getPortal().checkbook_model_module
205 def getCheckbookReceptionModule(self
):
206 return self
.getPortal().checkbook_reception_module
208 def getCheckbookVaultTransferModule(self
):
209 return self
.getPortal().checkbook_vault_transfer_module
211 def getCheckbookUsualCashTransferModule(self
):
212 return self
.getPortal().checkbook_usual_cash_transfer_module
214 def getCheckbookDeliveryModule(self
):
215 return self
.getPortal().checkbook_delivery_module
217 def getCheckModule(self
):
218 return self
.getPortal().check_module
220 def getAccountingDateModule(self
):
221 return self
.getPortal().accounting_date_module
223 def getCounterDateModule(self
):
224 return self
.getPortal().counter_date_module
226 def getCounterModule(self
):
227 return self
.getPortal().counter_module
229 def getCashMovementModule(self
):
230 return self
.getPortal().cash_movement_module
232 def getCashMovementNewNotEmittedModule(self
):
233 return self
.getPortal().cash_movement_new_not_emitted_module
235 def getMonetaryReceptionModule(self
):
236 return self
.getPortal().monetary_reception_module
238 def getMonetaryIssueModule(self
):
239 return self
.getPortal().monetary_issue_module
241 def getAccountingCancellationModule(self
):
242 return self
.getPortal().accounting_cancellation_module
244 def getCashBalanceRegulationModule(self
):
245 return self
.getPortal().cash_balance_regulation_module
247 def getCashSortingModule(self
):
248 return self
.getPortal().cash_sorting_module
250 def getCashExchangeModule(self
):
251 return self
.getPortal().cash_exchange_module
253 def getCashToCurrencyPurchaseModule(self
):
254 return self
.getPortal().cash_to_currency_purchase_module
256 def getClassificationSurveyModule(self
):
257 return self
.getPortal().classification_survey_module
259 def getCounterRenderingModule(self
):
260 return self
.getPortal().counter_rendering_module
262 def getDestructionSurveyModule(self
):
263 return self
.getPortal().destruction_survey_module
265 def getForeignCashReceptionModule(self
):
266 return self
.getPortal().foreign_cash_reception_module
268 def getInternalMoneyDepositModule(self
):
269 return self
.getPortal().internal_money_deposit_module
271 def getInternalMoneyPaymentModule(self
):
272 return self
.getPortal().internal_money_payment_module
274 def getMonetaryDestructionModule(self
):
275 return self
.getPortal().monetary_destruction_module
277 def getMonetaryRecallModule(self
):
278 return self
.getPortal().monetary_recall_module
280 def getMonetarySurveyModule(self
):
281 return self
.getPortal().monetary_survey_module
283 def getMoneyDepositModule(self
):
284 return self
.getPortal().money_deposit_module
286 def getMoneyDepositRenderingModule(self
):
287 return self
.getPortal().money_deposit_rendering_module
289 def getMutilatedBanknoteModule(self
):
290 return self
.getPortal().mutilated_banknote_module
292 def getTravelerCheckPurchaseModule(self
):
293 return self
.getPortal().traveler_check_purchase_module
295 def getTravelerCheckSaleModule(self
):
296 return self
.getPortal().traveler_check_sale_module
298 def getUsualCashRenderingModule(self
):
299 return self
.getPortal().usual_cash_rendering_module
301 def getUsualCashTransferModule(self
):
302 return self
.getPortal().usual_cash_transfer_module
304 def getVaultTransferModule(self
):
305 return self
.getPortal().vault_transfer_module
307 def createCurrency(self
, currency_list
=(('EUR', 'Euro', 1/652., 1/650., 'USD'), ('USD', 'USD', 652, 650., 'EUR')), only_currency
=False):
308 # create the currency document for euro inside the currency module
309 #currency_list = (('EUR', 'Euro', 1/650., 'USD'), ('USD', 'Dollar', 650., 'EUR'))
310 # first create currency
311 for currency_id
, title
, base_price
, cell_price
, price_currency
in currency_list
:
312 self
._maybeNewContent(self
.getCurrencyModule(), id=currency_id
,
313 title
=title
, reference
=currency_id
)
318 # second, create exchange lines
319 for currency_id
, title
, base_price
, cell_price
, price_currency
in currency_list
:
320 currency
= self
.getCurrencyModule()[currency_id
]
322 exchange_line
= currency
.newContent(portal_type
='Currency Exchange Line',
323 start_date
='01/01/1900', stop_date
='01/01/2900',
324 base_price
=base_price
,
325 currency_exchange_type_list
=['currency_exchange_type/sale',
326 'currency_exchange_type/purchase',
327 'currency_exchange_type/transfer'],
329 exchange_line
.setPriceCurrencyValue(self
.getCurrencyModule()[price_currency
])
330 cell_list
= exchange_line
.objectValues()
331 self
.assertEqual(len(cell_list
), 3)
332 for cell
in cell_list
:
333 cell
.setBasePrice(cell_price
)
335 exchange_line
.confirm()
336 exchange_line
.validate()
340 def _createBanknotesAndCoins(self
):
342 Create some banknotes and coins
344 # Define static values (only use prime numbers to prevent confusions like 2 * 6 == 3 * 4)
345 # variation list is the list of years for banknotes and coins
346 self
.variation_list
= ('variation/1992', 'variation/2003')
347 self
.usd_variation_list
= ('variation/not_defined', )
348 # quantity of banknotes of 10000 :
349 self
.quantity_10000
= {}
350 # 2 banknotes of 10000 for the year 1992
351 self
.quantity_10000
[self
.variation_list
[0]] = 2
352 # 3 banknotes of 10000 for the year of 2003
353 self
.quantity_10000
[self
.variation_list
[1]] = 3
355 # quantity of coin of 200
356 self
.quantity_200
= {}
357 # 5 coins of 200 for the year 1992
358 self
.quantity_200
[self
.variation_list
[0]] = 5
359 # 7 coins of 200 for the year 2003
360 self
.quantity_200
[self
.variation_list
[1]] = 7
362 # quantity of coin of 100
363 self
.quantity_100
= {}
364 # 5 coins of 100 for the year 1992
365 self
.quantity_100
[self
.variation_list
[0]] = 4
366 # 7 coins of 100 for the year 2003
367 self
.quantity_100
[self
.variation_list
[1]] = 6
369 # quantity of banknotes of 5000
370 self
.quantity_5000
= {}
371 # 11 banknotes of 5000 for hte year 1992
372 self
.quantity_5000
[self
.variation_list
[0]] = 11
373 # 13 banknotes of 5000 for the year 2003
374 self
.quantity_5000
[self
.variation_list
[1]] = 13
376 # quantity of usd banknote of 200
377 self
.quantity_usd_200
= {}
379 self
.quantity_usd_200
['variation/not_defined'] = 2
380 # quantity of usd banknote of 100
381 self
.quantity_usd_100
= {}
383 self
.quantity_usd_100
['variation/not_defined'] = 2
384 # quantity of usd banknote of 50
385 self
.quantity_usd_50
= {}
387 self
.quantity_usd_50
['variation/not_defined'] = 3
388 # quantity of usd banknote of 20
389 self
.quantity_usd_20
= {}
391 self
.quantity_usd_20
['variation/not_defined'] = 5
393 # Now create required category for banknotes and coin
394 self
.cash_status_base_category
= getattr(self
.category_tool
, 'cash_status')
395 # add the category valid in cash_status which define status of banknotes and coin
396 self
.cash_status_valid
= self
._maybeNewContent(self
.cash_status_base_category
, id='valid', portal_type
='Category')
397 self
.cash_status_to_sort
= self
._maybeNewContent(self
.cash_status_base_category
, id='to_sort', portal_type
='Category')
398 self
.cash_status_cancelled
= self
._maybeNewContent(self
.cash_status_base_category
, id='cancelled', portal_type
='Category')
399 self
.cash_status_not_defined
= self
._maybeNewContent(self
.cash_status_base_category
, id='not_defined', portal_type
='Category')
400 self
.cash_status_mutilated
= self
._maybeNewContent(self
.cash_status_base_category
, id='mutilated', portal_type
='Category')
401 self
.cash_status_retired
= self
._maybeNewContent(self
.cash_status_base_category
, id='retired', portal_type
='Category')
402 self
.cash_status_new_not_emitted
= self
._maybeNewContent(self
.cash_status_base_category
, id='new_not_emitted', portal_type
='Category')
403 self
.cash_status_mixed
= self
._maybeNewContent(self
.cash_status_base_category
, id='mixed', portal_type
='Category')
405 self
.emission_letter_base_category
= getattr(self
.category_tool
, 'emission_letter')
406 # add the category k in emission letter that will be used fo banknotes and coins
407 self
.emission_letter_p
= self
._maybeNewContent(self
.emission_letter_base_category
, id='p', portal_type
='Category')
408 self
.emission_letter_s
= self
._maybeNewContent(self
.emission_letter_base_category
, id='s', portal_type
='Category')
409 self
.emission_letter_b
= self
._maybeNewContent(self
.emission_letter_base_category
, id='b', portal_type
='Category')
410 self
.emission_letter_k
= self
._maybeNewContent(self
.emission_letter_base_category
, id='k', portal_type
='Category')
411 self
.emission_letter_mixed
= self
._maybeNewContent(self
.emission_letter_base_category
, id='mixed', portal_type
='Category')
412 self
.emission_letter_not_defined
= self
._maybeNewContent(self
.emission_letter_base_category
, id='not_defined', portal_type
='Category')
414 self
.variation_base_category
= getattr(self
.category_tool
, 'variation')
415 # add the category 1992 in variation
416 self
.variation_1992
= self
._maybeNewContent(self
.variation_base_category
, id='1992', portal_type
='Category')
417 # add the category 2003 in variation
418 self
.variation_2003
= self
._maybeNewContent(self
.variation_base_category
, id='2003', portal_type
='Category')
419 # add the category not_defined in variation
420 self
.variation_not_defined
= self
._maybeNewContent(self
.variation_base_category
, id='not_defined',
421 portal_type
='Category')
423 # Now create required category for region and coin
424 self
.region_base_category
= getattr(self
.category_tool
, 'region')
425 # add the category valid in cash_status which define status of banknotes and coin
426 self
.region_france
= self
._maybeNewContent(self
.region_base_category
, id='france', title
="France", portal_type
='Category')
427 self
.region_spain
= self
._maybeNewContent(self
.region_base_category
, id='spain', title
="Spain", portal_type
='Category')
429 # Create Resources Document (Banknotes & Coins)
430 # get the currency cash module
431 self
.currency_cash_module
= self
.getCurrencyCashModule()
432 # Create Resources Document (Banknotes & Coins)
433 self
.createCurrency()
434 self
.currency_1
= self
.currency_module
['EUR']
435 # create document for banknote of 10000 euros from years 1992 and 2003
436 self
.billet_10000
= self
.currency_cash_module
.newContent(id='billet_10000',
437 portal_type
='Banknote', base_price
=10000,
438 price_currency_value
=self
.currency_1
, variation_list
=('1992', '2003'),
439 quantity_unit_value
=self
.unit
)
440 # create document for banknote of 500 euros from years 1992 and 2003
441 self
.billet_5000
= self
.currency_cash_module
.newContent(id='billet_5000',
442 portal_type
='Banknote', base_price
=5000,
443 price_currency_value
=self
.currency_1
, variation_list
=('1992', '2003'),
444 quantity_unit_value
=self
.unit
)
445 # create document for coin of 200 euros from years 1992 and 2003
446 self
.piece_200
= self
.currency_cash_module
.newContent(id='piece_200',
447 portal_type
='Coin', base_price
=200,
448 price_currency_value
=self
.currency_1
, variation_list
=('1992', '2003'),
449 quantity_unit_value
=self
.unit
)
450 # create document for coin of 200 euros from years 1992 and 2003
451 self
.piece_100
= self
.currency_cash_module
.newContent(id='piece_100',
452 portal_type
='Coin', base_price
=100,
453 price_currency_value
=self
.currency_1
, variation_list
=('1992', '2003'),
454 quantity_unit_value
=self
.unit
)
455 # create document for banknote of 200 euros from years 1992 and 2003
456 self
.billet_200
= self
.currency_cash_module
.newContent(id='billet_200',
457 portal_type
='Banknote', base_price
=200,
458 price_currency_value
=self
.currency_1
, variation_list
=('1992', '2003'),
459 quantity_unit_value
=self
.unit
)
460 # create document for banknote of 200 euros from years 1992 and 2003
461 self
.billet_100
= self
.currency_cash_module
.newContent(id='billet_100',
462 portal_type
='Banknote', base_price
=100,
463 price_currency_value
=self
.currency_1
, variation_list
=('1992', '2003'),
464 quantity_unit_value
=self
.unit
)
465 # Create Resources Document (Banknotes & Coins) in USD
466 self
.currency_2
= self
.currency_module
['USD']
467 # create document for banknote of 100 USD
468 self
.usd_billet_100
= self
.currency_cash_module
.newContent(id='usd_billet_100',
469 portal_type
='Banknote', base_price
=100,
470 price_currency_value
=self
.currency_2
, variation_list
=('not_defined', ),
471 quantity_unit_value
=self
.unit
)
472 # create document for banknote of 200 USD
473 self
.usd_billet_200
= self
.currency_cash_module
.newContent(id='usd_billet_200',
474 portal_type
='Banknote', base_price
=200,
475 price_currency_value
=self
.currency_2
, variation_list
=('not_defined', ),
476 quantity_unit_value
=self
.unit
)
477 # create document for banknote of 50 USD
478 self
.usd_billet_50
= self
.currency_cash_module
.newContent(id='usd_billet_50',
479 portal_type
='Banknote', base_price
=50,
480 price_currency_value
=self
.currency_2
, variation_list
=('not_defined', ),
481 quantity_unit_value
=self
.unit
)
482 # create document for banknote of 20 USD
483 self
.usd_billet_20
= self
.currency_cash_module
.newContent(id='usd_billet_20',
484 portal_type
='Banknote', base_price
=20,
485 price_currency_value
=self
.currency_2
, variation_list
=('not_defined', ),
486 quantity_unit_value
=self
.unit
)
488 def _maybeNewContent(self
, container
, id, **kw
):
490 result
= container
[id]
492 result
= container
.newContent(id=id, **kw
)
495 def createFunctionGroupSiteCategory(self
, no_site
=0, site_list
=None):
497 Create site group function category that can be used for security
499 if site_list
is None:
500 site_list
= ["paris", 'madrid', 'siege']
502 # add category unit in quantity_unit which is the unit that will be used for banknotes and coins
503 self
.variation_base_category
= getattr(self
.category_tool
, 'quantity_unit')
504 self
.unit
= self
._maybeNewContent(self
.variation_base_category
, id='unit', title
='Unit')
506 self
._maybeNewContent(self
.category_tool
.role
, id='internal', portal_type
='Category')
508 # add category for currency_exchange_type
509 self
.currency_exchange_type
= getattr(self
.category_tool
, 'currency_exchange_type')
510 self
._maybeNewContent(self
.currency_exchange_type
, id='sale')
511 self
._maybeNewContent(self
.currency_exchange_type
, id='purchase')
512 self
._maybeNewContent(self
.currency_exchange_type
, id='transfer')
514 # get the base category function
515 self
.function_base_category
= getattr(self
.category_tool
, 'function')
516 # add category banking in function which will hold all functions neccessary in a bank (at least for this unit test)
517 self
.banking
= self
._maybeNewContent(self
.function_base_category
, id='banking', portal_type
='Category', codification
='BNK')
518 self
.caissier_principal
= self
._maybeNewContent(self
.banking
, id='caissier_principal', portal_type
='Category', codification
='CCP')
519 self
.controleur_caisse
= self
._maybeNewContent(self
.banking
, id='controleur_caisse', portal_type
='Category', codification
='CCT')
520 self
.void_function
= self
._maybeNewContent(self
.banking
, id='void_function', portal_type
='Category', codification
='VOID')
521 self
.gestionnaire_caisse_courante
= self
._maybeNewContent(self
.banking
, id='gestionnaire_caisse_courante', portal_type
='Category', codification
='CCO')
522 self
.gestionnaire_caveau
= self
._maybeNewContent(self
.banking
, id='gestionnaire_caveau', portal_type
='Category', codification
='CCV')
523 self
.caissier_particulier
= self
._maybeNewContent(self
.banking
, id='caissier_particulier', portal_type
='Category', codification
='CGU')
524 self
.controleur_caisse_courante
= self
._maybeNewContent(self
.banking
, id='controleur_caisse_courante', portal_type
='Category', codification
='CCC')
525 self
.controleur_caveau
= self
._maybeNewContent(self
.banking
, id='controleur_caveau', portal_type
='Category', codification
='CCA')
526 self
.comptable
= self
._maybeNewContent(self
.banking
, id='comptable', portal_type
='Category', codification
='FXF')
527 self
.commis_comptable
= self
._maybeNewContent(self
.banking
, id='commis_comptable', portal_type
='Category', codification
='CBM')
528 self
.commis_caisse
= self
._maybeNewContent(self
.banking
, id='commis_caisse', portal_type
='Category', codification
='CCM')
529 self
.chef_section_comptable
= self
._maybeNewContent(self
.banking
, id='chef_section_comptable', portal_type
='Category', codification
='CSB')
530 self
.chef_comptable
= self
._maybeNewContent(self
.banking
, id='chef_comptable', portal_type
='Category', codification
='CCB')
531 self
.chef_de_tri
= self
._maybeNewContent(self
.banking
, id='chef_de_tri', portal_type
='Category', codification
='CTR')
532 self
.chef_caisse
= self
._maybeNewContent(self
.banking
, id='chef_caisse', portal_type
='Category', codification
='CCP')
533 self
.chef_section
= self
._maybeNewContent(self
.banking
, id='chef_section', portal_type
='Category', codification
='FXS')
534 self
.chef_section_financier
= self
._maybeNewContent(self
.banking
, id='chef_section_financier', portal_type
='Category', codification
='FXA')
535 self
.financier_a
= self
._maybeNewContent(self
.banking
, id='financier_a', portal_type
='Category', codification
='FNA')
536 self
.financier_b
= self
._maybeNewContent(self
.banking
, id='financier_b', portal_type
='Category', codification
='FNB')
537 self
.chef_financier
= self
._maybeNewContent(self
.banking
, id='chef_financier', portal_type
='Category', codification
='FCF')
538 self
.admin_local
= self
._maybeNewContent(self
.banking
, id='administrateur_local', portal_type
='Category', codification
='ADL')
539 self
.agent_saisie_sref
= self
._maybeNewContent(self
.banking
, id='agent_saisie_sref', portal_type
='Category', codification
='SSREF')
540 self
.chef_sref
= self
._maybeNewContent(self
.banking
, id='chef_sref', portal_type
='Category', codification
='CSREF')
541 self
.analyste_sref
= self
._maybeNewContent(self
.banking
, id='analyste_sref', portal_type
='Category', codification
='ASREF')
542 self
.gestionnaire_devise_a
= self
._maybeNewContent(self
.banking
, id='gestionnaire_cours_devise_a', portal_type
='Category', codification
='GCA')
543 self
.gestionnaire_devise_b
= self
._maybeNewContent(self
.banking
, id='gestionnaire_cours_devise_b', portal_type
='Category', codification
='GCB')
544 self
.comptable_inter_site
= self
._maybeNewContent(self
.banking
, id='comptable_inter_site', portal_type
='Category', codification
='FXFIS')
546 # get the base category group
547 self
.group_base_category
= getattr(self
.category_tool
, 'group')
548 self
.baobab_group
= self
._maybeNewContent(self
.group_base_category
, id='baobab', portal_type
='Category', codification
='BAOBAB')
549 # get the base category site
550 self
.site_base_category
= getattr(self
.category_tool
, 'site')
551 # add the category testsite in the category site which hold vaults situated in the bank
552 self
.testsite
= self
._maybeNewContent(self
.site_base_category
, id='testsite', portal_type
='Category', codification
='TEST')
553 site_reference_from_codification_dict
= {
554 'P10': ('FR', '000', '11111', '000000000000', '25'),
555 'S10': ('SP', '000', '11111', '000000000000', '08'),
556 'HQ1': ('FR', '000', '11112', '000000000000', '69'),
558 site_region_from_codification_dict
= {
559 'P10': 'france', # paris
560 'S10': 'spain', # madrid
561 'HQ1': 'france', # main
563 self
.paris
= self
._maybeNewContent(self
.testsite
, id='paris', portal_type
='Category', codification
='P10', vault_type
='site')
564 self
.madrid
= self
._maybeNewContent(self
.testsite
, id='madrid', portal_type
='Category', codification
='S10', vault_type
='site')
565 self
.siege
= self
._maybeNewContent(self
.site_base_category
, id='siege', portal_type
='Category', codification
='HQ1', vault_type
='site')
566 created_site_list
= [self
.paris
, self
.madrid
, self
.siege
]
568 self
._createBanknotesAndCoins()
570 if len(site_list
) != 0:
571 for site
in site_list
:
572 if isinstance(site
, tuple):
573 container
= self
.site_base_category
575 for category_id
in site
[2].split('/'):
576 contained
= getattr(container
, category_id
, None)
577 if contained
is None:
578 contained
= self
._maybeNewContent(container
, id=category_id
, portal_type
='Category')
579 container
= contained
581 site_reference_from_codification_dict
[site
[1]] = site
[3]
583 site_region_from_codification_dict
[site
[1]] = site
[4]
584 codification
= site
[1]
586 if site
not in ("paris", 'madrid', 'siege'):
587 site
= self
._maybeNewContent(container
, id=site
, portal_type
='Category', codification
=codification
, vault_type
='site')
588 created_site_list
.append(site
)
590 # Create organisation + bank account for each site category.
591 organisation_module
= self
.organisation_module
592 newContent
= organisation_module
.newContent
593 for site
in created_site_list
:
594 codification
= site
.getCodification()
595 organisation_id
= 'site_%s' %
(codification
, )
597 organisation_module
[organisation_id
]
599 organisation
= newContent(
600 portal_type
='Organisation',
602 site
=site
.getRelativeUrl(),
603 region
=site_region_from_codification_dict
.get(codification
),
607 site_reference
= site_reference_from_codification_dict
.get(codification
)
608 if site_reference
is not None:
609 self
.createBankAccount(
611 account_id
='account_%s' %
(codification
, ),
612 currency
=self
.currency_1
,
614 bank_country_code
=site_reference
[0],
615 bank_code
=site_reference
[1],
616 branch
=site_reference
[2],
617 bank_account_number
=site_reference
[3],
618 bank_account_key
=site_reference
[4],
621 self
.vault_type_base_category
= getattr(self
.category_tool
, 'vault_type')
622 site_vault_type
= self
._maybeNewContent(self
.vault_type_base_category
, id='site')
623 surface_vault_type
= self
._maybeNewContent(site_vault_type
, 'surface')
624 bi_vault_type
= self
._maybeNewContent(surface_vault_type
, 'banque_interne')
625 co_vault_type
= self
._maybeNewContent(surface_vault_type
, 'caisse_courante')
626 de_co_vault_type
= self
._maybeNewContent(co_vault_type
, 'encaisse_des_devises')
627 guichet_bi_vault_type
= self
._maybeNewContent(bi_vault_type
, 'guichet')
628 gp_vault_type
= self
._maybeNewContent(surface_vault_type
, 'gros_paiement')
629 guichet_gp_vault_type
= self
._maybeNewContent(gp_vault_type
, 'guichet')
630 gv_vault_type
= self
._maybeNewContent(surface_vault_type
, 'gros_versement')
631 guichet_gv_vault_type
= self
._maybeNewContent(gv_vault_type
, 'guichet')
632 op_vault_type
= self
._maybeNewContent(surface_vault_type
, 'operations_diverses')
633 guichet_op_vault_type
= self
._maybeNewContent(op_vault_type
, 'guichet')
634 caveau_vault_type
= self
._maybeNewContent(site_vault_type
, 'caveau')
635 auxiliaire_vault_type
= self
._maybeNewContent(caveau_vault_type
, 'auxiliaire')
636 self
._maybeNewContent(auxiliaire_vault_type
, 'auxiliaire_vault_type')
637 self
._maybeNewContent(auxiliaire_vault_type
, 'encaisse_des_devises')
638 externe
= self
._maybeNewContent(auxiliaire_vault_type
, 'encaisse_des_externes')
639 self
._maybeNewContent(externe
, 'transit')
640 self
._maybeNewContent(caveau_vault_type
, 'reserve')
641 serre
= self
._maybeNewContent(caveau_vault_type
, 'serre')
642 self
._maybeNewContent(serre
, 'transit')
643 self
._maybeNewContent(serre
, 'retire')
644 salle_tri
= self
._maybeNewContent(surface_vault_type
, 'salle_tri')
647 destination_site_list
= [x
.getId() for x
in created_site_list
]
648 for c
in created_site_list
: #self.testsite.getCategoryChildValueList():
649 # create bank structure for each agency
652 surface
= self
._maybeNewContent(c
, id='surface', portal_type
='Category', codification
='', vault_type
='site/surface')
653 caisse_courante
= self
._maybeNewContent(surface
, id='caisse_courante', portal_type
='Category', codification
='', vault_type
='site/surface/caisse_courante')
654 self
._maybeNewContent(caisse_courante
, id='encaisse_des_billets_et_monnaies', portal_type
='Category', codification
='', vault_type
='site/surface/caisse_courante')
655 self
._maybeNewContent(caisse_courante
, id='billets_mutiles', portal_type
='Category', codification
='', vault_type
='site/surface/caisse_courante')
656 self
._maybeNewContent(caisse_courante
, id='billets_macules', portal_type
='Category', codification
='', vault_type
='site/surface/caisse_courante')
657 encaisse_des_devises
= self
._maybeNewContent(caisse_courante
, id='encaisse_des_devises', portal_type
='Category', codification
='', vault_type
='site/surface/caisse_courante/encaisse_des_devises')
658 # create counter for surface
659 for s
in ['banque_interne', 'gros_versement', 'gros_paiement']:
660 vault_codification
= c
.getCodification()
661 if s
== 'banque_interne':
662 vault_codification
+= 'BI'
663 elif s
== 'gros_versement':
664 vault_codification
+= 'GV'
665 elif s
== 'gros_paiement':
666 vault_codification
+= 'GP'
667 s
= self
._maybeNewContent(surface
, id='%s' %
(s
, ), portal_type
='Category', codification
=vault_codification
, vault_type
='site/surface/%s' %
(s
, ))
668 for ss
in ['guichet_1', 'guichet_2']:
669 final_vault_codification
= vault_codification
+ ss
[-1]
670 ss
= self
._maybeNewContent(s
, id='%s' %
(ss
, ), portal_type
='Category', codification
=final_vault_codification
, vault_type
='site/surface/%s/guichet' %
(s
.getId(), ))
671 for sss
in ['encaisse_des_billets_et_monnaies']:
672 sss
= self
._maybeNewContent(ss
, id='%s' %
(sss
, ), portal_type
='Category', codification
='', vault_type
='site/surface/%s/guichet' %
(s
.getId(), ))
673 for ssss
in ['entrante', 'sortante']:
674 self
._maybeNewContent(sss
, id='%s' %
(ssss
, ), portal_type
='Category', codification
='', vault_type
='site/surface/%s/guichet' %
(s
.getId(), ))
675 for sss
in ['encaisse_des_devises']:
676 sss
= self
._maybeNewContent(ss
, id='%s' %
(sss
, ), portal_type
='Category', codification
='', vault_type
='site/surface/%s/guichet' %
(s
.getId(), ))
677 for currency
in ['usd']:
678 currency_cat
= self
._maybeNewContent(sss
, id='%s' %
(currency
, ), portal_type
='Category', codification
='', vault_type
='site/surface/%s' %
(ss
.getId(), ))
679 for ssss
in ['entrante', 'sortante']:
680 self
._maybeNewContent(currency_cat
, id='%s' %
(ssss
, ), portal_type
='Category', codification
='', vault_type
='site/surface/%s/guichet' %
(s
.getId(), ))
682 salle_tri
= self
._maybeNewContent(surface
, id='salle_tri', portal_type
='Category', codification
='', vault_type
='site/surface/salle_tri')
683 for ss
in ['encaisse_des_billets_et_monnaies', 'encaisse_des_billets_recus_pour_ventilation', 'encaisse_des_differences', 'encaisse_des_externes']:
684 ss
= self
._maybeNewContent(salle_tri
, id='%s' %
(ss
, ), portal_type
='Category', codification
='', vault_type
='site/surface/salle_tri')
685 if 'ventilation' in ss
.getId():
686 for country
in destination_site_list
:
687 if country
[0] != c
.getCodification()[0]:
688 self
._maybeNewContent(ss
, id='%s' %
(country
, ), portal_type
='Category', codification
='', vault_type
='site/caveau/%s' %
(s
.getId(), ))
690 caveau
= self
._maybeNewContent(c
, id='caveau', portal_type
='Category', codification
='', vault_type
='site/caveau')
691 for s
in ['auxiliaire', 'reserve', 'serre']:
692 s
= self
._maybeNewContent(caveau
, id='%s' %
(s
, ), portal_type
='Category', codification
='', vault_type
='site/caveau/%s' %
(s
, ))
693 if s
.getId() == 'serre':
694 for ss
in ['encaisse_des_billets_neufs_non_emis', 'encaisse_des_billets_retires_de_la_circulation', 'encaisse_des_billets_detruits', 'encaisse_des_billets_neufs_non_emis_en_transit_allant_a']:
695 ss
= self
._maybeNewContent(s
, id='%s' %
(ss
, ), portal_type
='Category', codification
='', vault_type
='site/caveau/%s' %
(s
.getId(), ))
696 if 'transit' in ss
.getId():
697 for country
in destination_site_list
:
698 if country
[0] != c
.getCodification()[0]:
699 self
._maybeNewContent(ss
, id='%s' %
(country
, ), portal_type
='Category', codification
='', vault_type
='site/caveau/%s' %
(s
.getId(), ))
702 for ss
in ['encaisse_des_billets_et_monnaies', 'encaisse_des_externes',
703 'encaisse_des_billets_recus_pour_ventilation', 'encaisse_des_devises']:
704 ss
= self
._maybeNewContent(s
, id='%s' %
(ss
, ), portal_type
='Category', codification
='', vault_type
='site/caveau/%s' %
(s
.getId(), ))
705 if 'ventilation' in ss
.getId():
706 for country
in destination_site_list
:
707 if country
[0] != c
.getCodification()[0]:
708 self
._maybeNewContent(ss
, id='%s' %
(country
, ), portal_type
='Category', codification
='', vault_type
='site/caveau/%s' %
(s
.getId(), ))
709 if 'devises' in ss
.getId():
710 for currency
in ['eur', 'usd']:
711 self
._maybeNewContent(ss
, id='%s' %
(currency
, ), portal_type
='Category', codification
='', vault_type
='site/caveau/%s' %
(ss
.getId(), ))
712 if 'encaisse_des_externes' in ss
.getId():
713 self
._maybeNewContent(ss
, id='transit', portal_type
='Category', codification
='', vault_type
='site/caveau/%s' %
(s
.getId(), ))
714 #if ss.getId()=='encaisse_des_devises':
716 if s
.getId() == 'auxiliaire':
717 for ss
in ['encaisse_des_billets_a_ventiler_et_a_detruire', 'encaisse_des_billets_ventiles_et_detruits', 'billets_detenus_par_des_tiers', 'encaisse_des_billets_recus_pour_ventilation_venant_de']:
718 self
._maybeNewContent(s
, id='%s' %
(ss
, ), portal_type
='Category', codification
='', vault_type
='site/caveau/%s' %
(s
.getId(), ))
719 # Create forreing currency entries in encaisse_des_devises.
720 for currency
in ['usd', ]:
721 self
._maybeNewContent(caisse_courante
.encaisse_des_devises
, id=currency
, portal_type
='Category', codification
='', vault_type
='site/surface/caisse_courante/encaisse_des_devises')
723 return created_site_list
725 def _openDate(self
, date
=None, site
=None, id=None, open=True, container
=None,
726 portal_type
=None, force_check
=0):
728 date
= DateTime().Date()
729 if not isinstance(date
, str):
733 date_object
= container
.newContent(id=id, portal_type
=portal_type
,
734 site_value
= site
, start_date
= date
)
736 if force_check
and date_object
.getPortalType() == 'Counter Date':
737 self
.workflow_tool
.doActionFor(date_object
, 'open_action',
738 wf_id
='counter_date_workflow',
739 your_check_date_is_today
=0)
742 setattr(self
, id, date_object
)
743 date_object
.assignRoleToSecurityGroup()
745 def openAccountingDate(self
, date
=None, site
=None, id='accounting_date_1', open=True):
747 open an accounting date for the given date
748 by default use the current date
750 self
._openDate(date
=date
, site
=site
, id=id, open=open, container
=self
.getAccountingDateModule(), portal_type
='Accounting Date')
752 def openCounterDate(self
, date
=None, site
=None, id='counter_date_1', open=True, force_check
=0):
754 open a couter date for the given date
755 by default use the current date
757 self
._openDate(date
=date
, site
=site
, id=id, open=open,
758 container
=self
.getCounterDateModule(),
759 portal_type
='Counter Date',
760 force_check
=force_check
)
762 def openCounter(self
, site
=None, id='counter_1'):
764 open a counter for the givent site
767 counter_module
= self
.getCounterModule()
768 while "guichet" not in site
.getId():
769 site
= site
.getParentValue()
770 counter
= counter_module
.newContent(id=id, site_value
=site
)
774 def closeCounterDate(self
, id):
776 close the counter date
778 module
= self
.getCounterDateModule()
779 counter_date
= module
[id]
782 def initDefaultVariable(self
):
784 init some default variable use in all test
787 self
.portal
= self
.getPortal()
789 # Make sure movement table does not exist
790 sql_connection
= self
.getSQLConnection()
791 sql_connection
.manage_test("DROP TABLE IF EXISTS movement")
792 # Delete also all ZSQL Methods related to movement table
793 catalog
= self
.portal
.portal_catalog
.getSQLCatalog()
794 for zsql
in ["z0_drop_movement", "z0_uncatalog_movement",
795 "z_catalog_movement_list", "z_create_movement", ]:
796 if catalog
._getOb(zsql
, None) is not None:
797 catalog
.manage_delObjects(ids
=[zsql
])
799 # Update properties of catalog
800 sql_catalog_object_list
= list(catalog
.sql_catalog_object_list
)
801 sql_uncatalog_object
= list(catalog
.sql_uncatalog_object
)
802 sql_clear_catalog
= list(catalog
.sql_clear_catalog
)
803 sql_search_tables
= list(catalog
.sql_search_tables
)
805 if "z_catalog_movement_list" in sql_catalog_object_list
:
806 sql_catalog_object_list
.remove("z_catalog_movement_list")
807 if "z0_uncatalog_movement" in sql_uncatalog_object
:
808 sql_uncatalog_object
.remove("z0_uncatalog_movement")
809 if "z0_drop_movement" in sql_clear_catalog
:
810 sql_clear_catalog
.remove("z0_drop_movement")
811 if "z_create_movement" in sql_clear_catalog
:
812 sql_clear_catalog
.remove("z_create_movement")
813 if "movement" in sql_search_tables
:
814 sql_search_tables
.remove("movement")
816 catalog
.sql_catalog_object_list
= tuple(sql_catalog_object_list
)
817 catalog
.sql_uncatalog_object
= tuple(sql_uncatalog_object
)
818 catalog
.sql_clear_catalog
= tuple(sql_clear_catalog
)
819 catalog
.sql_search_tables
= tuple(sql_search_tables
)
821 # the default currency for the site
822 if not self
.portal
.hasProperty('reference_currency_id'):
823 self
.portal
.manage_addProperty('reference_currency_id', 'EUR', type='string')
825 if not self
.portal
.hasProperty('not_working_days'):
826 self
.portal
.manage_addProperty('not_working_days', '', type='string')
828 self
.portal
.not_working_days
= ''
829 setattr(self
.portal
, 'functionnal_test_mode', 1)
831 self
.person_module
= self
.getPersonModule()
832 # the organisation module
833 self
.organisation_module
= self
.getOrganisationModule()
835 self
.category_tool
= self
.getCategoryTool()
837 self
.workflow_tool
= self
.getWorkflowTool()
838 # nb use for bank account inventory
839 self
.account_inventory_number
= 0
840 # the cash inventory module
841 self
.cash_inventory_module
= self
.getCashInventoryModule()
842 # the bank inventory module
843 self
.bank_account_inventory_module
= self
.getBankAccountInventoryModule()
845 self
.simulation_tool
= self
.getSimulationTool()
846 # get the currency module
847 self
.currency_module
= self
.getCurrencyModule()
848 self
.checkbook_model_module
= self
.portal
.checkbook_model_module
850 self
.date
= DateTime()
852 def setDocumentSourceReference(self
, doc
):
854 Compute and set the source reference for a document
856 # document must have a date defined
857 if doc
.getStartDate() is None:
858 doc
.edit(start_date
=DateTime())
859 # call script to set source reference
860 doc
.Baobab_getUniqueReference()
863 def createPerson(self
, id, first_name
, last_name
, site
=None):
868 site
= "testsite/paris"
869 return self
.person_module
.newContent(id = id,
870 portal_type
= 'Person',
871 first_name
= first_name
,
872 last_name
= last_name
,
876 def createBankAccount(self
, person
, account_id
, currency
, amount
, inv_date
=None, **kw
):
878 Create and initialize a bank account for a person
880 if not kw
.has_key('bank_country_code'):
881 kw
['bank_country_code'] = 'k'
882 if not kw
.has_key('bank_code'):
883 kw
['bank_code'] = '1234'
884 if not kw
.has_key('branch'):
885 kw
['branch'] = '12345'
886 if not kw
.has_key('bank_account_number'):
887 kw
['bank_account_number'] = '123456789012'
888 if not kw
.has_key('bank_account_key'):
889 kw
['bank_account_key'] = '12'
890 if not kw
.has_key('internal_bank_account_number'):
891 kw
['internal_bank_account_number'] = 'k%11s' %
(12341234512 + self
.account_inventory_number
, )
892 #kw['internal_bank_account_number'] = 'k12341234512'
893 bank_account
= person
.newContent(id = account_id
,
894 portal_type
= 'Bank Account',
895 price_currency_value
= currency
,
897 if not kw
.has_key('reference') and bank_account
.getReference() is None:
898 # If there is no automatic getter-time calculation of the reference and
899 # no reference has been explicitely set, generate one composed of all
900 # bank codes and a static prefix - to avoid collisions as much as
902 bank_account
.edit(reference
='ref_%s%s%s%s%s' %
(kw
['bank_country_code'],
903 kw
['bank_code'], kw
['branch'], kw
['bank_account_number'],
904 kw
['bank_account_key']))
906 # validate this bank account for payment
907 bank_account
.validate()
909 # we need to put some money on this bank account
910 self
.createBankAccountInventory(bank_account
, amount
, inv_date
=inv_date
)
913 def createBankAccountInventory(self
, bank_account
, amount
, inv_date
=None):
914 if not hasattr(self
, 'bank_account_inventory'):
915 self
.bank_account_inventory
= self
.bank_account_inventory_module
.newContent(id='account_inventory_group',
916 portal_type
='Bank Account Inventory Group',
917 site_value
=self
.testsite
,
918 stop_date
=DateTime().Date())
921 inv_date
= DateTime()
922 inventory
= self
.bank_account_inventory
.newContent(id=bank_account
.getInternalBankAccountNumber(),
923 portal_type
='Bank Account Inventory',
924 destination_payment_value
=bank_account
,
926 account_inventory_line_id
= 'account_inventory_line_%s' %
(self
.account_inventory_number
, )
927 inventory_line
= inventory
.newContent(id=account_inventory_line_id
,
928 portal_type
='Bank Account Inventory Line',
929 resource_value
=bank_account
.getPriceCurrencyValue(),
933 # deliver the inventory
934 if inventory
.getSimulationState()!='delivered':
937 self
.account_inventory_number
+= 1
939 def createCheckbook(self
, id, vault
, bank_account
, min, max, date
=None):
941 Create a checkbook for the given bank account
944 date
= DateTime().Date()
945 return self
.checkbook_module
.newContent(
947 portal_type
='Checkbook',
948 destination_value
=vault
,
949 destination_payment_value
=bank_account
,
950 reference_range_min
=min,
951 reference_range_max
=max,
955 def createCheckbookModel(self
, id, check_model
, reference
=None,
956 unique_per_account
=True):
958 Create a checkbook for the given bank account
961 model
= self
.checkbook_model_module
.newContent(
963 portal_type
='Checkbook Model',
965 account_number_enabled
=True,
967 composition
=check_model
.getRelativeUrl(),
968 unique_per_account
=unique_per_account
,
970 model
.newContent(id='variant_1', portal_type
='Checkbook Model Check Amount Variation',
971 quantity
=50, title
='50')
972 model
.newContent(id='variant_2', portal_type
='Checkbook Model Check Amount Variation',
973 quantity
=100, title
='100')
974 model
.newContent(id='variant_3', portal_type
='Checkbook Model Check Amount Variation',
975 quantity
=200, title
='200')
979 def createCheckModel(self
, id, reference
='CCOP', unique_per_account
=True):
981 Create a checkbook for the given bank account
983 return self
.checkbook_model_module
.newContent(
985 portal_type
='Check Model',
988 account_number_enabled
=True,
989 unique_per_account
=unique_per_account
,
992 def createCheckAndCheckbookModel(self
):
994 create default checkbook and check models
996 self
.check_model
= self
.createCheckModel(id='check_model')
997 self
.check_model_1
= self
.check_model
998 self
.check_model_2
= self
.createCheckModel(id='check_model_2', reference
='CCCO')
999 self
.check_model_1_2
= self
.createCheckModel(
1000 id='check_model_1_2',
1002 unique_per_account
=False,
1004 self
.check_model_2_2
= self
.createCheckModel(
1005 id='check_model_2_2',
1007 unique_per_account
=False,
1009 self
.checkbook_model
= self
.createCheckbookModel(
1010 id='checkbook_model', check_model
=self
.check_model
)
1011 self
.checkbook_model_1
= self
.checkbook_model
1012 self
.checkbook_model_2
= self
.createCheckbookModel(
1013 id='checkbook_model_2', check_model
=self
.check_model_2
)
1014 self
.checkbook_model_1_2
= self
.createCheckbookModel(
1015 id='checkbook_model_1_2',
1016 check_model
=self
.check_model_1_2
,
1017 unique_per_account
=False,
1019 self
.checkbook_model_2_2
= self
.createCheckbookModel(
1020 id='checkbook_model_2_2',
1021 check_model
=self
.check_model_2_2
,
1022 unique_per_account
=False,
1025 def createCheck(self
, id, reference
, checkbook
, bank_account
=None,
1026 resource_value
=None, destination_value
=None):
1028 Create Check in a checkbook
1030 check
= checkbook
.newContent(id=id,
1031 portal_type
= 'Check',
1032 reference
=reference
,
1033 destination_payment_value
=bank_account
,
1034 resource_value
=resource_value
,
1035 destination_value
=destination_value
1038 # mark the check as issued
1042 def createTravelerCheckModel(self
, id):
1044 Create a checkbook for the given bank account
1046 model
= self
.checkbook_model_module
.newContent(id = id,
1047 title
= 'USD Traveler Check',
1048 portal_type
= 'Check Model',
1051 variation
= model
.newContent(id='variant_1',
1052 portal_type
='Check Model Type Variation',
1054 model
.setPriceCurrency(self
.currency_2
.getRelativeUrl())
1057 def createCashContainer(self
, document
, container_portal_type
, global_dict
, line_list
, delivery_line_type
='Cash Delivery Line'):
1059 Create a cash container
1060 global_dict has keys :
1061 emission_letter, variation, cash_status, resource
1062 line_list is a list od dict with keys:
1063 reference, range_start, range_stop, quantity, aggregate
1065 # Container Creation
1066 base_list
= ('emission_letter', 'variation', 'cash_status')
1067 category_list
= ('emission_letter/'+global_dict
['emission_letter'], 'variation/'+global_dict
['variation'], 'cash_status/'+global_dict
['cash_status'] )
1068 resource_total_quantity
= 0
1069 # create cash container
1070 for line_dict
in line_list
:
1071 movement_container
= document
.newContent(portal_type
= container_portal_type
1072 , reindex_object
= 1
1073 , reference
= line_dict
['reference']
1074 , cash_number_range_start
= line_dict
['range_start']
1075 , cash_number_range_stop
= line_dict
['range_stop']
1077 if line_dict
.has_key('aggregate'):
1078 movement_container
.setAggregateValueList([line_dict
['aggregate'], ])
1079 # create a cash container line
1080 container_line
= movement_container
.newContent(portal_type
= 'Container Line'
1081 , reindex_object
= 1
1082 , resource_value
= global_dict
['resource']
1083 , quantity
= line_dict
['quantity']
1085 container_line
.setResourceValue(global_dict
['resource'])
1086 container_line
.setVariationCategoryList(category_list
)
1087 container_line
.updateCellRange(script_id
='CashDetail_asCellRange', base_id
="movement")
1088 for key
in container_line
.getCellKeyList(base_id
='movement'):
1089 if isSameSet(key
, category_list
):
1090 cell
= container_line
.newCell(*key
)
1091 cell
.setCategoryList(category_list
)
1092 cell
.setQuantity(line_dict
['quantity'])
1093 cell
.setMappedValuePropertyList(['quantity', 'price'])
1094 cell
.setMembershipCriterionBaseCategoryList(base_list
)
1095 cell
.setMembershipCriterionCategoryList(category_list
)
1096 cell
.edit(force_update
= 1,
1097 price
= container_line
.getResourceValue().getBasePrice())
1100 resource_total_quantity
+= line_dict
['quantity']
1101 # create cash delivery movement
1102 movement_line
= document
.newContent(id = "movement"
1103 , portal_type
= delivery_line_type
1104 , resource_value
= global_dict
['resource']
1105 , quantity_unit_value
= self
.getCategoryTool().quantity_unit
.unit
1107 movement_line
.setVariationBaseCategoryList(base_list
)
1108 movement_line
.setVariationCategoryList(category_list
)
1109 movement_line
.updateCellRange(script_id
="CashDetail_asCellRange", base_id
="movement")
1110 for key
in movement_line
.getCellKeyList(base_id
='movement'):
1111 if isSameSet(key
, category_list
):
1112 cell
= movement_line
.newCell(*key
)
1113 cell
.setCategoryList(category_list
)
1114 cell
.setQuantity(resource_total_quantity
)
1115 cell
.setMappedValuePropertyList(['quantity', 'price'])
1116 cell
.setMembershipCriterionBaseCategoryList(base_list
)
1117 cell
.setMembershipCriterionCategoryList(category_list
)
1118 cell
.edit(force_update
= 1,
1119 price
= movement_line
.getResourceValue().getBasePrice())
1122 def createCashInventory(self
, source
, destination
, currency
, line_list
=[], extra_id
='',
1123 reset_quantity
=0, start_date
=None, quantity_factor
=1):
1125 Create a cash inventory group
1127 # we need to have a unique inventory group id by destination
1129 inventory_group_id
= 'inventory_group_%s_%s%s' % \
1130 (destination
.getParentValue().getUid(), destination
.getId(), extra_id
)
1131 if start_date
is None:
1132 start_date
= DateTime()-1
1133 if not hasattr(self
, inventory_group_id
):
1134 inventory_group
= self
.cash_inventory_module
.newContent(id=inventory_group_id
,
1135 portal_type
='Cash Inventory Group',
1136 destination_value
=destination
,
1137 start_date
=start_date
)
1138 setattr(self
, inventory_group_id
, inventory_group
)
1140 inventory_group
= getattr(self
, inventory_group_id
)
1142 # get/create the inventory based on currency
1143 inventory_id
= '%s_inventory_%s' %
(inventory_group_id
, currency
.getId())
1144 if not hasattr(self
, inventory_id
):
1145 inventory
= inventory_group
.newContent(id=inventory_id
,
1146 portal_type
='Cash Inventory',
1147 price_currency_value
=currency
)
1148 setattr(self
, inventory_id
, inventory
)
1150 inventory
= getattr(self
, inventory_id
)
1152 # line data are given by a list of dict, dicts must have this key :
1154 # resource : banknote or coin
1155 # variation_id : list of variation id
1156 # variation_value : list of variation value (must be in the same order as variation_id
1158 for line
in line_list
:
1159 variation_list
= line
.get('variation_list', None)
1160 self
.addCashLineToDelivery(inventory
,
1162 "Cash Inventory Line",
1164 line
['variation_id'],
1165 line
['variation_value'],
1167 variation_list
=variation_list
,
1168 reset_quantity
=reset_quantity
,
1169 quantity_factor
=quantity_factor
)
1170 # deliver the inventory
1171 if inventory
.getSimulationState()!='delivered':
1173 return inventory_group
1176 def addCashLineToDelivery(self
, delivery_object
, line_id
, line_portal_type
, resource_object
,
1177 variation_base_category_list
, variation_category_list
, resource_quantity_dict
,
1178 variation_list
=None, reset_quantity
=0, quantity_factor
=1):
1180 Add a cash line to a delivery
1182 base_id
= 'movement'
1183 line_kwd
= {'base_id':base_id
}
1184 # create the cash line
1185 line
= delivery_object
.newContent( id = line_id
1186 , portal_type
= line_portal_type
1187 , resource_value
= resource_object
# banknote or coin
1188 , quantity_unit_value
= self
.unit
1190 # set base category list on line
1191 line
.setVariationBaseCategoryList(variation_base_category_list
)
1192 # set category list line
1193 line
.setVariationCategoryList(variation_category_list
)
1194 line
.updateCellRange(script_id
='CashDetail_asCellRange', base_id
=base_id
)
1195 cell_range_key_list
= line
.getCellRangeKeyList(base_id
=base_id
)
1196 if cell_range_key_list
<> [[None, None]] :
1197 for k
in cell_range_key_list
:
1198 category_list
= filter(lambda k_item
: k_item
is not None, k
)
1199 c
= line
.newCell(*k
, **line_kwd
)
1200 mapped_value_list
= ['price', 'quantity']
1201 c
.edit( membership_criterion_category_list
= category_list
1202 , mapped_value_property_list
= mapped_value_list
1203 , category_list
= category_list
1206 # set quantity on cell to define quantity of bank notes / coins
1207 if variation_list
is None:
1208 variation_list
= self
.variation_list
1209 for variation
in variation_list
:
1210 v1
, v2
= variation_category_list
[:2]
1211 cell
= line
.getCell(v1
, variation
, v2
)
1212 if cell
is not None:
1213 quantity
= resource_quantity_dict
[variation
]
1216 cell
.setQuantity(quantity
*quantity_factor
)
1219 def checkResourceCreated(self
):
1221 Check that all have been create after setup
1223 # check that Categories were created
1224 self
.assertEqual(self
.paris
.getPortalType(), 'Category')
1226 # check that Resources were created
1227 # check portal type of billet_10000
1228 self
.assertEqual(self
.billet_10000
.getPortalType(), 'Banknote')
1229 # check value of billet_10000
1230 self
.assertEqual(self
.billet_10000
.getBasePrice(), 10000)
1231 # check currency value of billet_10000
1232 self
.assertEqual(self
.billet_10000
.getPriceCurrency(), 'currency_module/EUR')
1233 # check years of billet_10000
1234 self
.assertEqual(self
.billet_10000
.getVariationList(), ['1992', '2003'])
1236 # check portal type of billet_5000
1237 self
.assertEqual(self
.billet_5000
.getPortalType(), 'Banknote')
1238 # check value of billet_5000
1239 self
.assertEqual(self
.billet_5000
.getBasePrice(), 5000)
1240 # check currency value of billet_5000
1241 self
.assertEqual(self
.billet_5000
.getPriceCurrency(), 'currency_module/EUR')
1242 # check years of billet_5000
1243 self
.assertEqual(self
.billet_5000
.getVariationList(), ['1992', '2003'])
1245 # check portal type of billet_200
1246 self
.assertEqual(self
.billet_200
.getPortalType(), 'Banknote')
1247 # check value of billet_200
1248 self
.assertEqual(self
.billet_200
.getBasePrice(), 200)
1249 # check currency value of billet_200
1250 self
.assertEqual(self
.billet_200
.getPriceCurrency(), 'currency_module/EUR')
1251 # check years of billet_200
1252 self
.assertEqual(self
.billet_200
.getVariationList(), ['1992', '2003'])
1254 def resetInventory(self
,
1255 sequence
=None, line_list
=None, sequence_list
=None, extra_id
=None,
1256 destination
=None, currency
=None, start_date
=None, **kwd
):
1258 Make sure we can not close the counter date
1259 when there is still some operations remaining
1261 if extra_id
is not None:
1262 extra_id
= '_reset_%s' % extra_id
1265 # Before the test, we need to input the inventory
1266 self
.createCashInventory(source
=None, destination
=destination
, currency
=currency
,
1267 line_list
=line_list
, extra_id
=extra_id
, reset_quantity
=1,
1268 start_date
=start_date
)
1270 def stepDeleteResetInventory(self
, sequence
=None, sequence_list
=None, **kwd
):
1272 Make sure we can not close the counter date
1273 when there is still some operations remaining
1275 inventory_module
= self
.getPortal().cash_inventory_module
1276 to_delete_id_list
= [x
for x
in inventory_module
.objectIds()
1277 if x
.find('reset')>=0]
1278 inventory_module
.manage_delObjects(ids
=to_delete_id_list
)