@@ -, +, @@ the screen. left. price of the item in the table on the left. collected from patron' box. appears here. back at a fresh 'Pay' page ready for the next transaction. --- Koha/Charges/Sales.pm | 251 ++++++++++++++ .../prog/en/includes/pos-menu.inc | 16 + .../prog/en/modules/intranet-main.tt | 4 + .../intranet-tmpl/prog/en/modules/pos/pay.tt | 319 ++++++++++++++++++ pos/pay.pl | 80 +++++ 5 files changed, 670 insertions(+) create mode 100644 Koha/Charges/Sales.pm create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/pos-menu.inc create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt create mode 100755 pos/pay.pl --- a/Koha/Charges/Sales.pm +++ a/Koha/Charges/Sales.pm @@ -0,0 +1,251 @@ +package Koha::Charges::Sales; + +# Copyright 2019 PTFS Europe +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Koha::Account::Lines; +use Koha::Account::Offsets; +use Koha::DateUtils qw( dt_from_string ); +use Koha::Exceptions; + +=head1 NAME + +Koha::Charges::Sale - Module for collecting sales in Koha + +=head1 SYNOPSIS + + use Koha::Charges::Sale; + + my $sale = Koha::Charges::Sale->new( cash_register => $register ); + $sale->add_item($item); + $sale->purchase; + +=head2 Class methods + +=head3 new + + Koha::Charges::Sale->new( + { + cash_register => $cash_register, + user_id => $user_id, + [ payment_type => $payment_type ], + [ items => $items ], + [ patron => $patron ], + } + ); + +=cut + +sub new { + my ( $class, $params ) = @_; + + Koha::Exceptions::MissingParameter->throw( + "Missing mandatory parameter: cash_register") + unless $params->{cash_register}; + Carp::confess("Key 'cash_register' is not a Koha::Cash::Register object!") + unless $params->{cash_register}->isa('Koha::Cash::Register'); + + $params->{valid_items} = { + map { $_ => 1 } Koha::AuthorisedValues->search( + { + category => 'MANUAL_INV', + branchcode => $params->{cash_register}->branch + } + )->get_column('authorised_value') + }; + + return bless( $params, $class ); +} + +=head3 cash_register + + my $cash_register = $sales->cash_register( $cash_register ); + +=cut + +sub cash_register { + my ( $self, $cash_register ) = @_; + + $self->{cash_register} = $cash_register + if $cash_register && $cash_register->isa('Koha::Cash::Register'); + + return $self->{cash_register}; +} + +=head3 payment_type + + my $payment_type = $sale->payment_type( $payment_type ); + +=cut + +sub payment_type { + my ( $self, $payment_type ) = @_; + + $self->{payment_type} = $payment_type; + + return $self; +} + +=head3 patron + + my $patron = $sale->patron( $patron ); + +=cut + +sub patron { + my ( $self, $patron ) = @_; + + $self->{patron} = $patron if $patron && $patron->isa('Koha::Patron'); + + return $self->{patron}; +} + +=head3 items + + my $items = $sale->items; + +=cut + +sub items { + my ( $self, $item ) = @_; + + $self->{item} = $item if $item && $item->isa('Koha::Item'); + + return $self->{item}; +} + +=head3 add_item + + my $item = { price => 0.25, quantity => 1, code => 'COPY' }; + $sale->add_item( $item ); + +=cut + +sub add_item { + my ( $self, $item ) = @_; + + Koha::Exceptions::MissingParameter->throw( + "Missing mandatory parameter: code") + unless $item->{code}; + + Koha::Exceptions::Account::UnrecognisedType->throw( + error => 'Type of debit not recognised' ) + unless ( exists( $self->{valid_items}->{ $item->{code} } ) ); + + Koha::Exceptions::MissingParameter->throw( + "Missing mandatory parameter: price") + unless $item->{price}; + + Koha::Exceptions::MissingParameter->throw( + "Missing mandatory parameter: quantity") + unless $item->{quantity}; + + push @{ $self->{items} }, $item; + return $self; +} + +=head3 purchase + + my $credit_line = $sale->purchase; + +=cut + +sub purchase { + my ( $self, $params ) = @_; + + my $payment_type = + exists( $params->{payment_type} ) + ? $params->{payment_type} + : $self->{payment_type}; + + Koha::Exceptions::MissingParameter->throw( + "Missing mandatory parameter: payment_type") + unless $payment_type; + + my $schema = Koha::Database->new->schema; + my $dt = dt_from_string(); + my $total_owed = 0; + my $credit; + + $schema->txn_do( + sub { + + my $debit_offsets; + for my $item ( @{ $self->{items} } ) { + + my $amount = $item->{quantity} * $item->{price}; + $total_owed = $total_owed + $amount; + + # Insert the account line + my $line = Koha::Account::Line->new( + { + amount => $amount, + accounttype => $item->{code}, + amountoutstanding => 0, + note => $item->{quantity}, + manager_id => $self->{user_id}, + interface => 'intranet', + branchcode => $self->{cash_register}->branch, + date => $dt + } + )->store(); + + # Record the account offset + my $account_offset = Koha::Account::Offset->new( + { + debit_id => $line->id, + type => 'Payment', + amount => $amount * -1 + } + )->store(); + + push @{$debit_offsets}, $account_offset; + } + + $credit = Koha::Account::Line->new( + { + amount => 0 - $total_owed, + accounttype => 'Purchase', + payment_type => $payment_type, + amountoutstanding => 0, + manager_id => $self->{user_id}, + interface => 'intranet', + branchcode => $self->{cash_register}->branch, + register_id => $self->{cash_register}->id, + date => $dt, + note => "POS SALE" + } + )->store(); + + for my $offset (@{$debit_offsets}) { + $offset->credit_id( $credit->accountlines_id )->store(); + } + } + ); + + return $credit; +} + +=head1 AUTHOR + +Martin Renvoize + +=cut + +1; --- a/koha-tmpl/intranet-tmpl/prog/en/includes/pos-menu.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/pos-menu.inc @@ -0,0 +1,16 @@ + --- a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt @@ -80,6 +80,10 @@