summaryrefslogtreecommitdiff
path: root/addons/point_of_sale/wizard
diff options
context:
space:
mode:
Diffstat (limited to 'addons/point_of_sale/wizard')
-rw-r--r--addons/point_of_sale/wizard/__init__.py6
-rw-r--r--addons/point_of_sale/wizard/pos_box.py35
-rw-r--r--addons/point_of_sale/wizard/pos_box.xml9
-rw-r--r--addons/point_of_sale/wizard/pos_details.py47
-rw-r--r--addons/point_of_sale/wizard/pos_details.xml23
-rw-r--r--addons/point_of_sale/wizard/pos_open_statement.py38
-rw-r--r--addons/point_of_sale/wizard/pos_payment.py74
-rw-r--r--addons/point_of_sale/wizard/pos_payment.xml28
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>