Add custom global to party
This commit is contained in:
parent
a92bc79e53
commit
289737f38a
|
@ -80,6 +80,7 @@ def register():
|
||||||
production.ProductionTask,
|
production.ProductionTask,
|
||||||
party.Party,
|
party.Party,
|
||||||
party.Company,
|
party.Company,
|
||||||
|
party.CustomsGlobal,
|
||||||
charge.ExportationCharge,
|
charge.ExportationCharge,
|
||||||
charge.ExportationPort,
|
charge.ExportationPort,
|
||||||
charge.ExportationChargeLine,
|
charge.ExportationChargeLine,
|
||||||
|
|
7
crop.py
7
crop.py
|
@ -364,7 +364,6 @@ class FarmingCrop(Workflow, ModelSQL, ModelView):
|
||||||
for act in crop.variety.activities:
|
for act in crop.variety.activities:
|
||||||
_date = crop.start_date + timedelta(
|
_date = crop.start_date + timedelta(
|
||||||
weeks=act.time_of_realization)
|
weeks=act.time_of_realization)
|
||||||
print('Symbol....', act.uom_time.symbol)
|
|
||||||
work_time = act.work_time * crop.total_plants
|
work_time = act.work_time * crop.total_plants
|
||||||
if act.uom_time.symbol == 'min':
|
if act.uom_time.symbol == 'min':
|
||||||
_cost = round((act.cost_per_hour / 60) * work_time, 2)
|
_cost = round((act.cost_per_hour / 60) * work_time, 2)
|
||||||
|
@ -621,7 +620,7 @@ class CropActivity(Workflow, ModelSQL, ModelView):
|
||||||
], 'State', readonly=True, required=True)
|
], 'State', readonly=True, required=True)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generateShipment(cls, records):
|
def generate_shipment(cls, records):
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
company = Transaction().context.get('company')
|
company = Transaction().context.get('company')
|
||||||
Supply = pool.get('farming.crop.activity.supply')
|
Supply = pool.get('farming.crop.activity.supply')
|
||||||
|
@ -648,7 +647,7 @@ class CropActivity(Workflow, ModelSQL, ModelView):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ModelView.button
|
@ModelView.button
|
||||||
def generateShipmentButton(cls, records):
|
def generate_shipment_button(cls, records):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _move(self, activity, from_location, to_location, company, product,
|
def _move(self, activity, from_location, to_location, company, product,
|
||||||
|
@ -790,7 +789,7 @@ class CropActivity(Workflow, ModelSQL, ModelView):
|
||||||
def production(cls, records):
|
def production(cls, records):
|
||||||
for record in records:
|
for record in records:
|
||||||
#cls.create_shipment(record)
|
#cls.create_shipment(record)
|
||||||
cls.generateShipment([record])
|
cls.generate_shipment([record])
|
||||||
record.set_number()
|
record.set_number()
|
||||||
|
|
||||||
def set_number(self):
|
def set_number(self):
|
||||||
|
|
|
@ -1,22 +1,20 @@
|
||||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
# this repository contains the full copyright notices and license terms.
|
# this repository contains the full copyright notices and license terms.
|
||||||
from concurrent.futures import process
|
|
||||||
import copy
|
import copy
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from multiprocessing import pool
|
|
||||||
from trytond.model import Workflow, ModelView, ModelSQL, fields
|
from trytond.model import Workflow, ModelView, ModelSQL, fields
|
||||||
from trytond.pyson import Eval
|
from trytond.pyson import Eval
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
from trytond.pool import Pool
|
from trytond.pool import Pool
|
||||||
from trytond.wizard import Wizard, StateView, StateTransition, Button
|
from trytond.wizard import Wizard, StateView, StateTransition, Button
|
||||||
from trytond.modules.company import CompanyReport
|
from trytond.modules.company import CompanyReport
|
||||||
# from trytond.report import Report
|
|
||||||
# from trytond.wizard import Wizard, StateReport, StateView, Button
|
|
||||||
STATES = {
|
STATES = {
|
||||||
'readonly': (Eval('state') != 'draft'),
|
'readonly': (Eval('state') != 'draft'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class DEX(Workflow, ModelSQL, ModelView):
|
class DEX(Workflow, ModelSQL, ModelView):
|
||||||
"DEX"
|
"DEX"
|
||||||
__name__ = "exportation.dex"
|
__name__ = "exportation.dex"
|
||||||
|
@ -24,23 +22,24 @@ class DEX(Workflow, ModelSQL, ModelView):
|
||||||
_rec_name = 'number'
|
_rec_name = 'number'
|
||||||
number = fields.Char('Number', states=STATES)
|
number = fields.Char('Number', states=STATES)
|
||||||
|
|
||||||
issue_date = fields.Date('Issue Date', required=True,
|
issue_date = fields.Date('Issue Date', required=True, states=STATES)
|
||||||
states=STATES)
|
|
||||||
company = fields.Many2One('company.company', 'Company', required=True,
|
company = fields.Many2One('company.company', 'Company', required=True,
|
||||||
states=STATES)
|
states=STATES)
|
||||||
# freight_forwader = fields.Many2One('party.party', 'Freight Forwader',
|
# freight_forwader = fields.Many2One('party.party', 'Freight Forwader',
|
||||||
# required=True, select=True)
|
# required=True, select=True)
|
||||||
customer = fields.Many2One('party.party', 'Customer', select=True,
|
customer = fields.Many2One('party.party', 'Customer', select=True,
|
||||||
states=STATES, required=True)
|
states=STATES, required=True)
|
||||||
|
|
||||||
invoice = fields.Many2One('account.invoice', 'invoice', states=STATES, domain=[
|
invoice = fields.Many2One('account.invoice', 'invoice', states=STATES, domain=[
|
||||||
('party', '=', Eval('customer')),
|
('party', '=', Eval('customer')),
|
||||||
('company', '=', Eval('company')),
|
('company', '=', Eval('company')),
|
||||||
])
|
])
|
||||||
invoice_exchange_rate = fields.Float('Invoice Exchange Rate', digits=(16, 2))
|
invoice_exchange_rate = fields.Float('Invoice Exchange Rate',
|
||||||
currency = fields.Many2One('currency.currency', 'Currency', states=STATES, required=True)
|
digits=(16, 2))
|
||||||
|
currency = fields.Many2One('currency.currency', 'Currency', states=STATES,
|
||||||
|
required=True)
|
||||||
invoiced_amount = fields.Numeric('Invoiced Amount', digits=(16, 2),
|
invoiced_amount = fields.Numeric('Invoiced Amount', digits=(16, 2),
|
||||||
states=STATES)
|
states=STATES)
|
||||||
description = fields.Char('Description', states=STATES)
|
description = fields.Char('Description', states=STATES)
|
||||||
lines = fields.One2Many('exportation.dex.line', 'dex', 'Lines')
|
lines = fields.One2Many('exportation.dex.line', 'dex', 'Lines')
|
||||||
state = fields.Selection([
|
state = fields.Selection([
|
||||||
|
@ -52,9 +51,9 @@ class DEX(Workflow, ModelSQL, ModelView):
|
||||||
digits=(16, 2), readonly=True), 'get_amounts')
|
digits=(16, 2), readonly=True), 'get_amounts')
|
||||||
amount_for_exchange = fields.Function(fields.Numeric('Amount For Exchange',
|
amount_for_exchange = fields.Function(fields.Numeric('Amount For Exchange',
|
||||||
digits=(16, 2), readonly=True), 'get_amounts')
|
digits=(16, 2), readonly=True), 'get_amounts')
|
||||||
|
conversion_invoiced_amount = fields.Function(fields.Numeric(
|
||||||
conversion_invoiced_amount = fields.Function(fields.Numeric('Conversion Invoiced Amount',
|
'Conversion Invoiced Amount', digits=(16, 2), readonly=True),
|
||||||
digits=(16,2), readonly=True), 'get_conversion_of_invoiced_amount')
|
'get_conversion_of_invoiced_amount')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __setup__(cls):
|
def __setup__(cls):
|
||||||
|
@ -152,11 +151,11 @@ class DEX(Workflow, ModelSQL, ModelView):
|
||||||
amount_for_exchange = []
|
amount_for_exchange = []
|
||||||
amount_receivable = []
|
amount_receivable = []
|
||||||
if self.lines:
|
if self.lines:
|
||||||
for l in self.lines:
|
for line in self.lines:
|
||||||
if l.amount_paid:
|
if line.amount_paid:
|
||||||
amount_receivable.append(l.amount_paid)
|
amount_receivable.append(line.amount_paid)
|
||||||
elif l.amount_exchanged:
|
elif line.amount_exchanged:
|
||||||
amount_for_exchange.append(l.amount_exchanged)
|
amount_for_exchange.append(line.amount_exchanged)
|
||||||
|
|
||||||
if name == 'amount_receivable':
|
if name == 'amount_receivable':
|
||||||
return (round(self.invoiced_amount - sum(amount_receivable), 2) if self.invoiced_amount else 0)
|
return (round(self.invoiced_amount - sum(amount_receivable), 2) if self.invoiced_amount else 0)
|
||||||
|
@ -193,12 +192,14 @@ class DEXLine(ModelSQL, ModelView):
|
||||||
'get_balance')
|
'get_balance')
|
||||||
trading_line = fields.Many2One('foreign.exchange.trading_line', 'line',
|
trading_line = fields.Many2One('foreign.exchange.trading_line', 'line',
|
||||||
'Trading Line')
|
'Trading Line')
|
||||||
amount_local_currency = fields.Function(fields.Numeric('Amount Local Currency', digits=(16, 2))
|
amount_local_currency = fields.Function(fields.Numeric(
|
||||||
,'get_local_amount')
|
'Amount Local Currency', digits=(16, 2)), 'get_local_amount')
|
||||||
profit = fields.Function(fields.Numeric('Profit', digits=(16, 2)),
|
profit = fields.Function(fields.Numeric('Profit', digits=(16, 2)),
|
||||||
'get_profit')
|
'get_profit')
|
||||||
currency=fields.Function(fields.Many2One('currency.currency', 'Currency'), 'get_currency')
|
currency = fields.Function(fields.Many2One('currency.currency', 'Currency'),
|
||||||
currency_company=fields.Function(fields.Many2One('currency.currency', ' Company'), 'get_currency')
|
'get_currency')
|
||||||
|
currency_company = fields.Function(fields.Many2One('currency.currency',
|
||||||
|
'Company'), 'get_currency')
|
||||||
|
|
||||||
@fields.depends('amount_exchanged', 'amount_paid', 'date')
|
@fields.depends('amount_exchanged', 'amount_paid', 'date')
|
||||||
def on_change_exchage_rate(self):
|
def on_change_exchage_rate(self):
|
||||||
|
@ -207,7 +208,7 @@ class DEXLine(ModelSQL, ModelView):
|
||||||
ctx = {'date': self.date}
|
ctx = {'date': self.date}
|
||||||
|
|
||||||
with Transaction().set_context(ctx):
|
with Transaction().set_context(ctx):
|
||||||
rates= Currency.get_rate([self.currency])
|
rates = Currency.get_rate([self.currency])
|
||||||
try:
|
try:
|
||||||
rate = round((1/rates[self.currency.id]), 2)
|
rate = round((1/rates[self.currency.id]), 2)
|
||||||
except:
|
except:
|
||||||
|
@ -226,7 +227,8 @@ class DEXLine(ModelSQL, ModelView):
|
||||||
|
|
||||||
def get_profit(self, name=None):
|
def get_profit(self, name=None):
|
||||||
res = 0
|
res = 0
|
||||||
if self.amount_exchanged and self.amount_local_currency and self.dex.invoice_exchange_rate:
|
if self.amount_exchanged and self.amount_local_currency and \
|
||||||
|
self.dex.invoice_exchange_rate:
|
||||||
res = self.amount_local_currency - (
|
res = self.amount_local_currency - (
|
||||||
Decimal(self.dex.invoice_exchange_rate) * self.amount_exchanged
|
Decimal(self.dex.invoice_exchange_rate) * self.amount_exchanged
|
||||||
)
|
)
|
||||||
|
@ -234,9 +236,9 @@ class DEXLine(ModelSQL, ModelView):
|
||||||
|
|
||||||
def get_currency(self, name=None):
|
def get_currency(self, name=None):
|
||||||
currency=None
|
currency=None
|
||||||
if name =='currency' and self.dex.currency:
|
if name == 'currency' and self.dex.currency:
|
||||||
currency = self.dex.currency.id
|
currency = self.dex.currency.id
|
||||||
elif name=='currency_company' and self.dex.company:
|
elif name == 'currency_company' and self.dex.company:
|
||||||
currency = self.dex.company.currency.id
|
currency = self.dex.company.currency.id
|
||||||
return currency
|
return currency
|
||||||
|
|
||||||
|
@ -330,14 +332,14 @@ class ForeignExhangeTrading(Workflow, ModelSQL, ModelView):
|
||||||
'date': record.exchange_date,
|
'date': record.exchange_date,
|
||||||
'exchange_rate': record.exchange_rate,
|
'exchange_rate': record.exchange_rate,
|
||||||
}
|
}
|
||||||
for l in record.lines:
|
for line in record.lines:
|
||||||
value_ = copy.deepcopy(value)
|
value_ = copy.deepcopy(value)
|
||||||
value_.update({
|
value_.update({
|
||||||
'amount_exchanged': l.trading_amount,
|
'amount_exchanged': line.trading_amount,
|
||||||
'dex': l.dex.id,
|
'dex': line.dex.id,
|
||||||
'trading_line': l.id,
|
'trading_line': line.id,
|
||||||
})
|
})
|
||||||
dex_to_refresh.append(l.dex)
|
dex_to_refresh.append(line.dex)
|
||||||
DEXLine.create([value_])
|
DEXLine.create([value_])
|
||||||
DEX.refresh(dex_to_refresh)
|
DEX.refresh(dex_to_refresh)
|
||||||
|
|
||||||
|
@ -353,12 +355,12 @@ class ForeignExhangeTrading(Workflow, ModelSQL, ModelView):
|
||||||
lines_to_remove = DEXLine.search([
|
lines_to_remove = DEXLine.search([
|
||||||
('trading_line', 'in', lines_trading)
|
('trading_line', 'in', lines_trading)
|
||||||
])
|
])
|
||||||
dexs = [l.dex for l in lines_to_remove]
|
dexs = [line.dex for line in lines_to_remove]
|
||||||
DEXLine.delete(lines_to_remove)
|
DEXLine.delete(lines_to_remove)
|
||||||
DEX.refresh(dexs)
|
DEX.refresh(dexs)
|
||||||
|
|
||||||
def get_total_exchange(self, name=None):
|
def get_total_exchange(self, name=None):
|
||||||
res = [l.trading_amount for l in self.lines]
|
res = [line.trading_amount for line in self.lines]
|
||||||
return sum(res)
|
return sum(res)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -379,10 +381,10 @@ class ForeignExhangeTradingLine(ModelSQL, ModelView):
|
||||||
|
|
||||||
exchange = fields.Many2One('foreign.exchange.trading', 'Exchange',
|
exchange = fields.Many2One('foreign.exchange.trading', 'Exchange',
|
||||||
required=True)
|
required=True)
|
||||||
dex = fields.Many2One('exportation.dex', 'DEX',
|
dex = fields.Many2One('exportation.dex', 'DEX', required=True)
|
||||||
required=True)
|
|
||||||
trading_amount = fields.Numeric('Trading Amount', digits=(16, 2))
|
trading_amount = fields.Numeric('Trading Amount', digits=(16, 2))
|
||||||
party = fields.Function(fields.Many2One('party.party', 'Party'), 'get_values_dex')
|
party = fields.Function(fields.Many2One('party.party', 'Party'),
|
||||||
|
'get_values_dex')
|
||||||
date_dex = fields.Function(fields.Date('Date Dex'), 'get_values_dex')
|
date_dex = fields.Function(fields.Date('Date Dex'), 'get_values_dex')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -412,16 +414,16 @@ class ForeignExhangeTradingLine(ModelSQL, ModelView):
|
||||||
class SelectLinesAsk(ModelView):
|
class SelectLinesAsk(ModelView):
|
||||||
'Select Lines Assistant'
|
'Select Lines Assistant'
|
||||||
__name__ = 'farming.select_lines.ask'
|
__name__ = 'farming.select_lines.ask'
|
||||||
lines = fields.Many2Many('exportation.dex', None, None,
|
lines = fields.Many2Many('exportation.dex', None, None, 'Dexs', domain=[
|
||||||
'Dexs', domain=[
|
('state', '=', 'processing')
|
||||||
('state', '=', 'processing')
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
class SelectLines(Wizard):
|
class SelectLines(Wizard):
|
||||||
'Select Lines'
|
'Select Lines'
|
||||||
__name__ = 'farming.select_lines'
|
__name__ = 'farming.select_lines'
|
||||||
start = StateView('farming.select_lines.ask',
|
start = StateView(
|
||||||
|
'farming.select_lines.ask',
|
||||||
'farming.view_search_lines_form', [
|
'farming.view_search_lines_form', [
|
||||||
Button('Cancel', 'end', 'tryton-cancel'),
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
Button('Add', 'add_lines', 'tryton-ok', default=True),
|
Button('Add', 'add_lines', 'tryton-ok', default=True),
|
||||||
|
@ -433,11 +435,11 @@ class SelectLines(Wizard):
|
||||||
TradingLine = pool.get('foreign.exchange.trading_line')
|
TradingLine = pool.get('foreign.exchange.trading_line')
|
||||||
exchange_id = Transaction().context.get('active_id')
|
exchange_id = Transaction().context.get('active_id')
|
||||||
lines_to_create = []
|
lines_to_create = []
|
||||||
for l in self.start.lines:
|
for line in self.start.lines:
|
||||||
value = {
|
value = {
|
||||||
'exchange': exchange_id,
|
'exchange': exchange_id,
|
||||||
'dex': l.id,
|
'dex': line.id,
|
||||||
'trading_amount': l.amount_for_exchange
|
'trading_amount': line.amount_for_exchange
|
||||||
}
|
}
|
||||||
lines_to_create.append(value)
|
lines_to_create.append(value)
|
||||||
TradingLine.create(lines_to_create)
|
TradingLine.create(lines_to_create)
|
||||||
|
|
15
party.py
15
party.py
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
from trytond.pool import PoolMeta
|
from trytond.pool import PoolMeta
|
||||||
from trytond.model import fields
|
from trytond.model import fields, ModelSQL, ModelView
|
||||||
|
|
||||||
|
|
||||||
class Party(metaclass=PoolMeta):
|
class Party(metaclass=PoolMeta):
|
||||||
|
@ -8,9 +8,20 @@ class Party(metaclass=PoolMeta):
|
||||||
carrier = fields.Many2One('party.party', 'Carrier')
|
carrier = fields.Many2One('party.party', 'Carrier')
|
||||||
freight_forwader = fields.Many2One('party.party', 'Freight Forwader')
|
freight_forwader = fields.Many2One('party.party', 'Freight Forwader')
|
||||||
export_route = fields.Char('Export Route', select=True)
|
export_route = fields.Char('Export Route', select=True)
|
||||||
global_aduana = fields.BigInteger('Global Aduana')
|
customs_globals = fields.One2Many('party.customs_global', 'party',
|
||||||
|
'Custom Globals')
|
||||||
|
|
||||||
|
|
||||||
class Company(metaclass=PoolMeta):
|
class Company(metaclass=PoolMeta):
|
||||||
__name__ = 'company.company'
|
__name__ = 'company.company'
|
||||||
ica_register = fields.Char('ICA Register')
|
ica_register = fields.Char('ICA Register')
|
||||||
|
|
||||||
|
|
||||||
|
class CustomsGlobal(ModelSQL, ModelView):
|
||||||
|
'Party Customs Global'
|
||||||
|
__name__ = 'party.customs_global'
|
||||||
|
party = fields.Many2One('party.party', 'Party', ondelete='CASCADE',
|
||||||
|
required=True)
|
||||||
|
export_target_city = fields.Many2One('party.city_code', 'Target City',
|
||||||
|
required=True, select=True)
|
||||||
|
global_custom = fields.Char('Global Custom')
|
||||||
|
|
12
party.xml
12
party.xml
|
@ -3,6 +3,18 @@
|
||||||
this repository contains the full copyright notices and license terms. -->
|
this repository contains the full copyright notices and license terms. -->
|
||||||
<tryton>
|
<tryton>
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="party_customs_global_view_tree">
|
||||||
|
<field name="model">party.customs_global</field>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="name">customs_global_tree</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="party_customs_global_view_form">
|
||||||
|
<field name="model">party.customs_global</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">customs_global_form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="party_view_form">
|
<record model="ir.ui.view" id="party_view_form">
|
||||||
<field name="model">party.party</field>
|
<field name="model">party.party</field>
|
||||||
<field name="inherit" ref="party.party_view_form"/>
|
<field name="inherit" ref="party.party_view_form"/>
|
||||||
|
|
155
production.py
155
production.py
|
@ -1,18 +1,14 @@
|
||||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
# this repository contains the full copyright notices and license terms.
|
# this repository contains the full copyright notices and license terms.
|
||||||
from cgi import print_environ
|
|
||||||
import copy
|
import copy
|
||||||
from datetime import timedelta, date, datetime
|
from datetime import timedelta, date, datetime
|
||||||
from http import client
|
|
||||||
from datetime import date
|
|
||||||
from shutil import move
|
|
||||||
from unittest import result
|
|
||||||
from sql import Table
|
from sql import Table
|
||||||
from trytond.model import fields, ModelView, ModelSQL, Workflow
|
from trytond.model import fields, ModelView, ModelSQL
|
||||||
from trytond.pool import PoolMeta, Pool
|
from trytond.pool import PoolMeta, Pool
|
||||||
from trytond.pyson import Eval, If, And, DateTime , Date, Bool, Or
|
from trytond.pyson import Eval
|
||||||
from trytond.report import Report
|
from trytond.report import Report
|
||||||
from trytond.wizard import Wizard, StateReport, StateView, Button, StateTransition
|
from trytond.wizard import (
|
||||||
|
Wizard, StateReport, StateView, Button, StateTransition)
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
from trytond.exceptions import UserError
|
from trytond.exceptions import UserError
|
||||||
from trytond.i18n import gettext
|
from trytond.i18n import gettext
|
||||||
|
@ -61,33 +57,6 @@ class Production(metaclass=PoolMeta):
|
||||||
if self.packing_qty and self.packing_uom:
|
if self.packing_qty and self.packing_uom:
|
||||||
return self.packing_qty * self.packing_uom.factor
|
return self.packing_qty * self.packing_uom.factor
|
||||||
|
|
||||||
#@classmethod
|
|
||||||
#def assign_lots(cls, inputs):
|
|
||||||
# Lot = Pool().get('stock.lot')
|
|
||||||
# transaction = Transaction()
|
|
||||||
# for input in inputs:
|
|
||||||
# ctx = {
|
|
||||||
# 'locations': [input.from_location.id]
|
|
||||||
# }
|
|
||||||
# with transaction.set_context(ctx):
|
|
||||||
# lots = Lot.search([
|
|
||||||
# ('product', '=', input.product.id),
|
|
||||||
# ('quantity', '>', 0)
|
|
||||||
# ], order=[('create_date', 'ASC')])
|
|
||||||
#
|
|
||||||
# # if lots:
|
|
||||||
# # input.save()
|
|
||||||
# remainder = input.quantity
|
|
||||||
# if remainder > 0:
|
|
||||||
# for lot in lots:
|
|
||||||
# if lot.quantity > remainder:
|
|
||||||
# input.lot = lot.id
|
|
||||||
# break
|
|
||||||
# else:
|
|
||||||
# remainder = remainder - lot.quantity
|
|
||||||
# input.quantity = lot.quantity
|
|
||||||
# input.save()
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def assign_lot(cls, productions):
|
def assign_lot(cls, productions):
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
|
@ -98,7 +67,9 @@ class Production(metaclass=PoolMeta):
|
||||||
if production.state == 'assigned':
|
if production.state == 'assigned':
|
||||||
continue
|
continue
|
||||||
for input in production.inputs:
|
for input in production.inputs:
|
||||||
has_origin = MovePhyto.search_read([('origin', '=', str(input))], limit=1)
|
has_origin = MovePhyto.search_read(
|
||||||
|
[('origin', '=', str(input))], limit=1
|
||||||
|
)
|
||||||
if input.product.farming and len(has_origin) <= 0:
|
if input.product.farming and len(has_origin) <= 0:
|
||||||
lots = Lot.search([
|
lots = Lot.search([
|
||||||
('product', '=', input.product.id),
|
('product', '=', input.product.id),
|
||||||
|
@ -106,7 +77,7 @@ class Production(metaclass=PoolMeta):
|
||||||
], order=[('create_date', 'ASC')])
|
], order=[('create_date', 'ASC')])
|
||||||
required_quantity = input.quantity
|
required_quantity = input.quantity
|
||||||
for lot in lots:
|
for lot in lots:
|
||||||
if required_quantity > 0 :
|
if required_quantity > 0:
|
||||||
move_in = 0
|
move_in = 0
|
||||||
lot_balance = lot.balance
|
lot_balance = lot.balance
|
||||||
if required_quantity >= lot_balance:
|
if required_quantity >= lot_balance:
|
||||||
|
@ -120,12 +91,11 @@ class Production(metaclass=PoolMeta):
|
||||||
move_in = required_quantity
|
move_in = required_quantity
|
||||||
required_quantity = 0
|
required_quantity = 0
|
||||||
move_phyto = MovePhyto(
|
move_phyto = MovePhyto(
|
||||||
lot = lot.id,
|
lot=lot.id,
|
||||||
#stock_move = input.id,
|
origin=(input),
|
||||||
origin = (input),
|
date_move=delivery_date,
|
||||||
date_move = delivery_date,
|
move_in=move_in,
|
||||||
move_in = move_in,
|
move_out=0
|
||||||
move_out = 0
|
|
||||||
)
|
)
|
||||||
move_phyto.save()
|
move_phyto.save()
|
||||||
lot.save()
|
lot.save()
|
||||||
|
@ -133,7 +103,9 @@ class Production(metaclass=PoolMeta):
|
||||||
break
|
break
|
||||||
if required_quantity > 0:
|
if required_quantity > 0:
|
||||||
raise UserError(
|
raise UserError(
|
||||||
gettext('farming.msg_missing_quantity_lot', product=input.product.name))
|
gettext(
|
||||||
|
'farming.msg_missing_quantity_lot',
|
||||||
|
product=input.product.name))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def draft(cls, productions):
|
def draft(cls, productions):
|
||||||
|
@ -165,7 +137,7 @@ class Production(metaclass=PoolMeta):
|
||||||
super(Production, cls).run(productions)
|
super(Production, cls).run(productions)
|
||||||
for pd in productions:
|
for pd in productions:
|
||||||
if pd.subproductions:
|
if pd.subproductions:
|
||||||
cls.run(pd.subproductions)
|
cls.run(pd.subproductions)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def done(cls, productions):
|
def done(cls, productions):
|
||||||
|
@ -173,7 +145,7 @@ class Production(metaclass=PoolMeta):
|
||||||
for pd in productions:
|
for pd in productions:
|
||||||
cls.assign_lot([pd])
|
cls.assign_lot([pd])
|
||||||
if pd.subproductions:
|
if pd.subproductions:
|
||||||
cls.done(pd.subproductions)
|
cls.done(pd.subproductions)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def copy(cls, records, default=None):
|
def copy(cls, records, default=None):
|
||||||
|
@ -204,8 +176,9 @@ class ProductionTask(ModelView, ModelSQL):
|
||||||
performance = fields.Function(fields.Float('Performance', digits=(4, 2)),
|
performance = fields.Function(fields.Float('Performance', digits=(4, 2)),
|
||||||
'get_performance')
|
'get_performance')
|
||||||
production = fields.Many2One('production', 'Production', states=STATES)
|
production = fields.Many2One('production', 'Production', states=STATES)
|
||||||
customer = fields.Many2One('party.party','Customer')
|
customer = fields.Many2One('party.party', 'Customer')
|
||||||
reference = fields.Many2One('product.product', 'Product', domain=[('type', '=', 'goods')])
|
reference = fields.Many2One('product.product', 'Product',
|
||||||
|
domain=[('type', '=', 'goods')])
|
||||||
units = fields.Integer('Units')
|
units = fields.Integer('Units')
|
||||||
uom = fields.Many2One('product.uom', 'Uom')
|
uom = fields.Many2One('product.uom', 'Uom')
|
||||||
factor = fields.Integer('Factor')
|
factor = fields.Integer('Factor')
|
||||||
|
@ -221,14 +194,9 @@ class ProductionTask(ModelView, ModelSQL):
|
||||||
def __setup__(cls):
|
def __setup__(cls):
|
||||||
super(ProductionTask, cls).__setup__()
|
super(ProductionTask, cls).__setup__()
|
||||||
cls._buttons.update({
|
cls._buttons.update({
|
||||||
'duplicate_wizard': {
|
'duplicate_wizard': {},
|
||||||
# 'invisible': Eval('_parent_production', {}).get('state') != 'done',
|
'finishButton': {}
|
||||||
# 'depends': ['_parent_production.state', 'production']
|
})
|
||||||
},
|
|
||||||
'finishButton': {
|
|
||||||
# 'invisible': Eval('_parent_production', {}).get('state') != 'done',
|
|
||||||
# 'depends': ['_parent_production.state', 'production']
|
|
||||||
}})
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ModelView.button
|
@ModelView.button
|
||||||
|
@ -265,20 +233,19 @@ class ProductionTask(ModelView, ModelSQL):
|
||||||
return self.start_time + timedelta(minutes=self.goal)
|
return self.start_time + timedelta(minutes=self.goal)
|
||||||
|
|
||||||
@fields.depends('production')
|
@fields.depends('production')
|
||||||
def on_change_with_customer(self, name= None):
|
def on_change_with_customer(self, name=None):
|
||||||
if self.production:
|
if self.production:
|
||||||
return self.production.customer.id
|
return self.production.customer.id
|
||||||
|
|
||||||
@fields.depends('production')
|
@fields.depends('production')
|
||||||
def on_change_with_reference(self, name= None):
|
def on_change_with_reference(self, name=None):
|
||||||
if self.production:
|
if self.production:
|
||||||
return self.production.product.id
|
return self.production.product.id
|
||||||
|
|
||||||
|
|
||||||
@fields.depends('operation', 'quantity')
|
@fields.depends('operation', 'quantity')
|
||||||
def on_change_with_goal(self, name=None):
|
def on_change_with_goal(self, name=None):
|
||||||
if self.operation and self.quantity and self.operation.productivity:
|
if self.operation and self.quantity and self.operation.productivity:
|
||||||
return int((self.operation.productivity / 60) * self.quantity)
|
return int((self.operation.productivity / 60) * self.quantity)
|
||||||
|
|
||||||
@fields.depends('start_time', 'end_time')
|
@fields.depends('start_time', 'end_time')
|
||||||
def on_change_with_total_time(self, name=None):
|
def on_change_with_total_time(self, name=None):
|
||||||
|
@ -313,7 +280,8 @@ class ProductionSummaryStart(ModelView):
|
||||||
class ProductionSummary(Wizard):
|
class ProductionSummary(Wizard):
|
||||||
'Purchase Analytic Report'
|
'Purchase Analytic Report'
|
||||||
__name__ = 'production.summary'
|
__name__ = 'production.summary'
|
||||||
start = StateView('production.summary.start',
|
start = StateView(
|
||||||
|
'production.summary.start',
|
||||||
'farming.production_summary_start_view_form', [
|
'farming.production_summary_start_view_form', [
|
||||||
Button('Cancel', 'end', 'tryton-cancel'),
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
Button('Print', 'print_', 'tryton-ok', default=True),
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
||||||
|
@ -350,7 +318,7 @@ class ProductionSummaryReport(Report):
|
||||||
], order=[('id', 'ASC')])
|
], order=[('id', 'ASC')])
|
||||||
|
|
||||||
inputs = {}
|
inputs = {}
|
||||||
types = {'solidos':{}, 'bouquets':{}}
|
types = {'solidos': {}, 'bouquets': {}}
|
||||||
styles = []
|
styles = []
|
||||||
styles_append = styles.append
|
styles_append = styles.append
|
||||||
products = []
|
products = []
|
||||||
|
@ -372,12 +340,15 @@ class ProductionSummaryReport(Report):
|
||||||
product = _inp.product
|
product = _inp.product
|
||||||
product_id = str(product.id)
|
product_id = str(product.id)
|
||||||
products_append(product_id)
|
products_append(product_id)
|
||||||
cat_id = str(product.categories[0].id) if product.categories else 'none'
|
cat = None
|
||||||
cat_name = product.categories[0].name if product.categories else 'none'
|
if product.categories:
|
||||||
key = cat_id + '_' + product_id
|
cat = product.categories[0]
|
||||||
quantity_pending = 0
|
cat_id = str(cat.id if cat else 'none')
|
||||||
|
cat_name = cat.name if cat else 'none'
|
||||||
|
key = cat_id + '_' + product_id
|
||||||
|
qty_pending = 0
|
||||||
if state != 'done':
|
if state != 'done':
|
||||||
quantity_pending = _inp.quantity
|
qty_pending = _inp.quantity
|
||||||
if key not in inputs.keys():
|
if key not in inputs.keys():
|
||||||
inputs[key] = {
|
inputs[key] = {
|
||||||
'id': product_id,
|
'id': product_id,
|
||||||
|
@ -386,17 +357,18 @@ class ProductionSummaryReport(Report):
|
||||||
'quantity': _inp.quantity,
|
'quantity': _inp.quantity,
|
||||||
'uom': product.default_uom.name,
|
'uom': product.default_uom.name,
|
||||||
'solidos': 0,
|
'solidos': 0,
|
||||||
'quantity_pending': quantity_pending
|
'qty_pending': qty_pending
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
qty = inputs[key]['quantity']
|
qty = inputs[key]['quantity']
|
||||||
pend = inputs[key]['quantity_pending']
|
pend = inputs[key]['qty_pending']
|
||||||
inputs[key]['quantity'] = qty + _inp.quantity
|
inputs[key]['quantity'] = qty + _inp.quantity
|
||||||
inputs[key]['quantity_pending'] = pend + quantity_pending
|
inputs[key]['qty_pending'] = pend + qty_pending
|
||||||
|
|
||||||
|
|
||||||
with Transaction().set_context({'locations': list(locations)}):
|
with Transaction().set_context({'locations': list(locations)}):
|
||||||
products = Product.search_read([('id', 'in', products)], fields_names = ['quantity'])
|
products = Product.search_read(
|
||||||
|
[('id', 'in', products)],
|
||||||
|
fields_names=['quantity'])
|
||||||
products = {str(p['id']): p for p in products}
|
products = {str(p['id']): p for p in products}
|
||||||
totals = {
|
totals = {
|
||||||
'box': {
|
'box': {
|
||||||
|
@ -423,33 +395,43 @@ class ProductionSummaryReport(Report):
|
||||||
for _input in types['solidos'][s].inputs:
|
for _input in types['solidos'][s].inputs:
|
||||||
if _input.uom.symbol == 'STEM':
|
if _input.uom.symbol == 'STEM':
|
||||||
if state != 'done':
|
if state != 'done':
|
||||||
cat_id = str(_input.product.categories[0].id) if _input.product.categories else 'none'
|
cat_id = str(
|
||||||
key = cat_id + '_' + str(_input.product.id)
|
_input.product.categories[0].id) if _input.product.categories else 'none'
|
||||||
|
key = cat_id + '_' + str(_input.product.id)
|
||||||
inputs[key]['solidos'] += _input.quantity
|
inputs[key]['solidos'] += _input.quantity
|
||||||
flag += 1
|
flag += 1
|
||||||
if flag == 1:
|
if flag == 1:
|
||||||
_solidos.append({'input': _input, 'pcc': _input.production_input})
|
_solidos.append({
|
||||||
|
'input': _input,
|
||||||
|
'pcc': _input.production_input
|
||||||
|
})
|
||||||
else:
|
else:
|
||||||
_solidos.append({'input': _input, 'pcc': None})
|
_solidos.append({'input': _input, 'pcc': None})
|
||||||
state = 'done' if state == 'done' else 'process'
|
state = 'done' if state == 'done' else 'process'
|
||||||
totals = cls.get_values(totals, 'solidos', state, units, quantity )
|
totals = cls.get_values(
|
||||||
|
totals, 'solidos', state, units, quantity)
|
||||||
|
|
||||||
_bouquets = []
|
_bouquets = []
|
||||||
for b in types['bouquets'].values():
|
for b in types['bouquets'].values():
|
||||||
flag = 0
|
flag = 0
|
||||||
for _input in b.inputs:
|
for _input in b.inputs:
|
||||||
if _input.uom.symbol not in ['u', 'STEM']:
|
if _input.uom.symbol not in ['u', 'STEM']:
|
||||||
flag += 1
|
flag += 1
|
||||||
if flag == 1:
|
if flag == 1:
|
||||||
pcc =_input.production_input
|
pcc = _input.production_input
|
||||||
_bouquets.append({'input': _input, 'pcc': pcc})
|
_bouquets.append({'input': _input, 'pcc': pcc})
|
||||||
quantity = pcc.quantity
|
quantity = pcc.quantity
|
||||||
units = pcc.units
|
units = pcc.units
|
||||||
state = pcc.state
|
state = pcc.state
|
||||||
state = 'done' if state == 'done' else 'process'
|
state = 'done' if state == 'done' else 'process'
|
||||||
totals = cls.get_values(totals, 'bouquets', state, units, quantity )
|
totals = cls.get_values(
|
||||||
|
totals, 'bouquets', state, units, quantity)
|
||||||
else:
|
else:
|
||||||
_bouquets.append({'input': _input, 'pcc': None, 'factor_packing': _input.quantity/_input.production_input.quantity})
|
_bouquets.append({
|
||||||
|
'input': _input,
|
||||||
|
'pcc': None,
|
||||||
|
'factor_packing': _input.quantity/_input.production_input.quantity
|
||||||
|
})
|
||||||
report_context['records'] = records
|
report_context['records'] = records
|
||||||
report_context['inputs'] = dict(sorted(inputs.items())).values()
|
report_context['inputs'] = dict(sorted(inputs.items())).values()
|
||||||
report_context['solidos'] = _solidos
|
report_context['solidos'] = _solidos
|
||||||
|
@ -470,6 +452,7 @@ class ProductionSummaryReport(Report):
|
||||||
totals['box'][state] += quantity
|
totals['box'][state] += quantity
|
||||||
return totals
|
return totals
|
||||||
|
|
||||||
|
|
||||||
class MaterialsForecastStart(ModelView):
|
class MaterialsForecastStart(ModelView):
|
||||||
'Materials Forecast Start'
|
'Materials Forecast Start'
|
||||||
__name__ = 'production.materials_forecast.start'
|
__name__ = 'production.materials_forecast.start'
|
||||||
|
@ -486,7 +469,8 @@ class MaterialsForecastStart(ModelView):
|
||||||
class MaterialsForecast(Wizard):
|
class MaterialsForecast(Wizard):
|
||||||
'Materials Forecast'
|
'Materials Forecast'
|
||||||
__name__ = 'production.materials_forecast'
|
__name__ = 'production.materials_forecast'
|
||||||
start = StateView('production.materials_forecast.start',
|
start = StateView(
|
||||||
|
'production.materials_forecast.start',
|
||||||
'farming.production_materials_forecast_start_view_form', [
|
'farming.production_materials_forecast_start_view_form', [
|
||||||
Button('Cancel', 'end', 'tryton-cancel'),
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
Button('Print', 'print_', 'tryton-ok', default=True),
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
||||||
|
@ -605,7 +589,6 @@ class ProductionForceDraft(Wizard):
|
||||||
|
|
||||||
def _reset_data(self, prod, delete=None):
|
def _reset_data(self, prod, delete=None):
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
Production = pool.get('production')
|
|
||||||
Move_Phyto = pool.get('stock.lot.phyto.move')
|
Move_Phyto = pool.get('stock.lot.phyto.move')
|
||||||
Lot = pool.get('stock.lot')
|
Lot = pool.get('stock.lot')
|
||||||
stock_move = Table('stock_move')
|
stock_move = Table('stock_move')
|
||||||
|
@ -614,10 +597,6 @@ class ProductionForceDraft(Wizard):
|
||||||
lots_to_update = []
|
lots_to_update = []
|
||||||
if not delete:
|
if not delete:
|
||||||
outputs_to_update = [out.id for out in prod.outputs]
|
outputs_to_update = [out.id for out in prod.outputs]
|
||||||
# if outputs_to_delete:
|
|
||||||
# cursor.execute(*stock_move.delete(
|
|
||||||
# where=stock_move.id.in_(outputs_to_delete)))
|
|
||||||
|
|
||||||
origin_inputs = []
|
origin_inputs = []
|
||||||
inputs_to_update = []
|
inputs_to_update = []
|
||||||
|
|
||||||
|
@ -648,9 +627,6 @@ class ProductionForceDraft(Wizard):
|
||||||
Move_Phyto.delete(move_phytos)
|
Move_Phyto.delete(move_phytos)
|
||||||
moves_to_update = [r.id for r in prod.outputs] + inputs_to_delete
|
moves_to_update = [r.id for r in prod.outputs] + inputs_to_delete
|
||||||
if moves_to_update:
|
if moves_to_update:
|
||||||
# cursor.execute(*stock_move.delete(
|
|
||||||
# where=stock_move.id.in_(moves_to_delete) )
|
|
||||||
# )
|
|
||||||
cursor.execute(*stock_move.update(
|
cursor.execute(*stock_move.update(
|
||||||
columns=[stock_move.state],
|
columns=[stock_move.state],
|
||||||
values=['draft'],
|
values=['draft'],
|
||||||
|
@ -659,7 +635,6 @@ class ProductionForceDraft(Wizard):
|
||||||
|
|
||||||
prod.state = 'draft'
|
prod.state = 'draft'
|
||||||
prod.save()
|
prod.save()
|
||||||
# Production.delete([prod])
|
|
||||||
|
|
||||||
if lots_to_update:
|
if lots_to_update:
|
||||||
Lot.recompute_balance(list(set(lots_to_update)))
|
Lot.recompute_balance(list(set(lots_to_update)))
|
||||||
|
|
43
quality.py
43
quality.py
|
@ -90,7 +90,8 @@ class ICACertificate(ModelSQL, ModelView):
|
||||||
bool_op = 'AND'
|
bool_op = 'AND'
|
||||||
else:
|
else:
|
||||||
bool_op = 'OR'
|
bool_op = 'OR'
|
||||||
return [bool_op,
|
return [
|
||||||
|
bool_op,
|
||||||
('number',) + tuple(clause[1:]),
|
('number',) + tuple(clause[1:]),
|
||||||
('farm',) + tuple(clause[1:]),
|
('farm',) + tuple(clause[1:]),
|
||||||
('party.name',) + tuple(clause[1:]),
|
('party.name',) + tuple(clause[1:]),
|
||||||
|
@ -105,10 +106,10 @@ class Phytosanitary(ModelSQL, ModelView):
|
||||||
__name__ = "farming.phyto"
|
__name__ = "farming.phyto"
|
||||||
_rec_name = 'number'
|
_rec_name = 'number'
|
||||||
number = fields.Char('Number', required=True, select=True)
|
number = fields.Char('Number', required=True, select=True)
|
||||||
ica = fields.Many2One('farming.quality.ica', 'ICA Certificate', required=True, select=True)
|
ica = fields.Many2One('farming.quality.ica', 'ICA Certificate',
|
||||||
|
required=True, select=True)
|
||||||
issue_date = fields.Date('Issue Date', required=True)
|
issue_date = fields.Date('Issue Date', required=True)
|
||||||
stock_lots = fields.One2Many('stock.lot', 'phyto', 'Stock Lots')
|
stock_lots = fields.One2Many('stock.lot', 'phyto', 'Stock Lots')
|
||||||
# stocks = fields.One2Many('farming.phyto.stock', 'phyto', 'Stocks')
|
|
||||||
balance = fields.Function(fields.Integer('Balance'), 'get_balance')
|
balance = fields.Function(fields.Integer('Balance'), 'get_balance')
|
||||||
state = fields.Selection([
|
state = fields.Selection([
|
||||||
('active', 'Active'),
|
('active', 'Active'),
|
||||||
|
@ -136,12 +137,6 @@ class Phytosanitary(ModelSQL, ModelView):
|
||||||
res = [stock.balance for stock in self.stock_lots if stock.balance]
|
res = [stock.balance for stock in self.stock_lots if stock.balance]
|
||||||
return Decimal(sum(res))
|
return Decimal(sum(res))
|
||||||
|
|
||||||
# def get_balance(self, name=None):
|
|
||||||
# res = []
|
|
||||||
# for stock in self.stocks:
|
|
||||||
# res.append(stock.balance)
|
|
||||||
# return sum(res)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search_rec_name(cls, name, clause):
|
def search_rec_name(cls, name, clause):
|
||||||
if clause[1].startswith('!') or clause[1].startswith('not '):
|
if clause[1].startswith('!') or clause[1].startswith('not '):
|
||||||
|
@ -208,8 +203,8 @@ class PhytoStock(ModelSQL, ModelView):
|
||||||
class PhytoStockMove(ModelSQL, ModelView):
|
class PhytoStockMove(ModelSQL, ModelView):
|
||||||
"Phytosanitary Stock Move"
|
"Phytosanitary Stock Move"
|
||||||
__name__ = "farming.phyto.stock.move"
|
__name__ = "farming.phyto.stock.move"
|
||||||
stock = fields.Many2One('farming.phyto.stock', 'Stock Phyto', required=True,
|
stock = fields.Many2One('farming.phyto.stock', 'Stock Phyto',
|
||||||
ondelete='CASCADE')
|
required=True, ondelete='CASCADE')
|
||||||
date = fields.Date('Date', required=True)
|
date = fields.Date('Date', required=True)
|
||||||
move_in = fields.Integer('Move In', required=True)
|
move_in = fields.Integer('Move In', required=True)
|
||||||
move_out = fields.Integer('Move Out', required=True)
|
move_out = fields.Integer('Move Out', required=True)
|
||||||
|
@ -351,7 +346,9 @@ class ExportationPhyto(Workflow, ModelSQL, ModelView):
|
||||||
if input.product.template.farming:
|
if input.product.template.farming:
|
||||||
moves.append(input)
|
moves.append(input)
|
||||||
for move in moves:
|
for move in moves:
|
||||||
query = move_phyto_table.select(move_phyto_table.id, where=move_phyto_table.origin==str(move))
|
query = move_phyto_table.select(
|
||||||
|
move_phyto_table.id,
|
||||||
|
where=move_phyto_table.origin == str(move))
|
||||||
cursor.execute(*query)
|
cursor.execute(*query)
|
||||||
result = cursor.fetchall()
|
result = cursor.fetchall()
|
||||||
if result:
|
if result:
|
||||||
|
@ -370,11 +367,11 @@ class ExportationPhyto(Workflow, ModelSQL, ModelView):
|
||||||
}
|
}
|
||||||
line, = ExLine.create([ex_line])
|
line, = ExLine.create([ex_line])
|
||||||
new_phyto_move = {
|
new_phyto_move = {
|
||||||
'lot' : move_phyto.lot,
|
'lot': move_phyto.lot,
|
||||||
'date_move' : export_date,
|
'date_move': export_date,
|
||||||
'move_in' : 0,
|
'move_in': 0,
|
||||||
'move_out' : move_phyto.move_in,
|
'move_out': move_phyto.move_in,
|
||||||
'origin' : str(line)
|
'origin': str(line)
|
||||||
}
|
}
|
||||||
new_id_phyto, = MovePhyto.create([new_phyto_move])
|
new_id_phyto, = MovePhyto.create([new_phyto_move])
|
||||||
line.phyto_moves = new_id_phyto.id
|
line.phyto_moves = new_id_phyto.id
|
||||||
|
@ -416,7 +413,7 @@ class ExportationPhyto(Workflow, ModelSQL, ModelView):
|
||||||
self.write([self], {'number': number})
|
self.write([self], {'number': number})
|
||||||
|
|
||||||
def get_total_quantity(self, name=None):
|
def get_total_quantity(self, name=None):
|
||||||
return sum(l.quantity for l in self.lines)
|
return sum(line.quantity for line in self.lines)
|
||||||
|
|
||||||
|
|
||||||
class ExportationPhytoLine(ModelSQL, ModelView):
|
class ExportationPhytoLine(ModelSQL, ModelView):
|
||||||
|
@ -425,15 +422,11 @@ class ExportationPhytoLine(ModelSQL, ModelView):
|
||||||
ica_register = fields.Many2One('farming.quality.ica', 'ICA Register',
|
ica_register = fields.Many2One('farming.quality.ica', 'ICA Register',
|
||||||
required=True)
|
required=True)
|
||||||
phyto = fields.Many2One('exportation.phyto', 'Phyto')
|
phyto = fields.Many2One('exportation.phyto', 'Phyto')
|
||||||
# in_phyto = fields.Many2One('farming.phyto', 'In Phyto', domain=[('ica', '=', Eval('ica_register'))])
|
|
||||||
quantity = fields.Integer('Quantity')
|
quantity = fields.Integer('Quantity')
|
||||||
phyto_moves = fields.Many2One('stock.lot.phyto.move', 'origin', 'Phyto Move',
|
phyto_moves = fields.Many2One('stock.lot.phyto.move', 'origin', 'Phyto Move',
|
||||||
domain=[('lot.phyto.ica', '=', Eval('ica_register'))], ondelete="CASCADE")
|
domain=[('lot.phyto.ica', '=', Eval('ica_register'))], ondelete="CASCADE")
|
||||||
# phyto_move = fields.Many2One('farming.phyto.stock.move', 'Phyto Move',
|
|
||||||
# states = {'required': False}, ondelete='CASCADE')
|
|
||||||
manual = fields.Boolean('Manual')
|
manual = fields.Boolean('Manual')
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete(cls, records):
|
def delete(cls, records):
|
||||||
StockMove = Pool().get('stock.lot.phyto.move')
|
StockMove = Pool().get('stock.lot.phyto.move')
|
||||||
|
@ -461,7 +454,8 @@ class PhytoMovesStart(ModelView):
|
||||||
class PhytoMoves(Wizard):
|
class PhytoMoves(Wizard):
|
||||||
'Phyto Moves'
|
'Phyto Moves'
|
||||||
__name__ = 'farming.phyto_moves'
|
__name__ = 'farming.phyto_moves'
|
||||||
start = StateView('farming.phyto_moves.start',
|
start = StateView(
|
||||||
|
'farming.phyto_moves.start',
|
||||||
'farming.phyto_moves_start_view_form', [
|
'farming.phyto_moves_start_view_form', [
|
||||||
Button('Cancel', 'end', 'tryton-cancel'),
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
Button('Print', 'print_', 'tryton-ok', default=True),
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
||||||
|
@ -555,7 +549,8 @@ class PurchaseMonitoringStart(ModelView):
|
||||||
class PurchaseMonitoring(Wizard):
|
class PurchaseMonitoring(Wizard):
|
||||||
'Purchase Monitoring'
|
'Purchase Monitoring'
|
||||||
__name__ = 'farming.purchase_monitoring'
|
__name__ = 'farming.purchase_monitoring'
|
||||||
start = StateView('farming.purchase_monitoring.start',
|
start = StateView(
|
||||||
|
'farming.purchase_monitoring.start',
|
||||||
'farming.purchase_monitoring_start_view_form', [
|
'farming.purchase_monitoring_start_view_form', [
|
||||||
Button('Cancel', 'end', 'tryton-cancel'),
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
Button('Print', 'print_', 'tryton-ok', default=True),
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
||||||
|
|
75
sale.py
75
sale.py
|
@ -6,7 +6,8 @@ from sql import Table
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from trytond.model import fields, ModelSQL, ModelView
|
from trytond.model import fields, ModelSQL, ModelView
|
||||||
from trytond.wizard import Wizard, StateView, Button, StateTransition, StateReport
|
from trytond.wizard import (
|
||||||
|
Wizard, StateView, Button, StateTransition, StateReport)
|
||||||
from trytond.pool import PoolMeta, Pool
|
from trytond.pool import PoolMeta, Pool
|
||||||
from trytond.pyson import Eval
|
from trytond.pyson import Eval
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
|
@ -42,6 +43,9 @@ class Sale(metaclass=PoolMeta):
|
||||||
aged = fields.Function(fields.Integer('Aged'), 'get_aged')
|
aged = fields.Function(fields.Integer('Aged'), 'get_aged')
|
||||||
total_amount_ref = fields.Function(fields.Numeric('Total Amount Ref.',
|
total_amount_ref = fields.Function(fields.Numeric('Total Amount Ref.',
|
||||||
digits=(6, 2)), 'get_total_amount_ref')
|
digits=(6, 2)), 'get_total_amount_ref')
|
||||||
|
custom_global = fields.Many2One('party.customs_global', domain=[
|
||||||
|
('party', '=', Eval('party'))
|
||||||
|
])
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __setup__(cls):
|
def __setup__(cls):
|
||||||
|
@ -281,7 +285,8 @@ class SaleLine(metaclass=PoolMeta):
|
||||||
@fields.depends('kits', 'product', 'description')
|
@fields.depends('kits', 'product', 'description')
|
||||||
def on_change_kits(self, name=None):
|
def on_change_kits(self, name=None):
|
||||||
if self.product and self.kits:
|
if self.product and self.kits:
|
||||||
string_ = [ki.product.template.name
|
string_ = [
|
||||||
|
ki.product.template.name
|
||||||
for ki in self.kits if ki.product and ki.product.template.farming]
|
for ki in self.kits if ki.product and ki.product.template.farming]
|
||||||
if not string_:
|
if not string_:
|
||||||
return
|
return
|
||||||
|
@ -390,7 +395,8 @@ class GroupingSalesStart(ModelView):
|
||||||
class GroupingSales(Wizard):
|
class GroupingSales(Wizard):
|
||||||
'Grouping Sales'
|
'Grouping Sales'
|
||||||
__name__ = 'sale.grouping_sales'
|
__name__ = 'sale.grouping_sales'
|
||||||
start = StateView('sale.grouping_sales.start',
|
start = StateView(
|
||||||
|
'sale.grouping_sales.start',
|
||||||
'farming.grouping_sales_start_view_form', [
|
'farming.grouping_sales_start_view_form', [
|
||||||
Button('Cancel', 'end', 'tryton-cancel'),
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
Button('Ok', 'accept', 'tryton-ok', default=True),
|
Button('Ok', 'accept', 'tryton-ok', default=True),
|
||||||
|
@ -489,7 +495,11 @@ class SaleChangeProcessing(Wizard):
|
||||||
sale, = Sale.browse([sale_id])
|
sale, = Sale.browse([sale_id])
|
||||||
if sale.state in ['done', 'processing'] and sale.id:
|
if sale.state in ['done', 'processing'] and sale.id:
|
||||||
cursor.execute(*sale_table.update(
|
cursor.execute(*sale_table.update(
|
||||||
columns=[sale_table.state, sale_table.untaxed_amount_cache, sale_table.tax_amount_cache, sale_table.total_amount_cache],
|
columns=[
|
||||||
|
sale_table.state,
|
||||||
|
sale_table.untaxed_amount_cache,
|
||||||
|
sale_table.tax_amount_cache,
|
||||||
|
sale_table.total_amount_cache],
|
||||||
values=['processing', 0, 0, 0],
|
values=['processing', 0, 0, 0],
|
||||||
where=sale_table.id == sale.id)
|
where=sale_table.id == sale.id)
|
||||||
)
|
)
|
||||||
|
@ -504,7 +514,6 @@ class PortfolioDetailedStart(ModelView):
|
||||||
parties = fields.Many2Many('party.party', None, None, 'Parties')
|
parties = fields.Many2Many('party.party', None, None, 'Parties')
|
||||||
type = fields.Selection([
|
type = fields.Selection([
|
||||||
('out', 'Customer'),
|
('out', 'Customer'),
|
||||||
# ('in', 'Supplier'),
|
|
||||||
], 'Type', required=True)
|
], 'Type', required=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -519,7 +528,8 @@ class PortfolioDetailedStart(ModelView):
|
||||||
class PortfolioDetailed(Wizard):
|
class PortfolioDetailed(Wizard):
|
||||||
'Portfolio Detailed'
|
'Portfolio Detailed'
|
||||||
__name__ = 'farming.portfolio_detailed'
|
__name__ = 'farming.portfolio_detailed'
|
||||||
start = StateView('farming.portfolio_detailed.start',
|
start = StateView(
|
||||||
|
'farming.portfolio_detailed.start',
|
||||||
'farming.print_sale_portfolio_detailed_start_view_form', [
|
'farming.print_sale_portfolio_detailed_start_view_form', [
|
||||||
Button('Cancel', 'end', 'tryton-cancel'),
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
Button('Print', 'print_', 'tryton-ok', default=True),
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
||||||
|
@ -545,7 +555,6 @@ class PortfolioDetailedReport(Report):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_domain_inv(cls, dom_sales, data):
|
def get_domain_inv(cls, dom_sales, data):
|
||||||
states = ['done']
|
|
||||||
dom_sales.append([
|
dom_sales.append([
|
||||||
('company', '=', data['company']),
|
('company', '=', data['company']),
|
||||||
])
|
])
|
||||||
|
@ -569,14 +578,14 @@ class PortfolioDetailedReport(Report):
|
||||||
Sale = pool.get('sale.sale')
|
Sale = pool.get('sale.sale')
|
||||||
dom_sales = []
|
dom_sales = []
|
||||||
dom_sales = cls.get_domain_inv(dom_sales, data)
|
dom_sales = cls.get_domain_inv(dom_sales, data)
|
||||||
sales = Sale.search(dom_sales,
|
sales = Sale.search(
|
||||||
|
dom_sales,
|
||||||
order=[('party.name', 'ASC'), ('shipping_date', 'ASC')]
|
order=[('party.name', 'ASC'), ('shipping_date', 'ASC')]
|
||||||
)
|
)
|
||||||
salesmans = {}
|
salesmans = {}
|
||||||
for sale in sales:
|
for sale in sales:
|
||||||
pay_to_date = []
|
pay_to_date = []
|
||||||
if data['to_date']:
|
if data['to_date']:
|
||||||
move_lines_paid = []
|
|
||||||
for line in sale.payments:
|
for line in sale.payments:
|
||||||
if line.date <= data['to_date']:
|
if line.date <= data['to_date']:
|
||||||
pay_to_date.append(line.amount)
|
pay_to_date.append(line.amount)
|
||||||
|
@ -584,12 +593,14 @@ class PortfolioDetailedReport(Report):
|
||||||
amount_to_pay = sale.total_amount - sum(pay_to_date)
|
amount_to_pay = sale.total_amount - sum(pay_to_date)
|
||||||
else:
|
else:
|
||||||
amount_to_pay = sale.residual_amount
|
amount_to_pay = sale.residual_amount
|
||||||
pay_to_date = [pay.amount for pay in sale.payments if pay.amount]
|
pay_to_date = [
|
||||||
|
pay.amount for pay in sale.payments if pay.amount]
|
||||||
|
|
||||||
if sale.total_amount == sum(pay_to_date):
|
if sale.total_amount == sum(pay_to_date):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if 'field_salesman' in data.keys() and data['field_salesman'] and sale.salesman:
|
if 'field_salesman' in data.keys() and \
|
||||||
|
data['field_salesman'] and sale.salesman:
|
||||||
if sale.salesman.id not in salesmans.keys():
|
if sale.salesman.id not in salesmans.keys():
|
||||||
salesmans[sale.salesman.id] = {
|
salesmans[sale.salesman.id] = {
|
||||||
'salesman': sale.salesman.party.full_name,
|
'salesman': sale.salesman.party.full_name,
|
||||||
|
@ -617,11 +628,12 @@ class PortfolioDetailedReport(Report):
|
||||||
'total_amount_to_pay': [],
|
'total_amount_to_pay': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
party_key = salesmans[salesman]['parties'][sale.party.id]
|
||||||
salesmans[salesman]['total_invoices'].append(sale.total_amount)
|
salesmans[salesman]['total_invoices'].append(sale.total_amount)
|
||||||
salesmans[salesman]['total_amount_to_pay'].append(amount_to_pay)
|
salesmans[salesman]['total_amount_to_pay'].append(amount_to_pay)
|
||||||
salesmans[salesman]['parties'][sale.party.id]['invoices'].append(sale)
|
party_key['invoices'].append(sale)
|
||||||
salesmans[salesman]['parties'][sale.party.id]['total_invoices'].append(sale.total_amount)
|
party_key['total_invoices'].append(sale.total_amount)
|
||||||
salesmans[salesman]['parties'][sale.party.id]['total_amount_to_pay'].append(amount_to_pay)
|
party_key['total_amount_to_pay'].append(amount_to_pay)
|
||||||
|
|
||||||
report_context['records'] = salesmans
|
report_context['records'] = salesmans
|
||||||
report_context['data'] = data
|
report_context['data'] = data
|
||||||
|
@ -638,7 +650,8 @@ class AduanaDetailedStart(ModelView):
|
||||||
class AduanaDetailed(Wizard):
|
class AduanaDetailed(Wizard):
|
||||||
'Aduana Detailed'
|
'Aduana Detailed'
|
||||||
__name__ = 'farming.aduana_detailed'
|
__name__ = 'farming.aduana_detailed'
|
||||||
start = StateView('farming.aduana_detailed.start',
|
start = StateView(
|
||||||
|
'farming.aduana_detailed.start',
|
||||||
'farming.aduana_detailed_start_view_form', [
|
'farming.aduana_detailed_start_view_form', [
|
||||||
Button('Cancel', 'end', 'tryton-cancel'),
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
Button('Print', 'print_', 'tryton-ok', default=True),
|
Button('Print', 'print_', 'tryton-ok', default=True),
|
||||||
|
@ -661,11 +674,10 @@ class AduanaDetailedReport(Report):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_context(cls, records, header, data):
|
def get_context(cls, records, header, data):
|
||||||
report_context = super().get_context(records, header, data)
|
report_context = super().get_context(records, header, data)
|
||||||
|
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
Sale = pool.get('sale.sale')
|
Sale = pool.get('sale.sale')
|
||||||
sales = Sale.search( ('shipping_date', '=', data['date']))
|
sales = Sale.search(('shipping_date', '=', data['date']))
|
||||||
reportSales = {}
|
report_sales = {}
|
||||||
for sale in sales:
|
for sale in sales:
|
||||||
if sale.number:
|
if sale.number:
|
||||||
total_weight = 0
|
total_weight = 0
|
||||||
|
@ -677,21 +689,20 @@ class AduanaDetailedReport(Report):
|
||||||
elif line.packing_uom.symbol == 'HB':
|
elif line.packing_uom.symbol == 'HB':
|
||||||
total_weight = total_weight + (line.packing_qty * 8.5)
|
total_weight = total_weight + (line.packing_qty * 8.5)
|
||||||
|
|
||||||
reportSales[sale.number] = {
|
report_sales[sale.number] = {
|
||||||
'client': sale.party.name,
|
'client': sale.party.name,
|
||||||
'nit' : sale.carrier.id_number,
|
'nit': sale.carrier.id_number,
|
||||||
'guia' : sale.mawb,
|
'guia': sale.mawb,
|
||||||
'global' : sale.party.global_aduana,
|
'global': sale.custom_global and sale.custom_global.global_custom,
|
||||||
'invoice' : sale.number,
|
'invoice': sale.number,
|
||||||
'code' : '0001',
|
'code': '0001',
|
||||||
'product' : 'Hidrangea',
|
'product': 'Hidrangea',
|
||||||
'units' : sale.unit_qty,
|
'units': sale.unit_qty,
|
||||||
'pieces' : sale.packing_qty,
|
'pieces': sale.packing_qty,
|
||||||
'weight' : total_weight,
|
'weight': total_weight,
|
||||||
'total' : sale.total_amount,
|
'total': sale.total_amount,
|
||||||
'license_plate' : 'WHO-265',
|
'license_plate': 'WHO-265',
|
||||||
}
|
}
|
||||||
report_context['records'] = reportSales.values()
|
report_context['records'] = report_sales.values()
|
||||||
|
|
||||||
return report_context
|
return report_context
|
||||||
|
|
||||||
|
|
27
stock.py
27
stock.py
|
@ -1,10 +1,5 @@
|
||||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
# this repository contains the full copyright notices and license terms.
|
# this repository contains the full copyright notices and license terms.
|
||||||
from dataclasses import field
|
|
||||||
from datetime import date
|
|
||||||
from itertools import product
|
|
||||||
from operator import index
|
|
||||||
from shutil import move
|
|
||||||
from trytond.model import fields, ModelView, ModelSQL
|
from trytond.model import fields, ModelView, ModelSQL
|
||||||
from trytond.pool import PoolMeta, Pool
|
from trytond.pool import PoolMeta, Pool
|
||||||
from trytond.pyson import Eval
|
from trytond.pyson import Eval
|
||||||
|
@ -19,10 +14,9 @@ class StockLot(metaclass=PoolMeta):
|
||||||
quantity_purchase = fields.Float('Quantity Purchase',
|
quantity_purchase = fields.Float('Quantity Purchase',
|
||||||
digits=(16, Eval('unit_digits', 2)))
|
digits=(16, Eval('unit_digits', 2)))
|
||||||
arrival_date = fields.Date('Arrival Date')
|
arrival_date = fields.Date('Arrival Date')
|
||||||
balance = fields.Float('Balance',
|
balance = fields.Float('Balance', digits=(16, Eval('unit_digits', 2)))
|
||||||
digits=(16, Eval('unit_digits', 2)))
|
balance_export = fields.Float('Balance Export', digits=(16,
|
||||||
balance_export = fields.Float('Balance Export',
|
Eval('unit_digits', 2)))
|
||||||
digits=(16, Eval('unit_digits', 2)))
|
|
||||||
location = fields.Char('Location')
|
location = fields.Char('Location')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -62,15 +56,12 @@ class PythoMove(ModelSQL, ModelView):
|
||||||
__name__ = 'stock.lot.phyto.move'
|
__name__ = 'stock.lot.phyto.move'
|
||||||
lot = fields.Many2One('stock.lot', 'Lot', select=True,
|
lot = fields.Many2One('stock.lot', 'Lot', select=True,
|
||||||
ondelete='CASCADE')
|
ondelete='CASCADE')
|
||||||
exportation_phyto = fields.Many2One('exportation.phyto', 'Exportation Phyto', select=True)
|
exportation_phyto = fields.Many2One(
|
||||||
#subproduction = fields.Many2One('production', 'Sub-Production')
|
'exportation.phyto', 'Exportation Phyto', select=True)
|
||||||
#stock_move = fields.Many2One('stock.move', 'Moves Stock')
|
|
||||||
origin = fields.Reference('Origin', selection='get_origin')
|
origin = fields.Reference('Origin', selection='get_origin')
|
||||||
date_move = fields.Date("Date Move")
|
date_move = fields.Date("Date Move")
|
||||||
move_in = fields.Float('Move In',
|
move_in = fields.Float('Move In', digits=(16, Eval('unit_digits', 2)))
|
||||||
digits=(16, Eval('unit_digits', 2)))
|
move_out = fields.Float('Move out', digits=(16, Eval('unit_digits', 2)))
|
||||||
move_out = fields.Float('Move out',
|
|
||||||
digits=(16, Eval('unit_digits', 2)))
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_origin(cls):
|
def _get_origin(cls):
|
||||||
|
@ -108,13 +99,13 @@ class StockMove(metaclass=PoolMeta):
|
||||||
}
|
}
|
||||||
farming = fields.Boolean('Farming')
|
farming = fields.Boolean('Farming')
|
||||||
original_qty = fields.Float('Qty Original', states=STATES)
|
original_qty = fields.Float('Qty Original', states=STATES)
|
||||||
#move_phyto = fields.One2Many('stock.lot.phyto.move', 'stock_move', 'Move Phyto')
|
|
||||||
production = fields.Many2One("production", "Production")
|
production = fields.Many2One("production", "Production")
|
||||||
style = fields.Many2One('product.style', 'Style')
|
style = fields.Many2One('product.style', 'Style')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_origin(cls):
|
def _get_origin(cls):
|
||||||
return super(StockMove, cls)._get_origin() + ['production', 'farming.crop.activity']
|
return super(StockMove, cls)._get_origin() + [
|
||||||
|
'production', 'farming.crop.activity']
|
||||||
|
|
||||||
|
|
||||||
class ShipmentIn(metaclass=PoolMeta):
|
class ShipmentIn(metaclass=PoolMeta):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[tryton]
|
[tryton]
|
||||||
version=6.0.31
|
version=6.0.32
|
||||||
depends:
|
depends:
|
||||||
party
|
party
|
||||||
company
|
company
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<form>
|
||||||
|
<label name="export_target_city"/>
|
||||||
|
<field name="export_target_city"/>
|
||||||
|
<label name="global_custom"/>
|
||||||
|
<field name="global_custom"/>
|
||||||
|
</form>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tree>
|
||||||
|
<field name="export_target_city" expand="1"/>
|
||||||
|
<field name="global_custom" expand="1"/>
|
||||||
|
</tree>
|
|
@ -6,10 +6,8 @@ this repository contains the full copyright notices and license terms. -->
|
||||||
<label name="carrier"/>
|
<label name="carrier"/>
|
||||||
<field name="carrier"/>
|
<field name="carrier"/>
|
||||||
<label name="freight_forwader"/>
|
<label name="freight_forwader"/>
|
||||||
<field name="freight_forwader"/>
|
<field name="freight_forwader"/>>
|
||||||
<label name="export_route"/>
|
<field name="customs_globals" colspan="4"/>
|
||||||
<field name="export_route"/>
|
|
||||||
<label name="global_aduana"/>
|
|
||||||
<field name="global_aduana"/>
|
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -25,6 +25,8 @@ copyright notices and license terms. -->
|
||||||
<field name="export_target_city"/>
|
<field name="export_target_city"/>
|
||||||
<label name="export_route"/>
|
<label name="export_route"/>
|
||||||
<field name="export_route"/>
|
<field name="export_route"/>
|
||||||
|
<label name="custom_global"/>
|
||||||
|
<field name="custom_global"/>
|
||||||
</page>
|
</page>
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
|
|
Loading…
Reference in New Issue