Purchase tree
This commit is contained in:
@@ -286,6 +286,22 @@ class Purchase(metaclass=PoolMeta):
|
||||
'bank.account', "Our Bank Account")
|
||||
from_location = fields.Many2One('stock.location', 'From location', required=True,domain=[('type', "!=", 'customer')])
|
||||
to_location = fields.Many2One('stock.location', 'To location', required=True,domain=[('type', "!=", 'supplier')])
|
||||
first_line_product = fields.Function(
|
||||
fields.Many2One('product.product', "Product"),
|
||||
'get_first_line_product')
|
||||
first_line_price_type = fields.Function(fields.Selection([
|
||||
('cash', 'Cash Price'),
|
||||
('priced', 'Priced'),
|
||||
('basis', 'Basis'),
|
||||
('efp', 'EFP'),
|
||||
], "Price Type"), 'get_first_line_price_type')
|
||||
first_line_del_period = fields.Function(
|
||||
fields.Many2One('product.month', "Delivery Period"),
|
||||
'get_first_line_del_period')
|
||||
first_line_from_del = fields.Function(
|
||||
fields.Date("Delivery From"), 'get_first_line_from_del')
|
||||
first_line_to_del = fields.Function(
|
||||
fields.Date("Delivery To"), 'get_first_line_to_del')
|
||||
shipment_in = fields.Many2One('stock.shipment.in','Purchases')
|
||||
broker = fields.Many2One('party.party',"Broker",domain=[('categories.parent', 'child_of', [4])])
|
||||
tol_min = fields.Numeric("Tol - in %", required=True)
|
||||
@@ -499,6 +515,35 @@ class Purchase(metaclass=PoolMeta):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _get_first_trade_line(self):
|
||||
for line in self.lines or []:
|
||||
if getattr(line, 'type', None) == 'line':
|
||||
return line
|
||||
|
||||
@staticmethod
|
||||
def _record_id(record):
|
||||
return getattr(record, 'id', record) if record else None
|
||||
|
||||
def get_first_line_product(self, name):
|
||||
line = self._get_first_trade_line()
|
||||
return self._record_id(getattr(line, 'product', None))
|
||||
|
||||
def get_first_line_price_type(self, name):
|
||||
line = self._get_first_trade_line()
|
||||
return getattr(line, 'price_type', None) if line else None
|
||||
|
||||
def get_first_line_del_period(self, name):
|
||||
line = self._get_first_trade_line()
|
||||
return self._record_id(getattr(line, 'del_period', None))
|
||||
|
||||
def get_first_line_from_del(self, name):
|
||||
line = self._get_first_trade_line()
|
||||
return getattr(line, 'from_del', None) if line else None
|
||||
|
||||
def get_first_line_to_del(self, name):
|
||||
line = self._get_first_trade_line()
|
||||
return getattr(line, 'to_del', None) if line else None
|
||||
|
||||
@classmethod
|
||||
def delete(cls, purchases):
|
||||
for purchase in purchases:
|
||||
|
||||
@@ -24,6 +24,35 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
'Test purchase_trade module'
|
||||
module = 'purchase_trade'
|
||||
|
||||
@with_transaction()
|
||||
def test_purchase_list_fields_use_first_trade_line(self):
|
||||
'purchase list helper fields use the first real purchase line'
|
||||
Purchase = Pool().get('purchase.purchase')
|
||||
|
||||
product = Mock(id=10)
|
||||
period = Mock(id=20)
|
||||
comment_line = Mock(type='comment')
|
||||
trade_line = Mock(
|
||||
type='line',
|
||||
product=product,
|
||||
price_type='basis',
|
||||
del_period=period,
|
||||
from_del=datetime.date(2026, 7, 1),
|
||||
to_del=datetime.date(2026, 7, 31),
|
||||
)
|
||||
purchase = Purchase()
|
||||
purchase.lines = [comment_line, trade_line]
|
||||
|
||||
self.assertEqual(purchase.get_first_line_product(None), 10)
|
||||
self.assertEqual(purchase.get_first_line_price_type(None), 'basis')
|
||||
self.assertEqual(purchase.get_first_line_del_period(None), 20)
|
||||
self.assertEqual(
|
||||
purchase.get_first_line_from_del(None),
|
||||
datetime.date(2026, 7, 1))
|
||||
self.assertEqual(
|
||||
purchase.get_first_line_to_del(None),
|
||||
datetime.date(2026, 7, 31))
|
||||
|
||||
@with_transaction()
|
||||
def test_get_totals_without_rows(self):
|
||||
'get_totals returns zeros when the query has no row'
|
||||
|
||||
@@ -4,5 +4,17 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="//field[@name='reference']" position="after">
|
||||
<field name="plan"/>
|
||||
<field name="from_location" optional="0"/>
|
||||
<field name="to_location" optional="0"/>
|
||||
<field name="first_line_product" string="Product" optional="0"/>
|
||||
<field name="first_line_price_type"
|
||||
string="Price Type"
|
||||
widget="badge"
|
||||
badge_colors="priced:#16a34a,basis:#2563eb,efp:#8b5cf6,cash:#f59e0b"
|
||||
optional="0"
|
||||
width="100"/>
|
||||
<field name="first_line_del_period" string="Delivery Period" optional="0"/>
|
||||
<field name="first_line_from_del" string="Delivery From" optional="1"/>
|
||||
<field name="first_line_to_del" string="Delivery To" optional="1"/>
|
||||
</xpath>
|
||||
</data>
|
||||
@@ -15,13 +15,7 @@ Option Explicit
|
||||
' dans n'importe quelle cellule, puis F9 pour recalculer.
|
||||
' Mode macro : remplis Setup!B6:B9, lance RefreshGLApi.
|
||||
|
||||
Private Const GL_API_CONNECTION_STRING As String = _
|
||||
"Driver={PostgreSQL Unicode(x64)};" & _
|
||||
"Server=vps107.geneva.hosting;" & _
|
||||
"Port=5432;" & _
|
||||
"Database=tradon;" & _
|
||||
"Uid=postgres;" & _
|
||||
"Pwd=dsproject;"
|
||||
Private Const GL_API_CONNECTION_STRING As String = "DSN=tradon;"
|
||||
|
||||
Private gConnection As Object
|
||||
Private gCache As Object
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user