Commit 465de5a5 authored by Rafael Monnerat's avatar Rafael Monnerat 👻

Update from upstream/master

parents a8562e40 9fa162e8
Pipeline #40089 failed with stage
in 0 seconds
Changes Changes
======= =======
0.4.77 (2025-02-18)
-------------------
* testnode:
- fix handling of shebang like '#!/bin/sh -e'
* remove totally webchecker
0.4.76 (2024-05-07) 0.4.76 (2024-05-07)
------------------- -------------------
......
...@@ -163,7 +163,7 @@ class BalanceTransaction(AccountingTransaction, Inventory): ...@@ -163,7 +163,7 @@ class BalanceTransaction(AccountingTransaction, Inventory):
group_by_node=1, group_by_node=1,
group_by_resource=1, group_by_resource=1,
**default_inventory_params): **default_inventory_params):
if inventory.total_price and inventory.total_quantity: if inventory.total_price or inventory.total_quantity:
stock_list.append( stock_list.append(
dict(destination_uid=node_uid, dict(destination_uid=node_uid,
destination_section_uid=section_uid, destination_section_uid=section_uid,
...@@ -193,7 +193,7 @@ class BalanceTransaction(AccountingTransaction, Inventory): ...@@ -193,7 +193,7 @@ class BalanceTransaction(AccountingTransaction, Inventory):
group_by_mirror_section=1, group_by_mirror_section=1,
group_by_resource=1, group_by_resource=1,
**default_inventory_params): **default_inventory_params):
if inventory.total_price and inventory.total_quantity: if inventory.total_price or inventory.total_quantity:
stock_list.append( stock_list.append(
dict(destination_uid=node_uid, dict(destination_uid=node_uid,
destination_section_uid=section_uid, destination_section_uid=section_uid,
...@@ -224,7 +224,7 @@ class BalanceTransaction(AccountingTransaction, Inventory): ...@@ -224,7 +224,7 @@ class BalanceTransaction(AccountingTransaction, Inventory):
group_by_payment=1, group_by_payment=1,
group_by_resource=1, group_by_resource=1,
**default_inventory_params): **default_inventory_params):
if inventory.total_price and inventory.total_quantity: if inventory.total_price or inventory.total_quantity:
stock_list.append( stock_list.append(
dict(destination_uid=node_uid, dict(destination_uid=node_uid,
destination_section_uid=section_uid, destination_section_uid=section_uid,
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
<string>columns</string> <string>columns</string>
<string>count_method</string> <string>count_method</string>
<string>default_params</string> <string>default_params</string>
<string>domain_root_list</string>
<string>domain_tree</string>
<string>editable_columns</string> <string>editable_columns</string>
<string>list_method</string> <string>list_method</string>
<string>portal_types</string> <string>portal_types</string>
...@@ -282,6 +284,21 @@ ...@@ -282,6 +284,21 @@
<list/> <list/>
</value> </value>
</item> </item>
<item>
<key> <string>domain_root_list</string> </key>
<value>
<list>
<tuple>
<string>ledger</string>
<string>Ledger</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>domain_tree</string> </key>
<value> <int>1</int> </value>
</item>
<item> <item>
<key> <string>editable_columns</string> </key> <key> <string>editable_columns</string> </key>
<value> <value>
......
...@@ -2240,6 +2240,160 @@ class TestClosingPeriod(AccountingTestCase): ...@@ -2240,6 +2240,160 @@ class TestClosingPeriod(AccountingTestCase):
balance_transaction.reindexObject() balance_transaction.reindexObject()
self.tic() self.tic()
def test_createBalanceTransactionZeroInAccountingTransactionCurrencyNextYear(self):
pl = self.portal.account_module.newContent(
portal_type='Account', account_type='equity')
bank_account = self.section.newContent(portal_type='Bank Account')
organisation_module = self.organisation_module
period = self.section.newContent(portal_type='Accounting Period')
period.setStartDate(DateTime(2006, 1, 1))
period.setStopDate(DateTime(2006, 12, 31))
self._makeOne(
start_date=DateTime(2006, 1, 1),
title='Yen',
resource='currency_module/yen',
destination_section_value=organisation_module.client_1,
portal_type='Sale Invoice Transaction',
simulation_state='delivered',
lines=(
dict(
source_value=self.account_module.goods_sales,
source_asset_debit=1,
source_debit=70,
),
dict(
source_value=self.account_module.stocks,
source_asset_credit=1,
source_credit=30,
),
# account by node
dict(
source_value=self.account_module.stocks,
source_asset_credit=0,
source_debit=70,
),
# account by mirror_section
dict(
source_value=self.account_module.receivable,
source_asset_credit=0,
source_debit=30,
),
# account by payment
dict(
source_value=self.account_module.bank,
source_payment_value=bank_account,
source_asset_credit=0,
source_credit=100,
),
))
self.tic()
period.AccountingPeriod_createBalanceTransaction(
profit_and_loss_account=pl.getRelativeUrl())
self.tic()
accounting_transaction_list = self.accounting_module.contentValues()
self.assertEqual(2, len(accounting_transaction_list))
balance_transaction, = self.accounting_module.contentValues(
portal_type='Balance Transaction')
self.assertEqual(
self.section, balance_transaction.getDestinationSectionValue())
self.assertEqual(None, balance_transaction.getSourceSection())
self.assertEqual(DateTime(2007, 1, 1), balance_transaction.getStartDate())
self.assertEqual('currency_module/euro', balance_transaction.getResource())
def check_balance_transaction_lines(bt):
self.assertEqual(
sorted(
[
(
line.getDestinationDebit(),
line.getDestinationCredit(),
line.getDestinationInventoriatedTotalAssetDebit(),
line.getDestinationInventoriatedTotalAssetCredit(),
line.getResourceTitle(),
line.getDestinationValue(),
line.getDestinationPaymentValue(),
line.getSourceSectionValue(),
) for line in bt.contentValues()
]), [
(
0.0,
100.0,
0.0,
0.0,
'Yen',
self.account_module.bank,
bank_account,
None,
),
(
1.0,
0.0,
1.0,
0.0,
'Euro',
pl,
None,
None,
),
(
30.0,
0.0,
0.0,
0.0,
'Yen',
self.account_module.receivable,
None,
organisation_module.client_1,
),
(
40.0,
0.0,
0.0,
1.0,
'Yen',
self.portal.account_module.stocks,
None,
None,
),
])
check_balance_transaction_lines(balance_transaction)
q = self.portal.erp5_sql_connection.manage_test
self.assertEqual(
1,
q(
"SELECT count(*) FROM stock WHERE portal_type="
"'Balance Transaction Line'")[0][0])
self.assertEqual(
1,
q(
"SELECT total_price FROM stock WHERE portal_type="
"'Balance Transaction Line'")[0][0])
self.assertEqual(
1,
q(
"SELECT quantity FROM stock WHERE portal_type="
"'Balance Transaction Line'")[0][0])
# next year, if there are no transactions during period, closing should produce
# the same balance transaction.
period_next_year = self.section.newContent(portal_type='Accounting Period')
period_next_year.setStartDate(DateTime(2007, 1, 1))
period_next_year.setStopDate(DateTime(2007, 12, 31))
period_next_year.AccountingPeriod_createBalanceTransaction(
profit_and_loss_account=pl.getRelativeUrl())
accounting_transaction_list = self.accounting_module.contentValues()
self.assertEqual(3, len(accounting_transaction_list))
balance_transaction_next_year, = [bt for bt in self.accounting_module.contentValues(
portal_type='Balance Transaction') if bt != balance_transaction]
check_balance_transaction_lines(balance_transaction_next_year)
# we can reindex again
balance_transaction.reindexObject()
balance_transaction_next_year.reindexObject()
self.tic()
def test_AccountingPeriodWorkflow(self): def test_AccountingPeriodWorkflow(self):
"""Tests that accounting_period_workflow creates a balance transaction. """Tests that accounting_period_workflow creates a balance transaction.
......
...@@ -652,9 +652,7 @@ class TestCurrencyExchangeCell(CurrencyExchangeTestCase): ...@@ -652,9 +652,7 @@ class TestCurrencyExchangeCell(CurrencyExchangeTestCase):
self.tic() self.tic()
# we need a base for asContext, we use the currency, but in real code you context = self._getPriceContext(
# might want to use a more meaningful context.
context = euro.asContext(
categories=['resource/%s' % euro.getRelativeUrl(), categories=['resource/%s' % euro.getRelativeUrl(),
'price_currency/%s' % usd.getRelativeUrl(), 'price_currency/%s' % usd.getRelativeUrl(),
'currency_exchange_type/type_a']) 'currency_exchange_type/type_a'])
......
...@@ -48,7 +48,7 @@ if not shopping_cart_id in session.keys(): ...@@ -48,7 +48,7 @@ if not shopping_cart_id in session.keys():
"Modify portal content", "Modify portal content",
"View"]) "View"])
context.WebSection_updateShoppingCartTradeCondition(shopping_cart, None) context.WebSection_updateShoppingCartTradeCondition(shopping_cart, None)
user = context.ERP5Site_getAuthenticatedMemberPersonValue() user = context.portal_membership.getAuthenticatedMember().getUserValue()
if user: if user:
shopping_cart.setDestinationValue(user) shopping_cart.setDestinationValue(user)
shopping_cart.setPriceCurrency(shopping_cart.getSpecialiseValue().getPriceCurrency()) shopping_cart.setPriceCurrency(shopping_cart.getSpecialiseValue().getPriceCurrency())
......
...@@ -112,6 +112,10 @@ ...@@ -112,6 +112,10 @@
<key> <string>alternate_name</string> </key> <key> <string>alternate_name</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>autocomplete</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>css_class</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -154,6 +158,10 @@ ...@@ -154,6 +158,10 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -267,7 +275,7 @@ ...@@ -267,7 +275,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: here.ERP5Site_getAuthenticatedMemberPersonValue().getDefaultAddressCity() or context.Base_translateString("Missing")</string> </value> <value> <string>python: here.portal_membership.getAuthenticatedMember().getUserValue().getDefaultAddressCity() or context.Base_translateString("Missing")</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -112,6 +112,10 @@ ...@@ -112,6 +112,10 @@
<key> <string>alternate_name</string> </key> <key> <string>alternate_name</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>autocomplete</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>css_class</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -154,6 +158,10 @@ ...@@ -154,6 +158,10 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -267,7 +275,7 @@ ...@@ -267,7 +275,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: here.ERP5Site_getAuthenticatedMemberPersonValue().getDefaultAddressRegionTitle() or context.Base_translateString("Missing")</string> </value> <value> <string>python: here.portal_membership.getAuthenticatedMember().getUserValue().getDefaultAddressRegionTitle() or context.Base_translateString("Missing")</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -112,6 +112,10 @@ ...@@ -112,6 +112,10 @@
<key> <string>alternate_name</string> </key> <key> <string>alternate_name</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>autocomplete</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>css_class</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -154,6 +158,10 @@ ...@@ -154,6 +158,10 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -267,7 +275,7 @@ ...@@ -267,7 +275,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: here.ERP5Site_getAuthenticatedMemberPersonValue().getDefaultAddressStreetAddress() or context.Base_translateString("Missing")</string> </value> <value> <string>python: here.portal_membership.getAuthenticatedMember().getUserValue().getDefaultAddressStreetAddress() or context.Base_translateString("Missing")</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -112,6 +112,10 @@ ...@@ -112,6 +112,10 @@
<key> <string>alternate_name</string> </key> <key> <string>alternate_name</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>autocomplete</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>css_class</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -154,6 +158,10 @@ ...@@ -154,6 +158,10 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -267,7 +275,7 @@ ...@@ -267,7 +275,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: here.ERP5Site_getAuthenticatedMemberPersonValue().getDefaultAddressZipCode() or context.Base_translateString("Missing")</string> </value> <value> <string>python: here.portal_membership.getAuthenticatedMember().getUserValue().getDefaultAddressZipCode() or context.Base_translateString("Missing")</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -112,6 +112,10 @@ ...@@ -112,6 +112,10 @@
<key> <string>alternate_name</string> </key> <key> <string>alternate_name</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>autocomplete</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>css_class</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -154,6 +158,10 @@ ...@@ -154,6 +158,10 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -267,7 +275,7 @@ ...@@ -267,7 +275,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: here.ERP5Site_getAuthenticatedMemberPersonValue().getDefaultEmailText() or context.Base_translateString("Missing")</string> </value> <value> <string>python: here.portal_membership.getAuthenticatedMember().getUserValue().getDefaultEmailText() or context.Base_translateString("Missing")</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -112,6 +112,10 @@ ...@@ -112,6 +112,10 @@
<key> <string>alternate_name</string> </key> <key> <string>alternate_name</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>autocomplete</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>css_class</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -156,6 +160,10 @@ ...@@ -156,6 +160,10 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -269,7 +277,7 @@ ...@@ -269,7 +277,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: here.ERP5Site_getAuthenticatedMemberPersonValue().getDefaultTelephoneText()</string> </value> <value> <string>python: here.portal_membership.getAuthenticatedMember().getUserValue().getDefaultTelephoneText()</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
...@@ -282,7 +290,7 @@ ...@@ -282,7 +290,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: here.ERP5Site_getAuthenticatedMemberPersonValue().getDefaultTelephoneText() is not None</string> </value> <value> <string>python: here.portal_membership.getAuthenticatedMember().getUserValue().getDefaultTelephoneText() is not None</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -112,6 +112,10 @@ ...@@ -112,6 +112,10 @@
<key> <string>alternate_name</string> </key> <key> <string>alternate_name</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>autocomplete</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>css_class</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -154,6 +158,10 @@ ...@@ -154,6 +158,10 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -267,7 +275,7 @@ ...@@ -267,7 +275,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: here.ERP5Site_getAuthenticatedMemberPersonValue().getTitle() or context.Base_translateString("Missing")</string> </value> <value> <string>python: here.portal_membership.getAuthenticatedMember().getUserValue().getTitle() or context.Base_translateString("Missing")</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -23,7 +23,7 @@ if sale_order.getSimulationState() == "draft": ...@@ -23,7 +23,7 @@ if sale_order.getSimulationState() == "draft":
for amount in sale_order.getAggregatedAmountList(): for amount in sale_order.getAggregatedAmountList():
if 'base_amount/loyalty_program/using_point' in amount.getBaseApplicationList(): if 'base_amount/loyalty_program/using_point' in amount.getBaseApplicationList():
user = context.ERP5Site_getAuthenticatedMemberPersonValue() user = context.portal_membership.getAuthenticatedMember().getUserValue()
loyalty_transaction = context.loyalty_transaction_module.newContent( loyalty_transaction = context.loyalty_transaction_module.newContent(
portal_type='Loyalty Transaction', portal_type='Loyalty Transaction',
destination_section_value=user, destination_section_value=user,
......
import random import random
translateString = context.Base_translateString translateString = context.Base_translateString
person = context.ERP5Site_getAuthenticatedMemberPersonValue() person = context.portal_membership.getAuthenticatedMember().getUserValue()
if person is None: if person is None:
......
...@@ -12,7 +12,7 @@ reference='no_loyalty_reward' ...@@ -12,7 +12,7 @@ reference='no_loyalty_reward'
if context.REQUEST.get("loyalty_reward", "") == "enable" and context.getSiteLoyaltyExplanationTemplate(): if context.REQUEST.get("loyalty_reward", "") == "enable" and context.getSiteLoyaltyExplanationTemplate():
# this is double check. # this is double check.
# a trade condition should properly configured for anonymous # a trade condition should properly configured for anonymous
if context.ERP5Site_getAuthenticatedMemberPersonValue(): if context.portal_membership.getAuthenticatedMember().getUserValue():
reference= 'loyalty_reward' reference= 'loyalty_reward'
if payment_mode: if payment_mode:
......
<tal:block tal:define="enable_reward_discount python: request.get('loyalty_reward', '') == 'enable';"> <tal:block tal:define="enable_reward_discount python: request.get('loyalty_reward', '') == 'enable';">
<div class="promotional_information" tal:condition="python: here.ERP5Site_getAuthenticatedMemberPersonValue() and here.getSiteLoyaltyExplanationTemplate()"> <div class="promotional_information" tal:condition="python: here.portal_membership.getAuthenticatedMember().getUserValue() and here.getSiteLoyaltyExplanationTemplate()">
<tal:block tal:condition="python: here.ERP5Site_getAuthenticatedMemberPersonValue().Person_getTotalLoyaltyPoint() >= 0"> <tal:block tal:condition="python: here.portal_membership.getAuthenticatedMember().getUserValue().Person_getTotalLoyaltyPoint() >= 0">
<span i18n:translate="" i18n:domain="ui">You should overwrite this page template.</span> <span i18n:translate="" i18n:domain="ui">You should overwrite this page template.</span>
<br /> <br />
<a tal:condition="python: enable_reward_discount" <a tal:condition="python: enable_reward_discount"
......
<tal:block tal:define="isAnon here/portal_membership/isAnonymousUser"> <tal:block tal:define="isAnon here/portal_membership/isAnonymousUser">
<tal:block tal:condition="not: isAnon" <tal:block tal:condition="not: isAnon"
tal:define="customer here/ERP5Site_getAuthenticatedMemberPersonValue; tal:define="customer python: here.portal_membership.getAuthenticatedMember().getUserValue();
login customer/getReference | string: ; login customer/getReference | string: ;
website here/getWebSiteValue"> website here/getWebSiteValue">
......
...@@ -314,7 +314,7 @@ ...@@ -314,7 +314,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: not here.getPortalObject().portal_membership.isAnonymousUser() and here.ERP5Site_getAuthenticatedMemberPersonValue().checkConsistency()</string> </value> <value> <string>python: not here.getPortalObject().portal_membership.isAnonymousUser() and here.portal_membership.getAuthenticatedMember().getUserValue().checkConsistency()</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -197,7 +197,7 @@ ...@@ -197,7 +197,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: not here.getPortalObject().portal_membership.isAnonymousUser() and not here.SaleOrder_isShoppingCartEmpty() and len(here.ERP5Site_getAuthenticatedMemberPersonValue().checkConsistency()) == 0 and here.SaleOrder_getSelectedShippingResource() is not None</string> </value> <value> <string>python: not here.getPortalObject().portal_membership.isAnonymousUser() and not here.SaleOrder_isShoppingCartEmpty() and len(here.portal_membership.getAuthenticatedMember().getUserValue().checkConsistency()) == 0 and here.SaleOrder_getSelectedShippingResource() is not None</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -199,7 +199,7 @@ ...@@ -199,7 +199,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: not here.getPortalObject().portal_membership.isAnonymousUser() and not here.SaleOrder_isShoppingCartEmpty() and len(here.ERP5Site_getAuthenticatedMemberPersonValue().checkConsistency())</string> </value> <value> <string>python: not here.getPortalObject().portal_membership.isAnonymousUser() and not here.SaleOrder_isShoppingCartEmpty() and len(here.portal_membership.getAuthenticatedMember().getUserValue().checkConsistency())</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
...@@ -212,7 +212,7 @@ ...@@ -212,7 +212,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: "%s:method" % here.ERP5Site_getAuthenticatedMemberPersonValue().getRelativeUrl()</string> </value> <value> <string>python: "%s:method" % here.portal_membership.getAuthenticatedMember().getUserValue().getRelativeUrl()</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -311,7 +311,7 @@ ...@@ -311,7 +311,7 @@
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
python: "<a href=%s/person_module/%s?login_come_from_url=%s> %s </a>" % (context.getWebSiteValue().absolute_url(),context.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue().getId(), context.getWebSectionValue().absolute_url(), context.Base_translateString("Change your informations")) python: "<a href=%s/person_module/%s?login_come_from_url=%s> %s </a>" % (context.getWebSiteValue().absolute_url(),context.getPortalObject().portal_membership.getAuthenticatedMember().getUserValue().getId(), context.getWebSectionValue().absolute_url(), context.Base_translateString("Change your informations"))
]]></string> </value> ]]></string> </value>
</item> </item>
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
</tal:block> </tal:block>
<tal:block tal:condition="not: isAnon" <tal:block tal:condition="not: isAnon"
tal:define="customer here/ERP5Site_getAuthenticatedMemberPersonValue; tal:define="customer python: here.portal_membership.getAuthenticatedMember().getUserValue();
login customer/getReference | string: ; login customer/getReference | string: ;
website here/getWebSiteValue"> website here/getWebSiteValue">
......
payment_mode = payment_mode.lower() payment_mode = payment_mode.lower()
person = context.ERP5Site_getAuthenticatedMemberPersonValue() person = context.portal_membership.getAuthenticatedMember().getUserValue()
sale_order = context.WebSection_persistShoppingCart(shopping_cart, person) sale_order = context.WebSection_persistShoppingCart(shopping_cart, person)
if payment_mode == 'paypal': if payment_mode == 'paypal':
......
erp5_advanced_ecommerce erp5_advanced_ecommerce
erp5_ui_test_core erp5_ui_test_core
erp5_configurator_standard_categories
erp5_configurator_standard_trade_template erp5_configurator_standard_trade_template
erp5_simulation_test erp5_simulation_test
\ No newline at end of file
"""This script is used to know if quantity can be edited by user.
* If this is not a movement (line containing lines or cell), user
cannot edit this line which is just a container, but no actual movement.
* If items are used, quantity is set by the item quantity.
"""
if not context.isMovement():
return False
return not (context.getResource() and context.getResourceValue().getAggregatedPortalTypeList())
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Movement_isQuantityEditable</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -23,6 +23,12 @@ def sort_key(exchange_line): ...@@ -23,6 +23,12 @@ def sort_key(exchange_line):
if movement is None: if movement is None:
return context.Resource_getPriceCalculationOperandDict(**kw) return context.Resource_getPriceCalculationOperandDict(**kw)
else: else:
portal = context.getPortalObject()
if (not movement.hasResource()
and movement.getPortalType() in portal.getPortalInvoiceMovementTypeList()):
# XXX Invoice have a currency as resource and this resource is acquired on lines, but we don't want
# to lookup a price using the currency exchange line for such lines.
return None
if validation_state is None: if validation_state is None:
validation_state = 'validated' validation_state = 'validated'
kw.setdefault('portal_type', 'Currency Exchange Line') kw.setdefault('portal_type', 'Currency Exchange Line')
...@@ -31,7 +37,7 @@ else: ...@@ -31,7 +37,7 @@ else:
# and that searchPredicateList does not accept. # and that searchPredicateList does not accept.
kw.pop('categories', None) kw.pop('categories', None)
predicate_list = context.portal_domains.searchPredicateList( predicate_list = portal.portal_domains.searchPredicateList(
context=movement, context=movement,
validation_state=validation_state, validation_state=validation_state,
test=True, test=True,
......
erp5_trade erp5_trade
erp5_base erp5_base
erp5_configurator_standard_categories \ No newline at end of file
\ No newline at end of file
...@@ -2,4 +2,5 @@ erp5_commerce_loyalty_program ...@@ -2,4 +2,5 @@ erp5_commerce_loyalty_program
erp5_simulation_test erp5_simulation_test
erp5_configurator_standard_trade_template erp5_configurator_standard_trade_template
erp5_configurator_standard_invoicing_template erp5_configurator_standard_invoicing_template
erp5_configurator_standard_categories
erp5_simplified_invoicing erp5_simplified_invoicing
\ No newline at end of file
...@@ -7211,6 +7211,53 @@ class TestBusinessTemplate(BusinessTemplateMixin): ...@@ -7211,6 +7211,53 @@ class TestBusinessTemplate(BusinessTemplateMixin):
self.assertEqual(module_content_uid, self.portal.geek_module['1'].uid) self.assertEqual(module_content_uid, self.portal.geek_module['1'].uid)
self.assertEqual('kept', self.portal.geek_module['1'].title) self.assertEqual('kept', self.portal.geek_module['1'].title)
def test_update_business_template_with_module_removed(self):
"""Updating business template with a module removed keeps the module if it contains documents
"""
self.portal.newContent(
portal_type='Person Module',
id='kept_module',
).newContent(
portal_type='Person',
id='keep',
)
self.portal.newContent(portal_type='Person Module', id='removed_module')
self.tic()
# install a bt containing two modules
bt = self.portal.portal_templates.newContent(
portal_type='Business Template',
title=self.id(),
template_module_id_list=['kept_module', 'removed_module'])
bt.build()
self.tic()
bt.install()
self.tic()
# in next version, both modules are removed
bt = self.portal.portal_templates.newContent(
portal_type='Business Template',
title=self.id(),
)
bt.build()
self.tic()
export_dir = tempfile.mkdtemp()
try:
bt.export(path=export_dir, local=True)
self.tic()
new_bt = self.portal.portal_templates.download(
url='file://%s' % export_dir)
finally:
shutil.rmtree(export_dir)
self.assertEqual(
new_bt.preinstall(),
{
'removed_module': ('Removed', 'Module'),
'kept_module': ('Removed but should be kept', 'Module'),
})
def test_BusinessTemplateWithTest(self): def test_BusinessTemplateWithTest(self):
sequence_list = SequenceList() sequence_list = SequenceList()
sequence_string = '\ sequence_string = '\
......
...@@ -74,6 +74,10 @@ class TestDateUtils(unittest.TestCase): ...@@ -74,6 +74,10 @@ class TestDateUtils(unittest.TestCase):
addToDate(march_31, month=1).toZone('UTC').ISO()) addToDate(march_31, month=1).toZone('UTC').ISO())
self.assertEqual(DateTime('2001/05/1 %s' % self.timezone).toZone('UTC').ISO(), self.assertEqual(DateTime('2001/05/1 %s' % self.timezone).toZone('UTC').ISO(),
addToDate(march_31, month=1, day=1).toZone('UTC').ISO()) addToDate(march_31, month=1, day=1).toZone('UTC').ISO())
self.assertEqual(DateTime('2001/05/1 %s' % self.timezone).toZone('UTC').ISO(),
addToDate(march_31, month=1, hour=24).toZone('UTC').ISO())
self.assertEqual(DateTime('2001/05/1 %s' % self.timezone).toZone('UTC').ISO(),
addToDate(march_31, hour=24*31).toZone('UTC').ISO())
def test_negative_add_to_date(self): def test_negative_add_to_date(self):
date = DateTime('2000/01/01 %s' % self.timezone) date = DateTime('2000/01/01 %s' % self.timezone)
...@@ -97,6 +101,10 @@ class TestDateUtils(unittest.TestCase): ...@@ -97,6 +101,10 @@ class TestDateUtils(unittest.TestCase):
may_31 = DateTime('2000/05/31 %s' % self.timezone) may_31 = DateTime('2000/05/31 %s' % self.timezone)
self.assertEqual(DateTime('2000/04/30 %s' % self.timezone).toZone('UTC').ISO(), self.assertEqual(DateTime('2000/04/30 %s' % self.timezone).toZone('UTC').ISO(),
addToDate(may_31, month=-1).toZone('UTC').ISO()) addToDate(may_31, month=-1).toZone('UTC').ISO())
self.assertEqual(DateTime('2001/02/27 %s' % self.timezone).toZone('UTC').ISO(),
addToDate(march_31, month=-1, hour=-24).toZone('UTC').ISO())
self.assertEqual(DateTime('2001/02/27 %s' % self.timezone).toZone('UTC').ISO(),
addToDate(march_31, hour=-24*32).toZone('UTC').ISO())
def test_float_add_to_date(self): def test_float_add_to_date(self):
date = DateTime('2000/01/01 %s' % self.timezone) date = DateTime('2000/01/01 %s' % self.timezone)
......
...@@ -13,6 +13,7 @@ if portal_type_list: ...@@ -13,6 +13,7 @@ if portal_type_list:
searchAndActivate( searchAndActivate(
portal_type=portal_type_list, portal_type=portal_type_list,
validation_state='submitted', validation_state='submitted',
activate_kw={'tag': tag}
) )
credential_update_destination_decision_portal_type_list = [] credential_update_destination_decision_portal_type_list = []
...@@ -25,4 +26,9 @@ if credential_update_destination_decision_portal_type_list: ...@@ -25,4 +26,9 @@ if credential_update_destination_decision_portal_type_list:
portal_type='Credential Update', portal_type='Credential Update',
destination_decision_portal_type=credential_update_destination_decision_portal_type_list, destination_decision_portal_type=credential_update_destination_decision_portal_type_list,
validation_state='submitted', validation_state='submitted',
activate_kw={'tag': tag}
) )
# Do not prevent the alarm to run again if one activity fails
# Fixing this requires to review the credential scripts
# context.activate(after_tag=tag).getId()
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string>tag, fixit, params</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -7333,6 +7333,9 @@ msgstr "Mouvements" ...@@ -7333,6 +7333,9 @@ msgstr "Mouvements"
msgid "Multiple (${document_count}) documents ${document_reference} - ${document_language} - ${document_version} already exists." msgid "Multiple (${document_count}) documents ${document_reference} - ${document_language} - ${document_version} already exists."
msgstr "Plusieurs (${document_count}) documents ${document_reference} - ${document_language} - ${document_version} existent déjà." msgstr "Plusieurs (${document_count}) documents ${document_reference} - ${document_language} - ${document_version} existent déjà."
msgid "My Account"
msgstr "Mon compte"
msgid "My Contacts" msgid "My Contacts"
msgstr "Mes contacts" msgstr "Mes contacts"
......
...@@ -135,11 +135,11 @@ ...@@ -135,11 +135,11 @@
<string>Sender or Provider</string> <string>Sender or Provider</string>
</tuple> </tuple>
<tuple> <tuple>
<string>start_date_range_min</string> <string>predicate.start_date_range_min</string>
<string>Valid from</string> <string>Valid from</string>
</tuple> </tuple>
<tuple> <tuple>
<string>start_date_range_max</string> <string>predicate.start_date_range_max</string>
<string>Valid until</string> <string>Valid until</string>
</tuple> </tuple>
<tuple> <tuple>
...@@ -238,6 +238,14 @@ ...@@ -238,6 +238,14 @@
<string>modification_date</string> <string>modification_date</string>
<string>Modification Date</string> <string>Modification Date</string>
</tuple> </tuple>
<tuple>
<string>predicate.start_date_range_min</string>
<string>Valid from</string>
</tuple>
<tuple>
<string>predicate.start_date_range_max</string>
<string>Valid until</string>
</tuple>
</list> </list>
</value> </value>
</item> </item>
...@@ -300,6 +308,14 @@ ...@@ -300,6 +308,14 @@
<string>modification_date</string> <string>modification_date</string>
<string>Modification Date</string> <string>Modification Date</string>
</tuple> </tuple>
<tuple>
<string>predicate.start_date_range_min</string>
<string>Valid from</string>
</tuple>
<tuple>
<string>predicate.start_date_range_max</string>
<string>Valid until</string>
</tuple>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -109,11 +109,11 @@ ...@@ -109,11 +109,11 @@
<string>Recipient or Beneficiary</string> <string>Recipient or Beneficiary</string>
</tuple> </tuple>
<tuple> <tuple>
<string>start_date_range_min</string> <string>predicate.start_date_range_min</string>
<string>Valid from</string> <string>Valid from</string>
</tuple> </tuple>
<tuple> <tuple>
<string>start_date_range_max</string> <string>predicate.start_date_range_max</string>
<string>Valid until</string> <string>Valid until</string>
</tuple> </tuple>
<tuple> <tuple>
......
...@@ -84,8 +84,8 @@ ...@@ -84,8 +84,8 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <value>
<list> <list>
<string>listbox_start_date_range_max</string> <string>listbox_predicate_start_date_range_max</string>
<string>listbox_start_date_range_min</string> <string>listbox_predicate_start_date_range_min</string>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>listbox_start_date_range_max</string> </value> <value> <string>listbox_predicate_start_date_range_max</string> </value>
</item> </item>
<item> <item>
<key> <string>message_values</string> </key> <key> <string>message_values</string> </key>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>listbox_start_date_range_min</string> </value> <value> <string>listbox_predicate_start_date_range_min</string> </value>
</item> </item>
<item> <item>
<key> <string>message_values</string> </key> <key> <string>message_values</string> </key>
......
...@@ -74,8 +74,8 @@ ...@@ -74,8 +74,8 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <value>
<list> <list>
<string>listbox_start_date_range_max</string> <string>listbox_predicate_start_date_range_max</string>
<string>listbox_start_date_range_min</string> <string>listbox_predicate_start_date_range_min</string>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<key> <string>delegated_list</string> </key> <key> <string>delegated_list</string> </key>
<value> <value>
<list> <list>
<string>editable_columns</string> <string>sort</string>
</list> </list>
</value> </value>
</item> </item>
...@@ -77,21 +77,6 @@ ...@@ -77,21 +77,6 @@
<list/> <list/>
</value> </value>
</item> </item>
<item>
<key> <string>editable_columns</string> </key>
<value>
<list>
<tuple>
<string>start_date_range_min</string>
<string>Valid from</string>
</tuple>
<tuple>
<string>start_date_range_max</string>
<string>Valid until</string>
</tuple>
</list>
</value>
</item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>field_id</string> </key>
<value> <string>my_purchase_supplies_listbox</string> </value> <value> <string>my_purchase_supplies_listbox</string> </value>
...@@ -100,6 +85,12 @@ ...@@ -100,6 +85,12 @@
<key> <string>form_id</string> </key> <key> <string>form_id</string> </key>
<value> <string>Base_viewPDMFieldLibrary</string> </value> <value> <string>Base_viewPDMFieldLibrary</string> </value>
</item> </item>
<item>
<key> <string>sort</string> </key>
<value>
<list/>
</value>
</item>
<item> <item>
<key> <string>target</string> </key> <key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value> <value> <string>Click to edit the target</string> </value>
......
...@@ -6,9 +6,15 @@ ...@@ -6,9 +6,15 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>listbox_start_date_range_max</string> </value> <value> <string>listbox_predicate_start_date_range_max</string> </value>
</item> </item>
<item> <item>
<key> <string>message_values</string> </key> <key> <string>message_values</string> </key>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>listbox_start_date_range_min</string> </value> <value> <string>listbox_predicate_start_date_range_min</string> </value>
</item> </item>
<item> <item>
<key> <string>message_values</string> </key> <key> <string>message_values</string> </key>
......
...@@ -74,8 +74,8 @@ ...@@ -74,8 +74,8 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <value>
<list> <list>
<string>listbox_start_date_range_max</string> <string>listbox_predicate_start_date_range_max</string>
<string>listbox_start_date_range_min</string> <string>listbox_predicate_start_date_range_min</string>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>listbox_start_date_range_max</string> </value> <value> <string>listbox_predicate_start_date_range_max</string> </value>
</item> </item>
<item> <item>
<key> <string>message_values</string> </key> <key> <string>message_values</string> </key>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>listbox_start_date_range_min</string> </value> <value> <string>listbox_predicate_start_date_range_min</string> </value>
</item> </item>
<item> <item>
<key> <string>message_values</string> </key> <key> <string>message_values</string> </key>
......
...@@ -1499,6 +1499,51 @@ self.portal.getDefaultModule(self.packing_list_portal_type).newContent( ...@@ -1499,6 +1499,51 @@ self.portal.getDefaultModule(self.packing_list_portal_type).newContent(
sale_invoice_brain, = self.portal.portal_catalog(uid=sale_invoice.getUid(), select_list=["specialise_trade_condition_title"], limit=1) sale_invoice_brain, = self.portal.portal_catalog(uid=sale_invoice.getUid(), select_list=["specialise_trade_condition_title"], limit=1)
self.assertEqual(sale_invoice_brain.specialise_trade_condition_title, trade_condition_title) self.assertEqual(sale_invoice_brain.specialise_trade_condition_title, trade_condition_title)
def test_invoice_movement_getPrice(self):
resource = self.portal.product_module.newContent(
portal_type='Product',
title='Resource %s' % self.id(),
)
resource.setSaleSupplyLineBasePrice(123)
resource.setPurchaseSupplyLineBasePrice(123)
currency = self.portal.currency_module.newContent(
portal_type='Currency', title='Currency %s' % self.id())
currency.newContent(
portal_type='Currency Exchange Line',
price_currency_value=currency,
base_price=1,
).validate()
client = self.portal.organisation_module.newContent(
portal_type='Organisation', title='Client')
vendor = self.portal.organisation_module.newContent(
portal_type='Organisation', title='Vendor')
self.tic()
invoice = self.portal.accounting_module.newContent(
portal_type=self.invoice_portal_type,
source_value=vendor,
source_section_value=vendor,
destination_value=client,
destination_section_value=client,
start_date=DateTime(2008, 10, 21),
price_currency_value=currency,
resource_value=currency,
)
invoice_line = invoice.newContent(
portal_type=self.invoice_line_portal_type,
resource_value=resource,
quantity=1)
self.assertEqual(invoice_line.getPrice(), 123)
invoice_line_without_resource = invoice.newContent(
portal_type=self.invoice_line_portal_type, quantity=1)
self.assertIsNone(invoice_line_without_resource.getPrice())
invoice_cell_without_resource = invoice_line_without_resource.newContent(
portal_type=self.invoice_line_portal_type, quantity=1)
self.assertIsNone(invoice_cell_without_resource.getPrice())
class TestSaleInvoice(TestSaleInvoiceMixin, TestInvoice, ERP5TypeTestCase): class TestSaleInvoice(TestSaleInvoiceMixin, TestInvoice, ERP5TypeTestCase):
"""Tests for sale invoice. """Tests for sale invoice.
""" """
......
"""This script is used to know if quantity can be edited by user. """
This script is used to know if quantity can be edited by user.
* If this is not a movement (line containing lines or cell), user
cannot edit this line which is just a container, but no actual movement.
* If this line has variation category list, then it means it's a line that * If quantity is not enabled on the movement, quantity cannot be set.
will contain cell, so it's already not possible to set quantity, user have
to create cells and set quantities on cells.
* If items are used, quantity is set by the item quantity. * If items are required, quantity is set by the item quantity.
""" """
if not context.isMovement(): if not context.Movement_isQuantityEnabled():
return False
if context.getVariationCategoryList(omit_optional_variation=1) and not 'Cell' in context.getPortalType():
return False return False
return not (context.getResource() and context.getResourceValue().getAggregatedPortalTypeList()) return not (context.getResource() and context.getResourceValue().getRequiredAggregatedPortalTypeList())
return context.isMovement() and not context.getVariationCategoryList() """
This script is used to know if quantity should be shown to the user. Usually, not showing quantity happens when a total quantity is shown instead, meaning the line uses cells.
* If this is not a movement (line containing lines or cell), user cannot see quantity for this line which is just a container, but no actual movement.
* If this line has required variation category list, then it means it's a line that will contain cell, so total quantity will be used instead.
* If this line has optional variation category list, and already contain cells, total quantity should also be used.
"""
if not context.isMovement():
return False
if not 'Cell' in context.getPortalType() and \
(context.getVariationCategoryList(omit_optional_variation=1) or \
context.hasCellContent(base_id='movement')):
return False
return True
...@@ -37,16 +37,15 @@ ...@@ -37,16 +37,15 @@
hour = minute * 60, hour = minute * 60,
day = hour * 24, day = hour * 24,
week = day * 7, week = day * 7,
year = day * 365,
time_format = new Intl.RelativeTimeFormat(language); time_format = new Intl.RelativeTimeFormat(language);
diff = date.getFullYear() - current_date.getFullYear();
if (diff !== 0) {
return time_format.format(diff, 'year');
}
diff = date - current_date; diff = date - current_date;
abs = Math.abs(diff); abs = Math.abs(diff);
// "year", "quarter", "month", "week", "day", "hour", "minute", "second" // "year", "quarter", "month", "week", "day", "hour", "minute", "second"
if (abs > year) {
return time_format.format(Math.floor(diff / year), 'year');
}
if (abs > (week * 2)) { if (abs > (week * 2)) {
return time_format.format(Math.floor(diff / week), 'week'); return time_format.format(Math.floor(diff / week), 'week');
} }
......
...@@ -238,7 +238,7 @@ ...@@ -238,7 +238,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1017.21412.29767.13277</string> </value> <value> <string>1017.42673.18426.35652</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -258,7 +258,7 @@ ...@@ -258,7 +258,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1718640624.19</float> <float>1735815864.25</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -38,7 +38,7 @@ from slapos.grid.utils import md5digest ...@@ -38,7 +38,7 @@ from slapos.grid.utils import md5digest
def dealShebang(run_test_suite_path): def dealShebang(run_test_suite_path):
with open(run_test_suite_path) as f: with open(run_test_suite_path) as f:
if f.read(2) == '#!': if f.read(2) == '#!':
return f.readline().split(None, 1) return f.readline().rstrip().split(None, 1)
return [] return []
class UnitTestRunner(object): class UnitTestRunner(object):
......
...@@ -426,9 +426,13 @@ CREATE TABLE %s ( ...@@ -426,9 +426,13 @@ CREATE TABLE %s (
0, 0,
)[1] )[1]
else: else:
# MariaDB often choose processing_node_priority_date index
# but node2_priority_date is much faster if there exist
# many node < 0 non-groupable activities.
subquery = lambda *a, **k: str2bytes(bytes2str(b"(" subquery = lambda *a, **k: str2bytes(bytes2str(b"("
b"SELECT 3*priority{} AS effective_priority, date" b"SELECT 3*priority{} AS effective_priority, date"
b" FROM %s" b" FROM %s"
b" FORCE INDEX (node2_priority_date)"
b" WHERE" b" WHERE"
b" {} AND" b" {} AND"
b" processing_node=0 AND" b" processing_node=0 AND"
...@@ -781,9 +785,17 @@ CREATE TABLE %s ( ...@@ -781,9 +785,17 @@ CREATE TABLE %s (
0, 0,
)) ))
else: else:
if group_method_id:
force_index = ''
else:
# MariaDB often choose processing_node_priority_date index
# but node2_priority_date is much faster if there exist
# many node < 0 non-groupable activities.
force_index = b'FORCE INDEX (node2_priority_date)'
subquery = lambda *a, **k: str2bytes(bytes2str(b"(" subquery = lambda *a, **k: str2bytes(bytes2str(b"("
b"SELECT *, 3*priority{} AS effective_priority" b"SELECT *, 3*priority{} AS effective_priority"
b" FROM %s" b" FROM %s"
b" {}"
b" WHERE" b" WHERE"
b" {} AND" b" {} AND"
b" processing_node=0 AND" b" processing_node=0 AND"
...@@ -799,11 +811,11 @@ CREATE TABLE %s ( ...@@ -799,11 +811,11 @@ CREATE TABLE %s (
b" UNION ALL ".join( b" UNION ALL ".join(
chain( chain(
( (
subquery('-1', 'node = %i' % processing_node), subquery('-1', force_index, 'node = %i' % processing_node),
subquery('', 'node=0'), subquery('', force_index, 'node=0'),
), ),
( (
subquery('-1', 'node = %i' % x) subquery('-1', force_index, 'node = %i' % x)
for x in node_set for x in node_set
), ),
), ),
...@@ -821,7 +833,7 @@ CREATE TABLE %s ( ...@@ -821,7 +833,7 @@ CREATE TABLE %s (
# sorted set to filter negative node values. # sorted set to filter negative node values.
# This is why this query is only executed when the previous one # This is why this query is only executed when the previous one
# did not find anything. # did not find anything.
result = Results(query(subquery('+1', 'node>0'), 0)) result = Results(query(subquery('+1', force_index, 'node>0'), 0))
if result: if result:
# Reserve messages. # Reserve messages.
uid_list = [x.uid for x in result] uid_list = [x.uid for x in result]
......
...@@ -3775,6 +3775,20 @@ class ModuleTemplateItem(BaseTemplateItem): ...@@ -3775,6 +3775,20 @@ class ModuleTemplateItem(BaseTemplateItem):
xml_data = self.generateXml(path=key) xml_data = self.generateXml(path=key)
bta.addObject(xml_data, name=key, path=path) bta.addObject(xml_data, name=key, path=path)
def preinstall(self, context, installed_item, **kw):
"""Keep modules when they are not empty.
"""
_modified_object_dict = super(ModuleTemplateItem, self).preinstall(context, installed_item, **kw)
portal = context.getPortalObject()
modified_object_dict = {}
for module_id, (action, item_class) in _modified_object_dict.items():
if action == 'Removed':
module = portal._getOb(module_id, None)
if module is not None and len(module.objectValues()):
action = 'Removed but should be kept'
modified_object_dict[module_id] = (action, item_class)
return modified_object_dict
def install(self, context, trashbin, **kw): def install(self, context, trashbin, **kw):
portal = context.getPortalObject() portal = context.getPortalObject()
update_dict = kw.get('object_to_update') update_dict = kw.get('object_to_update')
......
...@@ -109,9 +109,8 @@ def addToDate(date, to_add=None, **kw): ...@@ -109,9 +109,8 @@ def addToDate(date, to_add=None, **kw):
return_value[key] = return_value[key] - number_of_in_dict[key] return_value[key] = return_value[key] - number_of_in_dict[key]
return_value[larger_key_dict[key]] = return_value[larger_key_dict[key]] + 1 return_value[larger_key_dict[key]] = return_value[larger_key_dict[key]] + 1
month_in_to_add = to_add.get('month', None)
for key in key_list: for key in key_list:
if key == 'day':
continue
if to_add.get(key, None) is not None: if to_add.get(key, None) is not None:
return_value[key] = return_value[key] + to_add[key] return_value[key] = return_value[key] + to_add[key]
del to_add[key] del to_add[key]
...@@ -126,13 +125,7 @@ def addToDate(date, to_add=None, **kw): ...@@ -126,13 +125,7 @@ def addToDate(date, to_add=None, **kw):
for local_key in return_value.keys(): for local_key in return_value.keys():
if local_key not in ('day', 'year'): if local_key not in ('day', 'year'):
treatPositiveValues(return_value, local_key) treatPositiveValues(return_value, local_key)
day_to_add = return_value['day'] - 1
day_to_add = min(
return_value['day'],
getNumberOfDayInMonth(
DateTime(return_value['year'], int(return_value['month']), 1)
)
) - 1
if to_add.get('day', None) is not None: if to_add.get('day', None) is not None:
day_to_add += to_add['day'] day_to_add += to_add['day']
return_value['day'] = 1 return_value['day'] = 1
...@@ -143,6 +136,9 @@ def addToDate(date, to_add=None, **kw): ...@@ -143,6 +136,9 @@ def addToDate(date, to_add=None, **kw):
return_value['minute'], return_value['minute'],
return_value['second'], return_value['second'],
date.timezone())) date.timezone()))
overflow_day = date.day() - getNumberOfDayInMonth(return_date)
if (month_in_to_add is not None) and (overflow_day > 0):
day_to_add -= overflow_day
return_date += day_to_add return_date += day_to_add
return return_date return return_date
......
...@@ -2,7 +2,7 @@ from setuptools import setup, find_packages ...@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
import glob import glob
import os import os
version = '0.4.76' version = '0.4.77'
name = 'erp5.util' name = 'erp5.util'
long_description = open("README.erp5.util.txt").read() + "\n" long_description = open("README.erp5.util.txt").read() + "\n"
......
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