trytonpsk-hotel/sale.py

361 lines
13 KiB
Python
Raw Normal View History

2022-11-24 04:53:04 +01:00
# This file is part of Presik. The COPYRIGHT file at the top level of
2020-04-16 14:45:13 +02:00
# this repository contains the full copyright notices and license terms.
from datetime import datetime, date
2020-04-16 14:45:13 +02:00
from decimal import Decimal
2022-11-24 04:53:04 +01:00
from trytond.i18n import gettext
from trytond.pool import Pool, PoolMeta
2023-11-01 15:33:39 +01:00
from trytond.pyson import Eval
2020-04-16 14:45:13 +02:00
from trytond.report import Report
from trytond.model import ModelView, fields
from trytond.transaction import Transaction
from trytond.exceptions import UserError
from trytond.wizard import (
Wizard, StateView, Button, StateReport, StateTransition)
2020-04-16 14:45:13 +02:00
_ZERO = Decimal(0)
class Sale(metaclass=PoolMeta):
__name__ = 'sale.sale'
2023-11-01 15:33:39 +01:00
# folio = fields.Many2One('hotel.folio', 'Folio', states={
# 'readonly': True,
# })
@classmethod
def __setup__(cls):
super(Sale, cls).__setup__()
2023-11-01 17:24:27 +01:00
# _states = {
# 'readonly': Eval('state') != 'draft',
# }
cls.state.selection.append(('transferred', 'Transferred'))
@classmethod
def transfer_to_folio(cls, sale_id, folio_id):
sale, = cls.browse([sale_id])
Charge = Pool().get('hotel.folio.charge')
Folio = Pool().get('hotel.folio')
to_create = []
folio = Folio(folio_id)
2023-10-26 00:08:39 +02:00
number = sale.number
if folio.charges_blocked:
raise UserError(gettext('hotel.msg_folio_charges_blocked'))
if folio.registration_state == 'check_out':
raise UserError(gettext('hotel.msg_folio_closed'))
for line in sale.lines:
2023-10-26 00:08:39 +02:00
unit_price = line.unit_price.quantize(Decimal('.01'))
to_create.append({
'folio': folio_id,
'product': line.product.id,
'description': line.description,
'quantity': line.quantity,
'date_service': line.sale.sale_date,
2023-10-26 00:08:39 +02:00
'unit_price': unit_price,
'kind': 'product',
'order': number,
'status': 'pending',
2023-11-02 06:38:22 +01:00
'origin': f'sale.line,{line.id}',
})
2023-11-01 15:33:39 +01:00
charges_ids = Charge.create(to_create)
2023-11-01 15:33:39 +01:00
# 'folio': folio_id,
cls.write([sale], {
2023-11-01 17:24:27 +01:00
'state': 'transferred',
'invoice_method': 'manual',
'shipment_method': 'manual',
2023-10-26 00:08:39 +02:00
'reference': folio.booking.number,
})
2023-11-01 15:33:39 +01:00
# FIXME: Add stock moves
return 'ok'
@classmethod
def transfer_to_sale(cls, sale_id, target_sale_id):
Line = Pool().get('sale.line')
sale, = cls.browse([sale_id])
target, = cls.browse([target_sale_id])
for line in sale.lines:
nwline, = Line.copy([line])
nwline.sale = target.id
nwline.origin = f'sale.line,{line.id}'
nwline.save()
cls.write([sale], {
2023-11-01 17:24:27 +01:00
'state': 'transferred',
2023-11-01 15:33:39 +01:00
'invoice_method': 'manual',
'shipment_method': 'manual',
'reference': sale.number,
})
# FIXME: Add stock moves
return 'ok'
2023-11-01 15:33:39 +01:00
class SaleLine(metaclass=PoolMeta):
__name__ = 'sale.line'
origin = fields.Reference('Origin', selection='get_origin', readonly=True)
@classmethod
def _get_origin(cls):
'Return list of Model names for origin Reference'
return ['sale.line']
@classmethod
def get_origin(cls):
Model = Pool().get('ir.model')
get_name = Model.get_name
models = cls._get_origin()
return [(None, '')] + [(m, get_name(m)) for m in models]
2020-04-16 14:45:13 +02:00
class InvoiceIncomeDailyStart(ModelView):
'Invoice Income Daily Start'
__name__ = 'hotel.invoice_income_daily.start'
company = fields.Many2One('company.company', 'Company', required=True)
invoice_date = fields.Date('Invoice Date', required=True)
user = fields.Many2One('res.user', 'User', required=True)
shop = fields.Many2One('sale.shop', 'Shop', required=True)
# journal = fields.Many2One('account.statement.journal', 'Journal')
@staticmethod
def default_company():
return Transaction().context.get('company')
@staticmethod
def default_sale_date():
Date = Pool().get('ir.date')
return Date.today()
class InvoiceIncomeDaily(Wizard):
'Invoice Income Daily'
__name__ = 'hotel.invoice_income_daily'
2022-10-13 22:27:24 +02:00
start = StateView(
'hotel.invoice_income_daily.start',
2020-04-16 14:45:13 +02:00
'hotel.invoice_income_daily_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-ok', default=True),
2023-11-01 15:33:39 +01:00
])
2020-04-16 14:45:13 +02:00
print_ = StateReport('hotel.invoice_income_daily_report')
def do_print_(self, action):
report_context = {
'company': self.start.company.id,
'invoice_date': self.start.invoice_date,
'user': self.start.user.id,
'shop': self.start.shop.id,
}
return action, report_context
def transition_print_(self):
return 'end'
class InvoiceIncomeDailyReport(Report):
'Invoice Income Daily Report'
__name__ = 'hotel.invoice_income_daily_report'
@classmethod
2021-07-21 14:56:53 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-16 14:45:13 +02:00
pool = Pool()
Invoice = pool.get('account.invoice')
Company = pool.get('company.company')
company = Company(data['company'])
Statement = pool.get('account.statement')
Shop = pool.get('sale.shop')
User = pool.get('res.user')
shop = Shop(data['shop'])
statements = Statement.search([
('date', '=', data['invoice_date']),
('create_uid', '=', data['user']),
])
user = User(data['user'])
records = []
advances = []
statements_ = []
total_advances = []
advances_cash = []
advances_electronic = []
total_statements = []
for statement in statements:
2023-10-04 05:31:09 +02:00
st_amount = sum(li.amount for li in statement.lines)
2020-04-16 14:45:13 +02:00
statements_.append({
'id': statement.id,
'sale_device': statement.sale_device.name,
'journal': statement.journal.name,
'turn': statement.turn,
'total_amount': st_amount,
'state': statement.state,
})
total_statements.append(st_amount)
2023-10-04 05:31:09 +02:00
for li in statement.lines:
sale = li.sale
2020-04-16 14:45:13 +02:00
cash = 0
electronic = 0
if sale and not sale.invoice_number:
for pline in sale.payments:
if pline.statement.journal.kind == 'cash':
advances_cash.append(pline.amount)
cash = pline.amount
else:
electronic = pline.amount
advances_electronic.append(pline.amount)
advances.append({
'number': sale.number,
'reference': sale.reference,
'party': sale.party.name,
'total_amount': pline.amount,
'cash': cash,
'electronic': electronic,
})
total_advances.append(pline.amount)
dom_ = [
('company', '=', data['company']),
('invoice_date', '=', data['invoice_date']),
('shop', '=', data['shop']),
('number', '!=', None),
('state', 'in', ['posted', 'paid', 'canceled']),
('create_uid', '=', data['user']),
]
invoices = Invoice.search(dom_, order=[('number', 'ASC')])
invoices_number = []
total_invoices_cash = []
total_invoices_electronic = []
total_invoices_credit = []
total_invoices_paid = []
total_invoices_amount = []
for invoice in invoices:
invoices_number.append(invoice.number)
cash = 0
electronic = 0
credit = 0
total_invoices_amount.append(invoice.total_amount)
sale = invoice.sales[0]
if not sale.payments:
total_invoices_credit.append(invoice.amount_to_pay)
credit = invoice.amount_to_pay
else:
for p in sale.payments:
if p.statement.date == data['invoice_date']:
if p.statement.journal.kind == 'cash':
cash += p.amount
total_invoices_cash.append(p.amount)
else:
electronic += p.amount
total_invoices_electronic.append(p.amount)
total_invoices_paid.append(p.amount)
inv = {
'number': invoice.number,
'reference': invoice.reference,
'party': invoice.party.name,
'total_amount': invoice.total_amount,
'credit': credit,
'cash': cash,
'electronic': electronic,
'paid': cash + electronic,
'state': invoice.state_string,
}
records.append(inv)
report_context['records'] = records
report_context['advances'] = advances
report_context['statements'] = statements_
report_context['date'] = data['invoice_date']
2023-11-04 23:42:13 +01:00
report_context['company'] = company
2020-04-16 14:45:13 +02:00
report_context['shop'] = shop.name
report_context['user'] = user.name
report_context['print_date'] = datetime.now()
report_context['total_invoices_amount'] = sum(total_invoices_amount)
report_context['total_invoices_cash'] = sum(total_invoices_cash)
report_context['total_invoices_electronic'] = sum(total_invoices_electronic)
report_context['total_invoices_credit'] = sum(total_invoices_credit)
report_context['total_invoices_paid'] = sum(total_invoices_paid)
report_context['total_advances'] = sum(total_advances)
report_context['advances_cash'] = sum(advances_cash)
report_context['advances_electronic'] = sum(advances_electronic)
report_context['total_statements'] = sum(total_statements)
report_context['start_invoice'] = min(invoices_number) if invoices_number else ''
report_context['end_invoice'] = max(invoices_number) if invoices_number else ''
return report_context
class InvoiceSimplifiedReport(Report):
__name__ = 'account.invoice_simplified'
@classmethod
2021-07-21 14:56:53 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-16 14:45:13 +02:00
Company = Pool().get('company.company')
categories = {}
if records:
record = records[0]
for l in record.lines:
cat = l.product.template.account_category
taxes = ''
for tax in cat.customer_taxes_used:
taxes += tax.name + ' '
if cat.id not in categories.keys():
categories[cat.id] = {
'description': cat.name,
'amount': l.amount,
'taxes': taxes
}
else:
categories[cat.id]['amount'] += l.amount
record._lines = categories.values()
report_context['company'] = Company(Transaction().context['company'])
return report_context
2023-11-01 15:33:39 +01:00
class SaleTransferStart(ModelView):
'Sale Transfer Start'
__name__ = 'sale.transfer.start'
kind = fields.Selection([
('folio', 'Folio'),
('sale', 'Sale'),
], 'Kind', required=True)
folio = fields.Many2One('hotel.folio', 'Folio', domain=[
('registration_state', '=', 'check_in'),
('arrival_date', '<=', date.today()),
('departure_date', '>=', date.today()),
2023-11-01 15:33:39 +01:00
], states={
'invisible': Eval('kind') != 'folio'
})
sale = fields.Many2One('sale.sale', 'Sale', domain=[
('state', '=', 'draft'),
('number', '!=', None),
], states={
'invisible': Eval('kind') != 'sale'
})
2023-11-01 15:33:39 +01:00
class SaleTransfer(Wizard):
'Sale Transfer'
__name__ = 'sale.transfer'
start = StateView(
2023-11-01 15:33:39 +01:00
'sale.transfer.start',
'hotel.sale_transfer_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Ok', 'accept', 'tryton-ok', default=True),
])
accept = StateTransition()
def transition_accept(self):
Sale = Pool().get('sale.sale')
sale_id = Transaction().context['active_id']
2023-11-01 15:33:39 +01:00
if self.start.kind == 'folio':
Sale.transfer_to_folio(sale_id, self.start.folio.id)
else:
Sale.transfer_to_sale(sale_id, self.start.sale.id)
return 'end'