diff --git a/modules/sale/CHANGELOG b/modules/sale/CHANGELOG index 1a82032875..13b53a7834 100644 --- a/modules/sale/CHANGELOG +++ b/modules/sale/CHANGELOG @@ -1,3 +1,4 @@ +* Add relate to open products from sale Version 7.4.0 - 2024-11-04 -------------------------- diff --git a/modules/sale/__init__.py b/modules/sale/__init__.py index 84901cfb41..7f8f812fa2 100644 --- a/modules/sale/__init__.py +++ b/modules/sale/__init__.py @@ -61,6 +61,7 @@ def register(): sale.HandleInvoiceException, sale.ReturnSale, sale.ModifyHeader, + sale.OpenProduct, party.Replace, party.Erase, sale_reporting.OpenRegionTree, diff --git a/modules/sale/product.py b/modules/sale/product.py index cc172a56e2..ca4952f4d8 100644 --- a/modules/sale/product.py +++ b/modules/sale/product.py @@ -242,10 +242,13 @@ class SaleContext(ModelView): def default_locations(cls): pool = Pool() Location = pool.get('stock.location') - locations = [] - warehouse = Location.get_default_warehouse() - if warehouse: - locations.append(warehouse) + context = Transaction().context + locations = context.get('locations') + if locations is None: + locations = [] + warehouse = Location.get_default_warehouse() + if warehouse: + locations.append(warehouse) return locations @classmethod @@ -256,10 +259,26 @@ class SaleContext(ModelView): def default_currency(cls): pool = Pool() Company = pool.get('company.company') - company_id = cls.default_company() - if company_id: - company = Company(company_id) - return company.currency.id + context = Transaction().context + currency = context.get('currency') + if currency is None: + company_id = cls.default_company() + if company_id: + company = Company(company_id) + currency = company.currency.id + return currency + + @classmethod + def default_customer(cls): + return Transaction().context.get('customer') + + @classmethod + def default_sale_date(cls): + return Transaction().context.get('sale_date') + + @classmethod + def default_quantity(cls): + return Transaction().context.get('quantity') @fields.depends('sale_date') def on_change_with_stock_date_end(self, name=None): diff --git a/modules/sale/sale.py b/modules/sale/sale.py index 6da2e43a7b..388f924ca2 100644 --- a/modules/sale/sale.py +++ b/modules/sale/sale.py @@ -25,7 +25,7 @@ from trytond.modules.company.model import ( from trytond.modules.currency.fields import Monetary from trytond.modules.product import price_digits from trytond.pool import Pool -from trytond.pyson import Bool, Eval, If +from trytond.pyson import Bool, Eval, If, PYSONEncoder from trytond.tools import cached_property, firstline, sortable_values from trytond.transaction import Transaction from trytond.wizard import ( @@ -2467,3 +2467,50 @@ class ModifyHeader(Wizard): Line.save(sale.lines) return 'end' + + +class OpenProduct(Wizard): + __name__ = 'sale.open_product' + + start = StateAction('sale.act_product') + + def _context(self): + context = { + 'stock_skip_warehouse': True, + 'locations': [], + } + companies = set() + currencies = set() + customers = set() + sale_dates = set() + for record in self.records: + companies.add(record.company.id) + currencies.add(record.currency.id) + customers.add(record.party.id) + sale_dates.add(record.sale_date) + if self.record.warehouse: + context['locations'].append(self.record.warehouse.id) + if len(companies) == 1: + context['company'], = companies + if len(currencies) == 1: + context['currency'], = currencies + if len(customers) == 1: + context['customer'], = customers + if len(sale_dates) == 1: + context['sale_date'], = sale_dates + return context + + def do_start(self, action): + product_ids = { + l.product.id for r in self.records for l in r.lines if l.product} + encoder = PYSONEncoder() + domain = [ + ('id', 'in', list(product_ids)), + ] + action['pyson_domain'] = encoder.encode(domain) + action['pyson_context'] = encoder.encode(self._context()) + name_suffix = ', '.join(r.rec_name for r in self.records[:5]) + if len(self.records) > 5: + name_suffix += ',...' + action['name'] += f' ({name_suffix})' + return action, {} diff --git a/modules/sale/sale.xml b/modules/sale/sale.xml index b53541603b..559a8c0332 100644 --- a/modules/sale/sale.xml +++ b/modules/sale/sale.xml @@ -542,5 +542,16 @@ this repository contains the full copyright notices and license terms. --> eval="Eval('context', {}).get('modify_header', False)" pyson="1"/> + + + Products + sale.open_product + sale.sale + + + form_relate + sale.sale,-1 + + diff --git a/modules/sale_price_list/__init__.py b/modules/sale_price_list/__init__.py index ad0a00bc0c..cec58797d2 100644 --- a/modules/sale_price_list/__init__.py +++ b/modules/sale_price_list/__init__.py @@ -18,3 +18,6 @@ def register(): configuration.Configuration, configuration.ConfigurationSalePriceList, module='sale_price_list', type_='model') + Pool.register( + sale.OpenProduct, + module='sale_price_list', type_='wizard') diff --git a/modules/sale_price_list/product.py b/modules/sale_price_list/product.py index a8ec55f3f2..fa8f8c56b6 100644 --- a/modules/sale_price_list/product.py +++ b/modules/sale_price_list/product.py @@ -63,10 +63,14 @@ class SaleContext(metaclass=PoolMeta): def default_price_list(cls, **pattern): pool = Pool() Configuration = pool.get('sale.configuration') - config = Configuration(1) - price_list = config.get_multivalue('sale_price_list', **pattern) - if price_list: - return price_list.id + context = Transaction().context + price_list = context.get('price_list') + if price_list is None: + config = Configuration(1) + price_list = config.get_multivalue('sale_price_list', **pattern) + if price_list: + price_list = price_list.id + return price_list @fields.depends(methods=['on_change_customer']) def on_change_company(self): diff --git a/modules/sale_price_list/sale.py b/modules/sale_price_list/sale.py index 614487cb04..aadd048380 100644 --- a/modules/sale_price_list/sale.py +++ b/modules/sale_price_list/sale.py @@ -66,3 +66,16 @@ class Line(metaclass=PoolMeta): if getattr(self.sale, 'price_list', None): context['price_list'] = self.sale.price_list.id return context + + +class OpenProduct(metaclass=PoolMeta): + __name__ = 'sale.open_product' + + def _context(self): + context = super()._context() + price_lists = {r.price_list for r in self.records} + if len(price_lists) == 1: + price_list, = price_lists + if price_list: + context['price_list'] = price_list.id + return context