Commit a454122e authored by Jean-Paul Smets's avatar Jean-Paul Smets

initial check in


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@1166 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent c2f00125
def _checkPermission(folder):
msg=''
if hasattr(folder, 'objectValues'):
for child in folder.objectValues():
msg += _checkPermission(child)
if hasattr(folder, 'valid_roles'):
valid_role_list = folder.valid_roles()
manager_index = list(valid_role_list).index('Manager')
permission_list = folder.permission_settings()
for permission in permission_list:
if permission['acquire'] == '':
for role in permission['roles']:
name = role['name']
pos = name.find('r')
index = int(name[pos+1:])
if manager_index == index:
if role['checked'] == '':
msg += '%s: %s does not contain Manager\n' % (folder.getUrl(), permission['name'])
break
return msg
def ERP5Site_checkAllPermissions(self):
portal = self.portal_url.getPortalObject()
return _checkPermission(portal)
## Script (Python) "Account_countAccountingTransactions"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=self
##title=
##
currency = None
if currency in (None, 'None'):
currency = context.currency.EUR
#inventory = context.Resource_zGetInventory(node_uid=context.getUid(), omit_simulation=1,
# resource_uid=(currency.getUid(),),
# simulation_state=('draft', 'planned', 'confirmed', 'stopped', 'delivered'))
inventory = context.Resource_zGetInventory(node_uid=self.uid, omit_simulation=1,
resource_uid=(currency.getUid(),),
simulation_state=('draft', 'planned', 'confirmed', 'stopped', 'delivered'))
inventory = inventory[0]
return str(inventory.stock_uid)
## Script (Python) "Account_getTotalSourceCredit"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=self
##title=
##
currency = None
if currency in (None, 'None'):
currency = context.currency.EUR
total = 0.0
try:
inventory = context.Resource_zGetInventory(node_uid=context.getUid(), omit_output=1, omit_simulation=1,
resource_uid=(currency.getUid(),),
simulation_state=('draft', 'planned', 'confirmed', 'stopped', 'delivered'))
total = inventory[0].inventory or 0.0
except:
pass
return '%.02f' % total
## Script (Python) "Account_getTotalSourceDebit"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=self
##title=
##
currency = None
if currency in (None, 'None'):
currency = context.currency.EUR
total = 0.0
try:
inventory = context.Resource_zGetInventory(node_uid=context.getUid(), omit_input=1, omit_simulation=1,
resource_uid=(currency.getUid(),),
simulation_state=('draft', 'planned', 'confirmed', 'stopped', 'delivered'))
total = - inventory[0].inventory or 0.0
except:
pass
return '%.02f' % total
<?xml version="1.0"?>
<form>
<title>Set List Settting</title>
<row_length>4</row_length>
<name>Account_list_ui</name>
<pt>form_list_ui</pt>
<action>base_list_ui</action>
<update_action></update_action>
<method>POST</method>
<enctype></enctype>
<encoding>UTF-8</encoding>
<stored_encoding>ISO-8859-1</stored_encoding>
<unicode_mode>false</unicode_mode>
<groups>
<group>
<title>left</title>
<fields>
</fields>
</group>
<group>
<title>right</title>
<fields>
</fields>
</group>
</groups>
</form>
\ No newline at end of file
## Script (Python) "Account_search"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=**kwd
##title=
##
for cname in kwd.keys():
if kwd[cname] == '' or kwd[cname] is None:
del kwd[cname]
kwd['select_expression'] = "'EUR' AS accounting_transaction_line_currency"
return context.portal_catalog(**kwd)
## Script (Python) "Account_stat"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=**kwd
##title=
##
return 'toto'
return repr(kwd)
<?xml version="1.0"?>
<form>
<title>Account</title>
<row_length>4</row_length>
<name>Account_viewTransactionList</name>
<pt>form_view</pt>
<action>base_edit</action>
<update_action></update_action>
<method>POST</method>
<enctype></enctype>
<encoding>UTF-8</encoding>
<stored_encoding>ISO-8859-1</stored_encoding>
<unicode_mode>false</unicode_mode>
<groups>
<group>
<title>left</title>
<fields>
</fields>
</group>
<group>
<title>right</title>
<fields>
</fields>
</group>
<group>
<title>center</title>
<fields>
</fields>
</group>
<group>
<title>bottom</title>
<fields>
<field><id>listbox</id> <type>ListBox</type>
<values>
<all_columns type="list">[]</all_columns>
<all_editable_columns type="list">[]</all_editable_columns>
<alternate_name></alternate_name>
<columns type="list">[('date', 'Date'), ('type', 'Type'), ('getReference', 'Reference'), ('quantity', 'Quantity')]</columns>
<css_class></css_class>
<default></default>
<default_params type="list">[]</default_params>
<description></description>
<domain_root_list type="list">[('portal_categories/group', 'Group'), ('portal_categories/region', 'Region')]</domain_root_list>
<domain_tree type="int">1</domain_tree>
<editable type="int">1</editable>
<editable_columns type="list">[]</editable_columns>
<editable_expression></editable_expression>
<editable_permission type="list">[]</editable_permission>
<editable_role type="list">[]</editable_role>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<global_attributes type="list">[]</global_attributes>
<hidden type="int">0</hidden>
<lines type="int">25</lines>
<list_action>list</list_action>
<list_method type="method">sql_stock_account_parent</list_method>
<meta_types type="list">[]</meta_types>
<not_viewable type="int">0</not_viewable>
<portal_types type="list">[('Accounting Transaction', 'Accounting Transaction'), ('Purchase Invoice Transaction', 'Purchase Invoice Transaction'), ('Sale Invoice Transaction', 'Sale Invoice Transaction')]</portal_types>
<read_only type="int">0</read_only>
<report_root_list type="list">[]</report_root_list>
<report_tree type="int">0</report_tree>
<search type="int">1</search>
<search_columns type="list">[]</search_columns>
<select type="int">1</select>
<selection_name>account_history_selection</selection_name>
<sort type="list">[]</sort>
<sort_columns type="list">[]</sort_columns>
<stat_method></stat_method>
<title>Transactions concerned by this account</title>
<viewable_expression></viewable_expression>
<viewable_permission type="list">[]</viewable_permission>
<viewable_role type="list">[]</viewable_role>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
</messages>
</field>
</fields>
</group>
</groups>
</form>
\ No newline at end of file
<?xml version="1.0"?>
<form>
<title>Balance Transaction Line</title>
<row_length>4</row_length>
<name>BalanceTransactionLine_view</name>
<pt>form_view</pt>
<action>base_edit</action>
<update_action></update_action>
<method>POST</method>
<enctype></enctype>
<encoding>UTF-8</encoding>
<stored_encoding>ISO-8859-1</stored_encoding>
<unicode_mode>false</unicode_mode>
<groups>
<group>
<title>left</title>
<fields>
<field><id>my_source</id> <type>ListField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<editable type="int">1</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<extra_item></extra_item>
<first_item type="int">0</first_item>
<hidden type="int">0</hidden>
<items type="list">[]</items>
<required type="int">0</required>
<size type="int">1</size>
<title>Account</title>
<unicode type="int">0</unicode>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
<items>python:here.getInvoiceTransactionLineSourceItemList()</items>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="unknown_selection">You selected an item that was not in the list.</message>
</messages>
</field>
<field><id>my_source_payment</id> <type>ListField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<editable type="int">1</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<extra_item></extra_item>
<first_item type="int">0</first_item>
<hidden type="int">0</hidden>
<items type="list">[]</items>
<required type="int">0</required>
<size type="int">1</size>
<title>Bank Account</title>
<unicode type="int">0</unicode>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
<items>python: here.getBalanceTransactionLineSourcePaymentItemList()</items>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="unknown_selection">You selected an item that was not in the list.</message>
</messages>
</field>
<field><id>my_destination_section_title</id> <type>RelationStringField</type>
<values>
<alternate_name></alternate_name>
<base_category>destination_section</base_category>
<catalog_index>Title</catalog_index>
<css_class></css_class>
<default></default>
<default_module>organisation</default_module>
<description></description>
<display_maxwidth></display_maxwidth>
<display_width type="int">20</display_width>
<editable type="int">1</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<hidden type="int">0</hidden>
<jump_method>base_jump_relation</jump_method>
<max_length></max_length>
<portal_type type="list">[('Person', 'Person'), ('Organisation', 'Organisation')]</portal_type>
<relation_setter_id></relation_setter_id>
<required type="int">0</required>
<title>Third Party</title>
<truncate type="int">0</truncate>
<unicode type="int">0</unicode>
<update_method>base_update_relation</update_method>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="too_long">Too much input was given.</message>
</messages>
</field>
<field><id>my_resource</id> <type>ListField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<editable type="int">1</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<extra_item></extra_item>
<first_item type="int">0</first_item>
<hidden type="int">0</hidden>
<items type="list">[]</items>
<required type="int">0</required>
<size type="int">1</size>
<title>Currency</title>
<unicode type="int">0</unicode>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
<items>python:map(lambda x: (x.id,'currency/%s' % x.id),here.currency.objectValues())</items>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="unknown_selection">You selected an item that was not in the list.</message>
</messages>
</field>
<field><id>my_source_credit</id> <type>FloatField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<display_maxwidth></display_maxwidth>
<display_width type="int">20</display_width>
<editable type="int">1</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<hidden type="int">0</hidden>
<required type="int">0</required>
<title>Credit</title>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="not_float">You did not enter a floating point number.</message>
</messages>
</field>
<field><id>my_source_debit</id> <type>FloatField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<display_maxwidth></display_maxwidth>
<display_width type="int">20</display_width>
<editable type="int">1</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<hidden type="int">0</hidden>
<required type="int">0</required>
<title>Debit</title>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="not_float">You did not enter a floating point number.</message>
</messages>
</field>
</fields>
</group>
<group>
<title>right</title>
<fields>
</fields>
</group>
<group>
<title>center</title>
<fields>
</fields>
</group>
<group>
<title>bottom</title>
<fields>
</fields>
</group>
</groups>
</form>
\ No newline at end of file
This diff is collapsed.
## Script (Python) "PaySheetLinesPrintFormat"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
True = 1
False = 0
pay_sheet = context.getObject()
all = pay_sheet.objectValues()
# this dictionnary contain all pay sheet details extracted from Pay Sheet Lines.
# these details are sorted and tidy for a clean print of the Pay Sheet
formated_lines = [] # id, title, pp, cs, ps
# todo: add: description assiette, montant assiette, pourcentage de la part salariale et patronale
# get all PaySheetLines
for pay_sheet_line in all:
ID = pay_sheet_line.getId()
if ID[-3:] == '_pp' or ID[-3:] == '_cs':
# search an existing id without the suffix in the final table
i = 0
id_exist = False
for line in formated_lines:
if line['id'] == ID[:-3]:
id_exist = True
break
i += 1
# add a new line of contribution in pay sheet details
if id_exist == False:
new_formated_line = { 'id' : ID[:-3],
'title' : None,
'pp' : None,
'cs' : None,
'ps' : None,
'ps_desc' : None,
'pp_desc' : None}
formated_lines.append(new_formated_line)
# get the employer share ('pp' is the french acronym of 'part patronale')
if ID[-3:] == '_pp':
formated_lines[i]['pp'] = pay_sheet_line.getDestinationCredit()
formated_lines[i]['pp_desc'] = pay_sheet_line.getDescription()
# get the social contribution (= employer + salary share) ('cs' is a french acronym of 'cotisation sociale')
elif ID[-3:] == '_cs':
formated_lines[i]['cs'] = pay_sheet_line.getDestinationCredit()
formated_lines[i]['title'] = pay_sheet_line.getTitle()
formated_lines[i]['ps_desc'] = pay_sheet_line.getDescription()
# calculation of the salary share ('ps' is a french acronym of 'part salariale')
for line in formated_lines:
if line['cs']!=None and line['pp']!=None and line['cs']!=line['pp']:
line['ps'] = float(line['cs']) - float(line['pp'])
if line['cs']!=None and line['pp']==None:
line['ps'] = float(line['cs'])
return formated_lines
## Script (Python) "PaySheetTransactionLine_generate"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
paysheet = context.getObject()
paysheet_type = paysheet.getPortalType()
paysheet_line_type = 'Pay Sheet Line'
paysheet_transactionline_type = 'Pay Sheet Transaction Line'
paysheet_cell_type = 'Pay Sheet Cell'
employee = paysheet.getDestinationSection()
employer = paysheet.getSourceSection()
employer_object = paysheet.getSourceSectionValue()
# gross salary source and destination
charge_salariale = 'account/charges_salariales'
produit_salarial = 'account/produits_salariaux'
# final salary source and destination
dette_salarie = 'account/dettes_salaries'
creance_salarie = 'account/creances_salaries'
# employer share source and destination
charge_sociale = 'account/charges_sociales'
produit_social = 'account/produits_sociaux'
# employer + employee share source and destination
dette_sociale = 'account/dettes_sociales'
creance_sociale = 'account/creances_sociales'
# the currency related to this french rules set is euros
paysheet_resource = 'currency/EUR'
# Create a new pay sheet line
def createPaySheetTransactionLine(new_title='', share='',
src_sec='', src='', src_deb=None,
dest_sec='', dest='', new_desc=''):
suffix = { 'social' : ' (cotisations sociales)'
, 'employer': ' (part patronale)'
}
if share == 'social' or share == 'employer':
new_title += suffix[share]
if share == 'social':
src_sec = employer
src = dette_sociale
dest = creance_sociale
elif share == 'employer':
src_sec = employer
src = charge_sociale
dest = produit_social
new_id = str(paysheet.generateNewId())
context.portal_types.constructContent ( type_name = paysheet_transactionline_type
, container = paysheet
, id = new_id
)
# alternate method but doesn't work
#new_line = paysheet.getObject(new_id)
paysheet[new_id].setTitle(new_title)
paysheet[new_id].setResource(paysheet_resource)
paysheet[new_id].setSourceSection(src_sec)
paysheet[new_id].setSource(src)
paysheet[new_id].setDestinationSection(dest_sec)
paysheet[new_id].setDestination(dest)
paysheet[new_id].setSourceDebit(src_deb)
paysheet[new_id].setDescription(new_desc)
def addAccountingItem(title='', mplyee_share=None, mplyer_share=None, dest_org=''):
if mplyer_share == 0 and mplyee_share == 0:
return
if mplyer_share == 0:
createPaySheetTransactionLine ( new_title = title
, share = 'social'
, src_deb = mplyee_share
, dest_sec = dest_org
)
return
if mplyee_share == 0:
createPaySheetTransactionLine ( new_title = title
, share = 'social'
, src_deb = mplyer_share
, dest_sec = dest_org
)
createPaySheetTransactionLine ( new_title = title
, share = 'employer'
, src_deb = mplyer_share
, dest_sec = dest_org
)
return
createPaySheetTransactionLine ( new_title = title
, share = 'social'
, src_deb = float(mplyer_share) + float(mplyee_share)
, dest_sec = dest_org
)
createPaySheetTransactionLine ( new_title = title
, share = 'employer'
, src_deb = mplyer_share
, dest_sec = dest_org
)
# Only keep the PaySheetLine in the paysheet, delete all other objects
id_list = []
for paysheet_item in paysheet.objectValues():
if paysheet_item.getPortalType() != paysheet_line_type:
id_list.append(paysheet_item.getId())
paysheet.manage_delObjects(id_list)
# Get all amount
paysheet_details = paysheet.PaySheetTransaction_getDetails()
paysheet_categories = paysheet_details['paysheet_categories']
paysheet_formated_lines = []
for category in paysheet_categories:
for line in paysheet_categories[category]['lines']:
paysheet_formated_lines.append(line)
# Analyze every PaySheet Line
paysheet_lines = paysheet.objectValues()
for paysheet_item in paysheet_lines:
if paysheet_item.getPortalType() == paysheet_line_type:
# Find the dictionnary that contain the pre-calculated employer and employee share
employer_share = 0.0
employee_share = 0.0
for line in paysheet_formated_lines:
if line['id'] == paysheet_item.getId():
er = line['employer_share']
ee = line['employee_share']
if er not in (None, ''):
employer_share += abs(float(er))
if ee not in (None, ''):
employee_share += abs(float(ee))
# Get the destination organisation
paysheet_line_service = paysheet_item.getResourceValue()
organisation = paysheet_line_service.getSource()
# Add accounting item corresponding to the PaySheet Line
addAccountingItem ( title = paysheet_item.getTitle()
, mplyer_share = employer_share
, mplyee_share = employee_share
, dest_org = organisation
)
# Add the gross salary
createPaySheetTransactionLine ( new_title = 'Salaire brut'
, src_sec = employer
, src = charge_salariale
, src_deb = abs(float(paysheet_details['gross_salary']))
, dest_sec = employee
, dest = produit_salarial
)
# Add the final salary
createPaySheetTransactionLine ( new_title = 'Salaire net'
, src_sec = employer
, src = dette_salarie
, src_deb = abs(float(paysheet_details['net_salary']))
, dest_sec = employee
, dest = creance_salarie
)
# 'refresh' screen
return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=Pay+Sheet+Transaction+Lines+created.')
## Script (Python) "PaySheetTransaction_checkParameters"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
paysheet = context.getObject()
paysheet_type = paysheet.getPortalType()
employee = paysheet.getDestinationSection()
employer = paysheet.getSourceSection()
if paysheet.getGrossSalary() == None:
return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=Gross+salary+is+required')
if employee in ('', None):
return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employee+is+required')
if employer in ('', None):
return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employer+is+required')
employee_obj = paysheet.getDestinationSectionValue()
employer_obj = paysheet.getSourceSectionValue()
if employee_obj.getCareerGrade() in ('', None):
return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employee+must+have+a+career+grade')
if employer_obj.getCreationDate() in ('', None):
return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employer+must+have+an+organisation+creation+date')
if employer_obj.getDefaultAddress().getZipCode() in ('', None):
return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employer+must+have+a+zip+code')
# parameters are OK, go to the pre-calculation form
return context.REQUEST.RESPONSE.redirect(context.absolute_url() + "/PaySheetTransaction_previewForm?selection_name=default&amp;dialog_category=object_action&amp;form_id=PaySheetTransaction_view")
## Script (Python) "PaySheetTransaction_getDetails"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
# this dict contain all paysheet details
paysheet_details = {}
# initialize the employee and employer share total
total_employee_share = 0.0
total_employer_share = 0.0
total_taxable_employee_share = 0.0
# get the gross salary
gross_salary = context.getGrossSalary()
if gross_salary == None:
gross_salary = 0.0
paysheet_cat = {}
object_list = []
for object in context.objectValues():
object_list += [object]
# Sort the list by id since lines are already ordered by id.
object_list.sort(lambda x, y: cmp(int(x.getId()), int(y.getId())))
for pay_sheet_line in object_list:
variation_list = pay_sheet_line.getVariationCategoryList()
range_variation = []
for variation in variation_list:
if variation.find('salary_range')==0:
if not variation in range_variation: # Extra checking because
# get VariationCategoryList returns
# the same 1 items 2 times
range_variation += [variation]
for range in range_variation:
pay_sheet_dict = {}
#pay_sheet_dict['range']=range[range.rfind('/')+1:]
pay_sheet_dict['id'] = pay_sheet_line.getId()
pay_sheet_dict['title'] = pay_sheet_line.getResourceTitle()
for cell in pay_sheet_line.objectValues():
predicate_list = cell.getPredicateValueList()
if range in predicate_list:
pay_sheet_dict['base_name'] = context.portal_categories.resolveCategory(range).getTitleOrId()
for predicate in predicate_list:
if cell.getTotalPrice() != 0:
if predicate.find('employee_share')>=0:
pay_sheet_dict['base']= - cell.getQuantity()
pay_sheet_dict['employee_share'] = cell.getTotalPrice()
pay_sheet_dict['employee_share_rate'] = cell.getPrice() * 100
total_employee_share += float(-pay_sheet_dict['employee_share'])
# here we decide if a resource is taxable or not
if str(pay_sheet_line.getResource())[-14:] == 'non_deductible' or str(pay_sheet_line.getResource())[-4:] == 'crds' or str(pay_sheet_line.getResource())[-7:] == 'taxable':
pay_sheet_dict['taxable']='yes'
elif str(pay_sheet_line.getResource())[-10:] == 'deductible':
pay_sheet_dict['taxable']='no'
else:
pay_sheet_dict['taxable']='no'
if pay_sheet_dict['taxable'] == 'yes':
total_taxable_employee_share += float(-pay_sheet_dict['employee_share'])
elif predicate.find('employer_share')>=0:
pay_sheet_dict['base'] = - cell.getQuantity()
pay_sheet_dict['employer_share'] = cell.getTotalPrice()
pay_sheet_dict['employer_share_rate'] = cell.getPrice() * 100
total_employer_share += float(-pay_sheet_dict['employer_share'])
for key in ('employee_share','employee_share_rate','employer_share','employer_share_rate'):
if not (pay_sheet_dict.has_key(key)):
pay_sheet_dict[key]='' # so that we can display nothing
# find the category of the current pay sheet line
cat_id = None
cat_path = None
for var in variation_list:
sub_cat = var.split('/')
if sub_cat[0] == 'tax_category':
cat_id = sub_cat[1]
cat_path = sub_cat[0] + '/' + sub_cat[1]
break
if cat_id == None:
cat_id = 'no_cat'
# add the current pay sheet line to its category
if not paysheet_cat.has_key(cat_id):
paysheet_cat[cat_id] = {}
paysheet_cat[cat_id]['lines'] = []
if cat_path != None:
paysheet_cat[cat_id]['title'] = context.portal_categories.resolveCategory(cat_path).getTitleOrId()
paysheet_cat[cat_id]['lines'].append(pay_sheet_dict)
# get all paysheet transaction to calculate the sum of different value in a year
accounting_folder = context.aq_parent
paysheet_transactions = accounting_folder.contentValues(filter={'portal_type':'Pay Sheet Transaction'})
# initialize every yearly variable
yearly_net_salary = 0.0
yearly_gross_salary = 0.0
yearly_employee_share = 0.0
yearly_employer_share = 0.0
yearly_taxable_net_salary = 0.0
# get the current paysheet start date and employee
start_date = context.getStartDate()
employee = context.restrictedTraverse(context.getDestinationSectionRelativeUrl())
# browse through paysheet transaction
for paysheet_obj in paysheet_transactions:
# ignore the current paysheet to avoid infinite loop
if paysheet_obj.getId() != context.getId():
# the paysheet must have the same employee
if (employee==None) or (employee!=None and context.restrictedTraverse(paysheet_obj.getDestinationSectionRelativeUrl())==employee):
# check the date
if (start_date==None) or (start_date!=None and paysheet_obj.getStartDate()!=None and start_date.year()==paysheet_obj.getStartDate().year() and paysheet_obj.getStartDate()<= start_date):
# get all detailed values of the paysheet
ps_details = paysheet_obj.PaySheetTransaction_getDetails()
# sum of yearly values
yearly_net_salary += float(ps_details['net_salary'])
yearly_gross_salary += float(ps_details['gross_salary'])
yearly_employee_share += float(ps_details['total_employee_share'])
yearly_employer_share += float(ps_details['total_employer_share'])
yearly_taxable_net_salary += float(ps_details['taxable_net_salary'])
# save the total share values in the exported dict
paysheet_details['net_salary'] = gross_salary - total_employee_share
paysheet_details['gross_salary'] = gross_salary
paysheet_details['paysheet_categories'] = paysheet_cat
paysheet_details['total_employee_share'] = total_employee_share
paysheet_details['taxable_net_salary'] = paysheet_details['net_salary'] + total_taxable_employee_share
paysheet_details['total_employer_share'] = total_employer_share
paysheet_details['total_taxable_employee_share'] = total_taxable_employee_share
# don't forget to add the current values to the yearly sum
paysheet_details['yearly_net_salary'] = yearly_net_salary + paysheet_details['net_salary']
paysheet_details['yearly_gross_salary'] = yearly_gross_salary + paysheet_details['gross_salary']
paysheet_details['yearly_employee_share'] = yearly_employee_share + paysheet_details['total_employee_share']
paysheet_details['yearly_employer_share'] = yearly_employer_share + paysheet_details['total_employer_share']
paysheet_details['yearly_taxable_net_salary'] = yearly_taxable_net_salary + paysheet_details['taxable_net_salary']
return paysheet_details
## Script (Python) "PaySheetTransaction_getDetails_BACKUP"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
# this dict contain all paysheet details
paysheet_details = {}
# initialize the salary and employer share total
total_salary_share = 0.0
total_employer_share = 0.0
total_taxable_salary_share = 0.0
# get the gross salary
gross_salary = context.getGrossSalary()
pay_sheet_lines=tuple()
object_list = []
for object in context.objectValues():
object_list += [object]
# Sort the list by id since lines are already ordered by id.
object_list.sort(lambda x, y: cmp(int(x.getId()), int(y.getId())))
for pay_sheet_line in object_list:
variation_list = pay_sheet_line.getVariationCategoryList()
range_variation = []
for variation in variation_list:
if variation.find('salary_range')==0:
if not variation in range_variation: # Extra checking because
# get VariationCategoryList returns
# the same 1 items 2 times
range_variation += [variation]
for range in range_variation:
pay_sheet_dict = {}
#pay_sheet_dict['range']=range[range.rfind('/')+1:]
pay_sheet_dict['id'] = pay_sheet_line.getId()
pay_sheet_dict['title'] = pay_sheet_line.getResourceTitle()
for cell in pay_sheet_line.objectValues():
predicate_list = cell.getPredicateValueList()
if range in predicate_list:
for predicate in predicate_list:
if cell.getTotalPrice() != 0:
if predicate.find('salary_share')>=0:
pay_sheet_dict['base']= - cell.getQuantity()
pay_sheet_dict['salary_share'] = cell.getTotalPrice()
pay_sheet_dict['salary_share_rate'] = cell.getPrice() * 100
total_salary_share += float(-pay_sheet_dict['salary_share'])
# here we decide if a resource is taxable or not
if str(pay_sheet_line.getResource())[-14:] == 'non_deductible' or str(pay_sheet_line.getResource())[-4:] == 'crds' or str(pay_sheet_line.getResource())[-7:] == 'taxable':
pay_sheet_dict['taxable']='yes'
elif str(pay_sheet_line.getResource())[-10:] == 'deductible':
pay_sheet_dict['taxable']='no'
else:
pay_sheet_dict['taxable']='no'
if pay_sheet_dict['taxable'] == 'yes':
total_taxable_salary_share += float(-pay_sheet_dict['salary_share'])
elif predicate.find('employer_share')>=0:
pay_sheet_dict['base'] = - cell.getQuantity()
pay_sheet_dict['employer_share'] = cell.getTotalPrice()
pay_sheet_dict['employer_share_rate'] = cell.getPrice() * 100
total_employer_share += float(-pay_sheet_dict['employer_share'])
for key in ('salary_share','salary_share_rate','employer_share','employer_share_rate'):
if not (pay_sheet_dict.has_key(key)):
pay_sheet_dict[key]='' # so that we can display nothing
pay_sheet_lines += (pay_sheet_dict,)
# get all paysheet transaction to calculate the sum of different value in a year
accounting_folder = context.aq_parent
paysheet_transactions = accounting_folder.contentValues(filter={'portal_type':'Pay Sheet Transaction'})
# initialize every yearly variable
yearly_net_salary = 0.0
yearly_gross_salary = 0.0
yearly_salary_share = 0.0
yearly_employer_share = 0.0
yearly_taxable_net_salary = 0.0
# get the current paysheet start date and employee
start_date = context.getStartDate()
employee = context.restrictedTraverse(context.getDestinationSectionRelativeUrl())
# browse through paysheet transaction
for paysheet_obj in paysheet_transactions:
# ignore the current paysheet
if paysheet_obj.getId() != context.getId():
# the paysheet must have the same employee
if (employee==None) or (employee!=None and context.restrictedTraverse(paysheet_obj.getDestinationSectionRelativeUrl())==employee):
# check the date
if (start_date==None) or (start_date!=None and paysheet_obj.getStartDate()!=None and start_date.year()==paysheet_obj.getStartDate().year() and paysheet_obj.getStartDate()<= start_date):
# get all detailed values of the paysheet
ps_details = paysheet_obj.PaySheetTransaction_getDetails()
# sum of yearly values
yearly_net_salary += float(ps_details['net_salary'])
yearly_gross_salary += float(ps_details['gross_salary'])
yearly_salary_share += float(ps_details['total_salary_share'])
yearly_employer_share += float(ps_details['total_employer_share'])
yearly_taxable_net_salary += float(ps_details['taxable_net_salary'])
# save the total share values in the exported dict
paysheet_details['net_salary'] = gross_salary - total_salary_share
paysheet_details['gross_salary'] = gross_salary
paysheet_details['paysheet_lines'] = pay_sheet_lines
paysheet_details['total_salary_share'] = total_salary_share
paysheet_details['taxable_net_salary'] = paysheet_details['net_salary'] + total_taxable_salary_share
paysheet_details['total_employer_share'] = total_employer_share
paysheet_details['total_taxable_salary_share'] = total_taxable_salary_share
# don't forget to add the current values to the yearly sum
paysheet_details['yearly_net_salary'] = yearly_net_salary + paysheet_details['net_salary']
paysheet_details['yearly_gross_salary'] = yearly_gross_salary + paysheet_details['gross_salary']
paysheet_details['yearly_salary_share'] = yearly_salary_share + paysheet_details['total_salary_share']
paysheet_details['yearly_employer_share'] = yearly_employer_share + paysheet_details['total_employer_share']
paysheet_details['yearly_taxable_net_salary'] = yearly_taxable_net_salary + paysheet_details['taxable_net_salary']
return paysheet_details
## Script (Python) "PaySheetTransaction_getFormattedLines_OLD"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
# Example code:
pay_sheet_lines=tuple()
object_list = []
for object in context.objectValues():
object_list += [object]
# Sort the list by id since lines are already ordered by id.
object_list.sort(lambda x, y: cmp(int(x.getId()), int(y.getId())))
for pay_sheet_line in object_list:
variation_list = pay_sheet_line.getVariationCategoryList()
range_variation = []
for variation in variation_list:
if variation.find('salary_range')==0:
if not variation in range_variation: # Extra checking because
# get VariationCategoryList returns
# the same 1 items 2 times
range_variation += [variation]
for range in range_variation:
pay_sheet_dict = {}
#pay_sheet_dict['range']=range[range.rfind('/')+1:]
pay_sheet_dict['id'] = pay_sheet_line.getId()
pay_sheet_dict['title'] = pay_sheet_line.getResourceTitle()
for cell in pay_sheet_line.objectValues():
predicate_list = cell.getPredicateValueList()
if range in predicate_list:
for predicate in predicate_list:
if cell.getTotalPrice() != 0:
if predicate.find('salary_share')>=0:
pay_sheet_dict['range']= - cell.getQuantity()
pay_sheet_dict['salary_share']='%.2f' % cell.getTotalPrice()
pay_sheet_dict['salary_share_rate']='%.3f %%' % (cell.getPrice()*100)
if str(pay_sheet_line.getResource())[-14:] == 'non_deductible' or str(pay_sheet_line.getResource())[-4:] == 'crds' or str(pay_sheet_line.getResource())[-7:] == 'taxable':
pay_sheet_dict['taxable']='yes'
elif str(pay_sheet_line.getResource())[-10:] == 'deductible':
pay_sheet_dict['taxable']='no'
else:
pay_sheet_dict['taxable']='no'
elif predicate.find('employer_share')>=0:
pay_sheet_dict['range']= - cell.getQuantity()
pay_sheet_dict['employer_share']='%.2f' % cell.getTotalPrice()
pay_sheet_dict['employer_share_rate']='%.3f %%' % (cell.getPrice()*100)
for key in ('salary_share','salary_share_rate','employer_share','employer_share_rate'):
if not (pay_sheet_dict.has_key(key)):
pay_sheet_dict[key]='' # so that we can display nothing
pay_sheet_lines += (pay_sheet_dict,)
return pay_sheet_lines
## Script (Python) "PaySheetTransaction_getPreavis"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
# Définition des préavis selon le temps dans l'entreprise (en jours)
seuils = [ { 'limite':30 , 'preavis':'1 jour' }, # 1er mois d'essai
{ 'limite':60 , 'preavis':'1 semaine' }, # 2e mois d'essai
{ 'limite':730, 'preavis':'1 mois' }, # 2 premières années
{ 'limite':0, 'preavis':'2 mois' } ] # Après les 2 premières années
paysheet = context.getObject()
employee_object = paysheet.getDestinationSectionValue()
# Récupération de l'entreprise actuelle
currentOrg = None
if hasattr(employee_object,"default_career"):
currentOrg = employee_object["default_career"].getSubordinationValue()
if currentOrg == None:
return '???'
# Calcul du temps total dans cette entreprise
totalTime = 0
steps = employee_object.contentValues()
for step in steps:
if step.getPortalType() == "Career" and step.getId() != "default_career":
if step.getSubordinationValue() == currentOrg:
difference = step.getStopDate() - step.getStartDate()
if difference > 0:
totalTime = totalTime + difference
totalTime = int( totalTime + (DateTime() - employee_object["default_career"].getStartDate()) )
# Détermination du préavis
for i in range(len(seuils)):
if i < len(seuils)-1:
if seuils[i]['limite'] >= totalTime:
return seuils[i]['preavis']
else:
return seuils[i]['preavis']
## Script (Python) "PaySheetTransaction_initializePreview"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=**kw
##title=
##
import random
from Products.ERP5Type.Document import newTempBase
from string import zfill
global portal_object, num, l
portal_object = context.getPortalObject()
num = 0
l = []
# get all pre-calculated rates and bases
default_values = context.PaySheetTransaction_preCalculation()
# function to create a new preview line
def createPreviewLine ( new_id = None
, new_title = None
, new_base = None
, new_base_name = None
, new_employee_rate = None
, new_employer_rate = None
, new_service_url = None
, new_organisation_url = None
, new_salary_range_cat = None
, new_tax_cat = None
):
global portal_object, num, l
num += 1
int_len = 3
o = newTempBase(portal_object, new_id)
o.setUid('new_%s' % zfill(num, int_len))
o.edit(uid='new_%s' % zfill(num, int_len))
o.edit ( id = new_id
, title = new_title
, base = new_base
, base_name = new_base_name
, employee_share_rate = new_employee_rate
, employer_share_rate = new_employer_rate
, service_url = new_service_url
, organisation_url = new_organisation_url
, salary_range_cat = new_salary_range_cat
, tax_cat = new_tax_cat
)
l.append(o)
# get all services related to pay sheet transaction
paysheet_services = []
erp5site = context.portal_url.getPortalObject()
for service in erp5site['service'].objectValues():
base_cat = service.getVariationRangeBaseCategoryList()
# a service is related to paysheet transaction if it has 'tax_category' et 'salary_range' as base category
if 'tax_category' in base_cat and 'salary_range' in base_cat:
paysheet_services.append(service)
# Sort the service list by id
paysheet_services.sort(lambda x, y: cmp(x.getId(), y.getId()))
# generate all lines for the preview form
for serv in paysheet_services:
cat_list = serv.getCategoryList()
# store all categories of the service into lists
tax_cat = []
range_cat = []
for cat in cat_list:
if str(cat).find('tax_category') != -1:
tax_cat.append(cat)
if str(cat).find('salary_range') != -1:
range_cat.append(cat)
# create a line for every salary_range of the service
for base in range_cat:
name = serv.getId() + '/' + context.portal_categories.resolveCategory(base).getId()
# a preview line is composed of a base calculation, an employee share rate and an employer share rate
if default_values.has_key(name):
new_base = default_values[name]['base']
new_employee_rate = default_values[name]['employee_rate']
new_employer_rate = default_values[name]['employer_rate']
# create a preview line for every salary_range value of the service
createPreviewLine ( new_id = serv.getId()
, new_title = serv.getTitleOrId()
, new_base = new_base
, new_base_name = context.portal_categories.resolveCategory(base).getTitleOrId()
, new_employee_rate = new_employee_rate
, new_employer_rate = new_employer_rate
, new_service_url = serv.getRelativeUrl()
, new_organisation_url = serv.getSource()
, new_salary_range_cat = base
, new_tax_cat = tax_cat
)
# return the list of preview lines
return l
## Script (Python) "PaySheetTransaction_postCalculation"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=listbox=[],**kw
##title=
##
True = 1
False = 0
global paysheet
paysheet = context.getObject()
paysheet_type = paysheet.getPortalType()
paysheet_line_type = 'Pay Sheet Line'
paysheet_cell_type = 'Pay Sheet Cell'
employee = paysheet.getDestinationSection()
employee_object = paysheet.getDestinationSectionValue()
employer = paysheet.getSourceSection()
employer_object = paysheet.getSourceSectionValue()
# delete all objects in the paysheet
id_list = []
for paysheet_item in paysheet.objectValues():
id_list.append(paysheet_item.getId())
paysheet.manage_delObjects(id_list)
# this function register all paysheet informations in paysheet lines and cells
def createPaySheetItem(title='', res='', dest_org='', cells=[]):
global paysheet
# select good cells only
good_cells = []
for cell in cells:
if cell["base"] not in ('', 0, None) and cell["rate"] not in ('', 0, None):
good_cells.append(cell)
if len(good_cells) == 0:
return
# get all variation categories used in cells
var_cat_list = []
for cell in good_cells:
var_cat_list.append(cell["x"])
var_cat_list.append(cell["y"])
# add a new Pay Sheet Line
payline = paysheet.newContent( portal_type = 'Pay Sheet Line'
, title = title
, resource = res
, destination_section = dest_org
, destination = dest_org
, variation_base_category_list = ('tax_category', 'salary_range')
, variation_category_list = var_cat_list
)
# fill each cell with values
for cell in good_cells:
paycell = payline.getCell(cell["x"], cell["y"], base_id = 'movement')
paycell.edit(quantity=-cell["base"], price=cell["rate"]/100.0)
# set the title of the paysheet if empty
months = ['janvier', 'fvrier', 'mars', 'avril', 'mai', 'juin', 'juillet', 'aot', 'septembre', 'octobre', 'novembre', 'dcembre']
if paysheet.getTitle() in ('', None):
new_title = 'Salaire ' + str(employee_object.getTitle())
if paysheet.getStartDate() not in ('', None):
new_title = ' ' + months[int(str(paysheet.getStartDate())[5:7])-1] + ' ' + str(paysheet.getStartDate())[0:4]
paysheet.setTitle(new_title)
# get the ordered list of standard preview line objects
std_lines = context.PaySheetTransaction_initializePreview()
# this list contain all paysheet items, indexed by service
paysheet_items = {}
# scan every standard preview line to create an item for each service
for std_line in std_lines:
# get the service url (unique because containing the id)
service = std_line.getProperty('service_url')
# verify that the service is not existing
if not paysheet_items.has_key(service):
# create a temporary service item
temp_item = {}
# fill the new item with needed data
temp_item['title'] = std_line.getProperty('title')
temp_item['res'] = std_line.getProperty('service_url')
temp_item['dest_org'] = std_line.getProperty('organisation_url')
temp_item['cells'] = []
# add the new service item to the list
paysheet_items[service] = temp_item
# initialise the user preview line index
user_line_index = 0
# scan every standard preview line and get the correspondant user preview line to put user parameters in appropriate cells
for std_line in std_lines:
# define some values related to current standard preview line
service = std_line.getProperty('service_url')
salary_range_cat = std_line.getProperty('salary_range_cat')
tax_cat = std_line.getProperty('tax_cat')
# increment the user line index: we can use this strategy because preview lines (user or standard ones) are sorted
user_line_index += 1
# get user paysheet parameters stored in user preview line (=listbox)
for user_line in listbox:
# search the user preview line corresponding to the standard preview line
if user_line.has_key('listbox_key') and int(user_line['listbox_key'])==user_line_index:
# got it ! we have the right line
# get the base salary
base = user_line['base']
# scan allowed tax categories to get employee and/or employer share rate
for cat in tax_cat:
# define an empty new cell
new_cell = None
mployee_r = user_line['employee_share_rate']
mployer_r = user_line['employer_share_rate']
if str(cat).find('employer_share') != -1 and mployer_r not in (None, ''):
new_cell = { "x" : cat
, "y" : salary_range_cat
, "base" : base
, "rate" : mployer_r
}
if str(cat).find('employee_share') != -1 and mployee_r not in (None, ''):
new_cell = { "x" : cat
, "y" : salary_range_cat
, "base" : base
, "rate" : mployee_r
}
# add the cell to the conresponding paysheet item
if new_cell != None:
paysheet_items[service]['cells'].append(new_cell)
# create a paysheet item for each service with user data in it
for item in paysheet_items:
if paysheet_items[item]['cells'] not in ([], None, ''):
#print item
createPaySheetItem ( title = paysheet_items[item]['title']
, res = paysheet_items[item]['res']
, dest_org = paysheet_items[item]['dest_org']
, cells = paysheet_items[item]['cells']
)
# calculation of all paysheet transaction lines
#get_transaction().commit()
#context.PaySheetTransactionLine_generate()
context.immediateReindexObject()
# return to pay sheet
return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=Pay+sheet+calculation+done.')
<?xml version="1.0"?>
<form>
<title>Calculate the Pay Sheet Transaction</title>
<row_length>4</row_length>
<name>PaySheetTransaction_postCalculation</name>
<pt>form_view_dialog</pt>
<action>PaySheetTransaction_postCalculation</action>
<update_action></update_action>
<method>POST</method>
<enctype>multipart/form-data</enctype>
<encoding>UTF-8</encoding>
<stored_encoding>ISO-8859-1</stored_encoding>
<unicode_mode>false</unicode_mode>
<groups>
<group>
<title>left</title>
<fields>
</fields>
</group>
<group>
<title>right</title>
<fields>
</fields>
</group>
<group>
<title>center</title>
<fields>
</fields>
</group>
<group>
<title>bottom</title>
<fields>
<field><id>listbox</id> <type>ListBox</type>
<values>
<all_columns type="list">[('title', 'Tax title'), ('base_name', 'Base name'), ('base', 'Base value'), ('employer_share_rate', 'Employer share rate'), ('employee_share_rate', 'Employee share rate')]</all_columns>
<all_editable_columns type="list">[('base', 'Base value'), ('employer_share_rate', 'Employer share rate'), ('employee_share_rate', 'Employee share rate')]</all_editable_columns>
<alternate_name></alternate_name>
<columns type="list">[('title', 'Tax title'), ('base_name', 'Base name'), ('base', 'Base value'), ('employer_share_rate', 'Employer share rate'), ('employee_share_rate', 'Employee share rate')]</columns>
<css_class></css_class>
<default></default>
<default_params type="list">[]</default_params>
<description></description>
<domain_root_list type="list">[]</domain_root_list>
<domain_tree type="int">0</domain_tree>
<editable type="int">1</editable>
<editable_columns type="list">[('base', 'Base value'), ('employer_share_rate', 'Employer share rate'), ('employee_share_rate', 'Employee share rate')]</editable_columns>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<global_attributes type="list">[]</global_attributes>
<hidden type="int">0</hidden>
<lines type="int">100</lines>
<list_action>folder_contents</list_action>
<list_method type="method">PaySheetTransaction_initializePreview</list_method>
<meta_types type="list">[]</meta_types>
<portal_types type="list">[]</portal_types>
<report_root_list type="list">[]</report_root_list>
<report_tree type="int">0</report_tree>
<search type="int">0</search>
<search_columns type="list">[]</search_columns>
<select type="int">0</select>
<selection_name>pay_sheet_transaction_calcul_preview</selection_name>
<sort type="list">[('title', 'Tax title'), ('base_name', 'Base name')]</sort>
<sort_columns type="list">[]</sort_columns>
<stat_method></stat_method>
<title>listbox</title>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
</messages>
</field>
</fields>
</group>
<group>
<title>hidden</title>
<fields>
<field><id>listbox_title</id> <type>StringField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<display_maxwidth></display_maxwidth>
<display_width type="int">20</display_width>
<editable type="int">0</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<hidden type="int">0</hidden>
<max_length></max_length>
<required type="int">0</required>
<title>Title</title>
<truncate type="int">0</truncate>
<unicode type="int">0</unicode>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="too_long">Too much input was given.</message>
</messages>
</field>
<field><id>listbox_base</id> <type>FloatField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<display_maxwidth></display_maxwidth>
<display_width type="int">15</display_width>
<editable type="int">1</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<hidden type="int">0</hidden>
<required type="int">0</required>
<title>Base value</title>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="not_float">You did not enter a floating point number.</message>
</messages>
</field>
<field><id>listbox_employer_share_rate</id> <type>FloatField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<display_maxwidth></display_maxwidth>
<display_width type="int">10</display_width>
<editable type="int">1</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<hidden type="int">0</hidden>
<required type="int">0</required>
<title>Employer share rate (%)</title>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="not_float">You did not enter a floating point number.</message>
</messages>
</field>
<field><id>listbox_base_name</id> <type>StringField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<display_maxwidth></display_maxwidth>
<display_width type="int">20</display_width>
<editable type="int">0</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<hidden type="int">0</hidden>
<max_length></max_length>
<required type="int">0</required>
<title>Base name</title>
<truncate type="int">0</truncate>
<unicode type="int">0</unicode>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="too_long">Too much input was given.</message>
</messages>
</field>
<field><id>listbox_employee_share_rate</id> <type>FloatField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<display_maxwidth></display_maxwidth>
<display_width type="int">10</display_width>
<editable type="int">1</editable>
<enabled type="int">1</enabled>
<external_validator></external_validator>
<extra></extra>
<hidden type="int">0</hidden>
<required type="int">0</required>
<title>Employee share rate (%)</title>
<whitespace_preserve type="int">0</whitespace_preserve>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="not_float">You did not enter a floating point number.</message>
</messages>
</field>
</fields>
</group>
</groups>
</form>
\ No newline at end of file
## Script (Python) "PaySheet_getReportLines"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
report_items = context.PaySheet_zGetDetailedTotal()
report_lines = []
# scan every sql report item
for item in report_items:
line = { 'title' : None
, 'employer_totalbase' : None
, 'employer_rate' : None
, 'employer_total' : None
, 'employee_totalbase' : None
, 'employee_rate' : None
, 'employee_total' : None
, 'total' : None
}
# sort by employer/salary share
if item['variation_text'].find('employee_share') != -1:
line['title'] = item['parent_title']
line['employee_totalbase'] = item['base']
line['employee_rate'] = item['rate']
line['employee_total'] = item['total_price']
if item['variation_text'].find('employer_share') != -1:
line['title'] = item['parent_title']
line['employer_totalbase'] = item['base']
line['employer_rate'] = item['rate']
line['employer_total'] = item['total_price']
report_lines.append(line)
# scan every line and group them
#here.portal
# first grouping:
return report_lines
<dtml-comment>
title:
connection_id:MySQL
max_rows:1000
max_cache:100
cache_time:0
class_name:
class_file:
</dtml-comment>
<params>year</params>
SELECT
parent.title AS parent_title,
movement.variation_text AS variation_text,
destination.title AS destination_title,
movement.price AS rate,
- SUM(movement.quantity) AS base,
- SUM(movement.total_price) AS total_price
FROM
catalog
LEFT JOIN
movement ON (movement.uid = catalog.uid)
LEFT JOIN
catalog AS destination ON (movement.destination_uid = destination.uid)
LEFT JOIN
catalog AS parent ON (catalog.parent_uid = parent.uid)
WHERE
catalog.portal_type = "Pay Sheet Cell" <dtml-if year>and YEAR(movement.target_stop_date) = <dtml-sqlvar year type="int"> </dtml-if>
GROUP BY
movement.resource_uid, movement.variation_text, movement.price
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<template bottommargin='0.665cm' showboundary='0' topmargin='0.635cm' rightmargin='0.665cm' tal:define='portal python:here.portal_url.getPortalObject()' filename='paysheet.pdf' pagesize='A4' allowsplitting='1' landscape='0' leftmargin='0.635cm'>
<pagetemplate startframe='content' id='FirstPage'>
<static>
<infostring x='3cm' y='3cm'>blabla</infostring>
</static>
<frame showBoundary='0' leftpadding='0.1cm' height='18.14cm' width='19.701cm' rightpadding='0.1cm' y='2.289cm' x='0.635cm' nextid='content' toppadding='0.2cm' id='content' bottompadding='0.5cm'/>
</pagetemplate>
</template>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment