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 croak "param customer is missing" unless ref($customer) eq 'SL::DB::Customer';
32 croak "param employee is missing" unless ref($employee) eq 'SL::DB::Employee';
34 require SL::DB::Order;
35 require SL::DB::OrderItem;
37 require SL::DB::Shipto;
42 my $part = SL::DB::Manager::Part->find_by(partnumber => $_->partnumber);
45 push @error_report, t8('Part with partnumber: #1 not found', $_->partnumber);
47 my $current_order_item = SL::DB::OrderItem->new(
48 parts_id => $part->id,
49 description => $part->description,
51 sellprice => $_->price,
53 position => $_->position,
54 active_price_source => $_->active_price_source,
57 }@{ $self->shop_order_items };
59 if(!scalar(@error_report)){
62 if ($self->has_differing_delivery_address) {
63 if(my $address = SL::DB::Manager::Shipto->find_by( shiptoname => $self->delivery_fullname,
64 shiptostreet => $self->delivery_street,
65 shiptocity => $self->delivery_city,
67 $shipto_id = $address->{shipto_id};
69 my $deliveryaddress = SL::DB::Shipto->new;
70 $deliveryaddress->assign_attributes(
71 shiptoname => $self->delivery_fullname,
72 shiptodepartment_1 => $self->delivery_company,
73 shiptodepartment_2 => $self->delivery_department,
74 shiptostreet => $self->delivery_street,
75 shiptozipcode => $self->delivery_zipcode,
76 shiptocity => $self->delivery_city,
77 shiptocountry => $self->delivery_country,
78 trans_id => $customer->id,
81 $deliveryaddress->save;
82 $shipto_id = $deliveryaddress->{shipto_id};
86 my $shop = SL::DB::Manager::Shop->find_by(id => $self->shop_id);
87 my $order = SL::DB::Order->new(
88 amount => $self->amount,
89 cusordnumber => $self->shop_ordernumber,
90 customer_id => $customer->id,
91 shipto_id => $shipto_id,
92 orderitems => [ @items ],
93 employee_id => $employee->id,
94 intnotes => $customer->notes,
95 salesman_id => $employee->id,
96 taxincluded => $self->tax_included,
97 payment_id => $customer->payment_id,
98 taxzone_id => $customer->taxzone_id,
99 currency_id => $customer->currency_id,
100 transaction_description => $shop->transaction_description,
101 transdate => DateTime->today_local
105 my %error_order = (error => 1,
106 errors => [ @error_report ],
108 return \%error_order;
112 sub check_for_existing_customers {
113 my ($self, %params) = @_;
116 my $name = $self->billing_lastname ne '' ? $self->billing_firstname . " " . $self->billing_lastname : '';
117 my $lastname = $self->billing_lastname ne '' ? "%" . $self->billing_lastname . "%" : '';
118 my $company = $self->billing_company ne '' ? "%" . $self->billing_company . "%" : '';
119 my $street = $self->billing_street ne '' ? $self->billing_street : '';
120 my $street_not_fuzzy = $self->billing_street ne '' ? "%" . $self->billing_street . "%" : '';
121 my $zipcode = $self->billing_street ne '' ? $self->billing_zipcode : '';
122 my $email = $self->billing_street ne '' ? $self->billing_email : '';
124 if($self->check_trgm) {
125 # Fuzzysearch for street to find e.g. "Dorfstrasse - Dorfstr. - Dorfstraße"
126 my $fs_query = <<SQL;
131 ( name ILIKE ? OR name ILIKE ? )
136 ( street % ? AND zipcode ILIKE ?)
142 my @values = ($lastname, $company, $self->billing_zipcode, $street, $self->billing_zipcode, $self->billing_email);
144 $customers = SL::DB::Manager::Customer->get_objects_from_sql(
149 # If trgm extension is not installed
150 $customers = SL::DB::Manager::Customer->get_all(
154 or => [ 'name' => { ilike => $lastname },
155 'name' => { ilike => $company },
157 'zipcode' => { ilike => $zipcode },
160 and => [ 'street' => { ilike => $street_not_fuzzy },
161 'zipcode' => { ilike => $zipcode },
164 or => [ 'email' => { ilike => $email } ],
174 my ($self, %params) = @_;
175 my $shop = SL::DB::Manager::Shop->find_by(id => $self->shop_id);
176 my $customer_proposals = $self->check_for_existing_customers;
177 my $name = $self->billing_firstname . " " . $self->billing_lastname;
179 if(!scalar(@{$customer_proposals})){
180 my %address = ( 'name' => $name,
181 'department_1' => $self->billing_company,
182 'department_2' => $self->billing_department,
183 'street' => $self->billing_street,
184 'zipcode' => $self->billing_zipcode,
185 'city' => $self->billing_city,
186 'email' => $self->billing_email,
187 'country' => $self->billing_country,
188 'greeting' => $self->billing_greeting,
189 'fax' => $self->billing_fax,
190 'phone' => $self->billing_phone,
191 'ustid' => $self->billing_vat,
192 'taxincluded_checked' => $shop->pricetype eq "brutto" ? 1 : 0,
193 'taxincluded' => $shop->pricetype eq "brutto" ? 1 : 0,
194 'pricegroup_id' => (split '\/',$shop->price_source)[0] eq "pricegroup" ? (split '\/',$shop->price_source)[1] : undef,
195 'taxzone_id' => $shop->taxzone_id,
196 'currency' => $::instance_conf->get_currency_id,
197 #'payment_id' => 7345,# TODO hardcoded
199 $customer = SL::DB::Customer->new(%address);
202 my $snumbers = "customernumber_" . $customer->customernumber;
203 SL::DB::History->new(
204 trans_id => $customer->id,
205 snumbers => $snumbers,
206 employee_id => SL::DB::Manager::Employee->current->id,
208 what_done => 'Shopimport',
211 }elsif(scalar(@{$customer_proposals}) == 1){
212 # 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"
213 $customer = SL::DB::Manager::Customer->find_by( id => $customer_proposals->[0]->id,
215 email => $self->billing_email,
216 street => $self->billing_street,
217 zipcode => $self->billing_zipcode,
218 city => $self->billing_city,
227 my ($self, $other) = @_;
229 return 1 if $self->transfer_date && !$other->transfer_date;
230 return -1 if !$self->transfer_date && $other->transfer_date;
233 $result = $self->transfer_date <=> $other->transfer_date if $self->transfer_date;
234 return $result || ($self->id <=> $other->id);
240 my $dbh = $::form->get_standard_dbh();
241 my $sql = "SELECT installed_version FROM pg_available_extensions WHERE name = 'pg_trgm'";
242 my @version = selectall_hashref_query($::form, $dbh, $sql);
244 return 1 if($version[0]->{installed_version});
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
298 Checks if the postgresextension pg_trgm is installed and return 0 or 1.
304 some variables like payments could be better implemented. Transaction description is hardcoded
308 Werner Hahn E<lt>wh@futureworldsearch.netE<gt>
310 G. Richardson E<lt>grichardson@kivitendo-premium.deE<gt>