1 # This file has been auto-generated only because it didn't exist.
 
   2 # Feel free to modify it at will; it will not be overwritten automatically.
 
   4 package SL::DB::ShopOrder;
 
  10 use SL::DB::MetaSetup::ShopOrder;
 
  11 use SL::DB::Manager::ShopOrder;
 
  12 use SL::DB::Helper::LinkedRecords;
 
  13 use SL::Locale::String qw(t8);
 
  16 __PACKAGE__->meta->add_relationships(
 
  18     class      => 'SL::DB::ShopOrderItem',
 
  19     column_map => { id => 'shop_order_id' },
 
  20     type       => 'one to many',
 
  24 __PACKAGE__->meta->initialize;
 
  26 sub convert_to_sales_order {
 
  27   my ($self, %params) = @_;
 
  29   my $customer  = delete $params{customer};
 
  30   my $employee  = delete $params{employee};
 
  31   my $transdate = delete $params{transdate} // DateTime->today_local;
 
  32   croak "param customer is missing" unless ref($customer) eq 'SL::DB::Customer';
 
  33   croak "param employee is missing" unless ref($employee) eq 'SL::DB::Employee';
 
  35   require SL::DB::Order;
 
  36   require SL::DB::OrderItem;
 
  38   require SL::DB::Shipto;
 
  43     my $part = SL::DB::Manager::Part->find_by(partnumber => $_->partnumber);
 
  46       push @error_report, t8('Part with partnumber: #1 not found', $_->partnumber);
 
  48       my $current_order_item = SL::DB::OrderItem->new(
 
  49         parts_id            => $part->id,
 
  50         description         => $part->description,
 
  52         sellprice           => $_->price,
 
  54         position            => $_->position,
 
  55         active_price_source => $_->active_price_source,
 
  58   }@{ $self->shop_order_items };
 
  60   if(!scalar(@error_report)){
 
  63     if ($self->has_differing_delivery_address) {
 
  64       if(my $address = SL::DB::Manager::Shipto->find_by( shiptoname   => $self->delivery_fullname,
 
  65                                                          shiptostreet => $self->delivery_street,
 
  66                                                          shiptocity   => $self->delivery_city,
 
  68         $shipto_id = $address->{shipto_id};
 
  70         my $deliveryaddress = SL::DB::Shipto->new;
 
  71         $deliveryaddress->assign_attributes(
 
  72           shiptoname         => $self->delivery_fullname,
 
  73           shiptodepartment_1 => $self->delivery_company,
 
  74           shiptodepartment_2 => $self->delivery_department,
 
  75           shiptostreet       => $self->delivery_street,
 
  76           shiptozipcode      => $self->delivery_zipcode,
 
  77           shiptocity         => $self->delivery_city,
 
  78           shiptocountry      => $self->delivery_country,
 
  79           trans_id           => $customer->id,
 
  82         $deliveryaddress->save;
 
  83         $shipto_id = $deliveryaddress->{shipto_id};
 
  87     my $shop = SL::DB::Manager::Shop->find_by(id => $self->shop_id);
 
  88     my $order = SL::DB::Order->new(
 
  89       amount                  => $self->amount,
 
  90       cusordnumber            => $self->shop_ordernumber,
 
  91       customer_id             => $customer->id,
 
  92       shipto_id               => $shipto_id,
 
  93       orderitems              => [ @items ],
 
  94       employee_id             => $employee->id,
 
  95       intnotes                => $customer->notes,
 
  96       salesman_id             => $employee->id,
 
  97       taxincluded             => $self->tax_included,
 
  98       payment_id              => $customer->payment_id,
 
  99       taxzone_id              => $customer->taxzone_id,
 
 100       currency_id             => $customer->currency_id,
 
 101       transaction_description => $shop->transaction_description,
 
 102       transdate               => $transdate,
 
 106      my %error_order = (error   => 1,
 
 107                         errors  => [ @error_report ],
 
 109      return \%error_order;
 
 113 sub check_for_existing_customers {
 
 114   my ($self, %params) = @_;
 
 117   my $name             = $self->billing_lastname ne '' ? $self->billing_firstname . " " . $self->billing_lastname : '';
 
 118   my $lastname         = $self->billing_lastname ne '' ? "%" . $self->billing_lastname . "%"                      : '';
 
 119   my $company          = $self->billing_company  ne '' ? "%" . $self->billing_company  . "%"                      : '';
 
 120   my $street           = $self->billing_street   ne '' ?  $self->billing_street                                   : '';
 
 121   my $street_not_fuzzy = $self->billing_street   ne '' ?  "%" . $self->billing_street . "%"                       : '';
 
 122   my $zipcode          = $self->billing_street   ne '' ?  $self->billing_zipcode                                  : '';
 
 123   my $email            = $self->billing_street   ne '' ?  $self->billing_email                                    : '';
 
 125   if(check_trgm($::form->get_standard_dbh())) {
 
 126     # Fuzzysearch for street to find e.g. "Dorfstrasse - Dorfstr. - Dorfstraße"
 
 127     my $fs_query = <<SQL;
 
 132     ( name ILIKE ? OR name ILIKE ? )
 
 137    ( street % ?  AND zipcode ILIKE ?)
 
 143     my @values = ($lastname, $company, $self->billing_zipcode, $street, $self->billing_zipcode, $self->billing_email);
 
 145     $customers = SL::DB::Manager::Customer->get_objects_from_sql(
 
 150     # If trgm extension is not installed
 
 151     $customers = SL::DB::Manager::Customer->get_all(
 
 155                      or => [ 'name' => { ilike => $lastname },
 
 156                              'name' => { ilike => $company  },
 
 158                      'zipcode' => { ilike => $zipcode },
 
 161                      and => [ 'street'  => { ilike => $street_not_fuzzy },
 
 162                               'zipcode' => { ilike => $zipcode },
 
 165             or  => [ 'email' => { ilike => $email } ],
 
 174 sub check_for_open_invoices {
 
 176     my $open_invoices = SL::DB::Manager::Invoice->get_all_count(
 
 177       query => [customer_id => $self->{kivi_customer_id},
 
 178               paid => {lt_sql => 'amount'},
 
 181   return $open_invoices;
 
 185   my ($self, %params) = @_;
 
 186   my $shop = SL::DB::Manager::Shop->find_by(id => $self->shop_id);
 
 187   my $customer_proposals = $self->check_for_existing_customers;
 
 188   my $name = $self->billing_firstname . " " . $self->billing_lastname;
 
 190   if(!scalar(@{$customer_proposals})){
 
 191     my %address = ( 'name'                  => $name,
 
 192                     'department_1'          => $self->billing_company,
 
 193                     'department_2'          => $self->billing_department,
 
 194                     'street'                => $self->billing_street,
 
 195                     'zipcode'               => $self->billing_zipcode,
 
 196                     'city'                  => $self->billing_city,
 
 197                     'email'                 => $self->billing_email,
 
 198                     'country'               => $self->billing_country,
 
 199                     'greeting'              => $self->billing_greeting,
 
 200                     'fax'                   => $self->billing_fax,
 
 201                     'phone'                 => $self->billing_phone,
 
 202                     'ustid'                 => $self->billing_vat,
 
 203                     'taxincluded_checked'   => $shop->pricetype eq "brutto" ? 1 : 0,
 
 204                     'taxincluded'           => $shop->pricetype eq "brutto" ? 1 : 0,
 
 205                     'pricegroup_id'         => (split '\/',$shop->price_source)[0] eq "pricegroup" ?  (split '\/',$shop->price_source)[1] : undef,
 
 206                     'taxzone_id'            => $shop->taxzone_id,
 
 207                     'currency'              => $::instance_conf->get_currency_id,
 
 208                     #'payment_id'            => 7345,# TODO hardcoded
 
 210     $customer = SL::DB::Customer->new(%address);
 
 213     my $snumbers = "customernumber_" . $customer->customernumber;
 
 214     SL::DB::History->new(
 
 215                       trans_id    => $customer->id,
 
 216                       snumbers    => $snumbers,
 
 217                       employee_id => SL::DB::Manager::Employee->current->id,
 
 219                       what_done   => 'Shopimport',
 
 222   }elsif(scalar(@{$customer_proposals}) == 1){
 
 223     # check if the proposal is the right customer, could be different names under the same address. Depends on how first- and familyname is handled. Here is for customername = companyname or customername = "firstname familyname"
 
 224     $customer = SL::DB::Manager::Customer->find_by( id       => $customer_proposals->[0]->id,
 
 226                                                     email    => $self->billing_email,
 
 227                                                     street   => $self->billing_street,
 
 228                                                     zipcode  => $self->billing_zipcode,
 
 229                                                     city     => $self->billing_city,
 
 238   my ($self, $other) = @_;
 
 240   return  1 if  $self->transfer_date && !$other->transfer_date;
 
 241   return -1 if !$self->transfer_date &&  $other->transfer_date;
 
 244   $result    = $self->transfer_date <=> $other->transfer_date if $self->transfer_date;
 
 245   return $result || ($self->id <=> $other->id);
 
 248 sub has_differing_delivery_address {
 
 250   ($self->billing_firstname // '') ne ($self->delivery_firstname // '') ||
 
 251   ($self->billing_lastname  // '') ne ($self->delivery_lastname  // '') ||
 
 252   ($self->billing_city      // '') ne ($self->delivery_city      // '') ||
 
 253   ($self->billing_street    // '') ne ($self->delivery_street    // '')
 
 256 sub delivery_fullname {
 
 257   ($_[0]->delivery_firstname // '') . " " . ($_[0]->delivery_lastname // '')
 
 270 SL::DB::ShopOrder - Model for the 'shop_orders' table
 
 274 This is a standard Rose::DB::Object based model and can be used as one.
 
 280 =item C<convert_to_sales_order>
 
 282 =item C<check_for_existing_customers>
 
 284 Inexact search for possible matches with existing customers in the database.
 
 286 Returns all found customers as an arrayref of SL::DB::Customer objects.
 
 288 =item C<get_customer>
 
 290 returns only one customer from the check_for_existing_customers if the return from it is 0 or 1 customer.
 
 292 When it is 0 get customer creates a new customer object of the shop order billing data and returns it
 
 300 some variables like payments could be better implemented. Transaction description is hardcoded
 
 304 Werner Hahn E<lt>wh@futureworldsearch.netE<gt>
 
 306 G. Richardson E<lt>grichardson@kivitendo-premium.deE<gt>