Create moves and invoices while processing the weighing. (#14)

Task #045017
This commit is contained in:
juanjo-nan 2022-05-10 14:37:09 +02:00 committed by Juanjo Garcia
parent 91b5822cc2
commit 3c6ec5295e
7 changed files with 147 additions and 4 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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"/>

View File

@ -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'