mirror of
https://bitbucket.org/presik/trytonpsk-sale_pos_frontend_rest.git
synced 2023-12-14 06:12:59 +01:00
353 lines
13 KiB
Python
353 lines
13 KiB
Python
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
# this repository contains the full copyright notices and license terms.
|
|
from __future__ import unicode_literals
|
|
from datetime import date
|
|
from trytond.pool import PoolMeta, Pool
|
|
from trytond.model import fields
|
|
from trytond.pyson import Eval
|
|
from trytond.transaction import Transaction
|
|
from trytond.wizard import Wizard
|
|
|
|
|
|
__all__ = ['Sale', 'Shop']
|
|
|
|
KIND = [
|
|
('', ''),
|
|
('take_away', 'Take Away'),
|
|
('delivery', 'Delivery'),
|
|
('to_table', 'To Table')
|
|
]
|
|
|
|
|
|
class Sale(metaclass=PoolMeta):
|
|
__name__ = 'sale.sale'
|
|
consumer = fields.Many2One('party.consumer', 'Consumer')
|
|
table_assigned = fields.Many2One('sale.shop.table', 'Table Assigned',
|
|
domain=[
|
|
('shop', '=', Eval('shop'))
|
|
])
|
|
productions = fields.Function(fields.One2Many('production', None, 'Productions'), 'get_productions')
|
|
delivery_time = fields.Numeric('Delivery Time (Min)', help="In Minutes")
|
|
# kind = fields.Selection([
|
|
# ('', ''),
|
|
# ('delivery', 'Delivery'),
|
|
# ('take_away', 'Take Away'),
|
|
# ('to_table', 'To Table'),
|
|
# ], 'Kind Order')
|
|
# kind_string = kind.translated('kind')
|
|
shipping_time = fields.Time('Shipping Time')
|
|
waiting_time = fields.Function(fields.Integer('Shipping Time',
|
|
help="In Minutes"), 'get_waiting_time')
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(Sale, cls).__setup__()
|
|
cls._error_messages.update({
|
|
'product_without_bom': (
|
|
"The product '%(product)s' has no production bom"),
|
|
'message_error': 'Error: %s',
|
|
},)
|
|
|
|
def get_waiting_time(self, name=None):
|
|
if self.state in ('draft', 'quotation', 'confirmed', 'processing'):
|
|
delta = int((self.write_date - self.create_date).seconds / 60)
|
|
return delta
|
|
|
|
@classmethod
|
|
def import_data(cls, fields_names, data):
|
|
pool = Pool()
|
|
Product = pool.get('product.product')
|
|
Party = pool.get('party.party')
|
|
Address = pool.get('party.address')
|
|
SaleLine = pool.get('sale.line')
|
|
Journal = pool.get('account.statement.journal')
|
|
config = pool.get('sale.configuration')(1)
|
|
user_ = pool.get('res.user')(Transaction().user)
|
|
shop_id = user_.shop.id
|
|
device_id = user_.sale_device.id
|
|
count = 0
|
|
sale_to_create = {}
|
|
sale_tip_product = {}
|
|
create_lines = []
|
|
sales_to_pay = []
|
|
tip_product = None
|
|
if config:
|
|
tip_product = config.tip_product.id
|
|
for row in data[1:]:
|
|
code_ = row[3].replace(' ', '')
|
|
products = Product.search([
|
|
('code', '=', code_)
|
|
])
|
|
|
|
if not products:
|
|
cls.raise_user_error('message_error',
|
|
('No se encontro un producto para el código: ' + row[3])
|
|
)
|
|
product = products[0]
|
|
if not product.salable:
|
|
print(product.code, product.name)
|
|
# day, month, year = row[2].split('/')
|
|
# sale_date = date(int(year), int(month), int(day))
|
|
# partys = Party.search([
|
|
# ('id_number', '=', row[1])
|
|
# ])
|
|
# if not partys:
|
|
# cls.raise_user_error('message_error',
|
|
# ('No se encontro un tercero para el documento: ' + row[1]))
|
|
# party = partys[0]
|
|
# if row[0] not in sale_to_create.keys():
|
|
# # with Transaction().set_context(ctx):
|
|
# sale, = cls.create([{
|
|
# 'sale_date': sale_date,
|
|
# 'party': party.id,
|
|
# 'number': row[0],
|
|
# 'payment_term': 1,
|
|
# 'shop': shop_id,
|
|
# 'sale_device': device_id,
|
|
# 'invoice_address': party.address_get(type='invoice'),
|
|
# 'shipment_address': party.address_get(type='delivery'),
|
|
# }])
|
|
# sale.on_change_party()
|
|
# sale.save()
|
|
# sale_to_create[row[0]] = sale.id
|
|
# journals = Journal.search_read([
|
|
# ('name', '=', row[11])
|
|
# ], fields_names=['id'])
|
|
# if not journals:
|
|
# cls.raise_user_error('message_error',
|
|
# ('No se encontro un libro con el nombre ' + row[11])
|
|
# )
|
|
# sales_to_pay.append({
|
|
# 'sale': sale,
|
|
# 'journal_id': journals[0]['id']
|
|
# })
|
|
# count += 1
|
|
# # print(count, row[0])
|
|
#
|
|
# sale_id = sale_to_create[row[0]]
|
|
# code_ = row[3].replace(' ', '')
|
|
# products = Product.search([
|
|
# ('code', '=', code_)
|
|
# ])
|
|
#
|
|
# if not products:
|
|
# cls.raise_user_error('message_error',
|
|
# ('No se encontro un producto para el código: ' + row[3])
|
|
# )
|
|
# product = products[0]
|
|
# if not product.salable:
|
|
# product.template.write([product.template], {'salable': True})
|
|
# print('No vendible en lista')
|
|
# print(product.code, product.name)
|
|
# line = {
|
|
# 'sale': sale_id,
|
|
# 'product': product.id,
|
|
# 'quantity': row[5],
|
|
# 'description': row[4],
|
|
# 'unit_digits': product.sale_uom.digits,
|
|
# 'unit': product.sale_uom,
|
|
# 'unit_price': Decimal(row[6]),
|
|
# 'discount': Decimal(row[7]),
|
|
# 'taxes': [('add', product.customer_taxes_used)],
|
|
# }
|
|
# SaleLine.create([line])
|
|
# if if row[0] not in sale_tip_product.keys() and row[10] and tip_product:
|
|
# create_lines.append({
|
|
# 'sale': sale_id,
|
|
# 'product': tip_product,
|
|
# 'quantity': 1,
|
|
# 'description': "PROPINA",
|
|
# 'unit': 1,
|
|
# 'unit_price': Decimal(row[10]),
|
|
# 'discount': Decimal('0.00'),
|
|
# })
|
|
# sale_tip_product[row[0]] = row[10]
|
|
# if not row[11]:
|
|
# cls.raise_user_error('message_error',
|
|
# ('el campo medio de pago es obligatorio')
|
|
# )
|
|
#
|
|
# cls.transition_pay_(sales_to_pay)
|
|
return count
|
|
|
|
@classmethod
|
|
def transition_pay_(cls, sales_to_pay):
|
|
pool = Pool()
|
|
Statement = pool.get('account.statement')
|
|
StatementLine = pool.get('account.statement.line')
|
|
for sale_pay in sales_to_pay:
|
|
sale = sale_pay['sale']
|
|
journal_id = sale_pay['journal_id']
|
|
statements = Statement.search([
|
|
('journal', '=', journal_id),
|
|
('state', '=', 'draft'),
|
|
('sale_device', '=', sale.sale_device),
|
|
], order=[('date', 'DESC')])
|
|
if not statements:
|
|
cls.raise_user_error(
|
|
'message_error',
|
|
'A draft statement payments has not been created.'
|
|
)
|
|
|
|
if not sale.number:
|
|
cls.set_number([sale])
|
|
|
|
account = (sale.party.account_receivable and sale.party.account_receivable.id
|
|
or cls.raise_user_error('message_error', 'Party %s has no any \
|
|
account receivable defined. Please, assign one.' % (sale.party.name)))
|
|
|
|
payment = StatementLine(
|
|
statement=statements[0].id,
|
|
date=date.today(),
|
|
amount=sale.total_amount,
|
|
party=sale.party.id,
|
|
account=account,
|
|
description=sale.number,
|
|
sale=sale.id,
|
|
)
|
|
payment.save()
|
|
sale.save()
|
|
cls.workflow_to_end([sale])
|
|
|
|
@classmethod
|
|
def update_consumer(cls, args, context):
|
|
Consumer = Pool().get('party.consumer')
|
|
fields = args['fields']
|
|
consumer = Consumer(args['id'])
|
|
for key, value in fields.items():
|
|
if hasattr(consumer, key):
|
|
Consumer.write([consumer], {key: value})
|
|
return cls._get_object(consumer)
|
|
|
|
@classmethod
|
|
def create_consumer(cls, args, context):
|
|
Consumer = Pool().get('party.consumer')
|
|
consumer = None
|
|
notes = ''
|
|
if args.get('fields'):
|
|
fields = args['fields']
|
|
consumer, = Consumer.create([fields])
|
|
if consumer and consumer.party:
|
|
party = consumer.party
|
|
party.write([party], {'notes': notes})
|
|
return cls._get_object(consumer)
|
|
return {
|
|
'msg': 'ok',
|
|
'consumer': {
|
|
'id': consumer.id,
|
|
'name': consumer.name,
|
|
'phone': consumer.phone,
|
|
'address': consumer.address or '',
|
|
'notes': consumer.notes,
|
|
}
|
|
}
|
|
|
|
@classmethod
|
|
def _get_object(cls, consumer):
|
|
obj_ = {
|
|
'msg': 'ok',
|
|
'party': None,
|
|
'consumer': {
|
|
'id': consumer.id,
|
|
'name': consumer.name,
|
|
'phone': consumer.phone,
|
|
'address': consumer.address or '',
|
|
'notes': consumer.notes or '',
|
|
},
|
|
}
|
|
if consumer.party:
|
|
obj_['party'] = consumer.party.id
|
|
return obj_
|
|
|
|
@classmethod
|
|
def _create_productions(cls, lines):
|
|
pool = Pool()
|
|
Production = pool.get('production')
|
|
Location = pool.get('stock.location')
|
|
Bom = pool.get('production.bom')
|
|
for line in lines:
|
|
if line.production:
|
|
return
|
|
if line.product.producible:
|
|
boms = Bom.search_read([
|
|
('output_products', '=', line.product.id)
|
|
], fields_names=['id'])
|
|
|
|
if not boms:
|
|
continue
|
|
warning_name = '%s.product.without_bom' % line
|
|
cls.raise_user_warning(
|
|
warning_name, 'product_without_bom', {
|
|
'product': line.product.rec_name,
|
|
})
|
|
else:
|
|
bom_ = boms[0]
|
|
locations = Location.search_read([
|
|
('type', '=', 'production'),
|
|
], fields_names=['id'])
|
|
location_ = locations[0] if locations else None
|
|
sale = line.sale
|
|
date_ = sale.sale_date
|
|
product_ = line.product
|
|
create_production = {
|
|
'reference': sale.number,
|
|
'planned_date': date_,
|
|
'effective_date': date_,
|
|
'planned_start_date': date_,
|
|
'effective_start_date': date_,
|
|
'company': sale.company.id,
|
|
'warehouse': sale.warehouse.id,
|
|
'location': location_['id'],
|
|
'product': product_.id,
|
|
'uom': product_.default_uom.id,
|
|
'unit_digits': product_.default_uom.digits,
|
|
'state': 'draft',
|
|
}
|
|
production, = Production.create([create_production])
|
|
production.bom = bom_['id']
|
|
production.quantity = line.quantity
|
|
production.on_change_quantity()
|
|
production.save()
|
|
Production.wait([production])
|
|
Production.assign([production])
|
|
Production.run([production])
|
|
Production.done([production])
|
|
line.production = production.id
|
|
line.save()
|
|
|
|
def get_productions(self, name):
|
|
productions = []
|
|
for line in self.lines:
|
|
if line.production:
|
|
productions.append(line.production)
|
|
return productions
|
|
|
|
|
|
class SaleForceDraft(Wizard):
|
|
__name__ = 'sale_pos.force_draft'
|
|
|
|
def transition_force_draft(self):
|
|
pool = Pool()
|
|
Sale = pool.get('sale.sale')
|
|
Production = pool.get('production')
|
|
ids = Transaction().context['active_ids']
|
|
if not ids:
|
|
return 'end'
|
|
for sale in Sale.browse(ids):
|
|
for p in sale.productions:
|
|
cursor = Transaction().connection.cursor()
|
|
cursor.execute("UPDATE production SET state='waiting' WHERE id in (%s)" % (p.id))
|
|
Production.draft([p])
|
|
Production.cancel([p])
|
|
Production.delete([p])
|
|
return super(SaleForceDraft, self).transition_force_draft()
|
|
|
|
|
|
class SaleLine(metaclass=PoolMeta):
|
|
__name__ = 'sale.line'
|
|
production = fields.Many2One('production', 'Production')
|
|
|
|
|
|
class Shop(metaclass=PoolMeta):
|
|
__name__ = 'sale.shop'
|
|
tables = fields.One2Many('sale.shop.table', 'shop', 'Tables')
|