merged with HEAD and other interesting changes
This commit is contained in:
parent
66c6c0fae5
commit
856cc06d04
151 changed files with 7335 additions and 2602 deletions
|
|
@ -147,7 +147,7 @@ An address object's unique id.
|
|||
|
||||
sub getAddress {
|
||||
my ($self, $addressId) = @_;
|
||||
my $id = ref $self;
|
||||
my $id = id $self;
|
||||
unless (exists $addressCache{$id}{$addressId}) {
|
||||
$addressCache{$id}{$addressId} = WebGUI::Shop::Address->new($self, $addressId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ sub getAdminConsole {
|
|||
$ac->addSubmenuItem($url->page("shop=ship;method=manage"), $i18n->get("shipping methods"));
|
||||
$ac->addSubmenuItem($url->page("shop=transaction;method=manage"), $i18n->get("transactions"));
|
||||
$ac->addSubmenuItem($url->page("shop=vendor;method=manage"), $i18n->get("vendors"));
|
||||
$ac->addSubmenuItem($url->page("shop=vendor;method=managePayouts"), $i18n->get("vendor payouts"));
|
||||
$ac->addSubmenuItem($url->page("shop=credit;method=manage"), $i18n->get("in shop credit"));
|
||||
return $ac;
|
||||
}
|
||||
|
|
@ -151,6 +152,13 @@ sub www_editSettings {
|
|||
label => $i18n->get('who is a cashier'),
|
||||
hoverHelp => $i18n->get('who is a cashier help'),
|
||||
);
|
||||
$form->float(
|
||||
name => 'shopCartCheckoutMinimum',
|
||||
value => $setting->get('shopCartCheckoutMinimum'),
|
||||
defaultValue=> '0.00',
|
||||
label => $i18n->get('cart checkout minimum'),
|
||||
hoverHelp => $i18n->get('cart checkout minimum help'),
|
||||
);
|
||||
$form->template(
|
||||
name => "shopCartTemplateId",
|
||||
value => $setting->get("shopCartTemplateId"),
|
||||
|
|
@ -202,13 +210,21 @@ sub www_editSettingsSave {
|
|||
my $self = shift;
|
||||
return $self->session->privilege->adminOnly() unless ($self->session->user->isAdmin);
|
||||
my ($setting, $form) = $self->session->quick(qw(setting form));
|
||||
|
||||
# Save shop templates
|
||||
foreach my $template (qw(shopMyPurchasesDetailTemplateId shopMyPurchasesTemplateId
|
||||
shopCartTemplateId shopAddressBookTemplateId shopAddressTemplateId)) {
|
||||
$setting->set($template, $form->get($template, "template"));
|
||||
}
|
||||
|
||||
# Save group settings
|
||||
foreach my $group (qw(groupIdCashier groupIdAdminCommerce)) {
|
||||
$setting->set($group, $form->get($group, "group"));
|
||||
}
|
||||
|
||||
# Save mininmum cart checkout
|
||||
$setting->set( 'shopCartCheckoutMinimum', $form->get( 'shopCartCheckoutMinimum', 'float' ) );
|
||||
|
||||
return $self->www_editSettings();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ Returns a reference to the address book for the user who's cart this is.
|
|||
|
||||
sub getAddressBook {
|
||||
my $self = shift;
|
||||
my $id = ref $self;
|
||||
my $id = id $self;
|
||||
unless (exists $addressBookCache{$id}) {
|
||||
$addressBookCache{$id} = WebGUI::Shop::AddressBook->newBySession($self->session);
|
||||
}
|
||||
|
|
@ -297,7 +297,6 @@ sub getItem {
|
|||
unless (defined $itemId && $itemId =~ m/^[A-Za-z0-9_-]{22}$/) {
|
||||
WebGUI::Error::InvalidParam->throw(error=>"Need an itemId.");
|
||||
}
|
||||
my $id = ref $self;
|
||||
my $item = WebGUI::Shop::CartItem->new($self, $itemId);
|
||||
return $item;
|
||||
}
|
||||
|
|
@ -499,7 +498,7 @@ Returns whether all the required properties of the the cart are set.
|
|||
|
||||
sub readyForCheckout {
|
||||
my $self = shift;
|
||||
|
||||
|
||||
# Check if the shipping address is set and correct
|
||||
my $address = eval{$self->getShippingAddress};
|
||||
return 0 if WebGUI::Error->caught;
|
||||
|
|
@ -514,6 +513,12 @@ sub readyForCheckout {
|
|||
# fail if there are multiple recurring items or if
|
||||
return 0 if ($self->hasMixedItems);
|
||||
|
||||
# Check minimum cart checkout requirement
|
||||
my $requiredAmount = $self->session->setting->get( 'shopCartCheckoutMinimum' );
|
||||
if ( $requiredAmount > 0 ) {
|
||||
return 0 if $self->calculateTotal < $requiredAmount;
|
||||
}
|
||||
|
||||
# All checks passed so return true
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -802,6 +807,10 @@ sub www_view {
|
|||
shipToButton => WebGUI::Form::submit($session, {value=>$i18n->get("ship to button"),
|
||||
extras=>q|onclick="setCallbackForAddressChooser(this.form);"|}),
|
||||
subtotalPrice => $self->formatCurrency($self->calculateSubtotal()),
|
||||
minimumCartAmount => $session->setting->get( 'shopCartCheckoutMinimum' ) > 0
|
||||
? sprintf( '%.2f', $session->setting->get( 'shopCartCheckoutMinimum' ) )
|
||||
: 0
|
||||
,
|
||||
);
|
||||
|
||||
# get the shipping address
|
||||
|
|
@ -847,10 +856,11 @@ sub www_view {
|
|||
# calculate price adjusted for in-store credit
|
||||
$var{totalPrice} = $var{subtotalPrice} + $var{shippingPrice} + $var{tax};
|
||||
my $credit = WebGUI::Shop::Credit->new($session, $posUser->userId);
|
||||
$var{inShopCreditAvailable} = $credit->getSum;
|
||||
$var{inShopCreditDeduction} = $credit->calculateDeduction($var{totalPrice});
|
||||
$var{totalPrice} = $self->formatCurrency($var{totalPrice} + $var{inShopCreditDeduction});
|
||||
|
||||
$var{ inShopCreditAvailable } = $credit->getSum;
|
||||
$var{ inShopCreditDeduction } = $credit->calculateDeduction($var{totalPrice});
|
||||
$var{ totalPrice } = $self->formatCurrency($var{totalPrice} + $var{inShopCreditDeduction});
|
||||
$var{ readyForCheckout } = $self->readyForCheckout;
|
||||
|
||||
# render the cart
|
||||
my $template = WebGUI::Asset::Template->new($session, $session->setting->get("shopCartTemplateId"));
|
||||
return $session->style->userStyle($template->process(\%var));
|
||||
|
|
|
|||
|
|
@ -173,7 +173,6 @@ Returns an instanciated WebGUI::Asset::Sku object for this cart item.
|
|||
|
||||
sub getSku {
|
||||
my ($self) = @_;
|
||||
my $id = ref $self;
|
||||
my $asset = '';
|
||||
$asset = WebGUI::Asset->newByDynamicClass($self->cart->session, $self->get("assetId"));
|
||||
$asset->applyOptions($self->get("options"));
|
||||
|
|
|
|||
|
|
@ -267,11 +267,14 @@ sub update {
|
|||
if (exists $newProperties->{item}) {
|
||||
my $item = $newProperties->{ item };
|
||||
my $sku = $item->getSku;
|
||||
$newProperties->{ options } = $sku->getOptions;
|
||||
$newProperties->{ assetId } = $sku->getId;
|
||||
$newProperties->{ price } = $sku->getPrice;
|
||||
$newProperties->{ configuredTitle } = $item->get('configuredTitle');
|
||||
$newProperties->{ quantity } = $item->get('quantity');
|
||||
$newProperties->{ options } = $sku->getOptions;
|
||||
$newProperties->{ assetId } = $sku->getId;
|
||||
$newProperties->{ price } = $sku->getPrice;
|
||||
$newProperties->{ configuredTitle } = $item->get('configuredTitle');
|
||||
$newProperties->{ quantity } = $item->get('quantity');
|
||||
$newProperties->{ vendorId } = $sku->getVendorId;
|
||||
$newProperties->{ vendorPayoutAmount } = sprintf '%.2f', $sku->getVendorPayout * $item->get('quantity');
|
||||
|
||||
my $address = $item->getShippingAddress;
|
||||
$newProperties->{ shippingAddressId } = $address->getId;
|
||||
$newProperties->{ shippingAddressName } = $address->get('name');
|
||||
|
|
@ -289,7 +292,8 @@ sub update {
|
|||
}
|
||||
my @fields = (qw(assetId configuredTitle options shippingAddressId shippingTrackingNumber orderStatus
|
||||
shippingName shippingAddress1 shippingAddress2 shippingAddress3 shippingCity shippingState
|
||||
shippingCountry shippingCode shippingPhoneNumber quantity price vendorId));
|
||||
shippingCountry shippingCode shippingPhoneNumber quantity price vendorId
|
||||
vendorPayoutStatus vendorPayoutAmount));
|
||||
foreach my $field (@fields) {
|
||||
$properties{$id}{$field} = (exists $newProperties->{$field}) ? $newProperties->{$field} : $properties{$id}{$field};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ use Class::InsideOut qw{ :std };
|
|||
use WebGUI::Shop::Admin;
|
||||
use WebGUI::Exception::Shop;
|
||||
use WebGUI::International;
|
||||
|
||||
use WebGUI::Utility qw{ isIn };
|
||||
use List::Util qw{ sum };
|
||||
use JSON qw{ encode_json };
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
|
@ -117,6 +119,48 @@ sub getId {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getPayoutTotals ( )
|
||||
|
||||
Returns a hash ref, containing the payout details for this vendor. The keys in the hash are:
|
||||
|
||||
=head3 paid
|
||||
|
||||
The amount of money already transfered to the vendor.
|
||||
|
||||
=head3 scheduled
|
||||
|
||||
The amount of money scheduled to be transfered to the vendor.
|
||||
|
||||
=head3 notPaid
|
||||
|
||||
The amount of money that is yet to be scheduled for payment to the vendor.
|
||||
|
||||
=head3 total
|
||||
|
||||
The sum of these three values.
|
||||
|
||||
=cut
|
||||
|
||||
sub getPayoutTotals {
|
||||
my $self = shift;
|
||||
|
||||
my %totals = $self->session->db->buildHash(
|
||||
'select vendorPayoutStatus, sum(vendorPayoutAmount) as amount from transactionItem '
|
||||
.'where vendorId=? group by vendorPayoutStatus ',
|
||||
[ $self->getId ]
|
||||
);
|
||||
|
||||
# Format the payout categories and calc the total those.
|
||||
%totals =
|
||||
map { lcfirst $_ => sprintf '%.2f', $totals{ $_ } }
|
||||
qw( Paid Scheduled NotPaid );
|
||||
$totals{ total } = sprintf '%.2f', sum values %totals;
|
||||
|
||||
return \%totals;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getVendors ( session, options )
|
||||
|
||||
Class method. Returns an array reference of WebGUI::Shop::Vendor objects.
|
||||
|
|
@ -150,6 +194,26 @@ sub getVendors {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 isVendorInfoComplete ( )
|
||||
|
||||
Returns a boolean indicating whether the payoutinformation entered by the vendor is complete.
|
||||
|
||||
=cut
|
||||
|
||||
sub isVendorInfoComplete {
|
||||
my $self = shift;
|
||||
|
||||
my $complete =
|
||||
defined $self->get( 'name' )
|
||||
&& defined $self->get( 'userId' )
|
||||
&& defined $self->get( 'preferredPaymentType' )
|
||||
&& defined $self->get( 'paymentInformation' );
|
||||
|
||||
return $complete
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 new ( session, vendorId )
|
||||
|
||||
Constructor. Returns a WebGUI::Shop::Vendor object.
|
||||
|
|
@ -405,5 +469,215 @@ sub www_manage {
|
|||
return $console->render($output, $i18n->get("vendors"));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_managePayouts ( )
|
||||
|
||||
Displays the payout manager.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_managePayouts {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
|
||||
my $admin = WebGUI::Shop::Admin->new($session);
|
||||
return $session->privilege->adminOnly() unless ($admin->canManage);
|
||||
|
||||
# Load the required YUI stuff.
|
||||
$session->style->setLink('/extras/yui/build/paginator/assets/skins/sam/paginator.css', {type=>'text/css', rel=>'stylesheet'});
|
||||
$session->style->setLink('/extras/yui/build/datatable/assets/skins/sam/datatable.css', {type=>'text/css', rel=>'stylesheet'});
|
||||
$session->style->setLink('/extras/yui/build/button/assets/skins/sam/button.css', {type=>'text/css', rel=>'stylesheet'});
|
||||
$session->style->setScript('/extras/yui/build/yahoo-dom-event/yahoo-dom-event.js', {type=>'text/javascript'});
|
||||
$session->style->setScript('/extras/yui/build/element/element-beta-min.js', {type=>'text/javascript'});
|
||||
$session->style->setScript('/extras/yui/build/connection/connection-min.js', {type=>'text/javascript'});
|
||||
$session->style->setScript('/extras/yui/build/json/json-min.js', {type=>'text/javascript'});
|
||||
$session->style->setScript('/extras/yui/build/paginator/paginator-min.js', {type=>'text/javascript'});
|
||||
$session->style->setScript('/extras/yui/build/datasource/datasource.js', {type=>'text/javascript'});
|
||||
$session->style->setScript('/extras/yui/build/datatable/datatable-min.js', {type=>'text/javascript'});
|
||||
$session->style->setScript('/extras/yui/build/button/button-min.js', {type=>'text/javascript'});
|
||||
$session->style->setScript('/extras/VendorPayout/vendorPayout.js', {type=>'text/javascript'});
|
||||
|
||||
# Add css for scheduled payout highlighting
|
||||
$session->style->setRawHeadTags(<<CSS);
|
||||
<style type="text/css">
|
||||
.yui-skin-sam .yui-dt tr.scheduled,
|
||||
.yui-skin-sam .yui-dt tr.scheduled td.yui-dt-asc,
|
||||
.yui-skin-sam .yui-dt tr.scheduled td.yui-dt-desc,
|
||||
.yui-skin-sam .yui-dt tr.scheduled td.yui-dt-asc,
|
||||
.yui-skin-sam .yui-dt tr.scheduled td.yui-dt-desc {
|
||||
background-color : #080;
|
||||
color : #fff;
|
||||
}
|
||||
</style>
|
||||
CSS
|
||||
|
||||
my $output = q{<div id="vendorPayoutContainer" class="yui-skin-sam"></div>}
|
||||
.q{<script type="text/javascript">var vp = new WebGUI.VendorPayout( 'vendorPayoutContainer' );</script>};
|
||||
|
||||
my $console = WebGUI::Shop::Admin->new($session)->getAdminConsole;
|
||||
return $console->render($output, 'Vendor payout'); #$i18n->get("vendors"));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_payoutDataAsJSON ( )
|
||||
|
||||
Returns a JSON string containing paginated payout data for a specific vendor.
|
||||
The following form params should be passed:
|
||||
|
||||
=head3 vendorId
|
||||
|
||||
The vendorId of the vendor you want the payout data for.
|
||||
|
||||
=head3 results
|
||||
|
||||
The number of results to be returned. Defaults to 100.
|
||||
|
||||
=head3 startIndex
|
||||
|
||||
The index of the record at which the payout data should start.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_payoutDataAsJSON {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
|
||||
my $admin = WebGUI::Shop::Admin->new($session);
|
||||
return $session->privilege->adminOnly() unless ($admin->canManage);
|
||||
|
||||
my $vendorId = $session->form->process('vendorId');
|
||||
my $startIndex = $session->form->process('startIndex');
|
||||
my $rowsPerPage = $session->form->process('results') || 100;
|
||||
my $pageNumber = int( $startIndex / $rowsPerPage ) + 1;
|
||||
|
||||
my $sql =
|
||||
"select t1.* from transactionItem as t1 join transaction as t2 on t1.transactionId=t2.transactionId "
|
||||
." where vendorId=? and vendorPayoutAmount > 0 and vendorPayoutStatus <> 'Paid' order by t2.orderNumber";
|
||||
my $placeholders = [ $vendorId ];
|
||||
|
||||
my $paginator = WebGUI::Paginator->new( $session, '', $rowsPerPage, '', $pageNumber );
|
||||
$paginator->setDataByQuery( $sql, undef, 0, $placeholders );
|
||||
|
||||
my $data = {
|
||||
totalRecords => $paginator->getRowCount,
|
||||
results => $paginator->getPageData,
|
||||
};
|
||||
|
||||
$session->http->setMimeType( 'application/json' );
|
||||
|
||||
return JSON::to_json( $data );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_setPayoutStatus ( )
|
||||
|
||||
Sets the vendorPayoutStatus flag for each transaction passed by the form param 'itemId'. The new status is passed
|
||||
by the form param 'status'. Status can either be 'NotPaid' or 'Scheduled' and may only be applied on items that do
|
||||
not have their vendorPayoutStatus set to 'Paid'.
|
||||
|
||||
Returns the status to which the item(s) are set.
|
||||
=cut
|
||||
|
||||
sub www_setPayoutStatus {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
|
||||
my $admin = WebGUI::Shop::Admin->new($session);
|
||||
return $session->privilege->adminOnly() unless ($admin->canManage);
|
||||
|
||||
my @itemIds = $session->form->process('itemId');
|
||||
my $status = $session->form->process('status');
|
||||
return "error: wrong status [$status]" unless isIn( $status, qw{ NotPaid Scheduled } );
|
||||
|
||||
foreach my $itemId (@itemIds) {
|
||||
my $item = WebGUI::Shop::TransactionItem->newByDynamicTransaction( $session, $itemId );
|
||||
return "error: invalid transactionItemId [$itemId]" unless $item;
|
||||
return "error: cannot change status of a Paid item" if $item->get('vendorPayoutStatus') eq 'Paid';
|
||||
|
||||
$item->update({ vendorPayoutStatus => $status });
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_submitScheduledPayouts ()
|
||||
|
||||
Sets the vendorPayoutStatus flag of scheduled payments to 'Paid'.
|
||||
|
||||
NOTE: This method does no payments at all. In the future this method should trigger some automated payout
|
||||
mechanism.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_submitScheduledPayouts {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
|
||||
my $admin = WebGUI::Shop::Admin->new($session);
|
||||
return $session->privilege->adminOnly() unless ($admin->canManage);
|
||||
|
||||
$session->db->write(
|
||||
q{ update transactionItem set vendorPayoutStatus = 'Paid' where vendorPayoutStatus = 'Scheduled' }
|
||||
);
|
||||
|
||||
return $class->www_managePayouts( $session );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_vendorTotalsAsJSON ( )
|
||||
|
||||
Returns a JSON string containing all vendors and their payout details. The following
|
||||
form parameters can be passed:
|
||||
|
||||
=head3 vendorId
|
||||
|
||||
If passed, the results will include only the totals of this vendor.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_vendorTotalsAsJSON {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
|
||||
my $admin = WebGUI::Shop::Admin->new($session);
|
||||
return $session->privilege->adminOnly() unless ($admin->canManage);
|
||||
|
||||
my $vendorId = $session->form->process('vendorId');
|
||||
my ($vendorPayoutData, @placeholders);
|
||||
|
||||
my @sql;
|
||||
push @sql,
|
||||
'select vendorId, vendorPayoutStatus, sum(vendorPayoutAmount) as total from transactionItem';
|
||||
push @sql, ' where vendorId=? ' if $vendorId;
|
||||
push @sql, ' group by vendorId, vendorPayoutStatus ';
|
||||
|
||||
push @placeholders, $vendorId if $vendorId;
|
||||
|
||||
my $sth = $session->db->read( join( ' ', @sql) , \@placeholders );
|
||||
while (my $row = $sth->hashRef) {
|
||||
$vendorPayoutData->{ $row->{vendorId} }->{ $row->{vendorPayoutStatus} } = $row->{total};
|
||||
}
|
||||
$sth->finish;
|
||||
|
||||
my @dataset;
|
||||
foreach my $vendorId (keys %{ $vendorPayoutData }) {
|
||||
my $vendor = WebGUI::Shop::Vendor->new( $session, $vendorId );
|
||||
|
||||
push @dataset, {
|
||||
%{ $vendor->get },
|
||||
%{ $vendorPayoutData->{ $vendorId } },
|
||||
}
|
||||
}
|
||||
|
||||
$session->http->setMimeType( 'application/json' );
|
||||
return JSON::to_json( { vendors => \@dataset } );
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue