trytonpsk-farming/supplier_certificate.py

257 lines
11 KiB
Python

from trytond.model import fields, ModelSQL, ModelView, Unique, Workflow
from trytond.pool import Pool
# from trytond.transaction import Transaction
# from trytond.wizard import Button, StateTransition, StateView, Wizard
from trytond.pyson import Eval
from decimal import Decimal
from trytond.exceptions import UserError
from lxml import etree
from datetime import datetime, timedelta
class SupplierCertificate(Workflow, ModelSQL, ModelView):
"""Supplier Certificate"""
__name__ = 'farming.supplier_certificate'
number = fields.Char('Number', states={
'readonly': True
})
# supplier = fields.Many2Many('party.party', 'Supplier')
suppliers = fields.Many2Many('farming.supplier_certificate-party.party', 'supplier_certificate',
'party', 'Party')
provider_link = fields.Char('Link Mail')
start_date = fields.Date('Start Date')
end_date = fields.Date('End Date')
invoice_lines = fields.Many2Many('farming.supplier_certificate-account_invoice_line', 'supplier_certificate',
'invoice_line', 'Invoice Lines', domain=[
('invoice.type', '=', 'in'),
('invoice.party', 'in', Eval('suppliers')),
('product.exportable', '=', True),
('invoice.invoice_date', '>=', Eval('start_date')),
('invoice.invoice_date', '<=', Eval('end_date')),
], depends=['suppliers', 'start_date', 'end_date'])
# ('invoice', '=', Eval('invoice')),
state = fields.Selection([
('draft', 'Draft'),
('cancelled', 'Cancelled'),
('done', 'Done'),
('processed', 'Processed'),
], 'State', readonly=True, select=True)
total_amount = fields.Function(fields.Numeric('Total_amount'), 'get_total_amount')
vat_amount = fields.Function(fields.Numeric('Vat Amount'), 'get_vat_amount')
xml_certificate = fields.Text('XML Certificate')
@classmethod
def __setup__(cls):
super(SupplierCertificate, cls).__setup__()
cls._transitions |= set((
('draft', 'processed'),
('processed', 'done'),
('processed', 'cancelled'),
))
cls._buttons.update({
'draft': {
'invisible': Eval('state').in_(['draft', 'processed', 'done'])
},
'cancel': {
'invisible': Eval('state').in_(['cancelled', 'draft', 'done']),
},
'process': {
'invisible': Eval('state') != 'draft',
},
'done': {
'invisible': Eval('state').in_(['draft', 'cancelled', 'done']),
},
'create_certificate': {
}
})
@classmethod
@ModelView.button
@Workflow.transition('draft')
def draft(cls, records):
pass
@classmethod
@ModelView.button
@Workflow.transition('cancelled')
def cancel(cls, records):
pass
@classmethod
@ModelView.button
@Workflow.transition('processed')
def process(cls, records):
for record in records:
record.set_number()
@classmethod
@ModelView.button
@Workflow.transition('done')
def done(cls, records):
pass
@staticmethod
def default_state():
return 'draft'
def get_total_amount(self, name):
total_amount = 0
if self.invoice_lines:
for invoice_line in self.invoice_lines:
total_amount += invoice_line.amount
return Decimal(total_amount)
def get_vat_amount(self, name):
total_amount_taxes = 0
TAX = Pool().get('account.tax')
iva = TAX(2)
if self.invoice_lines:
for invoice_line in self.invoice_lines:
# total_amount_taxes += invoice_line.amount * iva.rate * Decimal(invoice_line.quantity)
total_amount_taxes += invoice_line.amount * iva.rate
return Decimal(total_amount_taxes)
@classmethod
@ModelView.button
def create_certificate(cls, certificates):
for record in certificates:
date_exp = record.start_date + timedelta(days=180)
flimexp = date_exp.strftime("%Y-%m-%d")
root = etree.Element("mas", nsmap={"xsi": "http://www.w3.org/2001/XMLSchema-instance"})
root.set("{http://www.w3.org/2001/XMLSchema-instance}noNamespaceSchemaLocation", "../xsd/640.xsd")
cab = etree.SubElement(root, "Cab")
elements_to_add = {
"Ano": str(record.start_date.year),
"CodCpt": "1",
"Formato": "640",
"Version": "1",
"NumEnvio": record.number,
"FecEnvio": str(datetime.today().isoformat()).split('.')[0],
"FecInicial": str(record.start_date),
"FecFinal": str(record.start_date),
"ValorTotal": "31",
"CantReg": str(len(record.suppliers))
}
for tag, text in elements_to_add.items():
element = etree.Element(tag)
element.text = text
cab.append(element)
pool = Pool()
Authorization = pool.get('account.invoice.authorization')
for supplier in record.suppliers:
resolution_number = supplier.invoice_authorization.number
start_date_auth = supplier.invoice_authorization.start_date_auth
invoice_lines = []
vtcons = 0
vtexen = 0
for line in record.invoice_lines:
try:
autorization, = Authorization.search([('id', '=', line.invoice.authorization)])
except:
autorization = '9999'
if line.invoice.party == supplier:
harmonized_tariff_schedule = line.product.harmonized_tariff_schedule
invoice_line_dict = {
'nfact': line.invoice.reference,
'ffac': str(line.invoice.invoice_date),
'resfac': resolution_number,
'fres': str(start_date_auth),
'tipo': '1',
'subp': harmonized_tariff_schedule.code,
'desc': line.product.description if line.product.description else line.product.name,
'cunfi': f"{line.quantity:.6f}",
'unfi': harmonized_tariff_schedule.uom.symbol,
'cunco': f"{line.quantity:.6f}",
'unco': 'NAR',
'vuni': line.unit_price,
'amount': round(float(line.unit_price) * line.quantity, 6),
'tiva': '19.00',
'vexen': round((float(line.unit_price) * line.quantity) * 0.19, 6),
'codins': line.product.code,
}
vtcons += invoice_line_dict['amount']
vtexen += invoice_line_dict['vexen']
invoice_lines.append(invoice_line_dict)
cp = etree.SubElement(root, "cp")
cp.set("cpto", "1")
cp.set("tdoc", supplier.type_document)
cp.set("ndoc", supplier.id_number)
if supplier.type_document == '31':
cp.set("razsoc", supplier.name)
else:
cp.set("apl1", supplier.patient.first_family_name)
cp.set("apl2", supplier.patient.second_family_name)
cp.set("nom1", supplier.first_name)
cp.set("nom2", supplier.second_name)
cp.set("cantfac", "1")
cp.set("vtcons", f"{vtcons:.6f}")
cp.set("vtexen", f"{vtexen:.6f}")
cp.set("flimexp", flimexp)
cp.set("nitems", str(len(invoice_lines)))
for line in invoice_lines:
cphoja2 = etree.SubElement(cp, "cphoja2")
cphoja2.set("nfact", line['nfact'])
cphoja2.set("ffac", line['ffac'])
cphoja2.set("resfac", line['resfac'])
cphoja2.set("fres", line['fres'])
cphoja2.set("tipo", '1')
cphoja2.set("subp", line['subp'])
cphoja2.set("desc", line['desc'])
cphoja2.set("cunfi", line['cunfi'])
cphoja2.set("unfi", line['unfi'])
cphoja2.set("cunco", line['cunco'])
cphoja2.set("unco", 'NAR')
cphoja2.set("vuni", f"{line['vuni']:.6f}")
cphoja2.set("vtotal", f"{line['amount']:.6f}")
cphoja2.set("tiva", '19.00')
cphoja2.set("vexen", f"{line['vexen']:.6f}")
cphoja2.set("codins", line['codins'])
tree = etree.ElementTree(root)
record.xml_certificate = etree.tostring(tree, xml_declaration=True, pretty_print=True, encoding="ISO-8859-1").decode("ISO-8859-1")
record.save()
def set_number(self):
pool = Pool()
Config = pool.get('account.configuration')
config = Config(1)
if self.number:
return
if not config.sequence_supplier_certificate:
raise UserError('No existe secuencia de certificado de proveedor')
number = config.certificate_sequence.get()
self.write([self], {'number': number})
class SupplierCetificateInvoiceLine(ModelSQL):
'Supplier certificate - invoice Line'
__name__ = 'farming.supplier_certificate-account_invoice_line'
_table = 'supplier_certificate-account_invoice_line'
supplier_certificate = fields.Many2One('farming.supplier_certificate',
'Supplier Certificate', select=True, required=True, ondelete='CASCADE')
invoice_line = fields.Many2One('account.invoice.line', 'Invoice Line',
ondelete='CASCADE', select=True, required=True)
@classmethod
def __setup__(cls):
super(SupplierCetificateInvoiceLine, cls).__setup__()
table = cls.__table__()
cls._sql_constraints += [
('invoice_line_uniq', Unique(table, table.invoice_line),
'invoice line already exists!'),
]
class SupplierCetificateParty(ModelSQL):
'Supplier certificate - invoice Line'
__name__ = 'farming.supplier_certificate-party.party'
_table = 'supplier_certificate-party_party'
supplier_certificate = fields.Many2One('farming.supplier_certificate',
'Supplier Certificate', select=True, required=True, ondelete='CASCADE')
party = fields.Many2One('party.party', 'Party',
ondelete='CASCADE', select=True, required=True)