diff options
Diffstat (limited to 'addons/point_of_sale/wizard')
| -rw-r--r-- | addons/point_of_sale/wizard/__init__.py | 6 | ||||
| -rw-r--r-- | addons/point_of_sale/wizard/pos_box.py | 35 | ||||
| -rw-r--r-- | addons/point_of_sale/wizard/pos_box.xml | 9 | ||||
| -rw-r--r-- | addons/point_of_sale/wizard/pos_details.py | 47 | ||||
| -rw-r--r-- | addons/point_of_sale/wizard/pos_details.xml | 23 | ||||
| -rw-r--r-- | addons/point_of_sale/wizard/pos_open_statement.py | 38 | ||||
| -rw-r--r-- | addons/point_of_sale/wizard/pos_payment.py | 74 | ||||
| -rw-r--r-- | addons/point_of_sale/wizard/pos_payment.xml | 28 |
8 files changed, 260 insertions, 0 deletions
diff --git a/addons/point_of_sale/wizard/__init__.py b/addons/point_of_sale/wizard/__init__.py new file mode 100644 index 00000000..16789e5d --- /dev/null +++ b/addons/point_of_sale/wizard/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import pos_box +from . import pos_details +from . import pos_payment diff --git a/addons/point_of_sale/wizard/pos_box.py b/addons/point_of_sale/wizard/pos_box.py new file mode 100644 index 00000000..bd8aa751 --- /dev/null +++ b/addons/point_of_sale/wizard/pos_box.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, _ +from odoo.exceptions import UserError + +from odoo.addons.account.wizard.pos_box import CashBox + + +class PosBox(CashBox): + _register = False + + def run(self): + active_model = self.env.context.get('active_model', False) + active_ids = self.env.context.get('active_ids', []) + + if active_model == 'pos.session': + bank_statements = [session.cash_register_id for session in self.env[active_model].browse(active_ids) if session.cash_register_id] + if not bank_statements: + raise UserError(_("There is no cash register for this PoS Session")) + return self._run(bank_statements) + else: + return super(PosBox, self).run() + + +class PosBoxOut(PosBox): + _inherit = 'cash.box.out' + + def _calculate_values_for_statement_line(self, record): + values = super(PosBoxOut, self)._calculate_values_for_statement_line(record) + active_model = self.env.context.get('active_model', False) + active_ids = self.env.context.get('active_ids', []) + if active_model == 'pos.session' and active_ids: + values['ref'] = self.env[active_model].browse(active_ids)[0].name + return values diff --git a/addons/point_of_sale/wizard/pos_box.xml b/addons/point_of_sale/wizard/pos_box.xml new file mode 100644 index 00000000..586770af --- /dev/null +++ b/addons/point_of_sale/wizard/pos_box.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<odoo> + <record id="action_pos_box_out" model="ir.actions.act_window"> + <field name="name">Take Money In/Out</field> + <field name="res_model">cash.box.out</field> + <field name="view_mode">form</field> + <field name="target">new</field> + </record> +</odoo> diff --git a/addons/point_of_sale/wizard/pos_details.py b/addons/point_of_sale/wizard/pos_details.py new file mode 100644 index 00000000..9be4caa0 --- /dev/null +++ b/addons/point_of_sale/wizard/pos_details.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class PosDetails(models.TransientModel): + _name = 'pos.details.wizard' + _description = 'Point of Sale Details Report' + + def _default_start_date(self): + """ Find the earliest start_date of the latests sessions """ + # restrict to configs available to the user + config_ids = self.env['pos.config'].search([]).ids + # exclude configs has not been opened for 2 days + self.env.cr.execute(""" + SELECT + max(start_at) as start, + config_id + FROM pos_session + WHERE config_id = ANY(%s) + AND start_at > (NOW() - INTERVAL '2 DAYS') + GROUP BY config_id + """, (config_ids,)) + latest_start_dates = [res['start'] for res in self.env.cr.dictfetchall()] + # earliest of the latest sessions + return latest_start_dates and min(latest_start_dates) or fields.Datetime.now() + + start_date = fields.Datetime(required=True, default=_default_start_date) + end_date = fields.Datetime(required=True, default=fields.Datetime.now) + pos_config_ids = fields.Many2many('pos.config', 'pos_detail_configs', + default=lambda s: s.env['pos.config'].search([])) + + @api.onchange('start_date') + def _onchange_start_date(self): + if self.start_date and self.end_date and self.end_date < self.start_date: + self.end_date = self.start_date + + @api.onchange('end_date') + def _onchange_end_date(self): + if self.end_date and self.end_date < self.start_date: + self.start_date = self.end_date + + def generate_report(self): + data = {'date_start': self.start_date, 'date_stop': self.end_date, 'config_ids': self.pos_config_ids.ids} + return self.env.ref('point_of_sale.sale_details_report').report_action([], data=data) diff --git a/addons/point_of_sale/wizard/pos_details.xml b/addons/point_of_sale/wizard/pos_details.xml new file mode 100644 index 00000000..6a10896b --- /dev/null +++ b/addons/point_of_sale/wizard/pos_details.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <record id="view_pos_details_wizard" model="ir.ui.view"> + <field name="name">pos.details.wizard.form</field> + <field name="model">pos.details.wizard</field> + <field name="arch" type="xml"> + <form string="Sales Details"> + <group> + <field name="start_date"/> + <field name="end_date"/> + </group> + <group> + <field name="pos_config_ids" mode="tree" colspan="4" nolabel="1" /> + </group> + <footer> + <button name="generate_report" string="Print" type="object" class="btn-primary"/> + <button string="Cancel" class="btn-secondary" special="cancel" /> + </footer> + </form> + </field> + </record> + +</odoo> diff --git a/addons/point_of_sale/wizard/pos_open_statement.py b/addons/point_of_sale/wizard/pos_open_statement.py new file mode 100644 index 00000000..f6049bf5 --- /dev/null +++ b/addons/point_of_sale/wizard/pos_open_statement.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, models, _ +from odoo.exceptions import UserError + + +class PosOpenStatement(models.TransientModel): + _name = 'pos.open.statement' + _description = 'Point of Sale Open Statement' + + def open_statement(self): + self.ensure_one() + BankStatement = self.env['account.bank.statement'] + journals = self.env['account.journal'].search([('journal_user', '=', True)]) + if not journals: + raise UserError(_('You have to define which payment method must be available in the point of sale by reusing existing bank and cash through "Accounting / Configuration / Journals / Journals". Select a journal and check the field "PoS Payment Method" from the "Point of Sale" tab. You can also create new payment methods directly from menu "PoS Backend / Configuration / Payment Methods".')) + + for journal in journals: + if journal.sequence_id: + number = journal.sequence_id.next_by_id() + else: + raise UserError(_("No sequence defined on the journal")) + BankStatement += BankStatement.create({'journal_id': journal.id, 'user_id': self.env.uid, 'name': number}) + + tree_id = self.env.ref('account.view_bank_statement_tree').id + form_id = self.env.ref('account.view_bank_statement_form').id + search_id = self.env.ref('account.view_bank_statement_search').id + + return { + 'type': 'ir.actions.act_window', + 'name': _('List of Cash Registers'), + 'view_mode': 'tree,form', + 'res_model': 'account.bank.statement', + 'domain': str([('id', 'in', BankStatement.ids)]), + 'views': [(tree_id, 'tree'), (form_id, 'form')], + 'search_view_id': search_id, + } diff --git a/addons/point_of_sale/wizard/pos_payment.py b/addons/point_of_sale/wizard/pos_payment.py new file mode 100644 index 00000000..40f37419 --- /dev/null +++ b/addons/point_of_sale/wizard/pos_payment.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.tools import float_is_zero + + +class PosMakePayment(models.TransientModel): + _name = 'pos.make.payment' + _description = 'Point of Sale Make Payment Wizard' + + def _default_config(self): + active_id = self.env.context.get('active_id') + if active_id: + return self.env['pos.order'].browse(active_id).session_id.config_id + return False + + def _default_amount(self): + active_id = self.env.context.get('active_id') + if active_id: + order = self.env['pos.order'].browse(active_id) + return order.amount_total - order.amount_paid + return False + + def _default_payment_method(self): + active_id = self.env.context.get('active_id') + if active_id: + order_id = self.env['pos.order'].browse(active_id) + return order_id.session_id.payment_method_ids.sorted(lambda pm: pm.is_cash_count, reverse=True)[:1] + return False + + config_id = fields.Many2one('pos.config', string='Point of Sale Configuration', required=True, default=_default_config) + amount = fields.Float(digits=0, required=True, default=_default_amount) + payment_method_id = fields.Many2one('pos.payment.method', string='Payment Method', required=True, default=_default_payment_method) + payment_name = fields.Char(string='Payment Reference') + payment_date = fields.Datetime(string='Payment Date', required=True, default=lambda self: fields.Datetime.now()) + + def check(self): + """Check the order: + if the order is not paid: continue payment, + if the order is paid print ticket. + """ + self.ensure_one() + + order = self.env['pos.order'].browse(self.env.context.get('active_id', False)) + currency = order.currency_id + + init_data = self.read()[0] + if not float_is_zero(init_data['amount'], precision_rounding=currency.rounding): + order.add_payment({ + 'pos_order_id': order.id, + 'amount': order._get_rounded_amount(init_data['amount']), + 'name': init_data['payment_name'], + 'payment_method_id': init_data['payment_method_id'][0], + }) + + if order._is_pos_order_paid(): + order.action_pos_order_paid() + order._create_order_picking() + return {'type': 'ir.actions.act_window_close'} + + return self.launch_payment() + + def launch_payment(self): + return { + 'name': _('Payment'), + 'view_mode': 'form', + 'res_model': 'pos.make.payment', + 'view_id': False, + 'target': 'new', + 'views': False, + 'type': 'ir.actions.act_window', + 'context': self.env.context, + } diff --git a/addons/point_of_sale/wizard/pos_payment.xml b/addons/point_of_sale/wizard/pos_payment.xml new file mode 100644 index 00000000..e44bb429 --- /dev/null +++ b/addons/point_of_sale/wizard/pos_payment.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <record id="view_pos_payment" model="ir.ui.view"> + <field name="name">pos.make.payment.form</field> + <field name="model">pos.make.payment</field> + <field name="arch" type="xml"> + <form string="Pay Order"> + <group> + <field name="config_id" invisible="1" /> + <field name="payment_method_id" domain="[('config_ids', 'in', config_id)]"/> + <field name="amount" /> + <field name="payment_name"/> + </group> + <footer> + <button name="check" string="Make Payment" type="object" class="btn-primary"/> + <button special="cancel" string="Cancel" class="btn-secondary"/> + </footer> + </form> + </field> + </record> + <record id="action_pos_payment" model="ir.actions.act_window"> + <field name="name">Payment</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">pos.make.payment</field> + <field name="view_mode">form</field> + <field name="target">new</field> + </record> +</odoo> |
