trytonpsk-sale_pos_frontend.../sale.py

324 lines
12 KiB
Python
Raw Normal View History

2020-04-15 21:49:23 +02:00
# 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
2020-07-22 06:26:28 +02:00
from datetime import date
2020-04-15 21:49:23 +02:00
from trytond.pool import PoolMeta, Pool
2020-07-22 06:26:28 +02:00
from trytond.model import fields, ModelSQL
2020-04-15 21:49:23 +02:00
from trytond.pyson import Eval
from trytond.transaction import Transaction
2020-07-22 06:26:28 +02:00
from trytond.wizard import Wizard
2020-04-15 21:49:23 +02:00
__all__ = ['Sale', 'Shop']
2020-07-22 06:26:28 +02:00
DELIVERY_WAY = [
('', ''),
('take_away', 'Take Away'),
('delivery', 'Delivery'),
('table', 'Table')
]
2020-04-15 21:49:23 +02:00
class Sale(metaclass=PoolMeta):
__name__ = 'sale.sale'
table_assigned = fields.Many2One('sale.shop.table', 'Table Assigned',
domain=[
('shop', '=', Eval('shop'))
])
productions = fields.Function(fields.One2Many('production', None, 'Productions'), 'get_productions')
2020-07-22 06:26:28 +02:00
delivery_men = fields.Many2One('sale.delivery_men', 'Delivery Men')
delivery_time = fields.Numeric('Delivery Time (Min)', help="In Minutes")
delivery_way = fields.Selection(DELIVERY_WAY, 'Delivery Way')
shipping_time = fields.Time('Shipping Time')
@classmethod
def __setup__(cls):
super(Sale, cls).__setup__()
cls._error_messages.update({
'product_without_bom': (
"The product '%(product)s' has no production bom"),
2020-06-12 03:51:21 +02:00
'message_error': 'Error: %s',
},)
2020-06-12 03:51:21 +02:00
@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 = {}
2020-07-22 06:26:28 +02:00
sale_tip_product = {}
2020-06-12 03:51:21 +02:00
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])
2020-07-22 06:26:28 +02:00
# 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]
2020-06-12 03:51:21 +02:00
# 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])
2020-07-22 06:26:28 +02:00
@classmethod
def update_consumer(cls, args, context):
Consumer = Pool().get('party.consumer')
fields = args['fields']
id = args['id']
consumer = Consumer(id)
for key, value in fields.items():
Consumer.write([consumer], {key: value})
return {'msg': 'ok'}
@classmethod
def create_consumer(cls, args, context):
Consumer = Pool().get('party.consumer')
consumer = None
if args.get('fields'):
print(args)
consumer, = Consumer.create([args['fields']])
if consumer:
return {'msg': 'ok'}
else:
return {'msg': 'error'}
@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:
2020-06-12 03:51:21 +02:00
continue
2020-06-10 14:28:23 +02:00
warning_name = '%s.product.without_bom' % line
cls.raise_user_warning(
warning_name, 'product_without_bom', {
2020-06-10 14:28:23 +02:00
'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')
2020-04-15 21:49:23 +02:00
class Shop(metaclass=PoolMeta):
__name__ = 'sale.shop'
tables = fields.One2Many('sale.shop.table', 'shop','Tables')
2020-07-22 06:26:28 +02:00
delivery_man = fields.Many2Many('sale.shop.delivery_men', 'shop',
'delivery_men', 'Delivery Man')
class SaleShopDeliveryMen(ModelSQL):
'Sale Shop - Delivery Men'
__name__ = 'sale.shop.delivery_men'
_table = 'sale_shop_delivery_men'
shop = fields.Many2One('sale.shop', 'Shop', ondelete='CASCADE',
select=True, required=True)
delivery_men = fields.Many2One('sale.delivery_men', 'Delivery Men', ondelete='RESTRICT', required=True)