Create moves and invoices while processing the weighing. (#14)
Task #045017
This commit is contained in:
parent
91b5822cc2
commit
3c6ec5295e
|
@ -45,6 +45,7 @@ def register():
|
||||||
weighing.Weighing,
|
weighing.Weighing,
|
||||||
weighing.WeighingPlantation,
|
weighing.WeighingPlantation,
|
||||||
weighing.WeighingDo,
|
weighing.WeighingDo,
|
||||||
|
weighing.WeighingInvoice,
|
||||||
weighing.WeighingParcel,
|
weighing.WeighingParcel,
|
||||||
quality.Configuration,
|
quality.Configuration,
|
||||||
quality.ConfigurationCompany,
|
quality.ConfigurationCompany,
|
||||||
|
|
|
@ -41,7 +41,7 @@ class AgronomicsContract(Workflow, ModelSQL, ModelView):
|
||||||
start_date = fields.Function(
|
start_date = fields.Function(
|
||||||
fields.Date('Start Date'), 'on_change_with_start_date')
|
fields.Date('Start Date'), 'on_change_with_start_date')
|
||||||
end_date = fields.Function(
|
end_date = fields.Function(
|
||||||
fields.Date('End Date'), 'on_change_with_start_date')
|
fields.Date('End Date'), 'on_change_with_end_date')
|
||||||
producer = fields.Many2One(
|
producer = fields.Many2One(
|
||||||
'party.party', "Producer", states=_STATES, depends=_DEPENDS,
|
'party.party', "Producer", states=_STATES, depends=_DEPENDS,
|
||||||
required=True)
|
required=True)
|
||||||
|
|
|
@ -42,5 +42,8 @@ this repository contains the full copyright notices and license terms. -->
|
||||||
<record model="ir.message" id="msg_cant_active_contract">
|
<record model="ir.message" id="msg_cant_active_contract">
|
||||||
<field name="text">The contract "%(contract)s" cant be activated because the parcel "%(parcel)s" is in another active contract.</field>
|
<field name="text">The contract "%(contract)s" cant be activated because the parcel "%(parcel)s" is in another active contract.</field>
|
||||||
</record>
|
</record>
|
||||||
|
<record model="ir.message" id="msg_location_no_configured">
|
||||||
|
<field name="text">The weighing center "%(center)s" dont have a to location configured.</field>
|
||||||
|
</record>
|
||||||
</data>
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|
|
@ -11,6 +11,7 @@ depends:
|
||||||
quality_control
|
quality_control
|
||||||
production
|
production
|
||||||
stock
|
stock
|
||||||
|
account_invoice_line_standalone
|
||||||
xml:
|
xml:
|
||||||
plot.xml
|
plot.xml
|
||||||
party.xml
|
party.xml
|
||||||
|
|
|
@ -3,4 +3,8 @@
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<label name="weighing_sequence"/>
|
<label name="weighing_sequence"/>
|
||||||
<field name="weighing_sequence"/>
|
<field name="weighing_sequence"/>
|
||||||
|
<label name="warehouse"/>
|
||||||
|
<field name="warehouse"/>
|
||||||
|
<label name="to_location"/>
|
||||||
|
<field name="to_location"/>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
<field name="product_created"/>
|
<field name="product_created"/>
|
||||||
<label name="quality_test"/>
|
<label name="quality_test"/>
|
||||||
<field name="quality_test"/>
|
<field name="quality_test"/>
|
||||||
|
<label name="inventory_move"/>
|
||||||
|
<field name="inventory_move"/>
|
||||||
|
|
||||||
<notebook>
|
<notebook>
|
||||||
<page name="plantations">
|
<page name="plantations">
|
||||||
|
@ -37,6 +39,7 @@
|
||||||
</page>
|
</page>
|
||||||
<page name="beneficiaries">
|
<page name="beneficiaries">
|
||||||
<field name="beneficiaries" colspan="4"/>
|
<field name="beneficiaries" colspan="4"/>
|
||||||
|
<field name="beneficiaries_invoices_line" colspan="4"/>
|
||||||
</page>
|
</page>
|
||||||
<page string="Parcel Distribution" id="parcel_distribution" >
|
<page string="Parcel Distribution" id="parcel_distribution" >
|
||||||
<field name="parcels" colspan="4"/>
|
<field name="parcels" colspan="4"/>
|
||||||
|
|
137
weighing.py
137
weighing.py
|
@ -7,6 +7,7 @@ from trytond.i18n import gettext
|
||||||
from trytond.exceptions import UserError
|
from trytond.exceptions import UserError
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
class WeighingCenter(ModelSQL, ModelView):
|
class WeighingCenter(ModelSQL, ModelView):
|
||||||
""" Weighing Center """
|
""" Weighing Center """
|
||||||
|
@ -17,7 +18,9 @@ class WeighingCenter(ModelSQL, ModelView):
|
||||||
domain=[
|
domain=[
|
||||||
('sequence_type', '=', Id('agronomics', 'sequence_type_weighing'))
|
('sequence_type', '=', Id('agronomics', 'sequence_type_weighing'))
|
||||||
])
|
])
|
||||||
|
warehouse = fields.Many2One('stock.location', "Warehouse",
|
||||||
|
domain=[('type', '=', 'warehouse')])
|
||||||
|
to_location = fields.Many2One('stock.location', "To Location")
|
||||||
|
|
||||||
READONLY = ['processing', 'distributed', 'in_analysis', 'done', 'cancelled']
|
READONLY = ['processing', 'distributed', 'in_analysis', 'done', 'cancelled']
|
||||||
READONLY2 = ['draft', 'distributed', 'in_analysis', 'done', 'cancelled']
|
READONLY2 = ['draft', 'distributed', 'in_analysis', 'done', 'cancelled']
|
||||||
|
@ -86,6 +89,9 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
||||||
'readonly': Eval('state').in_(READONLY2),
|
'readonly': Eval('state').in_(READONLY2),
|
||||||
'required': Eval('state') == 'in_analysis',
|
'required': Eval('state') == 'in_analysis',
|
||||||
})
|
})
|
||||||
|
beneficiaries_invoices_line = fields.Many2Many(
|
||||||
|
'agronomics.weighing-account.invoice.line', 'weighing', 'invoice_line',
|
||||||
|
"Beneficiaries Invoices", readonly=True)
|
||||||
plantations = fields.One2Many('agronomics.weighing-agronomics.plantation',
|
plantations = fields.One2Many('agronomics.weighing-agronomics.plantation',
|
||||||
'weighing', 'plantations', states={
|
'weighing', 'plantations', states={
|
||||||
'readonly': Eval('state').in_(READONLY),
|
'readonly': Eval('state').in_(READONLY),
|
||||||
|
@ -113,6 +119,9 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
||||||
not_assigned_weight = fields.Function(
|
not_assigned_weight = fields.Function(
|
||||||
fields.Float('Not Assigned Weight'), 'get_not_assigned_weight')
|
fields.Float('Not Assigned Weight'), 'get_not_assigned_weight')
|
||||||
forced_analysis = fields.Boolean('Forced Analysis', readonly=True)
|
forced_analysis = fields.Boolean('Forced Analysis', readonly=True)
|
||||||
|
inventory_move = fields.Many2One('stock.move', "Inventory Move",
|
||||||
|
readonly=True)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __setup__(cls):
|
def __setup__(cls):
|
||||||
|
@ -273,10 +282,23 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
Product = pool.get('product.product')
|
Product = pool.get('product.product')
|
||||||
Quality = pool.get('quality.test')
|
Quality = pool.get('quality.test')
|
||||||
Variety = Pool().get('product.variety')
|
Variety = pool.get('product.variety')
|
||||||
|
Move = pool.get('stock.move')
|
||||||
|
Location = pool.get('stock.location')
|
||||||
|
|
||||||
|
supplier_location = Location.search([('code', '=', 'SUP')], limit=1)
|
||||||
|
if not supplier_location:
|
||||||
|
#Supplier location not found
|
||||||
|
raise UserError()
|
||||||
|
|
||||||
default_product_values = Product.default_get(Product._fields.keys(),
|
default_product_values = Product.default_get(Product._fields.keys(),
|
||||||
with_rec_name=False)
|
with_rec_name=False)
|
||||||
product = Product(**default_product_values)
|
product = Product(**default_product_values)
|
||||||
|
default_move_values = Move.default_get(Move._fields.keys(),
|
||||||
|
with_rec_name=False)
|
||||||
|
move = Move(**default_move_values)
|
||||||
|
|
||||||
|
to_done = []
|
||||||
for weighing in weighings:
|
for weighing in weighings:
|
||||||
if weighing.not_assigned_weight and not weighing.forced_analysis:
|
if weighing.not_assigned_weight and not weighing.forced_analysis:
|
||||||
raise UserError(gettext('agronomics.msg_not_assigned_weight',
|
raise UserError(gettext('agronomics.msg_not_assigned_weight',
|
||||||
|
@ -293,7 +315,27 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
||||||
product.vintages = [weighing.crop.id]
|
product.vintages = [weighing.crop.id]
|
||||||
weighing.product_created = product
|
weighing.product_created = product
|
||||||
|
|
||||||
|
if not weighing.weighing_center:
|
||||||
|
raise UserError()
|
||||||
|
|
||||||
|
# Create Move
|
||||||
|
move.from_location = supplier_location[0]
|
||||||
|
if not weighing.weighing_center.to_location:
|
||||||
|
raise UserError(
|
||||||
|
gettext('agronomics.msg_location_no_configured',
|
||||||
|
center=weighing.weighing_center.name))
|
||||||
|
move.to_location = weighing.weighing_center.to_location
|
||||||
|
move.product = weighing.product_created
|
||||||
|
move.uom = weighing.product_created.template.default_uom
|
||||||
|
move.unit_price = weighing.product_created.template.list_price
|
||||||
|
move.quantity = weighing.netweight or 0
|
||||||
|
|
||||||
|
weighing.inventory_move = move
|
||||||
|
to_done.append(move)
|
||||||
|
|
||||||
cls.save(weighings)
|
cls.save(weighings)
|
||||||
|
with Transaction().set_context(_skip_warnings=True):
|
||||||
|
Move.do(to_done)
|
||||||
tests = []
|
tests = []
|
||||||
for weighing in weighings:
|
for weighing in weighings:
|
||||||
tests.append(weighing.create_quality_test())
|
tests.append(weighing.create_quality_test())
|
||||||
|
@ -395,7 +437,86 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
||||||
@classmethod
|
@classmethod
|
||||||
@Workflow.transition('done')
|
@Workflow.transition('done')
|
||||||
def done(cls, weighings):
|
def done(cls, weighings):
|
||||||
pass
|
pool = Pool()
|
||||||
|
InvoiceLine = pool.get('account.invoice.line')
|
||||||
|
Product = pool.get('product.product')
|
||||||
|
Company = pool.get('company.company')
|
||||||
|
context = Transaction().context
|
||||||
|
ContractProductPriceListTypePriceList = pool.get(
|
||||||
|
'agronomics.contract-product.price_list.type-product.price_list')
|
||||||
|
WeighingInvoiceLine = pool.get(
|
||||||
|
'agronomics.weighing-account.invoice.line')
|
||||||
|
RecomputeCostPrice = pool.get('product.recompute_cost_price',
|
||||||
|
type='wizard')
|
||||||
|
Move = pool.get('stock.move')
|
||||||
|
|
||||||
|
default_invoice_line_values = InvoiceLine.default_get(
|
||||||
|
InvoiceLine._fields.keys(), with_rec_name=False)
|
||||||
|
invoice_line = InvoiceLine(**default_invoice_line_values)
|
||||||
|
|
||||||
|
to_save = []
|
||||||
|
to_save_moves = []
|
||||||
|
to_recompute_products = []
|
||||||
|
for weighing in weighings:
|
||||||
|
cost_price = Decimal(0)
|
||||||
|
if weighing.beneficiaries:
|
||||||
|
for beneficiary in weighing.beneficiaries:
|
||||||
|
price_list = ContractProductPriceListTypePriceList.search([
|
||||||
|
('contract', '=', weighing.purchase_contract),
|
||||||
|
('price_list_type', '=',
|
||||||
|
beneficiary.product_price_list_type),
|
||||||
|
])
|
||||||
|
|
||||||
|
invoice_line = InvoiceLine()
|
||||||
|
invoice_line.type = 'line'
|
||||||
|
invoice_line.invoice_type = 'in'
|
||||||
|
invoice_line.party = beneficiary.party
|
||||||
|
invoice_line.currency = (
|
||||||
|
Company(context['company']).currency)
|
||||||
|
invoice_line.company = Company(context['company'])
|
||||||
|
invoice_line.description = ''
|
||||||
|
invoice_line.product = weighing.product_created
|
||||||
|
invoice_line.on_change_product()
|
||||||
|
invoice_line.quantity = weighing.netweight or 0
|
||||||
|
|
||||||
|
unit_price = Product.get_purchase_price(
|
||||||
|
[weighing.product_created],
|
||||||
|
abs(weighing.netweight or 0))[
|
||||||
|
weighing.product_created.id]
|
||||||
|
if price_list:
|
||||||
|
if price_list[0].price_list:
|
||||||
|
price_list = price_list[0].price_list
|
||||||
|
unit_price = price_list.compute(beneficiary.party,
|
||||||
|
weighing.product_created, unit_price,
|
||||||
|
weighing.netweight or 0,
|
||||||
|
weighing.product_created.template.default_uom)
|
||||||
|
unit_price = unit_price
|
||||||
|
invoice_line.unit_price = unit_price
|
||||||
|
cost_price += unit_price
|
||||||
|
|
||||||
|
weighing_invoice = WeighingInvoiceLine(
|
||||||
|
weighing=weighing,
|
||||||
|
invoice_line=invoice_line
|
||||||
|
)
|
||||||
|
to_save.append(weighing_invoice)
|
||||||
|
|
||||||
|
weighing.inventory_move.unit_price = cost_price
|
||||||
|
weighing.inventory_move.unit_price_updated = True
|
||||||
|
weighing.product_created.cost_price = cost_price
|
||||||
|
to_save_moves.append(weighing.inventory_move)
|
||||||
|
to_recompute_products.append(weighing.product_created)
|
||||||
|
Product.save([weighing.product_created])
|
||||||
|
|
||||||
|
session_id, _, _ = RecomputeCostPrice.create()
|
||||||
|
recompute_cost_price = RecomputeCostPrice(session_id)
|
||||||
|
recompute_cost_price.model = Product
|
||||||
|
recompute_cost_price.records = [weighing.product_created]
|
||||||
|
default_values = recompute_cost_price.default_start({})
|
||||||
|
recompute_cost_price.start.from_ = default_values['from_']
|
||||||
|
recompute_cost_price.transition_recompute()
|
||||||
|
|
||||||
|
WeighingInvoiceLine.save(to_save)
|
||||||
|
Move.save(to_save_moves)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@Workflow.transition('processing')
|
@Workflow.transition('processing')
|
||||||
|
@ -448,9 +569,11 @@ class Weighing(Workflow, ModelSQL, ModelView):
|
||||||
else:
|
else:
|
||||||
default = default.copy()
|
default = default.copy()
|
||||||
default.setdefault('beneficiaries', None)
|
default.setdefault('beneficiaries', None)
|
||||||
|
default.setdefault('beneficiaries_invoices_line', None)
|
||||||
default.setdefault('product_created', None)
|
default.setdefault('product_created', None)
|
||||||
default.setdefault('number', None)
|
default.setdefault('number', None)
|
||||||
default.setdefault('parcels', None)
|
default.setdefault('parcels', None)
|
||||||
|
default.setdefault('inventory_move', None)
|
||||||
return super().copy(weighings, default=default)
|
return super().copy(weighings, default=default)
|
||||||
|
|
||||||
|
|
||||||
|
@ -463,6 +586,14 @@ class WeighingDo(ModelSQL):
|
||||||
'Denomination Origin')
|
'Denomination Origin')
|
||||||
|
|
||||||
|
|
||||||
|
class WeighingInvoice(ModelSQL):
|
||||||
|
"Weighing - Invoice"
|
||||||
|
__name__ = 'agronomics.weighing-account.invoice.line'
|
||||||
|
|
||||||
|
weighing = fields.Many2One('agronomics.weighing', "Weighing")
|
||||||
|
invoice_line = fields.Many2One('account.invoice.line', "Invoice Line")
|
||||||
|
|
||||||
|
|
||||||
class WeighingPlantation(sequence_ordered(), ModelSQL, ModelView):
|
class WeighingPlantation(sequence_ordered(), ModelSQL, ModelView):
|
||||||
'Weighing - Plantations'
|
'Weighing - Plantations'
|
||||||
__name__ = 'agronomics.weighing-agronomics.plantation'
|
__name__ = 'agronomics.weighing-agronomics.plantation'
|
||||||
|
|
Loading…
Reference in New Issue