diff --git a/configuration.py b/configuration.py index c82963c..5abe8ea 100644 --- a/configuration.py +++ b/configuration.py @@ -3,6 +3,8 @@ # the full copyright notices and license terms. from trytond.model import fields from trytond.pool import Pool, PoolMeta +from trytond.i18n import gettext +from trytond.exceptions import UserError __all__ = ['Configuration', 'ConfigurationSaleMethod'] @@ -29,6 +31,31 @@ class Configuration(metaclass=PoolMeta): return cls.multivalue_model( 'sale_margin_method').default_sale_margin_method() + @classmethod + def __setup__(cls): + super(Configuration, cls).__setup__() + cls._modify_no_sale = [ + ('sale_margin_method', 'change_sale_margin_method'), + ] + + @classmethod + def write(cls, *args): + actions = iter(args) + for _, values in zip(actions, actions): + for field, error in cls._modify_no_sale: + if field in values: + cls.check_no_sale(error) + break + super(Configuration, cls).write(*args) + + @classmethod + def check_no_sale(cls, error): + Sale = Pool().get('sale.sale') + + sales = Sale.search([], limit=1, order=[]) + if sales: + raise UserError(gettext('sale_margin.msg_%s' % error)) + class ConfigurationSaleMethod(metaclass=PoolMeta): __name__ = 'sale.configuration.sale_method' diff --git a/locale/ca.po b/locale/ca.po index 9ec4e1b..c7adeb6 100644 --- a/locale/ca.po +++ b/locale/ca.po @@ -2,6 +2,10 @@ msgid "" msgstr "Content-Type: text/plain; charset=utf-8\n" +msgctxt "error:sale.configuration:" +msgid "You cannot change the sale margin method because has sales." +msgstr "No podeu canviar el mètode marge venta perquè ja existeixen ventes." + msgctxt "field:sale.configuration,sale_margin_method:" msgid "Sale Margin Method" msgstr "Mètode marge venda" @@ -42,6 +46,10 @@ msgstr "" "Dóna la rendibilitat mitjançant el càlcul de la diferència entre el preu " "unitari i preu de cost." +msgctxt "model:ir.message,text:msg_change_sale_margin_method" +msgid "You cannot change the sale margin method because has sales." +msgstr "No podeu canviar el mètode marge venta perquè ja existeixen ventes." + msgctxt "selection:sale.configuration,sale_margin_method:" msgid "Cost Price" msgstr "Preu de cost" diff --git a/locale/es.po b/locale/es.po index 3b9544d..b71b8c5 100644 --- a/locale/es.po +++ b/locale/es.po @@ -2,6 +2,10 @@ msgid "" msgstr "Content-Type: text/plain; charset=utf-8\n" +msgctxt "error:sale.configuration:" +msgid "You cannot change the sale margin method because has sales." +msgstr "No puede cambiar el método de margen de venta porque ya existen ventas." + msgctxt "field:sale.configuration,sale_margin_method:" msgid "Sale Margin Method" msgstr "Método margen venta" @@ -42,6 +46,10 @@ msgstr "" "Proporciona la rentabilidad calculando la diferencia entre el precio unidad " "y el precio de coste." +msgctxt "model:ir.message,text:msg_change_sale_margin_method" +msgid "You cannot change the sale margin method because has sales." +msgstr "No puede cambiar el método de margen de venta porque ya existen ventas." + msgctxt "selection:sale.configuration,sale_margin_method:" msgid "Cost Price" msgstr "Precio de coste" diff --git a/message.xml b/message.xml new file mode 100644 index 0000000..0b220a4 --- /dev/null +++ b/message.xml @@ -0,0 +1,10 @@ + + + + + + You cannot change the sale margin method because has sales. + + + diff --git a/tests/scenario_sale_margin.rst b/tests/scenario_sale_margin.rst index 6bb86fc..cb4f314 100644 --- a/tests/scenario_sale_margin.rst +++ b/tests/scenario_sale_margin.rst @@ -193,38 +193,3 @@ Confirm sale and check cache is done:: True >>> sale.margin_percent and sale.margin_percent == sale.margin_percent_cache True - -Change sale configuration:: - - >>> Configuration = Model.get('sale.configuration') - >>> configuration = Configuration(1) - >>> configuration.sale_margin_method = 'unit_price' - >>> configuration.save() - -Sale margin with and percentatge with unit price method:: - - >>> sale2 = Sale() - >>> sale2.party = customer - >>> sale2.payment_term = payment_term - >>> sale2_line = SaleLine() - >>> sale2.lines.append(sale2_line) - >>> sale2_line.product = product - >>> sale2_line.quantity = 2 - >>> sale2.save() - >>> sale2.margin - Decimal('10.00') - >>> sale2.margin_percent - Decimal('0.5000') - >>> sale2_line.margin - Decimal('10.00') - >>> sale2_line.margin_percent - Decimal('0.5000') - -Confirm sale2 and check cache is done:: - - >>> Sale.quote([sale2.id], config.context) - >>> Sale.confirm([sale2.id], config.context) - >>> sale2.margin and sale2.margin == sale2.margin_cache - True - >>> sale2.margin_percent and sale2.margin_percent == sale2.margin_percent_cache - True diff --git a/tests/scenario_sale_margin_unit_price.rst b/tests/scenario_sale_margin_unit_price.rst new file mode 100644 index 0000000..3a582b9 --- /dev/null +++ b/tests/scenario_sale_margin_unit_price.rst @@ -0,0 +1,160 @@ +==================== +Sale Margin Scenario +==================== + +Imports:: + + >>> import datetime + >>> from dateutil.relativedelta import relativedelta + >>> from decimal import Decimal + >>> from proteus import config, Model, Wizard + >>> from trytond.tests.tools import activate_modules + >>> from trytond.modules.company.tests.tools import create_company, \ + ... get_company + >>> from trytond.modules.account.tests.tools import create_fiscalyear, \ + ... create_chart, get_accounts, create_tax + >>> from trytond.modules.account_invoice.tests.tools import \ + ... set_fiscalyear_invoice_sequences, create_payment_term + >>> today = datetime.date.today() + +Install sale_margin:: + + >>> config = activate_modules('sale_margin') + +Create company:: + + >>> _ = create_company() + >>> company = get_company() + +Create sale user:: + + >>> Group = Model.get('res.group') + >>> User = Model.get('res.user') + >>> sale_user = User() + >>> sale_user.name = 'Sale' + >>> sale_user.login = 'sale' + >>> sale_user.main_company = company + >>> sale_group, = Group.find([('name', '=', 'Sales')]) + >>> sale_user.groups.append(sale_group) + >>> sale_user.save() + +Create fiscal year:: + + >>> fiscalyear = set_fiscalyear_invoice_sequences( + ... create_fiscalyear(company)) + >>> fiscalyear.click('create_period') + >>> period = fiscalyear.periods[0] + +Create chart of accounts:: + + >>> _ = create_chart(company) + >>> accounts = get_accounts(company) + >>> receivable = accounts['receivable'] + >>> revenue = accounts['revenue'] + >>> expense = accounts['expense'] + + >>> AccountJournal = Model.get('account.journal') + >>> stock_journal, = AccountJournal.find([('code', '=', 'STO')]) + +Create parties:: + + >>> Party = Model.get('party.party') + >>> customer = Party(name='Customer') + >>> customer.save() + +Set default accounting values:: + + >>> AccountConfiguration = Model.get('account.configuration') + >>> account_configuration = AccountConfiguration(1) + >>> account_configuration.default_category_account_expense = expense + >>> account_configuration.default_category_account_revenue = revenue + >>> account_configuration.save() + +Create category:: + + >>> ProductCategory = Model.get('product.category') + >>> account_category = ProductCategory(name='Category') + >>> account_category.accounting = True + >>> account_category.account_expense = expense + >>> account_category.account_revenue = revenue + >>> account_category.save() + +Create products:: + + >>> ProductUom = Model.get('product.uom') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + >>> ProductTemplate = Model.get('product.template') + >>> Product = Model.get('product.product') + >>> template = ProductTemplate() + >>> template.name = 'Product' + >>> template.account_category = account_category + >>> template.default_uom = unit + >>> template.type = 'goods' + >>> template.purchasable = True + >>> template.salable = True + >>> template.list_price = Decimal('10') + >>> template.supply_on_sale = True + >>> product, = template.products + >>> product.cost_price = Decimal('5') + >>> template.save() + >>> product, = template.products + + >>> template2 = ProductTemplate() + >>> template2.name = 'Product 2' + >>> template2.account_category = account_category + >>> template2.default_uom = unit + >>> template2.type = 'goods' + >>> template2.purchasable = True + >>> template2.salable = True + >>> template2.list_price = Decimal('80') + >>> template2.cost_price = Decimal('50') + >>> template2.account_expense = expense + >>> template2.account_revenue = revenue + >>> template2.supply_on_sale = True + >>> product2, = template2.products + >>> product2.cost_price = Decimal('5') + >>> template2.save() + >>> product2, = template2.products + +Create payment term:: + + >>> payment_term = create_payment_term() + >>> payment_term.save() + +Change sale configuration:: + + >>> Configuration = Model.get('sale.configuration') + >>> configuration = Configuration(1) + >>> configuration.sale_margin_method = 'unit_price' + >>> configuration.save() + +Sale margin with and percentatge with unit price method:: + + >>> config.user = sale_user.id + >>> Sale = Model.get('sale.sale') + >>> SaleLine = Model.get('sale.line') + >>> sale2 = Sale() + >>> sale2.party = customer + >>> sale2.payment_term = payment_term + >>> sale2_line = SaleLine() + >>> sale2.lines.append(sale2_line) + >>> sale2_line.product = product + >>> sale2_line.quantity = 2 + >>> sale2.save() + >>> sale2.margin + Decimal('10.00') + >>> sale2.margin_percent + Decimal('0.5000') + >>> sale2_line.margin + Decimal('10.00') + >>> sale2_line.margin_percent + Decimal('0.5000') + +Confirm sale2 and check cache is done:: + + >>> Sale.quote([sale2.id], config.context) + >>> Sale.confirm([sale2.id], config.context) + >>> sale2.margin and sale2.margin == sale2.margin_cache + True + >>> sale2.margin_percent and sale2.margin_percent == sale2.margin_percent_cache + True diff --git a/tests/test_sale_margin.py b/tests/test_sale_margin.py index 7bcb196..9e571a3 100644 --- a/tests/test_sale_margin.py +++ b/tests/test_sale_margin.py @@ -22,4 +22,8 @@ def suite(): tearDown=doctest_teardown, encoding='utf-8', optionflags=doctest.REPORT_ONLY_FIRST_FAILURE, checker=doctest_checker)) + suite.addTests(doctest.DocFileSuite('scenario_sale_margin_unit_price.rst', + tearDown=doctest_teardown, encoding='utf-8', + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE, + checker=doctest_checker)) return suite diff --git a/tryton.cfg b/tryton.cfg index c29cc26..e879fec 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -9,3 +9,4 @@ extras_depend: xml: configuration.xml sale.xml + message.xml \ No newline at end of file